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-1281",
88 "id": "OptimisticLockFailedException",
90 "OptimisticLockFailedException: Optimistic lock failed.",
91 "ConflictingModificationAppliedException: Node children was modified by other transaction",
92 "Direct Exception (not failed Future) when executing job, won't even retry: JobEntry{key='VPNINTERFACE-"
94 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
95 "id": "ConflictingModificationAppliedException",
97 "Optimistic lock failed for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
98 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
99 "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
100 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid="
102 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
103 "id": "OptimisticLockFailedException",
105 "Got OptimisticLockFailedException",
106 "AbstractTranscriberInterface"
108 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
109 "id": "ConflictingModificationAppliedException",
111 "Optimistic lock failed for path /(urn:opendaylight:neutron?revision=2015-07-12)neutron"
114 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
115 "id": "ConflictingModificationAppliedException",
117 "OptimisticLockFailedException: Optimistic lock failed.",
118 "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
119 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
121 {"issue": "https://jira.opendaylight.org/browse/OPNFLWPLUG-917",
122 "id": "IllegalStateException",
124 "java.lang.IllegalStateException: Deserializer for key: msgVersion: 4 objectClass: " +
125 "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry " +
126 "msgType: 1 oxm_field: 33 experimenterID: null was not found " +
127 "- please verify that all needed deserializers ale loaded correctly"
131 _re_ts = re.compile(r"^[0-9]{4}(-[0-9]{2}){2}T([0-9]{2}:){2}[0-9]{2},[0-9]{3}")
132 _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 \| )")
133 _re_ex = re.compile(r"(?i)exception")
134 _ex_map = collections.OrderedDict()
139 def get_exceptions(lines):
141 Create a map of exceptions that also has a list of warnings and errors preceeding
142 the exception to use as context.
144 The lines are parsed to create a list where all lines related to a timestamp
145 are aggregated. Timestamped lines with exception (case insensitive) are copied
146 to the exception map keyed to the index of the timestamp line. Each exception value
147 also has a list containing WARN and ERROR lines proceeding the exception.
150 :return OrderedDict _ex_map: map of exceptions
153 _ex_map = collections.OrderedDict()
157 warnerr_deq = collections.deque(maxlen=5)
160 ts = _re_ts.search(line)
162 # Check if this is the start or continuation of a timestamp line
165 _ts_list.append(cur_list)
166 ts_we = _re_ts_we.search(line)
167 # Track WARN and ERROR lines
169 warn_err_index = len(_ts_list) - 1
170 warnerr_deq.append(warn_err_index)
171 # Append to current timestamp line since this is not a timestamp line
173 cur_list.append(line)
175 # Add the timestamp line to the exception map if it has an exception
176 ex = _re_ex.search(line)
178 index = len(_ts_list) - 1
179 if index not in _ex_map:
180 _ex_map[index] = {"warnerr_list": list(warnerr_deq), 'lines': cur_list}
181 warnerr_deq.clear() # reset the deque to only track new ERROR and WARN lines
186 def check_exceptions():
188 Return a list of exceptions that were not in the whitelist.
190 Each exception found is compared against all the patterns
193 :return list _fail: list of exceptions not in the whitelist
198 for ex_idx, ex in _ex_map.items():
199 ex_str = "__".join(ex.get("lines"))
200 for whitelist in _whitelist:
201 # skip the current whitelist exception if not in the current exception
202 if whitelist.get("id") not in ex_str:
204 whitelist_contexts = whitelist.get("context")
205 num_context_matches = 0
206 for whitelist_context in whitelist_contexts:
207 for exwe_index in reversed(ex.get("warnerr_list")):
208 exwe_str = "__".join(_ts_list[exwe_index])
209 if whitelist_context in exwe_str:
210 num_context_matches += 1
211 # Mark this exception as a known issue if all the context's matched
212 if num_context_matches >= len(whitelist_contexts):
213 ex["issue"] = whitelist.get("issue")
215 logging.info("known exception was seen: {}".format(ex["issue"]))
217 # A new exception when it isn't marked with a known issue.
218 if "issue" not in ex:
223 def verify_exceptions(lines):
225 Return a list of exceptions not in the whitelist for the given lines.
227 :param list lines: list of lines from a log
228 :return list, list: one list of exceptions not in the whitelist, and a second with matching issues
232 get_exceptions(lines)
233 return check_exceptions()
236 def write_exceptions_map_to_file(testname, filename, mode="a+"):
238 Write the exceptions map to a file under the testname header. The output
239 will include all lines in the exception itself as well as any previous
240 contextual warning or error lines. The output will be appended or overwritten
241 depending on the mode parameter. It is assumed that the caller has called
242 verify_exceptions() earlier to populate the exceptions map, otherwise only
243 the testname and header will be printed to the file.
245 :param str testname: The name of the test
246 :param str filename: The file to open for writing
247 :param str mode: Append (a+) or overwrite (w+)
250 os.makedirs(os.path.dirname(filename))
251 except OSError as exception:
252 if exception.errno != errno.EEXIST:
255 with open(filename, mode) as fp:
256 fp.write("Starting test: {}\n".format(testname))
257 fp.write("{}\n".format("-" * 40))
258 for ex_idx, ex in _ex_map.items():
259 for exwe_index in ex.get("warnerr_list"):
260 for line in _ts_list[exwe_index]:
262 fp.writelines(ex.get("lines"))