/* * Copyright 2016-present 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 com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.collect.ImmutableSet; import org.hamcrest.Description; import org.hamcrest.TypeSafeDiagnosingMatcher; import org.junit.Before; import org.junit.Test; import org.onlab.packet.Ethernet; import org.onlab.packet.MacAddress; import org.onosproject.codec.JsonCodec; import org.onosproject.net.PortNumber; import org.onosproject.net.flow.DefaultTrafficSelector; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.criteria.Criteria; import org.onosproject.net.flow.criteria.Criterion; import java.io.IOException; import java.io.InputStream; import java.util.Set; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; /** * Unit tests for traffic selector codec. */ public class TrafficSelectorCodecTest { private MockCodecContext context; private JsonCodec<TrafficSelector> trafficSelectorCodec; @Before public void setUp() { context = new MockCodecContext(); trafficSelectorCodec = context.codec(TrafficSelector.class); assertThat(trafficSelectorCodec, notNullValue()); } /** * Tests encoding of a traffic selector object. */ @Test public void testTrafficSelectorEncode() { Criterion inPort = Criteria.matchInPort(PortNumber.portNumber(0)); Criterion ethSrc = Criteria.matchEthSrc(MacAddress.valueOf("11:22:33:44:55:66")); Criterion ethDst = Criteria.matchEthDst(MacAddress.valueOf("44:55:66:77:88:99")); Criterion ethType = Criteria.matchEthType(Ethernet.TYPE_IPV4); TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); TrafficSelector selector = sBuilder .add(inPort) .add(ethSrc) .add(ethDst) .add(ethType) .build(); ObjectNode selectorJson = trafficSelectorCodec.encode(selector, context); assertThat(selectorJson, TrafficSelectorJsonMatcher.matchesTrafficSelector(selector)); } /** * Tests decoding of a traffic selector JSON object. */ @Test public void testTrafficSelectorDecode() throws IOException { TrafficSelector selector = getSelector("TrafficSelector.json"); Set<Criterion> criteria = selector.criteria(); assertThat(criteria.size(), is(4)); ImmutableSet<String> types = ImmutableSet.of("IN_PORT", "ETH_SRC", "ETH_DST", "ETH_TYPE"); criteria.forEach(c -> assertThat(types.contains(c.type().name()), is(true))); } public static final class TrafficSelectorJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> { private final TrafficSelector trafficSelector; private TrafficSelectorJsonMatcher(TrafficSelector trafficSelector) { this.trafficSelector = trafficSelector; } @Override protected boolean matchesSafely(JsonNode jsonNode, Description description) { // check size of criteria JsonNode jsonCriteria = jsonNode.get("criteria"); if (jsonCriteria.size() != trafficSelector.criteria().size()) { description.appendText("criteria size was " + jsonCriteria.size()); return false; } // check criteria for (Criterion criterion : trafficSelector.criteria()) { boolean criterionFound = false; for (int criterionIndex = 0; criterionIndex < jsonCriteria.size(); criterionIndex++) { 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; } } return true; } @Override public void describeTo(Description description) { description.appendText(trafficSelector.toString()); } /** * Factory to allocate a traffic selector matcher. * * @param selector traffic selector object we are looking for * @return matcher */ static TrafficSelectorJsonMatcher matchesTrafficSelector(TrafficSelector selector) { return new TrafficSelectorJsonMatcher(selector); } } /** * Reads in a traffic selector from the given resource and decodes it. * * @param resourceName resource to use to read the JSON for the rule * @return decoded trafficSelector * @throws IOException if processing the resource fails */ private TrafficSelector getSelector(String resourceName) throws IOException { InputStream jsonStream = TrafficSelectorCodecTest.class.getResourceAsStream(resourceName); JsonNode json = context.mapper().readTree(jsonStream); assertThat(json, notNullValue()); TrafficSelector selector = trafficSelectorCodec.decode((ObjectNode) json, context); assertThat(selector, notNullValue()); return selector; } }