blob: 72d3e418180d37ffea6bbe91aa6977ba3cb548da [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
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -080069 if (instructionToMatch.ethernetType() != ethJson.asInt()) {
70 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 /**
Ray Milkeydb358082015-01-13 16:34:38 -0800136 * Matches the contents of a mod Ethernet instruction.
Ray Milkeyd03eda02015-01-09 14:58:48 -0800137 *
138 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800139 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -0800140 * @return true if contents match, false otherwise
141 */
142 private boolean matchModEtherInstruction(JsonNode instructionJson,
143 Description description) {
144 ModEtherInstruction instructionToMatch =
145 (ModEtherInstruction) instruction;
146 final String jsonSubtype = instructionJson.get("subtype").textValue();
147 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
148 description.appendText("subtype was " + jsonSubtype);
149 return false;
150 }
151
152 final String jsonType = instructionJson.get("type").textValue();
153 if (!instructionToMatch.type().name().equals(jsonType)) {
154 description.appendText("type was " + jsonType);
155 return false;
156 }
157
158 final String jsonMac = instructionJson.get("mac").textValue();
159 final String mac = instructionToMatch.mac().toString();
160 if (!mac.equals(jsonMac)) {
161 description.appendText("mac was " + jsonMac);
162 return false;
163 }
164
165 return true;
166 }
167
168 /**
169 * Matches the contents of a mod vlan id instruction.
170 *
171 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800172 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -0800173 * @return true if contents match, false otherwise
174 */
175 private boolean matchModVlanIdInstruction(JsonNode instructionJson,
176 Description description) {
177 ModVlanIdInstruction instructionToMatch =
178 (ModVlanIdInstruction) instruction;
179 final String jsonSubtype = instructionJson.get("subtype").textValue();
180 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
181 description.appendText("subtype was " + jsonSubtype);
182 return false;
183 }
184
185 final String jsonType = instructionJson.get("type").textValue();
186 if (!instructionToMatch.type().name().equals(jsonType)) {
187 description.appendText("type was " + jsonType);
188 return false;
189 }
190
191 final short jsonVlanId = instructionJson.get("vlanId").shortValue();
192 final short vlanId = instructionToMatch.vlanId().toShort();
193 if (jsonVlanId != vlanId) {
194 description.appendText("vlan id was " + jsonVlanId);
195 return false;
196 }
197
198 return true;
199 }
200
201 /**
202 * Matches the contents of a mod vlan pcp instruction.
203 *
204 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800205 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -0800206 * @return true if contents match, false otherwise
207 */
208 private boolean matchModVlanPcpInstruction(JsonNode instructionJson,
209 Description description) {
210 ModVlanPcpInstruction instructionToMatch =
211 (ModVlanPcpInstruction) instruction;
212 final String jsonSubtype = instructionJson.get("subtype").textValue();
213 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
214 description.appendText("subtype was " + jsonSubtype);
215 return false;
216 }
217
218 final String jsonType = instructionJson.get("type").textValue();
219 if (!instructionToMatch.type().name().equals(jsonType)) {
220 description.appendText("type was " + jsonType);
221 return false;
222 }
223
224 final short jsonVlanPcp = instructionJson.get("vlanPcp").shortValue();
225 final short vlanId = instructionToMatch.vlanPcp();
226 if (jsonVlanPcp != vlanId) {
227 description.appendText("vlan pcp was " + jsonVlanPcp);
228 return false;
229 }
230
231 return true;
232 }
233
234 /**
235 * Matches the contents of a mod ip instruction.
236 *
237 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800238 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -0800239 * @return true if contents match, false otherwise
240 */
241 private boolean matchModIpInstruction(JsonNode instructionJson,
242 Description description) {
243 ModIPInstruction instructionToMatch =
244 (ModIPInstruction) instruction;
245 final String jsonSubtype = instructionJson.get("subtype").textValue();
246 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
247 description.appendText("subtype was " + jsonSubtype);
248 return false;
249 }
250
251 final String jsonType = instructionJson.get("type").textValue();
252 if (!instructionToMatch.type().name().equals(jsonType)) {
253 description.appendText("type was " + jsonType);
254 return false;
255 }
256
257 final String jsonIp = instructionJson.get("ip").textValue();
258 final String ip = instructionToMatch.ip().toString();
259 if (!ip.equals(jsonIp)) {
260 description.appendText("ip was " + jsonIp);
261 return false;
262 }
263
264 return true;
265 }
266
267 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800268 * Matches the contents of a mod IPv6 Flow Label instruction.
269 *
270 * @param instructionJson JSON instruction to match
271 * @param description Description object used for recording errors
272 * @return true if contents match, false otherwise
273 */
274 private boolean matchModIPv6FlowLabelInstruction(JsonNode instructionJson,
275 Description description) {
276 ModIPv6FlowLabelInstruction instructionToMatch =
277 (ModIPv6FlowLabelInstruction) instruction;
278 final String jsonSubtype = instructionJson.get("subtype").textValue();
279 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
280 description.appendText("subtype was " + jsonSubtype);
281 return false;
282 }
283
284 final String jsonType = instructionJson.get("type").textValue();
285 if (!instructionToMatch.type().name().equals(jsonType)) {
286 description.appendText("type was " + jsonType);
287 return false;
288 }
289
290 final int jsonFlowLabel = instructionJson.get("flowLabel").intValue();
291 final int flowLabel = instructionToMatch.flowLabel();
292 if (flowLabel != jsonFlowLabel) {
293 description.appendText("IPv6 flow label was " + jsonFlowLabel);
294 return false;
295 }
296
297 return true;
298 }
299
300 /**
Ray Milkeydb358082015-01-13 16:34:38 -0800301 * Matches the contents of a mod MPLS label instruction.
Ray Milkeyd03eda02015-01-09 14:58:48 -0800302 *
303 * @param instructionJson JSON instruction to match
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800304 * @param description Description object used for recording errors
Ray Milkeyd03eda02015-01-09 14:58:48 -0800305 * @return true if contents match, false otherwise
306 */
307 private boolean matchModMplsLabelInstruction(JsonNode instructionJson,
308 Description description) {
309 ModMplsLabelInstruction instructionToMatch =
310 (ModMplsLabelInstruction) instruction;
311 final String jsonSubtype = instructionJson.get("subtype").textValue();
312 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
313 description.appendText("subtype was " + jsonSubtype);
314 return false;
315 }
316
317 final String jsonType = instructionJson.get("type").textValue();
318 if (!instructionToMatch.type().name().equals(jsonType)) {
319 description.appendText("type was " + jsonType);
320 return false;
321 }
322
323 final int jsonLabel = instructionJson.get("label").intValue();
324 final int label = instructionToMatch.label();
325 if (label != jsonLabel) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800326 description.appendText("MPLS label was " + jsonLabel);
Ray Milkeyd03eda02015-01-09 14:58:48 -0800327 return false;
328 }
329
330 return true;
331 }
332
333 @Override
334 public boolean matchesSafely(JsonNode jsonInstruction, Description description) {
335
336 // check type
337 final JsonNode jsonTypeNode = jsonInstruction.get("type");
338 final String jsonType = jsonTypeNode.textValue();
339 final String type = instruction.type().name();
340 if (!jsonType.equals(type)) {
341 description.appendText("type was " + type);
342 return false;
343 }
344
345 if (instruction instanceof PushHeaderInstructions) {
346 return matchPushHeaderInstruction(jsonInstruction, description);
347 } else if (instruction instanceof DropInstruction) {
348 return true;
349 } else if (instruction instanceof OutputInstruction) {
350 return matchOutputInstruction(jsonInstruction, description);
351 } else if (instruction instanceof ModLambdaInstruction) {
352 return matchModLambdaInstruction(jsonInstruction, description);
353 } else if (instruction instanceof ModEtherInstruction) {
354 return matchModEtherInstruction(jsonInstruction, description);
355 } else if (instruction instanceof ModVlanIdInstruction) {
356 return matchModVlanIdInstruction(jsonInstruction, description);
357 } else if (instruction instanceof ModVlanPcpInstruction) {
358 return matchModVlanPcpInstruction(jsonInstruction, description);
359 } else if (instruction instanceof ModIPInstruction) {
360 return matchModIpInstruction(jsonInstruction, description);
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800361 } else if (instruction instanceof ModIPv6FlowLabelInstruction) {
362 return matchModIPv6FlowLabelInstruction(jsonInstruction,
363 description);
Ray Milkeyd03eda02015-01-09 14:58:48 -0800364 } else if (instruction instanceof ModMplsLabelInstruction) {
365 return matchModMplsLabelInstruction(jsonInstruction, description);
366 }
367
368 return false;
369 }
370
371 @Override
372 public void describeTo(Description description) {
373 description.appendText(instruction.toString());
374 }
375
376 /**
377 * Factory to allocate an instruction matcher.
378 *
379 * @param instruction instruction object we are looking for
380 * @return matcher
381 */
382 public static InstructionJsonMatcher matchesInstruction(Instruction instruction) {
383 return new InstructionJsonMatcher(instruction);
384 }
385}