1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
import os
from cloudinit.analyze.__main__ import (analyze_boot, get_parser)
from cloudinit.tests.helpers import CiTestCase, mock
from cloudinit.analyze.show import dist_check_timestamp, SystemctlReader, \
FAIL_CODE, CONTAINER_CODE
err_code = (FAIL_CODE, -1, -1, -1)
class TestDistroChecker(CiTestCase):
@mock.patch('cloudinit.util.system_info', return_value={'dist': ('', '',
''),
'system': ''})
@mock.patch('cloudinit.util.get_linux_distro', return_value=('', '', ''))
@mock.patch('cloudinit.util.is_FreeBSD', return_value=False)
def test_blank_distro(self, m_sys_info, m_get_linux_distro, m_free_bsd):
self.assertEqual(err_code, dist_check_timestamp())
@mock.patch('cloudinit.util.system_info', return_value={'dist': ('', '',
'')})
@mock.patch('cloudinit.util.get_linux_distro', return_value=('', '', ''))
@mock.patch('cloudinit.util.is_FreeBSD', return_value=True)
def test_freebsd_gentoo_cant_find(self, m_sys_info,
m_get_linux_distro, m_is_FreeBSD):
self.assertEqual(err_code, dist_check_timestamp())
@mock.patch('cloudinit.util.subp', return_value=(0, 1))
def test_subp_fails(self, m_subp):
self.assertEqual(err_code, dist_check_timestamp())
class TestSystemCtlReader(CiTestCase):
def test_systemctl_invalid_property(self):
reader = SystemctlReader('dummyProperty')
with self.assertRaises(RuntimeError):
reader.parse_epoch_as_float()
def test_systemctl_invalid_parameter(self):
reader = SystemctlReader('dummyProperty', 'dummyParameter')
with self.assertRaises(RuntimeError):
reader.parse_epoch_as_float()
@mock.patch('cloudinit.util.subp', return_value=('U=1000000', None))
def test_systemctl_works_correctly_threshold(self, m_subp):
reader = SystemctlReader('dummyProperty', 'dummyParameter')
self.assertEqual(1.0, reader.parse_epoch_as_float())
thresh = 1.0 - reader.parse_epoch_as_float()
self.assertTrue(thresh < 1e-6)
self.assertTrue(thresh > (-1 * 1e-6))
@mock.patch('cloudinit.util.subp', return_value=('U=0', None))
def test_systemctl_succeed_zero(self, m_subp):
reader = SystemctlReader('dummyProperty', 'dummyParameter')
self.assertEqual(0.0, reader.parse_epoch_as_float())
@mock.patch('cloudinit.util.subp', return_value=('U=1', None))
def test_systemctl_succeed_distinct(self, m_subp):
reader = SystemctlReader('dummyProperty', 'dummyParameter')
val1 = reader.parse_epoch_as_float()
m_subp.return_value = ('U=2', None)
reader2 = SystemctlReader('dummyProperty', 'dummyParameter')
val2 = reader2.parse_epoch_as_float()
self.assertNotEqual(val1, val2)
@mock.patch('cloudinit.util.subp', return_value=('100', None))
def test_systemctl_epoch_not_splittable(self, m_subp):
reader = SystemctlReader('dummyProperty', 'dummyParameter')
with self.assertRaises(IndexError):
reader.parse_epoch_as_float()
@mock.patch('cloudinit.util.subp', return_value=('U=foobar', None))
def test_systemctl_cannot_convert_epoch_to_float(self, m_subp):
reader = SystemctlReader('dummyProperty', 'dummyParameter')
with self.assertRaises(ValueError):
reader.parse_epoch_as_float()
class TestAnalyzeBoot(CiTestCase):
def set_up_dummy_file_ci(self, path, log_path):
infh = open(path, 'w+')
infh.write('2019-07-08 17:40:49,601 - util.py[DEBUG]: Cloud-init v. '
'19.1-1-gbaa47854-0ubuntu1~18.04.1 running \'init-local\' '
'at Mon, 08 Jul 2019 17:40:49 +0000. Up 18.84 seconds.')
infh.close()
outfh = open(log_path, 'w+')
outfh.close()
def set_up_dummy_file(self, path, log_path):
infh = open(path, 'w+')
infh.write('dummy data')
infh.close()
outfh = open(log_path, 'w+')
outfh.close()
def remove_dummy_file(self, path, log_path):
if os.path.isfile(path):
os.remove(path)
if os.path.isfile(log_path):
os.remove(log_path)
@mock.patch('cloudinit.analyze.show.dist_check_timestamp',
return_value=err_code)
def test_boot_invalid_distro(self, m_dist_check_timestamp):
path = os.path.dirname(os.path.abspath(__file__))
log_path = path + '/boot-test.log'
path += '/dummy.log'
self.set_up_dummy_file(path, log_path)
parser = get_parser()
args = parser.parse_args(args=['boot', '-i', path, '-o',
log_path])
name_default = ''
analyze_boot(name_default, args)
# now args have been tested, go into outfile and make sure error
# message is in the outfile
outfh = open(args.outfile, 'r')
data = outfh.read()
err_string = 'Your Linux distro or container does not support this ' \
'functionality.\nYou must be running a Kernel ' \
'Telemetry supported distro.\nPlease check ' \
'https://cloudinit.readthedocs.io/en/latest/topics' \
'/analyze.html for more information on supported ' \
'distros.\n'
self.remove_dummy_file(path, log_path)
self.assertEqual(err_string, data)
@mock.patch("cloudinit.util.is_container", return_value=True)
@mock.patch('cloudinit.util.subp', return_value=('U=1000000', None))
def test_container_no_ci_log_line(self, m_is_container, m_subp):
path = os.path.dirname(os.path.abspath(__file__))
log_path = path + '/boot-test.log'
path += '/dummy.log'
self.set_up_dummy_file(path, log_path)
parser = get_parser()
args = parser.parse_args(args=['boot', '-i', path, '-o',
log_path])
name_default = ''
finish_code = analyze_boot(name_default, args)
self.remove_dummy_file(path, log_path)
self.assertEqual(FAIL_CODE, finish_code)
@mock.patch("cloudinit.util.is_container", return_value=True)
@mock.patch('cloudinit.util.subp', return_value=('U=1000000', None))
@mock.patch('cloudinit.analyze.__main__._get_events', return_value=[{
'name': 'init-local', 'description': 'starting search', 'timestamp':
100000}])
@mock.patch('cloudinit.analyze.show.dist_check_timestamp',
return_value=(CONTAINER_CODE, 1, 1, 1))
def test_container_ci_log_line(self, m_is_container, m_subp, m_get, m_g):
path = os.path.dirname(os.path.abspath(__file__))
log_path = path + '/boot-test.log'
path += '/dummy.log'
self.set_up_dummy_file_ci(path, log_path)
parser = get_parser()
args = parser.parse_args(args=['boot', '-i', path, '-o',
log_path])
name_default = ''
finish_code = analyze_boot(name_default, args)
self.remove_dummy_file(path, log_path)
self.assertEqual(CONTAINER_CODE, finish_code)
|