Merge changes from topics 'YARDSTICK-1218', 'YARDSTICK-1216', 'YARDSTICK-1215', ...
[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 mock
16 import os
17 import six
18 from six.moves import configparser
19 import time
20 import unittest
21
22 import yardstick
23 from yardstick import ssh
24 from yardstick.common import constants
25 from yardstick.common import utils
26 from yardstick.common import exceptions
27
28
29 class IterSubclassesTestCase(unittest.TestCase):
30     # Disclaimer: this class is a modified copy from
31     # rally/tests/unit/common/plugin/test_discover.py
32     # Copyright 2015: Mirantis Inc.
33
34     def test_itersubclasses(self):
35         class A(object):
36             pass
37
38         class B(A):
39             pass
40
41         class C(A):
42             pass
43
44         class D(C):
45             pass
46
47         self.assertEqual([B, C, D], list(utils.itersubclasses(A)))
48
49
50 class ImportModulesFromPackageTestCase(unittest.TestCase):
51
52     @mock.patch('yardstick.common.utils.os.walk')
53     def test_import_modules_from_package_no_mod(self, mock_walk):
54         yardstick_root = os.path.dirname(os.path.dirname(yardstick.__file__))
55         mock_walk.return_value = ([
56             (os.path.join(yardstick_root, 'foo'), ['bar'], ['__init__.py']),
57             (os.path.join(yardstick_root, 'foo', 'bar'), [], ['baz.txt', 'qux.rst'])
58         ])
59
60         utils.import_modules_from_package('foo.bar')
61
62     @mock.patch('yardstick.common.utils.os.walk')
63     @mock.patch.object(importlib, 'import_module')
64     def test_import_modules_from_package(self, mock_import_module, mock_walk):
65
66         yardstick_root = os.path.dirname(os.path.dirname(yardstick.__file__))
67         mock_walk.return_value = ([
68             (os.path.join(yardstick_root, 'foo', os.pardir, 'bar'), [], ['baz.py'])
69         ])
70
71         utils.import_modules_from_package('foo.bar')
72         mock_import_module.assert_called_once_with('bar.baz')
73
74
75 class GetParaFromYaml(unittest.TestCase):
76
77     @mock.patch('yardstick.common.utils.os.environ.get')
78     def test_get_param_para_not_found(self, get_env):
79         file_path = 'config_sample.yaml'
80         get_env.return_value = self._get_file_abspath(file_path)
81         args = 'releng.file'
82         default = 'hello'
83         self.assertTrue(constants.get_param(args, default), default)
84
85     @mock.patch('yardstick.common.utils.os.environ.get')
86     def test_get_param_para_exists(self, get_env):
87         file_path = 'config_sample.yaml'
88         get_env.return_value = self._get_file_abspath(file_path)
89         args = 'releng.dir'
90         para = '/home/opnfv/repos/releng'
91         self.assertEqual(para, constants.get_param(args))
92
93     def _get_file_abspath(self, filename):
94         curr_path = os.path.dirname(os.path.abspath(__file__))
95         file_path = os.path.join(curr_path, filename)
96         return file_path
97
98
99 class CommonUtilTestCase(unittest.TestCase):
100
101     def setUp(self):
102         self.data = {
103             "benchmark": {
104                 "data": {
105                     "mpstat": {
106                         "cpu0": {
107                             "%sys": "0.00",
108                             "%idle": "99.00"
109                         },
110                         "loadavg": [
111                             "1.09",
112                             "0.29"
113                         ]
114                     },
115                     "rtt": "1.03"
116                 }
117             }
118         }
119
120     def test__dict_key_flatten(self):
121         line = 'mpstat.loadavg1=0.29,rtt=1.03,mpstat.loadavg0=1.09,' \
122                'mpstat.cpu0.%idle=99.00,mpstat.cpu0.%sys=0.00'
123         # need to sort for assert to work
124         line = ",".join(sorted(line.split(',')))
125         flattened_data = utils.flatten_dict_key(
126             self.data['benchmark']['data'])
127         result = ",".join(
128             ("=".join(item) for item in sorted(flattened_data.items())))
129         self.assertEqual(result, line)
130
131     def test_get_key_with_default_negative(self):
132         with self.assertRaises(KeyError):
133             utils.get_key_with_default({}, 'key1')
134
135     @mock.patch('yardstick.common.utils.open', create=True)
136     def test_(self, mock_open):
137         mock_open.side_effect = IOError
138
139         with self.assertRaises(IOError):
140             utils.find_relative_file('my/path', 'task/path')
141
142         self.assertEqual(mock_open.call_count, 2)
143
144     @mock.patch('yardstick.common.utils.open', create=True)
145     def test_open_relative_path(self, mock_open):
146         mock_open_result = mock_open()
147         mock_open_call_count = 1  # initial call to get result
148
149         self.assertEqual(utils.open_relative_file('foo', 'bar'), mock_open_result)
150
151         mock_open_call_count += 1  # one more call expected
152         self.assertEqual(mock_open.call_count, mock_open_call_count)
153         self.assertIn('foo', mock_open.call_args_list[-1][0][0])
154         self.assertNotIn('bar', mock_open.call_args_list[-1][0][0])
155
156         def open_effect(*args, **kwargs):
157             if kwargs.get('name', args[0]) == os.path.join('bar', 'foo'):
158                 return mock_open_result
159             raise IOError(errno.ENOENT, 'not found')
160
161         mock_open.side_effect = open_effect
162         self.assertEqual(utils.open_relative_file('foo', 'bar'), mock_open_result)
163
164         mock_open_call_count += 2  # two more calls expected
165         self.assertEqual(mock_open.call_count, mock_open_call_count)
166         self.assertIn('foo', mock_open.call_args_list[-1][0][0])
167         self.assertIn('bar', mock_open.call_args_list[-1][0][0])
168
169         # test an IOError of type ENOENT
170         mock_open.side_effect = IOError(errno.ENOENT, 'not found')
171         with self.assertRaises(IOError):
172             # the second call still raises
173             utils.open_relative_file('foo', 'bar')
174
175         mock_open_call_count += 2  # two more calls expected
176         self.assertEqual(mock_open.call_count, mock_open_call_count)
177         self.assertIn('foo', mock_open.call_args_list[-1][0][0])
178         self.assertIn('bar', mock_open.call_args_list[-1][0][0])
179
180         # test an IOError other than ENOENT
181         mock_open.side_effect = IOError(errno.EBUSY, 'busy')
182         with self.assertRaises(IOError):
183             utils.open_relative_file('foo', 'bar')
184
185         mock_open_call_count += 1  # one more call expected
186         self.assertEqual(mock_open.call_count, mock_open_call_count)
187
188
189 class TestMacAddressToHex(unittest.TestCase):
190
191     def test_mac_address_to_hex_list(self):
192         self.assertEqual(utils.mac_address_to_hex_list("ea:3e:e1:9a:99:e8"),
193                          ['0xea', '0x3e', '0xe1', '0x9a', '0x99', '0xe8'])
194
195
196 class TranslateToStrTestCase(unittest.TestCase):
197
198     def test_translate_to_str_unicode(self):
199         input_str = u'hello'
200         output_str = utils.translate_to_str(input_str)
201
202         result = 'hello'
203         self.assertEqual(result, output_str)
204
205     def test_translate_to_str_dict_list_unicode(self):
206         input_str = {
207             u'hello': {u'hello': [u'world']}
208         }
209         output_str = utils.translate_to_str(input_str)
210
211         result = {
212             'hello': {'hello': ['world']}
213         }
214         self.assertEqual(result, output_str)
215
216     def test_translate_to_str_non_string(self):
217         input_value = object()
218         result = utils.translate_to_str(input_value)
219         self.assertIs(input_value, result)
220
221
222 class TestParseCpuInfo(unittest.TestCase):
223
224     def test_single_socket_no_hyperthread(self):
225         cpuinfo = """\
226 processor       : 2
227 vendor_id       : GenuineIntel
228 cpu family      : 6
229 model           : 60
230 model name      : Intel Core Processor (Haswell, no TSX)
231 stepping        : 1
232 microcode       : 0x1
233 cpu MHz         : 2294.684
234 cache size      : 4096 KB
235 physical id     : 0
236 siblings        : 5
237 core id         : 2
238 cpu cores       : 5
239 apicid          : 2
240 initial apicid  : 2
241 fpu             : yes
242 fpu_exception   : yes
243 cpuid level     : 13
244 wp              : yes
245 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
246 bugs            :
247 bogomips        : 4589.36
248 clflush size    : 64
249 cache_alignment : 64
250 address sizes   : 46 bits physical, 48 bits virtual
251 power management:
252
253 processor       : 3
254 vendor_id       : GenuineIntel
255 cpu family      : 6
256 model           : 60
257 model name      : Intel Core Processor (Haswell, no TSX)
258 stepping        : 1
259 microcode       : 0x1
260 cpu MHz         : 2294.684
261 cache size      : 4096 KB
262 physical id     : 0
263 siblings        : 5
264 core id         : 3
265 cpu cores       : 5
266 apicid          : 3
267 initial apicid  : 3
268 fpu             : yes
269 fpu_exception   : yes
270 cpuid level     : 13
271 wp              : yes
272 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
273 bugs            :
274 bogomips        : 4589.36
275 clflush size    : 64
276 cache_alignment : 64
277 address sizes   : 46 bits physical, 48 bits virtual
278 power management:
279
280 processor       : 4
281 vendor_id       : GenuineIntel
282 cpu family      : 6
283 model           : 60
284 model name      : Intel Core Processor (Haswell, no TSX)
285 stepping        : 1
286 microcode       : 0x1
287 cpu MHz         : 2294.684
288 cache size      : 4096 KB
289 physical id     : 0
290 siblings        : 5
291 core id         : 4
292 cpu cores       : 5
293 apicid          : 4
294 initial apicid  : 4
295 fpu             : yes
296 fpu_exception   : yes
297 cpuid level     : 13
298 wp              : yes
299 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
300 bugs            :
301 bogomips        : 4589.36
302 clflush size    : 64
303 cache_alignment : 64
304 address sizes   : 46 bits physical, 48 bits virtual
305 power management:
306
307 """
308         socket_map = utils.SocketTopology.parse_cpuinfo(cpuinfo)
309         self.assertEqual(sorted(socket_map.keys()), [0])
310         self.assertEqual(sorted(socket_map[0].keys()), [2, 3, 4])
311
312     def test_single_socket_hyperthread(self):
313         cpuinfo = """\
314 processor       : 5
315 vendor_id       : GenuineIntel
316 cpu family      : 6
317 model           : 60
318 model name      : Intel(R) Xeon(R) CPU E3-1275 v3 @ 3.50GHz
319 stepping        : 3
320 microcode       : 0x1d
321 cpu MHz         : 3501.708
322 cache size      : 8192 KB
323 physical id     : 0
324 siblings        : 8
325 core id         : 1
326 cpu cores       : 4
327 apicid          : 3
328 initial apicid  : 3
329 fpu             : yes
330 fpu_exception   : yes
331 cpuid level     : 13
332 wp              : yes
333 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
334 bugs            :
335 bogomips        : 6987.36
336 clflush size    : 64
337 cache_alignment : 64
338 address sizes   : 39 bits physical, 48 bits virtual
339 power management:
340
341 processor       : 6
342 vendor_id       : GenuineIntel
343 cpu family      : 6
344 model           : 60
345 model name      : Intel(R) Xeon(R) CPU E3-1275 v3 @ 3.50GHz
346 stepping        : 3
347 microcode       : 0x1d
348 cpu MHz         : 3531.829
349 cache size      : 8192 KB
350 physical id     : 0
351 siblings        : 8
352 core id         : 2
353 cpu cores       : 4
354 apicid          : 5
355 initial apicid  : 5
356 fpu             : yes
357 fpu_exception   : yes
358 cpuid level     : 13
359 wp              : yes
360 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
361 bugs            :
362 bogomips        : 6987.36
363 clflush size    : 64
364 cache_alignment : 64
365 address sizes   : 39 bits physical, 48 bits virtual
366 power management:
367
368 processor       : 7
369 vendor_id       : GenuineIntel
370 cpu family      : 6
371 model           : 60
372 model name      : Intel(R) Xeon(R) CPU E3-1275 v3 @ 3.50GHz
373 stepping        : 3
374 microcode       : 0x1d
375 cpu MHz         : 3500.213
376 cache size      : 8192 KB
377 physical id     : 0
378 siblings        : 8
379 core id         : 3
380 cpu cores       : 4
381 apicid          : 7
382 initial apicid  : 7
383 fpu             : yes
384 fpu_exception   : yes
385 cpuid level     : 13
386 wp              : yes
387 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
388 bugs            :
389 bogomips        : 6987.24
390 clflush size    : 64
391 cache_alignment : 64
392 address sizes   : 39 bits physical, 48 bits virtual
393 power management:
394
395 """
396         socket_map = utils.SocketTopology.parse_cpuinfo(cpuinfo)
397         self.assertEqual(sorted(socket_map.keys()), [0])
398         self.assertEqual(sorted(socket_map[0].keys()), [1, 2, 3])
399         self.assertEqual(sorted(socket_map[0][1]), [5])
400         self.assertEqual(sorted(socket_map[0][2]), [6])
401         self.assertEqual(sorted(socket_map[0][3]), [7])
402
403     def test_dual_socket_hyperthread(self):
404         cpuinfo = """\
405 processor       : 1
406 vendor_id       : GenuineIntel
407 cpu family      : 6
408 model           : 79
409 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
410 stepping        : 1
411 microcode       : 0xb00001f
412 cpu MHz         : 1200.976
413 cache size      : 56320 KB
414 physical id     : 0
415 siblings        : 44
416 core id         : 1
417 cpu cores       : 22
418 apicid          : 2
419 initial apicid  : 2
420 fpu             : yes
421 fpu_exception   : yes
422 cpuid level     : 20
423 wp              : yes
424 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
425 bugs            :
426 bogomips        : 4401.07
427 clflush size    : 64
428 cache_alignment : 64
429 address sizes   : 46 bits physical, 48 bits virtual
430 power management:
431
432 processor       : 2
433 vendor_id       : GenuineIntel
434 cpu family      : 6
435 model           : 79
436 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
437 stepping        : 1
438 microcode       : 0xb00001f
439 cpu MHz         : 1226.892
440 cache size      : 56320 KB
441 physical id     : 0
442 siblings        : 44
443 core id         : 2
444 cpu cores       : 22
445 apicid          : 4
446 initial apicid  : 4
447 fpu             : yes
448 fpu_exception   : yes
449 cpuid level     : 20
450 wp              : yes
451 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
452 bugs            :
453 bogomips        : 4400.84
454 clflush size    : 64
455 cache_alignment : 64
456 address sizes   : 46 bits physical, 48 bits virtual
457 power management:
458
459 processor       : 43
460 vendor_id       : GenuineIntel
461 cpu family      : 6
462 model           : 79
463 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
464 stepping        : 1
465 microcode       : 0xb00001f
466 cpu MHz         : 1200.305
467 cache size      : 56320 KB
468 physical id     : 1
469 siblings        : 44
470 core id         : 28
471 cpu cores       : 22
472 apicid          : 120
473 initial apicid  : 120
474 fpu             : yes
475 fpu_exception   : yes
476 cpuid level     : 20
477 wp              : yes
478 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
479 bugs            :
480 bogomips        : 4411.31
481 clflush size    : 64
482 cache_alignment : 64
483 address sizes   : 46 bits physical, 48 bits virtual
484 power management:
485
486 processor       : 44
487 vendor_id       : GenuineIntel
488 cpu family      : 6
489 model           : 79
490 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
491 stepping        : 1
492 microcode       : 0xb00001f
493 cpu MHz         : 1200.305
494 cache size      : 56320 KB
495 physical id     : 0
496 siblings        : 44
497 core id         : 0
498 cpu cores       : 22
499 apicid          : 1
500 initial apicid  : 1
501 fpu             : yes
502 fpu_exception   : yes
503 cpuid level     : 20
504 wp              : yes
505 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
506 bugs            :
507 bogomips        : 4410.61
508 clflush size    : 64
509 cache_alignment : 64
510 address sizes   : 46 bits physical, 48 bits virtual
511 power management:
512
513 processor       : 85
514 vendor_id       : GenuineIntel
515 cpu family      : 6
516 model           : 79
517 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
518 stepping        : 1
519 microcode       : 0xb00001f
520 cpu MHz         : 1200.573
521 cache size      : 56320 KB
522 physical id     : 1
523 siblings        : 44
524 core id         : 26
525 cpu cores       : 22
526 apicid          : 117
527 initial apicid  : 117
528 fpu             : yes
529 fpu_exception   : yes
530 cpuid level     : 20
531 wp              : yes
532 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
533 bugs            :
534 bogomips        : 4409.07
535 clflush size    : 64
536 cache_alignment : 64
537 address sizes   : 46 bits physical, 48 bits virtual
538 power management:
539
540 processor       : 86
541 vendor_id       : GenuineIntel
542 cpu family      : 6
543 model           : 79
544 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
545 stepping        : 1
546 microcode       : 0xb00001f
547 cpu MHz         : 1200.305
548 cache size      : 56320 KB
549 physical id     : 1
550 siblings        : 44
551 core id         : 27
552 cpu cores       : 22
553 apicid          : 119
554 initial apicid  : 119
555 fpu             : yes
556 fpu_exception   : yes
557 cpuid level     : 20
558 wp              : yes
559 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
560 bugs            :
561 bogomips        : 4406.62
562 clflush size    : 64
563 cache_alignment : 64
564 address sizes   : 46 bits physical, 48 bits virtual
565 power management:
566
567 processor       : 87
568 vendor_id       : GenuineIntel
569 cpu family      : 6
570 model           : 79
571 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
572 stepping        : 1
573 microcode       : 0xb00001f
574 cpu MHz         : 1200.708
575 cache size      : 56320 KB
576 physical id     : 1
577 siblings        : 44
578 core id         : 28
579 cpu cores       : 22
580 apicid          : 121
581 initial apicid  : 121
582 fpu             : yes
583 fpu_exception   : yes
584 cpuid level     : 20
585 wp              : yes
586 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
587 bugs            :
588 bogomips        : 4413.48
589 clflush size    : 64
590 cache_alignment : 64
591 address sizes   : 46 bits physical, 48 bits virtual
592 power management:
593
594 """
595         socket_map = utils.SocketTopology.parse_cpuinfo(cpuinfo)
596         self.assertEqual(sorted(socket_map.keys()), [0, 1])
597         self.assertEqual(sorted(socket_map[0].keys()), [0, 1, 2])
598         self.assertEqual(sorted(socket_map[1].keys()), [26, 27, 28])
599         self.assertEqual(sorted(socket_map[0][0]), [44])
600         self.assertEqual(sorted(socket_map[0][1]), [1])
601         self.assertEqual(sorted(socket_map[0][2]), [2])
602         self.assertEqual(sorted(socket_map[1][26]), [85])
603         self.assertEqual(sorted(socket_map[1][27]), [86])
604         self.assertEqual(sorted(socket_map[1][28]), [43, 87])
605
606     def test_dual_socket_no_hyperthread(self):
607         cpuinfo = """\
608 processor       : 1
609 vendor_id       : GenuineIntel
610 cpu family      : 6
611 model           : 79
612 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
613 stepping        : 1
614 microcode       : 0xb00001f
615 cpu MHz         : 1200.976
616 cache size      : 56320 KB
617 physical id     : 0
618 siblings        : 44
619 core id         : 1
620 cpu cores       : 22
621 apicid          : 2
622 initial apicid  : 2
623 fpu             : yes
624 fpu_exception   : yes
625 cpuid level     : 20
626 wp              : yes
627 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
628 bugs            :
629 bogomips        : 4401.07
630 clflush size    : 64
631 cache_alignment : 64
632 address sizes   : 46 bits physical, 48 bits virtual
633 power management:
634
635 processor       : 2
636 vendor_id       : GenuineIntel
637 cpu family      : 6
638 model           : 79
639 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
640 stepping        : 1
641 microcode       : 0xb00001f
642 cpu MHz         : 1226.892
643 cache size      : 56320 KB
644 physical id     : 0
645 siblings        : 44
646 core id         : 2
647 cpu cores       : 22
648 apicid          : 4
649 initial apicid  : 4
650 fpu             : yes
651 fpu_exception   : yes
652 cpuid level     : 20
653 wp              : yes
654 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
655 bugs            :
656 bogomips        : 4400.84
657 clflush size    : 64
658 cache_alignment : 64
659 address sizes   : 46 bits physical, 48 bits virtual
660 power management:
661
662 processor       : 43
663 vendor_id       : GenuineIntel
664 cpu family      : 6
665 model           : 79
666 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
667 stepping        : 1
668 microcode       : 0xb00001f
669 cpu MHz         : 1200.305
670 cache size      : 56320 KB
671 physical id     : 1
672 siblings        : 44
673 core id         : 28
674 cpu cores       : 22
675 apicid          : 120
676 initial apicid  : 120
677 fpu             : yes
678 fpu_exception   : yes
679 cpuid level     : 20
680 wp              : yes
681 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
682 bugs            :
683 bogomips        : 4411.31
684 clflush size    : 64
685 cache_alignment : 64
686 address sizes   : 46 bits physical, 48 bits virtual
687 power management:
688
689 processor       : 44
690 vendor_id       : GenuineIntel
691 cpu family      : 6
692 model           : 79
693 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
694 stepping        : 1
695 microcode       : 0xb00001f
696 cpu MHz         : 1200.305
697 cache size      : 56320 KB
698 physical id     : 0
699 siblings        : 44
700 core id         : 0
701 cpu cores       : 22
702 apicid          : 1
703 initial apicid  : 1
704 fpu             : yes
705 fpu_exception   : yes
706 cpuid level     : 20
707 wp              : yes
708 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
709 bugs            :
710 bogomips        : 4410.61
711 clflush size    : 64
712 cache_alignment : 64
713 address sizes   : 46 bits physical, 48 bits virtual
714 power management:
715
716 processor       : 85
717 vendor_id       : GenuineIntel
718 cpu family      : 6
719 model           : 79
720 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
721 stepping        : 1
722 microcode       : 0xb00001f
723 cpu MHz         : 1200.573
724 cache size      : 56320 KB
725 physical id     : 1
726 siblings        : 44
727 core id         : 26
728 cpu cores       : 22
729 apicid          : 117
730 initial apicid  : 117
731 fpu             : yes
732 fpu_exception   : yes
733 cpuid level     : 20
734 wp              : yes
735 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
736 bugs            :
737 bogomips        : 4409.07
738 clflush size    : 64
739 cache_alignment : 64
740 address sizes   : 46 bits physical, 48 bits virtual
741 power management:
742
743 processor       : 86
744 vendor_id       : GenuineIntel
745 cpu family      : 6
746 model           : 79
747 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
748 stepping        : 1
749 microcode       : 0xb00001f
750 cpu MHz         : 1200.305
751 cache size      : 56320 KB
752 physical id     : 1
753 siblings        : 44
754 core id         : 27
755 cpu cores       : 22
756 apicid          : 119
757 initial apicid  : 119
758 fpu             : yes
759 fpu_exception   : yes
760 cpuid level     : 20
761 wp              : yes
762 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
763 bugs            :
764 bogomips        : 4406.62
765 clflush size    : 64
766 cache_alignment : 64
767 address sizes   : 46 bits physical, 48 bits virtual
768 power management:
769
770 processor       : 87
771 vendor_id       : GenuineIntel
772 cpu family      : 6
773 model           : 79
774 model name      : Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
775 stepping        : 1
776 microcode       : 0xb00001f
777 cpu MHz         : 1200.708
778 cache size      : 56320 KB
779 physical id     : 1
780 siblings        : 44
781 core id         : 28
782 cpu cores       : 22
783 apicid          : 121
784 initial apicid  : 121
785 fpu             : yes
786 fpu_exception   : yes
787 cpuid level     : 20
788 wp              : yes
789 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
790 bugs            :
791 bogomips        : 4413.48
792 clflush size    : 64
793 cache_alignment : 64
794 address sizes   : 46 bits physical, 48 bits virtual
795 power management:
796
797 """
798         socket_map = utils.SocketTopology.parse_cpuinfo(cpuinfo)
799         processors = socket_map.processors()
800         self.assertEqual(processors, [1, 2, 43, 44, 85, 86, 87])
801         cores = socket_map.cores()
802         self.assertEqual(cores, [0, 1, 2, 26, 27, 28])
803         sockets = socket_map.sockets()
804         self.assertEqual(sockets, [0, 1])
805
806
807 class ChangeObjToDictTestCase(unittest.TestCase):
808
809     def test_change_obj_to_dict(self):
810         class A(object):
811             def __init__(self):
812                 self.name = 'yardstick'
813
814         obj = A()
815         obj_r = utils.change_obj_to_dict(obj)
816         obj_s = {'name': 'yardstick'}
817         self.assertEqual(obj_r, obj_s)
818
819
820 class SetDictValueTestCase(unittest.TestCase):
821
822     def test_set_dict_value(self):
823         input_dic = {
824             'hello': 'world'
825         }
826         output_dic = utils.set_dict_value(input_dic, 'welcome.to', 'yardstick')
827         self.assertEqual(output_dic.get('welcome', {}).get('to'), 'yardstick')
828
829
830 class RemoveFileTestCase(unittest.TestCase):
831
832     def test_remove_file(self):
833         try:
834             utils.remove_file('notexistfile.txt')
835         except Exception as e:  # pylint: disable=broad-except
836             # NOTE(ralonsoh): to narrow the scope of this exception.
837             self.assertTrue(isinstance(e, OSError))
838
839
840 class TestUtils(unittest.TestCase):
841
842     @mock.patch('yardstick.common.utils.os.makedirs')
843     def test_makedirs(self, *_):
844         self.assertIsNone(utils.makedirs('a/b/c/d'))
845
846     @mock.patch('yardstick.common.utils.os.makedirs')
847     def test_makedirs_exists(self, mock_os_makedirs):
848         mock_os_makedirs.side_effect = OSError(errno.EEXIST, 'exists')
849         self.assertIsNone(utils.makedirs('a/b/c/d'))
850
851     @mock.patch('yardstick.common.utils.os.makedirs')
852     def test_makedirs_busy(self, mock_os_makedirs):
853         mock_os_makedirs.side_effect = OSError(errno.EBUSY, 'busy')
854         with self.assertRaises(OSError):
855             utils.makedirs('a/b/c/d')
856
857     @mock.patch('yardstick.common.utils.jsonify')
858     def test_result_handler(self, mock_jsonify):
859         mock_jsonify.return_value = 432
860
861         self.assertEqual(utils.result_handler('x', 234), 432)
862         mock_jsonify.assert_called_once_with({'status': 'x', 'result': 234})
863
864     @mock.patch('random.randint')
865     @mock.patch('socket.socket')
866     def test_get_free_port(self, mock_socket, mock_randint):
867         mock_randint.return_value = 7777
868         s = mock_socket('x', 'y')
869         s.connect_ex.side_effect = iter([0, 1])
870         result = utils.get_free_port('10.20.30.40')
871         self.assertEqual(result, 7777)
872         self.assertEqual(s.connect_ex.call_count, 2)
873
874     @mock.patch('subprocess.check_output')
875     def test_execute_command(self, mock_check_output):
876         expected = ['hello world', '1234']
877         mock_check_output.return_value = os.linesep.join(expected)
878         result = utils.execute_command('my_command arg1 arg2')
879         self.assertEqual(result, expected)
880
881     @mock.patch('subprocess.Popen')
882     def test_source_env(self, mock_popen):
883         base_env = deepcopy(os.environ)
884         mock_process = mock_popen()
885         output_list = [
886             'garbage line before',
887             'NEW_ENV_VALUE=234',
888             'garbage line after',
889         ]
890         mock_process.communicate.return_value = os.linesep.join(output_list), '', 0
891         expected = {'NEW_ENV_VALUE': '234'}
892         result = utils.source_env('my_file')
893         self.assertDictEqual(result, expected)
894         os.environ.clear()
895         os.environ.update(base_env)
896
897     @mock.patch.object(configparser, 'ConfigParser')
898     def test_parse_ini_file(self, mock_config_parser_type):
899         defaults = {
900             'default1': 'value1',
901             'default2': 'value2',
902         }
903         s1 = {
904             'key1': 'value11',
905             'key2': 'value22',
906         }
907         s2 = {
908             'key1': 'value123',
909             'key2': 'value234',
910         }
911
912         mock_config_parser = mock_config_parser_type()
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             defaults.items(),
917             s1.items(),
918             s2.items(),
919         ])
920
921         expected = {
922             'DEFAULT': defaults,
923             's1': s1,
924             's2': s2,
925         }
926         result = utils.parse_ini_file('my_path')
927         self.assertDictEqual(result, expected)
928
929     @mock.patch.object(utils, 'logger')
930     @mock.patch.object(configparser, 'ConfigParser')
931     def test_parse_ini_file_missing_section_header(
932             self, mock_config_parser_type, *args):
933         mock_config_parser = mock_config_parser_type()
934         mock_config_parser.read.side_effect = (
935             configparser.MissingSectionHeaderError(mock.Mock(), 321,
936                                                    mock.Mock()))
937
938         with self.assertRaises(configparser.MissingSectionHeaderError):
939             utils.parse_ini_file('my_path')
940
941     @mock.patch.object(configparser, 'ConfigParser')
942     def test_parse_ini_file_no_file(self, mock_config_parser_type):
943         mock_config_parser = mock_config_parser_type()
944         mock_config_parser.read.return_value = False
945         with self.assertRaises(RuntimeError):
946             utils.parse_ini_file('my_path')
947
948     @mock.patch.object(configparser, 'ConfigParser')
949     def test_parse_ini_file_no_default_section_header(self, mock_config_parser_type):
950         s1 = {
951             'key1': 'value11',
952             'key2': 'value22',
953         }
954         s2 = {
955             'key1': 'value123',
956             'key2': 'value234',
957         }
958
959         mock_config_parser = mock_config_parser_type()
960         mock_config_parser.read.return_value = True
961         mock_config_parser.sections.return_value = ['s1', 's2']
962         mock_config_parser.items.side_effect = iter([
963             configparser.NoSectionError(mock.Mock()),
964             s1.items(),
965             s2.items(),
966         ])
967
968         expected = {
969             'DEFAULT': {},
970             's1': s1,
971             's2': s2,
972         }
973         result = utils.parse_ini_file('my_path')
974         self.assertDictEqual(result, expected)
975
976     def test_join_non_strings(self):
977         self.assertEqual(utils.join_non_strings(':'), '')
978         self.assertEqual(utils.join_non_strings(':', 'a'), 'a')
979         self.assertEqual(utils.join_non_strings(':', 'a', 2, 'c'), 'a:2:c')
980         self.assertEqual(utils.join_non_strings(':', ['a', 2, 'c']), 'a:2:c')
981         self.assertEqual(utils.join_non_strings(':', 'abc'), 'abc')
982
983     def test_validate_non_string_sequence(self):
984         self.assertEqual(utils.validate_non_string_sequence([1, 2, 3]), [1, 2, 3])
985         self.assertIsNone(utils.validate_non_string_sequence('123'))
986         self.assertIsNone(utils.validate_non_string_sequence(1))
987
988         self.assertEqual(utils.validate_non_string_sequence(1, 2), 2)
989         self.assertEqual(utils.validate_non_string_sequence(1, default=2), 2)
990
991         with self.assertRaises(RuntimeError):
992             utils.validate_non_string_sequence(1, raise_exc=RuntimeError)
993
994
995 class TestUtilsIpAddrMethods(unittest.TestCase):
996
997     GOOD_IP_V4_ADDRESS_STR_LIST = [
998         u'0.0.0.0',
999         u'10.20.30.40',
1000         u'127.0.0.1',
1001         u'10.20.30.40',
1002         u'172.29.50.75',
1003         u'192.168.230.9',
1004         u'255.255.255.255',
1005     ]
1006
1007     GOOD_IP_V4_MASK_STR_LIST = [
1008         u'/1',
1009         u'/8',
1010         u'/13',
1011         u'/19',
1012         u'/24',
1013         u'/32',
1014     ]
1015
1016     GOOD_IP_V6_ADDRESS_STR_LIST = [
1017         u'::1',
1018         u'fe80::250:56ff:fe89:91ff',
1019         u'123:4567:89ab:cdef:123:4567:89ab:cdef',
1020     ]
1021
1022     GOOD_IP_V6_MASK_STR_LIST = [
1023         u'/1',
1024         u'/16',
1025         u'/29',
1026         u'/64',
1027         u'/99',
1028         u'/128',
1029     ]
1030
1031     INVALID_IP_ADDRESS_STR_LIST = [
1032         1,
1033         u'w.x.y.z',
1034         u'10.20.30.40/33',
1035         u'123:4567:89ab:cdef:123:4567:89ab:cdef/129',
1036     ]
1037
1038     def test_safe_ip_address(self):
1039         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1040         for addr in addr_list:
1041             # test with no mask
1042             expected = ipaddress.ip_address(addr)
1043             self.assertEqual(utils.safe_ip_address(addr), expected, addr)
1044
1045     def test_safe_ip_address_v6_ip(self):
1046         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1047         for addr in addr_list:
1048             # test with no mask
1049             expected = ipaddress.ip_address(addr)
1050             self.assertEqual(utils.safe_ip_address(addr), expected, addr)
1051
1052     @mock.patch("yardstick.common.utils.logging")
1053     def test_safe_ip_address_negative(self, *args):
1054         # NOTE(ralonsoh): check the calls to mocked functions.
1055         for value in self.INVALID_IP_ADDRESS_STR_LIST:
1056             self.assertIsNone(utils.safe_ip_address(value), value)
1057
1058         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1059         mask_list = self.GOOD_IP_V4_MASK_STR_LIST
1060         for addr_mask_pair in product(addr_list, mask_list):
1061             value = ''.join(addr_mask_pair)
1062             self.assertIsNone(utils.safe_ip_address(value), value)
1063
1064         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1065         mask_list = self.GOOD_IP_V6_MASK_STR_LIST
1066         for addr_mask_pair in product(addr_list, mask_list):
1067             value = ''.join(addr_mask_pair)
1068             self.assertIsNone(utils.safe_ip_address(value), value)
1069
1070     def test_get_ip_version(self):
1071         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1072         for addr in addr_list:
1073             # test with no mask
1074             self.assertEqual(utils.get_ip_version(addr), 4, addr)
1075
1076     def test_get_ip_version_v6_ip(self):
1077         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1078         for addr in addr_list:
1079             # test with no mask
1080             self.assertEqual(utils.get_ip_version(addr), 6, addr)
1081
1082     @mock.patch("yardstick.common.utils.logging")
1083     def test_get_ip_version_negative(self, *args):
1084         # NOTE(ralonsoh): check the calls to mocked functions.
1085         for value in self.INVALID_IP_ADDRESS_STR_LIST:
1086             self.assertIsNone(utils.get_ip_version(value), value)
1087
1088         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1089         mask_list = self.GOOD_IP_V4_MASK_STR_LIST
1090         for addr_mask_pair in product(addr_list, mask_list):
1091             value = ''.join(addr_mask_pair)
1092             self.assertIsNone(utils.get_ip_version(value), value)
1093
1094         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1095         mask_list = self.GOOD_IP_V6_MASK_STR_LIST
1096         for addr_mask_pair in product(addr_list, mask_list):
1097             value = ''.join(addr_mask_pair)
1098             self.assertIsNone(utils.get_ip_version(value), value)
1099
1100     def test_ip_to_hex(self):
1101         self.assertEqual(utils.ip_to_hex('0.0.0.0'), '00000000')
1102         self.assertEqual(utils.ip_to_hex('10.20.30.40'), '0a141e28')
1103         self.assertEqual(utils.ip_to_hex('127.0.0.1'), '7f000001')
1104         self.assertEqual(utils.ip_to_hex('172.31.90.100'), 'ac1f5a64')
1105         self.assertEqual(utils.ip_to_hex('192.168.254.253'), 'c0a8fefd')
1106         self.assertEqual(utils.ip_to_hex('255.255.255.255'), 'ffffffff')
1107
1108     def test_ip_to_hex_v6_ip(self):
1109         for value in self.GOOD_IP_V6_ADDRESS_STR_LIST:
1110             self.assertEqual(utils.ip_to_hex(value), value)
1111
1112     @mock.patch("yardstick.common.utils.logging")
1113     def test_ip_to_hex_negative(self, *args):
1114         # NOTE(ralonsoh): check the calls to mocked functions.
1115         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1116         mask_list = self.GOOD_IP_V4_MASK_STR_LIST
1117         value_iter = (''.join(pair) for pair in product(addr_list, mask_list))
1118         for value in chain(value_iter, self.INVALID_IP_ADDRESS_STR_LIST):
1119             self.assertEqual(utils.ip_to_hex(value), value)
1120
1121
1122 class SafeDecodeUtf8TestCase(unittest.TestCase):
1123
1124     @unittest.skipIf(six.PY2,
1125                      'This test should only be launched with Python 3.x')
1126     def test_safe_decode_utf8(self):
1127         _bytes = b'this is a byte array'
1128         out = utils.safe_decode_utf8(_bytes)
1129         self.assertIs(type(out), str)
1130         self.assertEqual('this is a byte array', out)
1131
1132
1133 class ReadMeminfoTestCase(unittest.TestCase):
1134
1135     MEMINFO = (b'MemTotal:       65860500 kB\n'
1136                b'MemFree:        28690900 kB\n'
1137                b'MemAvailable:   52873764 kB\n'
1138                b'Active(anon):    3015676 kB\n'
1139                b'HugePages_Total:       8\n'
1140                b'Hugepagesize:    1048576 kB')
1141     MEMINFO_DICT = {'MemTotal': '65860500',
1142                     'MemFree': '28690900',
1143                     'MemAvailable': '52873764',
1144                     'Active(anon)': '3015676',
1145                     'HugePages_Total': '8',
1146                     'Hugepagesize': '1048576'}
1147
1148     def test_read_meminfo(self):
1149         ssh_client = ssh.SSH('user', 'host')
1150         with mock.patch.object(ssh_client, 'get_file_obj') as \
1151                 mock_get_client, \
1152                 mock.patch.object(six, 'BytesIO',
1153                                   return_value=six.BytesIO(self.MEMINFO)):
1154             output = utils.read_meminfo(ssh_client)
1155             mock_get_client.assert_called_once_with('/proc/meminfo', mock.ANY)
1156         self.assertEqual(self.MEMINFO_DICT, output)
1157
1158
1159 class TimerTestCase(unittest.TestCase):
1160
1161     def test__getattr(self):
1162         with utils.Timer() as timer:
1163             time.sleep(1)
1164         self.assertEqual(1, round(timer.total_seconds(), 0))
1165         self.assertEqual(1, timer.delta.seconds)
1166
1167     def test__enter_with_timeout(self):
1168         with utils.Timer(timeout=10) as timer:
1169             time.sleep(1)
1170         self.assertEqual(1, round(timer.total_seconds(), 0))
1171
1172     def test__enter_with_timeout_exception(self):
1173         with self.assertRaises(exceptions.TimerTimeout):
1174             with utils.Timer(timeout=1):
1175                 time.sleep(2)
1176
1177
1178 class WaitUntilTrueTestCase(unittest.TestCase):
1179
1180     def test_no_timeout(self):
1181         self.assertIsNone(utils.wait_until_true(lambda: True,
1182                                                 timeout=1, sleep=1))
1183
1184     def test_timeout_generic_exception(self):
1185         with self.assertRaises(exceptions.WaitTimeout):
1186             self.assertIsNone(utils.wait_until_true(lambda: False,
1187                                                     timeout=1, sleep=1))
1188
1189     def test_timeout_given_exception(self):
1190         class MyTimeoutException(exceptions.YardstickException):
1191             message = 'My timeout exception'
1192
1193         with self.assertRaises(MyTimeoutException):
1194             self.assertIsNone(
1195                 utils.wait_until_true(lambda: False, timeout=1, sleep=1,
1196                                       exception=MyTimeoutException))