Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | # Copyright (c) 2013 The Chromium OS 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. |
| 5 | # pylint: disable-msg=C0111 |
| 6 | |
| 7 | import os, unittest |
| 8 | import mox |
| 9 | import common |
Aviv Keshet | 8268313 | 2013-06-18 10:44:41 -0700 | [diff] [blame] | 10 | import subprocess |
Aviv Keshet | 7cd1231 | 2013-07-25 10:25:55 -0700 | [diff] [blame] | 11 | import types |
Fang Deng | 2db9676 | 2013-10-03 16:45:31 -0700 | [diff] [blame] | 12 | from autotest_lib.server import utils |
| 13 | from autotest_lib.server.cros.dynamic_suite import constants |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 14 | from autotest_lib.site_utils import test_that |
| 15 | |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 16 | |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 17 | class StartsWithList(mox.Comparator): |
| 18 | def __init__(self, start_of_list): |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 19 | """Mox comparator which returns True if the argument |
| 20 | to the mocked function is a list that begins with the elements |
| 21 | in start_of_list. |
| 22 | """ |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 23 | self._lhs = start_of_list |
| 24 | |
| 25 | def equals(self, rhs): |
| 26 | if len(rhs)<len(self._lhs): |
| 27 | return False |
Fang Deng | 9a84123 | 2013-09-17 16:29:14 -0700 | [diff] [blame] | 28 | for (x, y) in zip(self._lhs, rhs): |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 29 | if x != y: |
| 30 | return False |
| 31 | return True |
| 32 | |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 33 | |
| 34 | class ContainsSublist(mox.Comparator): |
| 35 | def __init__(self, sublist): |
| 36 | """Mox comparator which returns True if the argument |
| 37 | to the mocked function is a list that contains sublist |
| 38 | as a sub-list. |
| 39 | """ |
| 40 | self._sublist = sublist |
| 41 | |
| 42 | def equals(self, rhs): |
| 43 | n = len(self._sublist) |
| 44 | if len(rhs)<n: |
| 45 | return False |
| 46 | return any((self._sublist == rhs[i:i+n]) |
| 47 | for i in xrange(len(rhs) - n + 1)) |
| 48 | |
| 49 | |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 50 | class TestThatUnittests(unittest.TestCase): |
| 51 | def test_validate_arguments(self): |
| 52 | # Deferred until validate_arguments allows for lab runs. |
| 53 | pass |
| 54 | |
| 55 | def test_parse_arguments(self): |
| 56 | args = test_that.parse_arguments( |
| 57 | ['-b', 'some_board', '-i', 'some_image', '--args', 'some_args', |
| 58 | 'some_remote', 'test1', 'test2']) |
| 59 | self.assertEqual('some_board', args.board) |
| 60 | self.assertEqual('some_image', args.build) |
| 61 | self.assertEqual('some_args', args.args) |
| 62 | self.assertEqual('some_remote', args.remote) |
| 63 | self.assertEqual(['test1', 'test2'], args.tests) |
| 64 | |
Aviv Keshet | 20b20c7 | 2014-04-02 11:54:28 -0700 | [diff] [blame] | 65 | def test_fetch_local_suite(self): |
| 66 | # Deferred until fetch_local_suite knows about non-local builds. |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 67 | pass |
| 68 | |
Aviv Keshet | 7cd1231 | 2013-07-25 10:25:55 -0700 | [diff] [blame] | 69 | def test_get_predicate_for_test_arg(self): |
| 70 | # Assert the type signature of get_predicate_for_test(...) |
| 71 | # Because control.test_that_wrapper calls this function, |
| 72 | # it is imperative for backwards compatilbility that |
| 73 | # the return type of the tested function does not change. |
| 74 | tests = ['dummy_test', 'e:name_expression', 'f:expression', |
| 75 | 'suite:suitename'] |
| 76 | for test in tests: |
| 77 | pred, desc = test_that.get_predicate_for_test_arg(test) |
| 78 | self.assertTrue(isinstance(pred, types.FunctionType)) |
| 79 | self.assertTrue(isinstance(desc, str)) |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 80 | |
| 81 | def test_run_job(self): |
| 82 | class Object(): |
| 83 | pass |
| 84 | |
| 85 | autotest_path = 'htap_tsetotua' |
| 86 | autoserv_command = os.path.join(autotest_path, 'server', 'autoserv') |
| 87 | remote = 'etomer' |
Aviv Keshet | c882440 | 2013-06-29 20:37:30 -0700 | [diff] [blame] | 88 | results_dir = '/tmp/fakeresults' |
Christopher Wiley | f6b5aae | 2013-07-09 10:14:02 -0700 | [diff] [blame] | 89 | fast_mode = False |
Aviv Keshet | ad7e34e | 2013-08-19 18:09:27 -0700 | [diff] [blame] | 90 | job1_results_dir = '/tmp/fakeresults/results-1-gilbert' |
| 91 | job2_results_dir = '/tmp/fakeresults/results-2-sullivan' |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 92 | args = 'matey' |
| 93 | expected_args_sublist = ['--args', args] |
Fang Deng | 2db9676 | 2013-10-03 16:45:31 -0700 | [diff] [blame] | 94 | experimental_keyval = {constants.JOB_EXPERIMENTAL_KEY: False} |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 95 | self.mox = mox.Mox() |
| 96 | |
| 97 | # Create some dummy job objects. |
| 98 | job1 = Object() |
| 99 | job2 = Object() |
| 100 | setattr(job1, 'control_type', 'cLiEnT') |
| 101 | setattr(job1, 'control_file', 'c1') |
Aviv Keshet | c882440 | 2013-06-29 20:37:30 -0700 | [diff] [blame] | 102 | setattr(job1, 'id', 1) |
Aviv Keshet | ad7e34e | 2013-08-19 18:09:27 -0700 | [diff] [blame] | 103 | setattr(job1, 'name', 'gilbert') |
Fang Deng | 2db9676 | 2013-10-03 16:45:31 -0700 | [diff] [blame] | 104 | setattr(job1, 'keyvals', experimental_keyval) |
Aviv Keshet | ad7e34e | 2013-08-19 18:09:27 -0700 | [diff] [blame] | 105 | |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 106 | setattr(job2, 'control_type', 'Server') |
| 107 | setattr(job2, 'control_file', 'c2') |
Aviv Keshet | c882440 | 2013-06-29 20:37:30 -0700 | [diff] [blame] | 108 | setattr(job2, 'id', 2) |
Aviv Keshet | ad7e34e | 2013-08-19 18:09:27 -0700 | [diff] [blame] | 109 | setattr(job2, 'name', 'sullivan') |
Fang Deng | 2db9676 | 2013-10-03 16:45:31 -0700 | [diff] [blame] | 110 | setattr(job2, 'keyvals', experimental_keyval) |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 111 | |
Aviv Keshet | 5e33c17 | 2013-07-16 05:00:49 -0700 | [diff] [blame] | 112 | id_digits = 1 |
| 113 | |
Aviv Keshet | 8268313 | 2013-06-18 10:44:41 -0700 | [diff] [blame] | 114 | # Stub out subprocess.Popen and wait calls. |
| 115 | # Make them expect correct arguments. |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 116 | def fake_readline(): |
| 117 | return b'' |
Aviv Keshet | 8268313 | 2013-06-18 10:44:41 -0700 | [diff] [blame] | 118 | mock_process_1 = self.mox.CreateMock(subprocess.Popen) |
| 119 | mock_process_2 = self.mox.CreateMock(subprocess.Popen) |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 120 | fake_stdout = self.mox.CreateMock(file) |
Fang Deng | 9a84123 | 2013-09-17 16:29:14 -0700 | [diff] [blame] | 121 | fake_returncode = 0 |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 122 | mock_process_1.stdout = fake_stdout |
Fang Deng | 9a84123 | 2013-09-17 16:29:14 -0700 | [diff] [blame] | 123 | mock_process_1.returncode = fake_returncode |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 124 | mock_process_2.stdout = fake_stdout |
Fang Deng | 9a84123 | 2013-09-17 16:29:14 -0700 | [diff] [blame] | 125 | mock_process_2.returncode = fake_returncode |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 126 | |
Fang Deng | 2db9676 | 2013-10-03 16:45:31 -0700 | [diff] [blame] | 127 | self.mox.StubOutWithMock(os, 'makedirs') |
| 128 | self.mox.StubOutWithMock(utils, 'write_keyval') |
Aviv Keshet | 8268313 | 2013-06-18 10:44:41 -0700 | [diff] [blame] | 129 | self.mox.StubOutWithMock(subprocess, 'Popen') |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 130 | |
Fang Deng | 2db9676 | 2013-10-03 16:45:31 -0700 | [diff] [blame] | 131 | os.makedirs(job1_results_dir) |
| 132 | utils.write_keyval(job1_results_dir, experimental_keyval) |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 133 | arglist_1 = [autoserv_command, '-p', '-r', job1_results_dir, |
Aviv Keshet | ad7e34e | 2013-08-19 18:09:27 -0700 | [diff] [blame] | 134 | '-m', remote, '--no_console_prefix', '-l', 'gilbert', |
| 135 | '-c'] |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 136 | subprocess.Popen(mox.And(StartsWithList(arglist_1), |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 137 | ContainsSublist(expected_args_sublist)), |
| 138 | stdout=subprocess.PIPE, |
| 139 | stderr=subprocess.STDOUT |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 140 | ).AndReturn(mock_process_1) |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 141 | mock_process_1.stdout.readline().AndReturn(b'') |
Aviv Keshet | 8268313 | 2013-06-18 10:44:41 -0700 | [diff] [blame] | 142 | mock_process_1.wait() |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 143 | |
Fang Deng | 2db9676 | 2013-10-03 16:45:31 -0700 | [diff] [blame] | 144 | os.makedirs(job2_results_dir) |
| 145 | utils.write_keyval(job2_results_dir, experimental_keyval) |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 146 | arglist_2 = [autoserv_command, '-p', '-r', job2_results_dir, |
Aviv Keshet | ad7e34e | 2013-08-19 18:09:27 -0700 | [diff] [blame] | 147 | '-m', remote, '--no_console_prefix', '-l', 'sullivan', |
| 148 | '-s'] |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 149 | subprocess.Popen(mox.And(StartsWithList(arglist_2), |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 150 | ContainsSublist(expected_args_sublist)), |
| 151 | stdout=subprocess.PIPE, |
| 152 | stderr=subprocess.STDOUT |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 153 | ).AndReturn(mock_process_2) |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 154 | mock_process_2.stdout.readline().AndReturn(b'') |
Aviv Keshet | 8268313 | 2013-06-18 10:44:41 -0700 | [diff] [blame] | 155 | mock_process_2.wait() |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 156 | |
| 157 | # Test run_job. |
| 158 | self.mox.ReplayAll() |
Christopher Wiley | f6b5aae | 2013-07-09 10:14:02 -0700 | [diff] [blame] | 159 | job_res = test_that.run_job(job1, remote, autotest_path, results_dir, |
Aviv Keshet | 6a704f7 | 2013-09-04 14:57:43 -0700 | [diff] [blame] | 160 | fast_mode, id_digits, 0, None, args) |
Aviv Keshet | c882440 | 2013-06-29 20:37:30 -0700 | [diff] [blame] | 161 | self.assertEqual(job_res, job1_results_dir) |
Christopher Wiley | f6b5aae | 2013-07-09 10:14:02 -0700 | [diff] [blame] | 162 | job_res = test_that.run_job(job2, remote, autotest_path, results_dir, |
Aviv Keshet | 6a704f7 | 2013-09-04 14:57:43 -0700 | [diff] [blame] | 163 | fast_mode, id_digits, 0, None, args) |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 164 | |
Aviv Keshet | c882440 | 2013-06-29 20:37:30 -0700 | [diff] [blame] | 165 | self.assertEqual(job_res, job2_results_dir) |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 166 | self.mox.UnsetStubs() |
| 167 | self.mox.VerifyAll() |
| 168 | self.mox.ResetAll() |
| 169 | |
| 170 | |
| 171 | def test_perform_local_run(self): |
| 172 | afe = test_that.setup_local_afe() |
| 173 | autotest_path = 'ottotest_path' |
| 174 | suite_name = 'sweet_name' |
| 175 | remote = 'remoat' |
Aviv Keshet | 1071196 | 2013-06-24 12:20:33 -0700 | [diff] [blame] | 176 | build = 'bild' |
| 177 | board = 'bored' |
Christopher Wiley | f6b5aae | 2013-07-09 10:14:02 -0700 | [diff] [blame] | 178 | fast_mode = False |
Fang Deng | 9a84123 | 2013-09-17 16:29:14 -0700 | [diff] [blame] | 179 | suite_control_files = ['c1', 'c2', 'c3', 'c4'] |
Aviv Keshet | c882440 | 2013-06-29 20:37:30 -0700 | [diff] [blame] | 180 | results_dir = '/tmp/test_that_results_fake' |
Aviv Keshet | 5e33c17 | 2013-07-16 05:00:49 -0700 | [diff] [blame] | 181 | id_digits = 1 |
Fang Deng | 9a84123 | 2013-09-17 16:29:14 -0700 | [diff] [blame] | 182 | ssh_verbosity = 2 |
Aviv Keshet | 6a704f7 | 2013-09-04 14:57:43 -0700 | [diff] [blame] | 183 | ssh_options = '-F /dev/null -i /dev/null' |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 184 | args = 'matey' |
Fang Deng | b1da830 | 2013-09-24 13:57:54 -0700 | [diff] [blame] | 185 | ignore_deps = False |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 186 | |
Aviv Keshet | 20b20c7 | 2014-04-02 11:54:28 -0700 | [diff] [blame] | 187 | # Fake suite objects that will be returned by fetch_local_suite |
| 188 | class fake_suite(object): |
| 189 | def __init__(self, suite_control_files, hosts): |
| 190 | self._suite_control_files = suite_control_files |
| 191 | self._hosts = hosts |
| 192 | |
| 193 | def schedule(self, *args, **kwargs): |
| 194 | for control_file in self._suite_control_files: |
| 195 | afe.create_job(control_file, hosts=self._hosts) |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 196 | |
| 197 | # Mock out scheduling of suite and running of jobs. |
| 198 | self.mox = mox.Mox() |
Aviv Keshet | 1de5bc6 | 2013-08-19 14:19:26 -0700 | [diff] [blame] | 199 | |
Aviv Keshet | 20b20c7 | 2014-04-02 11:54:28 -0700 | [diff] [blame] | 200 | self.mox.StubOutWithMock(test_that, 'fetch_local_suite') |
| 201 | test_that.fetch_local_suite(autotest_path, mox.IgnoreArg(), |
Fang Deng | b1da830 | 2013-09-24 13:57:54 -0700 | [diff] [blame] | 202 | afe, remote=remote, build=build, |
Aviv Keshet | e9170d9 | 2013-07-19 11:20:45 -0700 | [diff] [blame] | 203 | board=board, results_directory=results_dir, |
Aviv Keshet | 20b20c7 | 2014-04-02 11:54:28 -0700 | [diff] [blame] | 204 | no_experimental=False, |
| 205 | ignore_deps=ignore_deps |
| 206 | ).AndReturn(fake_suite(suite_control_files, [remote])) |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 207 | self.mox.StubOutWithMock(test_that, 'run_job') |
Fang Deng | 9a84123 | 2013-09-17 16:29:14 -0700 | [diff] [blame] | 208 | self.mox.StubOutWithMock(test_that, 'run_provisioning_job') |
Fang Deng | b1da830 | 2013-09-24 13:57:54 -0700 | [diff] [blame] | 209 | self.mox.StubOutWithMock(test_that, '_auto_detect_labels') |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 210 | |
Fang Deng | a6d597a | 2013-10-10 13:58:42 -0700 | [diff] [blame] | 211 | test_that._auto_detect_labels(afe, remote) |
Fang Deng | b1da830 | 2013-09-24 13:57:54 -0700 | [diff] [blame] | 212 | # Test perform_local_run. Enforce that run_provisioning_job, |
| 213 | # run_job and _auto_detect_labels are called correctly. |
Fang Deng | 9a84123 | 2013-09-17 16:29:14 -0700 | [diff] [blame] | 214 | test_that.run_provisioning_job( |
| 215 | 'cros-version:' + build, remote, autotest_path, |
| 216 | results_dir, fast_mode, |
| 217 | ssh_verbosity, ssh_options, |
| 218 | False, False) |
| 219 | |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 220 | for control_file in suite_control_files: |
| 221 | test_that.run_job(mox.ContainsAttributeValue('control_file', |
Christopher Wiley | f6b5aae | 2013-07-09 10:14:02 -0700 | [diff] [blame] | 222 | control_file), |
Aviv Keshet | 5e33c17 | 2013-07-16 05:00:49 -0700 | [diff] [blame] | 223 | remote, autotest_path, results_dir, fast_mode, |
Aviv Keshet | 6a704f7 | 2013-09-04 14:57:43 -0700 | [diff] [blame] | 224 | id_digits, ssh_verbosity, ssh_options, |
| 225 | args, False, False) |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 226 | self.mox.ReplayAll() |
| 227 | test_that.perform_local_run(afe, autotest_path, ['suite:'+suite_name], |
Aviv Keshet | 30322f9 | 2013-07-18 13:21:52 -0700 | [diff] [blame] | 228 | remote, fast_mode, build=build, board=board, |
Fang Deng | a6d597a | 2013-10-10 13:58:42 -0700 | [diff] [blame] | 229 | ignore_deps=False, |
Aviv Keshet | 6a704f7 | 2013-09-04 14:57:43 -0700 | [diff] [blame] | 230 | ssh_verbosity=ssh_verbosity, |
| 231 | ssh_options=ssh_options, |
| 232 | args=args, |
Aviv Keshet | e43bccf | 2013-08-14 14:11:59 -0700 | [diff] [blame] | 233 | results_directory=results_dir) |
Aviv Keshet | d4a0430 | 2013-04-30 15:48:30 -0700 | [diff] [blame] | 234 | self.mox.UnsetStubs() |
| 235 | self.mox.VerifyAll() |
| 236 | |
| 237 | |
| 238 | if __name__ == '__main__': |
| 239 | unittest.main() |