Ray Milkey

Unit tests for Instruction and Ethernet codecs

Added tests for codecs for Ethernet and Instruction classes
Also fixed some bugs uncovered by the tests

Change-Id: I29f82d169e81b3fca417f88fab992148bf36dc71
......@@ -94,6 +94,8 @@ public class InstructionsTest {
assertThatClassIsImmutable(L2ModificationInstruction.ModVlanIdInstruction.class);
assertThatClassIsImmutable(L2ModificationInstruction.ModVlanPcpInstruction.class);
assertThatClassIsImmutable(L3ModificationInstruction.ModIPInstruction.class);
assertThatClassIsImmutable(L2ModificationInstruction.ModMplsLabelInstruction.class);
assertThatClassIsImmutable(L2ModificationInstruction.PushHeaderInstructions.class);
}
// DropInstruction
......
......@@ -36,13 +36,23 @@ public class EthernetCodec extends JsonCodec<Ethernet> {
public ObjectNode encode(Ethernet ethernet, CodecContext context) {
checkNotNull(ethernet, "Ethernet cannot be null");
return context.mapper().createObjectNode()
.put("destinationMacAddress", ethernet.getDestinationMAC().toString())
.put("sourceMacAddress", ethernet.getSourceMAC().toString())
.put("priorityCode", ethernet.getPriorityCode())
final ObjectNode result = context.mapper().createObjectNode()
.put("vlanId", ethernet.getVlanID())
.put("etherType", ethernet.getEtherType())
.put("priorityCode", ethernet.getPriorityCode())
.put("pad", ethernet.isPad());
if (ethernet.getDestinationMAC() != null) {
result.put("destMac",
ethernet.getDestinationMAC().toString());
}
if (ethernet.getSourceMAC() != null) {
result.put("srcMac",
ethernet.getSourceMAC().toString());
}
return result;
}
}
......
......@@ -147,7 +147,7 @@ public class InstructionCodec extends JsonCodec<Instruction> {
case OUTPUT:
final Instructions.OutputInstruction outputInstruction =
(Instructions.OutputInstruction) instruction;
result.put("portNumber", outputInstruction.port().toLong());
result.put("port", outputInstruction.port().toLong());
break;
case DROP:
......
/*
* 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.junit.Test;
import org.onlab.packet.Ethernet;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import com.fasterxml.jackson.databind.node.ObjectNode;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;
import static org.onosproject.codec.impl.EthernetJsonMatcher.matchesEthernet;
/**
* Unit test for Ethernet class codec.
*/
public class EthernetCodecTest {
/**
* Unit test for the ethernet object codec.
*/
@Test
public void ethernetCodecTest() {
final CodecContext context = new MockCodecContext();
final JsonCodec<Ethernet> ethernetCodec = context.codec(Ethernet.class);
assertThat(ethernetCodec, notNullValue());
final Ethernet eth1 = new Ethernet();
eth1.setSourceMACAddress("11:22:33:44:55:01");
eth1.setDestinationMACAddress("11:22:33:44:55:02");
eth1.setPad(true);
eth1.setEtherType(Ethernet.TYPE_ARP);
eth1.setPriorityCode((byte) 7);
eth1.setVlanID((short) 33);
final ObjectNode eth1Json = ethernetCodec.encode(eth1, context);
assertThat(eth1Json, notNullValue());
assertThat(eth1Json, matchesEthernet(eth1));
}
}
/*
* 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.TypeSafeMatcher;
import org.onlab.packet.Ethernet;
import com.fasterxml.jackson.databind.JsonNode;
/**
* Hamcrest matcher for ethernet objects.
*/
public class EthernetJsonMatcher extends TypeSafeMatcher<JsonNode> {
private final Ethernet ethernet;
private String reason = "";
public EthernetJsonMatcher(Ethernet ethernetValue) {
ethernet = ethernetValue;
}
@Override
public boolean matchesSafely(JsonNode jsonEthernet) {
// check source MAC
final JsonNode jsonSourceMacNode = jsonEthernet.get("srcMac");
if (ethernet.getSourceMAC() != null) {
final String jsonSourceMac = jsonSourceMacNode.textValue();
final String sourceMac = ethernet.getSourceMAC().toString();
if (!jsonSourceMac.equals(sourceMac)) {
reason = "source MAC " + ethernet.getSourceMAC().toString();
return false;
}
} else {
// source MAC not specified, JSON representation must be empty
if (jsonSourceMacNode != null) {
reason = "source mac should be null ";
return false;
}
}
// check destination MAC
final JsonNode jsonDestinationMacNode = jsonEthernet.get("destMac");
if (ethernet.getDestinationMAC() != null) {
final String jsonDestinationMac = jsonDestinationMacNode.textValue();
final String destinationMac = ethernet.getDestinationMAC().toString();
if (!jsonDestinationMac.equals(destinationMac)) {
reason = "destination MAC " + ethernet.getDestinationMAC().toString();
return false;
}
} else {
// destination MAC not specified, JSON representation must be empty
if (jsonDestinationMacNode != null) {
reason = "destination mac should be null ";
return false;
}
}
// check priority code
final short jsonPriorityCode = jsonEthernet.get("priorityCode").shortValue();
final short priorityCode = ethernet.getPriorityCode();
if (jsonPriorityCode != priorityCode) {
reason = "priority code " + Short.toString(ethernet.getPriorityCode());
return false;
}
// check vlanId
final short jsonVlanId = jsonEthernet.get("vlanId").shortValue();
final short vlanId = ethernet.getVlanID();
if (jsonVlanId != vlanId) {
reason = "vlan id " + Short.toString(ethernet.getVlanID());
return false;
}
// check etherType
final short jsonEtherType = jsonEthernet.get("etherType").shortValue();
final short etherType = ethernet.getEtherType();
if (jsonEtherType != etherType) {
reason = "etherType " + Short.toString(ethernet.getEtherType());
return false;
}
// check pad
final boolean jsonPad = jsonEthernet.get("pad").asBoolean();
final boolean pad = ethernet.isPad();
if (jsonPad != pad) {
reason = "pad " + Boolean.toString(ethernet.isPad());
return false;
}
return true;
}
@Override
public void describeTo(Description description) {
description.appendText(reason);
}
/**
* Factory to allocate a ethernet matcher.
*
* @param ethernet ethernet object we are looking for
* @return matcher
*/
public static EthernetJsonMatcher matchesEthernet(Ethernet ethernet) {
return new EthernetJsonMatcher(ethernet);
}
}
/*
* 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.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import com.fasterxml.jackson.databind.node.ObjectNode;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;
import static org.onosproject.codec.impl.InstructionJsonMatcher.matchesInstruction;
/**
* Unit tests for Instruction codec.
*/
public class InstructionCodecTest {
CodecContext context;
JsonCodec<Instruction> instructionCodec;
/**
* Sets up for each tests. Creates a context and fetches the instruction
* codec.
*/
@Before
public void setUp() {
context = new MockCodecContext();
instructionCodec = context.codec(Instruction.class);
assertThat(instructionCodec, notNullValue());
}
/**
* Tests the encoding of push header instructions.
*/
@Test
public void pushHeaderInstructionsTest() {
final L2ModificationInstruction.PushHeaderInstructions instruction =
(L2ModificationInstruction.PushHeaderInstructions) Instructions.pushMpls();
final ObjectNode instructionJson = instructionCodec.encode(instruction, context);
assertThat(instructionJson, matchesInstruction(instruction));
}
/**
* Tests the encoding of drop instructions.
*/
@Test
public void dropInstructionTest() {
final Instructions.DropInstruction instruction =
new Instructions.DropInstruction();
final ObjectNode instructionJson =
instructionCodec.encode(instruction, context);
assertThat(instructionJson, matchesInstruction(instruction));
}
/**
* Tests the encoding of output instructions.
*/
@Test
public void outputInstructionTest() {
final Instructions.OutputInstruction instruction =
Instructions.createOutput(PortNumber.portNumber(22));
final ObjectNode instructionJson =
instructionCodec.encode(instruction, context);
assertThat(instructionJson, matchesInstruction(instruction));
}
/**
* Tests the encoding of mod lambda instructions.
*/
@Test
public void modLambdaInstructionTest() {
final L0ModificationInstruction.ModLambdaInstruction instruction =
(L0ModificationInstruction.ModLambdaInstruction)
Instructions.modL0Lambda((short) 55);
final ObjectNode instructionJson =
instructionCodec.encode(instruction, context);
assertThat(instructionJson, matchesInstruction(instruction));
}
/**
* Tests the encoding of mod ether instructions.
*/
@Test
public void modEtherInstructionTest() {
final L2ModificationInstruction.ModEtherInstruction instruction =
(L2ModificationInstruction.ModEtherInstruction)
Instructions.modL2Src(MacAddress.valueOf("11:22:33:44:55:66"));
final ObjectNode instructionJson =
instructionCodec.encode(instruction, context);
assertThat(instructionJson, matchesInstruction(instruction));
}
/**
* Tests the encoding of mod vlan id instructions.
*/
@Test
public void modVlanIdInstructionTest() {
final L2ModificationInstruction.ModVlanIdInstruction instruction =
(L2ModificationInstruction.ModVlanIdInstruction)
Instructions.modVlanId(VlanId.vlanId((short) 12));
final ObjectNode instructionJson =
instructionCodec.encode(instruction, context);
assertThat(instructionJson, matchesInstruction(instruction));
}
/**
* Tests the encoding of mod vlan pcp instructions.
*/
@Test
public void modVlanPcpInstructionTest() {
final L2ModificationInstruction.ModVlanPcpInstruction instruction =
(L2ModificationInstruction.ModVlanPcpInstruction)
Instructions.modVlanPcp((byte) 9);
final ObjectNode instructionJson =
instructionCodec.encode(instruction, context);
assertThat(instructionJson, matchesInstruction(instruction));
}
/**
* Tests the encoding of mod ip instructions.
*/
@Test
public void modIPInstructionTest() {
final IpAddress ip = IpPrefix.valueOf("1.2.3.4/24").address();
final L3ModificationInstruction.ModIPInstruction instruction =
(L3ModificationInstruction.ModIPInstruction)
Instructions.modL3Src(ip);
final ObjectNode instructionJson =
instructionCodec.encode(instruction, context);
assertThat(instructionJson, matchesInstruction(instruction));
}
/**
* Tests the encoding of mod MPLS label instructions.
*/
@Test
public void modMplsLabelInstructionTest() {
final L2ModificationInstruction.ModMplsLabelInstruction instruction =
(L2ModificationInstruction.ModMplsLabelInstruction)
Instructions.modMplsLabel(99);
final ObjectNode instructionJson =
instructionCodec.encode(instruction, context);
assertThat(instructionJson, matchesInstruction(instruction));
}
}
/*
* 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.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* Mock codec context for use in codec unit tests.
*/
public final class MockCodecContext implements CodecContext {
private ObjectMapper mapper = new ObjectMapper();
private CodecManager manager = new CodecManager();
public MockCodecContext() {
manager.activate();
}
@Override
public ObjectMapper mapper() {
return mapper;
}
@Override
@SuppressWarnings("unchecked")
public <T> JsonCodec<T> codec(Class<T> entityClass) {
return manager.getCodec(entityClass);
}
@Override
public <T> T get(Class<T> serviceClass) {
return null;
}
}