blob: 1647c8ee3fbe751aeff0d993461030bf0528aaaa [file] [log] [blame]
Ray Milkeyd03eda02015-01-09 14:58:48 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Ray Milkeyd03eda02015-01-09 14:58:48 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.codec.impl;
17
Frank Wang74ce2c12018-04-11 20:26:45 +080018import com.fasterxml.jackson.databind.JsonNode;
Jian Li11260a02016-05-19 13:07:22 -070019import com.fasterxml.jackson.databind.node.ObjectNode;
Frank Wang74ce2c12018-04-11 20:26:45 +080020import org.hamcrest.MatcherAssert;
21import org.junit.Assert;
Ray Milkeyd03eda02015-01-09 14:58:48 -080022import org.junit.Before;
23import org.junit.Test;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080024import org.onlab.packet.Ip4Address;
25import org.onlab.packet.Ip6Address;
Ray Milkeyd03eda02015-01-09 14:58:48 -080026import org.onlab.packet.MacAddress;
Michele Santuari4b6019e2014-12-19 11:31:45 +010027import org.onlab.packet.MplsLabel;
Ray Milkeyd03eda02015-01-09 14:58:48 -080028import org.onlab.packet.VlanId;
Frank Wang74ce2c12018-04-11 20:26:45 +080029import org.onlab.util.ImmutableByteSequence;
Ray Milkeyd03eda02015-01-09 14:58:48 -080030import org.onosproject.codec.CodecContext;
31import org.onosproject.codec.JsonCodec;
Sho SHIMIZUed7af542015-05-05 19:10:45 -070032import org.onosproject.net.ChannelSpacing;
33import org.onosproject.net.GridType;
34import org.onosproject.net.Lambda;
Yafit Hadar5796d972015-10-15 13:16:11 +030035import org.onosproject.net.OduSignalId;
Ray Milkeyd03eda02015-01-09 14:58:48 -080036import org.onosproject.net.PortNumber;
37import org.onosproject.net.flow.instructions.Instruction;
38import org.onosproject.net.flow.instructions.Instructions;
39import org.onosproject.net.flow.instructions.L0ModificationInstruction;
Yafit Hadar5796d972015-10-15 13:16:11 +030040import org.onosproject.net.flow.instructions.L1ModificationInstruction;
Ray Milkeyd03eda02015-01-09 14:58:48 -080041import org.onosproject.net.flow.instructions.L2ModificationInstruction;
42import org.onosproject.net.flow.instructions.L3ModificationInstruction;
Frank Wang74ce2c12018-04-11 20:26:45 +080043import org.onosproject.net.flow.instructions.PiInstruction;
44import org.onosproject.net.pi.model.PiActionId;
45import org.onosproject.net.pi.model.PiActionParamId;
46import org.onosproject.net.pi.runtime.PiAction;
Frank Wang74ce2c12018-04-11 20:26:45 +080047import org.onosproject.net.pi.runtime.PiActionParam;
Carmelo Casconecb4327a2018-09-11 15:17:23 -070048import org.onosproject.net.pi.runtime.PiActionProfileGroupId;
49import org.onosproject.net.pi.runtime.PiActionProfileMemberId;
Frank Wang74ce2c12018-04-11 20:26:45 +080050import org.onosproject.net.pi.runtime.PiTableAction;
51
52import java.io.IOException;
53import java.io.InputStream;
54import java.util.Collection;
Ray Milkeyd03eda02015-01-09 14:58:48 -080055
Jian Li11260a02016-05-19 13:07:22 -070056import static org.hamcrest.MatcherAssert.assertThat;
Frank Wang74ce2c12018-04-11 20:26:45 +080057import static org.hamcrest.Matchers.is;
Jian Li11260a02016-05-19 13:07:22 -070058import static org.hamcrest.Matchers.notNullValue;
Frank Wang74ce2c12018-04-11 20:26:45 +080059import static org.onlab.util.ImmutableByteSequence.copyFrom;
Jian Li11260a02016-05-19 13:07:22 -070060import static org.onosproject.codec.impl.InstructionJsonMatcher.matchesInstruction;
Ray Milkeyd03eda02015-01-09 14:58:48 -080061
Ray Milkeyd03eda02015-01-09 14:58:48 -080062/**
63 * Unit tests for Instruction codec.
64 */
65public class InstructionCodecTest {
66 CodecContext context;
67 JsonCodec<Instruction> instructionCodec;
Ray Milkeyd03eda02015-01-09 14:58:48 -080068 /**
Ray Milkeydb358082015-01-13 16:34:38 -080069 * Sets up for each test. Creates a context and fetches the instruction
Ray Milkeyd03eda02015-01-09 14:58:48 -080070 * codec.
71 */
72 @Before
73 public void setUp() {
74 context = new MockCodecContext();
75 instructionCodec = context.codec(Instruction.class);
76 assertThat(instructionCodec, notNullValue());
77 }
78
79 /**
Jian Li11260a02016-05-19 13:07:22 -070080 * Tests the encoding of push mpls header instructions.
Ray Milkeyd03eda02015-01-09 14:58:48 -080081 */
82 @Test
83 public void pushHeaderInstructionsTest() {
Jian Li11260a02016-05-19 13:07:22 -070084 final L2ModificationInstruction.ModMplsHeaderInstruction instruction =
85 (L2ModificationInstruction.ModMplsHeaderInstruction) Instructions.pushMpls();
Ray Milkeyd03eda02015-01-09 14:58:48 -080086 final ObjectNode instructionJson = instructionCodec.encode(instruction, context);
87
88 assertThat(instructionJson, matchesInstruction(instruction));
89 }
90
91 /**
Ray Milkeyd03eda02015-01-09 14:58:48 -080092 * Tests the encoding of output instructions.
93 */
94 @Test
95 public void outputInstructionTest() {
96 final Instructions.OutputInstruction instruction =
97 Instructions.createOutput(PortNumber.portNumber(22));
98 final ObjectNode instructionJson =
99 instructionCodec.encode(instruction, context);
100 assertThat(instructionJson, matchesInstruction(instruction));
101 }
102
103 /**
Sho SHIMIZUed7af542015-05-05 19:10:45 -0700104 * Tests the encoding of mod OCh signal instructions.
105 */
106 @Test
107 public void modOchSignalInstructionTest() {
108 L0ModificationInstruction.ModOchSignalInstruction instruction =
109 (L0ModificationInstruction.ModOchSignalInstruction)
110 Instructions.modL0Lambda(Lambda.ochSignal(GridType.DWDM, ChannelSpacing.CHL_100GHZ, 4, 8));
111 ObjectNode instructionJson =
112 instructionCodec.encode(instruction, context);
113 assertThat(instructionJson, matchesInstruction(instruction));
114 }
115
116 /**
Yafit Hadar5796d972015-10-15 13:16:11 +0300117 * Tests the encoding of mod ODU signal ID instructions.
118 */
119 @Test
120 public void modOduSignalIdInstructionTest() {
Jian Li68c4fc42016-01-11 16:07:03 -0800121 OduSignalId oduSignalId = OduSignalId.oduSignalId(1, 8, new byte[] {8, 0, 0, 0, 0, 0, 0, 0, 0, 0});
Yafit Hadar5796d972015-10-15 13:16:11 +0300122 L1ModificationInstruction.ModOduSignalIdInstruction instruction =
123 (L1ModificationInstruction.ModOduSignalIdInstruction)
124 Instructions.modL1OduSignalId(oduSignalId);
125 ObjectNode instructionJson =
126 instructionCodec.encode(instruction, context);
127 assertThat(instructionJson, matchesInstruction(instruction));
128 }
129
130 /**
Ray Milkeyd03eda02015-01-09 14:58:48 -0800131 * Tests the encoding of mod ether instructions.
132 */
133 @Test
134 public void modEtherInstructionTest() {
135 final L2ModificationInstruction.ModEtherInstruction instruction =
136 (L2ModificationInstruction.ModEtherInstruction)
137 Instructions.modL2Src(MacAddress.valueOf("11:22:33:44:55:66"));
138 final ObjectNode instructionJson =
139 instructionCodec.encode(instruction, context);
140 assertThat(instructionJson, matchesInstruction(instruction));
141 }
142
143 /**
144 * Tests the encoding of mod vlan id instructions.
145 */
146 @Test
147 public void modVlanIdInstructionTest() {
148 final L2ModificationInstruction.ModVlanIdInstruction instruction =
149 (L2ModificationInstruction.ModVlanIdInstruction)
150 Instructions.modVlanId(VlanId.vlanId((short) 12));
151
152 final ObjectNode instructionJson =
153 instructionCodec.encode(instruction, context);
154 assertThat(instructionJson, matchesInstruction(instruction));
155 }
156
157 /**
158 * Tests the encoding of mod vlan pcp instructions.
159 */
160 @Test
161 public void modVlanPcpInstructionTest() {
162 final L2ModificationInstruction.ModVlanPcpInstruction instruction =
163 (L2ModificationInstruction.ModVlanPcpInstruction)
164 Instructions.modVlanPcp((byte) 9);
165 final ObjectNode instructionJson =
166 instructionCodec.encode(instruction, context);
167 assertThat(instructionJson, matchesInstruction(instruction));
168 }
169
170 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800171 * Tests the encoding of mod IPv4 src instructions.
Ray Milkeyd03eda02015-01-09 14:58:48 -0800172 */
173 @Test
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800174 public void modIPSrcInstructionTest() {
175 final Ip4Address ip = Ip4Address.valueOf("1.2.3.4");
Ray Milkeyd03eda02015-01-09 14:58:48 -0800176 final L3ModificationInstruction.ModIPInstruction instruction =
177 (L3ModificationInstruction.ModIPInstruction)
178 Instructions.modL3Src(ip);
179 final ObjectNode instructionJson =
180 instructionCodec.encode(instruction, context);
181 assertThat(instructionJson, matchesInstruction(instruction));
182 }
183
184 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800185 * Tests the encoding of mod IPv4 dst instructions.
186 */
187 @Test
188 public void modIPDstInstructionTest() {
189 final Ip4Address ip = Ip4Address.valueOf("1.2.3.4");
190 final L3ModificationInstruction.ModIPInstruction instruction =
191 (L3ModificationInstruction.ModIPInstruction)
192 Instructions.modL3Dst(ip);
193 final ObjectNode instructionJson =
194 instructionCodec.encode(instruction, context);
195 assertThat(instructionJson, matchesInstruction(instruction));
196 }
197
198 /**
199 * Tests the encoding of mod IPv6 src instructions.
200 */
201 @Test
202 public void modIPv6SrcInstructionTest() {
203 final Ip6Address ip = Ip6Address.valueOf("1111::2222");
204 final L3ModificationInstruction.ModIPInstruction instruction =
205 (L3ModificationInstruction.ModIPInstruction)
206 Instructions.modL3IPv6Src(ip);
207 final ObjectNode instructionJson =
208 instructionCodec.encode(instruction, context);
209 assertThat(instructionJson, matchesInstruction(instruction));
210 }
211
212 /**
213 * Tests the encoding of mod IPv6 dst instructions.
214 */
215 @Test
216 public void modIPv6DstInstructionTest() {
217 final Ip6Address ip = Ip6Address.valueOf("1111::2222");
218 final L3ModificationInstruction.ModIPInstruction instruction =
219 (L3ModificationInstruction.ModIPInstruction)
220 Instructions.modL3IPv6Dst(ip);
221 final ObjectNode instructionJson =
222 instructionCodec.encode(instruction, context);
223 assertThat(instructionJson, matchesInstruction(instruction));
224 }
225
226 /**
227 * Tests the encoding of mod IPv6 flow label instructions.
228 */
229 @Test
230 public void modIPv6FlowLabelInstructionTest() {
231 final int flowLabel = 0xfffff;
232 final L3ModificationInstruction.ModIPv6FlowLabelInstruction instruction =
233 (L3ModificationInstruction.ModIPv6FlowLabelInstruction)
234 Instructions.modL3IPv6FlowLabel(flowLabel);
235 final ObjectNode instructionJson =
236 instructionCodec.encode(instruction, context);
237 assertThat(instructionJson, matchesInstruction(instruction));
238 }
239
240 /**
Ray Milkeyd03eda02015-01-09 14:58:48 -0800241 * Tests the encoding of mod MPLS label instructions.
242 */
243 @Test
244 public void modMplsLabelInstructionTest() {
245 final L2ModificationInstruction.ModMplsLabelInstruction instruction =
246 (L2ModificationInstruction.ModMplsLabelInstruction)
Michele Santuari4b6019e2014-12-19 11:31:45 +0100247 Instructions.modMplsLabel(MplsLabel.mplsLabel(99));
Ray Milkeyd03eda02015-01-09 14:58:48 -0800248 final ObjectNode instructionJson =
249 instructionCodec.encode(instruction, context);
250 assertThat(instructionJson, matchesInstruction(instruction));
251 }
252
Frank Wang74ce2c12018-04-11 20:26:45 +0800253 /**
254 * Tests the encoding of protocol-independent instructions.
255 */
256 @Test
257 public void piInstructionEncodingTest() {
258 PiActionId actionId = PiActionId.of("set_egress_port");
259 PiActionParamId actionParamId = PiActionParamId.of("port");
260 PiActionParam actionParam = new PiActionParam(actionParamId, ImmutableByteSequence.copyFrom(10));
261 PiTableAction action = PiAction.builder().withId(actionId).withParameter(actionParam).build();
262 final PiInstruction actionInstruction = Instructions.piTableAction(action);
263 final ObjectNode actionInstructionJson =
264 instructionCodec.encode(actionInstruction, context);
265 assertThat(actionInstructionJson, matchesInstruction(actionInstruction));
266
Carmelo Casconecb4327a2018-09-11 15:17:23 -0700267 PiTableAction actionGroupId = PiActionProfileGroupId.of(10);
Frank Wang74ce2c12018-04-11 20:26:45 +0800268 final PiInstruction actionGroupIdInstruction = Instructions.piTableAction(actionGroupId);
269 final ObjectNode actionGroupIdInstructionJson =
270 instructionCodec.encode(actionGroupIdInstruction, context);
271 assertThat(actionGroupIdInstructionJson, matchesInstruction(actionGroupIdInstruction));
272
Carmelo Casconecb4327a2018-09-11 15:17:23 -0700273 PiTableAction actionProfileMemberId = PiActionProfileMemberId.of(10);
274 final PiInstruction actionProfileMemberIdInstruction = Instructions.piTableAction(actionProfileMemberId);
275 final ObjectNode actionProfileMemberIdInstructionJson =
276 instructionCodec.encode(actionProfileMemberIdInstruction, context);
277 assertThat(actionProfileMemberIdInstructionJson, matchesInstruction(actionProfileMemberIdInstruction));
Frank Wang74ce2c12018-04-11 20:26:45 +0800278 }
279
280 /**
281 * Tests the decoding of protocol-independent instructions.
282 */
283 @Test
284 public void piInstructionDecodingTest() throws IOException {
285
286 Instruction actionInstruction = getInstruction("PiActionInstruction.json");
287 Assert.assertThat(actionInstruction.type(), is(Instruction.Type.PROTOCOL_INDEPENDENT));
288 PiTableAction action = ((PiInstruction) actionInstruction).action();
289 Assert.assertThat(action.type(), is(PiTableAction.Type.ACTION));
290 Assert.assertThat(((PiAction) action).id().id(), is("set_egress_port"));
291 Assert.assertThat(((PiAction) action).parameters().size(), is(1));
292 Collection<PiActionParam> actionParams = ((PiAction) action).parameters();
293 PiActionParam actionParam = actionParams.iterator().next();
294 Assert.assertThat(actionParam.id().id(), is("port"));
295 Assert.assertThat(actionParam.value(), is(copyFrom((byte) 0x1)));
296
Carmelo Casconecb4327a2018-09-11 15:17:23 -0700297 Instruction actionGroupIdInstruction = getInstruction("PiActionProfileGroupIdInstruction.json");
Frank Wang74ce2c12018-04-11 20:26:45 +0800298 Assert.assertThat(actionInstruction.type(), is(Instruction.Type.PROTOCOL_INDEPENDENT));
299 PiTableAction actionGroupId = ((PiInstruction) actionGroupIdInstruction).action();
Carmelo Casconecb4327a2018-09-11 15:17:23 -0700300 Assert.assertThat(actionGroupId.type(), is(PiTableAction.Type.ACTION_PROFILE_GROUP_ID));
301 Assert.assertThat(((PiActionProfileGroupId) actionGroupId).id(), is(100));
Frank Wang74ce2c12018-04-11 20:26:45 +0800302
Carmelo Casconecb4327a2018-09-11 15:17:23 -0700303 Instruction actionMemberIdInstruction = getInstruction("PiActionProfileMemberIdInstruction.json");
Frank Wang74ce2c12018-04-11 20:26:45 +0800304 Assert.assertThat(actionInstruction.type(), is(Instruction.Type.PROTOCOL_INDEPENDENT));
305 PiTableAction actionMemberId = ((PiInstruction) actionMemberIdInstruction).action();
Carmelo Casconecb4327a2018-09-11 15:17:23 -0700306 Assert.assertThat(actionMemberId.type(), is(PiTableAction.Type.ACTION_PROFILE_MEMBER_ID));
307 Assert.assertThat(((PiActionProfileMemberId) actionMemberId).id(), is(100));
Frank Wang74ce2c12018-04-11 20:26:45 +0800308 }
309
310 /**
311 * Reads in an instruction from the given resource and decodes it.
312 *
313 * @param resourceName resource to use to read the JSON for the rule
314 * @return decoded instruction
315 * @throws IOException if processing the resource fails
316 */
317 private Instruction getInstruction(String resourceName) throws IOException {
318 InputStream jsonStream = InstructionCodecTest.class.getResourceAsStream(resourceName);
319 JsonNode json = context.mapper().readTree(jsonStream);
320 MatcherAssert.assertThat(json, notNullValue());
321 Instruction instruction = instructionCodec.decode((ObjectNode) json, context);
322 Assert.assertThat(instruction, notNullValue());
323 return instruction;
324 }
325
Ray Milkeyd03eda02015-01-09 14:58:48 -0800326}