1*9c5db199SXin Li#!/usr/bin/python3 2*9c5db199SXin Li 3*9c5db199SXin Li"""Unittests for the JobSerializer class. 4*9c5db199SXin Li 5*9c5db199SXin LiMostly test if the serialized object has the expected content. 6*9c5db199SXin Li 7*9c5db199SXin Li""" 8*9c5db199SXin Li 9*9c5db199SXin Lifrom __future__ import division 10*9c5db199SXin Lifrom __future__ import print_function 11*9c5db199SXin Li 12*9c5db199SXin Liimport datetime 13*9c5db199SXin Liimport tempfile 14*9c5db199SXin Liimport time 15*9c5db199SXin Liimport unittest 16*9c5db199SXin Li 17*9c5db199SXin Liimport common 18*9c5db199SXin Lifrom autotest_lib.tko import tko_pb2 19*9c5db199SXin Lifrom autotest_lib.tko import job_serializer 20*9c5db199SXin Lifrom autotest_lib.tko import models 21*9c5db199SXin Liimport six 22*9c5db199SXin Lifrom six.moves import zip 23*9c5db199SXin Li 24*9c5db199SXin LiNamedTemporaryFile = tempfile.NamedTemporaryFile 25*9c5db199SXin Lidatetime = datetime.datetime 26*9c5db199SXin Limktime = time.mktime 27*9c5db199SXin Li 28*9c5db199SXin Liclass JobSerializerUnittest(unittest.TestCase): 29*9c5db199SXin Li """Base class as a job serializer unittest""" 30*9c5db199SXin Li 31*9c5db199SXin Li def setUp(self): 32*9c5db199SXin Li tko_patches = [] 33*9c5db199SXin Li tko_patches.append(models.patch('New spec!', 'Reference?', 34*9c5db199SXin Li 123456)) 35*9c5db199SXin Li 36*9c5db199SXin Li tko_kernel = models.kernel('My Computer', tko_patches, '1234567') 37*9c5db199SXin Li tko_time = datetime.now() 38*9c5db199SXin Li 39*9c5db199SXin Li tko_job = models.job('/tmp/', 'autotest', 'test', 'My Computer', 40*9c5db199SXin Li tko_time, tko_time, tko_time, 'root', 41*9c5db199SXin Li 'www', 'No one', tko_time, {'1+1':2}) 42*9c5db199SXin Li tko_job.afe_parent_job_id = 111 43*9c5db199SXin Li tko_job.build_version = 'R1-1.0.0' 44*9c5db199SXin Li tko_job.suite = 'bvt' 45*9c5db199SXin Li tko_job.board = 'alex' 46*9c5db199SXin Li tko_job.index = 2 47*9c5db199SXin Li 48*9c5db199SXin Li tko_iteration = models.iteration(0, {'2+2':4, '3+3':6}, 49*9c5db199SXin Li {'4+4':8, '5+5':10, '6+6':12}) 50*9c5db199SXin Li 51*9c5db199SXin Li tko_labels = ['unittest', 'dummy test', 'autotest'] 52*9c5db199SXin Li 53*9c5db199SXin Li # See the comment about the models.test constructor in 54*9c5db199SXin Li # job_serializer.py, where the models.test constructor is used. 55*9c5db199SXin Li tko_test = models.test('/tmp/', 'mocktest', 'Completed', 'N/A', 56*9c5db199SXin Li tko_kernel, 'My Computer', tko_time, 57*9c5db199SXin Li tko_time, [tko_iteration, 58*9c5db199SXin Li tko_iteration, tko_iteration], 59*9c5db199SXin Li {'abc':'def'}, [], tko_labels) 60*9c5db199SXin Li tko_test.test_idx = 3 61*9c5db199SXin Li self.tko_job = tko_job 62*9c5db199SXin Li self.tko_job.tests = [tko_test, tko_test, tko_test] 63*9c5db199SXin Li 64*9c5db199SXin Li self.pb_job = tko_pb2.Job() 65*9c5db199SXin Li self.tag = '1-abc./.' 66*9c5db199SXin Li self.expected_afe_job_id = '1' 67*9c5db199SXin Li 68*9c5db199SXin Li js = job_serializer.JobSerializer() 69*9c5db199SXin Li js.set_pb_job(self.tko_job, self.pb_job, self.tag) 70*9c5db199SXin Li 71*9c5db199SXin Li 72*9c5db199SXin Li def test_tag(self): 73*9c5db199SXin Li """Test serializing tag field.""" 74*9c5db199SXin Li self.assertEqual(self.tag, self.pb_job.tag) 75*9c5db199SXin Li 76*9c5db199SXin Li 77*9c5db199SXin Li def test_afe_job_id(self): 78*9c5db199SXin Li """Test serializing afe_job_id field.""" 79*9c5db199SXin Li self.assertEqual(self.expected_afe_job_id, 80*9c5db199SXin Li self.pb_job.afe_job_id) 81*9c5db199SXin Li 82*9c5db199SXin Li 83*9c5db199SXin Li def test_job_dir(self): 84*9c5db199SXin Li """Check if the dir field are the same. 85*9c5db199SXin Li """ 86*9c5db199SXin Li self.assertEqual(self.tko_job.dir, self.pb_job.dir) 87*9c5db199SXin Li 88*9c5db199SXin Li 89*9c5db199SXin Li def test_number_of_test(self): 90*9c5db199SXin Li """Check if the number of test are the same. 91*9c5db199SXin Li """ 92*9c5db199SXin Li self.assertEqual(len(self.tko_job.tests), 93*9c5db199SXin Li len(self.pb_job.tests)) 94*9c5db199SXin Li 95*9c5db199SXin Li 96*9c5db199SXin Li def test_user(self): 97*9c5db199SXin Li """Check if the user field are the same. 98*9c5db199SXin Li """ 99*9c5db199SXin Li self.assertEqual(self.tko_job.user, self.pb_job.user) 100*9c5db199SXin Li 101*9c5db199SXin Li 102*9c5db199SXin Li def test_machine(self): 103*9c5db199SXin Li """Check if the machine fields are the same. 104*9c5db199SXin Li """ 105*9c5db199SXin Li self.assertEqual(self.tko_job.machine, self.pb_job.machine) 106*9c5db199SXin Li 107*9c5db199SXin Li 108*9c5db199SXin Li def test_queued_time(self): 109*9c5db199SXin Li """Check if queued_time are the same. 110*9c5db199SXin Li """ 111*9c5db199SXin Li self.check_time(self.tko_job.queued_time, 112*9c5db199SXin Li self.pb_job.queued_time) 113*9c5db199SXin Li 114*9c5db199SXin Li 115*9c5db199SXin Li def test_started_time(self): 116*9c5db199SXin Li """Check if the started_time are the same. 117*9c5db199SXin Li """ 118*9c5db199SXin Li self.check_time(self.tko_job.started_time, 119*9c5db199SXin Li self.pb_job.started_time) 120*9c5db199SXin Li 121*9c5db199SXin Li 122*9c5db199SXin Li def test_finished_time(self): 123*9c5db199SXin Li """Check if the finished_time are the same. 124*9c5db199SXin Li """ 125*9c5db199SXin Li self.check_time(self.tko_job.finished_time, 126*9c5db199SXin Li self.pb_job.finished_time) 127*9c5db199SXin Li 128*9c5db199SXin Li 129*9c5db199SXin Li def test_machine_owner(self): 130*9c5db199SXin Li """Check if the machine owners are the same. 131*9c5db199SXin Li """ 132*9c5db199SXin Li self.assertEqual(self.tko_job.machine_owner, 133*9c5db199SXin Li self.pb_job.machine_owner) 134*9c5db199SXin Li 135*9c5db199SXin Li 136*9c5db199SXin Li def test_machine_group(self): 137*9c5db199SXin Li """Check if the machine groups are the same. 138*9c5db199SXin Li """ 139*9c5db199SXin Li self.assertEqual(self.tko_job.machine_group, 140*9c5db199SXin Li self.pb_job.machine_group) 141*9c5db199SXin Li 142*9c5db199SXin Li def test_aborted_by(self): 143*9c5db199SXin Li """Check if the jobs are aborted by the same person. 144*9c5db199SXin Li """ 145*9c5db199SXin Li self.assertEqual(self.tko_job.aborted_by, 146*9c5db199SXin Li self.pb_job.aborted_by) 147*9c5db199SXin Li 148*9c5db199SXin Li 149*9c5db199SXin Li def test_aborted_on(self): 150*9c5db199SXin Li """Test serializing aborted_on field.""" 151*9c5db199SXin Li self.check_time(self.tko_job.aborted_on, 152*9c5db199SXin Li self.pb_job.aborted_on) 153*9c5db199SXin Li 154*9c5db199SXin Li 155*9c5db199SXin Li def test_keyval_dict(self): 156*9c5db199SXin Li """Check if the contents of the dictionary are the same. 157*9c5db199SXin Li """ 158*9c5db199SXin Li self.assertEqual(len(self.tko_job.keyval_dict), 159*9c5db199SXin Li len(self.pb_job.keyval_dict)) 160*9c5db199SXin Li self.check_dict(self.tko_job.keyval_dict, 161*9c5db199SXin Li self.convert_keyval_to_dict(self.pb_job, 162*9c5db199SXin Li 'keyval_dict')) 163*9c5db199SXin Li 164*9c5db199SXin Li 165*9c5db199SXin Li def test_job_idx(self): 166*9c5db199SXin Li """Test serializing job_idx field.""" 167*9c5db199SXin Li self.assertEqual(self.tko_job.index, 168*9c5db199SXin Li self.pb_job.job_idx) 169*9c5db199SXin Li 170*9c5db199SXin Li 171*9c5db199SXin Li def test_afe_parent_job_id(self): 172*9c5db199SXin Li """Test serializing afe_parent_job_id field.""" 173*9c5db199SXin Li self.assertEqual(str(self.tko_job.afe_parent_job_id), 174*9c5db199SXin Li self.pb_job.afe_parent_job_id) 175*9c5db199SXin Li 176*9c5db199SXin Li 177*9c5db199SXin Li def test_build_version(self): 178*9c5db199SXin Li """Test serializing build_version field.""" 179*9c5db199SXin Li self.assertEqual(self.tko_job.build_version, 180*9c5db199SXin Li self.pb_job.build_version) 181*9c5db199SXin Li 182*9c5db199SXin Li 183*9c5db199SXin Li def test_suite(self): 184*9c5db199SXin Li """Test serializing suite field.""" 185*9c5db199SXin Li self.assertEqual(self.tko_job.suite, 186*9c5db199SXin Li self.pb_job.suite) 187*9c5db199SXin Li 188*9c5db199SXin Li 189*9c5db199SXin Li def test_board(self): 190*9c5db199SXin Li """Test serializing board field.""" 191*9c5db199SXin Li self.assertEqual(self.tko_job.board, 192*9c5db199SXin Li self.pb_job.board) 193*9c5db199SXin Li 194*9c5db199SXin Li 195*9c5db199SXin Li def test_tests(self): 196*9c5db199SXin Li """Check if all the test are the same. 197*9c5db199SXin Li """ 198*9c5db199SXin Li 199*9c5db199SXin Li for test, newtest in zip(self.tko_job.tests, 200*9c5db199SXin Li self.pb_job.tests): 201*9c5db199SXin Li 202*9c5db199SXin Li self.assertEqual(test.subdir, newtest.subdir) 203*9c5db199SXin Li self.assertEqual(test.testname, newtest.testname) 204*9c5db199SXin Li self.assertEqual(test.status, newtest.status) 205*9c5db199SXin Li self.assertEqual(test.reason, newtest.reason) 206*9c5db199SXin Li self.assertEqual(test.machine, newtest.machine) 207*9c5db199SXin Li self.assertEqual(test.labels, newtest.labels) 208*9c5db199SXin Li self.assertEqual(test.test_idx, newtest.test_idx) 209*9c5db199SXin Li 210*9c5db199SXin Li self.check_time(test.started_time, newtest.started_time) 211*9c5db199SXin Li self.check_time(test.finished_time, newtest.finished_time) 212*9c5db199SXin Li 213*9c5db199SXin Li self.check_iteration(test.iterations, newtest.iterations) 214*9c5db199SXin Li 215*9c5db199SXin Li self.check_dict(test.attributes, 216*9c5db199SXin Li self.convert_keyval_to_dict(newtest, 217*9c5db199SXin Li 'attributes')) 218*9c5db199SXin Li 219*9c5db199SXin Li self.check_kernel(test.kernel, newtest.kernel) 220*9c5db199SXin Li 221*9c5db199SXin Li 222*9c5db199SXin Li def check_time(self, dTime, stime): 223*9c5db199SXin Li """Check if the datetime object contains the same time value 224*9c5db199SXin Li in microseconds. 225*9c5db199SXin Li 226*9c5db199SXin Li @param dTime: The datetime. 227*9c5db199SXin Li @param stime: The original time. 228*9c5db199SXin Li """ 229*9c5db199SXin Li t = mktime(dTime.timetuple()) + 1e-6 * dTime.microsecond 230*9c5db199SXin Li if six.PY2: 231*9c5db199SXin Li self.assertEqual(long(t), stime/1000) 232*9c5db199SXin Li else: 233*9c5db199SXin Li self.assertEqual(int(t), stime/1000) 234*9c5db199SXin Li 235*9c5db199SXin Li 236*9c5db199SXin Li def check_iteration(self, tko_iterations, pb_iterations): 237*9c5db199SXin Li """Check if the iteration objects are the same. 238*9c5db199SXin Li 239*9c5db199SXin Li @param tko_iterations: The list of iterations. 240*9c5db199SXin Li @param pb_iterations: The proto iterations. 241*9c5db199SXin Li """ 242*9c5db199SXin Li for tko_iteration, pb_iteration in zip(tko_iterations, 243*9c5db199SXin Li pb_iterations): 244*9c5db199SXin Li 245*9c5db199SXin Li self.assertEqual(tko_iteration.index, pb_iteration.index) 246*9c5db199SXin Li 247*9c5db199SXin Li self.check_dict(tko_iteration.attr_keyval, 248*9c5db199SXin Li self.convert_keyval_to_dict(pb_iteration, 249*9c5db199SXin Li 'attr_keyval')) 250*9c5db199SXin Li 251*9c5db199SXin Li self.check_dict(tko_iteration.perf_keyval, 252*9c5db199SXin Li self.convert_keyval_to_dict(pb_iteration, 253*9c5db199SXin Li 'perf_keyval')) 254*9c5db199SXin Li 255*9c5db199SXin Li 256*9c5db199SXin Li def convert_keyval_to_dict(self, var, attr): 257*9c5db199SXin Li """Convert a protocol buffer repeated keyval object into a 258*9c5db199SXin Li python dict. 259*9c5db199SXin Li 260*9c5db199SXin Li @param var: The variable name. 261*9c5db199SXin Li @param attr: The attribute name. 262*9c5db199SXin Li """ 263*9c5db199SXin Li 264*9c5db199SXin Li return dict((keyval.name, keyval.value) for keyval in 265*9c5db199SXin Li getattr(var,attr)) 266*9c5db199SXin Li 267*9c5db199SXin Li 268*9c5db199SXin Li def check_dict(self, dictionary, keyval): 269*9c5db199SXin Li """Check if the contents of the dictionary are the same as a 270*9c5db199SXin Li repeated keyval pair. 271*9c5db199SXin Li 272*9c5db199SXin Li @param dictionary: The dict object. 273*9c5db199SXin Li @param keyval: The keyval object. 274*9c5db199SXin Li """ 275*9c5db199SXin Li for key, value in six.iteritems(dictionary): 276*9c5db199SXin Li self.assertTrue(key in keyval); 277*9c5db199SXin Li self.assertEqual(str(value), keyval[key]) 278*9c5db199SXin Li 279*9c5db199SXin Li 280*9c5db199SXin Li def check_kernel(self, kernel, newkernel): 281*9c5db199SXin Li """Check if the kernels are the same. 282*9c5db199SXin Li 283*9c5db199SXin Li @param kernel: The kernel object. 284*9c5db199SXin Li @param newkernel: The proto kernel object. 285*9c5db199SXin Li """ 286*9c5db199SXin Li self.assertEqual(kernel.base, newkernel.base) 287*9c5db199SXin Li self.assertEqual(kernel.kernel_hash, newkernel.kernel_hash) 288*9c5db199SXin Li 289*9c5db199SXin Li 290*9c5db199SXin Liclass ReadBackTest(JobSerializerUnittest): 291*9c5db199SXin Li """Check if convert between models.job and pb job is correct even 292*9c5db199SXin Li after being written to binary and read by manually 293*9c5db199SXin Li """ 294*9c5db199SXin Li 295*9c5db199SXin Li def setUp(self): 296*9c5db199SXin Li """Setup the test.""" 297*9c5db199SXin Li super(ReadBackTest, self).setUp() 298*9c5db199SXin Li 299*9c5db199SXin Li out_binary = NamedTemporaryFile(mode='wb') 300*9c5db199SXin Li try: 301*9c5db199SXin Li out_binary.write(self.pb_job.SerializeToString()) 302*9c5db199SXin Li out_binary.flush() 303*9c5db199SXin Li 304*9c5db199SXin Li binary = open(out_binary.name, 'rb') 305*9c5db199SXin Li try: 306*9c5db199SXin Li self.pb_job = tko_pb2.Job() 307*9c5db199SXin Li self.pb_job.ParseFromString(binary.read()) 308*9c5db199SXin Li finally: 309*9c5db199SXin Li binary.close() 310*9c5db199SXin Li finally: 311*9c5db199SXin Li out_binary.close() 312*9c5db199SXin Li 313*9c5db199SXin Li 314*9c5db199SXin Liclass ReadBackGetterTest(JobSerializerUnittest): 315*9c5db199SXin Li """Check if convert between models.job and pb job is correct after 316*9c5db199SXin Li using the getter methods in JobSerializer to read back the 317*9c5db199SXin Li data. 318*9c5db199SXin Li """ 319*9c5db199SXin Li 320*9c5db199SXin Li def setUp(self): 321*9c5db199SXin Li super(ReadBackGetterTest, self).setUp() 322*9c5db199SXin Li 323*9c5db199SXin Li temp_binary = NamedTemporaryFile(mode='wb') 324*9c5db199SXin Li try: 325*9c5db199SXin Li temp_binary.write(self.pb_job.SerializeToString()) 326*9c5db199SXin Li temp_binary.flush() 327*9c5db199SXin Li 328*9c5db199SXin Li js = job_serializer.JobSerializer() 329*9c5db199SXin Li self.from_pb_job = js.deserialize_from_binary(temp_binary.name) 330*9c5db199SXin Li finally: 331*9c5db199SXin Li temp_binary.close() 332*9c5db199SXin Li 333*9c5db199SXin Li 334*9c5db199SXin Li def test_keyval_dict(self): 335*9c5db199SXin Li """Check if the contents of the dictionary are the same. """ 336*9c5db199SXin Li 337*9c5db199SXin Li self.assertEqual(len(self.tko_job.keyval_dict), 338*9c5db199SXin Li len(self.from_pb_job.keyval_dict)) 339*9c5db199SXin Li 340*9c5db199SXin Li self.check_dict(self.tko_job.keyval_dict, 341*9c5db199SXin Li self.from_pb_job.keyval_dict) 342*9c5db199SXin Li 343*9c5db199SXin Li 344*9c5db199SXin Li def test_tests(self): 345*9c5db199SXin Li """Check if all the test are the same. 346*9c5db199SXin Li """ 347*9c5db199SXin Li for test, newtest in zip(self.tko_job.tests, 348*9c5db199SXin Li self.from_pb_job.tests): 349*9c5db199SXin Li 350*9c5db199SXin Li self.assertEqual(test.subdir, newtest.subdir) 351*9c5db199SXin Li self.assertEqual(test.testname, newtest.testname) 352*9c5db199SXin Li self.assertEqual(test.status, newtest.status) 353*9c5db199SXin Li self.assertEqual(test.reason, newtest.reason) 354*9c5db199SXin Li self.assertEqual(test.machine, newtest.machine) 355*9c5db199SXin Li self.assertEqual(test.labels, newtest.labels) 356*9c5db199SXin Li 357*9c5db199SXin Li self.check_time(test.started_time, newtest.started_time) 358*9c5db199SXin Li self.check_time(test.finished_time, newtest.finished_time) 359*9c5db199SXin Li 360*9c5db199SXin Li self.check_iteration(test.iterations, newtest.iterations) 361*9c5db199SXin Li 362*9c5db199SXin Li self.check_dict(test.attributes, newtest.attributes) 363*9c5db199SXin Li 364*9c5db199SXin Li self.check_kernel(test.kernel, newtest.kernel) 365*9c5db199SXin Li 366*9c5db199SXin Li 367*9c5db199SXin Li def check_time(self, dTime, sTime): 368*9c5db199SXin Li """Check if the datetime object contains the same time value 369*9c5db199SXin Li in microseconds. 370*9c5db199SXin Li 371*9c5db199SXin Li If sTime is type int or type long, then only convert dTime to 372*9c5db199SXin Li microseconds. Else, convert both dTime and sTime to 373*9c5db199SXin Li microseconds. Then, compare the two after casting them to 374*9c5db199SXin Li long. 375*9c5db199SXin Li """ 376*9c5db199SXin Li 377*9c5db199SXin Li t = mktime(dTime.timetuple()) + 1e-6 * dTime.microsecond 378*9c5db199SXin Li if isinstance(sTime, six.integer_types): 379*9c5db199SXin Li if six.PY2: 380*9c5db199SXin Li self.assertEqual(long(t*1000), sTime) 381*9c5db199SXin Li else: 382*9c5db199SXin Li self.assertEqual(int(t*1000), sTime) 383*9c5db199SXin Li 384*9c5db199SXin Li else: 385*9c5db199SXin Li t1 = mktime(sTime.timetuple()) + 1e-6 * sTime.microsecond 386*9c5db199SXin Li if six.PY2: 387*9c5db199SXin Li self.assertEqual(long(t*1000), long(t1*1000)) 388*9c5db199SXin Li else: 389*9c5db199SXin Li self.assertEqual(int(t*1000), int(t1*1000)) 390*9c5db199SXin Li 391*9c5db199SXin Li 392*9c5db199SXin Li def check_iteration(self, iterations, newiterations): 393*9c5db199SXin Li """Check if the iteration objects are the same. 394*9c5db199SXin Li """ 395*9c5db199SXin Li for iteration, newiteration in zip(iterations, newiterations): 396*9c5db199SXin Li self.assertEqual(iteration.index, newiteration.index) 397*9c5db199SXin Li self.check_dict(iteration.attr_keyval, 398*9c5db199SXin Li newiteration.attr_keyval) 399*9c5db199SXin Li self.check_dict(iteration.perf_keyval, 400*9c5db199SXin Li newiteration.perf_keyval) 401*9c5db199SXin Li 402*9c5db199SXin Li 403*9c5db199SXin Liif __name__ == '__main__': 404*9c5db199SXin Li unittest.main() 405