Ray Milkey

Unit tets for instruction JSON codecs

Fixed several bugs in codecs turned up by unit tests

Change-Id: Icddb31aa3d2cb58612a0578772d24ff5f113d073
...@@ -43,6 +43,13 @@ ...@@ -43,6 +43,13 @@
43 <artifactId>easymock</artifactId> 43 <artifactId>easymock</artifactId>
44 <scope>test</scope> 44 <scope>test</scope>
45 </dependency> 45 </dependency>
46 + <dependency>
47 + <groupId>org.onosproject</groupId>
48 + <artifactId>onos-api</artifactId>
49 + <version>${project.version}</version>
50 + <scope>test</scope>
51 + <classifier>tests</classifier>
52 + </dependency>
46 </dependencies> 53 </dependencies>
47 54
48 <properties> 55 <properties>
......
...@@ -20,8 +20,10 @@ import org.onosproject.codec.JsonCodec; ...@@ -20,8 +20,10 @@ import org.onosproject.codec.JsonCodec;
20 import org.onosproject.net.flow.TrafficSelector; 20 import org.onosproject.net.flow.TrafficSelector;
21 import org.onosproject.net.flow.TrafficTreatment; 21 import org.onosproject.net.flow.TrafficTreatment;
22 import org.onosproject.net.intent.ConnectivityIntent; 22 import org.onosproject.net.intent.ConnectivityIntent;
23 +import org.onosproject.net.intent.Constraint;
23 import org.onosproject.net.intent.Intent; 24 import org.onosproject.net.intent.Intent;
24 25
26 +import com.fasterxml.jackson.databind.node.ArrayNode;
25 import com.fasterxml.jackson.databind.node.ObjectNode; 27 import com.fasterxml.jackson.databind.node.ObjectNode;
26 28
27 import static com.google.common.base.Preconditions.checkNotNull; 29 import static com.google.common.base.Preconditions.checkNotNull;
...@@ -50,6 +52,17 @@ public class ConnectivityIntentCodec extends JsonCodec<ConnectivityIntent> { ...@@ -50,6 +52,17 @@ public class ConnectivityIntentCodec extends JsonCodec<ConnectivityIntent> {
50 result.set("treatment", treatmentCodec.encode(intent.treatment(), context)); 52 result.set("treatment", treatmentCodec.encode(intent.treatment(), context));
51 } 53 }
52 54
55 + if (intent.constraints() != null) {
56 + final ArrayNode jsonConstraints = result.putArray("constraints");
57 +
58 + if (intent.constraints() != null) {
59 + for (final Constraint constraint : intent.constraints()) {
60 + // TODO: constraint should have its own codec
61 + jsonConstraints.add(constraint.toString());
62 + }
63 + }
64 + }
65 +
53 return result; 66 return result;
54 } 67 }
55 } 68 }
......
...@@ -50,6 +50,7 @@ public class CriterionCodec extends JsonCodec<Criterion> { ...@@ -50,6 +50,7 @@ public class CriterionCodec extends JsonCodec<Criterion> {
50 case ETH_SRC: 50 case ETH_SRC:
51 case ETH_DST: 51 case ETH_DST:
52 final Criteria.EthCriterion ethCriterion = (Criteria.EthCriterion) criterion; 52 final Criteria.EthCriterion ethCriterion = (Criteria.EthCriterion) criterion;
53 + result.put("mac", ethCriterion.mac().toString());
53 break; 54 break;
54 55
55 case ETH_TYPE: 56 case ETH_TYPE:
...@@ -60,6 +61,8 @@ public class CriterionCodec extends JsonCodec<Criterion> { ...@@ -60,6 +61,8 @@ public class CriterionCodec extends JsonCodec<Criterion> {
60 61
61 case IPV4_SRC: 62 case IPV4_SRC:
62 case IPV6_SRC: 63 case IPV6_SRC:
64 + case IPV4_DST:
65 + case IPV6_DST:
63 final Criteria.IPCriterion iPCriterion = (Criteria.IPCriterion) criterion; 66 final Criteria.IPCriterion iPCriterion = (Criteria.IPCriterion) criterion;
64 result.put("ip", iPCriterion.ip().toString()); 67 result.put("ip", iPCriterion.ip().toString());
65 break; 68 break;
......
1 +/*
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 + */
16 +package org.onosproject.codec.impl;
17 +
18 +import org.hamcrest.Description;
19 +import org.hamcrest.TypeSafeDiagnosingMatcher;
20 +import org.onosproject.net.ConnectPoint;
21 +
22 +import com.fasterxml.jackson.databind.JsonNode;
23 +
24 +/**
25 + * Hamcrest matcher for connect points.
26 + */
27 +
28 +public final class ConnectPointJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
29 +
30 + private final ConnectPoint connectPoint;
31 +
32 + private ConnectPointJsonMatcher(ConnectPoint connectPointValue) {
33 + connectPoint = connectPointValue;
34 + }
35 +
36 + @Override
37 + public boolean matchesSafely(JsonNode jsonConnectPoint, Description description) {
38 + // check device
39 + final String jsonDevice = jsonConnectPoint.get("device").asText();
40 + final String device = connectPoint.deviceId().toString();
41 + if (!jsonDevice.equals(device)) {
42 + description.appendText("device was " + jsonDevice);
43 + return false;
44 + }
45 +
46 + // check port
47 + final String jsonPort = jsonConnectPoint.get("port").asText();
48 + final String port = connectPoint.port().toString();
49 + if (!jsonPort.equals(port)) {
50 + description.appendText("port was " + jsonPort);
51 + return false;
52 + }
53 +
54 + return true;
55 + }
56 +
57 + @Override
58 + public void describeTo(Description description) {
59 + description.appendText(connectPoint.toString());
60 + }
61 +
62 + /**
63 + * Factory to allocate an connect point matcher.
64 + *
65 + * @param connectPoint connect point object we are looking for
66 + * @return matcher
67 + */
68 + public static ConnectPointJsonMatcher matchesConnectPoint(ConnectPoint connectPoint) {
69 + return new ConnectPointJsonMatcher(connectPoint);
70 + }
71 +}
1 +/*
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 + */
16 +package org.onosproject.codec.impl;
17 +
18 +import org.hamcrest.Description;
19 +import org.hamcrest.TypeSafeDiagnosingMatcher;
20 +import org.onosproject.net.flow.criteria.Criteria;
21 +import org.onosproject.net.flow.criteria.Criterion;
22 +
23 +import com.fasterxml.jackson.databind.JsonNode;
24 +
25 +/**
26 + * Hamcrest matcher for criterion objects.
27 + */
28 +public final class CriterionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
29 +
30 + final Criterion criterion;
31 +
32 + private CriterionJsonMatcher(Criterion criterionValue) {
33 + criterion = criterionValue;
34 + }
35 +
36 + @Override
37 + public boolean matchesSafely(JsonNode jsonCriterion, Description description) {
38 + final String type = criterion.type().name();
39 + final String jsonType = jsonCriterion.get("type").asText();
40 + if (!type.equals(jsonType)) {
41 + description.appendText("type was " + type);
42 + return false;
43 + }
44 +
45 + switch (criterion.type()) {
46 +
47 + case IN_PORT:
48 + final Criteria.PortCriterion portCriterion = (Criteria.PortCriterion) criterion;
49 + final long port = portCriterion.port().toLong();
50 + final long jsonPort = jsonCriterion.get("port").asLong();
51 + if (port != jsonPort) {
52 + description.appendText("port was " + Long.toString(jsonPort));
53 + return false;
54 + }
55 + break;
56 +
57 + case ETH_SRC:
58 + case ETH_DST:
59 + final Criteria.EthCriterion ethCriterion = (Criteria.EthCriterion) criterion;
60 + final String mac = ethCriterion.mac().toString();
61 + final String jsonMac = jsonCriterion.get("mac").textValue();
62 + if (!mac.equals(jsonMac)) {
63 + description.appendText("mac was " + jsonMac);
64 + return false;
65 + }
66 + break;
67 +
68 + case ETH_TYPE:
69 + final Criteria.EthTypeCriterion ethTypeCriterion =
70 + (Criteria.EthTypeCriterion) criterion;
71 + final String ethType = ethTypeCriterion.ethType().toString();
72 + final String jsonEthType = jsonCriterion.get("ethType").textValue();
73 + if (!ethType.equals(jsonEthType)) {
74 + description.appendText("ethType was " + jsonEthType);
75 + return false;
76 + }
77 + break;
78 +
79 + case IPV4_SRC:
80 + case IPV6_SRC:
81 + case IPV4_DST:
82 + case IPV6_DST:
83 + final Criteria.IPCriterion ipCriterion = (Criteria.IPCriterion) criterion;
84 + final String ip = ipCriterion.ip().toString();
85 + final String jsonIp = jsonCriterion.get("ip").textValue();
86 + if (!ip.equals(jsonIp)) {
87 + description.appendText("ip was " + jsonIp);
88 + return false;
89 + }
90 + break;
91 +
92 + case IP_PROTO:
93 + final Criteria.IPProtocolCriterion iPProtocolCriterion =
94 + (Criteria.IPProtocolCriterion) criterion;
95 + final byte protocol = iPProtocolCriterion.protocol();
96 + final byte jsonProtocol = (byte) jsonCriterion.get("protocol").shortValue();
97 + if (protocol != jsonProtocol) {
98 + description.appendText("protocol was " + Byte.toString(jsonProtocol));
99 + return false;
100 + }
101 + break;
102 +
103 + case VLAN_PCP:
104 + final Criteria.VlanPcpCriterion vlanPcpCriterion =
105 + (Criteria.VlanPcpCriterion) criterion;
106 + final byte priority = vlanPcpCriterion.priority();
107 + final byte jsonPriority = (byte) jsonCriterion.get("protocol").shortValue();
108 + if (priority != jsonPriority) {
109 + description.appendText("priority was " + Byte.toString(jsonPriority));
110 + return false;
111 + }
112 + break;
113 +
114 + case VLAN_VID:
115 + final Criteria.VlanIdCriterion vlanIdCriterion =
116 + (Criteria.VlanIdCriterion) criterion;
117 + final short vlanId = vlanIdCriterion.vlanId().toShort();
118 + final short jsonvlanId = jsonCriterion.get("vlanId").shortValue();
119 + if (vlanId != jsonvlanId) {
120 + description.appendText("vlanId was " + Short.toString(jsonvlanId));
121 + return false;
122 + }
123 + break;
124 +
125 + case TCP_SRC:
126 + case TCP_DST:
127 + final Criteria.TcpPortCriterion tcpPortCriterion =
128 + (Criteria.TcpPortCriterion) criterion;
129 + final byte tcpPort = tcpPortCriterion.tcpPort().byteValue();
130 + final byte jsonTcpPort = (byte) jsonCriterion.get("tcpPort").shortValue();
131 + if (tcpPort != jsonTcpPort) {
132 + description.appendText("tcp port was " + Byte.toString(jsonTcpPort));
133 + return false;
134 + }
135 + break;
136 +
137 + case MPLS_LABEL:
138 + final Criteria.MplsCriterion mplsCriterion =
139 + (Criteria.MplsCriterion) criterion;
140 + final int label = mplsCriterion.label();
141 + final int jsonLabel = jsonCriterion.get("label").intValue();
142 + if (label != jsonLabel) {
143 + description.appendText("label was " + Integer.toString(jsonLabel));
144 + return false;
145 + }
146 + break;
147 +
148 + case OCH_SIGID:
149 + final Criteria.LambdaCriterion lambdaCriterion =
150 + (Criteria.LambdaCriterion) criterion;
151 + final short lambda = lambdaCriterion.lambda();
152 + final short jsonLambda = jsonCriterion.get("lambda").shortValue();
153 + if (lambda != jsonLambda) {
154 + description.appendText("lambda was " + Short.toString(lambda));
155 + return false;
156 + }
157 + break;
158 +
159 + case OCH_SIGTYPE:
160 + final Criteria.OpticalSignalTypeCriterion opticalSignalTypeCriterion =
161 + (Criteria.OpticalSignalTypeCriterion) criterion;
162 + final short signalType = opticalSignalTypeCriterion.signalType();
163 + final short jsonSignalType = jsonCriterion.get("signalType").shortValue();
164 + if (signalType != jsonSignalType) {
165 + description.appendText("signal type was " + Short.toString(signalType));
166 + return false;
167 + }
168 + break;
169 +
170 + default:
171 + // Don't know how to format this type
172 + description.appendText("unknown criterion type " +
173 + criterion.type());
174 + return false;
175 + }
176 + return true;
177 + }
178 +
179 + @Override
180 + public void describeTo(Description description) {
181 + description.appendText(criterion.toString());
182 + }
183 +
184 + /**
185 + * Factory to allocate an criterion matcher.
186 + *
187 + * @param criterion criterion object we are looking for
188 + * @return matcher
189 + */
190 + public static CriterionJsonMatcher matchesCriterion(Criterion criterion) {
191 + return new CriterionJsonMatcher(criterion);
192 + }
193 +}
...@@ -24,12 +24,12 @@ import com.fasterxml.jackson.databind.JsonNode; ...@@ -24,12 +24,12 @@ import com.fasterxml.jackson.databind.JsonNode;
24 /** 24 /**
25 * Hamcrest matcher for ethernet objects. 25 * Hamcrest matcher for ethernet objects.
26 */ 26 */
27 -public class EthernetJsonMatcher extends TypeSafeMatcher<JsonNode> { 27 +public final class EthernetJsonMatcher extends TypeSafeMatcher<JsonNode> {
28 28
29 private final Ethernet ethernet; 29 private final Ethernet ethernet;
30 private String reason = ""; 30 private String reason = "";
31 31
32 - public EthernetJsonMatcher(Ethernet ethernetValue) { 32 + private EthernetJsonMatcher(Ethernet ethernetValue) {
33 ethernet = ethernetValue; 33 ethernet = ethernetValue;
34 } 34 }
35 35
......
...@@ -44,7 +44,7 @@ public class InstructionCodecTest { ...@@ -44,7 +44,7 @@ public class InstructionCodecTest {
44 JsonCodec<Instruction> instructionCodec; 44 JsonCodec<Instruction> instructionCodec;
45 45
46 /** 46 /**
47 - * Sets up for each tests. Creates a context and fetches the instruction 47 + * Sets up for each test. Creates a context and fetches the instruction
48 * codec. 48 * codec.
49 */ 49 */
50 @Before 50 @Before
......
...@@ -31,11 +31,11 @@ import static org.onosproject.net.flow.instructions.L3ModificationInstruction.*; ...@@ -31,11 +31,11 @@ import static org.onosproject.net.flow.instructions.L3ModificationInstruction.*;
31 /** 31 /**
32 * Hamcrest matcher for instructions. 32 * Hamcrest matcher for instructions.
33 */ 33 */
34 -public class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> { 34 +public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
35 35
36 private final Instruction instruction; 36 private final Instruction instruction;
37 37
38 - public InstructionJsonMatcher(Instruction instructionValue) { 38 + private InstructionJsonMatcher(Instruction instructionValue) {
39 instruction = instructionValue; 39 instruction = instructionValue;
40 } 40 }
41 41
...@@ -134,7 +134,7 @@ public class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> ...@@ -134,7 +134,7 @@ public class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode>
134 } 134 }
135 135
136 /** 136 /**
137 - * Matches the contents of a mod lambda instruction. 137 + * Matches the contents of a mod Ethernet instruction.
138 * 138 *
139 * @param instructionJson JSON instruction to match 139 * @param instructionJson JSON instruction to match
140 * @return true if contents match, false otherwise 140 * @return true if contents match, false otherwise
...@@ -262,7 +262,7 @@ public class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> ...@@ -262,7 +262,7 @@ public class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode>
262 } 262 }
263 263
264 /** 264 /**
265 - * Matches the contents of a mod ip instruction. 265 + * Matches the contents of a mod MPLS label instruction.
266 * 266 *
267 * @param instructionJson JSON instruction to match 267 * @param instructionJson JSON instruction to match
268 * @return true if contents match, false otherwise 268 * @return true if contents match, false otherwise
......
1 +/*
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 + */
16 +package org.onosproject.codec.impl;
17 +
18 +import java.util.List;
19 +
20 +import org.junit.Test;
21 +import org.onlab.packet.IpPrefix;
22 +import org.onlab.packet.MacAddress;
23 +import org.onosproject.codec.CodecContext;
24 +import org.onosproject.codec.JsonCodec;
25 +import org.onosproject.core.ApplicationId;
26 +import org.onosproject.core.DefaultApplicationId;
27 +import org.onosproject.net.ConnectPoint;
28 +import org.onosproject.net.HostId;
29 +import org.onosproject.net.NetTestTools;
30 +import org.onosproject.net.PortNumber;
31 +import org.onosproject.net.flow.DefaultTrafficSelector;
32 +import org.onosproject.net.flow.DefaultTrafficTreatment;
33 +import org.onosproject.net.flow.TrafficSelector;
34 +import org.onosproject.net.flow.TrafficTreatment;
35 +import org.onosproject.net.intent.Constraint;
36 +import org.onosproject.net.intent.HostToHostIntent;
37 +import org.onosproject.net.intent.AbstractIntentTest;
38 +import org.onosproject.net.intent.PointToPointIntent;
39 +import org.onosproject.net.intent.constraint.BandwidthConstraint;
40 +import org.onosproject.net.intent.constraint.LambdaConstraint;
41 +import org.onosproject.net.resource.Bandwidth;
42 +import org.onosproject.net.resource.Lambda;
43 +
44 +import com.fasterxml.jackson.databind.node.ObjectNode;
45 +import com.google.common.collect.ImmutableList;
46 +
47 +import static org.onosproject.codec.impl.IntentJsonMatcher.matchesIntent;
48 +import static org.onosproject.net.NetTestTools.hid;
49 +
50 +
51 +import static org.hamcrest.MatcherAssert.assertThat;
52 +import static org.hamcrest.Matchers.notNullValue;
53 +
54 +/**
55 + * Unit tests for the host to host intent class codec.
56 + */
57 +public class IntentCodecTest extends AbstractIntentTest {
58 +
59 + private final HostId id1 = hid("12:34:56:78:91:ab/1");
60 + private final HostId id2 = hid("12:34:56:78:92:ab/1");
61 + private final ApplicationId appId =
62 + new DefaultApplicationId((short) 3, "test");
63 + final TrafficSelector emptySelector =
64 + DefaultTrafficSelector.builder().build();
65 + final TrafficTreatment emptyTreatment =
66 + DefaultTrafficTreatment.builder().build();
67 + private final CodecContext context = new MockCodecContext();
68 +
69 + /**
70 + * Tests the encoding of a host to host intent.
71 + */
72 + @Test
73 + public void hostToHostIntent() {
74 + final HostToHostIntent intent =
75 + new HostToHostIntent(appId, id1, id2);
76 +
77 + final JsonCodec<HostToHostIntent> intentCodec =
78 + context.codec(HostToHostIntent.class);
79 + assertThat(intentCodec, notNullValue());
80 +
81 + final ObjectNode intentJson = intentCodec.encode(intent, context);
82 + assertThat(intentJson, matchesIntent(intent));
83 + }
84 +
85 + /**
86 + * Tests the encoding of a point to point intent.
87 + */
88 + @Test
89 + public void pointToPointIntent() {
90 + ConnectPoint ingress = NetTestTools.connectPoint("ingress", 1);
91 + ConnectPoint egress = NetTestTools.connectPoint("egress", 2);
92 +
93 + final PointToPointIntent intent =
94 + new PointToPointIntent(appId, emptySelector,
95 + emptyTreatment, ingress, egress);
96 +
97 + final CodecContext context = new MockCodecContext();
98 + final JsonCodec<PointToPointIntent> intentCodec =
99 + context.codec(PointToPointIntent.class);
100 + assertThat(intentCodec, notNullValue());
101 +
102 + final ObjectNode intentJson = intentCodec.encode(intent, context);
103 + assertThat(intentJson, matchesIntent(intent));
104 + }
105 +
106 + /**
107 + * Tests the encoding of an intent with treatment, selector and constraints
108 + * specified.
109 + */
110 + @Test
111 + public void intentWithTreatmentSelectorAndConstraints() {
112 + ConnectPoint ingress = NetTestTools.connectPoint("ingress", 1);
113 + ConnectPoint egress = NetTestTools.connectPoint("egress", 2);
114 + final TrafficSelector selector = DefaultTrafficSelector.builder()
115 + .matchIPProtocol((byte) 3)
116 + .matchMplsLabel(4)
117 + .matchOpticalSignalType((short) 5)
118 + .matchLambda((short) 6)
119 + .matchEthDst(MacAddress.BROADCAST)
120 + .matchIPDst(IpPrefix.valueOf("1.2.3.4/24"))
121 + .build();
122 + final TrafficTreatment treatment = DefaultTrafficTreatment.builder()
123 + .setLambda((short) 33)
124 + .setMpls(44)
125 + .setOutput(PortNumber.CONTROLLER)
126 + .setEthDst(MacAddress.BROADCAST)
127 + .build();
128 + final Constraint constraint1 = new BandwidthConstraint(Bandwidth.valueOf(1.0));
129 + final Constraint constraint2 = new LambdaConstraint(Lambda.valueOf(3));
130 + final List<Constraint> constraints = ImmutableList.of(constraint1, constraint2);
131 +
132 + final PointToPointIntent intent =
133 + new PointToPointIntent(appId, selector, treatment,
134 + ingress, egress, constraints);
135 +
136 + final CodecContext context = new MockCodecContext();
137 + final JsonCodec<PointToPointIntent> intentCodec =
138 + context.codec(PointToPointIntent.class);
139 + assertThat(intentCodec, notNullValue());
140 +
141 + final ObjectNode intentJson = intentCodec.encode(intent, context);
142 + assertThat(intentJson, matchesIntent(intent));
143 +
144 + }
145 +}
...@@ -28,6 +28,9 @@ public final class MockCodecContext implements CodecContext { ...@@ -28,6 +28,9 @@ public final class MockCodecContext implements CodecContext {
28 private ObjectMapper mapper = new ObjectMapper(); 28 private ObjectMapper mapper = new ObjectMapper();
29 private CodecManager manager = new CodecManager(); 29 private CodecManager manager = new CodecManager();
30 30
31 + /**
32 + * Constructs a new mock codec context.
33 + */
31 public MockCodecContext() { 34 public MockCodecContext() {
32 manager.activate(); 35 manager.activate();
33 } 36 }
......