]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/lib/topolog.py
tests: Disable test which fails under micronet
[mirror_frr.git] / tests / topotests / lib / topolog.py
CommitLineData
36d1dc45
RZ
1#
2# topolog.py
3# Library of helper functions for NetDEF Topology Tests
4#
5# Copyright (c) 2017 by
6# Network Device Education Foundation, Inc. ("NetDEF")
7#
8# Permission to use, copy, modify, and/or distribute this software
9# for any purpose with or without fee is hereby granted, provided
10# that the above copyright notice and this permission notice appear
11# in all copies.
12#
13# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
14# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
16# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
17# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20# OF THIS SOFTWARE.
21#
22
23"""
24Logging utilities for topology tests.
25
26This file defines our logging abstraction.
27"""
28
29import logging
49581587
CH
30import os
31import subprocess
32import sys
33
34if sys.version_info[0] > 2:
35 import configparser
36else:
37 import ConfigParser as configparser
38
39try:
40 from xdist import is_xdist_controller
41except ImportError:
42 def is_xdist_controller():
43 return False
44
45BASENAME = "topolog"
36d1dc45
RZ
46
47# Helper dictionary to convert Topogen logging levels to Python's logging.
48DEBUG_TOPO2LOGGING = {
787e7624 49 "debug": logging.DEBUG,
50 "info": logging.INFO,
51 "output": logging.INFO,
52 "warning": logging.WARNING,
53 "error": logging.ERROR,
54 "critical": logging.CRITICAL,
36d1dc45 55}
49581587 56FORMAT = "%(asctime)s.%(msecs)03d %(levelname)s: %(name)s: %(message)s"
36d1dc45 57
49581587
CH
58handlers = {}
59logger = logging.getLogger("topolog")
787e7624 60
9427b78f 61
49581587
CH
62def set_handler(l, target=None):
63 if target is None:
64 h = logging.NullHandler()
65 else:
66 if isinstance(target, str):
67 h = logging.FileHandler(filename=target, mode="w")
68 else:
69 h = logging.StreamHandler(stream=target)
70 h.setFormatter(logging.Formatter(fmt=FORMAT))
71 # Don't filter anything at the handler level
72 h.setLevel(logging.DEBUG)
73 l.addHandler(h)
74 return h
787e7624 75
36d1dc45 76
49581587
CH
77def set_log_level(l, level):
78 "Set the logging level."
79 # Messages sent to this logger only are created if this level or above.
80 log_level = DEBUG_TOPO2LOGGING.get(level, level)
81 l.setLevel(log_level)
787e7624 82
77ebccac 83
49581587
CH
84def get_logger(name, log_level=None, target=None):
85 l = logging.getLogger("{}.{}".format(BASENAME, name))
36d1dc45 86
49581587
CH
87 if log_level is not None:
88 set_log_level(l, log_level)
89
90 if target is not None:
91 set_handler(l, target)
92
93 return l
94
95
96# nodeid: all_protocol_startup/test_all_protocol_startup.py::test_router_running
97
98def get_test_logdir(nodeid=None):
99 """Get log directory relative pathname."""
100 xdist_worker = os.getenv("PYTEST_XDIST_WORKER", "")
101 mode = os.getenv("PYTEST_XDIST_MODE", "no")
102
103 if not nodeid:
104 nodeid = os.environ["PYTEST_CURRENT_TEST"].split(" ")[0]
105
106 cur_test = nodeid.replace("[", "_").replace("]", "_")
107 path, testname = cur_test.split("::")
108 path = path[:-3].replace("/", ".")
109
110 # We use different logdir paths based on how xdist is running.
111 if mode == "each":
112 return os.path.join(path, testname, xdist_worker)
113 elif mode == "load":
114 return os.path.join(path, testname)
115 else:
116 assert (
117 mode == "no" or
118 mode == "loadfile" or
119 mode == "loadscope"
120 ), "Unknown dist mode {}".format(mode)
121
122 return path
123
124
125def logstart(nodeid, location, rundir):
126 """Called from pytest before module setup."""
127
128 mode = os.getenv("PYTEST_XDIST_MODE", "no")
129 worker = os.getenv("PYTEST_TOPOTEST_WORKER", "")
130
131 # We only per-test log in the workers (or non-dist)
132 if not worker and mode != "no":
133 return
134
135 handler_id = nodeid + worker
136 assert handler_id not in handlers
137
138 rel_log_dir = get_test_logdir(nodeid)
139 exec_log_dir = os.path.join(rundir, rel_log_dir)
140 subprocess.check_call("mkdir -p {0} && chmod 1777 {0}".format(exec_log_dir), shell=True)
141 exec_log_path = os.path.join(exec_log_dir, "exec.log")
142
143 # Add test based exec log handler
144 h = set_handler(logger, exec_log_path)
145 handlers[handler_id] = h
146
147 if worker:
148 logger.info("Logging on worker %s for %s into %s", worker, handler_id, exec_log_path)
149 else:
150 logger.info("Logging for %s into %s", handler_id, exec_log_path)
151
152
153def logfinish(nodeid, location):
154 """Called from pytest after module teardown."""
155 # This function may not be called if pytest is interrupted.
156
157 worker = os.getenv("PYTEST_TOPOTEST_WORKER", "")
158 handler_id = nodeid + worker
159
160 if handler_id in handlers:
161 # Remove test based exec log handler
162 if worker:
163 logger.info("Closing logs for %s", handler_id)
164
165 h = handlers[handler_id]
166 logger.removeHandler(handlers[handler_id])
167 h.flush()
168 h.close()
169 del handlers[handler_id]
787e7624 170
36d1dc45 171
49581587
CH
172console_handler = set_handler(logger, None)
173set_log_level(logger, "debug")