7 # Make sure to have unique matches in different lines
8 # Order the list in alphabetical order based on the "issue" key
10 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-972",
11 "id": "ConflictingModificationAppliedException",
13 "Node was created by other transaction",
14 "Optimistic lock failed for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
15 "[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow",
16 "table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=21}]/flow/flow" +
17 "[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=L3."
20 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-972",
21 "id": "ConflictingModificationAppliedException",
23 "Node was created by other transaction",
24 "OptimisticLockFailedException: Optimistic lock failed."
25 "Conflicting modification for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
26 "[{(urn:opendaylight:inventory?revision=2013-08-19)id=",
27 "table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=21}]/flow/flow" +
28 "[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=L3.", ".21.", ".42."
30 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1135",
31 "id": "ConflictingModificationAppliedException",
33 "Node was created by other transaction",
34 "Optimistic lock failed for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
35 "[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:",
38 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1135",
39 "id": "ConflictingModificationAppliedException",
41 "OptimisticLockFailedException: Optimistic lock failed."
42 "Conflicting modification for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
43 "[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:",
44 "table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=47}]/flow/flow" +
45 "[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=SNAT.", ".47."
47 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1136",
48 "id": "ConflictingModificationAppliedException",
50 "Node was deleted by other transaction",
51 "Optimistic lock failed for path /(urn:opendaylight:netvirt:elan?revision=2015-06-02)elan-" +
52 "forwarding-tables/mac-table/mac-table[{(urn:opendaylight:netvirt:elan?revision=2015-06-02)" +
53 "elan-instance-name=",
55 # oxygen version of NETVIRT-1136
56 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1136",
57 "id": "ConflictingModificationAppliedException",
59 "Node was deleted by other transaction",
60 "OptimisticLockFailedException: Optimistic lock failed.",
61 "Conflicting modification for path /(urn:opendaylight:netvirt:elan?revision=2015-06-02)elan-" +
62 "forwarding-tables/mac-table/mac-table[{(urn:opendaylight:netvirt:elan?revision=2015-06-02)" +
65 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1260",
66 "id": "ConflictingModificationAppliedException",
68 "Optimistic lock failed for path /(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)" +
69 "interfaces/interface/interface[{(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)name=",
71 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
72 "id": "ConflictingModificationAppliedException",
74 "ConflictingModificationAppliedException: Node children was modified by other transaction",
75 "OptimisticLockFailedException",
76 "Conflicting modification for path /(urn:opendaylight:netvirt:l3vpn?revision=2013-09-11)" +
77 "vpn-instance-op-data/vpn-instance-op-data-entry/vpn-instance-op-data-entry" +
78 "[{(urn:opendaylight:netvirt:l3vpn?revision=2013-09-11)vrf-id="
80 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
81 "id": "ExecutionException",
83 "OptimisticLockFailedException: Optimistic lock failed",
84 "ConflictingModificationAppliedException: Node children was modified by other transaction",
85 "removeOrUpdateVpnToDpnList: Error removing from dpnToVpnList for vpn "
87 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
88 "id": "OptimisticLockFailedException",
90 "OptimisticLockFailedException",
91 "VpnInterfaceOpListener",
92 "Direct Exception (not failed Future) when executing job, won't even retry: JobEntry{key='VPNINTERFACE-",
93 "Optimistic lock failed for path /(urn:opendaylight:netvirt:l3vpn?revision=2013-09-11)" +
94 "vpn-instance-op-data/vpn-instance-op-data-entry/vpn-instance-op-data-entry" +
95 "[{(urn:opendaylight:netvirt:l3vpn?revision=2013-09-11)vrf-id="
97 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1281",
98 "id": "OptimisticLockFailedException",
100 "OptimisticLockFailedException: Optimistic lock failed.",
101 "ConflictingModificationAppliedException: Node children was modified by other transaction",
102 "Direct Exception (not failed Future) when executing job, won't even retry: JobEntry{key='VPNINTERFACE-"
104 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
105 "id": "ConflictingModificationAppliedException",
107 "Optimistic lock failed for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
108 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
109 "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
110 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid="
112 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
113 "id": "OptimisticLockFailedException",
115 "Got OptimisticLockFailedException",
116 "AbstractTranscriberInterface"
118 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
119 "id": "ConflictingModificationAppliedException",
121 "Optimistic lock failed for path /(urn:opendaylight:neutron?revision=2015-07-12)neutron"
124 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
125 "id": "ConflictingModificationAppliedException",
127 "OptimisticLockFailedException: Optimistic lock failed.",
128 "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
129 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
131 {"issue": "https://jira.opendaylight.org/browse/OPNFLWPLUG-917",
132 "id": "IllegalStateException",
134 "java.lang.IllegalStateException: Deserializer for key: msgVersion: 4 objectClass: " +
135 "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry " +
136 "msgType: 1 oxm_field: 33 experimenterID: null was not found " +
137 "- please verify that all needed deserializers ale loaded correctly"
141 _re_ts = re.compile(r"^[0-9]{4}(-[0-9]{2}){2}T([0-9]{2}:){2}[0-9]{2},[0-9]{3}")
142 _re_ts_we = re.compile(r"^[0-9]{4}(-[0-9]{2}){2}T([0-9]{2}:){2}[0-9]{2},[0-9]{3}( \| ERROR \| | \| WARN \| )")
143 _re_ex = re.compile(r"(?i)exception")
144 _ex_map = collections.OrderedDict()
149 def get_exceptions(lines):
151 Create a map of exceptions that also has a list of warnings and errors preceeding
152 the exception to use as context.
154 The lines are parsed to create a list where all lines related to a timestamp
155 are aggregated. Timestamped lines with exception (case insensitive) are copied
156 to the exception map keyed to the index of the timestamp line. Each exception value
157 also has a list containing WARN and ERROR lines proceeding the exception.
160 :return OrderedDict _ex_map: map of exceptions
163 _ex_map = collections.OrderedDict()
167 warnerr_deq = collections.deque(maxlen=5)
170 ts = _re_ts.search(line)
172 # Check if this is the start or continuation of a timestamp line
175 _ts_list.append(cur_list)
176 ts_we = _re_ts_we.search(line)
177 # Track WARN and ERROR lines
179 warn_err_index = len(_ts_list) - 1
180 warnerr_deq.append(warn_err_index)
181 # Append to current timestamp line since this is not a timestamp line
183 cur_list.append(line)
185 # Add the timestamp line to the exception map if it has an exception
186 ex = _re_ex.search(line)
188 index = len(_ts_list) - 1
189 if index not in _ex_map:
190 _ex_map[index] = {"warnerr_list": list(warnerr_deq), 'lines': cur_list}
191 warnerr_deq.clear() # reset the deque to only track new ERROR and WARN lines
196 def check_exceptions():
198 Return a list of exceptions that were not in the whitelist.
200 Each exception found is compared against all the patterns
203 :return list _fail: list of exceptions not in the whitelist
208 for ex_idx, ex in _ex_map.items():
209 ex_str = "__".join(ex.get("lines"))
210 for whitelist in _whitelist:
211 # skip the current whitelist exception if not in the current exception
212 if whitelist.get("id") not in ex_str:
214 whitelist_contexts = whitelist.get("context")
215 num_context_matches = 0
216 for whitelist_context in whitelist_contexts:
217 for exwe_index in reversed(ex.get("warnerr_list")):
218 exwe_str = "__".join(_ts_list[exwe_index])
219 if whitelist_context in exwe_str:
220 num_context_matches += 1
221 # Mark this exception as a known issue if all the context's matched
222 if num_context_matches >= len(whitelist_contexts):
223 ex["issue"] = whitelist.get("issue")
225 logging.info("known exception was seen: {}".format(ex["issue"]))
227 # A new exception when it isn't marked with a known issue.
228 if "issue" not in ex:
233 def verify_exceptions(lines):
235 Return a list of exceptions not in the whitelist for the given lines.
237 :param list lines: list of lines from a log
238 :return list, list: one list of exceptions not in the whitelist, and a second with matching issues
242 get_exceptions(lines)
243 return check_exceptions()
246 def write_exceptions_map_to_file(testname, filename, mode="a+"):
248 Write the exceptions map to a file under the testname header. The output
249 will include all lines in the exception itself as well as any previous
250 contextual warning or error lines. The output will be appended or overwritten
251 depending on the mode parameter. It is assumed that the caller has called
252 verify_exceptions() earlier to populate the exceptions map, otherwise only
253 the testname and header will be printed to the file.
255 :param str testname: The name of the test
256 :param str filename: The file to open for writing
257 :param str mode: Append (a+) or overwrite (w+)
260 os.makedirs(os.path.dirname(filename))
261 except OSError as exception:
262 if exception.errno != errno.EEXIST:
265 with open(filename, mode) as fp:
266 fp.write("{}\n".format("=" * 60))
267 fp.write("Starting test: {}\n".format(testname))
268 for ex_idx, ex in _ex_map.items():
269 fp.write("{}\n".format("-" * 40))
271 fp.write("Exception was matched to: {}\n".format(ex.get("issue")))
273 fp.write("Exception is new\n")
274 for exwe_index in ex.get("warnerr_list")[:-1]:
275 for line in _ts_list[exwe_index]:
276 fp.write("{}\n".format(line))
277 fp.writelines(ex.get("lines"))