Merge "Change tc_trex files to execute standalone tests"
[yardstick.git] / yardstick / tests / unit / common / test_utils.py
1 ##############################################################################
2 # Copyright (c) 2015 Ericsson AB and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 from copy import deepcopy
11 import errno
12 import importlib
13 import ipaddress
14 from itertools import product, chain
15 import os
16 import socket
17 import time
18 import threading
19
20 import mock
21 import six
22 from six.moves import configparser
23 import unittest
24
25 import yardstick
26 from yardstick import ssh
27 from yardstick.common import constants
28 from yardstick.common import utils
29 from yardstick.common import exceptions
30 from yardstick.tests.unit import base as ut_base
31
32
33 class IterSubclassesTestCase(ut_base.BaseUnitTestCase):
34     # Disclaimer: this class is a modified copy from
35     # rally/tests/unit/common/plugin/test_discover.py
36     # Copyright 2015: Mirantis Inc.
37
38     def test_itersubclasses(self):
39         class A(object):
40             pass
41
42         class B(A):
43             pass
44
45         class C(A):
46             pass
47
48         class D(C):
49             pass
50
51         self.assertEqual([B, C, D], list(utils.itersubclasses(A)))
52
53
54 class ImportModulesFromPackageTestCase(ut_base.BaseUnitTestCase):
55
56     @mock.patch('yardstick.common.utils.os.walk')
57     def test_import_modules_from_package_no_mod(self, mock_walk):
58         yardstick_root = os.path.dirname(os.path.dirname(yardstick.__file__))
59         mock_walk.return_value = ([
60             (os.path.join(yardstick_root, 'foo'), ['bar'], ['__init__.py']),
61             (os.path.join(yardstick_root, 'foo', 'bar'), [], ['baz.txt', 'qux.rst'])
62         ])
63
64         utils.import_modules_from_package('foo.bar')
65
66     @mock.patch('yardstick.common.utils.os.walk')
67     @mock.patch.object(importlib, 'import_module')
68     def test_import_modules_from_package(self, mock_import_module, mock_walk):
69
70         yardstick_root = os.path.dirname(os.path.dirname(yardstick.__file__))
71         mock_walk.return_value = ([
72             (os.path.join(yardstick_root, 'foo', os.pardir, 'bar'), [], ['baz.py'])
73         ])
74
75         utils.import_modules_from_package('foo.bar')
76         mock_import_module.assert_called_once_with('bar.baz')
77
78
79 class GetParaFromYaml(ut_base.BaseUnitTestCase):
80
81     @mock.patch('yardstick.common.utils.os.environ.get')
82     def test_get_param_para_not_found(self, get_env):
83         file_path = 'config_sample.yaml'
84         get_env.return_value = self._get_file_abspath(file_path)
85         args = 'releng.file'
86         default = 'hello'
87         self.assertTrue(constants.get_param(args, default), default)
88
89     @mock.patch('yardstick.common.utils.os.environ.get')
90     def test_get_param_para_exists(self, get_env):
91         file_path = 'config_sample.yaml'
92         get_env.return_value = self._get_file_abspath(file_path)
93         args = 'releng.dir'
94         para = '/home/opnfv/repos/releng'
95         self.assertEqual(para, constants.get_param(args))
96
97     def _get_file_abspath(self, filename):
98         curr_path = os.path.dirname(os.path.abspath(__file__))
99         file_path = os.path.join(curr_path, filename)
100         return file_path
101
102
103 class CommonUtilTestCase(ut_base.BaseUnitTestCase):
104
105     def setUp(self):
106         self.data = {
107             "benchmark": {
108                 "data": {
109                     "mpstat": {
110                         "cpu0": {
111                             "%sys": "0.00",
112                             "%idle": "99.00"
113                         },
114                         "loadavg": [
115                             "1.09",
116                             "0.29"
117                         ]
118                     },
119                     "rtt": "1.03"
120                 }
121             }
122         }
123
124     def test__dict_key_flatten(self):
125         line = 'mpstat.loadavg1=0.29,rtt=1.03,mpstat.loadavg0=1.09,' \
126                'mpstat.cpu0.%idle=99.00,mpstat.cpu0.%sys=0.00'
127         # need to sort for assert to work
128         line = ",".join(sorted(line.split(',')))
129         flattened_data = utils.flatten_dict_key(
130             self.data['benchmark']['data'])
131         result = ",".join(
132             ("=".join(item) for item in sorted(flattened_data.items())))
133         self.assertEqual(result, line)
134
135     def test_get_key_with_default_negative(self):
136         with self.assertRaises(KeyError):
137             utils.get_key_with_default({}, 'key1')
138
139     @mock.patch('yardstick.common.utils.open', create=True)
140     def test_(self, mock_open):
141         mock_open.side_effect = IOError
142
143         with self.assertRaises(IOError):
144             utils.find_relative_file('my/path', 'task/path')
145
146         self.assertEqual(mock_open.call_count, 2)
147
148     @mock.patch('yardstick.common.utils.open', create=True)
149     def test_open_relative_path(self, mock_open):
150         mock_open_result = mock_open()
151         mock_open_call_count = 1  # initial call to get result
152
153         self.assertEqual(utils.open_relative_file('foo', 'bar'), mock_open_result)
154
155         mock_open_call_count += 1  # one more call expected
156         self.assertEqual(mock_open.call_count, mock_open_call_count)
157         self.assertIn('foo', mock_open.call_args_list[-1][0][0])
158         self.assertNotIn('bar', mock_open.call_args_list[-1][0][0])
159
160         def open_effect(*args, **kwargs):
161             if kwargs.get('name', args[0]) == os.path.join('bar', 'foo'):
162                 return mock_open_result
163             raise IOError(errno.ENOENT, 'not found')
164
165         mock_open.side_effect = open_effect
166         self.assertEqual(utils.open_relative_file('foo', 'bar'), mock_open_result)
167
168         mock_open_call_count += 2  # two more calls expected
169         self.assertEqual(mock_open.call_count, mock_open_call_count)
170         self.assertIn('foo', mock_open.call_args_list[-1][0][0])
171         self.assertIn('bar', mock_open.call_args_list[-1][0][0])
172
173         # test an IOError of type ENOENT
174         mock_open.side_effect = IOError(errno.ENOENT, 'not found')
175         with self.assertRaises(IOError):
176             # the second call still raises
177             utils.open_relative_file('foo', 'bar')
178
179         mock_open_call_count += 2  # two more calls expected
180         self.assertEqual(mock_open.call_count, mock_open_call_count)
181         self.assertIn('foo', mock_open.call_args_list[-1][0][0])
182         self.assertIn('bar', mock_open.call_args_list[-1][0][0])
183
184         # test an IOError other than ENOENT
185         mock_open.side_effect = IOError(errno.EBUSY, 'busy')
186         with self.assertRaises(IOError):
187             utils.open_relative_file('foo', 'bar')
188
189         mock_open_call_count += 1  # one more call expected
190         self.assertEqual(mock_open.call_count, mock_open_call_count)
191
192
193 class TestMacAddressToHex(ut_base.BaseUnitTestCase):
194
195     def test_mac_address_to_hex_list(self):
196         self.assertEqual(utils.mac_address_to_hex_list("ea:3e:e1:9a:99:e8"),
197                          ['0xea', '0x3e', '0xe1', '0x9a', '0x99', '0xe8'])
198
199     def test_mac_address_to_hex_list_too_short_mac(self):
200         with self.assertRaises(exceptions.InvalidMacAddress):
201             utils.mac_address_to_hex_list("ea:3e:e1:9a")
202
203     def test_mac_address_to_hex_list_no_int_mac(self):
204         with self.assertRaises(exceptions.InvalidMacAddress):
205             utils.mac_address_to_hex_list("invalid_mac")
206
207
208 class TranslateToStrTestCase(ut_base.BaseUnitTestCase):
209
210     def test_translate_to_str_unicode(self):
211         input_str = u'hello'
212         output_str = utils.translate_to_str(input_str)
213
214         result = 'hello'
215         self.assertEqual(result, output_str)
216
217     def test_translate_to_str_dict_list_unicode(self):
218         input_str = {
219             u'hello': {u'hello': [u'world']}
220         }
221         output_str = utils.translate_to_str(input_str)
222
223         result = {
224             'hello': {'hello': ['world']}
225         }
226         self.assertEqual(result, output_str)
227
228     def test_translate_to_str_non_string(self):
229         input_value = object()
230         result = utils.translate_to_str(input_value)
231         self.assertIs(input_value, result)
232
233
234 class TestParseCpuInfo(ut_base.BaseUnitTestCase):
235
236     def test_single_socket_no_hyperthread(self):
237         cpuinfo = """\
238 processor       : 2
239 vendor_id       : GenuineIntel
240 cpu family      : 6
241 model           : 60
242 model name      : Intel Core Processor (Haswell, no TSX)
243 stepping        : 1
244 microcode       : 0x1
245 cpu MHz         : 2294.684
246 cache size      : 4096 KB
247 physical id     : 0
248 siblings        : 5
249 core id         : 2
250 cpu cores       : 5
251 apicid          : 2
252 initial apicid  : 2
253 fpu             : yes
254 fpu_exception   : yes
255 cpuid level     : 13
256 wp              : yes
257 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt arat
258 bugs            :
259 bogomips        : 4589.36
260 clflush size    : 64
261 cache_alignment : 64
262 address sizes   : 46 bits physical, 48 bits virtual
263 power management:
264
265 processor       : 3
266 vendor_id       : GenuineIntel
267 cpu family      : 6
268 model           : 60
269 model name      : Intel Core Processor (Haswell, no TSX)
270 stepping        : 1
271 microcode       : 0x1
272 cpu MHz         : 2294.684
273 cache size      : 4096 KB
274 physical id     : 0
275 siblings        : 5
276 core id         : 3
277 cpu cores       : 5
278 apicid          : 3
279 initial apicid  : 3
280 fpu             : yes
281 fpu_exception   : yes
282 cpuid level     : 13
283 wp              : yes
284 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt arat
285 bugs            :
286 bogomips        : 4589.36
287 clflush size    : 64
288 cache_alignment : 64
289 address sizes   : 46 bits physical, 48 bits virtual
290 power management:
291
292 processor       : 4
293 vendor_id       : GenuineIntel
294 cpu family      : 6
295 model           : 60
296 model name      : Intel Core Processor (Haswell, no TSX)
297 stepping        : 1
298 microcode       : 0x1
299 cpu MHz         : 2294.684
300 cache size      : 4096 KB
301 physical id     : 0
302 siblings        : 5
303 core id         : 4
304 cpu cores       : 5
305 apicid          : 4
306 initial apicid  : 4
307 fpu             : yes
308 fpu_exception   : yes
309 cpuid level     : 13
310 wp              : yes
311 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt arat
312 bugs            :
313 bogomips        : 4589.36
314 clflush size    : 64
315 cache_alignment : 64
316 address sizes   : 46 bits physical, 48 bits virtual
317 power management:
318
319 """
320         socket_map = utils.SocketTopology.parse_cpuinfo(cpuinfo)
321         self.assertEqual(sorted(socket_map.keys()), [0])
322         self.assertEqual(sorted(socket_map[0].keys()), [2, 3, 4])
323
324     def test_single_socket_hyperthread(self):
325         cpuinfo = """\
326 processor       : 5
327 vendor_id       : GenuineIntel
328 cpu family      : 6
329 model           : 60
330 model name      : Intel(R) Xeon(R) CPU E3-1275 v3 @ 3.50GHz
331 stepping        : 3
332 microcode       : 0x1d
333 cpu MHz         : 3501.708
334 cache size      : 8192 KB
335 physical id     : 0
336 siblings        : 8
337 core id         : 1
338 cpu cores       : 4
339 apicid          : 3
340 initial apicid  : 3
341 fpu             : yes
342 fpu_exception   : yes
343 cpuid level     : 13
344 wp              : yes
345 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts
346 bugs            :
347 bogomips        : 6987.36
348 clflush size    : 64
349 cache_alignment : 64
350 address sizes   : 39 bits physical, 48 bits virtual
351 power management:
352
353 processor       : 6
354 vendor_id       : GenuineIntel
355 cpu family      : 6
356 model           : 60
357 model name      : Intel(R) Xeon(R) CPU E3-1275 v3 @ 3.50GHz
358 stepping        : 3
359 microcode       : 0x1d
360 cpu MHz         : 3531.829
361 cache size      : 8192 KB
362 physical id     : 0
363 siblings        : 8
364 core id         : 2
365 cpu cores       : 4
366 apicid          : 5
367 initial apicid  : 5
368 fpu             : yes
369 fpu_exception   : yes
370 cpuid level     : 13
371 wp              : yes
372 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts
373 bugs            :
374 bogomips        : 6987.36
375 clflush size    : 64
376 cache_alignment : 64
377 address sizes   : 39 bits physical, 48 bits virtual
378 power management:
379
380 processor       : 7
381 vendor_id       : GenuineIntel
382 cpu family      : 6
383 model           : 60
384 model name      : Intel(R) Xeon(R) CPU E3-1275 v3 @ 3.50GHz
385 stepping        : 3
386 microcode       : 0x1d
387 cpu MHz         : 3500.213
388 cache size      : 8192 KB
389 physical id     : 0
390 siblings        : 8
391 core id         : 3
392 cpu cores       : 4
393 apicid          : 7
394 initial apicid  : 7
395 fpu             : yes
396 fpu_exception   : yes
397 cpuid level     : 13
398 wp              : yes
399 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts
400 bugs            :
401 bogomips        : 6987.24
402 clflush size    : 64
403 cache_alignment : 64
404 address sizes   : 39 bits physical, 48 bits virtual
405 power management:
406
407 """
408         socket_map = utils.SocketTopology.parse_cpuinfo(cpuinfo)
409         self.assertEqual(sorted(socket_map.keys()), [0])
410         self.assertEqual(sorted(socket_map[0].keys()), [1, 2, 3])
411         self.assertEqual(sorted(socket_map[0][1]), [5])
412         self.assertEqual(sorted(socket_map[0][2]), [6])
413         self.assertEqual(sorted(socket_map[0][3]), [7])
414
415     def test_dual_socket_hyperthread(self):
416         cpuinfo = """\
417 processor       : 1
418 vendor_id       : GenuineIntel
419 cpu family      : 6
420 model           : 79
421 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
422 stepping        : 1
423 microcode       : 0xb00001f
424 cpu MHz         : 1200.976
425 cache size      : 56320 KB
426 physical id     : 0
427 siblings        : 44
428 core id         : 1
429 cpu cores       : 22
430 apicid          : 2
431 initial apicid  : 2
432 fpu             : yes
433 fpu_exception   : yes
434 cpuid level     : 20
435 wp              : yes
436 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
437 bugs            :
438 bogomips        : 4401.07
439 clflush size    : 64
440 cache_alignment : 64
441 address sizes   : 46 bits physical, 48 bits virtual
442 power management:
443
444 processor       : 2
445 vendor_id       : GenuineIntel
446 cpu family      : 6
447 model           : 79
448 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
449 stepping        : 1
450 microcode       : 0xb00001f
451 cpu MHz         : 1226.892
452 cache size      : 56320 KB
453 physical id     : 0
454 siblings        : 44
455 core id         : 2
456 cpu cores       : 22
457 apicid          : 4
458 initial apicid  : 4
459 fpu             : yes
460 fpu_exception   : yes
461 cpuid level     : 20
462 wp              : yes
463 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
464 bugs            :
465 bogomips        : 4400.84
466 clflush size    : 64
467 cache_alignment : 64
468 address sizes   : 46 bits physical, 48 bits virtual
469 power management:
470
471 processor       : 43
472 vendor_id       : GenuineIntel
473 cpu family      : 6
474 model           : 79
475 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
476 stepping        : 1
477 microcode       : 0xb00001f
478 cpu MHz         : 1200.305
479 cache size      : 56320 KB
480 physical id     : 1
481 siblings        : 44
482 core id         : 28
483 cpu cores       : 22
484 apicid          : 120
485 initial apicid  : 120
486 fpu             : yes
487 fpu_exception   : yes
488 cpuid level     : 20
489 wp              : yes
490 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
491 bugs            :
492 bogomips        : 4411.31
493 clflush size    : 64
494 cache_alignment : 64
495 address sizes   : 46 bits physical, 48 bits virtual
496 power management:
497
498 processor       : 44
499 vendor_id       : GenuineIntel
500 cpu family      : 6
501 model           : 79
502 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
503 stepping        : 1
504 microcode       : 0xb00001f
505 cpu MHz         : 1200.305
506 cache size      : 56320 KB
507 physical id     : 0
508 siblings        : 44
509 core id         : 0
510 cpu cores       : 22
511 apicid          : 1
512 initial apicid  : 1
513 fpu             : yes
514 fpu_exception   : yes
515 cpuid level     : 20
516 wp              : yes
517 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
518 bugs            :
519 bogomips        : 4410.61
520 clflush size    : 64
521 cache_alignment : 64
522 address sizes   : 46 bits physical, 48 bits virtual
523 power management:
524
525 processor       : 85
526 vendor_id       : GenuineIntel
527 cpu family      : 6
528 model           : 79
529 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
530 stepping        : 1
531 microcode       : 0xb00001f
532 cpu MHz         : 1200.573
533 cache size      : 56320 KB
534 physical id     : 1
535 siblings        : 44
536 core id         : 26
537 cpu cores       : 22
538 apicid          : 117
539 initial apicid  : 117
540 fpu             : yes
541 fpu_exception   : yes
542 cpuid level     : 20
543 wp              : yes
544 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
545 bugs            :
546 bogomips        : 4409.07
547 clflush size    : 64
548 cache_alignment : 64
549 address sizes   : 46 bits physical, 48 bits virtual
550 power management:
551
552 processor       : 86
553 vendor_id       : GenuineIntel
554 cpu family      : 6
555 model           : 79
556 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
557 stepping        : 1
558 microcode       : 0xb00001f
559 cpu MHz         : 1200.305
560 cache size      : 56320 KB
561 physical id     : 1
562 siblings        : 44
563 core id         : 27
564 cpu cores       : 22
565 apicid          : 119
566 initial apicid  : 119
567 fpu             : yes
568 fpu_exception   : yes
569 cpuid level     : 20
570 wp              : yes
571 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
572 bugs            :
573 bogomips        : 4406.62
574 clflush size    : 64
575 cache_alignment : 64
576 address sizes   : 46 bits physical, 48 bits virtual
577 power management:
578
579 processor       : 87
580 vendor_id       : GenuineIntel
581 cpu family      : 6
582 model           : 79
583 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
584 stepping        : 1
585 microcode       : 0xb00001f
586 cpu MHz         : 1200.708
587 cache size      : 56320 KB
588 physical id     : 1
589 siblings        : 44
590 core id         : 28
591 cpu cores       : 22
592 apicid          : 121
593 initial apicid  : 121
594 fpu             : yes
595 fpu_exception   : yes
596 cpuid level     : 20
597 wp              : yes
598 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
599 bugs            :
600 bogomips        : 4413.48
601 clflush size    : 64
602 cache_alignment : 64
603 address sizes   : 46 bits physical, 48 bits virtual
604 power management:
605
606 """
607         socket_map = utils.SocketTopology.parse_cpuinfo(cpuinfo)
608         self.assertEqual(sorted(socket_map.keys()), [0, 1])
609         self.assertEqual(sorted(socket_map[0].keys()), [0, 1, 2])
610         self.assertEqual(sorted(socket_map[1].keys()), [26, 27, 28])
611         self.assertEqual(sorted(socket_map[0][0]), [44])
612         self.assertEqual(sorted(socket_map[0][1]), [1])
613         self.assertEqual(sorted(socket_map[0][2]), [2])
614         self.assertEqual(sorted(socket_map[1][26]), [85])
615         self.assertEqual(sorted(socket_map[1][27]), [86])
616         self.assertEqual(sorted(socket_map[1][28]), [43, 87])
617
618     def test_dual_socket_no_hyperthread(self):
619         cpuinfo = """\
620 processor       : 1
621 vendor_id       : GenuineIntel
622 cpu family      : 6
623 model           : 79
624 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
625 stepping        : 1
626 microcode       : 0xb00001f
627 cpu MHz         : 1200.976
628 cache size      : 56320 KB
629 physical id     : 0
630 siblings        : 44
631 core id         : 1
632 cpu cores       : 22
633 apicid          : 2
634 initial apicid  : 2
635 fpu             : yes
636 fpu_exception   : yes
637 cpuid level     : 20
638 wp              : yes
639 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
640 bugs            :
641 bogomips        : 4401.07
642 clflush size    : 64
643 cache_alignment : 64
644 address sizes   : 46 bits physical, 48 bits virtual
645 power management:
646
647 processor       : 2
648 vendor_id       : GenuineIntel
649 cpu family      : 6
650 model           : 79
651 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
652 stepping        : 1
653 microcode       : 0xb00001f
654 cpu MHz         : 1226.892
655 cache size      : 56320 KB
656 physical id     : 0
657 siblings        : 44
658 core id         : 2
659 cpu cores       : 22
660 apicid          : 4
661 initial apicid  : 4
662 fpu             : yes
663 fpu_exception   : yes
664 cpuid level     : 20
665 wp              : yes
666 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
667 bugs            :
668 bogomips        : 4400.84
669 clflush size    : 64
670 cache_alignment : 64
671 address sizes   : 46 bits physical, 48 bits virtual
672 power management:
673
674 processor       : 43
675 vendor_id       : GenuineIntel
676 cpu family      : 6
677 model           : 79
678 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
679 stepping        : 1
680 microcode       : 0xb00001f
681 cpu MHz         : 1200.305
682 cache size      : 56320 KB
683 physical id     : 1
684 siblings        : 44
685 core id         : 28
686 cpu cores       : 22
687 apicid          : 120
688 initial apicid  : 120
689 fpu             : yes
690 fpu_exception   : yes
691 cpuid level     : 20
692 wp              : yes
693 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
694 bugs            :
695 bogomips        : 4411.31
696 clflush size    : 64
697 cache_alignment : 64
698 address sizes   : 46 bits physical, 48 bits virtual
699 power management:
700
701 processor       : 44
702 vendor_id       : GenuineIntel
703 cpu family      : 6
704 model           : 79
705 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
706 stepping        : 1
707 microcode       : 0xb00001f
708 cpu MHz         : 1200.305
709 cache size      : 56320 KB
710 physical id     : 0
711 siblings        : 44
712 core id         : 0
713 cpu cores       : 22
714 apicid          : 1
715 initial apicid  : 1
716 fpu             : yes
717 fpu_exception   : yes
718 cpuid level     : 20
719 wp              : yes
720 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
721 bugs            :
722 bogomips        : 4410.61
723 clflush size    : 64
724 cache_alignment : 64
725 address sizes   : 46 bits physical, 48 bits virtual
726 power management:
727
728 processor       : 85
729 vendor_id       : GenuineIntel
730 cpu family      : 6
731 model           : 79
732 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
733 stepping        : 1
734 microcode       : 0xb00001f
735 cpu MHz         : 1200.573
736 cache size      : 56320 KB
737 physical id     : 1
738 siblings        : 44
739 core id         : 26
740 cpu cores       : 22
741 apicid          : 117
742 initial apicid  : 117
743 fpu             : yes
744 fpu_exception   : yes
745 cpuid level     : 20
746 wp              : yes
747 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
748 bugs            :
749 bogomips        : 4409.07
750 clflush size    : 64
751 cache_alignment : 64
752 address sizes   : 46 bits physical, 48 bits virtual
753 power management:
754
755 processor       : 86
756 vendor_id       : GenuineIntel
757 cpu family      : 6
758 model           : 79
759 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
760 stepping        : 1
761 microcode       : 0xb00001f
762 cpu MHz         : 1200.305
763 cache size      : 56320 KB
764 physical id     : 1
765 siblings        : 44
766 core id         : 27
767 cpu cores       : 22
768 apicid          : 119
769 initial apicid  : 119
770 fpu             : yes
771 fpu_exception   : yes
772 cpuid level     : 20
773 wp              : yes
774 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
775 bugs            :
776 bogomips        : 4406.62
777 clflush size    : 64
778 cache_alignment : 64
779 address sizes   : 46 bits physical, 48 bits virtual
780 power management:
781
782 processor       : 87
783 vendor_id       : GenuineIntel
784 cpu family      : 6
785 model           : 79
786 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
787 stepping        : 1
788 microcode       : 0xb00001f
789 cpu MHz         : 1200.708
790 cache size      : 56320 KB
791 physical id     : 1
792 siblings        : 44
793 core id         : 28
794 cpu cores       : 22
795 apicid          : 121
796 initial apicid  : 121
797 fpu             : yes
798 fpu_exception   : yes
799 cpuid level     : 20
800 wp              : yes
801 flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
802 bugs            :
803 bogomips        : 4413.48
804 clflush size    : 64
805 cache_alignment : 64
806 address sizes   : 46 bits physical, 48 bits virtual
807 power management:
808
809 """
810         socket_map = utils.SocketTopology.parse_cpuinfo(cpuinfo)
811         processors = socket_map.processors()
812         self.assertEqual(processors, [1, 2, 43, 44, 85, 86, 87])
813         cores = socket_map.cores()
814         self.assertEqual(cores, [0, 1, 2, 26, 27, 28])
815         sockets = socket_map.sockets()
816         self.assertEqual(sockets, [0, 1])
817
818
819 class ChangeObjToDictTestCase(ut_base.BaseUnitTestCase):
820
821     def test_change_obj_to_dict(self):
822         class A(object):
823             def __init__(self):
824                 self.name = 'yardstick'
825
826         obj = A()
827         obj_r = utils.change_obj_to_dict(obj)
828         obj_s = {'name': 'yardstick'}
829         self.assertEqual(obj_r, obj_s)
830
831
832 class SetDictValueTestCase(ut_base.BaseUnitTestCase):
833
834     def test_set_dict_value(self):
835         input_dic = {
836             'hello': 'world'
837         }
838         output_dic = utils.set_dict_value(input_dic, 'welcome.to', 'yardstick')
839         self.assertEqual(output_dic.get('welcome', {}).get('to'), 'yardstick')
840
841
842 class RemoveFileTestCase(ut_base.BaseUnitTestCase):
843
844     def test_remove_file(self):
845         try:
846             utils.remove_file('notexistfile.txt')
847         except Exception as e:  # pylint: disable=broad-except
848             # NOTE(ralonsoh): to narrow the scope of this exception.
849             self.assertTrue(isinstance(e, OSError))
850
851
852 class ParseIniFileTestCase(ut_base.BaseUnitTestCase):
853
854     def setUp(self):
855         self._mock_config_parser_type = mock.patch.object(configparser,
856                                                           'ConfigParser')
857         self.mock_config_parser_type = self._mock_config_parser_type.start()
858         self.addCleanup(self._stop_mocks)
859
860     def _stop_mocks(self):
861         self._mock_config_parser_type.stop()
862
863     def test_parse_ini_file(self):
864         defaults = {'default1': 'value1',
865                     'default2': 'value2'}
866         s1 = {'key1': 'value11',
867               'key2': 'value22'}
868         s2 = {'key1': 'value123',
869               'key2': 'value234'}
870
871         mock_config_parser = mock.Mock()
872         self.mock_config_parser_type.return_value = mock_config_parser
873         mock_config_parser.read.return_value = True
874         mock_config_parser.sections.return_value = ['s1', 's2']
875         mock_config_parser.items.side_effect = iter([
876             defaults.items(),
877             s1.items(),
878             s2.items(),
879         ])
880
881         expected = {'DEFAULT': defaults,
882                     's1': s1,
883                     's2': s2}
884         result = utils.parse_ini_file('my_path')
885         self.assertDictEqual(expected, result)
886
887     @mock.patch.object(utils, 'logger')
888     def test_parse_ini_file_missing_section_header(self, *args):
889         mock_config_parser = mock.Mock()
890         self.mock_config_parser_type.return_value = mock_config_parser
891         mock_config_parser.read.side_effect = (
892             configparser.MissingSectionHeaderError(
893                 mock.Mock(), 321, mock.Mock()))
894
895         with self.assertRaises(configparser.MissingSectionHeaderError):
896             utils.parse_ini_file('my_path')
897
898     def test_parse_ini_file_no_file(self):
899         mock_config_parser = mock.Mock()
900         self.mock_config_parser_type.return_value = mock_config_parser
901         mock_config_parser.read.return_value = False
902         with self.assertRaises(RuntimeError):
903             utils.parse_ini_file('my_path')
904
905     def test_parse_ini_file_no_default_section_header(self):
906         s1 = {'key1': 'value11',
907               'key2': 'value22'}
908         s2 = {'key1': 'value123',
909               'key2': 'value234'}
910
911         mock_config_parser = mock.Mock()
912         self.mock_config_parser_type.return_value = mock_config_parser
913         mock_config_parser.read.return_value = True
914         mock_config_parser.sections.return_value = ['s1', 's2']
915         mock_config_parser.items.side_effect = iter([
916             configparser.NoSectionError(mock.Mock()),
917             s1.items(),
918             s2.items(),
919         ])
920
921         expected = {'DEFAULT': {},
922                     's1': s1,
923                     's2': s2}
924         result = utils.parse_ini_file('my_path')
925         self.assertDictEqual(expected, result)
926
927
928 class TestUtils(ut_base.BaseUnitTestCase):
929
930     @mock.patch('yardstick.common.utils.os.makedirs')
931     def test_makedirs(self, *_):
932         self.assertIsNone(utils.makedirs('a/b/c/d'))
933
934     @mock.patch('yardstick.common.utils.os.makedirs')
935     def test_makedirs_exists(self, mock_os_makedirs):
936         mock_os_makedirs.side_effect = OSError(errno.EEXIST, 'exists')
937         self.assertIsNone(utils.makedirs('a/b/c/d'))
938
939     @mock.patch('yardstick.common.utils.os.makedirs')
940     def test_makedirs_busy(self, mock_os_makedirs):
941         mock_os_makedirs.side_effect = OSError(errno.EBUSY, 'busy')
942         with self.assertRaises(OSError):
943             utils.makedirs('a/b/c/d')
944
945     @mock.patch('yardstick.common.utils.jsonify')
946     def test_result_handler(self, mock_jsonify):
947         mock_jsonify.return_value = 432
948
949         self.assertEqual(utils.result_handler('x', 234), 432)
950         mock_jsonify.assert_called_once_with({'status': 'x', 'result': 234})
951
952     @mock.patch('random.randint')
953     @mock.patch('socket.socket')
954     def test_get_free_port(self, mock_socket, mock_randint):
955         mock_randint.return_value = 7777
956         s = mock_socket('x', 'y')
957         s.connect_ex.side_effect = iter([0, 1])
958         result = utils.get_free_port('10.20.30.40')
959         self.assertEqual(result, 7777)
960         self.assertEqual(s.connect_ex.call_count, 2)
961
962     @mock.patch('subprocess.check_output')
963     def test_execute_command(self, mock_check_output):
964         expected = ['hello world', '1234']
965         mock_check_output.return_value = os.linesep.join(expected)
966         result = utils.execute_command('my_command arg1 arg2')
967         self.assertEqual(result, expected)
968
969     @mock.patch('subprocess.Popen')
970     def test_source_env(self, mock_popen):
971         base_env = deepcopy(os.environ)
972         mock_process = mock_popen()
973         output_list = [
974             'garbage line before',
975             'NEW_ENV_VALUE=234',
976             'garbage line after',
977         ]
978         mock_process.communicate.return_value = os.linesep.join(output_list), '', 0
979         expected = {'NEW_ENV_VALUE': '234'}
980         result = utils.source_env('my_file')
981         self.assertDictEqual(result, expected)
982         os.environ.clear()
983         os.environ.update(base_env)
984
985     @mock.patch.object(configparser, 'ConfigParser')
986     def test_parse_ini_file(self, mock_config_parser_type):
987         defaults = {
988             'default1': 'value1',
989             'default2': 'value2',
990         }
991         s1 = {
992             'key1': 'value11',
993             'key2': 'value22',
994         }
995         s2 = {
996             'key1': 'value123',
997             'key2': 'value234',
998         }
999
1000         mock_config_parser = mock_config_parser_type()
1001         mock_config_parser.read.return_value = True
1002         mock_config_parser.sections.return_value = ['s1', 's2']
1003         mock_config_parser.items.side_effect = iter([
1004             defaults.items(),
1005             s1.items(),
1006             s2.items(),
1007         ])
1008
1009         expected = {
1010             'DEFAULT': defaults,
1011             's1': s1,
1012             's2': s2,
1013         }
1014         result = utils.parse_ini_file('my_path')
1015         self.assertDictEqual(result, expected)
1016
1017     @mock.patch.object(utils, 'logger')
1018     @mock.patch.object(configparser, 'ConfigParser')
1019     def test_parse_ini_file_missing_section_header(
1020             self, mock_config_parser_type, *args):
1021         mock_config_parser = mock_config_parser_type()
1022         mock_config_parser.read.side_effect = (
1023             configparser.MissingSectionHeaderError(mock.Mock(), 321,
1024                                                    mock.Mock()))
1025
1026         with self.assertRaises(configparser.MissingSectionHeaderError):
1027             utils.parse_ini_file('my_path')
1028
1029     @mock.patch.object(configparser, 'ConfigParser')
1030     def test_parse_ini_file_no_file(self, mock_config_parser_type):
1031         mock_config_parser = mock_config_parser_type()
1032         mock_config_parser.read.return_value = False
1033         with self.assertRaises(RuntimeError):
1034             utils.parse_ini_file('my_path')
1035
1036     @mock.patch.object(configparser, 'ConfigParser')
1037     def test_parse_ini_file_no_default_section_header(self, mock_config_parser_type):
1038         s1 = {
1039             'key1': 'value11',
1040             'key2': 'value22',
1041         }
1042         s2 = {
1043             'key1': 'value123',
1044             'key2': 'value234',
1045         }
1046
1047         mock_config_parser = mock_config_parser_type()
1048         mock_config_parser.read.return_value = True
1049         mock_config_parser.sections.return_value = ['s1', 's2']
1050         mock_config_parser.items.side_effect = iter([
1051             configparser.NoSectionError(mock.Mock()),
1052             s1.items(),
1053             s2.items(),
1054         ])
1055
1056         expected = {
1057             'DEFAULT': {},
1058             's1': s1,
1059             's2': s2,
1060         }
1061         result = utils.parse_ini_file('my_path')
1062         self.assertDictEqual(result, expected)
1063
1064     def test_join_non_strings(self):
1065         self.assertEqual(utils.join_non_strings(':'), '')
1066         self.assertEqual(utils.join_non_strings(':', 'a'), 'a')
1067         self.assertEqual(utils.join_non_strings(':', 'a', 2, 'c'), 'a:2:c')
1068         self.assertEqual(utils.join_non_strings(':', ['a', 2, 'c']), 'a:2:c')
1069         self.assertEqual(utils.join_non_strings(':', 'abc'), 'abc')
1070
1071     def test_validate_non_string_sequence(self):
1072         self.assertEqual(utils.validate_non_string_sequence([1, 2, 3]), [1, 2, 3])
1073         self.assertIsNone(utils.validate_non_string_sequence('123'))
1074         self.assertIsNone(utils.validate_non_string_sequence(1))
1075
1076         self.assertEqual(utils.validate_non_string_sequence(1, 2), 2)
1077         self.assertEqual(utils.validate_non_string_sequence(1, default=2), 2)
1078
1079         with self.assertRaises(RuntimeError):
1080             utils.validate_non_string_sequence(1, raise_exc=RuntimeError)
1081
1082
1083 class TestUtilsIpAddrMethods(ut_base.BaseUnitTestCase):
1084
1085     GOOD_IP_V4_ADDRESS_STR_LIST = [
1086         u'0.0.0.0',
1087         u'10.20.30.40',
1088         u'127.0.0.1',
1089         u'10.20.30.40',
1090         u'172.29.50.75',
1091         u'192.168.230.9',
1092         u'255.255.255.255',
1093     ]
1094
1095     GOOD_IP_V4_MASK_STR_LIST = [
1096         u'/1',
1097         u'/8',
1098         u'/13',
1099         u'/19',
1100         u'/24',
1101         u'/32',
1102     ]
1103
1104     GOOD_IP_V6_ADDRESS_STR_LIST = [
1105         u'::1',
1106         u'fe80::250:56ff:fe89:91ff',
1107         u'123:4567:89ab:cdef:123:4567:89ab:cdef',
1108     ]
1109
1110     GOOD_IP_V6_MASK_STR_LIST = [
1111         u'/1',
1112         u'/16',
1113         u'/29',
1114         u'/64',
1115         u'/99',
1116         u'/128',
1117     ]
1118
1119     INVALID_IP_ADDRESS_STR_LIST = [
1120         1,
1121         u'w.x.y.z',
1122         u'10.20.30.40/33',
1123         u'123:4567:89ab:cdef:123:4567:89ab:cdef/129',
1124     ]
1125
1126     def test_make_ipv4_address(self):
1127         for addr in self.GOOD_IP_V4_ADDRESS_STR_LIST:
1128             # test with no mask
1129             expected = ipaddress.IPv4Address(addr)
1130             self.assertEqual(utils.make_ipv4_address(addr), expected, addr)
1131
1132     def test_make_ipv4_address_error(self):
1133         addr_list = self.INVALID_IP_ADDRESS_STR_LIST +\
1134                     self.GOOD_IP_V6_ADDRESS_STR_LIST
1135         for addr in addr_list:
1136             self.assertRaises(Exception, utils.make_ipv4_address, addr)
1137
1138
1139     def test_safe_ip_address(self):
1140         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1141         for addr in addr_list:
1142             # test with no mask
1143             expected = ipaddress.ip_address(addr)
1144             self.assertEqual(utils.safe_ip_address(addr), expected, addr)
1145
1146     def test_safe_ip_address_v6_ip(self):
1147         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1148         for addr in addr_list:
1149             # test with no mask
1150             expected = ipaddress.ip_address(addr)
1151             self.assertEqual(utils.safe_ip_address(addr), expected, addr)
1152
1153     @mock.patch("yardstick.common.utils.logging")
1154     def test_safe_ip_address_negative(self, *args):
1155         # NOTE(ralonsoh): check the calls to mocked functions.
1156         for value in self.INVALID_IP_ADDRESS_STR_LIST:
1157             self.assertIsNone(utils.safe_ip_address(value), value)
1158
1159         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1160         mask_list = self.GOOD_IP_V4_MASK_STR_LIST
1161         for addr_mask_pair in product(addr_list, mask_list):
1162             value = ''.join(addr_mask_pair)
1163             self.assertIsNone(utils.safe_ip_address(value), value)
1164
1165         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1166         mask_list = self.GOOD_IP_V6_MASK_STR_LIST
1167         for addr_mask_pair in product(addr_list, mask_list):
1168             value = ''.join(addr_mask_pair)
1169             self.assertIsNone(utils.safe_ip_address(value), value)
1170
1171     def test_get_ip_version(self):
1172         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1173         for addr in addr_list:
1174             # test with no mask
1175             self.assertEqual(utils.get_ip_version(addr), 4, addr)
1176
1177     def test_get_ip_version_v6_ip(self):
1178         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1179         for addr in addr_list:
1180             # test with no mask
1181             self.assertEqual(utils.get_ip_version(addr), 6, addr)
1182
1183     @mock.patch("yardstick.common.utils.logging")
1184     def test_get_ip_version_negative(self, *args):
1185         # NOTE(ralonsoh): check the calls to mocked functions.
1186         for value in self.INVALID_IP_ADDRESS_STR_LIST:
1187             self.assertIsNone(utils.get_ip_version(value), value)
1188
1189         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1190         mask_list = self.GOOD_IP_V4_MASK_STR_LIST
1191         for addr_mask_pair in product(addr_list, mask_list):
1192             value = ''.join(addr_mask_pair)
1193             self.assertIsNone(utils.get_ip_version(value), value)
1194
1195         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1196         mask_list = self.GOOD_IP_V6_MASK_STR_LIST
1197         for addr_mask_pair in product(addr_list, mask_list):
1198             value = ''.join(addr_mask_pair)
1199             self.assertIsNone(utils.get_ip_version(value), value)
1200
1201     def test_ip_to_hex(self):
1202         self.assertEqual(utils.ip_to_hex('0.0.0.0'), '00000000')
1203         self.assertEqual(utils.ip_to_hex('10.20.30.40'), '0a141e28')
1204         self.assertEqual(utils.ip_to_hex('127.0.0.1'), '7f000001')
1205         self.assertEqual(utils.ip_to_hex('172.31.90.100'), 'ac1f5a64')
1206         self.assertEqual(utils.ip_to_hex('192.168.254.253'), 'c0a8fefd')
1207         self.assertEqual(utils.ip_to_hex('255.255.255.255'), 'ffffffff')
1208
1209     def test_ip_to_hex_v6_ip(self):
1210         for value in self.GOOD_IP_V6_ADDRESS_STR_LIST:
1211             self.assertEqual(utils.ip_to_hex(value), value)
1212
1213     @mock.patch("yardstick.common.utils.logging")
1214     def test_ip_to_hex_negative(self, *args):
1215         # NOTE(ralonsoh): check the calls to mocked functions.
1216         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1217         mask_list = self.GOOD_IP_V4_MASK_STR_LIST
1218         value_iter = (''.join(pair) for pair in product(addr_list, mask_list))
1219         for value in chain(value_iter, self.INVALID_IP_ADDRESS_STR_LIST):
1220             self.assertEqual(utils.ip_to_hex(value), value)
1221
1222     def test_get_mask_from_ip_range_ipv4(self):
1223         ip_str = '1.1.1.1'
1224         for mask in range(8, 30):
1225             ip = ipaddress.ip_network(ip_str + '/' + str(mask), strict=False)
1226             result = utils.get_mask_from_ip_range(ip[2], ip[-2])
1227             self.assertEqual(mask, result)
1228
1229     def test_get_mask_from_ip_range_ipv6(self):
1230         ip_str = '2001::1'
1231         for mask in range(8, 120):
1232             ip = ipaddress.ip_network(ip_str + '/' + str(mask), strict=False)
1233             result = utils.get_mask_from_ip_range(ip[2], ip[-2])
1234             self.assertEqual(mask, result)
1235
1236
1237 class SafeDecodeUtf8TestCase(ut_base.BaseUnitTestCase):
1238
1239     @unittest.skipIf(six.PY2,
1240                      'This test should only be launched with Python 3.x')
1241     def test_safe_decode_utf8(self):
1242         _bytes = b'this is a byte array'
1243         out = utils.safe_decode_utf8(_bytes)
1244         self.assertIs(type(out), str)
1245         self.assertEqual('this is a byte array', out)
1246
1247
1248 class ReadMeminfoTestCase(ut_base.BaseUnitTestCase):
1249
1250     MEMINFO = (b'MemTotal:       65860500 kB\n'
1251                b'MemFree:        28690900 kB\n'
1252                b'MemAvailable:   52873764 kB\n'
1253                b'Active(anon):    3015676 kB\n'
1254                b'HugePages_Total:       8\n'
1255                b'Hugepagesize:    1048576 kB')
1256     MEMINFO_DICT = {'MemTotal': '65860500',
1257                     'MemFree': '28690900',
1258                     'MemAvailable': '52873764',
1259                     'Active(anon)': '3015676',
1260                     'HugePages_Total': '8',
1261                     'Hugepagesize': '1048576'}
1262
1263     def test_read_meminfo(self):
1264         ssh_client = ssh.SSH('user', 'host')
1265         with mock.patch.object(ssh_client, 'get_file_obj') as \
1266                 mock_get_client, \
1267                 mock.patch.object(six, 'BytesIO',
1268                                   return_value=six.BytesIO(self.MEMINFO)):
1269             output = utils.read_meminfo(ssh_client)
1270             mock_get_client.assert_called_once_with('/proc/meminfo', mock.ANY)
1271         self.assertEqual(self.MEMINFO_DICT, output)
1272
1273
1274 class TimerTestCase(ut_base.BaseUnitTestCase):
1275
1276     def test__getattr(self):
1277         with utils.Timer() as timer:
1278             time.sleep(1)
1279         self.assertEqual(1, round(timer.total_seconds(), 0))
1280         self.assertEqual(1, timer.delta.seconds)
1281
1282     def test__enter_with_timeout(self):
1283         with utils.Timer(timeout=10) as timer:
1284             time.sleep(1)
1285         self.assertEqual(1, round(timer.total_seconds(), 0))
1286
1287     def test__enter_with_timeout_exception(self):
1288         with self.assertRaises(exceptions.TimerTimeout):
1289             with utils.Timer(timeout=1):
1290                 time.sleep(2)
1291
1292     def test__enter_with_timeout_no_exception(self):
1293         with utils.Timer(timeout=1, raise_exception=False):
1294             time.sleep(2)
1295
1296     def test__iter(self):
1297         iterations = []
1298         for i in utils.Timer(timeout=2):
1299             iterations.append(i)
1300             time.sleep(1.1)
1301         self.assertEqual(2, len(iterations))
1302
1303     def test_delta_time_sec(self):
1304         with utils.Timer() as timer:
1305             self.assertIsInstance(timer.delta_time_sec(), float)
1306
1307
1308 class WaitUntilTrueTestCase(ut_base.BaseUnitTestCase):
1309
1310     def test_no_timeout(self):
1311         self.assertIsNone(utils.wait_until_true(lambda: True,
1312                                                 timeout=1, sleep=1))
1313
1314     def test_timeout_generic_exception(self):
1315         with self.assertRaises(exceptions.WaitTimeout):
1316             self.assertIsNone(utils.wait_until_true(lambda: False,
1317                                                     timeout=1, sleep=1))
1318
1319     def test_timeout_given_exception(self):
1320         class MyTimeoutException(exceptions.YardstickException):
1321             message = 'My timeout exception'
1322
1323         with self.assertRaises(MyTimeoutException):
1324             self.assertIsNone(
1325                 utils.wait_until_true(lambda: False, timeout=1, sleep=1,
1326                                       exception=MyTimeoutException))
1327
1328     def _run_thread(self):
1329         with self.assertRaises(exceptions.WaitTimeout):
1330             utils.wait_until_true(lambda: False, timeout=1, sleep=1)
1331
1332     def test_timeout_no_main_thread(self):
1333         new_thread = threading.Thread(target=self._run_thread)
1334         new_thread.start()
1335         new_thread.join(timeout=3)
1336
1337
1338 class SendSocketCommandTestCase(unittest.TestCase):
1339
1340     @mock.patch.object(socket, 'socket')
1341     def test_execute_correct(self, mock_socket):
1342         mock_socket_obj = mock.Mock()
1343         mock_socket_obj.connect_ex.return_value = 0
1344         mock_socket.return_value = mock_socket_obj
1345         self.assertEqual(0, utils.send_socket_command('host', 22, 'command'))
1346         mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_STREAM)
1347         mock_socket_obj.connect_ex.assert_called_once_with(('host', 22))
1348         mock_socket_obj.sendall.assert_called_once_with(six.b('command'))
1349         mock_socket_obj.close.assert_called_once()
1350
1351     @mock.patch.object(socket, 'socket')
1352     def test_execute_exception(self, mock_socket):
1353         mock_socket_obj = mock.Mock()
1354         mock_socket_obj.connect_ex.return_value = 0
1355         mock_socket.return_value = mock_socket_obj
1356         mock_socket_obj.sendall.side_effect = socket.error
1357         self.assertEqual(1, utils.send_socket_command('host', 22, 'command'))
1358         mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_STREAM)
1359         mock_socket_obj.connect_ex.assert_called_once_with(('host', 22))
1360         mock_socket_obj.sendall.assert_called_once_with(six.b('command'))
1361         mock_socket_obj.close.assert_called_once()
1362
1363
1364 class GetPortMacTestCase(unittest.TestCase):
1365
1366     def setUp(self):
1367         self.ssh_client = mock.Mock()
1368         self.ssh_client.execute.return_value = (0, 'foo    ', '')
1369
1370     def test_ssh_client_execute_called(self):
1371         utils.get_port_mac(self.ssh_client, 99)
1372         self.ssh_client.execute.assert_called_once_with(
1373             "ifconfig |grep HWaddr |grep 99 |awk '{print $5}' ",
1374             raise_on_error=True)
1375
1376     def test_return_value(self):
1377         self.assertEqual('foo', utils.get_port_mac(self.ssh_client, 99))
1378
1379
1380 class GetPortIPTestCase(unittest.TestCase):
1381
1382     def setUp(self):
1383         self.ssh_client = mock.Mock()
1384         self.ssh_client.execute.return_value = (0, 'foo    ', '')
1385
1386     def test_ssh_client_execute_called(self):
1387         utils.get_port_ip(self.ssh_client, 99)
1388         self.ssh_client.execute.assert_called_once_with(
1389             "ifconfig 99 |grep 'inet addr' |awk '{print $2}' |cut -d ':' -f2 ",
1390             raise_on_error=True)
1391
1392     def test_return_value(self):
1393         self.assertEqual('foo', utils.get_port_ip(self.ssh_client, 99))
1394
1395
1396 class SafeCaseTestCase(unittest.TestCase):
1397
1398     def test_correct_type_int(self):
1399         self.assertEqual(35, utils.safe_cast('35', int, 0))
1400
1401     def test_correct_int_as_string(self):
1402         self.assertEqual(25, utils.safe_cast('25', 'int', 0))
1403
1404     def test_incorrect_type_as_string(self):
1405         with self.assertRaises(exceptions.InvalidType):
1406             utils.safe_cast('100', 'intt', 0)
1407
1408     def test_default_value(self):
1409         self.assertEqual(0, utils.safe_cast('', 'int', 0))