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