blob: 001a8656c0f88823b9271d4ff2cb4175f4f0febd [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;
19import org.hamcrest.Matcher;
20import org.hamcrest.TypeSafeDiagnosingMatcher;
21import org.onosproject.net.flow.instructions.Instruction;
22
23import com.fasterxml.jackson.databind.JsonNode;
24
25import static org.onosproject.codec.impl.EthernetJsonMatcher.matchesEthernet;
26import static org.onosproject.net.flow.instructions.Instructions.*;
27import static org.onosproject.net.flow.instructions.L0ModificationInstruction.*;
28import static org.onosproject.net.flow.instructions.L2ModificationInstruction.*;
29import static org.onosproject.net.flow.instructions.L3ModificationInstruction.*;
30
31/**
32 * Hamcrest matcher for instructions.
33 */
Ray Milkeydb358082015-01-13 16:34:38 -080034public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
Ray Milkeyd03eda02015-01-09 14:58:48 -080035
36 private final Instruction instruction;
37
Ray Milkeydb358082015-01-13 16:34:38 -080038 private InstructionJsonMatcher(Instruction instructionValue) {
Ray Milkeyd03eda02015-01-09 14:58:48 -080039 instruction = instructionValue;
40 }
41
42 /**
43 * Matches the contents of a push header instruction.
44 *
45 * @param instructionJson JSON instruction to match
46 * @return true if contents match, false otherwise
47 */
48 private boolean matchPushHeaderInstruction(JsonNode instructionJson,
49 Description description) {
50 PushHeaderInstructions instructionToMatch =
51 (PushHeaderInstructions) instruction;
52 final String jsonSubtype = instructionJson.get("subtype").textValue();
53 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
54 description.appendText("subtype was " + jsonSubtype);
55 return false;
56 }
57
58 final String jsonType = instructionJson.get("type").textValue();
59 if (!instructionToMatch.type().name().equals(jsonType)) {
60 description.appendText("type was " + jsonType);
61 return false;
62 }
63
64 final JsonNode ethJson = instructionJson.get("ethernetType");
65 if (ethJson == null) {
66 description.appendText("ethernetType was not null");
67 return false;
68 }
69
70 final Matcher ethernetMatcher =
71 matchesEthernet(instructionToMatch.ethernetType());
72 final boolean ethernetMatches = ethernetMatcher.matches(ethJson);
73 if (!ethernetMatches) {
74 ethernetMatcher.describeMismatch(ethernetMatcher, description);
75 return false;
76 }
77 return true;
78 }
79
80 /**
81 * Matches the contents of an output instruction.
82 *
83 * @param instructionJson JSON instruction to match
84 * @return true if contents match, false otherwise
85 */
86 private boolean matchOutputInstruction(JsonNode instructionJson,
87 Description description) {
88 OutputInstruction instructionToMatch = (OutputInstruction) instruction;
89
90 final String jsonType = instructionJson.get("type").textValue();
91 if (!instructionToMatch.type().name().equals(jsonType)) {
92 description.appendText("type was " + jsonType);
93 return false;
94 }
95
96 final long jsonPort = instructionJson.get("port").asLong();
97 if (instructionToMatch.port().toLong() != jsonPort) {
98 description.appendText("port was " + jsonPort);
99 return false;
100 }
101
102 return true;
103 }
104
105 /**
106 * Matches the contents of a mod lambda instruction.
107 *
108 * @param instructionJson JSON instruction to match
109 * @return true if contents match, false otherwise
110 */
111 private boolean matchModLambdaInstruction(JsonNode instructionJson,
112 Description description) {
113 ModLambdaInstruction instructionToMatch =
114 (ModLambdaInstruction) instruction;
115 final String jsonSubtype = instructionJson.get("subtype").textValue();
116 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
117 description.appendText("subtype was " + jsonSubtype);
118 return false;
119 }
120
121 final String jsonType = instructionJson.get("type").textValue();
122 if (!instructionToMatch.type().name().equals(jsonType)) {
123 description.appendText("type was " + jsonType);
124 return false;
125 }
126
127 final long jsonLambda = instructionJson.get("lambda").shortValue();
128 if (instructionToMatch.lambda() != jsonLambda) {
129 description.appendText("lambda was " + jsonLambda);
130 return false;
131 }
132
133 return true;
134 }
135
136 /**
Ray Milkeydb358082015-01-13 16:34:38 -0800137 * Matches the contents of a mod Ethernet instruction.
Ray Milkeyd03eda02015-01-09 14:58:48 -0800138 *
139 * @param instructionJson JSON instruction to match
140 * @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
172 * @return true if contents match, false otherwise
173 */
174 private boolean matchModVlanIdInstruction(JsonNode instructionJson,
175 Description description) {
176 ModVlanIdInstruction instructionToMatch =
177 (ModVlanIdInstruction) instruction;
178 final String jsonSubtype = instructionJson.get("subtype").textValue();
179 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
180 description.appendText("subtype was " + jsonSubtype);
181 return false;
182 }
183
184 final String jsonType = instructionJson.get("type").textValue();
185 if (!instructionToMatch.type().name().equals(jsonType)) {
186 description.appendText("type was " + jsonType);
187 return false;
188 }
189
190 final short jsonVlanId = instructionJson.get("vlanId").shortValue();
191 final short vlanId = instructionToMatch.vlanId().toShort();
192 if (jsonVlanId != vlanId) {
193 description.appendText("vlan id was " + jsonVlanId);
194 return false;
195 }
196
197 return true;
198 }
199
200 /**
201 * Matches the contents of a mod vlan pcp instruction.
202 *
203 * @param instructionJson JSON instruction to match
204 * @return true if contents match, false otherwise
205 */
206 private boolean matchModVlanPcpInstruction(JsonNode instructionJson,
207 Description description) {
208 ModVlanPcpInstruction instructionToMatch =
209 (ModVlanPcpInstruction) instruction;
210 final String jsonSubtype = instructionJson.get("subtype").textValue();
211 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
212 description.appendText("subtype was " + jsonSubtype);
213 return false;
214 }
215
216 final String jsonType = instructionJson.get("type").textValue();
217 if (!instructionToMatch.type().name().equals(jsonType)) {
218 description.appendText("type was " + jsonType);
219 return false;
220 }
221
222 final short jsonVlanPcp = instructionJson.get("vlanPcp").shortValue();
223 final short vlanId = instructionToMatch.vlanPcp();
224 if (jsonVlanPcp != vlanId) {
225 description.appendText("vlan pcp was " + jsonVlanPcp);
226 return false;
227 }
228
229 return true;
230 }
231
232 /**
233 * Matches the contents of a mod ip instruction.
234 *
235 * @param instructionJson JSON instruction to match
236 * @return true if contents match, false otherwise
237 */
238 private boolean matchModIpInstruction(JsonNode instructionJson,
239 Description description) {
240 ModIPInstruction instructionToMatch =
241 (ModIPInstruction) instruction;
242 final String jsonSubtype = instructionJson.get("subtype").textValue();
243 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
244 description.appendText("subtype was " + jsonSubtype);
245 return false;
246 }
247
248 final String jsonType = instructionJson.get("type").textValue();
249 if (!instructionToMatch.type().name().equals(jsonType)) {
250 description.appendText("type was " + jsonType);
251 return false;
252 }
253
254 final String jsonIp = instructionJson.get("ip").textValue();
255 final String ip = instructionToMatch.ip().toString();
256 if (!ip.equals(jsonIp)) {
257 description.appendText("ip was " + jsonIp);
258 return false;
259 }
260
261 return true;
262 }
263
264 /**
Ray Milkeydb358082015-01-13 16:34:38 -0800265 * Matches the contents of a mod MPLS label instruction.
Ray Milkeyd03eda02015-01-09 14:58:48 -0800266 *
267 * @param instructionJson JSON instruction to match
268 * @return true if contents match, false otherwise
269 */
270 private boolean matchModMplsLabelInstruction(JsonNode instructionJson,
271 Description description) {
272 ModMplsLabelInstruction instructionToMatch =
273 (ModMplsLabelInstruction) instruction;
274 final String jsonSubtype = instructionJson.get("subtype").textValue();
275 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
276 description.appendText("subtype was " + jsonSubtype);
277 return false;
278 }
279
280 final String jsonType = instructionJson.get("type").textValue();
281 if (!instructionToMatch.type().name().equals(jsonType)) {
282 description.appendText("type was " + jsonType);
283 return false;
284 }
285
286 final int jsonLabel = instructionJson.get("label").intValue();
287 final int label = instructionToMatch.label();
288 if (label != jsonLabel) {
289 description.appendText("ip was " + jsonLabel);
290 return false;
291 }
292
293 return true;
294 }
295
296 @Override
297 public boolean matchesSafely(JsonNode jsonInstruction, Description description) {
298
299 // check type
300 final JsonNode jsonTypeNode = jsonInstruction.get("type");
301 final String jsonType = jsonTypeNode.textValue();
302 final String type = instruction.type().name();
303 if (!jsonType.equals(type)) {
304 description.appendText("type was " + type);
305 return false;
306 }
307
308 if (instruction instanceof PushHeaderInstructions) {
309 return matchPushHeaderInstruction(jsonInstruction, description);
310 } else if (instruction instanceof DropInstruction) {
311 return true;
312 } else if (instruction instanceof OutputInstruction) {
313 return matchOutputInstruction(jsonInstruction, description);
314 } else if (instruction instanceof ModLambdaInstruction) {
315 return matchModLambdaInstruction(jsonInstruction, description);
316 } else if (instruction instanceof ModEtherInstruction) {
317 return matchModEtherInstruction(jsonInstruction, description);
318 } else if (instruction instanceof ModVlanIdInstruction) {
319 return matchModVlanIdInstruction(jsonInstruction, description);
320 } else if (instruction instanceof ModVlanPcpInstruction) {
321 return matchModVlanPcpInstruction(jsonInstruction, description);
322 } else if (instruction instanceof ModIPInstruction) {
323 return matchModIpInstruction(jsonInstruction, description);
324 } else if (instruction instanceof ModMplsLabelInstruction) {
325 return matchModMplsLabelInstruction(jsonInstruction, description);
326 }
327
328 return false;
329 }
330
331 @Override
332 public void describeTo(Description description) {
333 description.appendText(instruction.toString());
334 }
335
336 /**
337 * Factory to allocate an instruction matcher.
338 *
339 * @param instruction instruction object we are looking for
340 * @return matcher
341 */
342 public static InstructionJsonMatcher matchesInstruction(Instruction instruction) {
343 return new InstructionJsonMatcher(instruction);
344 }
345}