blob: 1b2ca557f5ca48e6686cbe2b6386c661f111ac33 [file] [log] [blame]
mbligh81103b12008-06-12 19:55:37 +00001#!/usr/bin/python
mbligh7636b3a2008-06-11 15:44:01 +00002
jadmanski6bb32d72009-03-19 20:25:24 +00003import unittest, os, shutil, stat, sys, time, tempfile, warnings, pickle
mbligh7636b3a2008-06-11 15:44:01 +00004import common
mbligh084bc172008-10-18 14:02:45 +00005from autotest_lib.server import server_job, test, subcommand, hosts, autotest
mblighc6ca8102008-10-16 22:27:41 +00006from autotest_lib.client.bin import sysinfo
jadmanskifbc1f0a2008-07-09 14:12:54 +00007from autotest_lib.client.common_lib import utils, error, host_protections
showard75cdfee2009-06-10 17:40:41 +00008from autotest_lib.client.common_lib import packages, logging_manager
9from autotest_lib.client.common_lib import logging_config
mbligh7636b3a2008-06-11 15:44:01 +000010from autotest_lib.tko import db as tko_db, status_lib, utils as tko_utils
11from autotest_lib.client.common_lib.test_utils import mock
12from autotest_lib.tko.parsers import version_1 as parser_mod
13from autotest_lib.tko.parsers import version_0 as parser_mod0
mbligh7636b3a2008-06-11 15:44:01 +000014
15
mblighc6ca8102008-10-16 22:27:41 +000016class CopyLogsTest(unittest.TestCase):
mbligh7636b3a2008-06-11 15:44:01 +000017 def setUp(self):
18 self.control = "control"
19 self.args = ""
20 self.resultdir = "results"
jadmanski6bb32d72009-03-19 20:25:24 +000021 self.uncollected = "results/uncollected_logs"
mbligh7636b3a2008-06-11 15:44:01 +000022 self.label = "default"
23 self.user = "user"
24 self.machines = ('abcd1', 'abcd2', 'abcd3')
25
26 # make god
27 self.god = mock.mock_god()
28
29 # stub out some common functions
30 self.god.stub_function(os.path, 'exists')
31 self.god.stub_function(os, 'mkdir')
mblighc6ca8102008-10-16 22:27:41 +000032 self.god.stub_function(os, 'access')
33 self.god.stub_function(os, 'makedirs')
34 self.god.stub_function(os.path, 'isdir')
35 self.god.stub_function(os, 'chmod')
mbligh7636b3a2008-06-11 15:44:01 +000036 self.god.stub_function(os, 'chdir')
jadmanski779bd292009-03-19 17:33:33 +000037 self.god.stub_function(os, 'remove')
jadmanski6bb32d72009-03-19 20:25:24 +000038 self.god.stub_function(pickle, 'dump')
jadmanski10646442008-08-13 14:05:21 +000039 self.god.stub_function(server_job, 'get_site_job_data')
40 self.god.stub_function(server_job, 'open')
mbligh7636b3a2008-06-11 15:44:01 +000041 self.god.stub_function(utils, 'write_keyval')
42
showard75cdfee2009-06-10 17:40:41 +000043 logging_manager.configure_logging(logging_config.TestingConfig())
44
mblighaebe3b62008-12-22 14:45:40 +000045 self.construct_server_job()
46
mbligh7636b3a2008-06-11 15:44:01 +000047
mbligh7636b3a2008-06-11 15:44:01 +000048 def tearDown(self):
49 self.god.unstub_all()
50
51
52 def construct_server_job(self):
mblighc6ca8102008-10-16 22:27:41 +000053 # XXX(gps): These expect_call's must be kept in perfect sync
54 # call for call with what base_server_job does. This is too
55 # painful to maintain.
56
mbligh7636b3a2008-06-11 15:44:01 +000057 # setup recording for constructor
58 file_obj = self.god.create_mock_class(file, "file")
jadmanskie432dd22009-01-30 15:04:51 +000059 server_job.open.expect_call(self.control).and_return(file_obj)
mbligh7636b3a2008-06-11 15:44:01 +000060 file_obj.read.expect_call().and_return('')
jadmanskie432dd22009-01-30 15:04:51 +000061 file_obj.close.expect_call()
mbligh7636b3a2008-06-11 15:44:01 +000062 os.path.exists.expect_call(
63 mock.is_string_comparator()).and_return(False)
64 os.mkdir.expect_call(mock.is_string_comparator())
65 os.path.exists.expect_call(
66 mock.is_string_comparator()).and_return(False)
67 os.mkdir.expect_call(mock.is_string_comparator())
mblighc6ca8102008-10-16 22:27:41 +000068
69 self.god.mock_up(sysinfo, 'sysinfo')
70 sysinfo.sysinfo.expect_call(mock.is_string_comparator())
71
72 os.access.expect_call(mock.is_string_comparator(),
73 os.W_OK).and_return(False)
74 os.makedirs.expect_call(mock.is_string_comparator(), 0700)
75
76 os.access.expect_call(mock.is_string_comparator(),
77 os.W_OK).and_return(True)
78 os.path.isdir.expect_call(mock.is_string_comparator()).and_return(False)
79 self.god.stub_function(tempfile, 'gettempdir')
80 tempfile.gettempdir.expect_call().and_return('/tmp/server_job_unittest')
81 os.makedirs.expect_call(mock.is_string_comparator(),
82 0700).and_raises(os.error)
83 os.chmod.expect_call(mock.is_string_comparator(), stat.S_IRWXU)
84
jadmanski10646442008-08-13 14:05:21 +000085 cls = server_job.base_server_job
mbligh7636b3a2008-06-11 15:44:01 +000086 compare = mock.is_instance_comparator(cls)
jadmanski58962982009-04-21 19:54:34 +000087 os.path.isdir.expect_call('results').and_return(True)
88 os.path.exists.expect_call('results/keyval').and_return(False)
mblighc6ca8102008-10-16 22:27:41 +000089 server_job.get_site_job_data.expect_call(compare).and_return({})
mbligh7636b3a2008-06-11 15:44:01 +000090 utils.write_keyval.expect_call(mock.is_string_comparator(),
91 mock.is_instance_comparator(dict))
92
jadmanski10646442008-08-13 14:05:21 +000093 self.job = server_job.base_server_job(self.control,
94 self.args,
95 self.resultdir,
96 self.label,
97 self.user,
98 self.machines)
mbligh7636b3a2008-06-11 15:44:01 +000099
100 self.god.check_playback()
101
102 # use this stub alot
103 self.god.stub_function(self.job, "_execute_code")
104
105
mbligh7636b3a2008-06-11 15:44:01 +0000106 def test_init_parser(self):
mbligh7636b3a2008-06-11 15:44:01 +0000107 results = "results"
108 log = os.path.join(results, '.parse.log')
109
110 # do some additional setup
111 self.god.stub_function(tko_utils, 'redirect_parser_debugging')
112 self.god.stub_function(tko_db, 'db')
113 self.god.stub_function(status_lib, 'parser')
114
115 # set up recording
116 file_obj = self.god.create_mock_class(file, "file")
jadmanski6bb32d72009-03-19 20:25:24 +0000117 server_job.open.expect_call(log, 'w', 0).and_return(file_obj)
mbligh7636b3a2008-06-11 15:44:01 +0000118 tko_utils.redirect_parser_debugging.expect_call(file_obj)
119 db = self.god.create_mock_class(tko_db.db_sql, "db_sql")
120 tko_db.db.expect_call(autocommit=True).and_return(db)
mbligh81103b12008-06-12 19:55:37 +0000121 parser = self.god.create_mock_class(parser_mod.parser, "parser_class")
mbligh7636b3a2008-06-11 15:44:01 +0000122 status_lib.parser.expect_call(1).and_return(parser)
mbligh81103b12008-06-12 19:55:37 +0000123 job_model = self.god.create_mock_class_obj(parser_mod0.job, "pjob")
mbligh7636b3a2008-06-11 15:44:01 +0000124 parser.make_job.expect_call(results).and_return(job_model)
125 parser.start.expect_call(job_model)
126 db.find_job.expect_call(mock.is_string_comparator())
127 db.insert_job.expect_call(mock.is_string_comparator(),
128 job_model)
129
130 # run method
131 self.job.init_parser(results)
132
133 # check
134 self.god.check_playback()
135
136
mbligh084bc172008-10-18 14:02:45 +0000137 def test_fill_server_control_namespace(self):
mbligh084bc172008-10-18 14:02:45 +0000138 class MockAutotest(object):
139 job = None
140 class MockHosts(object):
141 job = None
142
143 # Verify that the job attributes are injected in the expected place.
144 self.god.stub_with(autotest, 'Autotest', MockAutotest)
145 self.god.stub_with(hosts, 'Host', MockHosts)
146 self.job._fill_server_control_namespace({})
147 self.assertEqual(hosts.Host.job, self.job)
148 self.assertEqual(autotest.Autotest.job, self.job)
149
150 test_ns = {}
151 self.job._fill_server_control_namespace(test_ns)
152
153 # Verify that a few of the expected module exports were loaded.
154 self.assertEqual(test_ns['sys'], sys)
155 self.assert_('git' in test_ns)
156 self.assert_('parallel_simple' in test_ns)
157 self.assert_('sh_escape' in test_ns)
158 self.assert_('barrier' in test_ns)
159 self.assert_('format_error' in test_ns)
160 self.assert_('AutoservRebootError' in test_ns)
161 # This should not exist, client.common_lib.errors does not export it.
162 self.assert_('format_exception' not in test_ns)
163
164 # Replacing something that exists with something else is an error.
165 orig_test_ns = {'hosts': 'not the autotest_lib.server.hosts module'}
166 test_ns = orig_test_ns.copy()
167 self.assertRaises(error.AutoservError,
168 self.job._fill_server_control_namespace, test_ns)
169
170 # Replacing something that exists with something else is an error.
171 test_ns = orig_test_ns.copy()
172 self.assertRaises(error.AutoservError,
173 self.job._fill_server_control_namespace, test_ns)
174
175 # Replacing something without protection should succeed.
176 test_ns = orig_test_ns.copy()
177 self.job._fill_server_control_namespace(test_ns, protect=False)
178 self.assertEqual(test_ns['hosts'], hosts)
179
180 # Replacing something with itself should issue a warning.
181 test_ns = {'hosts': hosts}
182 self.god.stub_function(warnings, 'showwarning')
183 warnings.showwarning.expect_call(
184 mock.is_instance_comparator(UserWarning), UserWarning,
185 mock.is_string_comparator(), mock.is_instance_comparator(int))
186 self.job._fill_server_control_namespace(test_ns)
187 self.god.check_playback()
188 self.assertEqual(test_ns['hosts'], hosts)
189
190
jadmanskic0e94602008-07-29 22:34:42 +0000191 def test_parallel_simple_with_one_machine(self):
jadmanskic0e94602008-07-29 22:34:42 +0000192 self.job.machines = ["hostname"]
mbligh7636b3a2008-06-11 15:44:01 +0000193
194 # setup
195 func = self.god.create_mock_function("wrapper")
mbligh7636b3a2008-06-11 15:44:01 +0000196
197 # record
jadmanskic0e94602008-07-29 22:34:42 +0000198 func.expect_call("hostname")
mbligh7636b3a2008-06-11 15:44:01 +0000199
200 # run and check
jadmanskic0e94602008-07-29 22:34:42 +0000201 self.job.parallel_simple(func, self.job.machines)
mbligh7636b3a2008-06-11 15:44:01 +0000202 self.god.check_playback()
203
204
mbligh7636b3a2008-06-11 15:44:01 +0000205 def test_run_test(self):
mbligh7636b3a2008-06-11 15:44:01 +0000206 # setup
mblighc5ddfd12008-08-04 17:15:00 +0000207 self.god.stub_function(self.job.pkgmgr, 'get_package_name')
mbligh7636b3a2008-06-11 15:44:01 +0000208 self.god.stub_function(test, 'runtest')
209 self.god.stub_function(self.job, 'record')
210
211 # record
212 url = "my.test.url"
213 group = "group"
214 testname = "testname"
mblighc5ddfd12008-08-04 17:15:00 +0000215 self.job.pkgmgr.get_package_name.expect_call(
216 url, 'test').and_return((group, testname))
mbligh7636b3a2008-06-11 15:44:01 +0000217 outputdir = os.path.join(self.resultdir, testname)
218 os.path.exists.expect_call(outputdir).and_return(False)
219 os.mkdir.expect_call(outputdir)
jadmanskicd95e1f2008-07-01 21:32:22 +0000220 self.job.record.expect_call('START', testname, testname)
mbligh7636b3a2008-06-11 15:44:01 +0000221 test.runtest.expect_call(self.job, url, None, (), {})
222 self.job.record.expect_call('GOOD', testname, testname,
223 'completed successfully')
jadmanskicd95e1f2008-07-01 21:32:22 +0000224 self.job.record.expect_call('END GOOD', testname, testname)
225
226 # run and check
227 self.job.run_test(url)
228 self.god.check_playback()
229
230
231 def test_run_test_with_test_error(self):
jadmanskicd95e1f2008-07-01 21:32:22 +0000232 # setup
mblighc5ddfd12008-08-04 17:15:00 +0000233 self.god.stub_function(self.job.pkgmgr, 'get_package_name')
jadmanskicd95e1f2008-07-01 21:32:22 +0000234 self.god.stub_function(test, 'runtest')
235 self.god.stub_function(self.job, 'record')
236
237 # record
238 url = "my.test.url"
239 group = "group"
240 testname = "testname"
241 e = error.TestError("Unexpected error")
mblighc5ddfd12008-08-04 17:15:00 +0000242 self.job.pkgmgr.get_package_name.expect_call(
243 url, 'test').and_return((group, testname))
jadmanskicd95e1f2008-07-01 21:32:22 +0000244 outputdir = os.path.join(self.resultdir, testname)
245 os.path.exists.expect_call(outputdir).and_return(False)
246 os.mkdir.expect_call(outputdir)
247 self.job.record.expect_call('START', testname, testname)
248 test.runtest.expect_call(self.job, url, None, (), {}).and_raises(e)
249 self.job.record.expect_call('ERROR', testname, testname,
250 'Unexpected error')
jadmanskib88d6dc2009-01-10 00:33:18 +0000251 self.job.record.expect_call('END ERROR', testname, testname)
jadmanskicd95e1f2008-07-01 21:32:22 +0000252
253 # run and check
254 self.job.run_test(url)
255 self.god.check_playback()
256
257
258 def test_run_test_with_test_fail(self):
jadmanskicd95e1f2008-07-01 21:32:22 +0000259 # setup
mblighc5ddfd12008-08-04 17:15:00 +0000260 self.god.stub_function(self.job.pkgmgr, 'get_package_name')
jadmanskicd95e1f2008-07-01 21:32:22 +0000261 self.god.stub_function(test, 'runtest')
262 self.god.stub_function(self.job, 'record')
263
264 # record
265 url = "my.test.url"
266 group = "group"
267 testname = "testname"
268 e = error.TestFail("The test failed!")
mblighc5ddfd12008-08-04 17:15:00 +0000269 self.job.pkgmgr.get_package_name.expect_call(
270 url, 'test').and_return((group, testname))
jadmanskicd95e1f2008-07-01 21:32:22 +0000271 outputdir = os.path.join(self.resultdir, testname)
272 os.path.exists.expect_call(outputdir).and_return(False)
273 os.mkdir.expect_call(outputdir)
274 self.job.record.expect_call('START', testname, testname)
275 test.runtest.expect_call(self.job, url, None, (), {}).and_raises(e)
276 self.job.record.expect_call('FAIL', testname, testname,
277 'The test failed!')
jadmanskib88d6dc2009-01-10 00:33:18 +0000278 self.job.record.expect_call('END FAIL', testname, testname)
mbligh7636b3a2008-06-11 15:44:01 +0000279
280 # run and check
281 self.job.run_test(url)
282 self.god.check_playback()
283
284
285 def test_run_group(self):
mbligh7636b3a2008-06-11 15:44:01 +0000286 # setup
287 func = self.god.create_mock_function("function")
288 name = func.__name__
289 self.god.stub_function(self.job, 'record')
290
291 # record
292 self.job.record.expect_call('START', None, name)
293 func.expect_call((), {}).and_return(None)
294 self.job.record.expect_call('END GOOD', None, name)
295
296 # run and check
297 self.job.run_group(func, (), {})
298 self.god.check_playback()
299
300
301 def test_run_reboot(self):
mbligh7636b3a2008-06-11 15:44:01 +0000302 # setup
303 self.god.stub_function(self.job, 'record')
304 reboot_func = self.god.create_mock_function('reboot')
305 get_kernel_func = self.god.create_mock_function('get_kernel')
306 kernel = '2.6.24'
307
308 # record
309 self.job.record.expect_call('START', None, 'reboot')
310 reboot_func.expect_call()
311 get_kernel_func.expect_call().and_return(kernel)
312 self.job.record.expect_call('END GOOD', None, 'reboot',
313 optional_fields={"kernel": kernel})
314
315 # run and check
316 self.job.run_reboot(reboot_func, get_kernel_func)
317 self.god.check_playback()
318
319
mblighaebe3b62008-12-22 14:45:40 +0000320 def test_record(self):
mbligh7636b3a2008-06-11 15:44:01 +0000321 # setup
322 self.god.stub_function(self.job, '_read_warnings')
323 self.god.stub_function(self.job, '_record')
324 status_code = 'GOOD'
325 subdir = "subdir"
326 operation = "operation"
327 timestamp = '0'
328 warnings = "danger, danger Will Robinson!"
329
330 # record
331 self.job._read_warnings.expect_call(
332 ).and_return(((timestamp, warnings),))
333 self.job._record.expect_call("WARN", None, None, warnings,
334 timestamp)
335 self.job._record.expect_call(status_code, subdir, operation, '',
336 optional_fields=None)
337
338 # run and check
339 self.job.record(status_code, subdir, operation)
340 self.god.check_playback()
341
342
jadmanskif37df842009-02-11 00:03:26 +0000343class WarningManagerTest(unittest.TestCase):
344 def test_never_disabled(self):
345 manager = server_job.warning_manager()
346 self.assertEqual(manager.is_valid(10, "MSGTYPE"), True)
347
348
349 def test_only_enabled(self):
350 manager = server_job.warning_manager()
351 manager.enable_warnings("MSGTYPE", lambda: 10)
352 self.assertEqual(manager.is_valid(20, "MSGTYPE"), True)
353
354
355 def test_disabled_once(self):
356 manager = server_job.warning_manager()
357 manager.disable_warnings("MSGTYPE", lambda: 10)
358 self.assertEqual(manager.is_valid(5, "MSGTYPE"), True)
359 self.assertEqual(manager.is_valid(15, "MSGTYPE"), False)
360
361
362 def test_disable_and_enabled(self):
363 manager = server_job.warning_manager()
364 manager.disable_warnings("MSGTYPE", lambda: 10)
365 manager.enable_warnings("MSGTYPE", lambda: 20)
366 self.assertEqual(manager.is_valid(15, "MSGTYPE"), False)
367 self.assertEqual(manager.is_valid(25, "MSGTYPE"), True)
368
369
370 def test_disabled_changes_is_valid(self):
371 manager = server_job.warning_manager()
372 self.assertEqual(manager.is_valid(15, "MSGTYPE"), True)
373 manager.disable_warnings("MSGTYPE", lambda: 10)
374 self.assertEqual(manager.is_valid(15, "MSGTYPE"), False)
375
376
377 def test_multiple_disabled_calls(self):
378 manager = server_job.warning_manager()
379 manager.disable_warnings("MSGTYPE", lambda: 10)
380 manager.disable_warnings("MSGTYPE", lambda: 20)
381 manager.enable_warnings("MSGTYPE", lambda: 30)
382 self.assertEqual(manager.is_valid(15, "MSGTYPE"), False)
383 self.assertEqual(manager.is_valid(25, "MSGTYPE"), False)
384 self.assertEqual(manager.is_valid(35, "MSGTYPE"), True)
385
386
387 def test_multiple_types(self):
388 manager = server_job.warning_manager()
389 manager.disable_warnings("MSGTYPE1", lambda: 10)
390 manager.disable_warnings("MSGTYPE2", lambda: 20)
391 manager.enable_warnings("MSGTYPE2", lambda: 30)
392 self.assertEqual(manager.is_valid(15, "MSGTYPE1"), False)
393 self.assertEqual(manager.is_valid(15, "MSGTYPE2"), True)
394 self.assertEqual(manager.is_valid(25, "MSGTYPE1"), False)
395 self.assertEqual(manager.is_valid(25, "MSGTYPE2"), False)
396 self.assertEqual(manager.is_valid(35, "MSGTYPE1"), False)
397 self.assertEqual(manager.is_valid(35, "MSGTYPE2"), True)
398
399
mbligh7636b3a2008-06-11 15:44:01 +0000400if __name__ == "__main__":
401 unittest.main()