OF-overlay PolicyEnforcer tests, refactoring
[groupbasedpolicy.git] / renderers / ofoverlay / src / test / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / mapper / policyenforcer / PolicyEnforcerTest.java
1 /*
2  * Copyright (c) 2015 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.mapper.policyenforcer;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotEquals;
13 import static org.junit.Assert.assertTrue;
14 import static org.mockito.Mockito.when;
15 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
16 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
17 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Objects;
24
25 import com.google.common.collect.ImmutableList;
26 import com.google.common.collect.ImmutableMap;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
31 import org.opendaylight.groupbasedpolicy.dto.ConditionGroup;
32 import org.opendaylight.groupbasedpolicy.dto.EgKey;
33 import org.opendaylight.groupbasedpolicy.dto.PolicyInfo;
34 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockOfContext;
35 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockPolicyManager;
36 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
37 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;
38 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.MockEndpointManager;
39 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
40 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
41 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory;
42 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest;
43 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.MockSwitchManager;
44 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;
45 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ChainAction;
46 import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
47 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
48 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfpName;
49 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
50 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPathsBuilder;
51 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
52 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionMatcherName;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.TunnelBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRefBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcherBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.ConditionBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ContractBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.SubjectBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchersBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.RuleBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstanceBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg0Key;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg2Key;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
106 import org.powermock.api.mockito.PowerMockito;
107 import org.powermock.core.classloader.annotations.PrepareForTest;
108 import org.powermock.modules.junit4.PowerMockRunner;
109
110 @RunWith(PowerMockRunner.class)
111 @PrepareForTest({PolicyManager.class, SfcProviderServicePathAPI.class})
112 public class PolicyEnforcerTest extends MapperUtilsTest {
113
114     private static final String SFC_CHAIN = "sfc-chain";
115     private static final String TCP_DST = "tcp_dst_80";
116     private static final int sameEpgFlows = 1;
117     private static final int allowTunnelFlows = 1;
118     private static final int layer4flowsIPv4 = 1;
119     private static final int layer4flowsIPv6 = 1;
120
121     private NodeConnectorId tunnelId = new NodeConnectorId(NODE_ID.getValue() + ":42");
122     private NodeConnectorId nodeConnector = new NodeConnectorId(NODE_ID.getValue() + CONNECTOR_0);
123
124     // custom mock instances to avoid downcasting of parent's fields
125     private MockEndpointManager endpointManagerMock;
126     private MockPolicyManager policyManagerMock;
127     private MockSwitchManager switchManagerMock;
128     private MockOfContext ctxMock;
129
130     private ActionInstance allowActionInstance;
131     private ActionInstance chainActionInstance;
132
133     @Before
134     public void init() {
135         PowerMockito.stub(PowerMockito.method(PolicyManager.class, "setSfcTableOffset")).toReturn(true);
136
137         endpointManagerMock = new MockEndpointManager();
138         policyManagerMock = new MockPolicyManager(endpointManagerMock);
139         switchManagerMock = new MockSwitchManager();
140         ctxMock = new MockOfContext(null, policyManagerMock, switchManagerMock, endpointManagerMock, null);
141         table = new PolicyEnforcer(ctxMock, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER());
142
143         ServiceFunctionPath path = new ServiceFunctionPathBuilder().setName(new SfpName("sfp-name"))
144             .setServiceChainName(new SfcName(SFC_CHAIN))
145             .setSymmetric(true)
146             .build();
147         ServiceFunctionPaths paths =
148                 new ServiceFunctionPathsBuilder().setServiceFunctionPath(ImmutableList.of(path)).build();
149
150         PowerMockito.mockStatic(SfcProviderServicePathAPI.class);
151         when(SfcProviderServicePathAPI.readAllServiceFunctionPaths()).thenReturn(paths);
152
153         allowActionInstance = new ActionInstanceBuilder().setName(new ActionName("allow"))
154             .setActionDefinitionId(new AllowAction().getId())
155             .build();
156
157         ParameterValue pv = new ParameterValueBuilder().setName(new ParameterName(ChainActionDefinition.SFC_CHAIN_NAME))
158             .setStringValue(SFC_CHAIN)
159             .build();
160         chainActionInstance = new ActionInstanceBuilder().setName(new ActionName("chain"))
161             .setActionDefinitionId(new ChainAction().getId())
162             .setParameterValue(ImmutableList.of(pv))
163             .build();
164
165         switchManagerMock
166             .addSwitch(NODE_ID, tunnelId,
167                     Collections
168                         .emptySet(),
169                     new OfOverlayNodeConfigBuilder()
170                         .setTunnel(ImmutableList.of(new TunnelBuilder().setIp(new IpAddress(new Ipv4Address("1.2.3.4")))
171                             .setTunnelType(TunnelTypeVxlan.class)
172                             .setNodeConnectorId(tunnelId)
173                             .build()))
174                         .build());
175     }
176
177     @Test
178     public void test_SameEg() throws Exception {
179         EndpointBuilder ep1Builder = buildEndpoint(IPV4_0, MAC_0, nodeConnector);
180         ep1Builder.setEndpointGroup(ENDPOINT_GROUP_0);
181         ep1Builder.setL2Context(L2BD_ID);
182         Endpoint ep1 = ep1Builder.build();
183         endpointManagerMock.addEndpoint(ep1);
184         EndpointBuilder ep2Builder = buildEndpoint(IPV4_1, MAC_1, nodeConnector);
185         ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1);
186         ep2Builder.setL2Context(L2BD_ID);
187         Endpoint ep2 = ep2Builder.build();
188         endpointManagerMock.addEndpoint(ep2);
189         ctxMock.addTenant(buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy())
190             .setContract(ImmutableList.of(baseContract(null).build())).build()).build());
191
192         ofWriter = new OfWriter();
193         table.sync(ep1, ofWriter);
194
195         assertTrue(!ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
196             .getFlow()
197             .isEmpty());
198
199         int count = 0;
200         for (Flow f : ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
201             .getFlow()) {
202             if (isAllowSameEpg(f)) {
203                 count++;
204             }
205         }
206         assertEquals(sameEpgFlows, count);
207
208         int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6;
209         assertEquals(totalFlows, ofWriter
210             .getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
211     }
212
213     @Test
214     public void test_DifferentEg() throws Exception {
215         int totalFlows = sameEpgFlows + allowTunnelFlows;
216         assertEquals(totalFlows, doTestDifferentEg(ImmutableList.of(baseSubject(null).build()), allowActionInstance));
217         // one layer4 flow for each direction
218         totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + (2 * layer4flowsIPv6);
219         assertEquals(totalFlows,
220                 doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Bidirectional).build()), allowActionInstance));
221         totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6;
222         assertEquals(totalFlows,
223                 doTestDifferentEg(ImmutableList.of(baseSubject(Direction.In).build()), allowActionInstance));
224         assertEquals(totalFlows,
225                 doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Out).build()), allowActionInstance));
226     }
227
228     @Test
229     public void test_Rules() throws Exception {
230         Rule rule1 = new RuleBuilder()
231             .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
232             .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.In)))
233             .build();
234         Rule rule2 = new RuleBuilder()
235             .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
236             .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out)))
237             .build();
238         Rule rule3 = new RuleBuilder()
239             .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
240             .setClassifierRef(createClassifierRefs(
241                     ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out, "ether_type", Direction.In)))
242             .build();
243         Rule rule4 = new RuleBuilder()
244             .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
245             .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, "tcp_dst_90", Direction.In)))
246             .build();
247
248         int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6;
249         assertEquals(totalFlows,
250                 doTestDifferentEg(ImmutableList.of(createSubject("s1", ImmutableList.of(rule1))), allowActionInstance));
251         // one layer4 flow for each direction
252         totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + (2 * layer4flowsIPv6);
253         assertEquals(totalFlows,
254                 doTestDifferentEg(ImmutableList.of(createSubject("s2", ImmutableList.of(rule2))), allowActionInstance));
255         // only one ether_type for out direction
256         totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + layer4flowsIPv6;
257         assertEquals(totalFlows,
258                 doTestDifferentEg(ImmutableList.of(createSubject("s3", ImmutableList.of(rule3))), allowActionInstance));
259         totalFlows = sameEpgFlows + allowTunnelFlows;
260         assertEquals(totalFlows,
261                 doTestDifferentEg(ImmutableList.of(createSubject("s4", ImmutableList.of(rule4))), allowActionInstance));
262     }
263
264     @Test
265     public void test_Rules_ChainAction() throws Exception {
266         Rule rule1 = new RuleBuilder()
267             .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
268             .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.In)))
269             .build();
270         Rule rule2 = new RuleBuilder()
271             .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
272             .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out)))
273             .build();
274         Rule rule3 = new RuleBuilder()
275             .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
276             .setClassifierRef(createClassifierRefs(
277                     ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out, "ether_type", Direction.In)))
278             .build();
279         Rule rule4 = new RuleBuilder()
280             .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
281             .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, "tcp_dst_90", Direction.In)))
282             .build();
283
284         assertEquals(2,
285                 doTestDifferentEg(ImmutableList.of(createSubject("s1", ImmutableList.of(rule1))), chainActionInstance));
286         assertEquals(2,
287                 doTestDifferentEg(ImmutableList.of(createSubject("s2", ImmutableList.of(rule2))), chainActionInstance));
288         assertEquals(2,
289                 doTestDifferentEg(ImmutableList.of(createSubject("s3", ImmutableList.of(rule3))), chainActionInstance));
290         assertEquals(2,
291                 doTestDifferentEg(ImmutableList.of(createSubject("s4", ImmutableList.of(rule4))), chainActionInstance));
292     }
293
294     private int doTestDifferentEg(List<Subject> subjects, ActionInstance actionInstance) throws Exception {
295         EndpointBuilder ep1Builder = buildEndpoint(IPV4_0, MAC_0, nodeConnector);
296         ep1Builder.setEndpointGroup(ENDPOINT_GROUP_0);
297         ep1Builder.setL2Context(L2BD_ID);
298         Endpoint ep1 = ep1Builder.build();
299         endpointManagerMock.addEndpoint(ep1);
300         EndpointBuilder ep2Builder = buildEndpoint(IPV4_1, MAC_1, nodeConnector);
301         ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1);
302         ep2Builder.setL2Context(L2BD_ID);
303         Endpoint ep2 = ep2Builder.build();
304         endpointManagerMock.addEndpoint(ep2);
305
306         TenantBuilder tb = buildTenant(actionInstance);
307         ctxMock.addTenant(tb.setPolicy(
308                 new PolicyBuilder(tb.getPolicy()).setContract(ImmutableList.of(baseContract(subjects).build())).build())
309             .build());
310
311         ofWriter = new OfWriter();
312         table.sync(ep1, ofWriter);
313
314         assertTrue(!ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
315             .getFlow()
316             .isEmpty());
317
318         int count = 0;
319         for (Flow f : ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
320             .getFlow()) {
321             if (isAllowSameEpg(f)) {
322                 count++;
323             } else if (f.getMatch() != null && Objects.equals(tunnelId, f.getMatch().getInPort())) {
324                 assertEquals(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))), f.getInstructions());
325                 count++;
326             } else if (f.getMatch() != null && f.getMatch().getEthernetMatch() != null
327                     && Objects.equals(FlowUtils.IPv4,
328                             f.getMatch().getEthernetMatch().getEthernetType().getType().getValue())
329                     && f.getMatch().getIpMatch() != null
330                     && Objects.equals((short) 6, f.getMatch().getIpMatch().getIpProtocol())
331                     && f.getMatch().getLayer4Match() != null
332                     && (Objects.equals(new PortNumber(80),
333                             ((TcpMatch) f.getMatch().getLayer4Match()).getTcpSourcePort())
334                             || Objects.equals(new PortNumber(80),
335                                     ((TcpMatch) f.getMatch().getLayer4Match()).getTcpDestinationPort()))) {
336                 count++;
337             } else if (f.getMatch() != null && f.getMatch().getEthernetMatch() != null
338                     && Objects.equals(FlowUtils.IPv6,
339                             f.getMatch().getEthernetMatch().getEthernetType().getType().getValue())
340                     && f.getMatch().getIpMatch() != null
341                     && Objects.equals((short) 6, f.getMatch().getIpMatch().getIpProtocol())
342                     && f.getMatch().getLayer4Match() != null
343                     && (Objects.equals(new PortNumber(80),
344                             ((TcpMatch) f.getMatch().getLayer4Match()).getTcpSourcePort())
345                             || Objects.equals(new PortNumber(80),
346                                     ((TcpMatch) f.getMatch().getLayer4Match()).getTcpDestinationPort()))) {
347                 count++;
348             }
349         }
350         return count;
351     }
352
353     @Test
354     public void test_Conditions() throws Exception {
355         Condition cond1 = new ConditionBuilder().setName(new ConditionName("cond1")).build();
356         Condition cond2 = new ConditionBuilder().setName(new ConditionName("cond2")).build();
357
358         EndpointBuilder ep1Builder = buildEndpoint(IPV4_0, MAC_0, nodeConnector);
359         ep1Builder.setEndpointGroup(ENDPOINT_GROUP_0);
360         ep1Builder.setL2Context(L2BD_ID);
361         ep1Builder.setCondition(ImmutableList.of(cond1.getName())).build();
362         Endpoint ep1 = ep1Builder.build();
363         endpointManagerMock.addEndpoint(ep1);
364         EndpointBuilder ep2Builder = buildEndpoint(IPV4_1, MAC_1, nodeConnector);
365         ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1);
366         ep2Builder.setL2Context(L2BD_ID);
367         ep2Builder.setCondition(ImmutableList.of(cond1.getName(), cond2.getName())).build();
368         Endpoint ep2 = ep2Builder.build();
369         endpointManagerMock.addEndpoint(ep2);
370
371         TenantBuilder tb = buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy())
372             .setContract(ImmutableList.of(new ContractBuilder().setId(CONTRACT_ID)
373                 .setSubject(ImmutableList.of(baseSubject(Direction.Out).build()))
374                 .setClause(ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test"))
375                     .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
376                     .setConsumerMatchers(new ConsumerMatchersBuilder().setConditionMatcher(
377                             ImmutableList.of(new ConditionMatcherBuilder().setName(new ConditionMatcherName("m1"))
378                                 .setCondition(ImmutableList.of(cond1, cond2))
379                                 .setMatchType(MatchType.Any)
380                                 .build()))
381                         .build())
382                     .setProviderMatchers(new ProviderMatchersBuilder()
383                         .setConditionMatcher(
384                                 ImmutableList.of(new ConditionMatcherBuilder().setName(new ConditionMatcherName("m2"))
385                                     .setCondition(ImmutableList.of(cond1, cond2))
386                                     .setMatchType(MatchType.All)
387                                     .build()))
388                         .build())
389                     .build()))
390                 .build()))
391             .build());
392         ctxMock.addTenant(tb.build());
393
394         PolicyInfo policy = ctxMock.getCurrentPolicy();
395         List<ConditionName> ep1c = endpointManagerMock.getConditionsForEndpoint(ep1);
396         ConditionGroup cg1 = policy.getEgCondGroup(new EgKey(tb.getId(), ep1.getEndpointGroup()), ep1c);
397         List<ConditionName> ep2c = endpointManagerMock.getConditionsForEndpoint(ep2);
398         ConditionGroup cg2 = policy.getEgCondGroup(new EgKey(tb.getId(), ep2.getEndpointGroup()), ep2c);
399         int cg1Id = OrdinalFactory.getCondGroupOrdinal(cg1);
400         int cg2Id = OrdinalFactory.getCondGroupOrdinal(cg2);
401         int eg1Id = OrdinalFactory.getContextOrdinal(ep1.getTenant(), ep1.getEndpointGroup());
402         int eg2Id = OrdinalFactory.getContextOrdinal(ep1.getTenant(), ep2.getEndpointGroup());
403
404         assertNotEquals(cg1Id, cg2Id);
405
406         MatchBuilder mb = new MatchBuilder();
407         FlowUtils.addNxRegMatch(mb, RegMatch.of(NxmNxReg0.class, (long) eg1Id),
408                 RegMatch.of(NxmNxReg1.class, (long) cg1Id), RegMatch.of(NxmNxReg2.class, (long) eg2Id),
409                 RegMatch.of(NxmNxReg3.class, (long) cg2Id));
410         int count = 0;
411         ofWriter = new OfWriter();
412         table.sync(ep1, ofWriter);
413         // one layer4 flow for each direction
414         int dropAllFlow = 1;
415         int arpFlows = 1;
416         int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6 + arpFlows + dropAllFlow;
417         assertEquals(totalFlows, ofWriter
418             .getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
419         for (Flow f : ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
420             .getFlow()) {
421             if (f.getMatch() != null && f.getMatch().getEthernetMatch() != null) {
422                 count++;
423             }
424         }
425         // flows with ether_type match
426         totalFlows = layer4flowsIPv4 + layer4flowsIPv6 + arpFlows;
427         assertEquals(totalFlows, count);
428     }
429
430     private boolean isAllowSameEpg(Flow flow) {
431         // flow has to have exactly 2 registers set, namely NxmNxReg0 and NxmNxReg2
432         // (these register values don't have to be equal)
433         boolean res = false;
434         if (flow != null && flow.getMatch() != null) {
435             GeneralAugMatchNodesNodeTableFlow genAug =
436                     flow.getMatch().getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
437             if (genAug != null) {
438                 List<ExtensionList> extensions = genAug.getExtensionList();
439                 if (extensions != null && extensions.size() == 2) {
440                     Long reg0 = null;
441                     Long reg2 = null;
442                     for (ExtensionList extensionList : extensions) {
443                         Class<? extends ExtensionKey> extensionKey = extensionList.getExtensionKey();
444                         Extension extension = extensionList.getExtension();
445                         if (extensionKey != null && extension != null) {
446                             NxAugMatchNodesNodeTableFlow nxAugMatch =
447                                     extension.getAugmentation(NxAugMatchNodesNodeTableFlow.class);
448                             if (nxAugMatch != null && nxAugMatch.getNxmNxReg() != null) {
449                                 if (extensionKey.equals(NxmNxReg0Key.class)) {
450                                     reg0 = nxAugMatch.getNxmNxReg().getValue();
451                                 } else if (extensionKey.equals(NxmNxReg2Key.class)) {
452                                     reg2 = nxAugMatch.getNxmNxReg().getValue();
453                                 }
454                             }
455                         }
456                     }
457                     if (reg0 != null && reg2 != null) {
458                         res = true;
459                     }
460                 }
461             }
462         }
463         return res;
464     }
465
466     private ContractBuilder baseContract(List<Subject> subjects) {
467         ContractBuilder contractBuilder = new ContractBuilder().setId(CONTRACT_ID).setSubject(subjects);
468         if (subjects == null) {
469             return contractBuilder.setClause(ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test"))
470                 .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
471                 .build()));
472         }
473         List<SubjectName> subjectNames = new ArrayList<>();
474         for (Subject subject : subjects) {
475             subjectNames.add(subject.getName());
476         }
477         return contractBuilder.setClause(ImmutableList
478             .of(new ClauseBuilder().setName(new ClauseName("test")).setSubjectRefs(subjectNames).build()));
479     }
480
481     private SubjectBuilder baseSubject(Direction direction) {
482         return new SubjectBuilder().setName(new SubjectName("s1"))
483             .setRule(ImmutableList.of(new RuleBuilder()
484                 .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
485                 .setClassifierRef(ImmutableList.of(new ClassifierRefBuilder().setName(new ClassifierName(TCP_DST))
486                     .setDirection(direction)
487                     .setInstanceName(new ClassifierName(TCP_DST))
488                     .build()))
489                 .build()));
490     }
491
492     private Subject createSubject(String name, List<Rule> rules) {
493         return new SubjectBuilder().setName(new SubjectName(name)).setRule(rules).build();
494     }
495
496     private List<ClassifierRef> createClassifierRefs(Map<String, Direction> refNamesAndDirections) {
497         List<ClassifierRef> refs = new ArrayList<>();
498         for (String refName : refNamesAndDirections.keySet()) {
499             refs.add(new ClassifierRefBuilder().setName(new ClassifierName(refName))
500                 .setDirection(refNamesAndDirections.get(refName))
501                 .setInstanceName(new ClassifierName(refName))
502                 .build());
503         }
504         return refs;
505     }
506 }