blob: 3db425c94b6be088356e6510c39286c3c31c66b5 [file] [log] [blame]
Ilia Samsonova00835302019-04-19 17:37:591#!/usr/bin/env python
Avi Drissmandfd880852022-09-15 20:11:092# Copyright 2019 The Chromium Authors
Ilia Samsonova00835302019-04-19 17:37:593# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
Ilia Samsonova00835302019-04-19 17:37:595"""Unit tests for xvfb.py functionality.
6
7Each unit test is launching xvfb_test_script.py
8through xvfb.py as a subprocess, then tests its expected output.
9"""
10
11import os
12import signal
13import subprocess
14import sys
15import time
16import unittest
17
Joshua Hood3fade1f2022-05-04 16:00:4218# pylint: disable=super-with-arguments
19
Ilia Samsonova00835302019-04-19 17:37:5920TEST_FILE = __file__.replace('.pyc', '.py')
21XVFB = TEST_FILE.replace('_unittest', '')
22XVFB_TEST_SCRIPT = TEST_FILE.replace('_unittest', '_test_script')
23
24
25def launch_process(args):
26 """Launches a sub process to run through xvfb.py."""
Ben Pasteneb5c67262024-05-15 21:24:0127 return subprocess.Popen([XVFB, XVFB_TEST_SCRIPT] + args,
28 stdout=subprocess.PIPE,
29 stderr=subprocess.STDOUT,
30 env=os.environ.copy())
Ilia Samsonova00835302019-04-19 17:37:5931
32
Joshua Hood3fade1f2022-05-04 16:00:4233# pylint: disable=inconsistent-return-statements
Ilia Samsonova00835302019-04-19 17:37:5934def read_subprocess_message(proc, starts_with):
35 """Finds the value after first line prefix condition."""
Joshua Hood3fade1f2022-05-04 16:00:4236 for line in proc.stdout.read().decode('utf-8').splitlines(True):
37 if str(line).startswith(starts_with):
Ilia Samsonova00835302019-04-19 17:37:5938 return line.rstrip().replace(starts_with, '')
Ben Pasteneb5c67262024-05-15 21:24:0139
40
Joshua Hood3fade1f2022-05-04 16:00:4241# pylint: enable=inconsistent-return-statements
Ilia Samsonova00835302019-04-19 17:37:5942
43
44def 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
51class XvfbLinuxTest(unittest.TestCase):
52
53 def setUp(self):
54 super(XvfbLinuxTest, self).setUp()
Joshua Hood3fade1f2022-05-04 16:00:4255 if not sys.platform.startswith('linux'):
Ilia Samsonova00835302019-04-19 17:37:5956 self.skipTest('linux only test')
Joshua Hood7bd582332022-05-10 21:35:2157 self._procs = []
Ilia Samsonova00835302019-04-19 17:37:5958
59 def test_no_xvfb_display(self):
Joshua Hood7bd582332022-05-10 21:35:2160 self._procs.append(launch_process(['--no-xvfb']))
61 self._procs[0].wait()
62 display = read_subprocess_message(self._procs[0], 'Display :')
Ilia Samsonova00835302019-04-19 17:37:5963 self.assertEqual(display, os.environ.get('DISPLAY', 'None'))
64
65 def test_xvfb_display(self):
Joshua Hood7bd582332022-05-10 21:35:2166 self._procs.append(launch_process([]))
67 self._procs[0].wait()
68 display = read_subprocess_message(self._procs[0], 'Display :')
Ben Pasteneb5c67262024-05-15 21:24:0169 self.assertIsNotNone(display) # Openbox likely failed to open DISPLAY
Ilia Samsonova00835302019-04-19 17:37:5970 self.assertNotEqual(display, os.environ.get('DISPLAY', 'None'))
71
72 def test_no_xvfb_flag(self):
Joshua Hood7bd582332022-05-10 21:35:2173 self._procs.append(launch_process(['--no-xvfb']))
74 self._procs[0].wait()
Ilia Samsonova00835302019-04-19 17:37:5975
76 def test_xvfb_flag(self):
Joshua Hood7bd582332022-05-10 21:35:2177 self._procs.append(launch_process([]))
78 self._procs[0].wait()
Ilia Samsonova00835302019-04-19 17:37:5979
Brian Sheedy0d2300f32024-08-13 23:14:4180 @unittest.skip('flaky; crbug.com/1320399')
Ilia Samsonova00835302019-04-19 17:37:5981 def test_xvfb_race_condition(self):
Joshua Hood7bd582332022-05-10 21:35:2182 self._procs = [launch_process([]) for _ in range(15)]
83 for proc in self._procs:
Ilia Samsonova00835302019-04-19 17:37:5984 proc.wait()
Ben Pasteneb5c67262024-05-15 21:24:0185 display_list = [
86 read_subprocess_message(p, 'Display :') for p in self._procs
87 ]
Ilia Samsonova00835302019-04-19 17:37:5988 for display in display_list:
Ben Pasteneb5c67262024-05-15 21:24:0189 self.assertIsNotNone(display) # Openbox likely failed to open DISPLAY
Ilia Samsonova00835302019-04-19 17:37:5990 self.assertNotEqual(display, os.environ.get('DISPLAY', 'None'))
91
Joshua Hood7bd582332022-05-10 21:35:2192 def tearDown(self):
93 super(XvfbLinuxTest, self).tearDown()
94 for proc in self._procs:
95 if proc.stdout:
96 proc.stdout.close()
97
98
Ilia Samsonova00835302019-04-19 17:37:5999class XvfbTest(unittest.TestCase):
100
101 def setUp(self):
102 super(XvfbTest, self).setUp()
103 if sys.platform == 'win32':
104 self.skipTest('non-win32 test')
Joshua Hood7bd582332022-05-10 21:35:21105 self._proc = None
106
Ilia Samsonova00835302019-04-19 17:37:59107 def test_send_sigint(self):
Joshua Hood7bd582332022-05-10 21:35:21108 self._proc = launch_process(['--sleep'])
Erik Staab3e50f0c72022-12-13 22:58:25109 # Give time for subprocess to install signal handlers
110 time.sleep(.3)
Joshua Hood7bd582332022-05-10 21:35:21111 send_signal(self._proc, signal.SIGINT, 1)
112 sig = read_subprocess_message(self._proc, 'Signal :')
Ben Pasteneb5c67262024-05-15 21:24:01113 self.assertIsNotNone(sig) # OpenBox likely failed to start
Joshua Hood3fade1f2022-05-04 16:00:42114 self.assertEqual(int(sig), int(signal.SIGINT))
Ilia Samsonova00835302019-04-19 17:37:59115
116 def test_send_sigterm(self):
Joshua Hood7bd582332022-05-10 21:35:21117 self._proc = launch_process(['--sleep'])
Erik Staab3e50f0c72022-12-13 22:58:25118 # Give time for subprocess to install signal handlers
119 time.sleep(.3)
Joshua Hood7bd582332022-05-10 21:35:21120 send_signal(self._proc, signal.SIGTERM, 1)
121 sig = read_subprocess_message(self._proc, 'Signal :')
Ben Pasteneb5c67262024-05-15 21:24:01122 self.assertIsNotNone(sig) # OpenBox likely failed to start
Joshua Hood3fade1f2022-05-04 16:00:42123 self.assertEqual(int(sig), int(signal.SIGTERM))
Ilia Samsonova00835302019-04-19 17:37:59124
Joshua Hood7bd582332022-05-10 21:35:21125 def tearDown(self):
126 super(XvfbTest, self).tearDown()
127 if self._proc.stdout:
128 self._proc.stdout.close()
129
Ben Pasteneb5c67262024-05-15 21:24:01130
Ilia Samsonova00835302019-04-19 17:37:59131if __name__ == '__main__':
132 unittest.main()