1 # Copyright (C) 2012 Zan Dobersek <zandobersek@gmail.com>
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 import unittest2 as unittest
32 from webkitpy.common.system.filesystem_mock import MockFileSystem
33 from webkitpy.common.system.executive_mock import MockExecutive2
34 from webkitpy.common.system.outputcapture import OutputCapture
35 from webkitpy.common.system.systemhost_mock import MockSystemHost
36 from webkitpy.port import Port
37 from webkitpy.port.server_process_mock import MockServerProcess
38 from webkitpy.port.xvfbdriver import XvfbDriver
39 from webkitpy.tool.mocktool import MockOptions
41 _log = logging.getLogger(__name__)
44 class XvfbDriverTest(unittest.TestCase):
45 def make_driver(self, worker_number=0, xorg_running=False, executive=None):
46 port = Port(MockSystemHost(log_executive=True, executive=executive), 'xvfbdrivertestport', options=MockOptions(configuration='Release'))
47 port._config.build_directory = lambda configuration: "/mock-build"
48 port._server_process_constructor = MockServerProcess
50 port._executive._running_pids['Xorg'] = 108
52 driver = XvfbDriver(port, worker_number=worker_number, pixel_tests=True)
53 driver._startup_delay_secs = 0
54 driver._xvfb_screen_depth = lambda: '24'
57 def cleanup_driver(self, driver):
58 # Setting _xvfb_process member to None is necessary as the Driver object is stopped on deletion,
59 # killing the Xvfb process if present. Thus, this method should only be called from tests that do not
60 # intend to test the behavior of XvfbDriver.stop.
61 driver._xvfb_process = None
63 def assertDriverStartSuccessful(self, driver, expected_logs, expected_display, pixel_tests=False):
64 OutputCapture().assert_outputs(self, driver.start, [pixel_tests, []], expected_logs=expected_logs)
65 self.assertTrue(driver._server_process.started)
66 self.assertEqual(driver._server_process.env["DISPLAY"], expected_display)
68 def test_start_no_pixel_tests(self):
69 driver = self.make_driver()
70 expected_logs = "MOCK run_command: ['ps', '-eo', 'comm,command'], cwd=None\nMOCK popen: ['Xvfb', ':0', '-screen', '0', '1024x768x24', '-nolisten', 'tcp']\n"
71 self.assertDriverStartSuccessful(driver, expected_logs=expected_logs, expected_display=":0")
72 self.cleanup_driver(driver)
74 def test_start_pixel_tests(self):
75 driver = self.make_driver()
76 expected_logs = "MOCK run_command: ['ps', '-eo', 'comm,command'], cwd=None\nMOCK popen: ['Xvfb', ':0', '-screen', '0', '1024x768x24', '-nolisten', 'tcp']\n"
77 self.assertDriverStartSuccessful(driver, expected_logs=expected_logs, expected_display=":0", pixel_tests=True)
78 self.cleanup_driver(driver)
80 def test_start_arbitrary_worker_number(self):
81 driver = self.make_driver(worker_number=17)
82 expected_logs = "MOCK run_command: ['ps', '-eo', 'comm,command'], cwd=None\nMOCK popen: ['Xvfb', ':0', '-screen', '0', '1024x768x24', '-nolisten', 'tcp']\n"
83 self.assertDriverStartSuccessful(driver, expected_logs=expected_logs, expected_display=":0", pixel_tests=True)
84 self.cleanup_driver(driver)
86 def test_next_free_display(self):
87 output = "Xorg /usr/bin/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch -background none\nXvfb Xvfb :1 -screen 0 800x600x24 -nolisten tcp"
88 executive = MockExecutive2(output)
89 driver = self.make_driver(executive=executive)
90 self.assertEqual(driver._next_free_display(), 2)
91 self.cleanup_driver(driver)
92 output = "X /usr/bin/X :0 vt7 -nolisten tcp -auth /var/run/xauth/A:0-8p7Ybb"
93 executive = MockExecutive2(output)
94 driver = self.make_driver(executive=executive)
95 self.assertEqual(driver._next_free_display(), 1)
96 self.cleanup_driver(driver)
97 output = "Xvfb Xvfb :0 -screen 0 800x600x24 -nolisten tcp"
98 executive = MockExecutive2(output)
99 driver = self.make_driver(executive=executive)
100 self.assertEqual(driver._next_free_display(), 1)
101 self.cleanup_driver(driver)
102 output = "Xvfb Xvfb :1 -screen 0 800x600x24 -nolisten tcp\nXvfb Xvfb :0 -screen 0 800x600x24 -nolisten tcp\nXvfb Xvfb :3 -screen 0 800x600x24 -nolisten tcp"
103 executive = MockExecutive2(output)
104 driver = self.make_driver(executive=executive)
105 self.assertEqual(driver._next_free_display(), 2)
106 self.cleanup_driver(driver)
108 def test_start_next_worker(self):
109 driver = self.make_driver()
110 driver._next_free_display = lambda: 0
111 expected_logs = "MOCK popen: ['Xvfb', ':0', '-screen', '0', '1024x768x24', '-nolisten', 'tcp']\n"
112 self.assertDriverStartSuccessful(driver, expected_logs=expected_logs, expected_display=":0", pixel_tests=True)
113 self.cleanup_driver(driver)
114 driver = self.make_driver()
115 driver._next_free_display = lambda: 3
116 expected_logs = "MOCK popen: ['Xvfb', ':3', '-screen', '0', '1024x768x24', '-nolisten', 'tcp']\n"
117 self.assertDriverStartSuccessful(driver, expected_logs=expected_logs, expected_display=":3", pixel_tests=True)
118 self.cleanup_driver(driver)
121 filesystem = MockFileSystem(files={'/tmp/.X42-lock': '1234\n'})
122 port = Port(MockSystemHost(log_executive=True, filesystem=filesystem), 'xvfbdrivertestport', options=MockOptions(configuration='Release'))
123 port._executive.kill_process = lambda x: _log.info("MOCK kill_process pid: " + str(x))
124 driver = XvfbDriver(port, worker_number=0, pixel_tests=True)
126 class FakeXvfbProcess(object):
129 driver._xvfb_process = FakeXvfbProcess()
130 driver._lock_file = '/tmp/.X42-lock'
132 expected_logs = "MOCK kill_process pid: 1234\n"
133 OutputCapture().assert_outputs(self, driver.stop, [], expected_logs=expected_logs)
135 self.assertIsNone(driver._xvfb_process)
136 self.assertFalse(port._filesystem.exists(driver._lock_file))