Refactor "utils.parse_ini_file" testing
[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 from yardstick import ssh
23 import yardstick.error
24 from yardstick.common import constants
25 from yardstick.common import utils
26 from yardstick.common import exceptions
27 from yardstick.tests.unit import base as ut_base
28
29
30 class IterSubclassesTestCase(ut_base.BaseUnitTestCase):
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(ut_base.BaseUnitTestCase):
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(ut_base.BaseUnitTestCase):
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(ut_base.BaseUnitTestCase):
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(ut_base.BaseUnitTestCase):
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(ut_base.BaseUnitTestCase):
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(ut_base.BaseUnitTestCase):
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(ut_base.BaseUnitTestCase):
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(ut_base.BaseUnitTestCase):
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(ut_base.BaseUnitTestCase):
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 ParseIniFileTestCase(ut_base.BaseUnitTestCase):
842
843     def setUp(self):
844         self._mock_config_parser_type = mock.patch.object(configparser,
845                                                           'ConfigParser')
846         self.mock_config_parser_type = self._mock_config_parser_type.start()
847         self.addCleanup(self._stop_mocks)
848
849     def _stop_mocks(self):
850         self._mock_config_parser_type.stop()
851
852     def test_parse_ini_file(self):
853         defaults = {'default1': 'value1',
854                     'default2': 'value2'}
855         s1 = {'key1': 'value11',
856               'key2': 'value22'}
857         s2 = {'key1': 'value123',
858               'key2': 'value234'}
859
860         mock_config_parser = mock.Mock()
861         self.mock_config_parser_type.return_value = mock_config_parser
862         mock_config_parser.read.return_value = True
863         mock_config_parser.sections.return_value = ['s1', 's2']
864         mock_config_parser.items.side_effect = iter([
865             defaults.items(),
866             s1.items(),
867             s2.items(),
868         ])
869
870         expected = {'DEFAULT': defaults,
871                     's1': s1,
872                     's2': s2}
873         result = utils.parse_ini_file('my_path')
874         self.assertDictEqual(expected, result)
875
876     @mock.patch.object(utils, 'logger')
877     def test_parse_ini_file_missing_section_header(self, *args):
878         mock_config_parser = mock.Mock()
879         self.mock_config_parser_type.return_value = mock_config_parser
880         mock_config_parser.read.side_effect = (
881             configparser.MissingSectionHeaderError(
882                 mock.Mock(), 321, mock.Mock()))
883
884         with self.assertRaises(configparser.MissingSectionHeaderError):
885             utils.parse_ini_file('my_path')
886
887     def test_parse_ini_file_no_file(self):
888         mock_config_parser = mock.Mock()
889         self.mock_config_parser_type.return_value = mock_config_parser
890         mock_config_parser.read.return_value = False
891         with self.assertRaises(RuntimeError):
892             utils.parse_ini_file('my_path')
893
894     def test_parse_ini_file_no_default_section_header(self):
895         s1 = {'key1': 'value11',
896               'key2': 'value22'}
897         s2 = {'key1': 'value123',
898               'key2': 'value234'}
899
900         mock_config_parser = mock.Mock()
901         self.mock_config_parser_type.return_value = mock_config_parser
902         mock_config_parser.read.return_value = True
903         mock_config_parser.sections.return_value = ['s1', 's2']
904         mock_config_parser.items.side_effect = iter([
905             configparser.NoSectionError(mock.Mock()),
906             s1.items(),
907             s2.items(),
908         ])
909
910         expected = {'DEFAULT': {},
911                     's1': s1,
912                     's2': s2}
913         result = utils.parse_ini_file('my_path')
914         self.assertDictEqual(expected, result)
915
916
917 class TestUtils(ut_base.BaseUnitTestCase):
918
919     @mock.patch('yardstick.common.utils.os.makedirs')
920     def test_makedirs(self, *_):
921         self.assertIsNone(utils.makedirs('a/b/c/d'))
922
923     @mock.patch('yardstick.common.utils.os.makedirs')
924     def test_makedirs_exists(self, mock_os_makedirs):
925         mock_os_makedirs.side_effect = OSError(errno.EEXIST, 'exists')
926         self.assertIsNone(utils.makedirs('a/b/c/d'))
927
928     @mock.patch('yardstick.common.utils.os.makedirs')
929     def test_makedirs_busy(self, mock_os_makedirs):
930         mock_os_makedirs.side_effect = OSError(errno.EBUSY, 'busy')
931         with self.assertRaises(OSError):
932             utils.makedirs('a/b/c/d')
933
934     @mock.patch('yardstick.common.utils.jsonify')
935     def test_result_handler(self, mock_jsonify):
936         mock_jsonify.return_value = 432
937
938         self.assertEqual(utils.result_handler('x', 234), 432)
939         mock_jsonify.assert_called_once_with({'status': 'x', 'result': 234})
940
941     @mock.patch('random.randint')
942     @mock.patch('socket.socket')
943     def test_get_free_port(self, mock_socket, mock_randint):
944         mock_randint.return_value = 7777
945         s = mock_socket('x', 'y')
946         s.connect_ex.side_effect = iter([0, 1])
947         result = utils.get_free_port('10.20.30.40')
948         self.assertEqual(result, 7777)
949         self.assertEqual(s.connect_ex.call_count, 2)
950
951     @mock.patch('subprocess.check_output')
952     def test_execute_command(self, mock_check_output):
953         expected = ['hello world', '1234']
954         mock_check_output.return_value = os.linesep.join(expected)
955         result = utils.execute_command('my_command arg1 arg2')
956         self.assertEqual(result, expected)
957
958     @mock.patch('subprocess.Popen')
959     def test_source_env(self, mock_popen):
960         base_env = deepcopy(os.environ)
961         mock_process = mock_popen()
962         output_list = [
963             'garbage line before',
964             'NEW_ENV_VALUE=234',
965             'garbage line after',
966         ]
967         mock_process.communicate.return_value = os.linesep.join(output_list), '', 0
968         expected = {'NEW_ENV_VALUE': '234'}
969         result = utils.source_env('my_file')
970         self.assertDictEqual(result, expected)
971         os.environ.clear()
972         os.environ.update(base_env)
973
974     @mock.patch.object(configparser, 'ConfigParser')
975     def test_parse_ini_file(self, mock_config_parser_type):
976         defaults = {
977             'default1': 'value1',
978             'default2': 'value2',
979         }
980         s1 = {
981             'key1': 'value11',
982             'key2': 'value22',
983         }
984         s2 = {
985             'key1': 'value123',
986             'key2': 'value234',
987         }
988
989         mock_config_parser = mock_config_parser_type()
990         mock_config_parser.read.return_value = True
991         mock_config_parser.sections.return_value = ['s1', 's2']
992         mock_config_parser.items.side_effect = iter([
993             defaults.items(),
994             s1.items(),
995             s2.items(),
996         ])
997
998         expected = {
999             'DEFAULT': defaults,
1000             's1': s1,
1001             's2': s2,
1002         }
1003         result = utils.parse_ini_file('my_path')
1004         self.assertDictEqual(result, expected)
1005
1006     @mock.patch.object(utils, 'logger')
1007     @mock.patch.object(configparser, 'ConfigParser')
1008     def test_parse_ini_file_missing_section_header(
1009             self, mock_config_parser_type, *args):
1010         mock_config_parser = mock_config_parser_type()
1011         mock_config_parser.read.side_effect = (
1012             configparser.MissingSectionHeaderError(mock.Mock(), 321,
1013                                                    mock.Mock()))
1014
1015         with self.assertRaises(configparser.MissingSectionHeaderError):
1016             utils.parse_ini_file('my_path')
1017
1018     @mock.patch.object(configparser, 'ConfigParser')
1019     def test_parse_ini_file_no_file(self, mock_config_parser_type):
1020         mock_config_parser = mock_config_parser_type()
1021         mock_config_parser.read.return_value = False
1022         with self.assertRaises(RuntimeError):
1023             utils.parse_ini_file('my_path')
1024
1025     @mock.patch.object(configparser, 'ConfigParser')
1026     def test_parse_ini_file_no_default_section_header(self, mock_config_parser_type):
1027         s1 = {
1028             'key1': 'value11',
1029             'key2': 'value22',
1030         }
1031         s2 = {
1032             'key1': 'value123',
1033             'key2': 'value234',
1034         }
1035
1036         mock_config_parser = mock_config_parser_type()
1037         mock_config_parser.read.return_value = True
1038         mock_config_parser.sections.return_value = ['s1', 's2']
1039         mock_config_parser.items.side_effect = iter([
1040             configparser.NoSectionError(mock.Mock()),
1041             s1.items(),
1042             s2.items(),
1043         ])
1044
1045         expected = {
1046             'DEFAULT': {},
1047             's1': s1,
1048             's2': s2,
1049         }
1050         result = utils.parse_ini_file('my_path')
1051         self.assertDictEqual(result, expected)
1052
1053     def test_join_non_strings(self):
1054         self.assertEqual(utils.join_non_strings(':'), '')
1055         self.assertEqual(utils.join_non_strings(':', 'a'), 'a')
1056         self.assertEqual(utils.join_non_strings(':', 'a', 2, 'c'), 'a:2:c')
1057         self.assertEqual(utils.join_non_strings(':', ['a', 2, 'c']), 'a:2:c')
1058         self.assertEqual(utils.join_non_strings(':', 'abc'), 'abc')
1059
1060     def test_validate_non_string_sequence(self):
1061         self.assertEqual(utils.validate_non_string_sequence([1, 2, 3]), [1, 2, 3])
1062         self.assertIsNone(utils.validate_non_string_sequence('123'))
1063         self.assertIsNone(utils.validate_non_string_sequence(1))
1064
1065         self.assertEqual(utils.validate_non_string_sequence(1, 2), 2)
1066         self.assertEqual(utils.validate_non_string_sequence(1, default=2), 2)
1067
1068         with self.assertRaises(RuntimeError):
1069             utils.validate_non_string_sequence(1, raise_exc=RuntimeError)
1070
1071     def test_error_class(self):
1072         with self.assertRaises(RuntimeError):
1073             yardstick.error.ErrorClass()
1074
1075         error_instance = yardstick.error.ErrorClass(test='')
1076         with self.assertRaises(AttributeError):
1077             error_instance.get_name()
1078
1079
1080 class TestUtilsIpAddrMethods(ut_base.BaseUnitTestCase):
1081
1082     GOOD_IP_V4_ADDRESS_STR_LIST = [
1083         u'0.0.0.0',
1084         u'10.20.30.40',
1085         u'127.0.0.1',
1086         u'10.20.30.40',
1087         u'172.29.50.75',
1088         u'192.168.230.9',
1089         u'255.255.255.255',
1090     ]
1091
1092     GOOD_IP_V4_MASK_STR_LIST = [
1093         u'/1',
1094         u'/8',
1095         u'/13',
1096         u'/19',
1097         u'/24',
1098         u'/32',
1099     ]
1100
1101     GOOD_IP_V6_ADDRESS_STR_LIST = [
1102         u'::1',
1103         u'fe80::250:56ff:fe89:91ff',
1104         u'123:4567:89ab:cdef:123:4567:89ab:cdef',
1105     ]
1106
1107     GOOD_IP_V6_MASK_STR_LIST = [
1108         u'/1',
1109         u'/16',
1110         u'/29',
1111         u'/64',
1112         u'/99',
1113         u'/128',
1114     ]
1115
1116     INVALID_IP_ADDRESS_STR_LIST = [
1117         1,
1118         u'w.x.y.z',
1119         u'10.20.30.40/33',
1120         u'123:4567:89ab:cdef:123:4567:89ab:cdef/129',
1121     ]
1122
1123     def test_safe_ip_address(self):
1124         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1125         for addr in addr_list:
1126             # test with no mask
1127             expected = ipaddress.ip_address(addr)
1128             self.assertEqual(utils.safe_ip_address(addr), expected, addr)
1129
1130     def test_safe_ip_address_v6_ip(self):
1131         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1132         for addr in addr_list:
1133             # test with no mask
1134             expected = ipaddress.ip_address(addr)
1135             self.assertEqual(utils.safe_ip_address(addr), expected, addr)
1136
1137     @mock.patch("yardstick.common.utils.logging")
1138     def test_safe_ip_address_negative(self, *args):
1139         # NOTE(ralonsoh): check the calls to mocked functions.
1140         for value in self.INVALID_IP_ADDRESS_STR_LIST:
1141             self.assertIsNone(utils.safe_ip_address(value), value)
1142
1143         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1144         mask_list = self.GOOD_IP_V4_MASK_STR_LIST
1145         for addr_mask_pair in product(addr_list, mask_list):
1146             value = ''.join(addr_mask_pair)
1147             self.assertIsNone(utils.safe_ip_address(value), value)
1148
1149         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1150         mask_list = self.GOOD_IP_V6_MASK_STR_LIST
1151         for addr_mask_pair in product(addr_list, mask_list):
1152             value = ''.join(addr_mask_pair)
1153             self.assertIsNone(utils.safe_ip_address(value), value)
1154
1155     def test_get_ip_version(self):
1156         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1157         for addr in addr_list:
1158             # test with no mask
1159             self.assertEqual(utils.get_ip_version(addr), 4, addr)
1160
1161     def test_get_ip_version_v6_ip(self):
1162         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1163         for addr in addr_list:
1164             # test with no mask
1165             self.assertEqual(utils.get_ip_version(addr), 6, addr)
1166
1167     @mock.patch("yardstick.common.utils.logging")
1168     def test_get_ip_version_negative(self, *args):
1169         # NOTE(ralonsoh): check the calls to mocked functions.
1170         for value in self.INVALID_IP_ADDRESS_STR_LIST:
1171             self.assertIsNone(utils.get_ip_version(value), value)
1172
1173         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1174         mask_list = self.GOOD_IP_V4_MASK_STR_LIST
1175         for addr_mask_pair in product(addr_list, mask_list):
1176             value = ''.join(addr_mask_pair)
1177             self.assertIsNone(utils.get_ip_version(value), value)
1178
1179         addr_list = self.GOOD_IP_V6_ADDRESS_STR_LIST
1180         mask_list = self.GOOD_IP_V6_MASK_STR_LIST
1181         for addr_mask_pair in product(addr_list, mask_list):
1182             value = ''.join(addr_mask_pair)
1183             self.assertIsNone(utils.get_ip_version(value), value)
1184
1185     def test_ip_to_hex(self):
1186         self.assertEqual(utils.ip_to_hex('0.0.0.0'), '00000000')
1187         self.assertEqual(utils.ip_to_hex('10.20.30.40'), '0a141e28')
1188         self.assertEqual(utils.ip_to_hex('127.0.0.1'), '7f000001')
1189         self.assertEqual(utils.ip_to_hex('172.31.90.100'), 'ac1f5a64')
1190         self.assertEqual(utils.ip_to_hex('192.168.254.253'), 'c0a8fefd')
1191         self.assertEqual(utils.ip_to_hex('255.255.255.255'), 'ffffffff')
1192
1193     def test_ip_to_hex_v6_ip(self):
1194         for value in self.GOOD_IP_V6_ADDRESS_STR_LIST:
1195             self.assertEqual(utils.ip_to_hex(value), value)
1196
1197     @mock.patch("yardstick.common.utils.logging")
1198     def test_ip_to_hex_negative(self, *args):
1199         # NOTE(ralonsoh): check the calls to mocked functions.
1200         addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
1201         mask_list = self.GOOD_IP_V4_MASK_STR_LIST
1202         value_iter = (''.join(pair) for pair in product(addr_list, mask_list))
1203         for value in chain(value_iter, self.INVALID_IP_ADDRESS_STR_LIST):
1204             self.assertEqual(utils.ip_to_hex(value), value)
1205
1206
1207 class SafeDecodeUtf8TestCase(ut_base.BaseUnitTestCase):
1208
1209     @unittest.skipIf(six.PY2,
1210                      'This test should only be launched with Python 3.x')
1211     def test_safe_decode_utf8(self):
1212         _bytes = b'this is a byte array'
1213         out = utils.safe_decode_utf8(_bytes)
1214         self.assertIs(type(out), str)
1215         self.assertEqual('this is a byte array', out)
1216
1217
1218 class ReadMeminfoTestCase(ut_base.BaseUnitTestCase):
1219
1220     MEMINFO = (b'MemTotal:       65860500 kB\n'
1221                b'MemFree:        28690900 kB\n'
1222                b'MemAvailable:   52873764 kB\n'
1223                b'Active(anon):    3015676 kB\n'
1224                b'HugePages_Total:       8\n'
1225                b'Hugepagesize:    1048576 kB')
1226     MEMINFO_DICT = {'MemTotal': '65860500',
1227                     'MemFree': '28690900',
1228                     'MemAvailable': '52873764',
1229                     'Active(anon)': '3015676',
1230                     'HugePages_Total': '8',
1231                     'Hugepagesize': '1048576'}
1232
1233     def test_read_meminfo(self):
1234         ssh_client = ssh.SSH('user', 'host')
1235         with mock.patch.object(ssh_client, 'get_file_obj') as \
1236                 mock_get_client, \
1237                 mock.patch.object(six, 'BytesIO',
1238                                   return_value=six.BytesIO(self.MEMINFO)):
1239             output = utils.read_meminfo(ssh_client)
1240             mock_get_client.assert_called_once_with('/proc/meminfo', mock.ANY)
1241         self.assertEqual(self.MEMINFO_DICT, output)
1242
1243
1244 class TimerTestCase(ut_base.BaseUnitTestCase):
1245
1246     def test__getattr(self):
1247         with utils.Timer() as timer:
1248             time.sleep(1)
1249         self.assertEqual(1, round(timer.total_seconds(), 0))
1250         self.assertEqual(1, timer.delta.seconds)
1251
1252     def test__enter_with_timeout(self):
1253         with utils.Timer(timeout=10) as timer:
1254             time.sleep(1)
1255         self.assertEqual(1, round(timer.total_seconds(), 0))
1256
1257     def test__enter_with_timeout_exception(self):
1258         with self.assertRaises(exceptions.TimerTimeout):
1259             with utils.Timer(timeout=1):
1260                 time.sleep(2)
1261
1262
1263 class WaitUntilTrueTestCase(ut_base.BaseUnitTestCase):
1264
1265     def test_no_timeout(self):
1266         self.assertIsNone(utils.wait_until_true(lambda: True,
1267                                                 timeout=1, sleep=1))
1268
1269     def test_timeout_generic_exception(self):
1270         with self.assertRaises(exceptions.WaitTimeout):
1271             self.assertIsNone(utils.wait_until_true(lambda: False,
1272                                                     timeout=1, sleep=1))
1273
1274     def test_timeout_given_exception(self):
1275         class MyTimeoutException(exceptions.YardstickException):
1276             message = 'My timeout exception'
1277
1278         with self.assertRaises(MyTimeoutException):
1279             self.assertIsNone(
1280                 utils.wait_until_true(lambda: False, timeout=1, sleep=1,
1281                                       exception=MyTimeoutException))