job_unittest.py revision 9e722984cea169afec7b6515f7178a131a22bb0b
1ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya#!/usr/bin/python 2ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya 3ef77253961f909f87e82e6d2b620e87af33e9665yaberauneyaimport os, unittest, pickle, shutil, sys, time 4ef77253961f909f87e82e6d2b620e87af33e9665yaberauneyaimport common 5ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya 6ef77253961f909f87e82e6d2b620e87af33e9665yaberauneyafrom autotest_lib.client.bin import job, boottool, config, sysinfo, harness 7ef77253961f909f87e82e6d2b620e87af33e9665yaberauneyafrom autotest_lib.client.bin import test, xen, kernel, autotest_utils, cpuset 8ef77253961f909f87e82e6d2b620e87af33e9665yaberauneyafrom autotest_lib.client.common_lib import utils, error, logging 9ef77253961f909f87e82e6d2b620e87af33e9665yaberauneyafrom autotest_lib.client.common_lib.test_utils import mock 10ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya 11ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya 12ef77253961f909f87e82e6d2b620e87af33e9665yaberauneyaclass first_line_comparator(mock.argument_comparator): 13ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya def __init__(self, first_line): 14ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya self.first_line = first_line 15ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya 16ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya 17ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya def is_satisfied_by(self, parameter): 18ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya return self.first_line == parameter.splitlines()[0] 19ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya 208967f960f820f449162101a02ee5747f195a8a57Ngie Cooper 21ef77253961f909f87e82e6d2b620e87af33e9665yaberauneyaclass TestBaseJob(unittest.TestCase): 22865695bbc89088b9526ea9045410e5afb70a985cplars def setUp(self): 23ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya # make god 24865695bbc89088b9526ea9045410e5afb70a985cplars self.god = mock.mock_god() 25ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya 2648ef3a4bb94e8e55952cd983dbcce749229c1bebnstraz # need to set some environ variables 27ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya self.autodir = "autodir" 28ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya os.environ['AUTODIR'] = self.autodir 29865695bbc89088b9526ea9045410e5afb70a985cplars 30ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya # set up some variables 31865695bbc89088b9526ea9045410e5afb70a985cplars self.control = "control" 32ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya self.jobtag = "jobtag" 33ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya 34ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya # stub out some stuff 35ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya self.god.stub_function(os.path, 'exists') 36ef77253961f909f87e82e6d2b620e87af33e9665yaberauneya self.god.stub_function(os.path, 'isdir') 37 self.god.stub_function(os, 'mkdir') 38 self.god.stub_function(shutil, 'copyfile') 39 self.god.stub_function(job, 'open') 40 self.god.stub_function(utils, 'system') 41 self.god.stub_function(harness, 'select') 42 self.god.stub_function(sysinfo, 'log_per_reboot_data') 43 self.god.stub_function(pickle, 'load') 44 self.god.stub_function(sysinfo, 'log_per_reboot_data') 45 46 self.god.stub_class(config, 'config') 47 self.god.stub_class(boottool, 'boottool') 48 49 50 def tearDown(self): 51 self.god.unstub_all() 52 53 54 def construct_job(self, cont): 55 # will construct class instance using __new__ 56 self.job = job.base_job.__new__(job.base_job) 57 58 # now some specific stubs 59 self.god.stub_function(self.job, '_load_state') 60 self.god.stub_function(self.job, '_init_group_level') 61 self.god.stub_function(self.job, 'config_get') 62 self.god.stub_function(self.job, 'record') 63 self.god.stub_function(self.job, '_increment_group_level') 64 self.god.stub_function(self.job, '_decrement_group_level') 65 self.god.stub_function(self.job, 'get_state') 66 67 # other setup 68 tmpdir = os.path.join(self.autodir, 'tmp') 69 results = os.path.join(self.autodir, 'results') 70 download = os.path.join(self.autodir, 'tests', 'download') 71 resultdir = os.path.join(self.autodir, 'results', self.jobtag) 72 sysinfodir = os.path.join(resultdir, 'sysinfo') 73 74 # record 75 self.job._load_state.expect_call() 76 if not cont: 77 os.path.exists.expect_call(tmpdir).and_return(False) 78 os.mkdir.expect_call(tmpdir) 79 os.path.exists.expect_call(results).and_return(False) 80 os.mkdir.expect_call(results) 81 os.path.exists.expect_call(download).and_return(False) 82 os.mkdir.expect_call(download) 83 os.path.exists.expect_call(resultdir).and_return(True) 84 utils.system.expect_call('rm -rf ' + resultdir) 85 os.mkdir.expect_call(resultdir) 86 os.mkdir.expect_call(sysinfodir) 87 os.mkdir.expect_call(os.path.join(resultdir, 'debug')) 88 os.mkdir.expect_call(os.path.join(resultdir, 89 'analysis')) 90 shutil.copyfile.expect_call(mock.is_string_comparator(), 91 os.path.join(resultdir, 'control')) 92 93 self.job._init_group_level.expect_call() 94 self.config = config.config.expect_new(self.job) 95 my_harness = self.god.create_mock_class(harness.harness, 96 'my_harness') 97 harness.select.expect_call(None, 98 self.job).and_return(my_harness) 99 self.job.config_get.expect_call( 100 'boottool.executable').and_return(None) 101 bootloader = boottool.boottool.expect_new(None) 102 sysinfo.log_per_reboot_data.expect_call(sysinfodir) 103 if not cont: 104 self.job.record.expect_call('START', None, None) 105 self.job._increment_group_level.expect_call() 106 107 my_harness.run_start.expect_call() 108 self.job.get_state.expect_call('__monitor_disk', 109 default=0.0).and_return(0.0) 110 111 # finish constructor 112 self.job.__init__(self.control, self.jobtag, cont) 113 114 # check 115 self.god.check_playback() 116 117 118 def test_constructor(self): 119 self.construct_job(False) 120 121 122 def test_monitor_disk_usage(self): 123 self.construct_job(True) 124 125 # setup 126 self.god.stub_function(self.job, 'set_state') 127 128 # record 129 max_rate = 10.0 130 self.job.set_state.expect_call('__monitor_disk', max_rate) 131 132 # test 133 self.job.monitor_disk_usage(max_rate) 134 self.god.check_playback() 135 136 137 def test_relative_path(self): 138 self.construct_job(True) 139 dummy = "asdf" 140 ret = self.job.relative_path(os.path.join(self.job.resultdir, dummy)) 141 self.assertEquals(ret, dummy) 142 143 144 def test_control_functions(self): 145 self.construct_job(True) 146 control_file = "blah" 147 self.job.control_set(control_file) 148 self.assertEquals(self.job.control_get(), os.path.abspath(control_file)) 149 150 151 def test_harness_select(self): 152 self.construct_job(True) 153 154 # record 155 which = "which" 156 harness.select.expect_call(which, self.job).and_return(None) 157 158 # run and test 159 self.job.harness_select(which) 160 self.god.check_playback() 161 162 163 def test_config_set(self): 164 self.construct_job(True) 165 166 # record 167 name = "foo" 168 val = 10 169 self.config.set.expect_call(name, val) 170 171 # run and test 172 self.job.config_set(name, val) 173 self.god.check_playback() 174 175 176 def test_config_get(self): 177 self.construct_job(True) 178 179 # unstub config_get 180 self.god.unstub(self.job, 'config_get') 181 # record 182 name = "foo" 183 val = 10 184 self.config.get.expect_call(name).and_return(val) 185 186 # run and test 187 self.job.config_get(name) 188 self.god.check_playback() 189 190 191 def test_setup_dirs_raise(self): 192 self.construct_job(True) 193 194 # setup 195 results_dir = 'foo' 196 tmp_dir = 'bar' 197 198 # record 199 os.path.exists.expect_call(tmp_dir).and_return(True) 200 os.path.isdir.expect_call(tmp_dir).and_return(False) 201 202 # test 203 self.assertRaises(ValueError, self.job.setup_dirs, results_dir, tmp_dir) 204 self.god.check_playback() 205 206 207 def test_setup_dirs(self): 208 self.construct_job(True) 209 210 # setup 211 results_dir1 = os.path.join(self.job.resultdir, 'build') 212 results_dir2 = os.path.join(self.job.resultdir, 'build.2') 213 results_dir3 = os.path.join(self.job.resultdir, 'build.3') 214 tmp_dir = 'bar' 215 216 # record 217 os.path.exists.expect_call(tmp_dir).and_return(False) 218 os.mkdir.expect_call(tmp_dir) 219 os.path.isdir.expect_call(tmp_dir).and_return(True) 220 os.path.exists.expect_call(results_dir1).and_return(True) 221 os.path.exists.expect_call(results_dir2).and_return(True) 222 os.path.exists.expect_call(results_dir3).and_return(False) 223 os.path.exists.expect_call(results_dir3).and_return(False) 224 os.mkdir.expect_call(results_dir3) 225 226 # test 227 self.assertEqual(self.job.setup_dirs(None, tmp_dir), 228 (results_dir3, tmp_dir)) 229 self.god.check_playback() 230 231 232 def test_xen(self): 233 self.construct_job(True) 234 235 # setup 236 self.god.stub_function(self.job, "setup_dirs") 237 self.god.stub_class(xen, "xen") 238 results = 'results_dir' 239 tmp = 'tmp' 240 build = 'xen' 241 base_tree = object() 242 243 # record 244 self.job.setup_dirs.expect_call(results, 245 tmp).and_return((results, tmp)) 246 myxen = xen.xen.expect_new(self.job, base_tree, results, tmp, build, 247 False, None) 248 249 # run job and check 250 axen = self.job.xen(base_tree, results, tmp) 251 self.god.check_playback() 252 self.assertEquals(myxen, axen) 253 254 255 def test_kernel_rpm(self): 256 self.construct_job(True) 257 258 # setup 259 self.god.stub_function(self.job, "setup_dirs") 260 self.god.stub_class(kernel, "rpm_kernel") 261 self.god.stub_function(kernel, "preprocess_path") 262 results = 'results_dir' 263 tmp = 'tmp' 264 build = 'xen' 265 path = "somepath.rpm" 266 267 # record 268 self.job.setup_dirs.expect_call(results, 269 tmp).and_return((results, tmp)) 270 kernel.preprocess_path.expect_call(path).and_return(path) 271 mykernel = kernel.rpm_kernel.expect_new(self.job, path, results) 272 273 # check 274 akernel = self.job.kernel(path, results, tmp) 275 self.god.check_playback() 276 self.assertEquals(mykernel, akernel) 277 278 279 def test_kernel(self): 280 self.construct_job(True) 281 282 # setup 283 self.god.stub_function(self.job, "setup_dirs") 284 self.god.stub_class(kernel, "kernel") 285 self.god.stub_function(kernel, "preprocess_path") 286 results = 'results_dir' 287 tmp = 'tmp' 288 build = 'linux' 289 path = "somepath.deb" 290 291 # record 292 self.job.setup_dirs.expect_call(results, 293 tmp).and_return((results, tmp)) 294 kernel.preprocess_path.expect_call(path).and_return(path) 295 mykernel = kernel.kernel.expect_new(self.job, path, results, tmp, 296 build, False) 297 298 # check 299 akernel = self.job.kernel(path, results, tmp) 300 self.god.check_playback() 301 self.assertEquals(mykernel, akernel) 302 303 304 def test_run_test_logs_test_error_from_unhandled_error(self): 305 self.construct_job(True) 306 307 # set up stubs 308 self.god.stub_function(test, "testname") 309 self.god.stub_function(self.job, "_runtest") 310 311 # create an unhandled error object 312 class MyError(error.TestError): 313 pass 314 real_error = MyError("this is the real error message") 315 unhandled_error = error.UnhandledError(real_error) 316 317 # set up the recording 318 testname = "error_test" 319 outputdir = os.path.join(self.job.resultdir, testname) 320 test.testname.expect_call(testname).and_return(("", testname)) 321 os.path.exists.expect_call(outputdir).and_return(False) 322 os.mkdir.expect_call(outputdir) 323 self.job.record.expect_call("START", testname, testname) 324 self.job._increment_group_level.expect_call() 325 self.job._runtest.expect_call(testname, "", (), {}).and_raises( 326 unhandled_error) 327 self.job.record.expect_call("FAIL", testname, testname, 328 first_line_comparator(str(real_error))) 329 self.job._decrement_group_level.expect_call() 330 self.job.record.expect_call("END FAIL", testname, testname, 331 first_line_comparator(str(real_error))) 332 333 # run and check 334 self.job.run_test(testname) 335 self.god.check_playback() 336 337 338 def test_run_test_logs_non_test_error_from_unhandled_error(self): 339 self.construct_job(True) 340 341 # set up stubs 342 self.god.stub_function(test, "testname") 343 self.god.stub_function(self.job, "_runtest") 344 345 # create an unhandled error object 346 class MyError(Exception): 347 pass 348 real_error = MyError("this is the real error message") 349 unhandled_error = error.UnhandledError(real_error) 350 reason = first_line_comparator("Unhandled MyError: %s" % real_error) 351 352 # set up the recording 353 testname = "error_test" 354 outputdir = os.path.join(self.job.resultdir, testname) 355 test.testname.expect_call(testname).and_return(("", testname)) 356 os.path.exists.expect_call(outputdir).and_return(False) 357 os.mkdir.expect_call(outputdir) 358 self.job.record.expect_call("START", testname, testname) 359 self.job._increment_group_level.expect_call() 360 self.job._runtest.expect_call(testname, "", (), {}).and_raises( 361 unhandled_error) 362 self.job.record.expect_call("FAIL", testname, testname, reason) 363 self.job._decrement_group_level.expect_call() 364 self.job.record.expect_call("END FAIL", testname, testname, reason) 365 366 # run and check 367 self.job.run_test(testname) 368 self.god.check_playback() 369 370 371 def new_container(self): 372 self.construct_job(True) 373 374 # set up stubs 375 self.god.stub_function(autotest_utils, "grep") 376 self.god.stub_function(os, "getpid") 377 self.god.stub_class(cpuset, "cpuset") 378 pid = 100 379 name = 'test%d' % pid 380 381 # record 382 autotest_utils.grep.expect_call('cpuset', 383 '/proc/filesystems').and_return(True) 384 os.getpid.expect_call().and_return(pid) 385 386 container = cpuset.cpuset.expect_new(name, job_size=None, job_pid=pid, 387 cpus=None, root=None, 388 network=None) 389 390 # run test 391 self.job.new_container() 392 self.god.check_playback() 393 return container 394 395 396 def test_new_container(self): 397 container = self.new_container() 398 self.assertEquals(self.job.container, container) 399 400 401 def test_release_container(self): 402 self.new_container() 403 404 # record 405 self.job.container.release.expect_call() 406 407 # run 408 self.job.release_container() 409 self.god.check_playback() 410 self.assertEquals(self.job.container, None) 411 412 413 def test_record(self): 414 self.construct_job(True) 415 416 # steup 417 self.job.group_level = 1 418 status = '' 419 status_code = "PASS" 420 subdir = "subdir" 421 operation = "super_fun" 422 mytime = "1234" 423 msg_tag = "" 424 if "." in self.job.log_filename: 425 msg_tag = self.job.log_filename.split(".", 1)[1] 426 epoch_time = int(mytime) 427 local_time = time.localtime(epoch_time) 428 optional_fields = {} 429 optional_fields["timestamp"] = str(epoch_time) 430 optional_fields["localtime"] = time.strftime("%b %d %H:%M:%S", 431 local_time) 432 fields = [status_code, subdir, operation] 433 fields += ["%s=%s" % x for x in optional_fields.iteritems()] 434 fields.append(status) 435 msg = '\t'.join(str(x) for x in fields) 436 msg = '\t' * self.job.group_level + msg 437 438 self.god.stub_function(logging, "is_valid_status") 439 self.god.stub_function(time, "time") 440 self.god.stub_function(self.job, "open") 441 442 443 # record 444 logging.is_valid_status.expect_call(status_code).and_return(True) 445 time.time.expect_call().and_return(mytime) 446 self.job.harness.test_status_detail.expect_call(status_code, subdir, 447 operation, '', msg_tag) 448 self.job.harness.test_status.expect_call(msg, msg_tag) 449 myfile = self.god.create_mock_class(file, "file") 450 status_file = os.path.join(self.job.resultdir, self.job.log_filename) 451 self.job.open.expect_call(status_file, "a").and_return(myfile) 452 myfile.write.expect_call(msg + "\n") 453 454 dir = os.path.join(self.job.resultdir, subdir) 455 status_file = os.path.join(dir, self.job.DEFAULT_LOG_FILENAME) 456 self.job.open.expect_call(status_file, "a").and_return(myfile) 457 myfile.write.expect_call(msg + "\n") 458 459 460 # run test 461 self.god.unstub(self.job, "record") 462 self.job.record(status_code, subdir, operation) 463 self.god.check_playback() 464 465 466if __name__ == "__main__": 467 unittest.main() 468