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