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