Fix unit tests and code to support schema-enforcement by yangtools.
[groupbasedpolicy.git] / groupbasedpolicy / src / test / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / flow / PortSecurityTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
10
11 import java.util.Collections;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Objects;
15 import java.util.Set;
16
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.mockito.ArgumentCaptor;
20 import org.mockito.Matchers;
21 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 import com.google.common.collect.ImmutableList;
42 import com.google.common.collect.ImmutableSet;
43
44 import static org.junit.Assert.*;
45
46 import static org.mockito.Matchers.*;
47
48 import static org.mockito.Mockito.*;
49
50 public class PortSecurityTest extends FlowTableTest {
51     protected static final Logger LOG = 
52             LoggerFactory.getLogger(PortSecurityTest.class);
53     
54     @Before
55     public void setup() throws Exception {
56         initCtx();
57         table = new PortSecurity(ctx);
58         super.setup();
59     }
60
61     @Test
62     public void testDefaultDeny() throws Exception {
63         ReadWriteTransaction t = dosync(null);
64         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
65         verify(t, times(4)).put(eq(LogicalDatastoreType.CONFIGURATION), 
66                                 Matchers.<InstanceIdentifier<Flow>>any(), 
67                                 ac.capture(), anyBoolean());
68         int count = 0;
69         
70         HashMap<String, FlowCtx> flowMap = new HashMap<>();
71         for (Flow f : ac.getAllValues()) {
72             flowMap.put(f.getId().getValue(), new FlowCtx(f));
73             Long etherType = null;
74             if (f.getMatch() != null) {
75                 etherType = f.getMatch().getEthernetMatch()
76                         .getEthernetType().getType().getValue();
77             }
78             if (f.getMatch() == null ||
79                 FlowUtils.ARP.equals(etherType) ||
80                 FlowUtils.IPv4.equals(etherType) ||
81                 FlowUtils.IPv6.equals(etherType)) {
82                 count += 1;
83                 assertEquals(FlowUtils.dropInstructions(),
84                              f.getInstructions());
85             }
86         }
87         assertEquals(4, count);
88         t = dosync(flowMap);
89         verify(t, never()).put(any(LogicalDatastoreType.class), 
90                                Matchers.<InstanceIdentifier<Flow>>any(), 
91                                any(Flow.class), anyBoolean());
92     }
93
94     @Test
95     public void testNonLocalAllow() throws Exception {
96         switchManager
97             .addSwitch(new NodeId("openflow:1"), 
98                        new NodeConnectorId("openflow:1:1"), 
99                        ImmutableSet.of(new NodeConnectorId("openflow:1:2")),
100                        null);
101
102         ReadWriteTransaction t = dosync(null);
103         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
104         verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION), 
105                                      Matchers.<InstanceIdentifier<Flow>>any(),
106                                      ac.capture(), anyBoolean());
107         
108         int count = 0;
109         HashMap<String, FlowCtx> flowMap = new HashMap<>();
110         Set<String> ncs = ImmutableSet.of("openflow:1:1", "openflow:1:2");
111         for (Flow f : ac.getAllValues()) {
112             flowMap.put(f.getId().getValue(), new FlowCtx(f));
113             if (f.getMatch() != null && f.getMatch().getInPort() != null &&
114                 ncs.contains(f.getMatch().getInPort().getValue())) {
115                 assertEquals(f.getInstructions(), 
116                              FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)));
117                 count += 1;
118             }
119         }
120         assertEquals(2, count);
121
122         t = dosync(flowMap);
123         verify(t, never()).put(any(LogicalDatastoreType.class), 
124                                Matchers.<InstanceIdentifier<Flow>>any(), 
125                                any(Flow.class), anyBoolean());
126     }
127     
128     @Test
129     public void testL2() throws Exception {
130         List<L3Address> l3 = Collections.emptyList();
131         Endpoint ep = localEP()
132             .setL3Address(l3)
133             .build();
134        
135         endpointManager.addEndpoint(ep);
136         
137         ReadWriteTransaction t = dosync(null);
138         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
139         verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION), 
140                                      Matchers.<InstanceIdentifier<Flow>>any(),
141                                      ac.capture(), anyBoolean());
142
143         int count = 0;
144         HashMap<String, FlowCtx> flowMap = new HashMap<>();
145         for (Flow f : ac.getAllValues()) {
146             flowMap.put(f.getId().getValue(), new FlowCtx(f));
147             if (f.getMatch() != null &&
148                 f.getMatch().getEthernetMatch() != null &&
149                 f.getMatch().getEthernetMatch().getEthernetSource() != null &&
150                 Objects.equals(ep.getMacAddress(), 
151                                f.getMatch().getEthernetMatch()
152                                    .getEthernetSource().getAddress()) &&
153                 Objects.equals(ep.getAugmentation(OfOverlayContext.class).getNodeConnectorId(), 
154                                f.getMatch().getInPort())) {
155                 count += 1;
156                 assertEquals(FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)),
157                              f.getInstructions());
158             }
159         }
160         assertEquals(1, count);
161         t = dosync(flowMap);
162         verify(t, never()).put(any(LogicalDatastoreType.class), 
163                                Matchers.<InstanceIdentifier<Flow>>any(), 
164                                any(Flow.class), anyBoolean());
165     }
166     
167     @Test
168     public void testL3() throws Exception {
169         Endpoint ep = localEP()
170             .setL3Address(ImmutableList.of(new L3AddressBuilder()
171                 .setIpAddress(new IpAddress(new Ipv4Address("10.10.10.10")))
172                 .build(),
173                 new L3AddressBuilder()
174                 .setIpAddress(new IpAddress(new Ipv6Address("2001:db8:85a3::8a2e:370:7334")))
175                 .build()))
176             .build();
177         
178         endpointManager.addEndpoint(ep);
179         
180         ReadWriteTransaction t = dosync(null);
181         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
182         verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION), 
183                                      Matchers.<InstanceIdentifier<Flow>>any(),
184                                      ac.capture(), anyBoolean());
185         
186         int count = 0;
187         HashMap<String, FlowCtx> flowMap = new HashMap<>();
188         for (Flow f : ac.getAllValues()) {
189             flowMap.put(f.getId().getValue(), new FlowCtx(f));
190             if (f.getMatch() != null &&
191                 Objects.equals(ep.getAugmentation(OfOverlayContext.class).getNodeConnectorId(), 
192                                f.getMatch().getInPort()) &&
193                 ((f.getMatch().getLayer3Match() != null &&
194                   f.getMatch().getLayer3Match() instanceof Ipv4Match &&
195                   Objects.equals(ep.getL3Address().get(0).getIpAddress().getIpv4Address().getValue(),
196                                  ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Source().getValue().split("/")[0])) ||
197                  (f.getMatch().getLayer3Match() != null &&
198                   f.getMatch().getLayer3Match() instanceof ArpMatch &&
199                   Objects.equals(ep.getL3Address().get(0).getIpAddress().getIpv4Address().getValue(),
200                                  ((ArpMatch)f.getMatch().getLayer3Match()).getArpSourceTransportAddress().getValue().split("/")[0])) ||
201                  (f.getMatch().getLayer3Match() != null &&
202                   f.getMatch().getLayer3Match() instanceof Ipv6Match &&
203                   Objects.equals(ep.getL3Address().get(1).getIpAddress().getIpv6Address().getValue(),
204                                  ((Ipv6Match)f.getMatch().getLayer3Match()).getIpv6Source().getValue().split("/")[0])))) {
205                 count += 1;
206                 assertEquals(FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)),
207                              f.getInstructions());
208             }
209         }
210         assertEquals(3, count);
211         t = dosync(flowMap);
212         verify(t, never()).put(any(LogicalDatastoreType.class), 
213                                Matchers.<InstanceIdentifier<Flow>>any(), 
214                                any(Flow.class), anyBoolean());
215     }
216 }