Added range type to subject-feature-definition/parameter
[groupbasedpolicy.git] / groupbasedpolicy / src / test / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / flow / DestinationMapperTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
10
11 import java.math.BigInteger;
12 import java.util.Collections;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Objects;
16
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.mockito.ArgumentCaptor;
20 import org.mockito.Matchers;
21 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 import com.google.common.collect.ImmutableList;
47
48 import static org.junit.Assert.*;
49
50 import static org.mockito.Matchers.*;
51
52 import static org.mockito.Mockito.*;
53
54 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
55
56 public class DestinationMapperTest extends FlowTableTest {
57     protected static final Logger LOG =
58             LoggerFactory.getLogger(DestinationMapperTest.class);
59
60     NodeConnectorId remoteTunnelId =
61             new NodeConnectorId(remoteNodeId.getValue() + ":101");
62
63     @Override
64     @Before
65     public void setup() throws Exception {
66         initCtx();
67         table = new DestinationMapper(ctx);
68         super.setup();
69     }
70
71     @Test
72     public void testNoEps() throws Exception {
73         ReadWriteTransaction t = dosync(null);
74         verify(t, times(1)).put(any(LogicalDatastoreType.class),
75                                 Matchers.<InstanceIdentifier<Flow>>any(),
76                                 any(Flow.class), anyBoolean());
77     }
78
79     private void verifyDMap(Endpoint remoteEp,
80                             Endpoint localEp) throws Exception {
81
82         ReadWriteTransaction t = dosync(null);
83         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
84         verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION),
85                                      Matchers.<InstanceIdentifier<Flow>>any(),
86                                      ac.capture(), anyBoolean());
87
88         int count = 0;
89         HashMap<String, FlowCtx> flowMap = new HashMap<>();
90         for (Flow f : ac.getAllValues()) {
91             flowMap.put(f.getId().getValue(), new FlowCtx(f));
92             if (f.getMatch() == null) {
93                 assertEquals(dropInstructions(),
94                              f.getInstructions());
95                 count += 1;
96             } else if (Objects.equals(ethernetMatch(null, null, ARP),
97                                       f.getMatch().getEthernetMatch())) {
98                 // router ARP reply
99                 Instruction ins = f.getInstructions().getInstruction().get(0);
100                 ins = f.getInstructions().getInstruction().get(0);
101                 assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
102                 List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
103                 assertEquals(nxMoveEthSrcToEthDstAction(),
104                              actions.get(0).getAction());
105                 assertEquals(Integer.valueOf(0), actions.get(0).getOrder());
106                 assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC),
107                              actions.get(1).getAction());
108                 assertEquals(Integer.valueOf(1), actions.get(1).getOrder());
109                 assertEquals(nxLoadArpOpAction(BigInteger.valueOf(2L)),
110                              actions.get(2).getAction());
111                 assertEquals(Integer.valueOf(2), actions.get(2).getOrder());
112                 assertEquals(nxMoveArpShaToArpThaAction(),
113                              actions.get(3).getAction());
114                 assertEquals(Integer.valueOf(3), actions.get(3).getOrder());
115                 assertEquals(nxLoadArpShaAction(new BigInteger(1, DestinationMapper
116                                                                .bytesFromHexString(DestinationMapper.ROUTER_MAC
117                                                                                    .getValue()))),
118                              actions.get(4).getAction());
119                 assertEquals(Integer.valueOf(4), actions.get(4).getOrder());
120                 assertEquals(nxMoveArpSpaToArpTpaAction(),
121                              actions.get(5).getAction());
122                 assertEquals(Integer.valueOf(5), actions.get(5).getOrder());
123                 assertTrue(nxLoadArpSpaAction("10.0.0.1").equals(actions.get(6).getAction()) ||
124                            nxLoadArpSpaAction("10.0.1.1").equals(actions.get(6).getAction()) ||
125                            nxLoadArpSpaAction("10.0.2.1").equals(actions.get(6).getAction()));
126                 assertEquals(Integer.valueOf(6), actions.get(6).getOrder());
127                 count += 1;
128             } else if (Objects.equals(localEp.getMacAddress(),
129                                f.getMatch().getEthernetMatch()
130                                    .getEthernetDestination().getAddress())) {
131                 int icount = 0;
132                 for (Instruction ins : f.getInstructions().getInstruction()) {
133                     if (ins.getInstruction() instanceof ApplyActionsCase) {
134                         long p = OfTable.getOfPortNum(nodeConnectorId);
135                         List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
136                         assertEquals(nxLoadRegAction(NxmNxReg7.class,
137                                                      BigInteger.valueOf(p)),
138                                      actions.get(2).getAction());
139                         icount += 1;
140                     } else if (ins.getInstruction() instanceof GoToTableCase) {
141                         assertEquals(gotoTableIns((short)(table.getTableId()+1)),
142                                      ins.getInstruction());
143                         icount += 1;
144                     }
145                 }
146                 assertEquals(2, icount);
147                 LOG.info("{}", f);
148                 count += 1;
149             } else if (Objects.equals(remoteEp.getMacAddress(),
150                                       f.getMatch().getEthernetMatch()
151                                       .getEthernetDestination().getAddress())) {
152                 int icount = 0;
153                 for (Instruction ins : f.getInstructions().getInstruction()) {
154                     if (ins.getInstruction() instanceof ApplyActionsCase) {
155                         long p = OfTable.getOfPortNum(tunnelId);
156                         List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
157                         assertEquals(nxLoadRegAction(NxmNxReg7.class,
158                                                      BigInteger.valueOf(p)),
159                                      actions.get(4).getAction());
160                         icount += 1;
161                     } else if (ins.getInstruction() instanceof GoToTableCase) {
162                         assertEquals(gotoTableIns((short)(table.getTableId()+1)),
163                                      ins.getInstruction());
164                         icount += 1;
165                     }
166                 }
167                 assertEquals(2, icount);
168                 LOG.info("{}", f);
169                 count += 1;
170             } else if (Objects.equals(DestinationMapper.ROUTER_MAC,
171                                       f.getMatch().getEthernetMatch()
172                                           .getEthernetDestination()
173                                           .getAddress())) {
174                 if (f.getMatch().getLayer3Match() instanceof Ipv4Match) {
175                     // should be local port with rewrite dlsrc and dldst plus
176                     // ttl decr
177                     Instruction ins = f.getInstructions().getInstruction().get(0);
178                     assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
179                     List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
180                     long p = OfTable.getOfPortNum(nodeConnectorId);
181                     assertEquals(nxLoadRegAction(NxmNxReg7.class,
182                                                  BigInteger.valueOf(p)),
183                                  actions.get(2).getAction());
184                     assertEquals(Integer.valueOf(2), actions.get(2).getOrder());
185                     assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC),
186                                  actions.get(3).getAction());
187                     assertEquals(Integer.valueOf(3), actions.get(3).getOrder());
188                     assertEquals(setDlDstAction(localEp.getMacAddress()),
189                                  actions.get(4).getAction());
190                     assertEquals(Integer.valueOf(4), actions.get(4).getOrder());
191                     assertEquals(decNwTtlAction(),
192                                  actions.get(5).getAction());
193                     assertEquals(Integer.valueOf(5), actions.get(5).getOrder());
194                     count += 1;
195                 } else if (f.getMatch().getLayer3Match() instanceof Ipv6Match) {
196                     // should be remote port with rewrite dlsrc plus
197                     // ttl decr
198                     Instruction ins = f.getInstructions().getInstruction().get(0);
199                     assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
200                     List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
201                     long p = OfTable.getOfPortNum(tunnelId);
202                     assertEquals(nxLoadRegAction(NxmNxReg7.class,
203                                                  BigInteger.valueOf(p)),
204                                  actions.get(4).getAction());
205                     assertEquals(Integer.valueOf(4), actions.get(4).getOrder());
206                     assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC),
207                                  actions.get(5).getAction());
208                     assertEquals(Integer.valueOf(5), actions.get(5).getOrder());
209                     assertEquals(decNwTtlAction(),
210                                  actions.get(6).getAction());
211                     assertEquals(Integer.valueOf(6), actions.get(6).getOrder());
212                     count += 1;
213                 }
214             } else if (Objects.equals(DestinationMapper.MULTICAST_MAC,
215                                       f.getMatch().getEthernetMatch()
216                                       .getEthernetDestination()
217                                       .getAddress())) {
218                 // broadcast/multicast flow should output to group table
219                 Instruction ins = f.getInstructions().getInstruction().get(0);
220                 ins = f.getInstructions().getInstruction().get(0);
221                 assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
222                 List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
223                 assertEquals(nxMoveRegTunIdAction(NxmNxReg0.class, false),
224                              actions.get(0).getAction());
225                 assertEquals(Integer.valueOf(0), actions.get(0).getOrder());
226                 Long v = Long.valueOf(policyManager.getContextOrdinal(tid, fd));
227                 assertEquals(groupAction(v), actions.get(1).getAction());
228                 assertEquals(Integer.valueOf(1), actions.get(1).getOrder());
229                 count += 1;
230             }
231         }
232
233         //This assertion no longer holds true, due to GroupTable=null in TestFlow pipeline and
234         // DestinationMapper now checking for GroupTable entries. Flows will not be written.
235         // TODO: alagalah to resolve correct unit tests.
236         //        assertEquals(9, count);
237         assertEquals(8, count);
238
239         t = dosync(flowMap);
240         verify(t, never()).put(any(LogicalDatastoreType.class),
241                                Matchers.<InstanceIdentifier<Flow>>any(),
242                                any(Flow.class), anyBoolean());
243     }
244
245     @Override
246     protected EndpointBuilder localEP() {
247         return super.localEP()
248             .setL3Address(ImmutableList.of(new L3AddressBuilder()
249                 .setL3Context(l3c)
250                 .setIpAddress(new IpAddress(new Ipv4Address("10.0.0.1")))
251                 .build()));
252     }
253     @Override
254     protected EndpointBuilder remoteEP(NodeId remoteNodeId) {
255         return super.remoteEP(remoteNodeId)
256             .setL3Address(ImmutableList.of(new L3AddressBuilder()
257                 .setL3Context(l3c)
258                 .setIpAddress(new IpAddress(new Ipv6Address("::ffff:0:0::10.0.0.2")))
259                 .build()));
260     }
261
262     private void addSwitches() {
263         switchManager.addSwitch(nodeId, tunnelId,
264                                 Collections.<NodeConnectorId>emptySet(),
265                                 new OfOverlayNodeConfigBuilder()
266                                     .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.4")))
267                                     .build());
268         switchManager.addSwitch(remoteNodeId, remoteTunnelId,
269                                 Collections.<NodeConnectorId>emptySet(),
270                                 new OfOverlayNodeConfigBuilder()
271                                     .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.5")))
272                                     .build());
273     }
274
275     @Test
276     public void testSame() throws Exception {
277         Endpoint localEp = localEP().build();
278         endpointManager.addEndpoint(localEp);
279         Endpoint remoteEp = remoteEP(remoteNodeId).build();
280         endpointManager.addEndpoint(remoteEp);
281         addSwitches();
282
283         policyResolver.addTenant(baseTenant().build());
284         verifyDMap(remoteEp, localEp);
285     }
286
287     @Test
288     public void testDiff() throws Exception {
289         Endpoint localEp = localEP().build();
290         endpointManager.addEndpoint(localEp);
291         Endpoint remoteEp = remoteEP(remoteNodeId)
292             .setEndpointGroup(eg2)
293             .build();
294         endpointManager.addEndpoint(remoteEp);
295         addSwitches();
296
297         policyResolver.addTenant(baseTenant().build());
298         verifyDMap(remoteEp, localEp);
299     }
300
301 }