Bug: 7483 Implement IPv6 component tests in ACLService
[netvirt.git] / vpnservice / aclservice / impl / src / test / java / org / opendaylight / netvirt / aclservice / tests / AclServiceTestBase.java
1 /*
2  * Copyright © 2016, 2017 Red Hat, 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 package org.opendaylight.netvirt.aclservice.tests;
9
10 import static com.google.common.truth.Truth.assertThat;
11 import static org.junit.Assert.assertTrue;
12 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
13 import static org.opendaylight.mdsal.binding.testutils.AssertDataObjects.assertEqualBeans;
14 import static org.opendaylight.netvirt.aclservice.tests.StateInterfaceBuilderHelper.putNewStateInterface;
15
16 import com.google.common.collect.Iterables;
17 import com.google.common.collect.Lists;
18 import java.util.Arrays;
19 import java.util.Collections;
20 import java.util.List;
21 import java.util.stream.Collectors;
22 import javax.inject.Inject;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
26 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
27 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
28 import org.opendaylight.genius.datastoreutils.testutils.AsyncEventsWaiter;
29 import org.opendaylight.genius.mdsalutil.FlowEntity;
30 import org.opendaylight.genius.mdsalutil.NwConstants;
31 import org.opendaylight.genius.mdsalutil.interfaces.testutils.TestIMdsalApiManager;
32 import org.opendaylight.netvirt.aclservice.tests.infra.DataBrokerPairsUtil;
33 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
34 import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Matches;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.MatchesBuilder;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.DestinationPortRangeBuilder;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairsBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
54 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58
59 public abstract class AclServiceTestBase {
60
61     private static final Logger LOG = LoggerFactory.getLogger(AclServiceTestBase.class);
62
63     static final String PORT_MAC_1 = "0D:AA:D8:42:30:F3";
64     static final String PORT_MAC_2 = "0D:AA:D8:42:30:F4";
65     static final String PORT_MAC_3 = "0D:AA:D8:42:30:F5";
66     static final String PORT_1 = "port1";
67     static final String PORT_2 = "port2";
68     static final String PORT_3 = "port3";
69     static String SG_UUID  = "85cc3048-abc3-43cc-89b3-377341426ac5";
70     static String SR_UUID_1 = "85cc3048-abc3-43cc-89b3-377341426ac6";
71     static String SR_UUID_2 = "85cc3048-abc3-43cc-89b3-377341426ac7";
72     static String SG_UUID_1  = "85cc3048-abc3-43cc-89b3-377341426ac5";
73     static String SG_UUID_2  = "85cc3048-abc3-43cc-89b3-377341426ac8";
74     static String SR_UUID_1_1 = "85cc3048-abc3-43cc-89b3-377341426ac6";
75     static String SR_UUID_1_2 = "85cc3048-abc3-43cc-89b3-377341426ac7";
76     static String SR_UUID_2_1 = "85cc3048-abc3-43cc-89b3-377341426a21";
77     static String SR_UUID_2_2 = "85cc3048-abc3-43cc-89b3-377341426a22";
78     static String ELAN = "elan1";
79     static String IP_PREFIX_1 = "10.0.0.1/32";
80     static String IP_PREFIX_2 = "10.0.0.2/32";
81     static String IP_PREFIX_3 = "10.0.0.3/32";
82     static long ELAN_TAG = 5000L;
83
84     protected static final Integer FLOW_PRIORITY_SG_1 = 1001;
85     protected static final Integer FLOW_PRIORITY_SG_2 = 1002;
86
87     @Inject DataBroker dataBroker;
88     @Inject DataBrokerPairsUtil dataBrokerUtil;
89     SingleTransactionDataBroker singleTransactionDataBroker;
90     @Inject TestIMdsalApiManager mdsalApiManager;
91     @Inject AsyncEventsWaiter asyncEventsWaiter;
92
93     @Before
94     public void beforeEachTest() throws Exception {
95         singleTransactionDataBroker = new SingleTransactionDataBroker(dataBroker);
96         setUpData();
97     }
98
99     @Test
100     public void newInterface() throws Exception {
101         // Given
102         // putNewInterface(dataBroker, "port1", true, Collections.emptyList(), Collections.emptyList());
103         dataBrokerUtil.put(ImmutableIdentifiedInterfaceWithAclBuilder.builder()
104                 .interfaceName("port1")
105                 .portSecurity(true).build());
106
107         // When
108         putNewStateInterface(dataBroker, "port1", PORT_MAC_1);
109
110         asyncEventsWaiter.awaitEventsConsumption();
111
112         // Then
113         newInterfaceCheck();
114     }
115
116     abstract void newInterfaceCheck();
117
118     @Test
119     public void newInterfaceWithEtherTypeAcl() throws Exception {
120         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
121             AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_UNSPECIFIED,
122             AclConstants.DEST_UPPER_PORT_UNSPECIFIED, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
123             AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short)-1);
124         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
125             .sgUuid(SG_UUID_1)
126             .newRuleName(SR_UUID_1_1)
127             .newMatches(matches)
128             .newDirection(DirectionEgress.class)
129             .build());
130
131         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
132             AclConstants.DEST_LOWER_PORT_UNSPECIFIED, AclConstants.DEST_UPPER_PORT_UNSPECIFIED,
133             AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED, (short)-1);
134         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
135             .sgUuid(SG_UUID_1)
136             .newRuleName(SR_UUID_1_2)
137             .newMatches(matches)
138             .newDirection(DirectionIngress.class)
139             .newRemoteGroupId(new Uuid(SG_UUID_1)).build());
140
141         // When
142         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
143         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
144
145         asyncEventsWaiter.awaitEventsConsumption();
146
147         // Then
148         newInterfaceWithEtherTypeAclCheck();
149     }
150
151     abstract void newInterfaceWithEtherTypeAclCheck();
152
153     @Test
154     public void newInterfaceWithTcpDstAcl() throws Exception {
155         // Given
156         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
157             AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_HTTP,
158             AclConstants.DEST_UPPER_PORT_HTTP, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
159             AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short)NwConstants.IP_PROT_TCP);
160         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
161             .sgUuid(SG_UUID_1)
162             .newRuleName(SR_UUID_1_1)
163             .newMatches(matches)
164             .newDirection(DirectionEgress.class)
165             .newRemoteGroupId(new Uuid(SG_UUID_1)).build());
166         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
167             AclConstants.DEST_LOWER_PORT_HTTP, AclConstants.DEST_UPPER_PORT_HTTP,
168             AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
169             (short)NwConstants.IP_PROT_TCP);
170
171         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
172             .sgUuid(SG_UUID_1)
173             .newRuleName(SR_UUID_1_2)
174             .newMatches(matches)
175             .newDirection(DirectionIngress.class)
176             .build());
177
178         // When
179         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
180         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
181
182         asyncEventsWaiter.awaitEventsConsumption();
183
184         // Then
185         newInterfaceWithTcpDstAclCheck();
186     }
187
188     abstract void newInterfaceWithTcpDstAclCheck();
189
190     @Test
191     public void newInterfaceWithUdpDstAcl() throws Exception {
192         // Given
193         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
194             AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_HTTP,
195             AclConstants.DEST_UPPER_PORT_HTTP, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
196             AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short)NwConstants.IP_PROT_UDP);
197         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
198             .sgUuid(SG_UUID_1)
199             .newRuleName(SR_UUID_1_1)
200             .newMatches(matches)
201             .newDirection(DirectionEgress.class)
202             .build());
203
204         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
205             AclConstants.DEST_LOWER_PORT_HTTP, AclConstants.DEST_UPPER_PORT_HTTP,
206             AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
207             (short)NwConstants.IP_PROT_UDP);
208         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
209             .sgUuid(SG_UUID_1)
210             .newRuleName(SR_UUID_1_2)
211             .newMatches(matches)
212             .newDirection(DirectionIngress.class)
213             .newRemoteGroupId(new Uuid(SG_UUID_1)).build());
214
215         // When
216         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
217         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
218
219         asyncEventsWaiter.awaitEventsConsumption();
220
221         // Then
222         newInterfaceWithUdpDstAclCheck();
223     }
224
225     abstract void newInterfaceWithUdpDstAclCheck();
226
227     @Test
228     public void newInterfaceWithIcmpAcl() throws Exception {
229         // Given
230         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
231             AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_2, AclConstants.DEST_UPPER_PORT_3,
232             AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED,
233             (short)NwConstants.IP_PROT_ICMP);
234         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
235             .sgUuid(SG_UUID_1)
236             .newRuleName(SR_UUID_1_1)
237             .newMatches(matches)
238             .newDirection(DirectionEgress.class)
239             .newRemoteGroupId(new Uuid(SG_UUID_1)).build());
240
241         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
242             AclConstants.DEST_LOWER_PORT_2, AclConstants.DEST_UPPER_PORT_3,
243             AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
244             (short)NwConstants.IP_PROT_ICMP);
245         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
246             .sgUuid(SG_UUID_1)
247             .newRuleName(SR_UUID_1_2)
248             .newMatches(matches)
249             .newDirection(DirectionIngress.class)
250             .build());
251
252         // When
253         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
254         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
255
256         asyncEventsWaiter.awaitEventsConsumption();
257
258         // Then
259         newInterfaceWithIcmpAclCheck();
260     }
261
262     abstract void newInterfaceWithIcmpAclCheck();
263
264     @Test
265     public void newInterfaceWithDstPortRange() throws Exception {
266         // Given
267         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
268             AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 333, 777,
269             AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED,
270             (short)NwConstants.IP_PROT_TCP);
271         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
272             .sgUuid(SG_UUID_1)
273             .newRuleName(SR_UUID_1_1)
274             .newMatches(matches)
275             .newDirection(DirectionEgress.class)
276             .build());
277         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
278             2000, 2003, AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED,
279             AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED, (short)NwConstants.IP_PROT_UDP);
280
281         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
282             .sgUuid(SG_UUID_1)
283             .newRuleName(SR_UUID_1_2)
284             .newMatches(matches)
285             .newDirection(DirectionIngress.class)
286             .build());
287
288         // When
289         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
290
291         asyncEventsWaiter.awaitEventsConsumption();
292
293         // Then
294         newInterfaceWithDstPortRangeCheck();
295     }
296
297     abstract void newInterfaceWithDstPortRangeCheck();
298
299     @Test
300     public void newInterfaceWithDstAllPorts() throws Exception {
301         // Given
302         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
303             AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 1, 65535,
304             AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED,
305             (short)NwConstants.IP_PROT_TCP);
306         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
307             .sgUuid(SG_UUID_1)
308             .newRuleName(SR_UUID_1_1)
309             .newMatches(matches)
310             .newDirection(DirectionEgress.class)
311             .build());
312         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
313             1, 65535, AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED,
314             AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED, (short)NwConstants.IP_PROT_UDP);
315
316         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder()
317             .sgUuid(SG_UUID_1)
318             .newRuleName(SR_UUID_1_2)
319             .newMatches(matches)
320             .newDirection(DirectionIngress.class)
321             .build());
322
323         // When
324         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
325
326         asyncEventsWaiter.awaitEventsConsumption();
327
328         // Then
329         newInterfaceWithDstAllPortsCheck();
330     }
331
332     abstract void newInterfaceWithDstAllPortsCheck();
333
334     @Test
335     public void newInterfaceWithTwoAclsHavingSameRules() throws Exception {
336         // Given
337         Matches icmpEgressMatches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
338             AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_2, AclConstants.DEST_UPPER_PORT_3,
339             AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED,
340             (short) NwConstants.IP_PROT_ICMP);
341         Matches icmpIngressMatches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
342             AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_2, AclConstants.DEST_UPPER_PORT_3,
343             AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
344             (short) NwConstants.IP_PROT_ICMP);
345
346         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
347                 .newMatches(icmpEgressMatches).newDirection(DirectionEgress.class).build());
348
349         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2)
350                 .newMatches(icmpIngressMatches).newDirection(DirectionIngress.class).build());
351
352         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_2).newRuleName(SR_UUID_2_1)
353                 .newMatches(icmpEgressMatches).newDirection(DirectionEgress.class).build());
354
355         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_2).newRuleName(SR_UUID_2_2)
356                 .newMatches(icmpIngressMatches).newDirection(DirectionIngress.class).build());
357
358         // When
359         putNewStateInterface(dataBroker, PORT_3, PORT_MAC_3);
360
361         asyncEventsWaiter.awaitEventsConsumption();
362
363         // Then
364         newInterfaceWithTwoAclsHavingSameRulesCheck();
365     }
366
367     abstract void newInterfaceWithTwoAclsHavingSameRulesCheck();
368
369     // TODO Remove this from here, use the one about to be merged in TestIMdsalApiManager
370     // under https://git.opendaylight.org/gerrit/#/c/47842/ *BUT* remember to integrate
371     // the ignore ordering fix recently added here to there...
372     protected void assertFlowsInAnyOrder(Iterable<FlowEntity> expectedFlows) {
373         List<FlowEntity> flows = mdsalApiManager.getFlows();
374         if (!Iterables.isEmpty(expectedFlows)) {
375             assertTrue("No Flows created (bean wiring may be broken?)", !flows.isEmpty());
376         }
377
378         // TODO Support Iterable <-> List directly within XtendBeanGenerator
379         List<FlowEntity> expectedFlowsAsNewArrayList = Lists.newArrayList(expectedFlows);
380
381         // FYI: This containsExactlyElementsIn() assumes that FlowEntity, and everything in it,
382         // has correctly working equals() implementations.  assertEqualBeans() does not assume
383         // that, and would work even without equals, because it only uses property reflection.
384         // Normally this will lead to the same result, but if one day it doesn't (because of
385         // a bug in an equals() implementation somewhere), then it's worth to keep this diff
386         // in mind.
387
388         // FTR: This use of G Truth and then catch AssertionError and using assertEqualBeans iff NOK
389         // (thus discarding the message from G Truth) is a bit of a hack, but it works well...
390         // If you're tempted to improve this, please remember that correctly re-implementing
391         // containsExactlyElementsIn (or Hamcrest's similar containsInAnyOrder) isn't a 1 line
392         // trivia... e.g. a.containsAll(b) && b.containsAll(a) isn't sufficient, because it
393         // won't work for duplicates (which we frequently have here); and ordering before is
394         // not viable because FlowEntity is not Comparable, and Comparator based on hashCode
395         // is not a good idea (different instances can have same hashCode), and e.g. on
396         // System#identityHashCode even less so.
397         try {
398             LOG.info("expectedFlows = {}", expectedFlowsAsNewArrayList);
399             LOG.info("flows = {}",flows);
400             assertThat(flows).containsExactlyElementsIn(expectedFlowsAsNewArrayList);
401         } catch (AssertionError e) {
402             // The point of this is basically just that our assertEqualBeans output,
403             // in case of a comparison failure, is *A LOT* more clearly readable
404             // than what G Truth (or Hamcrest) can do based on toString.
405             assertEqualBeans(expectedFlowsAsNewArrayList, flows);
406         }
407     }
408
409     protected void newAllowedAddressPair(String portName, List<String> sgUuidList, String ipAddress, String macAddress )
410             throws TransactionCommitFailedException {
411         AllowedAddressPairs allowedAddressPair = new AllowedAddressPairsBuilder()
412                 .setIpAddress(new IpPrefixOrAddress(new IpPrefix(ipAddress.toCharArray())))
413                 .setMacAddress(new MacAddress(macAddress))
414                 .build();
415         List<Uuid> sgList = sgUuidList.stream().map(Uuid::new).collect(Collectors.toList());
416
417         dataBrokerUtil.put(ImmutableIdentifiedInterfaceWithAclBuilder.builder()
418             .interfaceName(portName)
419             .portSecurity(true)
420             .addAllNewSecurityGroups(sgList)
421             .addIfAllowedAddressPair(allowedAddressPair).build());
422     }
423
424     protected void newElan(String elanName, long elanId) throws TransactionCommitFailedException {
425         ElanInstance elan = new ElanInstanceBuilder().setElanInstanceName(elanName).setElanTag(5000L).build();
426         singleTransactionDataBroker.syncWrite(CONFIGURATION,
427                 AclServiceUtils.getElanInstanceConfigurationDataPath(elanName),
428                 elan);
429     }
430
431     protected void newElanInterface(String elanName, String portName, boolean isWrite)
432             throws TransactionCommitFailedException {
433         ElanInterface elanInterface = new ElanInterfaceBuilder().setName(portName)
434                 .setElanInstanceName(elanName).build();
435         InstanceIdentifier<ElanInterface> id = AclServiceUtils.getElanInterfaceConfigurationDataPathId(portName);
436         if (isWrite) {
437             singleTransactionDataBroker.syncWrite(CONFIGURATION, id, elanInterface);
438         } else {
439             singleTransactionDataBroker.syncDelete(CONFIGURATION, id);
440         }
441     }
442
443     // TODO refactor this instead of stealing it from org.opendaylight.netvirt.neutronvpn.NeutronSecurityRuleListener
444     protected Matches newMatch(int srcLowerPort, int srcUpperPort, int destLowerPort, int destupperPort,
445             int srcRemoteIpPrefix, int dstRemoteIpPrefix, short protocol) {
446
447         AceIpBuilder aceIpBuilder = new AceIpBuilder();
448         if (destLowerPort != -1) {
449             DestinationPortRangeBuilder destinationPortRangeBuilder = new DestinationPortRangeBuilder();
450             destinationPortRangeBuilder.setLowerPort(new PortNumber(destLowerPort));
451             destinationPortRangeBuilder.setUpperPort(new PortNumber(destupperPort));
452             aceIpBuilder.setDestinationPortRange(destinationPortRangeBuilder.build());
453         }
454         AceIpv4Builder aceIpv4Builder = new AceIpv4Builder();
455         if (srcRemoteIpPrefix == AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED) {
456             aceIpv4Builder.setSourceIpv4Network(new Ipv4Prefix(AclConstants.IPV4_ALL_NETWORK));
457         }
458         if (dstRemoteIpPrefix == AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED) {
459             aceIpv4Builder.setSourceIpv4Network(new Ipv4Prefix(AclConstants.IPV4_ALL_NETWORK));
460         }
461         if (protocol != -1) {
462             aceIpBuilder.setProtocol(protocol);
463         }
464         aceIpBuilder.setAceIpVersion(aceIpv4Builder.build());
465
466         MatchesBuilder matchesBuilder = new MatchesBuilder();
467         matchesBuilder.setAceType(aceIpBuilder.build());
468         return matchesBuilder.build();
469     }
470
471     protected void setUpData() throws Exception {
472         newElan(ELAN, ELAN_TAG);
473         newElanInterface(ELAN, PORT_1 ,true);
474         newElanInterface(ELAN, PORT_2, true);
475         newElanInterface(ELAN, PORT_3, true);
476         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), IP_PREFIX_1, PORT_MAC_1);
477         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), IP_PREFIX_2, PORT_MAC_2);
478         newAllowedAddressPair(PORT_3, Arrays.asList(SG_UUID_1, SG_UUID_2), IP_PREFIX_3, PORT_MAC_3);
479     }
480
481 }