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 "Node was deleted by other transaction",
69 "Optimistic lock failed for path /(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)" +
70 "interfaces/interface/interface[{(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)name=",
72 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
73 "id": "ConflictingModificationAppliedException",
75 "ConflictingModificationAppliedException: Node children was modified by other transaction",
76 "OptimisticLockFailedException",
77 "Conflicting modification for path /(urn:opendaylight:netvirt:l3vpn?revision=2013-09-11)" +
78 "vpn-instance-op-data/vpn-instance-op-data-entry/vpn-instance-op-data-entry" +
79 "[{(urn:opendaylight:netvirt:l3vpn?revision=2013-09-11)vrf-id="
81 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
82 "id": "ExecutionException",
84 "OptimisticLockFailedException: Optimistic lock failed",
85 "ConflictingModificationAppliedException: Node children was modified by other transaction",
86 "removeOrUpdateVpnToDpnList: Error removing from dpnToVpnList for vpn "
88 {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1281",
89 "id": "OptimisticLockFailedException",
91 "OptimisticLockFailedException: Optimistic lock failed.",
92 "ConflictingModificationAppliedException: Node children was modified by other transaction",
93 "Direct Exception (not failed Future) when executing job, won't even retry: JobEntry{key='VPNINTERFACE-"
95 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
96 "id": "ConflictingModificationAppliedException",
98 "Optimistic lock failed for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
99 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
100 "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
101 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid="
103 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
104 "id": "OptimisticLockFailedException",
106 "Got OptimisticLockFailedException",
107 "AbstractTranscriberInterface"
109 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
110 "id": "ConflictingModificationAppliedException",
112 "Optimistic lock failed for path /(urn:opendaylight:neutron?revision=2015-07-12)neutron"
115 {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
116 "id": "ConflictingModificationAppliedException",
118 "OptimisticLockFailedException: Optimistic lock failed.",
119 "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
120 "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
122 {"issue": "https://jira.opendaylight.org/browse/OPNFLWPLUG-917",
123 "id": "IllegalStateException",
125 "java.lang.IllegalStateException: Deserializer for key: msgVersion: 4 objectClass: " +
126 "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry " +
127 "msgType: 1 oxm_field: 33 experimenterID: null was not found " +
128 "- please verify that all needed deserializers ale loaded correctly"
132 _re_ts = re.compile(r"^[0-9]{4}(-[0-9]{2}){2}T([0-9]{2}:){2}[0-9]{2},[0-9]{3}")
133 _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 \| )")
134 _re_ex = re.compile(r"(?i)exception")
135 _ex_map = collections.OrderedDict()
140 def get_exceptions(lines):
142 Create a map of exceptions that also has a list of warnings and errors preceeding
143 the exception to use as context.
145 The lines are parsed to create a list where all lines related to a timestamp
146 are aggregated. Timestamped lines with exception (case insensitive) are copied
147 to the exception map keyed to the index of the timestamp line. Each exception value
148 also has a list containing WARN and ERROR lines proceeding the exception.
151 :return OrderedDict _ex_map: map of exceptions
154 _ex_map = collections.OrderedDict()
158 warnerr_deq = collections.deque(maxlen=5)
161 ts = _re_ts.search(line)
163 # Check if this is the start or continuation of a timestamp line
166 _ts_list.append(cur_list)
167 ts_we = _re_ts_we.search(line)
168 # Track WARN and ERROR lines
170 warn_err_index = len(_ts_list) - 1
171 warnerr_deq.append(warn_err_index)
172 # Append to current timestamp line since this is not a timestamp line
174 cur_list.append(line)
176 # Add the timestamp line to the exception map if it has an exception
177 ex = _re_ex.search(line)
179 index = len(_ts_list) - 1
180 if index not in _ex_map:
181 _ex_map[index] = {"warnerr_list": list(warnerr_deq), 'lines': cur_list}
182 warnerr_deq.clear() # reset the deque to only track new ERROR and WARN lines
187 def check_exceptions():
189 Return a list of exceptions that were not in the whitelist.
191 Each exception found is compared against all the patterns
194 :return list _fail: list of exceptions not in the whitelist
199 for ex_idx, ex in _ex_map.items():
200 ex_str = "__".join(ex.get("lines"))
201 for whitelist in _whitelist:
202 # skip the current whitelist exception if not in the current exception
203 if whitelist.get("id") not in ex_str:
205 whitelist_contexts = whitelist.get("context")
206 num_context_matches = 0
207 for whitelist_context in whitelist_contexts:
208 for exwe_index in reversed(ex.get("warnerr_list")):
209 exwe_str = "__".join(_ts_list[exwe_index])
210 if whitelist_context in exwe_str:
211 num_context_matches += 1
212 # Mark this exception as a known issue if all the context's matched
213 if num_context_matches >= len(whitelist_contexts):
214 ex["issue"] = whitelist.get("issue")
216 logging.info("known exception was seen: {}".format(ex["issue"]))
218 # A new exception when it isn't marked with a known issue.
219 if "issue" not in ex:
224 def verify_exceptions(lines):
226 Return a list of exceptions not in the whitelist for the given lines.
228 :param list lines: list of lines from a log
229 :return list, list: one list of exceptions not in the whitelist, and a second with matching issues
233 get_exceptions(lines)
234 return check_exceptions()
237 def write_exceptions_map_to_file(testname, filename, mode="a+"):
239 Write the exceptions map to a file under the testname header. The output
240 will include all lines in the exception itself as well as any previous
241 contextual warning or error lines. The output will be appended or overwritten
242 depending on the mode parameter. It is assumed that the caller has called
243 verify_exceptions() earlier to populate the exceptions map, otherwise only
244 the testname and header will be printed to the file.
246 :param str testname: The name of the test
247 :param str filename: The file to open for writing
248 :param str mode: Append (a+) or overwrite (w+)
251 os.makedirs(os.path.dirname(filename))
252 except OSError as exception:
253 if exception.errno != errno.EEXIST:
256 with open(filename, mode) as fp:
257 fp.write("Starting test: {}\n".format(testname))
258 fp.write("{}\n".format("-" * 40))
259 for ex_idx, ex in _ex_map.items():
260 for exwe_index in ex.get("warnerr_list"):
261 for line in _ts_list[exwe_index]:
263 fp.writelines(ex.get("lines"))