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