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.",
18 "Conflicting modification for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
19 "[{(urn:opendaylight:inventory?revision=2013-08-19)id=",
20 "table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=21}]/flow/flow" +
21 "[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=L3.", ".21.", ".42."
24 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-972",
25 "id": "ConflictingModificationAppliedException",
27 "Node was created by other transaction",
28 "OptimisticLockFailedException: Optimistic lock failed."
29 "Conflicting modification for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
30 "[{(urn:opendaylight:inventory?revision=2013-08-19)id=",
31 "table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=21}]/flow/flow" +
32 "[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=L3.", ".21.", ".42."
34 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1135",
35 "id": "ConflictingModificationAppliedException",
37 "Node was created by other transaction",
38 "Optimistic lock failed for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
39 "[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:",
40 "Conflicting modification for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
41 "[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:",
42 "table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=47}]/flow/flow" +
43 "[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=SNAT.", ".47."
46 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1135",
47 "id": "ConflictingModificationAppliedException",
49 "OptimisticLockFailedException: Optimistic lock failed."
50 "Conflicting modification for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
51 "[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:",
52 "table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=47}]/flow/flow" +
53 "[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=SNAT.", ".47."
55 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1136",
56 "id": "ConflictingModificationAppliedException",
58 "Node was deleted by other transaction",
59 "Optimistic lock failed for path /(urn:opendaylight:netvirt:elan?revision=2015-06-02)elan-" +
60 "forwarding-tables/mac-table/mac-table[{(urn:opendaylight:netvirt:elan?revision=2015-06-02)" +
61 "elan-instance-name=",
62 "Conflicting modification for path /(urn:opendaylight:netvirt:elan?revision=2015-06-02)elan-" +
63 "forwarding-tables/mac-table/mac-table[{(urn:opendaylight:netvirt:elan?revision=2015-06-02)" +
66 # oxygen version of NETVIRT-1136
67 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1136",
68 "id": "ConflictingModificationAppliedException",
70 "Node was deleted by other transaction",
71 "OptimisticLockFailedException: Optimistic lock failed.",
72 "Conflicting modification for path /(urn:opendaylight:netvirt:elan?revision=2015-06-02)elan-" +
73 "forwarding-tables/mac-table/mac-table[{(urn:opendaylight:netvirt:elan?revision=2015-06-02)" +
76 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1260",
77 "id": "ConflictingModificationAppliedException",
79 "Node was deleted by other transaction",
80 "Optimistic lock failed for path /(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)" +
81 "interfaces/interface/interface[{(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)name=",
82 "Conflicting modification for path /(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)" +
83 "interfaces/interface/interface[{(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)name="
85 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
86 "id": "ConflictingModificationAppliedException",
88 "ConflictingModificationAppliedException: Node children was modified by other transaction",
89 "OptimisticLockFailedException",
90 "Conflicting modification for path /(urn:opendaylight:netvirt:l3vpn?revision=2013-09-11)" +
91 "vpn-instance-op-data/vpn-instance-op-data-entry/vpn-instance-op-data-entry" +
92 "[{(urn:opendaylight:netvirt:l3vpn?revision=2013-09-11)vrf-id="
94 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
95 "id": "ExecutionException",
97 "OptimisticLockFailedException: Optimistic lock failed",
98 "ConflictingModificationAppliedException: Node children was modified by other transaction",
99 "removeOrUpdateVpnToDpnList: Error removing from dpnToVpnList for vpn "
101 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1281",
102 "id": "OptimisticLockFailedException",
104 "OptimisticLockFailedException: Optimistic lock failed.",
105 "ConflictingModificationAppliedException: Node children was modified by other transaction",
106 "Direct Exception (not failed Future) when executing job, won't even retry: JobEntry{key='VPNINTERFACE-"
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)" +
112 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
113 "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
114 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid="
116 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
117 "id": "OptimisticLockFailedException",
119 "Got OptimisticLockFailedException",
120 "AbstractTranscriberInterface"
122 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
123 "id": "ConflictingModificationAppliedException",
125 "Optimistic lock failed for path /(urn:opendaylight:neutron?revision=2015-07-12)neutron"
128 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
129 "id": "ConflictingModificationAppliedException",
131 "OptimisticLockFailedException: Optimistic lock failed.",
132 "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
133 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
135 {"issue": "https://jira.opendaylight.org/browse/OPNFLWPLUG-917",
136 "id": "IllegalStateException",
138 "java.lang.IllegalStateException: Deserializer for key: msgVersion: 4 objectClass: " +
139 "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry " +
140 "msgType: 1 oxm_field: 33 experimenterID: null was not found " +
141 "- please verify that all needed deserializers ale loaded correctly"
145 _re_ts = re.compile(r"^[0-9]{4}(-[0-9]{2}){2}T([0-9]{2}:){2}[0-9]{2},[0-9]{3}")
146 _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 \| )")
147 _re_ex = re.compile(r"(?i)exception")
148 _ex_map = collections.OrderedDict()
153 def get_exceptions(lines):
155 Create a map of exceptions that also has a list of warnings and errors preceeding
156 the exception to use as context.
158 The lines are parsed to create a list where all lines related to a timestamp
159 are aggregated. Timestamped lines with exception (case insensitive) are copied
160 to the exception map keyed to the index of the timestamp line. Each exception value
161 also has a list containing WARN and ERROR lines proceeding the exception.
164 :return OrderedDict _ex_map: map of exceptions
167 _ex_map = collections.OrderedDict()
171 warnerr_deq = collections.deque(maxlen=5)
174 ts = _re_ts.search(line)
176 # Check if this is the start or continuation of a timestamp line
179 _ts_list.append(cur_list)
180 ts_we = _re_ts_we.search(line)
181 # Track WARN and ERROR lines
183 warn_err_index = len(_ts_list) - 1
184 warnerr_deq.append(warn_err_index)
185 # Append to current timestamp line since this is not a timestamp line
187 cur_list.append(line)
189 # Add the timestamp line to the exception map if it has an exception
190 ex = _re_ex.search(line)
192 index = len(_ts_list) - 1
193 if index not in _ex_map:
194 _ex_map[index] = {"warnerr_list": list(warnerr_deq), 'lines': cur_list}
195 warnerr_deq.clear() # reset the deque to only track new ERROR and WARN lines
200 def check_exceptions():
202 Return a list of exceptions that were not in the whitelist.
204 Each exception found is compared against all the patterns
207 :return list _fail: list of exceptions not in the whitelist
212 for ex_idx, ex in _ex_map.items():
213 ex_str = "__".join(ex.get("lines"))
214 for whitelist in _whitelist:
215 # skip the current whitelist exception if not in the current exception
216 if whitelist.get("id") not in ex_str:
218 whitelist_contexts = whitelist.get("context")
219 num_context_matches = 0
220 for whitelist_context in whitelist_contexts:
221 for exwe_index in reversed(ex.get("warnerr_list")):
222 exwe_str = "__".join(_ts_list[exwe_index])
223 if whitelist_context in exwe_str:
224 num_context_matches += 1
225 # Mark this exception as a known issue if all the context's matched
226 if num_context_matches >= len(whitelist_contexts):
227 ex["issue"] = whitelist.get("issue")
229 logging.info("known exception was seen: {}".format(ex["issue"]))
231 # A new exception when it isn't marked with a known issue.
232 if "issue" not in ex:
237 def verify_exceptions(lines):
239 Return a list of exceptions not in the whitelist for the given lines.
241 :param list lines: list of lines from a log
242 :return list, list: one list of exceptions not in the whitelist, and a second with matching issues
246 get_exceptions(lines)
247 return check_exceptions()
250 def write_exceptions_map_to_file(testname, filename, mode="a+"):
252 Write the exceptions map to a file under the testname header. The output
253 will include all lines in the exception itself as well as any previous
254 contextual warning or error lines. The output will be appended or overwritten
255 depending on the mode parameter. It is assumed that the caller has called
256 verify_exceptions() earlier to populate the exceptions map, otherwise only
257 the testname and header will be printed to the file.
259 :param str testname: The name of the test
260 :param str filename: The file to open for writing
261 :param str mode: Append (a+) or overwrite (w+)
264 os.makedirs(os.path.dirname(filename))
265 except OSError as exception:
266 if exception.errno != errno.EEXIST:
269 with open(filename, mode) as fp:
270 fp.write("Starting test: {}\n".format(testname))
271 fp.write("{}\n".format("-" * 40))
272 for ex_idx, ex in _ex_map.items():
273 for exwe_index in ex.get("warnerr_list"):
274 for line in _ts_list[exwe_index]:
276 fp.writelines(ex.get("lines"))