1*9c5db199SXin Li#!/usr/bin/python3 2*9c5db199SXin Li 3*9c5db199SXin Li__author__ = "[email protected], [email protected] (Gwendal Grignou)" 4*9c5db199SXin Li 5*9c5db199SXin Liimport io 6*9c5db199SXin Liimport six 7*9c5db199SXin Liimport unittest 8*9c5db199SXin Lifrom unittest import mock 9*9c5db199SXin Li 10*9c5db199SXin Lifrom autotest_lib.client.bin import utils 11*9c5db199SXin Li 12*9c5db199SXin Li_IOSTAT_OUTPUT = ( 13*9c5db199SXin Li 'Linux 3.8.11 (localhost) 02/19/19 _x86_64_ (4 CPU)\n' 14*9c5db199SXin Li '\n' 15*9c5db199SXin Li 'Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn\n' 16*9c5db199SXin Li 'ALL 4.45 10.33 292.40 665582 188458\n' 17*9c5db199SXin Li '\n') 18*9c5db199SXin Li 19*9c5db199SXin Liclass TestUtils(unittest.TestCase): 20*9c5db199SXin Li """Test utils functions.""" 21*9c5db199SXin Li 22*9c5db199SXin Li # Test methods, disable missing-docstring 23*9c5db199SXin Li # pylint: disable=missing-docstring 24*9c5db199SXin Li def setUp(self): 25*9c5db199SXin Li utils._open_file = self.fake_open 26*9c5db199SXin Li # Files opened with utils._open_file will contain this string. 27*9c5db199SXin Li self.fake_file_text = '' 28*9c5db199SXin Li 29*9c5db199SXin Li def fake_open(self, path): 30*9c5db199SXin Li # Use BytesIO instead of StringIO to support with statements. 31*9c5db199SXin Li if six.PY2: 32*9c5db199SXin Li return io.BytesIO(bytes(self.fake_file_text)) 33*9c5db199SXin Li else: 34*9c5db199SXin Li return io.StringIO(self.fake_file_text) 35*9c5db199SXin Li 36*9c5db199SXin Li def test_concat_partition(self): 37*9c5db199SXin Li self.assertEquals("nvme0n1p3", utils.concat_partition("nvme0n1", 3)) 38*9c5db199SXin Li self.assertEquals("mmcblk1p3", utils.concat_partition("mmcblk1", 3)) 39*9c5db199SXin Li self.assertEquals("sda3", utils.concat_partition("sda", 3)) 40*9c5db199SXin Li 41*9c5db199SXin Li # The columns in /proc/stat are: 42*9c5db199SXin Li # user nice system idle iowait irq softirq steal guest guest_nice 43*9c5db199SXin Li # 44*9c5db199SXin Li # Although older kernel versions might not contain all of them. 45*9c5db199SXin Li # Unit is 1/100ths of a second. 46*9c5db199SXin Li def test_get_cpu_usage(self): 47*9c5db199SXin Li self.fake_file_text = 'cpu 254544 9 254768 2859878 1 2 3 4 5 6\n' 48*9c5db199SXin Li usage = utils.get_cpu_usage() 49*9c5db199SXin Li self.assertEquals({ 50*9c5db199SXin Li 'user': 254544, 51*9c5db199SXin Li 'nice': 9, 52*9c5db199SXin Li 'system': 254768, 53*9c5db199SXin Li 'idle': 2859878, 54*9c5db199SXin Li 'iowait': 1, 55*9c5db199SXin Li 'irq': 2, 56*9c5db199SXin Li 'softirq': 3, 57*9c5db199SXin Li 'steal': 4, 58*9c5db199SXin Li 'guest': 5, 59*9c5db199SXin Li 'guest_nice': 6 60*9c5db199SXin Li }, usage) 61*9c5db199SXin Li 62*9c5db199SXin Li def test_get_cpu_missing_columns(self): 63*9c5db199SXin Li self.fake_file_text = 'cpu 254544 9 254768 2859878\n' 64*9c5db199SXin Li usage = utils.get_cpu_usage() 65*9c5db199SXin Li self.assertEquals({ 66*9c5db199SXin Li 'user': 254544, 67*9c5db199SXin Li 'nice': 9, 68*9c5db199SXin Li 'system': 254768, 69*9c5db199SXin Li 'idle': 2859878, 70*9c5db199SXin Li 'iowait': 0, 71*9c5db199SXin Li 'irq': 0, 72*9c5db199SXin Li 'softirq': 0, 73*9c5db199SXin Li 'steal': 0, 74*9c5db199SXin Li 'guest': 0, 75*9c5db199SXin Li 'guest_nice': 0 76*9c5db199SXin Li }, usage) 77*9c5db199SXin Li 78*9c5db199SXin Li def test_compute_active_cpu_time(self): 79*9c5db199SXin Li start_usage = { 80*9c5db199SXin Li 'user': 900, 81*9c5db199SXin Li 'nice': 10, 82*9c5db199SXin Li 'system': 90, 83*9c5db199SXin Li 'idle': 10000, 84*9c5db199SXin Li 'iowait': 500, 85*9c5db199SXin Li 'irq': 100, 86*9c5db199SXin Li 'softirq': 50, 87*9c5db199SXin Li 'steal': 150, 88*9c5db199SXin Li 'guest': 170, 89*9c5db199SXin Li 'guest_nice': 30 90*9c5db199SXin Li } 91*9c5db199SXin Li end_usage = { 92*9c5db199SXin Li 'user': 1800, 93*9c5db199SXin Li 'nice': 20, 94*9c5db199SXin Li 'system': 180, 95*9c5db199SXin Li 'idle': 13000, 96*9c5db199SXin Li 'iowait': 2000, 97*9c5db199SXin Li 'irq': 200, 98*9c5db199SXin Li 'softirq': 100, 99*9c5db199SXin Li 'steal': 300, 100*9c5db199SXin Li 'guest': 340, 101*9c5db199SXin Li 'guest_nice': 60 102*9c5db199SXin Li } 103*9c5db199SXin Li usage = utils.compute_active_cpu_time(start_usage, end_usage) 104*9c5db199SXin Li self.assertAlmostEqual(usage, 0.25) 105*9c5db199SXin Li 106*9c5db199SXin Li def test_compute_active_cpu_time_idle(self): 107*9c5db199SXin Li start_usage = { 108*9c5db199SXin Li 'user': 900, 109*9c5db199SXin Li 'nice': 10, 110*9c5db199SXin Li 'system': 90, 111*9c5db199SXin Li 'idle': 10000, 112*9c5db199SXin Li 'iowait': 500, 113*9c5db199SXin Li 'irq': 100, 114*9c5db199SXin Li 'softirq': 50, 115*9c5db199SXin Li 'steal': 150, 116*9c5db199SXin Li 'guest': 170, 117*9c5db199SXin Li 'guest_nice':30 118*9c5db199SXin Li } 119*9c5db199SXin Li end_usage = { 120*9c5db199SXin Li 'user': 900, 121*9c5db199SXin Li 'nice': 10, 122*9c5db199SXin Li 'system': 90, 123*9c5db199SXin Li 'idle': 11000, 124*9c5db199SXin Li 'iowait': 1000, 125*9c5db199SXin Li 'irq': 100, 126*9c5db199SXin Li 'softirq': 50, 127*9c5db199SXin Li 'steal': 150, 128*9c5db199SXin Li 'guest': 170, 129*9c5db199SXin Li 'guest_nice':30 130*9c5db199SXin Li } 131*9c5db199SXin Li usage = utils.compute_active_cpu_time(start_usage, end_usage) 132*9c5db199SXin Li self.assertAlmostEqual(usage, 0) 133*9c5db199SXin Li 134*9c5db199SXin Li def test_get_mem_total(self): 135*9c5db199SXin Li self.fake_file_text = ('MemTotal: 2048000 kB\n' 136*9c5db199SXin Li 'MemFree: 307200 kB\n' 137*9c5db199SXin Li 'Buffers: 102400 kB\n' 138*9c5db199SXin Li 'Cached: 204800 kB\n') 139*9c5db199SXin Li self.assertAlmostEqual(utils.get_mem_total(), 2000) 140*9c5db199SXin Li 141*9c5db199SXin Li def test_get_mem_free(self): 142*9c5db199SXin Li self.fake_file_text = ('MemTotal: 2048000 kB\n' 143*9c5db199SXin Li 'MemFree: 307200 kB\n' 144*9c5db199SXin Li 'Buffers: 102400 kB\n' 145*9c5db199SXin Li 'Cached: 204800 kB\n') 146*9c5db199SXin Li self.assertAlmostEqual(utils.get_mem_free(), 300) 147*9c5db199SXin Li 148*9c5db199SXin Li def test_get_mem_free_plus_buffers_and_cached(self): 149*9c5db199SXin Li self.fake_file_text = ('MemTotal: 2048000 kB\n' 150*9c5db199SXin Li 'MemFree: 307200 kB\n' 151*9c5db199SXin Li 'Buffers: 102400 kB\n' 152*9c5db199SXin Li 'Cached: 204800 kB\n') 153*9c5db199SXin Li self.assertAlmostEqual(utils.get_mem_free_plus_buffers_and_cached(), 154*9c5db199SXin Li 600) 155*9c5db199SXin Li 156*9c5db199SXin Li def test_get_meminfo(self): 157*9c5db199SXin Li self.fake_file_text = ('MemTotal: 2048000 kB\n' 158*9c5db199SXin Li 'MemFree: 307200 kB\n' 159*9c5db199SXin Li 'Buffers: 102400 kB\n' 160*9c5db199SXin Li 'Cached: 204800 kB\n' 161*9c5db199SXin Li 'Active(anon): 409600 kB') 162*9c5db199SXin Li meminfo = utils.get_meminfo() 163*9c5db199SXin Li self.assertEqual(meminfo.MemTotal, 2048000) 164*9c5db199SXin Li self.assertEqual(meminfo.Active_anon, 409600) 165*9c5db199SXin Li 166*9c5db199SXin Li def test_get_num_allocated_file_handles(self): 167*9c5db199SXin Li self.fake_file_text = '123 0 456\n' 168*9c5db199SXin Li self.assertEqual(utils.get_num_allocated_file_handles(), 123) 169*9c5db199SXin Li 170*9c5db199SXin Li @mock.patch('autotest_lib.client.common_lib.utils.system_output') 171*9c5db199SXin Li def test_get_storage_statistics(self, system_output_mock): 172*9c5db199SXin Li system_output_mock.return_value = _IOSTAT_OUTPUT 173*9c5db199SXin Li statistics = utils.get_storage_statistics() 174*9c5db199SXin Li self.assertEqual({ 175*9c5db199SXin Li 'read_kb': 665582.0, 176*9c5db199SXin Li 'written_kb_per_s': 292.4, 177*9c5db199SXin Li 'read_kb_per_s': 10.33, 178*9c5db199SXin Li 'transfers_per_s': 4.45, 179*9c5db199SXin Li 'written_kb': 188458.0, 180*9c5db199SXin Li }, statistics) 181*9c5db199SXin Li 182*9c5db199SXin Li def test_base64_recursive_encode(self): 183*9c5db199SXin Li obj = { 184*9c5db199SXin Li 'a': 10, 185*9c5db199SXin Li 'b': 'hello', 186*9c5db199SXin Li 'c': [100, 200, bytearray(b'\xf0\xf1\xf2\xf3\xf4')], 187*9c5db199SXin Li 'd': { 188*9c5db199SXin Li 784: bytearray(b'@\x14\x01P'), 189*9c5db199SXin Li 78.0: bytearray(b'\x10\x05\x0b\x10\xb2\x1b\x00') 190*9c5db199SXin Li } 191*9c5db199SXin Li } 192*9c5db199SXin Li if utils.is_python2(): 193*9c5db199SXin Li expected_encoded_obj = { 194*9c5db199SXin Li 'YQ==': 10, 195*9c5db199SXin Li 'Yg==': 'aGVsbG8=', 196*9c5db199SXin Li 'Yw==': [100, 200, '8PHy8/Q='], 197*9c5db199SXin Li 'ZA==': { 198*9c5db199SXin Li 784: 'QBQBUA==', 199*9c5db199SXin Li 78.0: 'EAULELIbAA==' 200*9c5db199SXin Li } 201*9c5db199SXin Li } 202*9c5db199SXin Li else: 203*9c5db199SXin Li expected_encoded_obj = { 204*9c5db199SXin Li 'a': 10, 205*9c5db199SXin Li 'b': 'hello', 206*9c5db199SXin Li 'c': [100, 200, b'8PHy8/Q='], 207*9c5db199SXin Li 'd': { 208*9c5db199SXin Li 784: b'QBQBUA==', 209*9c5db199SXin Li 78.0: b'EAULELIbAA==' 210*9c5db199SXin Li } 211*9c5db199SXin Li } 212*9c5db199SXin Li 213*9c5db199SXin Li encoded_obj = utils.base64_recursive_encode(obj) 214*9c5db199SXin Li self.assertEqual(expected_encoded_obj, encoded_obj) 215*9c5db199SXin Li 216*9c5db199SXin Li def test_base64_recursive_decode(self): 217*9c5db199SXin Li if utils.is_python2(): 218*9c5db199SXin Li encoded_obj = { 219*9c5db199SXin Li 'YQ==': 10, 220*9c5db199SXin Li 'Yg==': 'aGVsbG8=', 221*9c5db199SXin Li 'Yw==': [100, 200, '8PHy8/Q='], 222*9c5db199SXin Li 'ZA==': { 223*9c5db199SXin Li 784: 'QBQBUA==', 224*9c5db199SXin Li 78.0: 'EAULELIbAA==' 225*9c5db199SXin Li } 226*9c5db199SXin Li } 227*9c5db199SXin Li else: 228*9c5db199SXin Li encoded_obj = { 229*9c5db199SXin Li 'a': 10, 230*9c5db199SXin Li 'b': 'hello', 231*9c5db199SXin Li 'c': [100, 200, b'8PHy8/Q='], 232*9c5db199SXin Li 'd': { 233*9c5db199SXin Li 784: b'QBQBUA==', 234*9c5db199SXin Li 78.0: b'EAULELIbAA==' 235*9c5db199SXin Li } 236*9c5db199SXin Li } 237*9c5db199SXin Li 238*9c5db199SXin Li expected_decoded_obj = { 239*9c5db199SXin Li 'a': 10, 240*9c5db199SXin Li 'b': 'hello', 241*9c5db199SXin Li 'c': [100, 200, b'\xf0\xf1\xf2\xf3\xf4'], 242*9c5db199SXin Li 'd': { 243*9c5db199SXin Li 784: b'@\x14\x01P', 244*9c5db199SXin Li 78.0: b'\x10\x05\x0b\x10\xb2\x1b\x00' 245*9c5db199SXin Li } 246*9c5db199SXin Li } 247*9c5db199SXin Li 248*9c5db199SXin Li decoded_obj = utils.base64_recursive_decode(encoded_obj) 249*9c5db199SXin Li self.assertEqual(expected_decoded_obj, decoded_obj) 250*9c5db199SXin Li 251*9c5db199SXin Li def test_bytes_to_str_recursive(self): 252*9c5db199SXin Li obj = { 253*9c5db199SXin Li 'a': 10, 254*9c5db199SXin Li 'b': 'hello', 255*9c5db199SXin Li 'c': b'b_hello', 256*9c5db199SXin Li 'd': [100, 200, bytearray(b'\xf0\xf1\xf2\xf3\xf4')], 257*9c5db199SXin Li 'e': { 258*9c5db199SXin Li 784: bytearray(b'@\x14\x01P'), 259*9c5db199SXin Li 78.0: bytearray(b'\x10\x05\x0b\x10\xb2\x1b\x00') 260*9c5db199SXin Li } 261*9c5db199SXin Li } 262*9c5db199SXin Li 263*9c5db199SXin Li if utils.is_python2(): 264*9c5db199SXin Li self.assertEqual(b'foo', utils.bytes_to_str_recursive(b'foo')) 265*9c5db199SXin Li self.assertEqual(b'\x80abc', 266*9c5db199SXin Li utils.bytes_to_str_recursive(b'\x80abc')) 267*9c5db199SXin Li self.assertEqual('foo', utils.bytes_to_str_recursive('foo')) 268*9c5db199SXin Li self.assertEqual('\x80abc', 269*9c5db199SXin Li utils.bytes_to_str_recursive('\x80abc')) 270*9c5db199SXin Li self.assertEqual(obj, utils.bytes_to_str_recursive(obj)) 271*9c5db199SXin Li else: 272*9c5db199SXin Li self.assertEqual('foo', utils.bytes_to_str_recursive(b'foo')) 273*9c5db199SXin Li # self.assertEqual('\ufffdabc', utils.bytes_to_str_recursive(b'\x80abc')) 274*9c5db199SXin Li self.assertEqual('foo', utils.bytes_to_str_recursive('foo')) 275*9c5db199SXin Li self.assertEqual('\x80abc', 276*9c5db199SXin Li utils.bytes_to_str_recursive('\x80abc')) 277*9c5db199SXin Li expected_obj = { 278*9c5db199SXin Li 'a': 10, 279*9c5db199SXin Li 'b': 'hello', 280*9c5db199SXin Li 'c': 'b_hello', 281*9c5db199SXin Li # u prefix: Python 2 interpreter friendly. 282*9c5db199SXin Li 'd': [100, 200, u'\u0440\u0441\u0442\u0443\u0444'], 283*9c5db199SXin Li 'e': { 284*9c5db199SXin Li 784: '@\x14\x01P', 285*9c5db199SXin Li 78.0: u'\x10\x05\x0b\x10\u00b2\x1b\x00' 286*9c5db199SXin Li } 287*9c5db199SXin Li } 288*9c5db199SXin Li self.assertEqual(expected_obj, utils.bytes_to_str_recursive(obj)) 289