diff options
| -rw-r--r-- | bitbake/lib/toaster/tests/functional/functional_helpers.py | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/bitbake/lib/toaster/tests/functional/functional_helpers.py b/bitbake/lib/toaster/tests/functional/functional_helpers.py index 09cf3ba8e0..6039d736e9 100644 --- a/bitbake/lib/toaster/tests/functional/functional_helpers.py +++ b/bitbake/lib/toaster/tests/functional/functional_helpers.py | |||
| @@ -19,9 +19,10 @@ from selenium.webdriver.common.by import By | |||
| 19 | from selenium.common.exceptions import NoSuchElementException | 19 | from selenium.common.exceptions import NoSuchElementException |
| 20 | 20 | ||
| 21 | logger = logging.getLogger("toaster") | 21 | logger = logging.getLogger("toaster") |
| 22 | toaster_processes = [] | ||
| 22 | 23 | ||
| 23 | class SeleniumFunctionalTestCase(SeleniumTestCaseBase): | 24 | class SeleniumFunctionalTestCase(SeleniumTestCaseBase): |
| 24 | wait_toaster_time = 5 | 25 | wait_toaster_time = 10 |
| 25 | 26 | ||
| 26 | @classmethod | 27 | @classmethod |
| 27 | def setUpClass(cls): | 28 | def setUpClass(cls): |
| @@ -31,13 +32,22 @@ class SeleniumFunctionalTestCase(SeleniumTestCaseBase): | |||
| 31 | raise RuntimeError("Please initialise django with the tests settings: " | 32 | raise RuntimeError("Please initialise django with the tests settings: " |
| 32 | "DJANGO_SETTINGS_MODULE='toastermain.settings_test'") | 33 | "DJANGO_SETTINGS_MODULE='toastermain.settings_test'") |
| 33 | 34 | ||
| 35 | # Wait for any known toaster processes to exit | ||
| 36 | global toaster_processes | ||
| 37 | for toaster_process in toaster_processes: | ||
| 38 | try: | ||
| 39 | os.waitpid(toaster_process, os.WNOHANG) | ||
| 40 | except ChildProcessError: | ||
| 41 | pass | ||
| 42 | |||
| 34 | # start toaster | 43 | # start toaster |
| 35 | cmd = "bash -c 'source toaster start'" | 44 | cmd = "bash -c 'source toaster start'" |
| 36 | cls.p = subprocess.Popen( | 45 | start_process = subprocess.Popen( |
| 37 | cmd, | 46 | cmd, |
| 38 | cwd=os.environ.get("BUILDDIR"), | 47 | cwd=os.environ.get("BUILDDIR"), |
| 39 | shell=True) | 48 | shell=True) |
| 40 | if cls.p.wait() != 0: | 49 | toaster_processes = [start_process.pid] |
| 50 | if start_process.wait() != 0: | ||
| 41 | port_use = os.popen("lsof -i -P -n | grep '8000 (LISTEN)'").read().strip() | 51 | port_use = os.popen("lsof -i -P -n | grep '8000 (LISTEN)'").read().strip() |
| 42 | message = '' | 52 | message = '' |
| 43 | if port_use: | 53 | if port_use: |
| @@ -46,6 +56,12 @@ class SeleniumFunctionalTestCase(SeleniumTestCaseBase): | |||
| 46 | message = f"Port 8000 occupied by {process}" | 56 | message = f"Port 8000 occupied by {process}" |
| 47 | raise RuntimeError(f"Can't initialize toaster. {message}") | 57 | raise RuntimeError(f"Can't initialize toaster. {message}") |
| 48 | 58 | ||
| 59 | builddir = os.environ.get("BUILDDIR") | ||
| 60 | with open(os.path.join(builddir, '.toastermain.pid'), 'r') as f: | ||
| 61 | toaster_processes.append(int(f.read())) | ||
| 62 | with open(os.path.join(builddir, '.runbuilds.pid'), 'r') as f: | ||
| 63 | toaster_processes.append(int(f.read())) | ||
| 64 | |||
| 49 | super(SeleniumFunctionalTestCase, cls).setUpClass() | 65 | super(SeleniumFunctionalTestCase, cls).setUpClass() |
| 50 | cls.live_server_url = 'http://localhost:8000/' | 66 | cls.live_server_url = 'http://localhost:8000/' |
| 51 | 67 | ||
| @@ -53,18 +69,25 @@ class SeleniumFunctionalTestCase(SeleniumTestCaseBase): | |||
| 53 | def tearDownClass(cls): | 69 | def tearDownClass(cls): |
| 54 | super(SeleniumFunctionalTestCase, cls).tearDownClass() | 70 | super(SeleniumFunctionalTestCase, cls).tearDownClass() |
| 55 | 71 | ||
| 56 | # XXX: source toaster stop gets blocked, to review why? | 72 | global toaster_processes |
| 57 | # from now send SIGTERM by hand | ||
| 58 | time.sleep(cls.wait_toaster_time) | ||
| 59 | builddir = os.environ.get("BUILDDIR") | ||
| 60 | 73 | ||
| 61 | with open(os.path.join(builddir, '.toastermain.pid'), 'r') as f: | 74 | cmd = "bash -c 'source toaster stop'" |
| 62 | toastermain_pid = int(f.read()) | 75 | stop_process = subprocess.Popen( |
| 63 | os.kill(toastermain_pid, signal.SIGTERM) | 76 | cmd, |
| 64 | with open(os.path.join(builddir, '.runbuilds.pid'), 'r') as f: | 77 | cwd=os.environ.get("BUILDDIR"), |
| 65 | runbuilds_pid = int(f.read()) | 78 | shell=True) |
| 66 | os.kill(runbuilds_pid, signal.SIGTERM) | 79 | # Toaster stop has been known to hang in these tests so force kill if it stalls |
| 67 | cls.p.kill() | 80 | try: |
| 81 | if stop_process.wait(cls.wait_toaster_time) != 0: | ||
| 82 | raise Exception('Toaster stop process failed') | ||
| 83 | except Exception as e: | ||
| 84 | if e is subprocess.TimeoutExpired: | ||
| 85 | print('Toaster stop process took too long. Force killing toaster...') | ||
| 86 | else: | ||
| 87 | print('Toaster stop process failed. Force killing toaster...') | ||
| 88 | stop_process.kill() | ||
| 89 | for toaster_process in toaster_processes: | ||
| 90 | os.kill(toaster_process, signal.SIGTERM) | ||
| 68 | 91 | ||
| 69 | 92 | ||
| 70 | def get_URL(self): | 93 | def get_URL(self): |
