[ONOS-5420] CP/untagged ifaces support in VPLS

Changes:
- Tests to account for tag-tag and tag-notag connectivity
- Introducing untagged ifaces in netcfg and topo files

Change-Id: If56fd4d8bbe4f1f2505e4d5d85c3eeda8c22ac5c
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java
index 66edd13..ab2b7f4 100644
--- a/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java
@@ -66,28 +66,38 @@
 
     private static final String IFACES_NOT_EXPECTED =
             "The interfaces reached by the packet are not equal to the " +
-                    "interfaces expected";
+                    "interfaces expected.";
 
     private static final DeviceId DID1 = getDeviceId(1);
     private static final DeviceId DID2 = getDeviceId(2);
     private static final DeviceId DID3 = getDeviceId(3);
     private static final DeviceId DID4 = getDeviceId(4);
+    private static final DeviceId DID5 = getDeviceId(5);
 
     private static final PortNumber P1 = PortNumber.portNumber(1);
     private static final PortNumber P2 = PortNumber.portNumber(2);
+    private static final PortNumber P3 = PortNumber.portNumber(3);
 
     private static final ConnectPoint OF1P1 = new ConnectPoint(DID1, P1);
     private static final ConnectPoint OF2P1 = new ConnectPoint(DID2, P1);
     private static final ConnectPoint OF3P1 = new ConnectPoint(DID3, P1);
     private static final ConnectPoint OF4P1 = new ConnectPoint(DID4, P1);
     private static final ConnectPoint OF4P2 = new ConnectPoint(DID4, P2);
+    private static final ConnectPoint OF4P3 = new ConnectPoint(DID4, P3);
+    private static final ConnectPoint OF5P1 = new ConnectPoint(DID5, P1);
+    private static final ConnectPoint OF5P2 = new ConnectPoint(DID5, P2);
+    private static final ConnectPoint OF5P3 = new ConnectPoint(DID5, P3);
 
     private static final String VPLS1 = "vpls1";
     private static final String VPLS2 = "vpls2";
+    private static final String VPLS3 = "vpls3";
+    private static final String VPLS4 = "vpls4";
 
     private static final VlanId VLAN100 = VlanId.vlanId("100");
     private static final VlanId VLAN200 = VlanId.vlanId("200");
     private static final VlanId VLAN300 = VlanId.vlanId("300");
+    private static final VlanId VLAN400 = VlanId.vlanId("400");
+    private static final VlanId VLAN_NONE = VlanId.NONE;
 
     private static final Interface V100H1 =
             new Interface("v100h1", OF1P1, null, null, VLAN100);
@@ -99,12 +109,24 @@
             new Interface("v200h2", OF2P1, null, null, VLAN200);
     private static final Interface V300H1 =
             new Interface("v300h1", OF3P1, null, null, VLAN300);
+    private static final Interface V400H1 =
+            new Interface("v400h1", OF5P1, null, null, VLAN400);
+    private static final Interface VNONEH1 =
+            new Interface("vNoneh1", OF5P2, null, null, VLAN_NONE);
+    private static final Interface VNONEH2 =
+            new Interface("vNoneh2", OF5P3, null, null, VLAN_NONE);
+    private static final Interface VNONEH3 =
+            new Interface("vNoneh3", OF4P3, null, null, VLAN_NONE);
 
     private static final MacAddress MAC1 = MacAddress.valueOf("00:00:00:00:00:01");
     private static final MacAddress MAC2 = MacAddress.valueOf("00:00:00:00:00:02");
     private static final MacAddress MAC3 = MacAddress.valueOf("00:00:00:00:00:03");
     private static final MacAddress MAC4 = MacAddress.valueOf("00:00:00:00:00:04");
     private static final MacAddress MAC5 = MacAddress.valueOf("00:00:00:00:00:05");
+    private static final MacAddress MAC6 = MacAddress.valueOf("00:00:00:00:00:06");
+    private static final MacAddress MAC7 = MacAddress.valueOf("00:00:00:00:00:07");
+    private static final MacAddress MAC8 = MacAddress.valueOf("00:00:00:00:00:08");
+    private static final MacAddress MAC9 = MacAddress.valueOf("00:00:00:00:00:09");
 
     private static final ProviderId PID = new ProviderId("of", "foo");
 
@@ -113,24 +135,35 @@
     private final Host v200Host1 = makeHost(MAC3, VLAN200, OF4P2);
     private final Host v200Host2 = makeHost(MAC5, VLAN200, OF2P1);
     private final Host v300Host1 = makeHost(MAC4, VLAN300, OF3P1);
