2 # Copyright 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """The test controller for the chromoting localhost browser_tests.
8 This test uses the legion framework to setup this controller which will run
9 the chromoting_browser_tests on a task machine. This is intended to
10 be an example Legion-based test for the chromoting team.
12 The controller will start a task machine to run browser_tests_launcher on. The
13 output of these tests are streamed back to the test controller to be output
14 on the controller's stdout and stderr channels. The final test output is then
15 read and becomes the final output of the controller, mirroring the test's
25 # Map the legion directory so we can import the host controller.
26 SRC_DIR
= os
.path
.join('..', '..', '..')
27 sys
.path
.append(os
.path
.join(SRC_DIR
, 'testing'))
28 from legion
import test_controller
31 class ExampleController(test_controller
.TestController
):
32 """The test controller for the Chromoting browser_tests."""
35 super(ExampleController
, self
).__init
__()
40 """Main method to run the test code."""
43 self
.TestIntegrationTests()
45 def CreateBrowserTestsLauncherCommand(self
):
48 self
.TaskAbsPath('../browser_tests_launcher.py'),
49 '--commands_file', self
.TaskAbsPath(self
.args
.commands_file
),
50 '--prod_dir', self
.TaskAbsPath(self
.args
.prod_dir
),
51 '--cfg_file', self
.TaskAbsPath(self
.args
.cfg_file
),
52 '--me2me_manifest_file', self
.TaskAbsPath(
53 self
.args
.me2me_manifest_file
),
54 '--it2me_manifest_file', self
.TaskAbsPath(
55 self
.args
.it2me_manifest_file
),
56 '--user_profile_dir', self
.args
.user_profile_dir
,
59 def TaskAbsPath(self
, path
):
60 """Returns the absolute path to the resource on the task machine.
63 path: The relative path to the resource.
65 Since the test controller and the task machines run in different tmp dirs
66 on different machines the absolute path cannot be calculated correctly on
67 this machine. This function maps the relative path (from this directory)
68 to an absolute path on the task machine.
70 return self
.task
.rpc
.AbsPath(path
)
73 """Creates a task object and sets the proper values."""
74 self
.task
= self
.CreateNewTask(
75 isolated_hash
=self
.args
.task_machine
,
76 dimensions
={'os': 'Ubuntu-14.04', 'pool': 'Chromoting'})
78 self
.task
.WaitForConnection()
81 """Gets the command line args."""
82 parser
= argparse
.ArgumentParser()
83 parser
.add_argument('--task_machine',
84 help='isolated hash of the task machine.')
85 # The rest of the args are taken from
86 # testing/chromoting/browser_tests_launcher.py.
87 parser
.add_argument('-f', '--commands_file',
88 help='path to file listing commands to be launched.')
89 parser
.add_argument('-p', '--prod_dir',
90 help='path to folder having product and test binaries.')
91 parser
.add_argument('-c', '--cfg_file',
92 help='path to test host config file.')
93 parser
.add_argument('--me2me_manifest_file',
94 help='path to me2me host manifest file.')
95 parser
.add_argument('--it2me_manifest_file',
96 help='path to it2me host manifest file.')
98 '-u', '--user_profile_dir',
99 help='path to user-profile-dir, used by connect-to-host tests.')
100 self
.args
, _
= parser
.parse_known_args()
102 def TestIntegrationTests(self
):
103 """Runs the integration tests via browser_tests_launcher.py."""
104 # Create a process object, configure it, and start it.
105 # All interactions with the process are based on this "proc" key.
106 proc
= self
.task
.rpc
.subprocess
.Process(
107 self
.CreateBrowserTestsLauncherCommand())
108 # Set the cwd to browser_tests_launcher relative to this directory.
109 # This allows browser_test_launcher to use relative paths.
110 self
.task
.rpc
.subprocess
.SetCwd(proc
, '../')
111 # Set the task verbosity to true to allow stdout/stderr to be echo'ed to
112 # run_task's stdout/stderr on the task machine. This can assist in
114 self
.task
.rpc
.subprocess
.SetVerbose(proc
)
115 # Set the process as detached to create it in a new process group.
116 self
.task
.rpc
.subprocess
.SetDetached(proc
)
117 # Start the actual process on the task machine.
118 self
.task
.rpc
.subprocess
.Start(proc
)
120 # Collect the stdout/stderr and emit it from this controller while the
121 # process is running.
122 while self
.task
.rpc
.subprocess
.Poll(proc
) is None:
123 # Output the test's stdout and stderr in semi-realtime.
124 # This is not true realtime due to the RPC calls and the 1s sleep.
125 stdout
, stderr
= self
.task
.rpc
.subprocess
.ReadOutput(proc
)
127 sys
.stdout
.write(stdout
)
129 sys
.stderr
.write(stderr
)
132 # Get the return code, clean up the process object.
133 returncode
= self
.task
.rpc
.subprocess
.GetReturncode(proc
)
134 self
.task
.rpc
.subprocess
.Delete(proc
)
136 # Pass or fail depending on the return code from the browser_tests_launcher.
138 raise AssertionError('browser_tests_launcher failed with return code '
142 if __name__
== '__main__':
143 ExampleController().RunController()