Neutron-mapper uses only DTOs from neutron.yang
[groupbasedpolicy.git] / renderers / ofoverlay / src / test / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / mapper / destination / DestinationMapperFlowsTest.java
1 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.destination;
2
3 import org.junit.Before;
4 import org.junit.Test;
5 import org.junit.runner.RunWith;
6 import org.mockito.Mockito;
7 import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;
8 import org.opendaylight.groupbasedpolicy.dto.PolicyInfo;
9 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
10 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
11 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;
12 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager;
13 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowIdUtils;
14 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
15 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory;
16 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3PrefixBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroup;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroupBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
61 import org.powermock.core.classloader.annotations.PrepareForTest;
62 import org.powermock.modules.junit4.PowerMockRunner;
63
64 import java.lang.reflect.Field;
65 import java.math.BigInteger;
66 import java.util.ArrayList;
67 import java.util.HashSet;
68 import java.util.List;
69 import java.util.Set;
70 import java.util.concurrent.atomic.AtomicInteger;
71
72 import static org.mockito.Mockito.*;
73 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
74
75 @RunWith(PowerMockRunner.class)
76 @PrepareForTest({ OrdinalFactory.class })
77 public class DestinationMapperFlowsTest extends MapperUtilsTest {
78
79     private DestinationMapperFlows flows;
80
81     @Before
82     public void init() throws Exception {
83         endpointManager = mock(EndpointManager.class);
84         policyManager = mock(PolicyManager.class);
85         policyInfo = mock(PolicyInfo.class);
86         ctx = mock(OfContext.class);
87         ofWriter = mock(OfWriter.class);
88         tableId = 3;
89         flows = new DestinationMapperFlows(new DestinationMapperUtils(ctx), NODE_ID, tableId);
90         resetPolicyOrdinalCounterValue();
91     }
92
93     @Test
94     public void testDropFlow_noEthertype() {
95         Flow testFlow = buildFlow(new FlowId(DROP_ALL), tableId, 100, null, FlowUtils.dropInstructions()).build();
96
97         flows.dropFlow(100, null, ofWriter);
98         verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow);
99     }
100
101     @Test
102     public void testDropFlow_ipV4Ethertype() {
103         MatchBuilder matchBuilder = new MatchBuilder();
104         matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4));
105         Match match = matchBuilder.build();
106         Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
107                 FlowUtils.dropInstructions()).build();
108
109         flows.dropFlow(100, FlowUtils.IPv4, ofWriter);
110         verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow);
111     }
112
113     @Test
114     public void testDropFlow_ipV6Ethertype() {
115         MatchBuilder matchBuilder = new MatchBuilder();
116         matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv6));
117         Match match = matchBuilder.build();
118         Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
119                 FlowUtils.dropInstructions()).build();
120
121         flows.dropFlow(100, FlowUtils.IPv6, ofWriter);
122         verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow);
123     }
124
125     @Test
126     public void testDropFlow_arpEthertype() {
127         MatchBuilder matchBuilder = new MatchBuilder();
128         matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.ARP));
129         Match match = matchBuilder.build();
130         Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
131                 FlowUtils.dropInstructions()).build();
132
133         flows.dropFlow(100, FlowUtils.ARP, ofWriter);
134         verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow);
135     }
136
137     @Test
138     public void createExternalL2Flow_exceptionCaught() {
139         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
140         Set<NodeConnectorId> externalConnectors = new HashSet<>();
141         externalConnectors.add(new NodeConnectorId(CONNECTOR_0));
142         externalConnectors.add(new NodeConnectorId(CONNECTOR_1));
143
144         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
145         when(ctx.getEndpointManager()).thenReturn(endpointManager);
146         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
147
148         flows.createExternalL2Flow(tableId, 100, endpointBuilder.build(), externalConnectors, ofWriter);
149         verify(ctx, times(3)).getTenant(any(TenantId.class));
150         verify(ctx, times(1)).getEndpointManager();
151         verify(ctx, times(1)).getCurrentPolicy();
152         verifyZeroInteractions(ofWriter);
153     }
154
155     @Test
156     public void createExternalL2Flow() {
157         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
158         Set<NodeConnectorId> externalConnectors = new HashSet<>();
159         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()));
160         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue()));
161         Endpoint endpoint = endpointBuilder.build();
162
163
164         MatchBuilder matchBuilder = new MatchBuilder()
165                 .setEthernetMatch(ethernetMatch(null, endpoint.getMacAddress(), null));
166         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) 3));
167         Match match = matchBuilder.build();
168
169         List<Action> applyActions = new ArrayList<>();
170         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
171         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
172         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
173
174         int order = 0;
175         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
176                 .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
177                 .build();
178         Instruction gotoTable = new InstructionBuilder().setOrder(order)
179                 .setInstruction(gotoTableIns(tableId))
180                 .build();
181
182         ArrayList<Instruction> instructions = new ArrayList<>();
183         instructions.add(applyActionsIns);
184         instructions.add(gotoTable);
185         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
186         instructionsBuilder.setInstruction(instructions);
187
188         FlowId flowId = FlowIdUtils.newFlowId(tableId, "externalL2", match);
189         Flow flow = buildFlow(flowId, tableId, 100, match, instructionsBuilder.build()).build();
190
191         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
192         when(ctx.getEndpointManager()).thenReturn(endpointManager);
193         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
194
195         flows.createExternalL2Flow(tableId, 100, endpointBuilder.build(), externalConnectors, ofWriter);
196         verify(ctx, times(3)).getTenant(any(TenantId.class));
197         verify(ctx, times(1)).getEndpointManager();
198         verify(ctx, times(1)).getCurrentPolicy();
199         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
200     }
201
202     @Test
203     public void createExternalL3RoutedFlow_nullIpAddress() {
204         EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
205         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1);
206         Endpoint gateway = gatewayBuilder.build();
207         Endpoint endpoint = endpointBuilder.build();
208         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
209         l3AddressBuilder.setIpAddress(null);
210         Set<NodeConnectorId> externalConnectors = new HashSet<>();
211         externalConnectors.add(new NodeConnectorId(CONNECTOR_0));
212         externalConnectors.add(new NodeConnectorId(CONNECTOR_1));
213
214         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
215         when(ctx.getEndpointManager()).thenReturn(endpointManager);
216         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
217
218         flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors,
219                 ofWriter);
220
221         verify(ctx, times(3)).getTenant(any(TenantId.class));
222         verify(ctx, times(1)).getEndpointManager();
223         verify(ctx, times(1)).getCurrentPolicy();
224         verifyZeroInteractions(ofWriter);
225     }
226
227     @Test
228     public void createExternalL3RoutedFlow_exceptionCaught() {
229         EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
230         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1);
231         Endpoint gateway = gatewayBuilder.build();
232         Endpoint endpoint = endpointBuilder.build();
233         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
234         l3AddressBuilder.setIpAddress(new IpAddress(IPV4_0));
235         Set<NodeConnectorId> externalConnectors = new HashSet<>();
236         externalConnectors.add(new NodeConnectorId(CONNECTOR_0));
237         externalConnectors.add(new NodeConnectorId(CONNECTOR_1));
238
239         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
240         when(ctx.getEndpointManager()).thenReturn(endpointManager);
241         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
242
243         flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors,
244                 ofWriter);
245
246         verify(ctx, times(3)).getTenant(any(TenantId.class));
247         verify(ctx, times(1)).getEndpointManager();
248         verify(ctx, times(1)).getCurrentPolicy();
249         verifyZeroInteractions(ofWriter);
250     }
251
252     @Test
253     public void createExternalL3RoutedFlow_ipV4() {
254         EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
255         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1);
256         Endpoint gateway = gatewayBuilder.build();
257         Endpoint endpoint = endpointBuilder.build();
258         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
259         l3AddressBuilder.setIpAddress(new IpAddress(IPV4_0));
260         Set<NodeConnectorId> externalConnectors = new HashSet<>();
261         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()));
262         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue()));
263
264         List<Action> l3ApplyActions = new ArrayList<>();
265         l3ApplyActions.add(setDlSrcAction(MAC_0));
266         l3ApplyActions.add(setDlDstAction(MAC_0));
267         List<Action> applyActions = new ArrayList<>();
268         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
269         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
270         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
271         applyActions.addAll(l3ApplyActions);
272
273         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, MAC_1, IPv4))
274                 .setLayer3Match(new Ipv4MatchBuilder()
275                 .setIpv4Destination(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32)).build());
276         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
277         Match match = matchBuilder.build();
278
279         int order = 0;
280         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
281                 .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
282                 .build();
283         Instruction gotoTable = new InstructionBuilder().setOrder(order)
284                 .setInstruction(gotoTableIns(tableId))
285                 .build();
286         ArrayList<Instruction> l3instructions = new ArrayList<>();
287         l3instructions.add(applyActionsIns);
288         l3instructions.add(gotoTable);
289         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
290         instructionsBuilder.setInstruction(l3instructions);
291
292         FlowId flowid = FlowIdUtils.newFlowId(tableId, "externalL3", match);
293         Flow flow = buildFlow(flowid, tableId, 90, match, instructionsBuilder.build()).build();
294
295         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
296         when(ctx.getEndpointManager()).thenReturn(endpointManager);
297         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
298
299         flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors,
300                 ofWriter);
301
302         verify(ctx, times(3)).getTenant(any(TenantId.class));
303         verify(ctx, times(1)).getEndpointManager();
304         verify(ctx, times(1)).getCurrentPolicy();
305         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
306     }
307
308     @Test
309     public void createExternalL3RoutedFlow_ipV6() {
310         EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_1, MAC_0, CONNECTOR_0);
311         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_2, MAC_1, CONNECTOR_1);
312         Endpoint gateway = gatewayBuilder.build();
313         Endpoint endpoint = endpointBuilder.build();
314         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
315         l3AddressBuilder.setIpAddress(new IpAddress(new Ipv6Address(IPV6_1)));
316         Set<NodeConnectorId> externalConnectors = new HashSet<>();
317         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()));
318         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue()));
319
320         List<Action> l3ApplyActions = new ArrayList<>();
321         l3ApplyActions.add(setDlSrcAction(MAC_0));
322         l3ApplyActions.add(setDlDstAction(MAC_0));
323         List<Action> applyActions = new ArrayList<>();
324         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
325         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
326         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
327         applyActions.addAll(l3ApplyActions);
328
329         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, MAC_1, IPv6))
330                 .setLayer3Match(new Ipv6MatchBuilder()
331                 .setIpv6Destination(new Ipv6Prefix(IPV6_1.getValue() + IP_PREFIX_128)).build());
332         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 0));
333         Match match = matchBuilder.build();
334
335         int order = 0;
336         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
337                 .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
338                 .build();
339         Instruction gotoTable = new InstructionBuilder().setOrder(order)
340                 .setInstruction(gotoTableIns(tableId))
341                 .build();
342         ArrayList<Instruction> l3instructions = new ArrayList<>();
343         l3instructions.add(applyActionsIns);
344         l3instructions.add(gotoTable);
345         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
346         instructionsBuilder.setInstruction(l3instructions);
347
348         FlowId flowid = FlowIdUtils.newFlowId(tableId, "externalL3", match);
349         Flow flow = buildFlow(flowid, tableId, 90, match, instructionsBuilder.build()).build();
350
351         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
352         when(ctx.getEndpointManager()).thenReturn(endpointManager);
353         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
354
355         flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors,
356                 ofWriter);
357
358         verify(ctx, times(3)).getTenant(any(TenantId.class));
359         verify(ctx, times(1)).getEndpointManager();
360         verify(ctx, times(1)).getCurrentPolicy();
361         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
362     }
363
364     @Test
365     public void createLocalL2Flow_exceptionCaught() {
366         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_0, CONNECTOR_0);
367         Endpoint endpoint = endpointBuilder.build();
368
369         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
370         when(ctx.getEndpointManager()).thenReturn(endpointManager);
371         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
372
373         flows.createLocalL2Flow(tableId, 80, endpoint, ofWriter);
374
375         verify(ctx, times(3)).getTenant(any(TenantId.class));
376         verify(ctx, times(1)).getEndpointManager();
377         verify(ctx, times(1)).getCurrentPolicy();
378         verifyZeroInteractions(ofWriter);
379     }
380
381     @Test
382     public void createLocalL2Flow() {
383         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
384         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_0, connectorId);
385         endpointBuilder.setNetworkContainment(SUBNET_0);
386         Endpoint endpoint = endpointBuilder.build();
387
388         List<Action> applyActions = new ArrayList<>();
389         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
390         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
391         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
392
393         int order = 0;
394         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
395                 .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
396                 .build();
397         Instruction gotoTable = new InstructionBuilder().setOrder(order)
398                 .setInstruction(gotoTableIns(tableId))
399                 .build();
400
401         ArrayList<Instruction> instructions = new ArrayList<>();
402         instructions.add(applyActionsIns);
403         instructions.add(gotoTable);
404         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
405         instructionsBuilder.setInstruction(instructions);
406
407         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, endpoint.getMacAddress(),
408                 null));
409         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) 3));
410         Match match = matchBuilder.build();
411
412         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "localL2", match), tableId, 80, match,
413                 instructionsBuilder.build()).build();
414
415         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
416         when(ctx.getEndpointManager()).thenReturn(endpointManager);
417         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
418
419         flows.createLocalL2Flow(tableId, 80, endpoint, ofWriter);
420
421         verify(ctx, times(3)).getTenant(any(TenantId.class));
422         verify(ctx, times(1)).getEndpointManager();
423         verify(ctx, times(1)).getCurrentPolicy();
424         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
425     }
426
427     @Test
428     public void createLocalL3RoutedFlow_nullL3Context() {
429         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
430         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
431         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1));
432         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_0, connectorId);
433         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
434         Endpoint endpoint = endpointBuilder.build();
435         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, null, null, null, ofWriter);
436         verifyZeroInteractions(ofWriter);
437     }
438
439     @Test
440     public void createLocalL3RoutedFlow_noMac() {
441         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
442         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
443         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1));
444         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId);
445         endpointBuilder.setNetworkContainment(SUBNET_0);
446         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
447         endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId());
448         endpointBuilder.setMacAddress(null);
449         Endpoint endpoint = endpointBuilder.build();
450
451         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
452         localSubnetBuilder.setId(SUBNET_0);
453         localSubnetBuilder.setParent(L2FD_ID);
454         Subnet localSubnet = localSubnetBuilder.build();
455
456         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
457         destSubnetBuilder.setId(SUBNET_1);
458         Subnet destSubnet = destSubnetBuilder.build();
459
460         when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
461         when(ctx.getEndpointManager()).thenReturn(endpointManager);
462
463         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, null, localSubnet, destSubnet, ofWriter);
464         verify(ctx, times(1)).getTenant(any(TenantId.class));
465         verify(ctx, times(1)).getEndpointManager();
466         verifyZeroInteractions(ofWriter);
467     }
468
469     @Test
470     public void createLocalL3RoutedFlow_sameSubnetIdAndExceptionCaught() {
471         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
472         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
473         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1));
474         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId);
475         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
476         endpointBuilder.setNetworkContainment(SUBNET_0);
477         endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId());
478         Endpoint endpoint = endpointBuilder.build();
479
480         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
481         localSubnetBuilder.setId(SUBNET_0);
482         localSubnetBuilder.setParent(L2FD_ID);
483         Subnet localSubnet = localSubnetBuilder.build();
484
485         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
486         destSubnetBuilder.setId(SUBNET_1);
487         destSubnetBuilder.setParent(L2FD_ID);
488         Subnet destSubnet = destSubnetBuilder.build();
489
490         when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
491         when(ctx.getEndpointManager()).thenReturn(endpointManager);
492
493         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, null, localSubnet, destSubnet, ofWriter);
494         verify(ctx, times(3)).getTenant(any(TenantId.class));
495         verify(ctx, times(3)).getEndpointManager();
496         verifyZeroInteractions(ofWriter);
497     }
498
499     @Test
500     public void createLocalL3RoutedFlow_noIp() {
501         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
502         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
503         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(OPENFLOW + CONNECTOR_1));
504         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId);
505         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
506         endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId());
507         Endpoint endpoint = endpointBuilder.build();
508
509         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
510         localSubnetBuilder.setId(SUBNET_0).setParent(L2FD_ID);
511         Subnet localSubnet = localSubnetBuilder.build();
512
513         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
514         destSubnetBuilder.setId(SUBNET_1);
515         Subnet destSubnet = destSubnetBuilder.build();
516
517         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
518         l3AddressBuilder.setIpAddress(null);
519         L3Address l3Address = l3AddressBuilder.build();
520
521         when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
522         when(ctx.getEndpointManager()).thenReturn(endpointManager);
523         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
524
525         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, l3Address, localSubnet, destSubnet, ofWriter);
526         verify(ctx, times(4)).getTenant(any(TenantId.class));
527         verify(ctx, times(3)).getEndpointManager();
528         verify(ctx, times(1)).getCurrentPolicy();
529         verifyZeroInteractions(ofWriter);
530     }
531
532     @Test
533     public void createLocalL3RoutedFlow_ipV4() {
534         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
535         MacAddress destMac = DestinationMapper.ROUTER_MAC;
536         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
537         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(connectorId));
538         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId);
539         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
540         endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId());
541         endpointBuilder.setNetworkContainment(SUBNET_0);
542         Endpoint endpoint = endpointBuilder.build();
543
544         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
545         localSubnetBuilder.setId(SUBNET_0);
546         localSubnetBuilder.setParent(L2FD_ID);
547         Subnet localSubnet = localSubnetBuilder.build();
548
549         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
550         destSubnetBuilder.setId(SUBNET_1);
551         destSubnetBuilder.setParent(L2FD_ID);
552         Subnet destSubnet = destSubnetBuilder.build();
553
554         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
555         l3AddressBuilder.setIpAddress(new IpAddress((IPV4_0)));
556         L3Address l3Address = l3AddressBuilder.build();
557
558         List<Action> l3ApplyActions = new ArrayList<>();
559         l3ApplyActions.add(setDlDstAction((MAC_1)));
560         l3ApplyActions.add(decNwTtlAction());
561         l3ApplyActions.add(setDlSrcAction(destMac));
562
563         List<Action> applyActions = new ArrayList<>();
564         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
565         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
566         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
567         applyActions.addAll(l3ApplyActions);
568
569         int order = 0;
570         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
571                 .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
572                 .build();
573         Instruction gotoTable = new InstructionBuilder().setOrder(order)
574                 .setInstruction(gotoTableIns(tableId))
575                 .build();
576         ArrayList<Instruction> l3instructions = new ArrayList<>();
577         l3instructions.add(applyActionsIns);
578         l3instructions.add(gotoTable);
579
580         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, destMac, IPv4))
581                 .setLayer3Match(new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32)).build());
582         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
583         Match match = matchBuilder.build();
584         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
585         instructionsBuilder.setInstruction(l3instructions);
586
587         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "localL3", match), tableId, 80, match,
588                 instructionsBuilder.build()).build();
589
590         when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
591         when(ctx.getEndpointManager()).thenReturn(endpointManager);
592         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
593
594         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, l3Address, localSubnet, destSubnet, ofWriter);
595         verify(ctx, times(4)).getTenant(any(TenantId.class));
596         verify(ctx, times(3)).getEndpointManager();
597         verify(ctx, times(1)).getCurrentPolicy();
598         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
599     }
600
601     @Test
602     public void createLocalL3RoutedFlow_ipV6() {
603         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
604         MacAddress destMac = DestinationMapper.ROUTER_MAC;
605         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
606         ofOverlayContextBuilder.setNodeConnectorId(connectorId);
607         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1,MAC_1, connectorId);
608         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
609         endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId());
610         endpointBuilder.setNetworkContainment(SUBNET_0);
611         Endpoint endpoint = endpointBuilder.build();
612
613         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
614         localSubnetBuilder.setId(SUBNET_0);
615         localSubnetBuilder.setParent(L2FD_ID);
616         Subnet localSubnet = localSubnetBuilder.build();
617
618         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
619         destSubnetBuilder.setId(SUBNET_1);
620         destSubnetBuilder.setParent(L2FD_ID);
621         Subnet destSubnet = destSubnetBuilder.build();
622
623         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
624         l3AddressBuilder.setIpAddress(new IpAddress((IPV6_1)));
625         L3Address l3Address = l3AddressBuilder.build();
626
627         List<Action> l3ApplyActions = new ArrayList<>();
628         l3ApplyActions.add(setDlDstAction(MAC_1));
629         l3ApplyActions.add(decNwTtlAction());
630         l3ApplyActions.add(setDlSrcAction(destMac));
631
632         List<Action> applyActions = new ArrayList<>();
633         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
634         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
635         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
636         applyActions.addAll(l3ApplyActions);
637
638         int order = 0;
639         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
640                 .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
641                 .build();
642         Instruction gotoTable = new InstructionBuilder().setOrder(order)
643                 .setInstruction(gotoTableIns(tableId))
644                 .build();
645         ArrayList<Instruction> l3instructions = new ArrayList<>();
646         l3instructions.add(applyActionsIns);
647         l3instructions.add(gotoTable);
648
649         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, destMac, IPv6))
650                 .setLayer3Match(new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(IPV6_1.getValue() + IP_PREFIX_128)).build());
651         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
652         Match match = matchBuilder.build();
653         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
654         instructionsBuilder.setInstruction(l3instructions);
655
656         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "localL3", match), tableId, 80, match,
657                 instructionsBuilder.build()).build();
658
659         when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
660         when(ctx.getEndpointManager()).thenReturn(endpointManager);
661         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
662
663         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, l3Address, localSubnet, destSubnet, ofWriter);
664         verify(ctx, times(4)).getTenant(any(TenantId.class));
665         verify(ctx, times(3)).getEndpointManager();
666         verify(ctx, times(1)).getCurrentPolicy();
667         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
668     }
669
670     @Test
671     public void createRemoteL2Flow_exceptionCaught() {
672         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0);
673
674         when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
675         when(ctx.getEndpointManager()).thenReturn(endpointManager);
676         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
677
678         flows.createRemoteL2Flow(tableId, 70, endpointBuilder.build(), null, null, new NodeConnectorId(CONNECTOR_1),
679                 ofWriter);
680         verify(ctx, times(3)).getTenant(any(TenantId.class));
681         verify(ctx, times(1)).getEndpointManager();
682         verify(ctx, times(1)).getCurrentPolicy();
683         verifyZeroInteractions(ofWriter);
684     }
685
686     @Test
687     public void createRemoteL2Flow_ipV4() {
688         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue());
689         IpAddress ipAddress = new IpAddress(IPV4_0);
690         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_0);
691         EndpointBuilder peerEndpointBuilder = buildEndpoint(IPV4_1, MAC_0, CONNECTOR_1);
692
693         List<Action> applyActions = new ArrayList<>();
694         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
695         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
696         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(1)));
697         applyActions.add(nxLoadTunIPv4Action(ipAddress.getIpv4Address().getValue(), false));
698
699         int order = 0;
700         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
701                 .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
702                 .build();
703         Instruction gotoTable = new InstructionBuilder().setOrder(order)
704                 .setInstruction(gotoTableIns(tableId))
705                 .build();
706
707         ArrayList<Instruction> instructions = new ArrayList<>();
708         instructions.add(applyActionsIns);
709         instructions.add(gotoTable);
710         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
711         instructionsBuilder.setInstruction(instructions);
712
713         MatchBuilder matchBuilder = new MatchBuilder()
714                 .setEthernetMatch(ethernetMatch(null, MAC_0, null));
715         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) 3));
716         Match match = matchBuilder.build();
717
718         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "remoteL2", match), tableId, 70, match,
719                 instructionsBuilder.build()).build();
720
721         when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
722         when(ctx.getEndpointManager()).thenReturn(endpointManager);
723         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
724
725         flows.createRemoteL2Flow(tableId, 70, endpointBuilder.build(), peerEndpointBuilder.build(), ipAddress,
726                 connectorId, ofWriter);
727         verify(ctx, times(3)).getTenant(any(TenantId.class));
728         verify(ctx, times(1)).getEndpointManager();
729         verify(ctx, times(1)).getCurrentPolicy();
730         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
731     }
732
733     @Test
734     public void createRemoteL2Flow_ipV6() {
735         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_1);
736         IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6_1));
737         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0);
738         EndpointBuilder peerEndpointBuilder = buildEndpoint(IPV6_2, MAC_0, CONNECTOR_0);
739
740         when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
741         when(ctx.getEndpointManager()).thenReturn(endpointManager);
742         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
743
744         flows.createRemoteL2Flow(tableId, 70, endpointBuilder.build(), peerEndpointBuilder.build(), ipAddress,
745                 connectorId, ofWriter);
746         verify(ctx, times(3)).getTenant(any(TenantId.class));
747         verify(ctx, times(1)).getEndpointManager();
748         verify(ctx, times(1)).getCurrentPolicy();
749         verifyZeroInteractions(ofWriter);
750     }
751
752     @Test
753     public void createRemoteL3RoutedFlow_noL3Context() {
754         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0);
755         Endpoint endpoint = endpointBuilder.build();
756         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, null, null, null, null, ofWriter);
757         verifyZeroInteractions(ofWriter);
758     }
759
760     @Test
761     public void createRemoteL3RoutedFlow_noMac() {
762         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0);
763         endpointBuilder.setMacAddress(null);
764         Endpoint endpoint = endpointBuilder.build();
765
766         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
767         destSubnetBuilder.setId(SUBNET_0);
768         destSubnetBuilder.setParent(L2FD_ID);
769         Subnet destSubnet = destSubnetBuilder.build();
770
771         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
772         localSubnetBuilder.setId(SUBNET_1);
773         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_1));
774         localSubnetBuilder.setParent(L2FD_ID);
775         Subnet localSubnet = localSubnetBuilder.build();
776
777         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
778         when(ctx.getEndpointManager()).thenReturn(endpointManager);
779         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
780
781         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, destSubnet, null, null, localSubnet, ofWriter);
782         verify(ctx, times(4)).getTenant(any(TenantId.class));
783         verify(ctx, times(2)).getEndpointManager();
784         verify(ctx, times(1)).getCurrentPolicy();
785         verifyZeroInteractions(ofWriter);
786     }
787
788     @Test
789     public void createRemoteL3RoutedFlow_noIp() {
790         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0);
791         endpointBuilder.setNetworkContainment(SUBNET_0);
792         Endpoint endpoint = endpointBuilder.build();
793
794         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
795         destSubnetBuilder.setId(SUBNET_1);
796         destSubnetBuilder.setParent(L2FD_ID);
797         Subnet destSubnet = destSubnetBuilder.build();
798
799         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
800         localSubnetBuilder.setId(SUBNET_0);
801         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_1));
802         localSubnetBuilder.setParent(L2FD_ID);
803         Subnet localSubnet = localSubnetBuilder.build();
804
805         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
806         when(ctx.getEndpointManager()).thenReturn(endpointManager);
807         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
808
809         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, destSubnet, null, null, localSubnet, ofWriter);
810         verify(ctx, times(4)).getTenant(any(TenantId.class));
811         verify(ctx, times(3)).getEndpointManager();
812         verify(ctx, times(1)).getCurrentPolicy();
813         verifyZeroInteractions(ofWriter);
814     }
815
816     @Test
817     public void createRemoteL3RoutedFlow_incorrectPortId() {
818         IpAddress ipAddress = new IpAddress(IPV4_0);
819         NodeConnectorId connectorId = new NodeConnectorId(CONNECTOR_0);
820         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1,MAC_1,CONNECTOR_0);
821         endpointBuilder.setNetworkContainment(SUBNET_0);
822         Endpoint endpoint = endpointBuilder.build();
823
824
825         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
826         destSubnetBuilder.setId(SUBNET_1);
827         destSubnetBuilder.setParent(L2FD_ID);
828         Subnet destSubnet = destSubnetBuilder.build();
829
830         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
831         localSubnetBuilder.setId(SUBNET_0);
832         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_1));
833         Subnet localSubnet = localSubnetBuilder.build();
834
835         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
836         when(ctx.getEndpointManager()).thenReturn(endpointManager);
837         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
838
839         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, destSubnet, ipAddress, connectorId, localSubnet,
840                 ofWriter);
841         verify(ctx, times(4)).getTenant(any(TenantId.class));
842         verify(ctx, times(3)).getEndpointManager();
843         verify(ctx, times(1)).getCurrentPolicy();
844         verifyZeroInteractions(ofWriter);
845     }
846
847     @Test
848     public void createRemoteL3RoutedFlow_ipV4() {
849         MacAddress routerMac = DestinationMapper.ROUTER_MAC;
850         IpAddress ipAddress = new IpAddress(IPV4_1);
851         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
852         l3AddressBuilder.setIpAddress(new IpAddress(IPV4_1));
853         L3Address l3Address = l3AddressBuilder.build();
854         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
855         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_0);
856         Endpoint endpoint = endpointBuilder.build();
857
858         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
859         destSubnetBuilder.setId(SUBNET_1);
860         destSubnetBuilder.setParent(L2FD_ID);
861         Subnet destSubnet = destSubnetBuilder.build();
862
863         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
864         localSubnetBuilder.setId(SUBNET_0);
865         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_1));
866         localSubnetBuilder.setParent(L2FD_ID);
867         Subnet localSubnet = localSubnetBuilder.build();
868
869         List<Action> l3ApplyActions = new ArrayList<>();
870         l3ApplyActions.add(setDlSrcAction(routerMac));
871         l3ApplyActions.add(setDlDstAction(MAC_1));
872         l3ApplyActions.add(decNwTtlAction());
873         List<Action> applyActions = new ArrayList<>();
874         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
875         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
876         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
877         applyActions.add(nxLoadTunIPv4Action(IPV4_1.getValue(), false));
878         applyActions.addAll(l3ApplyActions);
879         Instruction applyActionsIns = new InstructionBuilder().setOrder(0)
880                 .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
881                 .build();
882         Instruction gotoTable = new InstructionBuilder().setOrder(1)
883                 .setInstruction(gotoTableIns(tableId))
884                 .build();
885         ArrayList<Instruction> l3instructions = new ArrayList<>();
886         l3instructions.add(applyActionsIns);
887         l3instructions.add(gotoTable);
888         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
889         instructionsBuilder.setInstruction(l3instructions);
890
891         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, routerMac, IPv4))
892                 .setLayer3Match(new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(IPV4_1.getValue() + IP_PREFIX_32)).build());
893         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
894         Match match = matchBuilder.build();
895
896         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "remoteL3", match), tableId, 60, match,
897                 instructionsBuilder.build()).build();
898
899         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
900         when(ctx.getEndpointManager()).thenReturn(endpointManager);
901         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
902
903         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, l3Address, destSubnet, ipAddress, connectorId, localSubnet,
904                 ofWriter);
905         verify(ctx, times(4)).getTenant(any(TenantId.class));
906         verify(ctx, times(3)).getEndpointManager();
907         verify(ctx, times(1)).getCurrentPolicy();
908         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
909     }
910
911     @Test
912     public void createRemoteL3RoutedFlow_ipV6() {
913         IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6_1));
914         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
915         l3AddressBuilder.setIpAddress(new IpAddress(IPV4_1));
916         L3Address l3Address = l3AddressBuilder.build();
917         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0);
918         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_0);
919         Endpoint endpoint = endpointBuilder.build();
920
921         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
922         destSubnetBuilder.setId(SUBNET_1);
923         destSubnetBuilder.setParent(L2FD_ID);
924         Subnet destSubnet = destSubnetBuilder.build();
925
926         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
927         localSubnetBuilder.setId(SUBNET_0);
928         localSubnetBuilder.setParent(L2FD_ID);
929         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_1));
930         Subnet localSubnet = localSubnetBuilder.build();
931
932         when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant());
933         when(ctx.getEndpointManager()).thenReturn(endpointManager);
934         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
935
936         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, l3Address, destSubnet, ipAddress, connectorId, localSubnet,
937                 ofWriter);
938         verify(ctx, times(4)).getTenant(any(TenantId.class));
939         verify(ctx, times(3)).getEndpointManager();
940         verify(ctx, times(1)).getCurrentPolicy();
941         verifyZeroInteractions(ofWriter);
942     }
943
944     @Test
945     public void createRouterArpFlow_nullL3SubnetContext() throws Exception {
946         IndexedTenant tenant = getTestIndexedTenant();
947         SubnetBuilder subnetBuilder = new SubnetBuilder();
948         subnetBuilder.setId(new SubnetId("otherSubnet"));
949         flows.createRouterArpFlow(50, tenant, subnetBuilder.build(), ofWriter);
950         verifyZeroInteractions(ofWriter);
951     }
952
953     @Test
954     public void createRouterArpFlow_ipV4() throws Exception {
955         IndexedTenant tenant = getTestIndexedTenant();
956         SubnetBuilder subnetBuilder = new SubnetBuilder();
957         subnetBuilder.setId(SUBNET_0);
958         subnetBuilder.setParent(L2FD_ID);
959         subnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_0));
960
961         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, null, ARP))
962                 .setLayer3Match(new ArpMatchBuilder().setArpOp(1)
963                         .setArpTargetTransportAddress(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32)).build());
964         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
965         Match match = matchBuilder.build();
966
967         List<Action> actions = new ArrayList<>();
968         actions.add(nxMoveEthSrcToEthDstAction());
969         actions.add(setDlSrcAction(DestinationMapper.ROUTER_MAC));
970         actions.add(nxLoadArpOpAction(BigInteger.valueOf(2L)));
971         actions.add(nxMoveArpShaToArpThaAction());
972         actions.add(nxLoadArpShaAction(new BigInteger(1, bytesFromHexString(DestinationMapper.ROUTER_MAC.getValue()))));
973         actions.add(nxMoveArpSpaToArpTpaAction());
974         actions.add(nxLoadArpSpaAction(IPV4_0.getValue()));
975         actions.add(outputAction(new NodeConnectorId(NODE_ID.getValue() + ":INPORT")));
976         List<Instruction> instructions = new ArrayList<>();
977         InstructionBuilder instructionBuilder = new InstructionBuilder();
978         instructionBuilder.setInstruction(applyActionIns(actions.toArray(new Action[actions.size()]))).setOrder(0);
979         instructions.add(instructionBuilder.build());
980         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
981         instructionsBuilder.setInstruction(instructions);
982
983         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "routerarp", match), tableId, 50, match,
984                 instructionsBuilder.build()).build();
985
986         when(ctx.getEndpointManager()).thenReturn(endpointManager);
987         flows.createRouterArpFlow(50, tenant, subnetBuilder.build(), ofWriter);
988
989         verify(ctx, times(1)).getEndpointManager();
990         verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow));
991     }
992
993     @Test
994     public void createRouterArpFlow_ipV6() throws Exception {
995         IndexedTenant tenant = getTestIndexedTenant();
996         SubnetBuilder subnetBuilder = new SubnetBuilder();
997         subnetBuilder.setId(SUBNET_1);
998         subnetBuilder.setParent(L2FD_ID);
999         subnetBuilder.setVirtualRouterIp(new IpAddress(IPV6_1));
1000
1001         when(ctx.getEndpointManager()).thenReturn(endpointManager);
1002
1003         flows.createRouterArpFlow(50, tenant, subnetBuilder.build(), ofWriter);
1004
1005         verify(ctx, times(1)).getEndpointManager();
1006         verifyZeroInteractions(ofWriter);
1007     }
1008
1009     @Test
1010     public void createBroadcastFlow() {
1011         DestinationMapperUtils utils = new DestinationMapperUtils(ctx);
1012         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_1);
1013         endpointBuilder.setTenant(buildTenant().getId());
1014
1015         when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
1016         when(ctx.getEndpointManager()).thenReturn(endpointManager);
1017         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
1018
1019         OrdinalFactory.EndpointFwdCtxOrdinals ordinals = utils.getEndpointOrdinals(endpointBuilder.build());
1020
1021         verify(ctx, times(3)).getTenant(any(TenantId.class));
1022         verify(ctx, times(1)).getEndpointManager();
1023         verify(ctx, times(1)).getCurrentPolicy();
1024
1025         MatchBuilder matchBuilder = new MatchBuilder()
1026                 .setEthernetMatch(new EthernetMatchBuilder()
1027                         .setEthernetDestination(new EthernetDestinationBuilder().setAddress(MAC_0)
1028                                 .setMask(MAC_0).build())
1029                         .build());
1030         addNxRegMatch(matchBuilder, FlowUtils.RegMatch.of(NxmNxReg5.class, (long) ordinals.getFdId()));
1031         Match match = matchBuilder.build();
1032         List<Action> actions = new ArrayList<>();
1033         actions.add(nxLoadTunIdAction(BigInteger.valueOf(ordinals.getFdId()), false));
1034         actions.add(groupAction((long) ordinals.getFdId()));
1035         List<Instruction> instructions = new ArrayList<>();
1036         InstructionBuilder instructionBuilder = new InstructionBuilder();
1037         instructionBuilder.setInstruction(applyActionIns(actions.toArray(new Action[actions.size()]))).setOrder(0);
1038         instructions.add(instructionBuilder.build());
1039         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
1040         instructionsBuilder.setInstruction(instructions);
1041
1042         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "broadcast", match), tableId, 40, match,
1043                 instructionsBuilder.build()).build();
1044
1045         flows.createBroadcastFlow(40, ordinals, MAC_0, ofWriter);
1046
1047         verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow));
1048     }
1049
1050     @Test
1051     public void createL3PrefixFlow_internalExceptionCaught() {
1052         EndpointBuilder gatewayEp = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
1053         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
1054         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1));
1055         gatewayEp.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
1056
1057         IndexedTenant tenant = getTestIndexedTenant();
1058         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
1059         localSubnetBuilder.setId(SUBNET_1);
1060         localSubnetBuilder.setVirtualRouterIp(new IpAddress((IPV4_0)));
1061         localSubnetBuilder.setParent(L2FD_ID);
1062         Subnet localSubnet = localSubnetBuilder.build();
1063
1064         when(ctx.getEndpointManager()).thenReturn(endpointManager);
1065
1066         flows.createL3PrefixFlow(tableId, 30, gatewayEp.build(), null, tenant, localSubnet, null, ofWriter);
1067         verify(ctx, times(1)).getEndpointManager();
1068         verifyZeroInteractions(ofWriter);
1069     }
1070
1071     @Test
1072     public void createL3PrefixFlow_externalExceptionCaught() {
1073         EndpointBuilder gatewayEpBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
1074         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
1075         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1));
1076         gatewayEpBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
1077         gatewayEpBuilder.setEndpointGroup(ENDPOINT_GROUP_0);
1078
1079         TenantBuilder tenantBuilder = new TenantBuilder(getTestIndexedTenant().getTenant());
1080         List<ExternalImplicitGroup> externalImplicitGroups = new ArrayList<>();
1081         ExternalImplicitGroupBuilder externalImplicitGroupBuilder = new ExternalImplicitGroupBuilder();
1082         externalImplicitGroupBuilder.setId(ENDPOINT_GROUP_0);
1083         externalImplicitGroups.add(externalImplicitGroupBuilder.build());
1084         tenantBuilder.setPolicy(new PolicyBuilder().setExternalImplicitGroup(externalImplicitGroups).build());
1085         IndexedTenant tenant = new IndexedTenant(tenantBuilder.build());
1086
1087         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
1088         localSubnetBuilder.setId(SUBNET_1);
1089         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_0));
1090         localSubnetBuilder.setParent(L2FD_ID);
1091         Subnet localSubnet = localSubnetBuilder.build();
1092
1093         Set<NodeConnectorId> externalPorts = new HashSet<>();
1094         externalPorts.add(new NodeConnectorId(CONNECTOR_0));
1095         externalPorts.add(new NodeConnectorId(CONNECTOR_1));
1096
1097         when(ctx.getEndpointManager()).thenReturn(endpointManager);
1098
1099         flows.createL3PrefixFlow(tableId, 30, gatewayEpBuilder.build(), null, tenant, localSubnet, externalPorts,
1100                 ofWriter);
1101         verify(ctx, times(1)).getEndpointManager();
1102         verifyZeroInteractions(ofWriter);
1103     }
1104
1105     @Test
1106     public void createL3PrefixFlow_internalIpV4() {
1107         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
1108         EndpointBuilder gatewayEp = buildEndpoint(IPV4_0, MAC_0, connectorId);
1109         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
1110         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue()));
1111         gatewayEp.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
1112
1113         EndpointL3PrefixBuilder l3PrefixBuilder = new EndpointL3PrefixBuilder();
1114         l3PrefixBuilder.setIpPrefix(new IpPrefix(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32)));
1115         EndpointL3Prefix l3Prefix = l3PrefixBuilder.build();
1116
1117         IndexedTenant tenant = getTestIndexedTenant();
1118         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
1119         localSubnetBuilder.setId(SUBNET_0);
1120         localSubnetBuilder.setParent(L2FD_ID);
1121         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_0));
1122         Subnet localSubnet = localSubnetBuilder.build();
1123
1124         List<Action> l3ApplyActions = new ArrayList<>();
1125         l3ApplyActions.add(setDlDstAction(MAC_0));
1126         l3ApplyActions.add(decNwTtlAction());
1127         List<Action> applyActions = new ArrayList<>();
1128         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
1129         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
1130         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(1)));
1131         applyActions.addAll(l3ApplyActions);
1132         Instruction applyActionsIns = new InstructionBuilder().setOrder(0)
1133                 .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
1134                 .build();
1135         Instruction gotoTable = new InstructionBuilder().setOrder(1)
1136                 .setInstruction(gotoTableIns(tableId))
1137                 .build();
1138         ArrayList<Instruction> l3instructions = new ArrayList<>();
1139         l3instructions.add(applyActionsIns);
1140         l3instructions.add(gotoTable);
1141         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
1142         instructionsBuilder.setInstruction(l3instructions);
1143
1144         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null,
1145                 DestinationMapper.ROUTER_MAC, IPv4));
1146         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
1147         Match match = matchBuilder.build();
1148
1149         Integer prefixLength = Integer.valueOf(l3Prefix.getIpPrefix().getIpv4Prefix().getValue().split("/")[1]);
1150         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "L3prefix", match), tableId, 30 + prefixLength, match,
1151                 instructionsBuilder.build()).build();
1152
1153         when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
1154         when(ctx.getEndpointManager()).thenReturn(endpointManager);
1155         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
1156
1157         flows.createL3PrefixFlow(tableId, 30, gatewayEp.build(), l3Prefix, tenant, localSubnet, null,
1158                 ofWriter);
1159         verify(ctx, times(3)).getTenant(any(TenantId.class));
1160         verify(ctx, times(2)).getEndpointManager();
1161         verify(ctx, times(1)).getCurrentPolicy();
1162         verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow));
1163     }
1164
1165     @Test
1166     public void createL3PrefixFlow_externalIpv6() throws Exception {
1167         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
1168         EndpointBuilder gatewayEpBuilder = buildEndpoint(IPV6_1, MAC_0, connectorId);
1169         gatewayEpBuilder.setNetworkContainment(SUBNET_0);
1170
1171         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
1172         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(OPENFLOW + CONNECTOR_1));
1173         gatewayEpBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
1174         gatewayEpBuilder.setEndpointGroup(ENDPOINT_GROUP_0);
1175
1176         TenantBuilder tenantBuilder = new TenantBuilder(getTestIndexedTenant().getTenant());
1177         List<ExternalImplicitGroup> externalImplicitGroups = new ArrayList<>();
1178         ExternalImplicitGroupBuilder externalImplicitGroupBuilder = new ExternalImplicitGroupBuilder();
1179         externalImplicitGroupBuilder.setId(ENDPOINT_GROUP_0);
1180         externalImplicitGroups.add(externalImplicitGroupBuilder.build());
1181         tenantBuilder.setPolicy(new PolicyBuilder().setExternalImplicitGroup(externalImplicitGroups).build());
1182         IndexedTenant tenant = new IndexedTenant(tenantBuilder.build());
1183
1184         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
1185         localSubnetBuilder.setId(SUBNET_0);
1186         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV6_2));
1187         localSubnetBuilder.setParent(L2FD_ID);
1188         Subnet localSubnet = localSubnetBuilder.build();
1189
1190         Set<NodeConnectorId> externalPorts = new HashSet<>();
1191         externalPorts.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()));
1192         externalPorts.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue()));
1193
1194         EndpointL3PrefixBuilder l3PrefixBuilder = new EndpointL3PrefixBuilder();
1195         l3PrefixBuilder.setIpPrefix(new IpPrefix(new Ipv6Prefix(IPV6_1.getValue() + IP_PREFIX_128)));
1196         EndpointL3Prefix l3Prefix = l3PrefixBuilder.build();
1197
1198         List<Action> l3ApplyActions = new ArrayList<>();
1199         l3ApplyActions.add(setDlDstAction(MAC_0));
1200         l3ApplyActions.add(decNwTtlAction());
1201         List<Action> applyActions = new ArrayList<>();
1202         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
1203         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
1204         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
1205         applyActions.addAll(l3ApplyActions);
1206         Instruction applyActionsIns = new InstructionBuilder().setOrder(0)
1207                 .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
1208                 .build();
1209         Instruction gotoTable = new InstructionBuilder().setOrder(1)
1210                 .setInstruction(gotoTableIns(tableId))
1211                 .build();
1212         ArrayList<Instruction> l3instructions = new ArrayList<>();
1213         l3instructions.add(applyActionsIns);
1214         l3instructions.add(gotoTable);
1215         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
1216         instructionsBuilder.setInstruction(l3instructions);
1217
1218         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null,
1219                 DestinationMapper.ROUTER_MAC, IPv6));
1220         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
1221         Match match = matchBuilder.build();
1222
1223         Integer prefixLength = Integer.valueOf(l3Prefix.getIpPrefix().getIpv6Prefix().getValue().split("/")[1]);
1224         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "L3prefix", match), tableId, 30 + prefixLength, match,
1225                 instructionsBuilder.build()).build();
1226
1227         when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
1228         when(ctx.getEndpointManager()).thenReturn(endpointManager);
1229         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
1230
1231         flows.createL3PrefixFlow(tableId, 30, gatewayEpBuilder.build(), l3Prefix, tenant, localSubnet, externalPorts,
1232                 ofWriter);
1233
1234         verify(ctx, times(6)).getTenant(any(TenantId.class));
1235         verify(ctx, times(3)).getEndpointManager();
1236         verify(ctx, times(2)).getCurrentPolicy();
1237         verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow));
1238     }
1239
1240     private void resetPolicyOrdinalCounterValue() throws  Exception {
1241         // TODO find better way, maybe fixed test method order?
1242         Field field = OrdinalFactory.class.getDeclaredField("policyOrdinal");
1243         field.setAccessible(true);
1244         field.set(null, new AtomicInteger(1));
1245     }
1246 }