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