Merge ~raharper/curtin:feature/vmtest-logger-classname into curtin:master

Proposed by Ryan Harper
Status: Merged
Approved by: Scott Moser
Approved revision: 796e12168d6b363a2d14f186f2a0bd71f42e9804
Merged at revision: 89698cda3ce931b7d6e85a077620b067f6b0608c
Proposed branch: ~raharper/curtin:feature/vmtest-logger-classname
Merge into: curtin:master
Diff against target: 273 lines (+41/-35)
6 files modified
tests/vmtests/__init__.py (+11/-2)
tests/vmtests/test_network.py (+20/-20)
tests/vmtests/test_network_bonding.py (+1/-2)
tests/vmtests/test_network_bridging.py (+2/-3)
tests/vmtests/test_network_enisource.py (+4/-4)
tests/vmtests/test_network_vlan.py (+3/-4)
Reviewer Review Type Date Requested Status
Scott Moser (community) Approve
Server Team CI bot continuous-integration Approve
Review via email: mp+336012@code.launchpad.net

Description of the change

vmtest: initialize logger with class names for easy parsing

When running vmtest in parallel, having each message include the
TestClass name helps developers map the output to specific tests when
reading the combined log.

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Scott Moser (smoser) wrote :
Revision history for this message
Scott Moser (smoser) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/tests/vmtests/__init__.py b/tests/vmtests/__init__.py
2index c76a268..564cfe4 100644
3--- a/tests/vmtests/__init__.py
4+++ b/tests/vmtests/__init__.py
5@@ -108,11 +108,13 @@ def _topdir():
6 return _TOPDIR
7
8
9-def _initialize_logging():
10+def _initialize_logging(name=None):
11 # Configure logging module to save output to disk and present it on
12 # sys.stderr
13+ if not name:
14+ name = __name__
15
16- logger = logging.getLogger(__name__)
17+ logger = logging.getLogger(name)
18 logger.setLevel(logging.DEBUG)
19
20 formatter = logging.Formatter(
21@@ -364,6 +366,7 @@ class VMBaseClass(TestCase):
22 boot_cloudconf = None
23 install_timeout = INSTALL_TIMEOUT
24 interactive = False
25+ logger = None
26 multipath = False
27 multipath_num_paths = 2
28 nvme_disks = []
29@@ -593,6 +596,12 @@ class VMBaseClass(TestCase):
30
31 @classmethod
32 def setUpClass(cls):
33+ # initialize global logger with class name to help make sense of
34+ # parallel vmtest runs which intermingle output.
35+ global logger
36+ logger = _initialize_logging(name=cls.__name__)
37+ cls.logger = logger
38+
39 # check if we should skip due to host arch
40 if cls.arch in cls.arch_skip:
41 reason = "{} is not supported on arch {}".format(cls.__name__,
42diff --git a/tests/vmtests/test_network.py b/tests/vmtests/test_network.py
43index 36ffad9..74501b5 100644
44--- a/tests/vmtests/test_network.py
45+++ b/tests/vmtests/test_network.py
46@@ -1,4 +1,4 @@
47-from . import VMBaseClass, logger, helpers
48+from . import VMBaseClass, helpers
49 from .releases import base_vm_classes as relbase
50 from .releases import centos_base_vm_classes as centos_relbase
51
52@@ -69,7 +69,7 @@ class TestNetworkBaseTestsAbs(VMBaseClass):
53 eni_cfg = ""
54
55 eni = self.load_collect_file("interfaces")
56- logger.debug('etc/network/interfaces:\n{}'.format(eni))
57+ self.logger.debug('etc/network/interfaces:\n{}'.format(eni))
58
59 # we don't use collect_path as we're building a glob
60 eni_dir = os.path.join(self.td.collect, "interfaces.d", "*.cfg")
61@@ -106,7 +106,7 @@ class TestNetworkBaseTestsAbs(VMBaseClass):
62 'network passthrough not available on %s' % self.__class__)
63
64 eni, eni_cfg = self.read_eni()
65- logger.debug('etc/network/interfaces:\n{}'.format(eni))
66+ self.logger.debug('etc/network/interfaces:\n{}'.format(eni))
67 expected_eni = self.get_expected_etc_network_interfaces()
68
69 eni_lines = eni.split('\n') + eni_cfg.split('\n')
70@@ -172,13 +172,13 @@ class TestNetworkBaseTestsAbs(VMBaseClass):
71 }
72 resolvconfpath = render2resolvconf.get(self._network_renderer(), None)
73 self.assertTrue(resolvconfpath is not None)
74- logger.debug('Selected path to resolvconf: %s', resolvconfpath)
75+ self.logger.debug('Selected path to resolvconf: %s', resolvconfpath)
76
77 resolvconf = self.load_collect_file(resolvconfpath)
78- logger.debug('etc/resolv.conf:\n{}'.format(resolvconf))
79+ self.logger.debug('etc/resolv.conf:\n{}'.format(resolvconf))
80
81 resolv_lines = resolvconf.split('\n')
82- logger.debug('resolv.conf lines:\n{}'.format(resolv_lines))
83+ self.logger.debug('resolv.conf lines:\n{}'.format(resolv_lines))
84 # resolv.conf
85 '''
86 nameserver X.Y.Z.A
87@@ -202,7 +202,7 @@ class TestNetworkBaseTestsAbs(VMBaseClass):
88 search: foo.bar
89 '''
90 expected_ifaces = self.get_expected_etc_resolvconf()
91- logger.debug('parsed eni ifaces:\n{}'.format(expected_ifaces))
92+ self.logger.debug('parsed eni ifaces:\n{}'.format(expected_ifaces))
93
94 def _mk_dns_lines(dns_type, config):
95 """ nameservers get a line per ns
96@@ -225,7 +225,7 @@ class TestNetworkBaseTestsAbs(VMBaseClass):
97 for k, v in iface.get('dns', {}).items():
98 print('k=%s v=%s' % (k, v))
99 for dns_line in _mk_dns_lines(k, v):
100- logger.debug('dns_line:%s', dns_line)
101+ self.logger.debug('dns_line:%s', dns_line)
102 self.assertTrue(dns_line in resolv_lines)
103
104 def test_static_routes(self):
105@@ -263,24 +263,24 @@ class TestNetworkBaseTestsAbs(VMBaseClass):
106 def test_ip_output(self):
107 '''check iproute2 'ip a' output with test input'''
108 network_state = self.get_network_state()
109- logger.debug('expected_network_state:\n{}'.format(
110+ self.logger.debug('expected_network_state:\n{}'.format(
111 yaml.dump(network_state, default_flow_style=False, indent=4)))
112
113 ip_a = self.load_collect_file("ip_a")
114- logger.debug('ip a:\n{}'.format(ip_a))
115+ self.logger.debug('ip a:\n{}'.format(ip_a))
116
117 ip_dict = helpers.ip_a_to_dict(ip_a)
118 print('parsed ip_a dict:\n{}'.format(
119 yaml.dump(ip_dict, default_flow_style=False, indent=4)))
120
121 route_n = self.load_collect_file("route_n")
122- logger.debug("route -n:\n{}".format(route_n))
123+ self.logger.debug("route -n:\n{}".format(route_n))
124
125 route_6_n = self.load_collect_file("route_6_n")
126- logger.debug("route -6 -n:\n{}".format(route_6_n))
127+ self.logger.debug("route -6 -n:\n{}".format(route_6_n))
128
129 ip_route_show = self.load_collect_file("ip_route_show")
130- logger.debug("ip route show:\n{}".format(ip_route_show))
131+ self.logger.debug("ip route show:\n{}".format(ip_route_show))
132 for line in [line for line in ip_route_show.split('\n')
133 if 'src' in line and not line.startswith('default')]:
134 print('ip_route_show: line: %s' % line)
135@@ -292,7 +292,7 @@ class TestNetworkBaseTestsAbs(VMBaseClass):
136 line)
137 if m:
138 route_info = m.groupdict('')
139- logger.debug(route_info)
140+ self.logger.debug(route_info)
141 else:
142 raise ValueError('Failed match ip_route_show line: %s' % line)
143
144@@ -399,8 +399,8 @@ class TestNetworkBaseTestsAbs(VMBaseClass):
145 configured_gws = __find_gw_config(subnet)
146 print('iface:%s configured_gws: %s' % (ifname, configured_gws))
147 for gw_ip in configured_gws:
148- logger.debug('found a gateway in subnet config: %s',
149- gw_ip)
150+ self.logger.debug('found a gateway in subnet config: %s',
151+ gw_ip)
152 if ":" in gw_ip:
153 route_d = routes['6']
154 else:
155@@ -408,8 +408,8 @@ class TestNetworkBaseTestsAbs(VMBaseClass):
156
157 found_gws = [line for line in route_d.split('\n')
158 if 'UG' in line and gw_ip in line]
159- logger.debug('found gateways in guest output:\n%s',
160- found_gws)
161+ self.logger.debug('found gateways in guest output:\n%s',
162+ found_gws)
163
164 print('found_gws: %s\nexpected: %s' % (found_gws,
165 configured_gws))
166@@ -422,8 +422,8 @@ class TestNetworkBaseTestsAbs(VMBaseClass):
167 else:
168 (dest, gw, genmask, flags, metric, ref, use, iface) = \
169 fgw.split()
170- logger.debug('configured gw:%s found gw:%s', gw_ip,
171- gw)
172+ self.logger.debug('configured gw:%s found gw:%s',
173+ gw_ip, gw)
174 self.assertEqual(gw_ip, gw)
175
176
177diff --git a/tests/vmtests/test_network_bonding.py b/tests/vmtests/test_network_bonding.py
178index 6d7e391..2be7cc3 100644
179--- a/tests/vmtests/test_network_bonding.py
180+++ b/tests/vmtests/test_network_bonding.py
181@@ -1,4 +1,3 @@
182-from . import logger
183 from .releases import base_vm_classes as relbase
184 from .test_network import TestNetworkBaseTestsAbs
185 from .releases import centos_base_vm_classes as centos_relbase
186@@ -28,7 +27,7 @@ class CentosTestNetworkBondingAbs(TestNetworkBondingAbs):
187
188 def test_ifenslave_installed(self):
189 status = self.load_collect_file("ifenslave_installed")
190- logger.debug('ifenslave installed: {}'.format(status))
191+ self.logger.debug('ifenslave installed: {}'.format(status))
192 self.assertTrue('iputils' in status)
193
194 def test_etc_network_interfaces(self):
195diff --git a/tests/vmtests/test_network_bridging.py b/tests/vmtests/test_network_bridging.py
196index f0e9c18..b440bc9 100644
197--- a/tests/vmtests/test_network_bridging.py
198+++ b/tests/vmtests/test_network_bridging.py
199@@ -1,4 +1,3 @@
200-from . import logger
201 from .releases import base_vm_classes as relbase
202 from .releases import centos_base_vm_classes as centos_relbase
203 from .test_network import TestNetworkBaseTestsAbs
204@@ -154,7 +153,7 @@ class TestBridgeNetworkAbs(TestNetworkBaseTestsAbs):
205 if self._network_renderer() == "systemd-networkd":
206 reason = ("%s: skip until lp#1668347"
207 " is fixed" % self.__class__)
208- logger.warn('Skipping: %s', reason)
209+ self.logger.warn('Skipping: %s', reason)
210 print(reason)
211 return
212
213@@ -203,7 +202,7 @@ class CentosTestBridgeNetworkAbs(TestBridgeNetworkAbs):
214 def test_bridge_utils_installed(self):
215 self.output_files_exist(["bridge-utils_installed"])
216 status = self.load_collect_file("bridge-utils_installed").strip()
217- logger.debug('bridge-utils installed: {}'.format(status))
218+ self.logger.debug('bridge-utils installed: {}'.format(status))
219 self.assertTrue('bridge' in status)
220
221
222diff --git a/tests/vmtests/test_network_enisource.py b/tests/vmtests/test_network_enisource.py
223index aa1fccd..fa5ec45 100644
224--- a/tests/vmtests/test_network_enisource.py
225+++ b/tests/vmtests/test_network_enisource.py
226@@ -1,4 +1,4 @@
227-from . import logger, helpers
228+from . import helpers
229 from .releases import base_vm_classes as relbase
230 from .test_network import TestNetworkBaseTestsAbs
231
232@@ -51,16 +51,16 @@ class TestNetworkENISource(TestNetworkBaseTestsAbs):
233 subprocess.check_call(cmd, stderr=subprocess.STDOUT)
234
235 curtin_ifaces = self.parse_deb_config(interfaces)
236- logger.debug('parsed eni dict:\n{}'.format(
237+ self.logger.debug('parsed eni dict:\n{}'.format(
238 yaml.dump(curtin_ifaces, default_flow_style=False, indent=4)))
239 print('parsed eni dict:\n{}'.format(
240 yaml.dump(curtin_ifaces, default_flow_style=False, indent=4)))
241
242 ip_a = self.load_collect_file("ip_a")
243- logger.debug('ip a:\n{}'.format(ip_a))
244+ self.logger.debug('ip a:\n{}'.format(ip_a))
245
246 ip_a_dict = helpers.ip_a_to_dict(ip_a)
247- logger.debug('parsed ip_a dict:\n{}'.format(
248+ self.logger.debug('parsed ip_a dict:\n{}'.format(
249 yaml.dump(ip_a_dict, default_flow_style=False, indent=4)))
250 print('parsed ip_a dict:\n{}'.format(
251 yaml.dump(ip_a_dict, default_flow_style=False, indent=4)))
252diff --git a/tests/vmtests/test_network_vlan.py b/tests/vmtests/test_network_vlan.py
253index 01fa46e..9385551 100644
254--- a/tests/vmtests/test_network_vlan.py
255+++ b/tests/vmtests/test_network_vlan.py
256@@ -1,4 +1,3 @@
257-from . import logger
258 from .releases import base_vm_classes as relbase
259 from .releases import centos_base_vm_classes as centos_relbase
260 from .test_network import TestNetworkBaseTestsAbs
261@@ -20,9 +19,9 @@ class TestNetworkVlanAbs(TestNetworkBaseTestsAbs):
262
263 def get_vlans(self):
264 network_state = self.get_network_state()
265- logger.debug('get_vlans ns:\n%s',
266- yaml.dump(network_state, default_flow_style=False,
267- indent=4))
268+ self.logger.debug('get_vlans ns:\n%s',
269+ yaml.dump(network_state, default_flow_style=False,
270+ indent=4))
271 interfaces = network_state.get('interfaces')
272 return [iface for iface in interfaces.values()
273 if iface['type'] == 'vlan']

Subscribers

People subscribed via source and target branches