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