update whitelist for NETVIRT-1270
[integration/test.git] / csit / libraries / netvirt / excepts.py
index 7c21fbed0c9dac0f9dcda60429c267329209d107..a00cffea4f51644dfd0cc339511d38bcf8b6c821 100644 (file)
@@ -1,5 +1,7 @@
 import collections
 import collections
+import errno
 import logging
 import logging
+import os
 import re
 
 # Make sure to have unique matches in different lines
 import re
 
 # Make sure to have unique matches in different lines
@@ -12,11 +14,7 @@ _whitelist = [
          "Optimistic lock failed for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
          "[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow",
          "table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=21}]/flow/flow" +
          "Optimistic lock failed for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
          "[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow",
          "table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=21}]/flow/flow" +
-         "[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=L3.",
-         "Conflicting modification for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
-         "[{(urn:opendaylight:inventory?revision=2013-08-19)id=",
-         "table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=21}]/flow/flow" +
-         "[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=L3.", ".21.", ".42."
+         "[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=L3."
      ]},
     # oxygen
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-972",
      ]},
     # oxygen
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-972",
@@ -35,10 +33,6 @@ _whitelist = [
          "Node was created by other transaction",
          "Optimistic lock failed for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
          "[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:",
          "Node was created by other transaction",
          "Optimistic lock failed for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
          "[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:",
-         "Conflicting modification for path /(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node" +
-         "[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:",
-         "table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=47}]/flow/flow" +
-         "[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=SNAT.", ".47."
      ]},
     # oxygen
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1135",
      ]},
     # oxygen
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1135",
@@ -57,9 +51,6 @@ _whitelist = [
          "Optimistic lock failed for path /(urn:opendaylight:netvirt:elan?revision=2015-06-02)elan-" +
          "forwarding-tables/mac-table/mac-table[{(urn:opendaylight:netvirt:elan?revision=2015-06-02)" +
          "elan-instance-name=",
          "Optimistic lock failed for path /(urn:opendaylight:netvirt:elan?revision=2015-06-02)elan-" +
          "forwarding-tables/mac-table/mac-table[{(urn:opendaylight:netvirt:elan?revision=2015-06-02)" +
          "elan-instance-name=",
-         "Conflicting modification for path /(urn:opendaylight:netvirt:elan?revision=2015-06-02)elan-" +
-         "forwarding-tables/mac-table/mac-table[{(urn:opendaylight:netvirt:elan?revision=2015-06-02)" +
-         "elan-instance-name="
      ]},
     # oxygen version of NETVIRT-1136
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1136",
      ]},
     # oxygen version of NETVIRT-1136
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1136",
@@ -74,11 +65,8 @@ _whitelist = [
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1260",
      "id": "ConflictingModificationAppliedException",
      "context": [
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1260",
      "id": "ConflictingModificationAppliedException",
      "context": [
-         "Node was deleted by other transaction",
          "Optimistic lock failed for path /(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)" +
          "interfaces/interface/interface[{(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)name=",
          "Optimistic lock failed for path /(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)" +
          "interfaces/interface/interface[{(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)name=",
-         "Conflicting modification for path /(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)" +
-         "interfaces/interface/interface[{(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)name="
      ]},
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
      "id": "ConflictingModificationAppliedException",
      ]},
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
      "id": "ConflictingModificationAppliedException",
@@ -92,10 +80,20 @@ _whitelist = [
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
      "id": "ExecutionException",
      "context": [
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
      "id": "ExecutionException",
      "context": [
-         "OptimisticLockFailedException: Optimistic lock failed.",
+         "OptimisticLockFailedException: Optimistic lock failed",
          "ConflictingModificationAppliedException: Node children was modified by other transaction",
          "removeOrUpdateVpnToDpnList: Error removing from dpnToVpnList for vpn "
      ]},
          "ConflictingModificationAppliedException: Node children was modified by other transaction",
          "removeOrUpdateVpnToDpnList: Error removing from dpnToVpnList for vpn "
      ]},
