blob: c3cdca0fca662feb2c956cd682f2ade1868b55dc [file] [log] [blame]
Ray Milkeyd03eda02015-01-09 14:58:48 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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
18import org.hamcrest.Description;
Ray Milkeyd03eda02015-01-09 14:58:48 -080019import org.hamcrest.TypeSafeDiagnosingMatcher;
20import org.onosproject.net.flow.instructions.Instruction;
21
22import com.fasterxml.jackson.databind.JsonNode;
23
Ray Milkeyd03eda02015-01-09 14:58:48 -080024import static org.onosproject.net.flow.instructions.Instructions.*;
25import static org.onosproject.net.flow.instructions.L0ModificationInstruction.*;
26import static org.onosproject.net.flow.instructions.L2ModificationInstruction.*;
27import static org.onosproject.net.flow.instructions.L3ModificationInstruction.*;
28
29/**
30 * Hamcrest matcher for instructions.
31 */
Ray Milkeydb358082015-01-13 16:34:38 -080032public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
Ray Milkeyd03eda02015-01-09 14:58:48 -080033
34 private final Instruction instruction;
35
Ray Milkeydb358082015-01-13 16:34:38 -080036 private InstructionJsonMatcher(Instruction instructionValue) {
Ray Milkeyd03eda02015-01-09 14:58:48 -080037 instruction = instructionValue;
38 }
39
40 /**
41 * Matches the contents of a push header instruction.
42 *
43 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080044 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -080045 * @return true if contents match, false otherwise
46 */
47 private boolean matchPushHeaderInstruction(JsonNode instructionJson,
48 Description description) {
49 PushHeaderInstructions instructionToMatch =
50 (PushHeaderInstructions) instruction;
51 final String jsonSubtype = instructionJson.get("subtype").textValue();
52 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
53 description.appendText("subtype was " + jsonSubtype);
54 return false;
55 }
56
57 final String jsonType = instructionJson.get("type").textValue();
58 if (!instructionToMatch.type().name().equals(jsonType)) {
59 description.appendText("type was " + jsonType);
60 return false;
61 }
62
63 final JsonNode ethJson = instructionJson.get("ethernetType");
64 if (ethJson == null) {
65 description.appendText("ethernetType was not null");
66 return false;
67 }
68
alshabib7b808c52015-06-26 14:22:24 -070069 if (instructionToMatch.ethernetType().toShort() != ethJson.asInt()) {
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -080070 description.appendText("ethernetType was " + ethJson);
Ray Milkeyd03eda02015-01-09 14:58:48 -080071 return false;
72 }
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -080073
Ray Milkeyd03eda02015-01-09 14:58:48 -080074 return true;
75 }
76
77 /**
78 * Matches the contents of an output instruction.
79 *
80 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080081 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -080082 * @return true if contents match, false otherwise
83 */
84 private boolean matchOutputInstruction(JsonNode instructionJson,
85 Description description) {
86 OutputInstruction instructionToMatch = (OutputInstruction) instruction;
87
88 final String jsonType = instructionJson.get("type").textValue();
89 if (!instructionToMatch.type().name().equals(jsonType)) {
90 description.appendText("type was " + jsonType);
91 return false;
92 }
93
94 final long jsonPort = instructionJson.get("port").asLong();
95 if (instructionToMatch.port().toLong() != jsonPort) {
96 description.appendText("port was " + jsonPort);
97 return false;
98 }
99
100 return true;
101 }
102
103 /**
104 * Matches the contents of a mod lambda instruction.
105 *
106 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800107 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -0800108 * @return true if contents match, false otherwise
109 */
110 private boolean matchModLambdaInstruction(JsonNode instructionJson,
111 Description description) {
112 ModLambdaInstruction instructionToMatch =
113 (ModLambdaInstruction) instruction;
114 final String jsonSubtype = instructionJson.get("subtype").textValue();
115 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
116 description.appendText("subtype was " + jsonSubtype);
117 return false;
118 }
119
120 final String jsonType = instructionJson.get("type").textValue();
121 if (!instructionToMatch.type().name().equals(jsonType)) {
122 description.appendText("type was " + jsonType);
123 return false;
124 }
125
126 final long jsonLambda = instructionJson.get("lambda").shortValue();
127 if (instructionToMatch.lambda() != jsonLambda) {
128 description.appendText("lambda was " + jsonLambda);
129 return false;
130 }
131
132 return true;
133 }
134
135 /**
Sho SHIMIZUed7af542015-05-05 19:10:45 -0700136 * Matches teh contents of a mod OCh singal instruction.
137 *
138 * @param instructionJson JSON instruction to match
139 * @param description Description object used for recording errors
140 * @return true if contents matches, false otherwise
141 */
142 private boolean matchModOchSingalInstruction(JsonNode instructionJson,
143 Description description) {
144 ModOchSignalInstruction instructionToMatch =
145 (ModOchSignalInstruction) instruction;
146
147 String jsonSubType = instructionJson.get("subtype").textValue();
148 if (!instructionToMatch.subtype().name().equals(jsonSubType)) {
149 description.appendText("subtype was " + jsonSubType);
150 return false;
151 }
152
153 String jsonType = instructionJson.get("type").textValue();
154 if (!instructionToMatch.type().name().equals(jsonType)) {
155 description.appendText("type was " + jsonType);
156 return false;
157 }
158
159 String jsonGridType = instructionJson.get("gridType").textValue();
160 if (!instructionToMatch.lambda().gridType().name().equals(jsonGridType)) {
161 description.appendText("gridType was " + jsonGridType);
162 return false;
163 }
164
165 String jsonChannelSpacing = instructionJson.get("channelSpacing").textValue();
166 if (!instructionToMatch.lambda().channelSpacing().name().equals(jsonChannelSpacing)) {
167 description.appendText("channelSpacing was " + jsonChannelSpacing);
168 return false;
169 }
170
171 int jsonSpacingMultiplier = instructionJson.get("spacingMultiplier").intValue();
172 if (instructionToMatch.lambda().spacingMultiplier() != jsonSpacingMultiplier) {
173 description.appendText("spacingMultiplier was " + jsonSpacingMultiplier);
174 return false;
175 }
176
177 int jsonSlotGranularity = instructionJson.get("slotGranularity").intValue();
178 if (instructionToMatch.lambda().slotGranularity() != jsonSlotGranularity) {
179 description.appendText("slotGranularity was " + jsonSlotGranularity);
180 return false;
181 }
182
183 return true;
184 }
185
186 /**
Ray Milkeydb358082015-01-13 16:34:38 -0800187 * Matches the contents of a mod Ethernet instruction.
Ray Milkeyd03eda02015-01-09 14:58:48 -0800188 *
189 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800190 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -0800191 * @return true if contents match, false otherwise
192 */
193 private boolean matchModEtherInstruction(JsonNode instructionJson,
194 Description description) {
195 ModEtherInstruction instructionToMatch =
196 (ModEtherInstruction) instruction;
197 final String jsonSubtype = instructionJson.get("subtype").textValue();
198 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
199 description.appendText("subtype was " + jsonSubtype);
200 return false;
201 }
202
203 final String jsonType = instructionJson.get("type").textValue();
204 if (!instructionToMatch.type().name().equals(jsonType)) {
205 description.appendText("type was " + jsonType);
206 return false;
207 }
208
209 final String jsonMac = instructionJson.get("mac").textValue();
210 final String mac = instructionToMatch.mac().toString();
211 if (!mac.equals(jsonMac)) {
212 description.appendText("mac was " + jsonMac);
213 return false;
214 }
215
216 return true;
217 }
218
219 /**
220 * Matches the contents of a mod vlan id instruction.
221 *
222 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800223 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -0800224 * @return true if contents match, false otherwise
225 */
226 private boolean matchModVlanIdInstruction(JsonNode instructionJson,
227 Description description) {
228 ModVlanIdInstruction instructionToMatch =
229 (ModVlanIdInstruction) instruction;
230 final String jsonSubtype = instructionJson.get("subtype").textValue();
231 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
232 description.appendText("subtype was " + jsonSubtype);
233 return false;
234 }
235
236 final String jsonType = instructionJson.get("type").textValue();
237 if (!instructionToMatch.type().name().equals(jsonType)) {
238 description.appendText("type was " + jsonType);
239 return false;
240 }
241
242 final short jsonVlanId = instructionJson.get("vlanId").shortValue();
243 final short vlanId = instructionToMatch.vlanId().toShort();
244 if (jsonVlanId != vlanId) {
245 description.appendText("vlan id was " + jsonVlanId);
246 return false;
247 }
248
249 return true;
250 }
251
252 /**
253 * Matches the contents of a mod vlan pcp instruction.
254 *
255 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800256 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -0800257 * @return true if contents match, false otherwise
258 */
259 private boolean matchModVlanPcpInstruction(JsonNode instructionJson,
260 Description description) {
261 ModVlanPcpInstruction instructionToMatch =
262 (ModVlanPcpInstruction) instruction;
263 final String jsonSubtype = instructionJson.get("subtype").textValue();
264 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
265 description.appendText("subtype was " + jsonSubtype);
266 return false;
267 }
268
269 final String jsonType = instructionJson.get("type").textValue();
270 if (!instructionToMatch.type().name().equals(jsonType)) {
271 description.appendText("type was " + jsonType);
272 return false;
273 }
274
275 final short jsonVlanPcp = instructionJson.get("vlanPcp").shortValue();
276 final short vlanId = instructionToMatch.vlanPcp();
277 if (jsonVlanPcp != vlanId) {
278 description.appendText("vlan pcp was " + jsonVlanPcp);
279 return false;
280 }
281
282 return true;
283 }
284
285 /**
286 * Matches the contents of a mod ip instruction.
287 *
288 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800289 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -0800290 * @return true if contents match, false otherwise
291 */
292 private boolean matchModIpInstruction(JsonNode instructionJson,
293 Description description) {
294 ModIPInstruction instructionToMatch =
295 (ModIPInstruction) instruction;
296 final String jsonSubtype = instructionJson.get("subtype").textValue();
297 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
298 description.appendText("subtype was " + jsonSubtype);
299 return false;
300 }
301
302 final String jsonType = instructionJson.get("type").textValue();
303 if (!instructionToMatch.type().name().equals(jsonType)) {
304 description.appendText("type was " + jsonType);
305 return false;
306 }
307
308 final String jsonIp = instructionJson.get("ip").textValue();
309 final String ip = instructionToMatch.ip().toString();
310 if (!ip.equals(jsonIp)) {
311 description.appendText("ip was " + jsonIp);
312 return false;
313 }
314
315 return true;
316 }
317
318 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800319 * Matches the contents of a mod IPv6 Flow Label instruction.
320 *
321 * @param instructionJson JSON instruction to match
322 * @param description Description object used for recording errors
323 * @return true if contents match, false otherwise
324 */
325 private boolean matchModIPv6FlowLabelInstruction(JsonNode instructionJson,
326 Description description) {
327 ModIPv6FlowLabelInstruction instructionToMatch =
328 (ModIPv6FlowLabelInstruction) instruction;
329 final String jsonSubtype = instructionJson.get("subtype").textValue();
330 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
331 description.appendText("subtype was " + jsonSubtype);
332 return false;
333 }
334
335 final String jsonType = instructionJson.get("type").textValue();
336 if (!instructionToMatch.type().name().equals(jsonType)) {
337 description.appendText("type was " + jsonType);
338 return false;
339 }
340
341 final int jsonFlowLabel = instructionJson.get("flowLabel").intValue();
342 final int flowLabel = instructionToMatch.flowLabel();
343 if (flowLabel != jsonFlowLabel) {
344 description.appendText("IPv6 flow label was " + jsonFlowLabel);
345 return false;
346 }
347
348 return true;
349 }
350
351 /**
Ray Milkeydb358082015-01-13 16:34:38 -0800352 * Matches the contents of a mod MPLS label instruction.
Ray Milkeyd03eda02015-01-09 14:58:48 -0800353 *
354 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800355 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -0800356 * @return true if contents match, false otherwise
357 */
358 private boolean matchModMplsLabelInstruction(JsonNode instructionJson,
359 Description description) {
360 ModMplsLabelInstruction instructionToMatch =
361 (ModMplsLabelInstruction) instruction;
362 final String jsonSubtype = instructionJson.get("subtype").textValue();
363 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
364 description.appendText("subtype was " + jsonSubtype);
365 return false;
366 }
367
368 final String jsonType = instructionJson.get("type").textValue();
369 if (!instructionToMatch.type().name().equals(jsonType)) {
370 description.appendText("type was " + jsonType);
371 return false;
372 }
373
374 final int jsonLabel = instructionJson.get("label").intValue();
HIGUCHI Yuta04b49fc2015-08-28 09:58:58 -0700375 final int label = instructionToMatch.mplsLabel().toInt();
Ray Milkeyd03eda02015-01-09 14:58:48 -0800376 if (label != jsonLabel) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800377 description.appendText("MPLS label was " + jsonLabel);
Ray Milkeyd03eda02015-01-09 14:58:48 -0800378 return false;
379 }
380
381 return true;
382 }
383
384 @Override
385 public boolean matchesSafely(JsonNode jsonInstruction, Description description) {
386
387 // check type
388 final JsonNode jsonTypeNode = jsonInstruction.get("type");
389 final String jsonType = jsonTypeNode.textValue();
390 final String type = instruction.type().name();
391 if (!jsonType.equals(type)) {
392 description.appendText("type was " + type);
393 return false;
394 }
395
396 if (instruction instanceof PushHeaderInstructions) {
397 return matchPushHeaderInstruction(jsonInstruction, description);
398 } else if (instruction instanceof DropInstruction) {
399 return true;
400 } else if (instruction instanceof OutputInstruction) {
401 return matchOutputInstruction(jsonInstruction, description);
402 } else if (instruction instanceof ModLambdaInstruction) {
403 return matchModLambdaInstruction(jsonInstruction, description);
Sho SHIMIZUed7af542015-05-05 19:10:45 -0700404 } else if (instruction instanceof ModOchSignalInstruction) {
405 return matchModOchSingalInstruction(jsonInstruction, description);
Ray Milkeyd03eda02015-01-09 14:58:48 -0800406 } else if (instruction instanceof ModEtherInstruction) {
407 return matchModEtherInstruction(jsonInstruction, description);
408 } else if (instruction instanceof ModVlanIdInstruction) {
409 return matchModVlanIdInstruction(jsonInstruction, description);
410 } else if (instruction instanceof ModVlanPcpInstruction) {
411 return matchModVlanPcpInstruction(jsonInstruction, description);
412 } else if (instruction instanceof ModIPInstruction) {
413 return matchModIpInstruction(jsonInstruction, description);
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800414 } else if (instruction instanceof ModIPv6FlowLabelInstruction) {
415 return matchModIPv6FlowLabelInstruction(jsonInstruction,
416 description);
Ray Milkeyd03eda02015-01-09 14:58:48 -0800417 } else if (instruction instanceof ModMplsLabelInstruction) {
418 return matchModMplsLabelInstruction(jsonInstruction, description);
Brian O'Connorb75a67a2015-10-07 14:34:06 -0700419 } else if (instruction instanceof NoActionInstruction) {
420 return true;
Ray Milkeyd03eda02015-01-09 14:58:48 -0800421 }
422
423 return false;
424 }
425
426 @Override
427 public void describeTo(Description description) {
428 description.appendText(instruction.toString());
429 }
430
431 /**
432 * Factory to allocate an instruction matcher.
433 *
434 * @param instruction instruction object we are looking for
435 * @return matcher
436 */
437 public static InstructionJsonMatcher matchesInstruction(Instruction instruction) {
438 return new InstructionJsonMatcher(instruction);
439 }
440}