Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 1 | #!/usr/bin/env python |
Avi Drissman | dfd88085 | 2022-09-15 20:11:09 | [diff] [blame] | 2 | # Copyright 2019 The Chromium Authors |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 5 | """Unit tests for xvfb.py functionality. |
| 6 | |
| 7 | Each unit test is launching xvfb_test_script.py |
| 8 | through xvfb.py as a subprocess, then tests its expected output. |
| 9 | """ |
| 10 | |
| 11 | import os |
| 12 | import signal |
| 13 | import subprocess |
| 14 | import sys |
| 15 | import time |
| 16 | import unittest |
| 17 | |
Joshua Hood | 3fade1f | 2022-05-04 16:00:42 | [diff] [blame] | 18 | # pylint: disable=super-with-arguments |
| 19 | |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 20 | TEST_FILE= __file__.replace('.pyc','.py') |
| 21 | XVFB= TEST_FILE.replace('_unittest','') |
| 22 | XVFB_TEST_SCRIPT= TEST_FILE.replace('_unittest','_test_script') |
| 23 | |
| 24 | |
| 25 | def launch_process(args): |
| 26 | """Launches a sub process to run through xvfb.py.""" |
Ben Pastene | b5c6726 | 2024-05-15 21:24:01 | [diff] [blame] | 27 | return subprocess.Popen([XVFB, XVFB_TEST_SCRIPT]+ args, |
| 28 | stdout=subprocess.PIPE, |
| 29 | stderr=subprocess.STDOUT, |
| 30 | env=os.environ.copy()) |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 31 | |
| 32 | |
Joshua Hood | 3fade1f | 2022-05-04 16:00:42 | [diff] [blame] | 33 | # pylint: disable=inconsistent-return-statements |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 34 | def read_subprocess_message(proc, starts_with): |
| 35 | """Finds the value after first line prefix condition.""" |
Joshua Hood | 3fade1f | 2022-05-04 16:00:42 | [diff] [blame] | 36 | for linein proc.stdout.read().decode('utf-8').splitlines(True): |
| 37 | if str(line).startswith(starts_with): |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 38 | return line.rstrip().replace(starts_with,'') |
Ben Pastene | b5c6726 | 2024-05-15 21:24:01 | [diff] [blame] | 39 | |
| 40 | |
Joshua Hood | 3fade1f | 2022-05-04 16:00:42 | [diff] [blame] | 41 | # pylint: enable=inconsistent-return-statements |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 42 | |
| 43 | |
| 44 | def send_signal(proc, sig, sleep_time=0.3): |
| 45 | """Sends a signal to subprocess.""" |
| 46 | time.sleep(sleep_time)# gives process time to launch. |
| 47 | os.kill(proc.pid, sig) |
| 48 | proc.wait() |
| 49 | |
| 50 | |
| 51 | classXvfbLinuxTest(unittest.TestCase): |
| 52 | |
| 53 | def setUp(self): |
| 54 | super(XvfbLinuxTest, self).setUp() |
Joshua Hood | 3fade1f | 2022-05-04 16:00:42 | [diff] [blame] | 55 | ifnot sys.platform.startswith('linux'): |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 56 | self.skipTest('linux only test') |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 57 | self._procs=[] |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 58 | |
| 59 | def test_no_xvfb_display(self): |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 60 | self._procs.append(launch_process(['--no-xvfb'])) |
| 61 | self._procs[0].wait() |
| 62 | display= read_subprocess_message(self._procs[0],'Display :') |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 63 | self.assertEqual(display, os.environ.get('DISPLAY','None')) |
| 64 | |
| 65 | def test_xvfb_display(self): |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 66 | self._procs.append(launch_process([])) |
| 67 | self._procs[0].wait() |
| 68 | display= read_subprocess_message(self._procs[0],'Display :') |
Ben Pastene | b5c6726 | 2024-05-15 21:24:01 | [diff] [blame] | 69 | self.assertIsNotNone(display)# Openbox likely failed to open DISPLAY |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 70 | self.assertNotEqual(display, os.environ.get('DISPLAY','None')) |
| 71 | |
| 72 | def test_no_xvfb_flag(self): |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 73 | self._procs.append(launch_process(['--no-xvfb'])) |
| 74 | self._procs[0].wait() |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 75 | |
| 76 | def test_xvfb_flag(self): |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 77 | self._procs.append(launch_process([])) |
| 78 | self._procs[0].wait() |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 79 | |
Brian Sheedy | 0d2300f3 | 2024-08-13 23:14:41 | [diff] [blame] | 80 | @unittest.skip('flaky; crbug.com/1320399') |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 81 | def test_xvfb_race_condition(self): |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 82 | self._procs=[launch_process([])for _in range(15)] |
| 83 | for procin self._procs: |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 84 | proc.wait() |
Ben Pastene | b5c6726 | 2024-05-15 21:24:01 | [diff] [blame] | 85 | display_list=[ |
| 86 | read_subprocess_message(p,'Display :')for pin self._procs |
| 87 | ] |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 88 | for displayin display_list: |
Ben Pastene | b5c6726 | 2024-05-15 21:24:01 | [diff] [blame] | 89 | self.assertIsNotNone(display)# Openbox likely failed to open DISPLAY |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 90 | self.assertNotEqual(display, os.environ.get('DISPLAY','None')) |
| 91 | |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 92 | def tearDown(self): |
| 93 | super(XvfbLinuxTest, self).tearDown() |
| 94 | for procin self._procs: |
| 95 | if proc.stdout: |
| 96 | proc.stdout.close() |
| 97 | |
| 98 | |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 99 | classXvfbTest(unittest.TestCase): |
| 100 | |
| 101 | def setUp(self): |
| 102 | super(XvfbTest, self).setUp() |
| 103 | if sys.platform=='win32': |
| 104 | self.skipTest('non-win32 test') |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 105 | self._proc=None |
| 106 | |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 107 | def test_send_sigint(self): |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 108 | self._proc= launch_process(['--sleep']) |
Erik Staab | 3e50f0c7 | 2022-12-13 22:58:25 | [diff] [blame] | 109 | # Give time for subprocess to install signal handlers |
| 110 | time.sleep(.3) |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 111 | send_signal(self._proc, signal.SIGINT,1) |
| 112 | sig= read_subprocess_message(self._proc,'Signal :') |
Ben Pastene | b5c6726 | 2024-05-15 21:24:01 | [diff] [blame] | 113 | self.assertIsNotNone(sig)# OpenBox likely failed to start |
Joshua Hood | 3fade1f | 2022-05-04 16:00:42 | [diff] [blame] | 114 | self.assertEqual(int(sig), int(signal.SIGINT)) |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 115 | |
| 116 | def test_send_sigterm(self): |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 117 | self._proc= launch_process(['--sleep']) |
Erik Staab | 3e50f0c7 | 2022-12-13 22:58:25 | [diff] [blame] | 118 | # Give time for subprocess to install signal handlers |
| 119 | time.sleep(.3) |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 120 | send_signal(self._proc, signal.SIGTERM,1) |
| 121 | sig= read_subprocess_message(self._proc,'Signal :') |
Ben Pastene | b5c6726 | 2024-05-15 21:24:01 | [diff] [blame] | 122 | self.assertIsNotNone(sig)# OpenBox likely failed to start |
Joshua Hood | 3fade1f | 2022-05-04 16:00:42 | [diff] [blame] | 123 | self.assertEqual(int(sig), int(signal.SIGTERM)) |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 124 | |
Joshua Hood | 7bd58233 | 2022-05-10 21:35:21 | [diff] [blame] | 125 | def tearDown(self): |
| 126 | super(XvfbTest, self).tearDown() |
| 127 | if self._proc.stdout: |
| 128 | self._proc.stdout.close() |
| 129 | |
Ben Pastene | b5c6726 | 2024-05-15 21:24:01 | [diff] [blame] | 130 | |
Ilia Samsonov | a0083530 | 2019-04-19 17:37:59 | [diff] [blame] | 131 | if __name__=='__main__': |
| 132 | unittest.main() |