+    {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1270",
+     "id": "OptimisticLockFailedException",
+     "context": [
+         "OptimisticLockFailedException",
+         "VpnInterfaceOpListener",
+         "Direct Exception (not failed Future) when executing job, won't even retry: JobEntry{key='VPNINTERFACE-",
+         "Optimistic lock failed for path /(urn:opendaylight:netvirt:l3vpn?revision=2013-09-11)" +
+         "vpn-instance-op-data/vpn-instance-op-data-entry/vpn-instance-op-data-entry" +
+         "[{(urn:opendaylight:netvirt:l3vpn?revision=2013-09-11)vrf-id="
+     ]},
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1281",
      "id": "OptimisticLockFailedException",
      "context": [
     {"issue": "https://jira.opendaylight.org/browse/NETVIRT-1281",
      "id": "OptimisticLockFailedException",
      "context": [
@@ -106,23 +104,26 @@ _whitelist = [
     {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
      "id": "ConflictingModificationAppliedException",
      "context": [
     {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
      "id": "ConflictingModificationAppliedException",
      "context": [
-         "Node was deleted by other transaction",
          "Optimistic lock failed for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
          "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
          "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
          "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid="
      ]},
     {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
          "Optimistic lock failed for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
          "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
          "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
          "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid="
      ]},
     {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
-     "id": "ConflictingModificationAppliedException",
+     "id": "OptimisticLockFailedException",
      "context": [
      "context": [
-         "Got OptimisticLockFailedException", "NeutronNetwork [networkUUID=",
+         "Got OptimisticLockFailedException",
          "AbstractTranscriberInterface"
      ]},
          "AbstractTranscriberInterface"
      ]},
+    {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
+     "id": "ConflictingModificationAppliedException",
+     "context": [
+         "Optimistic lock failed for path /(urn:opendaylight:neutron?revision=2015-07-12)neutron"
+     ]},
     # oxygen
     {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
      "id": "ConflictingModificationAppliedException",
      "context": [
     # oxygen
     {"issue": "https://jira.opendaylight.org/browse/NEUTRON-157",
      "id": "ConflictingModificationAppliedException",
      "context": [
-         "Node was deleted by other transaction",
          "OptimisticLockFailedException: Optimistic lock failed.",
          "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
          "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
          "OptimisticLockFailedException: Optimistic lock failed.",
          "Conflicting modification for path /(urn:opendaylight:neutron?revision=2015-07-12)" +
          "neutron/networks/network/network[{(urn:opendaylight:neutron?revision=2015-07-12)uuid=",
@@ -153,7 +154,7 @@ def get_exceptions(lines):
     The lines are parsed to create a list where all lines related to a timestamp
     are aggregated. Timestamped lines with exception (case insensitive) are copied
     to the exception map keyed to the index of the timestamp line. Each exception value
     The lines are parsed to create a list where all lines related to a timestamp
     are aggregated. Timestamped lines with exception (case insensitive) are copied
     to the exception map keyed to the index of the timestamp line. Each exception value
-    also has a 3 element list containing the last three WARN and ERROR lines.
+    also has a list containing WARN and ERROR lines proceeding the exception.
 
     :param list lines:
     :return OrderedDict _ex_map: map of exceptions
 
     :param list lines:
     :return OrderedDict _ex_map: map of exceptions
@@ -217,9 +218,8 @@ def check_exceptions():
                     exwe_str = "__".join(_ts_list[exwe_index])
                     if whitelist_context in exwe_str:
                         num_context_matches += 1
                     exwe_str = "__".join(_ts_list[exwe_index])
                     if whitelist_context in exwe_str:
                         num_context_matches += 1
-                        break
             # Mark this exception as a known issue if all the context's matched
             # Mark this exception as a known issue if all the context's matched
-            if num_context_matches == len(whitelist_contexts):
+            if num_context_matches >= len(whitelist_contexts):
                 ex["issue"] = whitelist.get("issue")
                 _match.append(ex)
                 logging.info("known exception was seen: {}".format(ex["issue"]))
                 ex["issue"] = whitelist.get("issue")
                 _match.append(ex)
                 logging.info("known exception was seen: {}".format(ex["issue"]))
@@ -241,3 +241,38 @@ def verify_exceptions(lines):
         return
     get_exceptions(lines)
     return check_exceptions()
         return
     get_exceptions(lines)
     return check_exceptions()
+
+
+def write_exceptions_map_to_file(testname, filename, mode="a+"):
+    """
+    Write the exceptions map to a file under the testname header. The output
+    will include all lines in the exception itself as well as any previous
+    contextual warning or error lines. The output will be appended or overwritten
+    depending on the mode parameter. It is assumed that the caller has called
+    verify_exceptions() earlier to populate the exceptions map, otherwise only
+    the testname and header will be printed to the file.
+
+    :param str testname: The name of the test
+    :param str filename: The file to open for writing
+    :param str mode: Append (a+) or overwrite (w+)
+    """
+    try:
+        os.makedirs(os.path.dirname(filename))
+    except OSError as exception:
+        if exception.errno != errno.EEXIST:
+            raise
+
+    with open(filename, mode) as fp:
+        fp.write("{}\n".format("=" * 60))
+        fp.write("Starting test: {}\n".format(testname))
+        for ex_idx, ex in _ex_map.items():
+            fp.write("{}\n".format("-" * 40))
+            if "issue" in ex:
+                fp.write("Exception was matched to: {}\n".format(ex.get("issue")))
+            else:
+                fp.write("Exception is new\n")
+            for exwe_index in ex.get("warnerr_list")[:-1]:
+                for line in _ts_list[exwe_index]:
+                    fp.write("{}\n".format(line))
+            fp.writelines(ex.get("lines"))
+            fp.write("\n")