+    private final Host v400Host1 = makeHost(MAC6, VLAN400, OF5P1);
+    private final Host vNoneHost1 = makeHost(MAC7, VLAN_NONE, OF5P2);
+    private final Host vNoneHost2 = makeHost(MAC8, VLAN_NONE, OF5P3);
+    private final Host vNoneHost3 = makeHost(MAC9, VLAN_NONE, OF4P3);
 
     private final Set<Host> availableHosts = ImmutableSet.of(v100Host1,
                                                              v100Host2,
                                                              v200Host1,
                                                              v300Host1,
-                                                             v200Host2);
+                                                             v200Host2,
+                                                             v400Host1,
+                                                             vNoneHost1,
+                                                             vNoneHost2,
+                                                             vNoneHost3);
 
     private final Set<Interface> availableInterfaces =
-            ImmutableSet.of(V100H1, V100H2, V200H1, V200H2, V300H1);
+            ImmutableSet.of(V100H1, V100H2, V200H1, V200H2, V300H1,
+                            V400H1, VNONEH1, VNONEH2, VNONEH3);
 
     private VplsNeighbourHandler vplsNeighbourHandler;
 
     private HostService hostService;
 
     /**
-     * Sets up 2 VPLS.
+     * Sets up 4 VPLS.
      * VPLS 1 contains 3 hosts: v100h1, v200h1 and v300h1
      * VPLS 2 contains 2 hosts: v100h2, v200h2
+     * VPLS 3 contains 2 hosts: vNoneh1, vNoneh2
+     * VPLS 4 contains 2 hosts: v400h1, vNoneh3
      */
     @Before
     public void setUp() {
@@ -142,6 +175,10 @@
         ifacesByVpls.put(VPLS1, V300H1);
         ifacesByVpls.put(VPLS2, V100H2);
         ifacesByVpls.put(VPLS2, V200H2);
+        ifacesByVpls.put(VPLS3, VNONEH1);
+        ifacesByVpls.put(VPLS3, VNONEH2);
+        ifacesByVpls.put(VPLS4, V400H1);
+        ifacesByVpls.put(VPLS4, VNONEH3);
         HashMap<String, EncapsulationType> encap = Maps.newHashMap();
         vplsNeighbourHandler.vplsConfigService =
                 new TestVplsConfigService(ifacesByVpls, encap);
@@ -149,13 +186,11 @@
                 new TestInterfaceService();
         vplsNeighbourHandler.neighbourService =
                 new TestNeighbourService();
-
         hostService = new TestHostService();
     }
 
     @After
     public void tearDown() {
-
     }
 
     /**
@@ -205,6 +240,50 @@
     }
 
     /**
+     * Tests correct connection between untagged interfaces.
+     *
+     * Sends request messages to all hosts in VPLS 3.
+     * Request messages should be received from other hosts in VPLS 3.
+     */
+    @Test
+    public void vpls3RequestMessage() {
+        // Request messages from vNoneHost1 (VPLS 3) should be received by vNoneHost2
+        TestMessageContext requestMessage =
+                makeBroadcastRequestContext(vNoneHost1);
+        Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH2);
+        vplsNeighbourHandler.handleRequest(requestMessage);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
+
+        // Request messages from vNoneh2 (VPLS 3) should be received by vNoneh1
+        requestMessage = makeBroadcastRequestContext(vNoneHost2);
+        expectInterfaces = ImmutableSet.of(VNONEH1);
+        vplsNeighbourHandler.handleRequest(requestMessage);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
+    }
+
+    /**
+     * Tests correct connection between tagged and untagged interfaces.
+     *
+     * Sends request messages to all hosts in VPLS 4.
+     * Request messages should be received from other hosts in VPLS 4.
+     */
+    @Test
+    public void vpls4RequestMessage() {
+        // Request messages from v400Host1 (VPLS 4) should be received by vNoneHost3
+        TestMessageContext requestMessage =
+                makeBroadcastRequestContext(v400Host1);
+        Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH3);
+        vplsNeighbourHandler.handleRequest(requestMessage);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
+
+        // Request messages from vNoneHost3 (VPLS 4) should be received by v400Host1
+        requestMessage = makeBroadcastRequestContext(vNoneHost3);
+        expectInterfaces = ImmutableSet.of(V400H1);
+        vplsNeighbourHandler.handleRequest(requestMessage);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
+    }
+
+    /**
      * Sends reply messages to hosts in VPLS 1.
      * Reply messages should be received by the host with MAC address equal to
      * the dstMac of the message context.
@@ -253,6 +332,48 @@
     }
 
     /**
+     * Sends reply messages to hosts in VPLS 3.
+     * Reply messages should be received by the host with MAC address equal to
+     * the dstMac of the message context.
+     */
+    @Test
+    public void vpls3ReplyMessage() {
+        // Reply messages from vNoneh1 (VPLS 3) should be received by vNoneh2
+        TestMessageContext replyMessage =
+                makeReplyContext(vNoneHost1, vNoneHost2);
+        Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH2);
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
+
+        // Reply messages from vNoneh2 (VPLS 3) should be received by vNoneh1
+        replyMessage = makeReplyContext(vNoneHost2, vNoneHost1);
+        expectInterfaces = ImmutableSet.of(VNONEH1);
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
+    }
+
+    /**
+     * Sends reply messages to hosts in VPLS 4.
+     * Reply messages should be received by the host with MAC address equal to
+     * the dstMac of the message context.
+     */
+    @Test
+    public void vpls4ReplyMessage() {
+        // Reply messages from v400h1 (VPLS 4) should be received by vNoneh3
+        TestMessageContext replyMessage =
+                makeReplyContext(v400Host1, vNoneHost3);
+        Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH3);
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
+
+        // Reply messages from vNoneh3 (VPLS 4) should be received by v400h1
+        replyMessage = makeReplyContext(vNoneHost3, v400Host1);
+        expectInterfaces = ImmutableSet.of(V400H1);
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
+    }
+
+    /**
      * Sends wrong reply messages to hosts.
      * The source and the destination MAC addresses are not set on any host of the VPLS.
      * The reply messages will not be received by any hosts.
@@ -272,6 +393,20 @@
         expectInterfaces = ImmutableSet.of();
         vplsNeighbourHandler.handleReply(replyMessage, hostService);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
+
+        // Reply message from vNoneh1 (VPLS 3) to v400h1 (VPLS 4).
+        // Forward results should be empty
+        replyMessage = makeReplyContext(vNoneHost1, v400Host1);
+        expectInterfaces = ImmutableSet.of();
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
+
+        // Reply message from vNoneh3 (VPLS 4) to vNoneH2 (VPLS 3).
+        // Forward results should be empty
+        replyMessage = makeReplyContext(vNoneHost3, vNoneHost2);
+        expectInterfaces = ImmutableSet.of();
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
     }
 
     /**
@@ -343,7 +478,6 @@
             this.type = type;
 
             this.forwardResults = Sets.newHashSet();
-
         }
 
         @Override
@@ -383,7 +517,6 @@
 
         @Override
         public void forward(ConnectPoint outPort) {
-
         }
 
         @Override
@@ -393,17 +526,14 @@
 
         @Override
         public void reply(MacAddress targetMac) {
-
         }
 
         @Override
         public void flood() {
-
         }
 
         @Override
         public void drop() {
-
         }
 
         @Override
@@ -417,7 +547,7 @@
         }
     }
 
-    private class TestVplsConfigService extends VplsConfigurationServiceAdapter {
+    private class TestVplsConfigService extends VplsConfigServiceAdapter {
 
         private final SetMultimap<String, Interface> ifacesByVplsName;
 
@@ -463,7 +593,6 @@
                     toBeRemoved.put(e.getKey(), e.getValue());
                 }
             });
-
             toBeRemoved.entries()
                     .forEach(e -> ifacesByVplsName.remove(e.getKey(),
                                                           e.getValue()));
@@ -503,7 +632,7 @@
                     ifacesByVplsName.entries().stream()
                             .filter(e -> e.getValue().connectPoint().equals(connectPoint))
                             .filter(e -> e.getValue().vlan().equals(vlan))
-                            .map(e -> e.getKey())
+                            .map(Map.Entry::getKey)
                             .findFirst()
                             .orElse(null);
             SetMultimap<String, Interface> result = HashMultimap.create();
@@ -637,7 +766,6 @@
             public ApplicationId appId() {
                 return appId;
             }
-
         }
     }
 
@@ -645,12 +773,10 @@
 
         @Override
         public void addListener(InterfaceListener listener) {
-
         }
 
         @Override
         public void removeListener(InterfaceListener listener) {
-
         }
 
         @Override
@@ -665,7 +791,6 @@
                     .filter(intf -> intf.name().equals(name))
                     .findFirst()
                     .orElse(null);
-
         }
 
         @Override