Jian Li
Committed by Gerrit Code Review

Add unit test for TrafficSelector Codec

Change-Id: Ibe84ce7955c40c20b3ed94482e0bebe6be28032e
1 +/*
2 + * Copyright 2016-present 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 com.fasterxml.jackson.databind.JsonNode;
19 +import com.fasterxml.jackson.databind.node.ObjectNode;
20 +import com.google.common.collect.ImmutableSet;
21 +import org.hamcrest.Description;
22 +import org.hamcrest.TypeSafeDiagnosingMatcher;
23 +import org.junit.Before;
24 +import org.junit.Test;
25 +import org.onlab.packet.Ethernet;
26 +import org.onlab.packet.MacAddress;
27 +import org.onosproject.codec.JsonCodec;
28 +import org.onosproject.net.PortNumber;
29 +import org.onosproject.net.flow.DefaultTrafficSelector;
30 +import org.onosproject.net.flow.TrafficSelector;
31 +import org.onosproject.net.flow.criteria.Criteria;
32 +import org.onosproject.net.flow.criteria.Criterion;
33 +
34 +import java.io.IOException;
35 +import java.io.InputStream;
36 +import java.util.Set;
37 +
38 +import static org.hamcrest.MatcherAssert.assertThat;
39 +import static org.hamcrest.Matchers.is;
40 +import static org.hamcrest.Matchers.notNullValue;
41 +
42 +/**
43 + * Unit tests for traffic selector codec.
44 + */
45 +public class TrafficSelectorCodecTest {
46 +
47 + private MockCodecContext context;
48 + private JsonCodec<TrafficSelector> trafficSelectorCodec;
49 +
50 + @Before
51 + public void setUp() {
52 + context = new MockCodecContext();
53 + trafficSelectorCodec = context.codec(TrafficSelector.class);
54 + assertThat(trafficSelectorCodec, notNullValue());
55 + }
56 +
57 + /**
58 + * Tests encoding of a traffic selector object.
59 + */
60 + @Test
61 + public void testTrafficSelectorEncode() {
62 +
63 + Criterion inPort = Criteria.matchInPort(PortNumber.portNumber(0));
64 + Criterion ethSrc = Criteria.matchEthSrc(MacAddress.valueOf("11:22:33:44:55:66"));
65 + Criterion ethDst = Criteria.matchEthDst(MacAddress.valueOf("44:55:66:77:88:99"));
66 + Criterion ethType = Criteria.matchEthType(Ethernet.TYPE_IPV4);
67 +
68 + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
69 + TrafficSelector selector = sBuilder
70 + .add(inPort)
71 + .add(ethSrc)
72 + .add(ethDst)
73 + .add(ethType)
74 + .build();
75 +
76 + ObjectNode selectorJson = trafficSelectorCodec.encode(selector, context);
77 + assertThat(selectorJson, TrafficSelectorJsonMatcher.matchesTrafficSelector(selector));
78 + }
79 +
80 + /**
81 + * Tests decoding of a traffic selector JSON object.
82 + */
83 + @Test
84 + public void testTrafficSelectorDecode() throws IOException {
85 + TrafficSelector selector = getSelector("TrafficSelector.json");
86 +
87 + Set<Criterion> criteria = selector.criteria();
88 + assertThat(criteria.size(), is(4));
89 +
90 + ImmutableSet<String> types = ImmutableSet.of("IN_PORT", "ETH_SRC", "ETH_DST", "ETH_TYPE");
91 +
92 + criteria.forEach(c -> assertThat(types.contains(c.type().name()), is(true)));
93 + }
94 +
95 + public static final class TrafficSelectorJsonMatcher
96 + extends TypeSafeDiagnosingMatcher<JsonNode> {
97 + private final TrafficSelector trafficSelector;
98 +
99 + private TrafficSelectorJsonMatcher(TrafficSelector trafficSelector) {
100 + this.trafficSelector = trafficSelector;
101 + }
102 +
103 + @Override
104 + protected boolean matchesSafely(JsonNode jsonNode, Description description) {
105 + // check size of criteria
106 + JsonNode jsonCriteria = jsonNode.get("criteria");
107 + if (jsonCriteria.size() != trafficSelector.criteria().size()) {
108 + description.appendText("criteria size was " + jsonCriteria.size());
109 + return false;
110 + }
111 +
112 + // check criteria
113 + for (Criterion criterion : trafficSelector.criteria()) {
114 + boolean criterionFound = false;
115 + for (int criterionIndex = 0; criterionIndex < jsonCriteria.size(); criterionIndex++) {
116 + CriterionJsonMatcher criterionMatcher = CriterionJsonMatcher.matchesCriterion(criterion);
117 + if (criterionMatcher.matches(jsonCriteria.get(criterionIndex))) {
118 + criterionFound = true;
119 + break;
120 + }
121 + }
122 +
123 + if (!criterionFound) {
124 + description.appendText("criterion not found " + criterion.toString());
125 + return false;
126 + }
127 + }
128 +
129 + return true;
130 + }
131 +
132 + @Override
133 + public void describeTo(Description description) {
134 + description.appendText(trafficSelector.toString());
135 + }
136 +
137 + /**
138 + * Factory to allocate a traffic selector matcher.
139 + *
140 + * @param selector traffic selector object we are looking for
141 + * @return matcher
142 + */
143 + static TrafficSelectorJsonMatcher matchesTrafficSelector(TrafficSelector selector) {
144 + return new TrafficSelectorJsonMatcher(selector);
145 + }
146 + }
147 +
148 + /**
149 + * Reads in a traffic selector from the given resource and decodes it.
150 + *
151 + * @param resourceName resource to use to read the JSON for the rule
152 + * @return decoded trafficSelector
153 + * @throws IOException if processing the resource fails
154 + */
155 + private TrafficSelector getSelector(String resourceName) throws IOException {
156 + InputStream jsonStream = TrafficSelectorCodecTest.class.getResourceAsStream(resourceName);
157 + JsonNode json = context.mapper().readTree(jsonStream);
158 + assertThat(json, notNullValue());
159 + TrafficSelector selector = trafficSelectorCodec.decode((ObjectNode) json, context);
160 + assertThat(selector, notNullValue());
161 + return selector;
162 + }
163 +}
1 +{
2 + "criteria": [
3 + {
4 + "type": "IN_PORT",
5 + "port": -3
6 + },
7 + {
8 + "type": "ETH_SRC",
9 + "mac": "11:22:33:44:55:66"
10 + },
11 + {
12 + "type": "ETH_DST",
13 + "mac": "44:55:66:77:88:99"
14 + },
15 + {
16 + "type": "ETH_TYPE",
17 + "ethType": 2054
18 + }
19 + ]
20 +}
...\ No newline at end of file ...\ No newline at end of file