Unit tets for instruction JSON codecs
Fixed several bugs in codecs turned up by unit tests
Change-Id: Icddb31aa3d2cb58612a0578772d24ff5f113d073
diff --git a/web/api/pom.xml b/web/api/pom.xml
index 093edcf..f1691be 100644
--- a/web/api/pom.xml
+++ b/web/api/pom.xml
@@ -43,6 +43,13 @@
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ <classifier>tests</classifier>
+ </dependency>
</dependencies>
<properties>
diff --git a/web/api/src/main/java/org/onosproject/codec/impl/ConnectivityIntentCodec.java b/web/api/src/main/java/org/onosproject/codec/impl/ConnectivityIntentCodec.java
index f460913..3a7aa15 100644
--- a/web/api/src/main/java/org/onosproject/codec/impl/ConnectivityIntentCodec.java
+++ b/web/api/src/main/java/org/onosproject/codec/impl/ConnectivityIntentCodec.java
@@ -20,8 +20,10 @@
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.ConnectivityIntent;
+import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.Intent;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -50,6 +52,17 @@
result.set("treatment", treatmentCodec.encode(intent.treatment(), context));
}
+ if (intent.constraints() != null) {
+ final ArrayNode jsonConstraints = result.putArray("constraints");
+
+ if (intent.constraints() != null) {
+ for (final Constraint constraint : intent.constraints()) {
+ // TODO: constraint should have its own codec
+ jsonConstraints.add(constraint.toString());
+ }
+ }
+ }
+
return result;
}
}
diff --git a/web/api/src/main/java/org/onosproject/codec/impl/CriterionCodec.java b/web/api/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
index 81033f2..e6fbea8 100644
--- a/web/api/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
+++ b/web/api/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
@@ -50,6 +50,7 @@
case ETH_SRC:
case ETH_DST:
final Criteria.EthCriterion ethCriterion = (Criteria.EthCriterion) criterion;
+ result.put("mac", ethCriterion.mac().toString());
break;
case ETH_TYPE:
@@ -60,6 +61,8 @@
case IPV4_SRC:
case IPV6_SRC:
+ case IPV4_DST:
+ case IPV6_DST:
final Criteria.IPCriterion iPCriterion = (Criteria.IPCriterion) criterion;
result.put("ip", iPCriterion.ip().toString());
break;
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/ConnectPointJsonMatcher.java b/web/api/src/test/java/org/onosproject/codec/impl/ConnectPointJsonMatcher.java
new file mode 100644
index 0000000..8d85751
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/codec/impl/ConnectPointJsonMatcher.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.codec.impl;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.onosproject.net.ConnectPoint;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Hamcrest matcher for connect points.
+ */
+
+public final class ConnectPointJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
+
+ private final ConnectPoint connectPoint;
+
+ private ConnectPointJsonMatcher(ConnectPoint connectPointValue) {
+ connectPoint = connectPointValue;
+ }
+
+ @Override
+ public boolean matchesSafely(JsonNode jsonConnectPoint, Description description) {
+ // check device
+ final String jsonDevice = jsonConnectPoint.get("device").asText();
+ final String device = connectPoint.deviceId().toString();
+ if (!jsonDevice.equals(device)) {
+ description.appendText("device was " + jsonDevice);
+ return false;
+ }
+
+ // check port
+ final String jsonPort = jsonConnectPoint.get("port").asText();
+ final String port = connectPoint.port().toString();
+ if (!jsonPort.equals(port)) {
+ description.appendText("port was " + jsonPort);
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(connectPoint.toString());
+ }
+
+ /**
+ * Factory to allocate an connect point matcher.
+ *
+ * @param connectPoint connect point object we are looking for
+ * @return matcher
+ */
+ public static ConnectPointJsonMatcher matchesConnectPoint(ConnectPoint connectPoint) {
+ return new ConnectPointJsonMatcher(connectPoint);
+ }
+}
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java b/web/api/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java
new file mode 100644
index 0000000..e0baf87
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.codec.impl;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Hamcrest matcher for criterion objects.
+ */
+public final class CriterionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
+
+ final Criterion criterion;
+
+ private CriterionJsonMatcher(Criterion criterionValue) {
+ criterion = criterionValue;
+ }
+
+ @Override
+ public boolean matchesSafely(JsonNode jsonCriterion, Description description) {
+ final String type = criterion.type().name();
+ final String jsonType = jsonCriterion.get("type").asText();
+ if (!type.equals(jsonType)) {
+ description.appendText("type was " + type);
+ return false;
+ }
+
+ switch (criterion.type()) {
+
+ case IN_PORT:
+ final Criteria.PortCriterion portCriterion = (Criteria.PortCriterion) criterion;
+ final long port = portCriterion.port().toLong();
+ final long jsonPort = jsonCriterion.get("port").asLong();
+ if (port != jsonPort) {
+ description.appendText("port was " + Long.toString(jsonPort));
+ return false;
+ }
+ break;
+
+ case ETH_SRC:
+ case ETH_DST:
+ final Criteria.EthCriterion ethCriterion = (Criteria.EthCriterion) criterion;
+ final String mac = ethCriterion.mac().toString();
+ final String jsonMac = jsonCriterion.get("mac").textValue();
+ if (!mac.equals(jsonMac)) {
+ description.appendText("mac was " + jsonMac);
+ return false;
+ }
+ break;
+
+ case ETH_TYPE:
+ final Criteria.EthTypeCriterion ethTypeCriterion =
+ (Criteria.EthTypeCriterion) criterion;
+ final String ethType = ethTypeCriterion.ethType().toString();
+ final String jsonEthType = jsonCriterion.get("ethType").textValue();
+ if (!ethType.equals(jsonEthType)) {
+ description.appendText("ethType was " + jsonEthType);
+ return false;
+ }
+ break;
+
+ case IPV4_SRC:
+ case IPV6_SRC:
+ case IPV4_DST:
+ case IPV6_DST:
+ final Criteria.IPCriterion ipCriterion = (Criteria.IPCriterion) criterion;
+ final String ip = ipCriterion.ip().toString();
+ final String jsonIp = jsonCriterion.get("ip").textValue();
+ if (!ip.equals(jsonIp)) {
+ description.appendText("ip was " + jsonIp);
+ return false;
+ }
+ break;
+
+ case IP_PROTO:
+ final Criteria.IPProtocolCriterion iPProtocolCriterion =
+ (Criteria.IPProtocolCriterion) criterion;
+ final byte protocol = iPProtocolCriterion.protocol();
+ final byte jsonProtocol = (byte) jsonCriterion.get("protocol").shortValue();
+ if (protocol != jsonProtocol) {
+ description.appendText("protocol was " + Byte.toString(jsonProtocol));
+ return false;
+ }
+ break;
+
+ case VLAN_PCP:
+ final Criteria.VlanPcpCriterion vlanPcpCriterion =
+ (Criteria.VlanPcpCriterion) criterion;
+ final byte priority = vlanPcpCriterion.priority();
+ final byte jsonPriority = (byte) jsonCriterion.get("protocol").shortValue();
+ if (priority != jsonPriority) {
+ description.appendText("priority was " + Byte.toString(jsonPriority));
+ return false;
+ }
+ break;
+
+ case VLAN_VID:
+ final Criteria.VlanIdCriterion vlanIdCriterion =
+ (Criteria.VlanIdCriterion) criterion;
+ final short vlanId = vlanIdCriterion.vlanId().toShort();
+ final short jsonvlanId = jsonCriterion.get("vlanId").shortValue();
+ if (vlanId != jsonvlanId) {
+ description.appendText("vlanId was " + Short.toString(jsonvlanId));
+ return false;
+ }
+ break;
+
+ case TCP_SRC:
+ case TCP_DST:
+ final Criteria.TcpPortCriterion tcpPortCriterion =
+ (Criteria.TcpPortCriterion) criterion;
+ final byte tcpPort = tcpPortCriterion.tcpPort().byteValue();
+ final byte jsonTcpPort = (byte) jsonCriterion.get("tcpPort").shortValue();
+ if (tcpPort != jsonTcpPort) {
+ description.appendText("tcp port was " + Byte.toString(jsonTcpPort));
+ return false;
+ }
+ break;
+
+ case MPLS_LABEL:
+ final Criteria.MplsCriterion mplsCriterion =
+ (Criteria.MplsCriterion) criterion;
+ final int label = mplsCriterion.label();
+ final int jsonLabel = jsonCriterion.get("label").intValue();
+ if (label != jsonLabel) {
+ description.appendText("label was " + Integer.toString(jsonLabel));
+ return false;
+ }
+ break;
+
+ case OCH_SIGID:
+ final Criteria.LambdaCriterion lambdaCriterion =
+ (Criteria.LambdaCriterion) criterion;
+ final short lambda = lambdaCriterion.lambda();
+ final short jsonLambda = jsonCriterion.get("lambda").shortValue();
+ if (lambda != jsonLambda) {
+ description.appendText("lambda was " + Short.toString(lambda));
+ return false;
+ }
+ break;
+
+ case OCH_SIGTYPE:
+ final Criteria.OpticalSignalTypeCriterion opticalSignalTypeCriterion =
+ (Criteria.OpticalSignalTypeCriterion) criterion;
+ final short signalType = opticalSignalTypeCriterion.signalType();
+ final short jsonSignalType = jsonCriterion.get("signalType").shortValue();
+ if (signalType != jsonSignalType) {
+ description.appendText("signal type was " + Short.toString(signalType));
+ return false;
+ }
+ break;
+
+ default:
+ // Don't know how to format this type
+ description.appendText("unknown criterion type " +
+ criterion.type());
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(criterion.toString());
+ }
+
+ /**
+ * Factory to allocate an criterion matcher.
+ *
+ * @param criterion criterion object we are looking for
+ * @return matcher
+ */
+ public static CriterionJsonMatcher matchesCriterion(Criterion criterion) {
+ return new CriterionJsonMatcher(criterion);
+ }
+}
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/EthernetJsonMatcher.java b/web/api/src/test/java/org/onosproject/codec/impl/EthernetJsonMatcher.java
index fd4190e..c5827b9 100644
--- a/web/api/src/test/java/org/onosproject/codec/impl/EthernetJsonMatcher.java
+++ b/web/api/src/test/java/org/onosproject/codec/impl/EthernetJsonMatcher.java
@@ -24,12 +24,12 @@
/**
* Hamcrest matcher for ethernet objects.
*/
-public class EthernetJsonMatcher extends TypeSafeMatcher<JsonNode> {
+public final class EthernetJsonMatcher extends TypeSafeMatcher<JsonNode> {
private final Ethernet ethernet;
private String reason = "";
- public EthernetJsonMatcher(Ethernet ethernetValue) {
+ private EthernetJsonMatcher(Ethernet ethernetValue) {
ethernet = ethernetValue;
}
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java b/web/api/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java
index 781f133..8bf4439 100644
--- a/web/api/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java
+++ b/web/api/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java
@@ -44,7 +44,7 @@
JsonCodec<Instruction> instructionCodec;
/**
- * Sets up for each tests. Creates a context and fetches the instruction
+ * Sets up for each test. Creates a context and fetches the instruction
* codec.
*/
@Before
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java b/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
index d5b4ae0..001a865 100644
--- a/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
+++ b/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
@@ -31,11 +31,11 @@
/**
* Hamcrest matcher for instructions.
*/
-public class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
+public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
private final Instruction instruction;
- public InstructionJsonMatcher(Instruction instructionValue) {
+ private InstructionJsonMatcher(Instruction instructionValue) {
instruction = instructionValue;
}
@@ -134,7 +134,7 @@
}
/**
- * Matches the contents of a mod lambda instruction.
+ * Matches the contents of a mod Ethernet instruction.
*
* @param instructionJson JSON instruction to match
* @return true if contents match, false otherwise
@@ -262,7 +262,7 @@
}
/**
- * Matches the contents of a mod ip instruction.
+ * Matches the contents of a mod MPLS label instruction.
*
* @param instructionJson JSON instruction to match
* @return true if contents match, false otherwise
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java b/web/api/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java
new file mode 100644
index 0000000..fd84f17
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.codec.impl;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.HostId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.HostToHostIntent;
+import org.onosproject.net.intent.AbstractIntentTest;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.intent.constraint.BandwidthConstraint;
+import org.onosproject.net.intent.constraint.LambdaConstraint;
+import org.onosproject.net.resource.Bandwidth;
+import org.onosproject.net.resource.Lambda;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableList;
+
+import static org.onosproject.codec.impl.IntentJsonMatcher.matchesIntent;
+import static org.onosproject.net.NetTestTools.hid;
+
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+
+/**
+ * Unit tests for the host to host intent class codec.
+ */
+public class IntentCodecTest extends AbstractIntentTest {
+
+ private final HostId id1 = hid("12:34:56:78:91:ab/1");
+ private final HostId id2 = hid("12:34:56:78:92:ab/1");
+ private final ApplicationId appId =
+ new DefaultApplicationId((short) 3, "test");
+ final TrafficSelector emptySelector =
+ DefaultTrafficSelector.builder().build();
+ final TrafficTreatment emptyTreatment =
+ DefaultTrafficTreatment.builder().build();
+ private final CodecContext context = new MockCodecContext();
+
+ /**
+ * Tests the encoding of a host to host intent.
+ */
+ @Test
+ public void hostToHostIntent() {
+ final HostToHostIntent intent =
+ new HostToHostIntent(appId, id1, id2);
+
+ final JsonCodec<HostToHostIntent> intentCodec =
+ context.codec(HostToHostIntent.class);
+ assertThat(intentCodec, notNullValue());
+
+ final ObjectNode intentJson = intentCodec.encode(intent, context);
+ assertThat(intentJson, matchesIntent(intent));
+ }
+
+ /**
+ * Tests the encoding of a point to point intent.
+ */
+ @Test
+ public void pointToPointIntent() {
+ ConnectPoint ingress = NetTestTools.connectPoint("ingress", 1);
+ ConnectPoint egress = NetTestTools.connectPoint("egress", 2);
+
+ final PointToPointIntent intent =
+ new PointToPointIntent(appId, emptySelector,
+ emptyTreatment, ingress, egress);
+
+ final CodecContext context = new MockCodecContext();
+ final JsonCodec<PointToPointIntent> intentCodec =
+ context.codec(PointToPointIntent.class);
+ assertThat(intentCodec, notNullValue());
+
+ final ObjectNode intentJson = intentCodec.encode(intent, context);
+ assertThat(intentJson, matchesIntent(intent));
+ }
+
+ /**
+ * Tests the encoding of an intent with treatment, selector and constraints
+ * specified.
+ */
+ @Test
+ public void intentWithTreatmentSelectorAndConstraints() {
+ ConnectPoint ingress = NetTestTools.connectPoint("ingress", 1);
+ ConnectPoint egress = NetTestTools.connectPoint("egress", 2);
+ final TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchIPProtocol((byte) 3)
+ .matchMplsLabel(4)
+ .matchOpticalSignalType((short) 5)
+ .matchLambda((short) 6)
+ .matchEthDst(MacAddress.BROADCAST)
+ .matchIPDst(IpPrefix.valueOf("1.2.3.4/24"))
+ .build();
+ final TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setLambda((short) 33)
+ .setMpls(44)
+ .setOutput(PortNumber.CONTROLLER)
+ .setEthDst(MacAddress.BROADCAST)
+ .build();
+ final Constraint constraint1 = new BandwidthConstraint(Bandwidth.valueOf(1.0));
+ final Constraint constraint2 = new LambdaConstraint(Lambda.valueOf(3));
+ final List<Constraint> constraints = ImmutableList.of(constraint1, constraint2);
+
+ final PointToPointIntent intent =
+ new PointToPointIntent(appId, selector, treatment,
+ ingress, egress, constraints);
+
+ final CodecContext context = new MockCodecContext();
+ final JsonCodec<PointToPointIntent> intentCodec =
+ context.codec(PointToPointIntent.class);
+ assertThat(intentCodec, notNullValue());
+
+ final ObjectNode intentJson = intentCodec.encode(intent, context);
+ assertThat(intentJson, matchesIntent(intent));
+
+ }
+}
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/IntentJsonMatcher.java b/web/api/src/test/java/org/onosproject/codec/impl/IntentJsonMatcher.java
new file mode 100644
index 0000000..a49307b
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/codec/impl/IntentJsonMatcher.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.codec.impl;
+
+import java.util.List;
+import java.util.Set;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.NetworkResource;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.intent.ConnectivityIntent;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.HostToHostIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.PointToPointIntent;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Hamcrest matcher to check that an intent representation in JSON matches
+ * the actual intent.
+ */
+public final class IntentJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
+
+ private final Intent intent;
+
+ /**
+ * Constructor is private, use factory method.
+ *
+ * @param intentValue the intent object to compare against
+ */
+ private IntentJsonMatcher(Intent intentValue) {
+ intent = intentValue;
+ }
+
+ /**
+ * Matches the JSON representation of a host to host intent.
+ *
+ * @param jsonIntent JSON representation of the intent
+ * @param description Description object used for recording errors
+ * @return true if the JSON matches the intent, false otherwise
+ */
+ private boolean matchHostToHostIntent(JsonNode jsonIntent, Description description) {
+ final HostToHostIntent hostToHostIntent = (HostToHostIntent) intent;
+
+ // check host one
+ final String host1 = hostToHostIntent.one().toString();
+ final String jsonHost1 = jsonIntent.get("one").asText();
+ if (!host1.equals(jsonHost1)) {
+ description.appendText("host one was " + jsonHost1);
+ return false;
+ }
+
+ // check host 2
+ final String host2 = hostToHostIntent.two().toString();
+ final String jsonHost2 = jsonIntent.get("two").asText();
+ if (!host2.equals(jsonHost2)) {
+ description.appendText("host two was " + jsonHost2);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Matches the JSON representation of a point to point intent.
+ *
+ * @param jsonIntent JSON representation of the intent
+ * @param description Description object used for recording errors
+ * @return true if the JSON matches the intent, false otherwise
+ */
+ private boolean matchPointToPointIntent(JsonNode jsonIntent, Description description) {
+ final PointToPointIntent pointToPointIntent = (PointToPointIntent) intent;
+
+ // check ingress connection
+ final ConnectPoint ingress = pointToPointIntent.ingressPoint();
+ final ConnectPointJsonMatcher ingressMatcher =
+ ConnectPointJsonMatcher.matchesConnectPoint(ingress);
+ final JsonNode jsonIngress = jsonIntent.get("ingressPoint");
+ final boolean ingressMatches =
+ ingressMatcher.matchesSafely(jsonIngress, description);
+
+ if (!ingressMatches) {
+ description.appendText("ingress was " + jsonIngress);
+ return false;
+ }
+
+ // check egress connection
+ final ConnectPoint egress = pointToPointIntent.egressPoint();
+ final ConnectPointJsonMatcher egressMatcher =
+ ConnectPointJsonMatcher.matchesConnectPoint(egress);
+ final JsonNode jsonEgress = jsonIntent.get("egressPoint");
+ final boolean egressMatches =
+ egressMatcher.matchesSafely(jsonEgress, description);
+
+ if (!egressMatches) {
+ description.appendText("egress was " + jsonEgress);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Matches the JSON representation of a connectivity intent. Calls the
+ * matcher for the connectivity intent subtype.
+ *
+ * @param jsonIntent JSON representation of the intent
+ * @param description Description object used for recording errors
+ * @return true if the JSON matches the intent, false otherwise
+ */
+ private boolean matchConnectivityIntent(JsonNode jsonIntent, Description description) {
+ final ConnectivityIntent connectivityIntent = (ConnectivityIntent) intent;
+
+ // check selector
+ final JsonNode jsonSelector = jsonIntent.get("selector");
+ final TrafficSelector selector = connectivityIntent.selector();
+ final Set<Criterion> criteria = selector.criteria();
+ final JsonNode jsonCriteria = jsonSelector.get("criteria");
+ if (jsonCriteria.size() != criteria.size()) {
+ description.appendText("size of criteria array is "
+ + Integer.toString(jsonCriteria.size()));
+ return false;
+ }
+
+ for (Criterion criterion : criteria) {
+ boolean criterionFound = false;
+ for (int criterionIndex = 0; criterionIndex < jsonCriteria.size(); criterionIndex++) {
+ final CriterionJsonMatcher criterionMatcher =
+ CriterionJsonMatcher.matchesCriterion(criterion);
+ if (criterionMatcher.matches(jsonCriteria.get(criterionIndex))) {
+ criterionFound = true;
+ break;
+ }
+ }
+ if (!criterionFound) {
+ description.appendText("criterion not found " + criterion.toString());
+ return false;
+ }
+ }
+
+ // check treatment
+ final JsonNode jsonTreatment = jsonIntent.get("treatment");
+ final TrafficTreatment treatment = connectivityIntent.treatment();
+ final List<Instruction> instructions = treatment.instructions();
+ final JsonNode jsonInstructions = jsonTreatment.get("instructions");
+ if (jsonInstructions.size() != instructions.size()) {
+ description.appendText("size of instructions array is "
+ + Integer.toString(jsonInstructions.size()));
+ return false;
+ }
+
+ for (Instruction instruction : instructions) {
+ boolean instructionFound = false;
+ for (int instructionIndex = 0; instructionIndex < jsonCriteria.size(); instructionIndex++) {
+ final InstructionJsonMatcher instructionMatcher =
+ InstructionJsonMatcher.matchesInstruction(instruction);
+ if (instructionMatcher.matches(jsonInstructions.get(instructionIndex))) {
+ instructionFound = true;
+ break;
+ }
+ }
+ if (!instructionFound) {
+ description.appendText("instruction not found " + instruction.toString());
+ return false;
+ }
+ }
+
+ // Check constraints
+ final JsonNode jsonConstraints = jsonIntent.get("constraints");
+ if (connectivityIntent.constraints() != null) {
+ if (connectivityIntent.constraints().size() != jsonConstraints.size()) {
+ description.appendText("constraints array size was "
+ + Integer.toString(jsonConstraints.size()));
+ return false;
+ }
+ for (final Constraint constraint : connectivityIntent.constraints()) {
+ boolean constraintFound = false;
+ final String constraintString = constraint.toString();
+ for (int constraintIndex = 0; constraintIndex < jsonConstraints.size();
+ constraintIndex++) {
+ final JsonNode value = jsonConstraints.get(constraintIndex);
+ if (value.asText().equals(constraintString)) {
+ constraintFound = true;
+ }
+ }
+ if (!constraintFound) {
+ description.appendText("resource missing " + constraintString);
+ return false;
+ }
+ }
+ } else if (jsonConstraints.size() != 0) {
+ description.appendText("constraint array not empty");
+ return false;
+ }
+
+ if (connectivityIntent instanceof HostToHostIntent) {
+ return matchHostToHostIntent(jsonIntent, description);
+ } else if (connectivityIntent instanceof PointToPointIntent) {
+ return matchPointToPointIntent(jsonIntent, description);
+ } else {
+ description.appendText("class of connectivity intent is unknown");
+ return false;
+ }
+ }
+
+ @Override
+ public boolean matchesSafely(JsonNode jsonIntent, Description description) {
+ // check id
+ final String jsonId = jsonIntent.get("id").asText();
+ final String id = intent.id().toString();
+ if (!jsonId.equals(id)) {
+ description.appendText("id was " + jsonId);
+ return false;
+ }
+
+ // check application id
+ final String jsonAppId = jsonIntent.get("appId").asText();
+ final String appId = intent.appId().toString();
+ if (!jsonAppId.equals(appId)) {
+ description.appendText("appId was " + jsonAppId);
+ return false;
+ }
+
+ // check intent type
+ final String jsonType = jsonIntent.get("type").asText();
+ final String type = intent.getClass().getSimpleName();
+ if (!jsonType.equals(type)) {
+ description.appendText("type was " + jsonType);
+ return false;
+ }
+
+ // check details field
+ final String jsonDetails = jsonIntent.get("details").asText();
+ final String details = intent.toString();
+ if (!jsonDetails.equals(details)) {
+ description.appendText("details were " + jsonDetails);
+ return false;
+ }
+
+ // check resources array
+ final JsonNode jsonResources = jsonIntent.get("resources");
+ if (intent.resources() != null) {
+ if (intent.resources().size() != jsonResources.size()) {
+ description.appendText("resources array size was "
+ + Integer.toString(jsonResources.size()));
+ return false;
+ }
+ for (final NetworkResource resource : intent.resources()) {
+ boolean resourceFound = false;
+ final String resourceString = resource.toString();
+ for (int resourceIndex = 0; resourceIndex < jsonResources.size(); resourceIndex++) {
+ final JsonNode value = jsonResources.get(resourceIndex);
+ if (value.asText().equals(resourceString)) {
+ resourceFound = true;
+ }
+ }
+ if (!resourceFound) {
+ description.appendText("resource missing " + resourceString);
+ return false;
+ }
+ }
+ } else if (jsonResources.size() != 0) {
+ description.appendText("resources array empty");
+ return false;
+ }
+
+ if (intent instanceof ConnectivityIntent) {
+ return matchConnectivityIntent(jsonIntent, description);
+ } else {
+ description.appendText("class of intent is unknown");
+ return false;
+ }
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(intent.toString());
+ }
+
+ /**
+ * Factory to allocate an intent matcher.
+ *
+ * @param intent intent object we are looking for
+ * @return matcher
+ */
+ public static IntentJsonMatcher matchesIntent(Intent intent) {
+ return new IntentJsonMatcher(intent);
+ }
+}
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/MockCodecContext.java b/web/api/src/test/java/org/onosproject/codec/impl/MockCodecContext.java
index f54f523..f49e829 100644
--- a/web/api/src/test/java/org/onosproject/codec/impl/MockCodecContext.java
+++ b/web/api/src/test/java/org/onosproject/codec/impl/MockCodecContext.java
@@ -28,6 +28,9 @@
private ObjectMapper mapper = new ObjectMapper();
private CodecManager manager = new CodecManager();
+ /**
+ * Constructs a new mock codec context.
+ */
public MockCodecContext() {
manager.activate();
}