blob: d5c880b1cf2dd77f440cc2735bcd2983f3a530ea [file] [log] [blame]
Carmelo Cascone00a59962017-06-16 17:51:49 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Carmelo Cascone00a59962017-06-16 17:51:49 +09003 *
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
17package org.onosproject.net.pi.impl;
18
19import com.google.common.testing.EqualsTester;
20import org.junit.Before;
21import org.junit.Test;
22import org.onlab.packet.MacAddress;
Carmelo Cascone07d72712017-07-14 15:57:47 -040023import org.onosproject.bmv2.model.Bmv2PipelineModelParser;
Carmelo Cascone00a59962017-06-16 17:51:49 +090024import org.onosproject.core.ApplicationId;
25import org.onosproject.core.DefaultApplicationId;
26import org.onosproject.net.DeviceId;
27import org.onosproject.net.PortNumber;
28import org.onosproject.net.flow.DefaultFlowRule;
29import org.onosproject.net.flow.DefaultTrafficSelector;
30import org.onosproject.net.flow.DefaultTrafficTreatment;
31import org.onosproject.net.flow.FlowRule;
32import org.onosproject.net.flow.TrafficSelector;
33import org.onosproject.net.flow.TrafficTreatment;
Carmelo Cascone07d72712017-07-14 15:57:47 -040034import org.onosproject.net.pi.model.DefaultPiPipeconf;
Carmelo Cascone00a59962017-06-16 17:51:49 +090035import org.onosproject.net.pi.model.PiPipeconf;
Carmelo Cascone07d72712017-07-14 15:57:47 -040036import org.onosproject.net.pi.model.PiPipeconfId;
37import org.onosproject.net.pi.model.PiPipelineInterpreter;
Carmelo Cascone00a59962017-06-16 17:51:49 +090038import org.onosproject.net.pi.runtime.PiTableEntry;
39import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
40
41import java.util.Optional;
42import java.util.Random;
43
44import static org.hamcrest.CoreMatchers.equalTo;
45import static org.hamcrest.CoreMatchers.is;
46import static org.hamcrest.MatcherAssert.assertThat;
47import static org.onosproject.net.pi.impl.MockInterpreter.*;
48
49/**
50 * Tests for {@link PiFlowRuleTranslator}.
51 */
52@SuppressWarnings("ConstantConditions")
53public class PiFlowRuleTranslatorTest {
54
Carmelo Cascone07d72712017-07-14 15:57:47 -040055 private static final String BMV2_JSON_PATH = "/org/onosproject/net/pi/impl/default.json";
56
Carmelo Cascone00a59962017-06-16 17:51:49 +090057 private Random random = new Random();
58 private PiPipeconf pipeconf;
59
60 @Before
61 public void setUp() throws Exception {
Carmelo Cascone07d72712017-07-14 15:57:47 -040062 pipeconf = DefaultPiPipeconf.builder()
63 .withId(new PiPipeconfId("mock-pipeconf"))
Carmelo Cascone31d3e442017-07-18 16:58:51 -040064 .withPipelineModel(Bmv2PipelineModelParser.parse(this.getClass().getResource(BMV2_JSON_PATH)))
Carmelo Cascone07d72712017-07-14 15:57:47 -040065 .addBehaviour(PiPipelineInterpreter.class, MockInterpreter.class)
66 .build();
Carmelo Cascone00a59962017-06-16 17:51:49 +090067 }
68
69 @Test
70 public void testTranslate() throws Exception {
71
72 DeviceId deviceId = DeviceId.NONE;
73 ApplicationId appId = new DefaultApplicationId(1, "test");
74 int tableId = 0;
75 MacAddress ethDstMac = MacAddress.valueOf(random.nextLong());
76 MacAddress ethSrcMac = MacAddress.valueOf(random.nextLong());
77 short ethType = (short) (0x0000FFFF & random.nextInt());
78 short outPort = (short) random.nextInt(65);
79 short inPort = (short) random.nextInt(65);
80 int timeout = random.nextInt(100);
81 int priority = random.nextInt(100);
82
83 TrafficSelector matchInPort1 = DefaultTrafficSelector
84 .builder()
85 .matchInPort(PortNumber.portNumber(inPort))
86 .matchEthDst(ethDstMac)
87 .matchEthSrc(ethSrcMac)
88 .matchEthType(ethType)
89 .build();
90
91 TrafficTreatment outPort2 = DefaultTrafficTreatment
92 .builder()
93 .setOutput(PortNumber.portNumber(outPort))
94 .build();
95
96 FlowRule rule1 = DefaultFlowRule.builder()
97 .forDevice(deviceId)
98 .forTable(tableId)
99 .fromApp(appId)
100 .withSelector(matchInPort1)
101 .withTreatment(outPort2)
102 .makeTemporary(timeout)
103 .withPriority(priority)
104 .build();
105
106 FlowRule rule2 = DefaultFlowRule.builder()
107 .forDevice(deviceId)
108 .forTable(tableId)
109 .fromApp(appId)
110 .withSelector(matchInPort1)
111 .withTreatment(outPort2)
112 .makeTemporary(timeout)
113 .withPriority(priority)
114 .build();
115
116 PiTableEntry entry1 = PiFlowRuleTranslator.translateFlowRule(rule1, pipeconf, null);
117 PiTableEntry entry2 = PiFlowRuleTranslator.translateFlowRule(rule1, pipeconf, null);
118
119 // check equality, i.e. same rules must produce same entries
120 new EqualsTester()
121 .addEqualityGroup(rule1, rule2)
122 .addEqualityGroup(entry1, entry2)
123 .testEquals();
124
125 int numMatchParams = pipeconf.pipelineModel().table(TABLE0).get().matchFields().size();
126 // parse values stored in entry1
Carmelo Cascone0e896a02017-07-31 07:22:27 +0200127 PiTernaryFieldMatch inPortParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(IN_PORT_ID).get();
128 PiTernaryFieldMatch ethDstParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(ETH_DST_ID).get();
129 PiTernaryFieldMatch ethSrcParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(ETH_SRC_ID).get();
130 PiTernaryFieldMatch ethTypeParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(ETH_TYPE_ID).get();
Carmelo Cascone00a59962017-06-16 17:51:49 +0900131 Optional<Double> expectedTimeout = pipeconf.pipelineModel().table(TABLE0).get().supportsAging()
132 ? Optional.of((double) rule1.timeout()) : Optional.empty();
133
134 // check that the number of parameters in the entry is the same as the number of table keys
135 assertThat("Incorrect number of match parameters",
Carmelo Cascone0e896a02017-07-31 07:22:27 +0200136 entry1.matchKey().fieldMatches().size(), is(equalTo(numMatchParams)));
Carmelo Cascone00a59962017-06-16 17:51:49 +0900137
138 // check that values stored in entry are the same used for the flow rule
139 assertThat("Incorrect inPort match param value",
140 inPortParam.value().asReadOnlyBuffer().getShort(), is(equalTo(inPort)));
141 assertThat("Incorrect ethDestMac match param value",
142 ethDstParam.value().asArray(), is(equalTo(ethDstMac.toBytes())));
143 assertThat("Incorrect ethSrcMac match param value",
144 ethSrcParam.value().asArray(), is(equalTo(ethSrcMac.toBytes())));
145 assertThat("Incorrect ethType match param value",
146 ethTypeParam.value().asReadOnlyBuffer().getShort(), is(equalTo(ethType)));
147 assertThat("Incorrect priority value",
Carmelo Cascone2cad9ef2017-08-01 21:52:07 +0200148 entry1.priority().get(), is(equalTo(Integer.MAX_VALUE - rule1.priority())));
Carmelo Cascone00a59962017-06-16 17:51:49 +0900149 assertThat("Incorrect timeout value",
150 entry1.timeout(), is(equalTo(expectedTimeout)));
151
152 }
153}