xref: /aosp_15_r20/external/autotest/autotest_lib/tko/job_serializer_unittest.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
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