aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/FlowRuleCodecTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/FlowRuleCodecTest.java')
-rw-r--r--framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/FlowRuleCodecTest.java546
1 files changed, 546 insertions, 0 deletions
diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/FlowRuleCodecTest.java b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/FlowRuleCodecTest.java
new file mode 100644
index 00000000..6c88ac1e
--- /dev/null
+++ b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/FlowRuleCodecTest.java
@@ -0,0 +1,546 @@
+/*
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.GridType;
+import org.onosproject.net.Lambda;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.IPDscpCriterion;
+import org.onosproject.net.flow.criteria.IPEcnCriterion;
+import org.onosproject.net.flow.criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
+import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
+import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
+import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
+import org.onosproject.net.flow.criteria.IndexedLambdaCriterion;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.OchSignalCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.SctpPortCriterion;
+import org.onosproject.net.flow.criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.TunnelIdCriterion;
+import org.onosproject.net.flow.criteria.UdpPortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.criteria.VlanPcpCriterion;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+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 org.onosproject.net.flow.instructions.L4ModificationInstruction;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onosproject.net.NetTestTools.APP_ID;
+
+/**
+ * Flow rule codec unit tests.
+ */
+public class FlowRuleCodecTest {
+
+ MockCodecContext context;
+ JsonCodec<FlowRule> flowRuleCodec;
+ final CoreService mockCoreService = createMock(CoreService.class);
+
+ /**
+ * Sets up for each test. Creates a context and fetches the flow rule
+ * codec.
+ */
+ @Before
+ public void setUp() {
+ context = new MockCodecContext();
+ flowRuleCodec = context.codec(FlowRule.class);
+ assertThat(flowRuleCodec, notNullValue());
+
+ expect(mockCoreService.registerApplication(FlowRuleCodec.REST_APP_ID))
+ .andReturn(APP_ID).anyTimes();
+ replay(mockCoreService);
+ context.registerService(CoreService.class, mockCoreService);
+ }
+
+ /**
+ * Reads in a rule from the given resource and decodes it.
+ *
+ * @param resourceName resource to use to read the JSON for the rule
+ * @return decoded flow rule
+ * @throws IOException if processing the resource fails
+ */
+ private FlowRule getRule(String resourceName) throws IOException {
+ InputStream jsonStream = FlowRuleCodecTest.class
+ .getResourceAsStream(resourceName);
+ JsonNode json = context.mapper().readTree(jsonStream);
+ assertThat(json, notNullValue());
+ FlowRule rule = flowRuleCodec.decode((ObjectNode) json, context);
+ assertThat(rule, notNullValue());
+ return rule;
+ }
+
+ /**
+ * Checks that the data shared by all the resources is correct for a
+ * given rule.
+ *
+ * @param rule rule to check
+ */
+ private void checkCommonData(FlowRule rule) {
+ assertThat(rule.appId(), is(APP_ID.id()));
+ assertThat(rule.isPermanent(), is(false));
+ assertThat(rule.timeout(), is(1));
+ assertThat(rule.priority(), is(1));
+ assertThat(rule.deviceId().toString(), is("of:0000000000000001"));
+ }
+
+ /**
+ * Checks that a simple rule decodes properly.
+ *
+ * @throws IOException if the resource cannot be processed
+ */
+ @Test
+ public void codecSimpleFlowTest() throws IOException {
+ FlowRule rule = getRule("simple-flow.json");
+
+ checkCommonData(rule);
+
+ assertThat(rule.selector().criteria().size(), is(1));
+ Criterion criterion1 = rule.selector().criteria().iterator().next();
+ assertThat(criterion1.type(), is(Criterion.Type.ETH_TYPE));
+ assertThat(((EthTypeCriterion) criterion1).ethType(), is(new EthType(2054)));
+
+ assertThat(rule.treatment().allInstructions().size(), is(1));
+ Instruction instruction1 = rule.treatment().allInstructions().get(0);
+ assertThat(instruction1.type(), is(Instruction.Type.OUTPUT));
+ assertThat(((Instructions.OutputInstruction) instruction1).port(), is(PortNumber.CONTROLLER));
+ }
+
+ SortedMap<String, Instruction> instructions = new TreeMap<>();
+
+ /**
+ * Looks up an instruction in the instruction map based on type and subtype.
+ *
+ * @param type type string
+ * @param subType subtype string
+ * @return instruction that matches
+ */
+ private Instruction getInstruction(Instruction.Type type, String subType) {
+ Instruction instruction = instructions.get(type.name() + "/" + subType);
+ assertThat(instruction, notNullValue());
+ assertThat(instruction.type(), is(type));
+ return instruction;
+ }
+
+ /**
+ * Checks that a rule with one of each instruction type decodes properly.
+ *
+ * @throws IOException if the resource cannot be processed
+ */
+ @Test
+ public void decodeInstructionsFlowTest() throws Exception {
+ FlowRule rule = getRule("instructions-flow.json");
+
+ checkCommonData(rule);
+
+ rule.treatment().allInstructions()
+ .stream()
+ .forEach(instruction ->
+ {
+ String subType;
+ if (instruction.type() == Instruction.Type.L0MODIFICATION) {
+ subType = ((L0ModificationInstruction) instruction)
+ .subtype().name();
+ } else if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+ subType = ((L2ModificationInstruction) instruction)
+ .subtype().name();
+ } else if (instruction.type() == Instruction.Type.L3MODIFICATION) {
+ subType = ((L3ModificationInstruction) instruction)
+ .subtype().name();
+ } else if (instruction.type() == Instruction.Type.L4MODIFICATION) {
+ subType = ((L4ModificationInstruction) instruction)
+ .subtype().name();
+ } else {
+ subType = "";
+ }
+ instructions.put(
+ instruction.type().name() + "/" + subType, instruction);
+ });
+
+ assertThat(rule.treatment().allInstructions().size(), is(24));
+
+ Instruction instruction;
+
+ instruction = getInstruction(Instruction.Type.OUTPUT, "");
+ assertThat(instruction.type(), is(Instruction.Type.OUTPUT));
+ assertThat(((Instructions.OutputInstruction) instruction).port(), is(PortNumber.CONTROLLER));
+
+ instruction = getInstruction(Instruction.Type.L2MODIFICATION,
+ L2ModificationInstruction.L2SubType.ETH_SRC.name());
+ assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
+ assertThat(((L2ModificationInstruction.ModEtherInstruction) instruction).mac(),
+ is(MacAddress.valueOf("12:34:56:78:90:12")));
+
+ instruction = getInstruction(Instruction.Type.L2MODIFICATION,
+ L2ModificationInstruction.L2SubType.ETH_DST.name());
+ assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
+ assertThat(((L2ModificationInstruction.ModEtherInstruction) instruction).mac(),
+ is(MacAddress.valueOf("98:76:54:32:01:00")));
+
+ instruction = getInstruction(Instruction.Type.L2MODIFICATION,
+ L2ModificationInstruction.L2SubType.VLAN_ID.name());
+ assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
+ assertThat(((L2ModificationInstruction.ModVlanIdInstruction) instruction).vlanId().toShort(),
+ is((short) 22));
+
+ instruction = getInstruction(Instruction.Type.L2MODIFICATION,
+ L2ModificationInstruction.L2SubType.VLAN_PCP.name());
+ assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
+ assertThat(((L2ModificationInstruction.ModVlanPcpInstruction) instruction).vlanPcp(),
+ is((byte) 1));
+
+ instruction = getInstruction(Instruction.Type.L2MODIFICATION,
+ L2ModificationInstruction.L2SubType.MPLS_LABEL.name());
+ assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
+ assertThat(((L2ModificationInstruction.ModMplsLabelInstruction) instruction)
+ .mplsLabel().toInt(),
+ is(MplsLabel.MAX_MPLS));
+
+ instruction = getInstruction(Instruction.Type.L2MODIFICATION,
+ L2ModificationInstruction.L2SubType.MPLS_PUSH.name());
+ assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
+ assertThat(((L2ModificationInstruction.PushHeaderInstructions) instruction)
+ .ethernetType().toShort(),
+ is(Ethernet.MPLS_UNICAST));
+
+ instruction = getInstruction(Instruction.Type.L2MODIFICATION,
+ L2ModificationInstruction.L2SubType.MPLS_POP.name());
+ assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
+ assertThat(((L2ModificationInstruction.PushHeaderInstructions) instruction)
+ .ethernetType().toShort(),
+ is(Ethernet.MPLS_UNICAST));
+
+ instruction = getInstruction(Instruction.Type.L2MODIFICATION,
+ L2ModificationInstruction.L2SubType.DEC_MPLS_TTL.name());
+ assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
+ assertThat(instruction, instanceOf(L2ModificationInstruction.ModMplsTtlInstruction.class));
+
+ instruction = getInstruction(Instruction.Type.L2MODIFICATION,
+ L2ModificationInstruction.L2SubType.VLAN_POP.name());
+ assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
+ assertThat(instruction, instanceOf(L2ModificationInstruction.PopVlanInstruction.class));
+
+ instruction = getInstruction(Instruction.Type.L2MODIFICATION,
+ L2ModificationInstruction.L2SubType.VLAN_PUSH.name());
+ assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
+ assertThat(instruction, instanceOf(L2ModificationInstruction.PushHeaderInstructions.class));
+
+ instruction = getInstruction(Instruction.Type.L2MODIFICATION,
+ L2ModificationInstruction.L2SubType.TUNNEL_ID.name());
+ assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
+ assertThat(((L2ModificationInstruction.ModTunnelIdInstruction) instruction)
+ .tunnelId(), is(100L));
+
+ instruction = getInstruction(Instruction.Type.L3MODIFICATION,
+ L3ModificationInstruction.L3SubType.IPV4_SRC.name());
+ assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
+ assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(),
+ is(IpAddress.valueOf("1.2.3.4")));
+
+ instruction = getInstruction(Instruction.Type.L3MODIFICATION,
+ L3ModificationInstruction.L3SubType.IPV4_DST.name());
+ assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
+ assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(),
+ is(IpAddress.valueOf("1.2.3.3")));
+
+ instruction = getInstruction(Instruction.Type.L3MODIFICATION,
+ L3ModificationInstruction.L3SubType.IPV6_SRC.name());
+ assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
+ assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(),
+ is(IpAddress.valueOf("1.2.3.2")));
+
+ instruction = getInstruction(Instruction.Type.L3MODIFICATION,
+ L3ModificationInstruction.L3SubType.IPV6_DST.name());
+ assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
+ assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(),
+ is(IpAddress.valueOf("1.2.3.1")));
+
+ instruction = getInstruction(Instruction.Type.L3MODIFICATION,
+ L3ModificationInstruction.L3SubType.IPV6_FLABEL.name());
+ assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
+ assertThat(((L3ModificationInstruction.ModIPv6FlowLabelInstruction) instruction)
+ .flowLabel(),
+ is(8));
+
+ instruction = getInstruction(Instruction.Type.L0MODIFICATION,
+ L0ModificationInstruction.L0SubType.LAMBDA.name());
+ assertThat(instruction.type(), is(Instruction.Type.L0MODIFICATION));
+ assertThat(((L0ModificationInstruction.ModLambdaInstruction) instruction)
+ .lambda(),
+ is((short) 7));
+
+ instruction = getInstruction(Instruction.Type.L0MODIFICATION,
+ L0ModificationInstruction.L0SubType.OCH.name());
+ assertThat(instruction.type(), is(Instruction.Type.L0MODIFICATION));
+ L0ModificationInstruction.ModOchSignalInstruction och =
+ (L0ModificationInstruction.ModOchSignalInstruction) instruction;
+ assertThat(och.lambda().spacingMultiplier(), is(4));
+ assertThat(och.lambda().slotGranularity(), is(8));
+ assertThat(och.lambda().gridType(), is(GridType.DWDM));
+ assertThat(och.lambda().channelSpacing(), is(ChannelSpacing.CHL_100GHZ));
+
+ instruction = getInstruction(Instruction.Type.L4MODIFICATION,
+ L4ModificationInstruction.L4SubType.TCP_DST.name());
+ assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
+ assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
+ .port().toInt(), is(40001));
+
+ instruction = getInstruction(Instruction.Type.L4MODIFICATION,
+ L4ModificationInstruction.L4SubType.TCP_SRC.name());
+ assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
+ assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
+ .port().toInt(), is(40002));
+
+ instruction = getInstruction(Instruction.Type.L4MODIFICATION,
+ L4ModificationInstruction.L4SubType.UDP_DST.name());
+ assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
+ assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
+ .port().toInt(), is(40003));
+
+ instruction = getInstruction(Instruction.Type.L4MODIFICATION,
+ L4ModificationInstruction.L4SubType.UDP_SRC.name());
+ assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
+ assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
+ .port().toInt(), is(40004));
+ }
+
+ SortedMap<String, Criterion> criteria = new TreeMap<>();
+
+ /**
+ * Looks up a criterion in the instruction map based on type and subtype.
+ *
+ * @param type type string
+ * @return criterion that matches
+ */
+ private Criterion getCriterion(Criterion.Type type) {
+ Criterion criterion = criteria.get(type.name());
+ assertThat(criterion.type(), is(type));
+ return criterion;
+ }
+
+ /**
+ * Checks that a rule with one of each kind of criterion decodes properly.
+ *
+ * @throws IOException if the resource cannot be processed
+ */
+ @Test
+ public void codecCriteriaFlowTest() throws Exception {
+ FlowRule rule = getRule("criteria-flow.json");
+
+ checkCommonData(rule);
+
+ assertThat(rule.selector().criteria().size(), is(33));
+
+ rule.selector().criteria()
+ .stream()
+ .forEach(criterion ->
+ criteria.put(criterion.type().name(), criterion));
+
+ Criterion criterion;
+
+ criterion = getCriterion(Criterion.Type.ETH_TYPE);
+ assertThat(((EthTypeCriterion) criterion).ethType(), is(new EthType(2054)));
+
+ criterion = getCriterion(Criterion.Type.ETH_DST);
+ assertThat(((EthCriterion) criterion).mac(),
+ is(MacAddress.valueOf("00:11:22:33:44:55")));
+
+ criterion = getCriterion(Criterion.Type.ETH_SRC);
+ assertThat(((EthCriterion) criterion).mac(),
+ is(MacAddress.valueOf("00:11:22:33:44:55")));
+
+ criterion = getCriterion(Criterion.Type.IN_PORT);
+ assertThat(((PortCriterion) criterion).port(),
+ is(PortNumber.portNumber(23)));
+
+ criterion = getCriterion(Criterion.Type.IN_PHY_PORT);
+ assertThat(((PortCriterion) criterion).port(),
+ is(PortNumber.portNumber(44)));
+
+ criterion = getCriterion(Criterion.Type.VLAN_VID);
+ assertThat(((VlanIdCriterion) criterion).vlanId(),
+ is(VlanId.vlanId((short) 777)));
+
+ criterion = getCriterion(Criterion.Type.VLAN_PCP);
+ assertThat(((VlanPcpCriterion) criterion).priority(),
+ is(((byte) 3)));
+
+ criterion = getCriterion(Criterion.Type.IP_DSCP);
+ assertThat(((IPDscpCriterion) criterion).ipDscp(),
+ is(((byte) 2)));
+
+ criterion = getCriterion(Criterion.Type.IP_ECN);
+ assertThat(((IPEcnCriterion) criterion).ipEcn(),
+ is(((byte) 1)));
+
+ criterion = getCriterion(Criterion.Type.IP_PROTO);
+ assertThat(((IPProtocolCriterion) criterion).protocol(),
+ is(((short) 4)));
+
+ criterion = getCriterion(Criterion.Type.IPV4_SRC);
+ assertThat(((IPCriterion) criterion).ip(),
+ is((IpPrefix.valueOf("1.2.0.0/32"))));
+
+ criterion = getCriterion(Criterion.Type.IPV4_DST);
+ assertThat(((IPCriterion) criterion).ip(),
+ is((IpPrefix.valueOf("2.2.0.0/32"))));
+
+ criterion = getCriterion(Criterion.Type.IPV6_SRC);
+ assertThat(((IPCriterion) criterion).ip(),
+ is((IpPrefix.valueOf("3.2.0.0/32"))));
+
+ criterion = getCriterion(Criterion.Type.IPV6_DST);
+ assertThat(((IPCriterion) criterion).ip(),
+ is((IpPrefix.valueOf("4.2.0.0/32"))));
+
+ criterion = getCriterion(Criterion.Type.TCP_SRC);
+ assertThat(((TcpPortCriterion) criterion).tcpPort().toInt(),
+ is(80));
+
+ criterion = getCriterion(Criterion.Type.TCP_DST);
+ assertThat(((TcpPortCriterion) criterion).tcpPort().toInt(),
+ is(443));
+
+ criterion = getCriterion(Criterion.Type.UDP_SRC);
+ assertThat(((UdpPortCriterion) criterion).udpPort().toInt(),
+ is(180));
+
+ criterion = getCriterion(Criterion.Type.UDP_DST);
+ assertThat(((UdpPortCriterion) criterion).udpPort().toInt(),
+ is(1443));
+
+ criterion = getCriterion(Criterion.Type.SCTP_SRC);
+ assertThat(((SctpPortCriterion) criterion).sctpPort().toInt(),
+ is(280));
+
+ criterion = getCriterion(Criterion.Type.SCTP_DST);
+ assertThat(((SctpPortCriterion) criterion).sctpPort().toInt(),
+ is(2443));
+
+ criterion = getCriterion(Criterion.Type.ICMPV4_TYPE);
+ assertThat(((IcmpTypeCriterion) criterion).icmpType(),
+ is((short) 24));
+
+ criterion = getCriterion(Criterion.Type.ICMPV4_CODE);
+ assertThat(((IcmpCodeCriterion) criterion).icmpCode(),
+ is((short) 16));
+
+ criterion = getCriterion(Criterion.Type.ICMPV6_TYPE);
+ assertThat(((Icmpv6TypeCriterion) criterion).icmpv6Type(),
+ is((short) 14));
+
+ criterion = getCriterion(Criterion.Type.ICMPV6_CODE);
+ assertThat(((Icmpv6CodeCriterion) criterion).icmpv6Code(),
+ is((short) 6));
+
+ criterion = getCriterion(Criterion.Type.IPV6_FLABEL);
+ assertThat(((IPv6FlowLabelCriterion) criterion).flowLabel(),
+ is(8));
+
+ criterion = getCriterion(Criterion.Type.IPV6_ND_TARGET);
+ assertThat(((IPv6NDTargetAddressCriterion) criterion)
+ .targetAddress().toString(),
+ is("1111:2222:3333:4444:5555:6666:7777:8888"));
+
+ criterion = getCriterion(Criterion.Type.IPV6_ND_SLL);
+ assertThat(((IPv6NDLinkLayerAddressCriterion) criterion).mac(),
+ is(MacAddress.valueOf("00:11:22:33:44:56")));
+
+ criterion = getCriterion(Criterion.Type.IPV6_ND_TLL);
+ assertThat(((IPv6NDLinkLayerAddressCriterion) criterion).mac(),
+ is(MacAddress.valueOf("00:11:22:33:44:57")));
+
+ criterion = getCriterion(Criterion.Type.MPLS_LABEL);
+ assertThat(((MplsCriterion) criterion).label(),
+ is(MplsLabel.mplsLabel(123)));
+
+ criterion = getCriterion(Criterion.Type.IPV6_EXTHDR);
+ assertThat(((IPv6ExthdrFlagsCriterion) criterion).exthdrFlags(),
+ is(99));
+
+ criterion = getCriterion(Criterion.Type.OCH_SIGID);
+ assertThat(((IndexedLambdaCriterion) criterion).lambda(),
+ is(Lambda.indexedLambda(122)));
+
+ criterion = getCriterion(Criterion.Type.TUNNEL_ID);
+ assertThat(((TunnelIdCriterion) criterion).tunnelId(),
+ is(100L));
+ }
+
+ /**
+ * Checks that a rule with a SigId criterion decodes properly.
+ *
+ * @throws IOException if the resource cannot be processed
+ */
+ @Test
+ public void codecSigIdCriteriaFlowTest() throws Exception {
+ FlowRule rule = getRule("sigid-flow.json");
+
+ checkCommonData(rule);
+
+ assertThat(rule.selector().criteria().size(), is(1));
+ Criterion criterion = rule.selector().criteria().iterator().next();
+ assertThat(criterion.type(), is(Criterion.Type.OCH_SIGID));
+ Lambda lambda = ((OchSignalCriterion) criterion).lambda();
+ assertThat(lambda, instanceOf(OchSignal.class));
+ OchSignal ochSignal = (OchSignal) lambda;
+ assertThat(ochSignal.spacingMultiplier(), is(3));
+ assertThat(ochSignal.slotGranularity(), is(4));
+ assertThat(ochSignal.gridType(), is(GridType.CWDM));
+ assertThat(ochSignal.channelSpacing(), is(ChannelSpacing.CHL_25GHZ));
+ }
+
+}