Bug 5540 - MeterStatsResponseConvertor, MeterConfigStatsResponseConvertor
[openflowplugin.git] / openflowplugin / src / test / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / match / MatchConvertorImplTest.java
1 /*
2  * Copyright (c) 2014 NEC Corporation 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.openflowplugin.openflow.md.core.sal.convertor.match;
10
11 import static org.junit.Assert.assertEquals;
12
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.List;
16 import org.junit.BeforeClass;
17 import org.junit.Test;
18 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
19 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthDst;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthSrc;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthType;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPort;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmMatchType;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanVid;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthDstCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthSrcCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthTypeCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPortCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanVidCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.dst._case.EthDstBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.src._case.EthSrcBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.type._case.EthTypeBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.in.port._case.InPortBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.vlan.vid._case.VlanVidBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder;
54
55 /**
56  * Unit test for {@link MatchConvertorImpl}.
57  */
58 public class MatchConvertorImplTest {
59     private static final BigInteger DPID = BigInteger.TEN;
60     private static final Long IN_PORT = Long.valueOf(6);
61     private static final String URI_IN_PORT =
62             "openflow:" + DPID + ":" + IN_PORT;
63     private static final MacAddress MAC_SRC =
64             MacAddress.getDefaultInstance("00:11:22:33:44:55");
65     private static final MacAddress MAC_DST =
66             MacAddress.getDefaultInstance("fa:fb:fc:fd:fe:ff");
67     private static final int ETHTYPE_IPV4 = 0x800;
68     private static final short VLAN_PCP = 7;
69     private static final Ipv4Address IPV4_SRC =
70             Ipv4Address.getDefaultInstance("192.168.10.254");
71     private static final Ipv4Address IPV4_DST =
72             Ipv4Address.getDefaultInstance("10.1.2.3");
73
74     private static final int DL_VLAN_NONE = 0xffff;
75
76     @BeforeClass
77     public static void setUp() {
78         OpenflowPortsUtil.init();
79     }
80
81     /**
82      * Test method for {@link MatchConvertorImpl#fromOFMatchToSALMatch(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match, java.math.BigInteger, org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion)}.
83      */
84
85     @Test
86     public void testFromOFMatchToSALMatch() {
87         List<MatchEntry> entries = createDefaultMatchEntry();
88
89         int[] vids = {
90                 // Match packet with VLAN tag regardless of its value.
91                 -1,
92
93                 // Match untagged frame.
94                 0,
95
96                 // Match packet with VLAN tag and VID equals the specified value.
97                 1, 20, 4095,
98         };
99
100         for (int vid : vids) {
101             List<MatchEntry> MatchEntry =
102                     new ArrayList<MatchEntry>(entries);
103             MatchEntry.add(toOfVlanVid(vid));
104             org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match ofMatch =
105                     createOFMatch(MatchEntry);
106
107             MatchBuilder builder = MatchConvertorImpl.
108                     fromOFMatchToSALMatch(ofMatch, DPID, OpenflowVersion.OF13);
109             checkDefault(builder);
110             VlanMatch vlanMatch = builder.getVlanMatch();
111             int expectedVid = (vid < 0) ? 0 : vid;
112             Boolean expectedCfi = Boolean.valueOf(vid != 0);
113             assertEquals(expectedVid, vlanMatch.getVlanId().getVlanId().
114                     getValue().intValue());
115             assertEquals(expectedCfi, vlanMatch.getVlanId().isVlanIdPresent());
116             assertEquals(null, vlanMatch.getVlanPcp());
117         }
118     }
119
120     /**
121      * Test method for {@link MatchConvertorImpl#fromOFMatchV10ToSALMatch(MatchV10, BigInteger, OpenflowVersion)}.
122      */
123
124     @Test
125     public void testFromOFMatchV10ToSALMatch() {
126         int[] vids = {
127                 // Match untagged frame.
128                 DL_VLAN_NONE,
129
130                 // Match packet with VLAN tag and VID equals the specified value.
131                 1, 20, 4095,
132         };
133         short[] dscps = {
134                 0, 1, 20, 40, 62, 63,
135         };
136
137         FlowWildcardsV10Builder wcBuilder = new FlowWildcardsV10Builder();
138         for (int vid : vids) {
139             for (short dscp : dscps) {
140                 short tos = (short) (dscp << 2);
141                 MatchV10Builder builder = new MatchV10Builder();
142                 builder.setDlSrc(MAC_SRC).setDlDst(MAC_DST).setDlVlan(vid).
143                         setDlVlanPcp(VLAN_PCP).setDlType(ETHTYPE_IPV4).
144                         setInPort(IN_PORT.intValue()).
145                         setNwSrc(IPV4_SRC).setNwDst(IPV4_DST).setNwTos(tos);
146                 wcBuilder.setAll(false).setNwProto(true).setTpSrc(true).
147                         setTpDst(true);
148                 if (vid == DL_VLAN_NONE) {
149                     wcBuilder.setDlVlanPcp(true);
150                 }
151
152                 FlowWildcardsV10 wc = wcBuilder.build();
153                 MatchV10 ofMatch = builder.setWildcards(wc).build();
154                 Match match = MatchConvertorImpl.fromOFMatchV10ToSALMatch(
155                         ofMatch, DPID, OpenflowVersion.OF10).build();
156                 checkDefaultV10(match, wc, vid);
157
158                 IpMatch ipMatch = match.getIpMatch();
159                 assertEquals(null, ipMatch.getIpProtocol());
160                 assertEquals(dscp, ipMatch.getIpDscp().getValue().shortValue());
161                 assertEquals(null, ipMatch.getIpEcn());
162
163                 // Set all wildcard bits.
164                 wc = wcBuilder.setAll(true).build();
165                 ofMatch = builder.setWildcards(wc).build();
166                 match = MatchConvertorImpl.fromOFMatchV10ToSALMatch(
167                         ofMatch, DPID, OpenflowVersion.OF10).build();
168                 checkDefaultV10(match, wc, vid);
169                 assertEquals(null, match.getIpMatch());
170             }
171         }
172     }
173
174     private static void checkDefault(final MatchBuilder builder) {
175         EthernetMatch ethMatch = builder.getEthernetMatch();
176         assertEquals(MAC_SRC, ethMatch.getEthernetSource().getAddress());
177         assertEquals(null, ethMatch.getEthernetSource().getMask());
178         assertEquals(MAC_DST, ethMatch.getEthernetDestination().getAddress());
179         assertEquals(null, ethMatch.getEthernetDestination().getMask());
180         assertEquals(ETHTYPE_IPV4, ethMatch.getEthernetType().getType().
181                 getValue().intValue());
182
183         NodeConnectorId inPort = builder.getInPort();
184         assertEquals(URI_IN_PORT, inPort.getValue());
185     }
186
187     private static org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match createOFMatch(final List<MatchEntry> entries) {
188         org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder builder =
189                 new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder();
190         return builder.setType(OxmMatchType.class).setMatchEntry(entries).
191                 build();
192     }
193
194     private static List<MatchEntry> createDefaultMatchEntry() {
195         List<MatchEntry> entries = new ArrayList<>();
196         entries.add(toOfPort(InPort.class, IN_PORT));
197
198         MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder();
199         EthSrcCaseBuilder ethSrcCaseBuilder = new EthSrcCaseBuilder();
200
201         EthSrcBuilder ethSrcBuilder = new EthSrcBuilder();
202         ethSrcBuilder.setMacAddress(MAC_SRC);
203         ethSrcCaseBuilder.setEthSrc(ethSrcBuilder.build());
204         matchEntryBuilder.setMatchEntryValue(ethSrcCaseBuilder.build());
205         matchEntryBuilder.setOxmMatchField(EthSrc.class);
206         entries.add(matchEntryBuilder.build());
207
208
209         EthDstCaseBuilder ethDstCaseBuilder = new EthDstCaseBuilder();
210         EthDstBuilder ethDstBuilder = new EthDstBuilder();
211         ethDstBuilder.setMacAddress(MAC_DST);
212         ethDstCaseBuilder.setEthDst(ethDstBuilder.build());
213         matchEntryBuilder.setMatchEntryValue(ethDstCaseBuilder.build());
214         matchEntryBuilder.setOxmMatchField(EthDst.class);
215         entries.add(matchEntryBuilder.build());
216
217         entries.add(toOfEthernetType(ETHTYPE_IPV4));
218         return entries;
219     }
220
221     private static MatchEntry toOfEthernetType(final int ethType) {
222         MatchEntryBuilder builder = new MatchEntryBuilder();
223         builder.setOxmClass(OpenflowBasicClass.class);
224         builder.setHasMask(false);
225         builder.setOxmMatchField(EthType.class);
226         EthTypeCaseBuilder ethTypeCaseBuilder = new EthTypeCaseBuilder();
227         EthTypeBuilder ethTypeBuilder = new EthTypeBuilder();
228         EtherType etherType = new EtherType(ethType);
229         ethTypeBuilder.setEthType(etherType);
230         ethTypeCaseBuilder.setEthType(ethTypeBuilder.build());
231         builder.setMatchEntryValue(ethTypeCaseBuilder.build());
232         return builder.build();
233     }
234
235     private static MatchEntry toOfPort(final Class<? extends MatchField> field,
236                                 final Long portNumber) {
237         MatchEntryBuilder builder = new MatchEntryBuilder();
238         builder.setOxmClass(OpenflowBasicClass.class);
239         builder.setHasMask(false);
240         builder.setOxmMatchField(field);
241         InPortCaseBuilder inPortCaseBuilder = new InPortCaseBuilder();
242         InPortBuilder portBuilder = new InPortBuilder();
243         portBuilder.setPortNumber(new PortNumber(portNumber));
244         inPortCaseBuilder.setInPort(portBuilder.build());
245         builder.setMatchEntryValue(inPortCaseBuilder.build());
246         return builder.build();
247     }
248
249     private static MatchEntry toOfVlanVid(final int vid) {
250         MatchEntryBuilder builder = new MatchEntryBuilder();
251         boolean cfi = true;
252         Integer vidValue = Integer.valueOf(vid);
253         byte[] mask = null;
254         builder.setOxmClass(OpenflowBasicClass.class);
255         builder.setOxmMatchField(VlanVid.class);
256         VlanVidCaseBuilder vlanVidCaseBuilder = new VlanVidCaseBuilder();
257         if (vid == 0) {
258             // Match untagged frame.
259             cfi = false;
260         } else if (vid < 0) {
261             // Match packet with VLAN tag regardless of its value.
262             mask = new byte[]{0x10, 0x00};
263             vidValue = Integer.valueOf(0);
264         }
265
266         VlanVidBuilder vlanVidBuilder = new VlanVidBuilder();
267         vlanVidBuilder.setCfiBit(cfi);
268         vlanVidBuilder.setVlanVid(vidValue);
269         boolean hasMask = mask != null;
270         if (hasMask) {
271             vlanVidBuilder.setMask(mask);
272         }
273         vlanVidCaseBuilder.setVlanVid(vlanVidBuilder.build());
274         builder.setHasMask(hasMask);
275         builder.setMatchEntryValue(vlanVidCaseBuilder.build());
276         return builder.build();
277     }
278
279     private static void checkDefaultV10(final Match match, final FlowWildcardsV10 wc, final int vid) {
280         EthernetMatch ethMatch = match.getEthernetMatch();
281         if (wc.isDLSRC().booleanValue()) {
282             if (ethMatch != null) {
283                 assertEquals(null, ethMatch.getEthernetSource());
284             }
285         } else {
286             assertEquals(MAC_SRC, ethMatch.getEthernetSource().getAddress());
287         }
288
289         if (wc.isDLDST().booleanValue()) {
290             if (ethMatch != null) {
291                 assertEquals(null, ethMatch.getEthernetDestination());
292             }
293         } else {
294             assertEquals(MAC_DST,
295                     ethMatch.getEthernetDestination().getAddress());
296         }
297
298         if (wc.isDLTYPE().booleanValue()) {
299             if (ethMatch != null) {
300                 assertEquals(null, ethMatch.getEthernetType());
301             }
302             assertEquals(null, match.getLayer3Match());
303         } else {
304             assertEquals(ETHTYPE_IPV4, ethMatch.getEthernetType().getType().
305                     getValue().intValue());
306
307             Ipv4Match ipv4Match = (Ipv4Match) match.getLayer3Match();
308             assertEquals(IPV4_SRC.getValue() + "/32",
309                     ipv4Match.getIpv4Source().getValue());
310             assertEquals(IPV4_DST.getValue() + "/32",
311                     ipv4Match.getIpv4Destination().getValue());
312         }
313
314         VlanMatch vlanMatch = match.getVlanMatch();
315         if (wc.isDLVLAN().booleanValue()) {
316             assertEquals(null, vlanMatch);
317         } else {
318             int expectedVid;
319             Boolean expectedCfi;
320             if (vid == DL_VLAN_NONE) {
321                 expectedVid = 0;
322                 expectedCfi = Boolean.FALSE;
323             } else {
324                 expectedVid = vid;
325                 expectedCfi = Boolean.TRUE;
326             }
327             assertEquals(expectedVid, vlanMatch.getVlanId().getVlanId().
328                     getValue().intValue());
329             assertEquals(expectedCfi, vlanMatch.getVlanId().isVlanIdPresent());
330
331             if (wc.isDLVLANPCP().booleanValue()) {
332                 assertEquals(null, vlanMatch.getVlanPcp());
333             } else {
334                 assertEquals(VLAN_PCP,
335                         vlanMatch.getVlanPcp().getValue().shortValue());
336             }
337         }
338     }
339 }