Extent unit tests
This commit is contained in:
parent
bddbb3b149
commit
04002ab6e6
@ -816,6 +816,7 @@ function read_and_display_file(file) {
|
|||||||
<h4>General</h4>
|
<h4>General</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li>Improve SVG chart colour palette</li>
|
<li>Improve SVG chart colour palette</li>
|
||||||
|
<li>Add Selenium based unit tests</li>
|
||||||
<li>...</li>
|
<li>...</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
|
@ -14,7 +14,34 @@ VERSION = "0.5.0 (devel)"
|
|||||||
"""Version number"""
|
"""Version number"""
|
||||||
|
|
||||||
# __pragma__ ('skip')
|
# __pragma__ ('skip')
|
||||||
js_undefined = 0 # Prevent complaints by optional static checker
|
# MOC objects to satisfy statical checker and imports in unit tests
|
||||||
|
js_undefined = 0
|
||||||
|
class classList():
|
||||||
|
|
||||||
|
def add(self, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def remove(self, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class document():
|
||||||
|
|
||||||
|
def querySelectorAll(self, *args, **kwargs):
|
||||||
|
return [element()]
|
||||||
|
|
||||||
|
def getElementById(self, *arg, **kwargs):
|
||||||
|
return element()
|
||||||
|
|
||||||
|
|
||||||
|
class element():
|
||||||
|
|
||||||
|
firstChild = []
|
||||||
|
classList = classList()
|
||||||
|
offsetWidth = 0
|
||||||
|
|
||||||
|
def removeChild(self, *args, **kwargs):
|
||||||
|
return
|
||||||
# __pragma__ ('noskip')
|
# __pragma__ ('noskip')
|
||||||
|
|
||||||
|
|
||||||
|
160
test.py
160
test.py
@ -23,7 +23,10 @@ import socketserver
|
|||||||
import threading
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
from selenium import webdriver
|
from selenium import webdriver
|
||||||
|
from selenium.common.exceptions import *
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
import OOMAnalyser
|
||||||
|
|
||||||
class MyRequestHandler(http.server.SimpleHTTPRequestHandler):
|
class MyRequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
|
|
||||||
@ -41,29 +44,91 @@ class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TestHTTPOOMAnalyser(unittest.TestCase):
|
class TestBase(unittest.TestCase):
|
||||||
"""Test OOM web page"""
|
|
||||||
|
def get_lines(self, text, count):
|
||||||
|
"""
|
||||||
|
Return the number of lines specified by count from given text
|
||||||
|
@type text: str
|
||||||
|
@type count: int
|
||||||
|
"""
|
||||||
|
lines = text.splitlines()[:count]
|
||||||
|
res = '\n'.join(lines)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def get_first_line(self, text):
|
||||||
|
"""
|
||||||
|
Return the first line of the given text
|
||||||
|
@type text: str
|
||||||
|
"""
|
||||||
|
return self.get_lines(text, 1)
|
||||||
|
|
||||||
|
def get_last_line(self, text):
|
||||||
|
"""
|
||||||
|
Return the last line of the given text
|
||||||
|
@type text: str
|
||||||
|
"""
|
||||||
|
return self.get_lines(text, -1)
|
||||||
|
|
||||||
|
class TestInBrowser(TestBase):
|
||||||
|
"""Test OOM web page in a browser"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
warnings.simplefilter("ignore", ResourceWarning)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
ThreadedTCPServer.allow_reuse_address = True
|
ThreadedTCPServer.allow_reuse_address = True
|
||||||
cls.httpd = ThreadedTCPServer(('127.0.0.1', 8000), MyRequestHandler)
|
self.httpd = ThreadedTCPServer(('127.0.0.1', 8000), MyRequestHandler)
|
||||||
# cls.httpd.allow_reuse_address = True
|
server_thread = threading.Thread(target=self.httpd.serve_forever, args=(0.1,))
|
||||||
server_thread = threading.Thread(target=cls.httpd.serve_forever, args=(0.1,))
|
|
||||||
server_thread.daemon = True
|
server_thread.daemon = True
|
||||||
server_thread.start()
|
server_thread.start()
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def tearDownClass(cls):
|
|
||||||
cls.httpd.shutdown()
|
|
||||||
cls.httpd.server_close()
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.driver = webdriver.Chrome()
|
self.driver = webdriver.Chrome()
|
||||||
self.driver.get("http://127.0.0.1:8000/OOMAnalyser.html")
|
self.driver.get("http://127.0.0.1:8000/OOMAnalyser.html")
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.driver.close()
|
self.driver.close()
|
||||||
|
self.httpd.shutdown()
|
||||||
|
self.httpd.server_close()
|
||||||
|
|
||||||
|
def assert_on_warn(self):
|
||||||
|
notify_box = self.driver.find_element_by_id('notify_box')
|
||||||
|
with self.assertRaises(NoSuchElementException):
|
||||||
|
notify_box.find_element_by_class_name('js-notify_box__msg--warning')
|
||||||
|
|
||||||
|
def assert_on_error(self):
|
||||||
|
notify_box = self.driver.find_element_by_id('notify_box')
|
||||||
|
with self.assertRaises(NoSuchElementException):
|
||||||
|
notify_box.find_element_by_class_name('js-notify_box__msg--error')
|
||||||
|
|
||||||
|
def click_analyse(self):
|
||||||
|
analyse = self.driver.find_element_by_xpath('//button[text()="Analyse"]')
|
||||||
|
analyse.click()
|
||||||
|
|
||||||
|
def click_reset(self):
|
||||||
|
reset = self.driver.find_element_by_xpath('//button[text()="Reset"]')
|
||||||
|
reset.click()
|
||||||
|
self.assert_on_warn_error()
|
||||||
|
|
||||||
|
def analyse_oom(self, text):
|
||||||
|
"""
|
||||||
|
Insert text and run analysis
|
||||||
|
|
||||||
|
:param str text: OOM text to analyse
|
||||||
|
"""
|
||||||
|
textarea = self.driver.find_element_by_id('textarea_oom')
|
||||||
|
self.assertEqual(textarea.get_attribute('value'), '', 'Empty textarea expected')
|
||||||
|
textarea.send_keys(text)
|
||||||
|
|
||||||
|
self.assertNotEqual(textarea.get_attribute('value'), '', 'Missing OOM text in textarea')
|
||||||
|
|
||||||
|
h3_summary = self.driver.find_element_by_xpath('//h3[text()="Summary"]')
|
||||||
|
self.assertFalse(h3_summary.is_displayed(), "Analysis details incl. <h3>Summary</h3> should be not displayed")
|
||||||
|
|
||||||
|
self.click_analyse()
|
||||||
|
|
||||||
|
def assert_on_warn_error(self):
|
||||||
|
self.assert_on_warn()
|
||||||
|
self.assert_on_error()
|
||||||
|
|
||||||
def test_001_load_page(self):
|
def test_001_load_page(self):
|
||||||
"""Test if the page is loading"""
|
"""Test if the page is loading"""
|
||||||
@ -85,9 +150,9 @@ class TestHTTPOOMAnalyser(unittest.TestCase):
|
|||||||
h3_summary = self.driver.find_element_by_xpath('//h3[text()="Summary"]')
|
h3_summary = self.driver.find_element_by_xpath('//h3[text()="Summary"]')
|
||||||
self.assertFalse(h3_summary.is_displayed(), "Analysis details incl. <h3>Summary</h3> should be not displayed")
|
self.assertFalse(h3_summary.is_displayed(), "Analysis details incl. <h3>Summary</h3> should be not displayed")
|
||||||
|
|
||||||
analyse = self.driver.find_element_by_xpath('//button[text()="Analyse"]')
|
self.click_analyse()
|
||||||
analyse.click()
|
|
||||||
|
|
||||||
|
self.assert_on_warn_error()
|
||||||
self.assertTrue(h3_summary.is_displayed(), "Analysis details incl. <h3>Summary</h3> should be displayed")
|
self.assertTrue(h3_summary.is_displayed(), "Analysis details incl. <h3>Summary</h3> should be displayed")
|
||||||
|
|
||||||
trigger_proc_name = self.driver.find_element_by_class_name('trigger_proc_name')
|
trigger_proc_name = self.driver.find_element_by_class_name('trigger_proc_name')
|
||||||
@ -98,6 +163,71 @@ class TestHTTPOOMAnalyser(unittest.TestCase):
|
|||||||
killed_proc_score = self.driver.find_element_by_class_name('killed_proc_score')
|
killed_proc_score = self.driver.find_element_by_class_name('killed_proc_score')
|
||||||
self.assertEqual(killed_proc_score.text, '651', 'Unexpected OOM score of killed process')
|
self.assertEqual(killed_proc_score.text, '651', 'Unexpected OOM score of killed process')
|
||||||
|
|
||||||
|
def test_004_begin_but_no_end(self):
|
||||||
|
"""Test incomplete OOM text - just the beginning"""
|
||||||
|
example = """\
|
||||||
|
sed invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0
|
||||||
|
sed cpuset=/ mems_allowed=0-1
|
||||||
|
"""
|
||||||
|
self.analyse_oom(example)
|
||||||
|
|
||||||
|
notify_box = self.driver.find_element_by_id('notify_box')
|
||||||
|
notify_box.find_element_by_class_name('js-notify_box__msg--warning')
|
||||||
|
self.assertTrue(notify_box.text.startswith("WARNING: The inserted OOM is incomplete!"))
|
||||||
|
|
||||||
|
self.click_reset()
|
||||||
|
|
||||||
|
def test_005_no_begin_but_end(self):
|
||||||
|
"""Test incomplete OOM text - just the end"""
|
||||||
|
example = """\
|
||||||
|
Out of memory: Kill process 6576 (java) score 651 or sacrifice child
|
||||||
|
Killed process 6576 (java) total-vm:33914892kB, anon-rss:20629004kB, file-rss:0kB, shmem-rss:0kB
|
||||||
|
"""
|
||||||
|
self.analyse_oom(example)
|
||||||
|
|
||||||
|
notify_box = self.driver.find_element_by_id('notify_box')
|
||||||
|
notify_box.find_element_by_class_name('js-notify_box__msg--error')
|
||||||
|
self.assertTrue(notify_box.text.startswith("ERROR: The inserted text is not a valid OOM block!"))
|
||||||
|
|
||||||
|
self.click_reset()
|
||||||
|
|
||||||
|
def test_006_trigger_proc_space(self):
|
||||||
|
"""Test trigger process name contains a space"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_007_kill_proc_space(self):
|
||||||
|
"""Test killed process name contains a space"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestPython(TestBase):
|
||||||
|
|
||||||
|
def test_001_trigger_proc_space(self):
|
||||||
|
"""Test RE to find name of trigger process"""
|
||||||
|
first = self.get_first_line(OOMAnalyser.OOMDisplay.example)
|
||||||
|
rec = OOMAnalyser.OOMAnalyser.REC_INVOKED_OOMKILLER
|
||||||
|
match = rec.search(first)
|
||||||
|
self.assertTrue(match, 'Error: re.search(REC_INVOKED_OOMKILLER) failed for simple '
|
||||||
|
'process name')
|
||||||
|
|
||||||
|
first = first.replace('sed', 'VM Monitoring Task')
|
||||||
|
match = rec.search(first)
|
||||||
|
self.assertTrue(match, 'Error: re.search(REC_INVOKED_OOMKILLER) failed for process name '
|
||||||
|
'with space')
|
||||||
|
|
||||||
|
def test_002_killed_proc_space(self):
|
||||||
|
"""Test RE to find name of killed process"""
|
||||||
|
last = self.get_last_line(OOMAnalyser.OOMDisplay.example)
|
||||||
|
rec = OOMAnalyser.OOMAnalyser.REC_OOM_KILL_PROCESS
|
||||||
|
match = rec.search(last)
|
||||||
|
self.assertTrue(match, 'Error: re.search(REC_OOM_KILL_PROCESS) failed for simple '
|
||||||
|
'process name')
|
||||||
|
|
||||||
|
last = last.replace('sed', 'VM Monitoring Task')
|
||||||
|
match = rec.search(last)
|
||||||
|
self.assertTrue(match, 'Error: re.search(REC_OOM_KILL_PROCESS) failed for process name '
|
||||||
|
'with space')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# import logging, sys
|
# import logging, sys
|
||||||
|
Loading…
x
Reference in New Issue
Block a user