blob: 8614527d5ea8a12a79ef204834ed5820f31fec36 [file] [log] [blame]
Carmelo Cascone8d99b172017-07-18 17:26:31 -04001/*
Carmelo Cascone4c289b72019-01-22 15:30:45 -08002 * Copyright 2019-present Open Networking Foundation
Carmelo Cascone8d99b172017-07-18 17:26:31 -04003 *
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
Carmelo Cascone4c289b72019-01-22 15:30:45 -080017package org.onosproject.p4runtime.ctl.codec;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040018
Carmelo Cascone8d99b172017-07-18 17:26:31 -040019import com.google.common.testing.EqualsTester;
Yi Tseng82512da2017-08-16 19:46:36 -070020import org.easymock.EasyMock;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040021import org.junit.Test;
22import org.onlab.util.ImmutableByteSequence;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040023import org.onosproject.net.pi.model.DefaultPiPipeconf;
Carmelo Cascone87892e22017-11-13 16:01:29 -080024import org.onosproject.net.pi.model.PiActionId;
25import org.onosproject.net.pi.model.PiActionParamId;
26import org.onosproject.net.pi.model.PiMatchFieldId;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040027import org.onosproject.net.pi.model.PiPipeconf;
28import org.onosproject.net.pi.model.PiPipeconfId;
Yi Tseng82512da2017-08-16 19:46:36 -070029import org.onosproject.net.pi.model.PiPipelineModel;
Carmelo Cascone87892e22017-11-13 16:01:29 -080030import org.onosproject.net.pi.model.PiTableId;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040031import org.onosproject.net.pi.runtime.PiAction;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040032import org.onosproject.net.pi.runtime.PiActionParam;
Carmelo Casconecb4327a2018-09-11 15:17:23 -070033import org.onosproject.net.pi.runtime.PiActionProfileGroupId;
steven308017632e152018-10-20 00:51:08 +080034import org.onosproject.net.pi.runtime.PiCounterCellData;
Yi Tseng95390822018-01-22 17:57:22 -080035import org.onosproject.net.pi.runtime.PiExactFieldMatch;
Carmelo Cascone0e896a02017-07-31 07:22:27 +020036import org.onosproject.net.pi.runtime.PiMatchKey;
Daniele Moroc6f2f7f2020-12-18 10:55:57 +010037import org.onosproject.net.pi.runtime.PiOptionalFieldMatch;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040038import org.onosproject.net.pi.runtime.PiTableEntry;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040039import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
Carmelo Cascone4c289b72019-01-22 15:30:45 -080040import org.onosproject.p4runtime.ctl.utils.P4InfoBrowser;
41import org.onosproject.p4runtime.ctl.utils.PipeconfHelper;
Daniele Moroc6f2f7f2020-12-18 10:55:57 +010042import p4.v1.P4RuntimeOuterClass;
Carmelo Cascone6af4e172018-06-15 16:01:30 +020043import p4.v1.P4RuntimeOuterClass.Action;
steven308017632e152018-10-20 00:51:08 +080044import p4.v1.P4RuntimeOuterClass.CounterData;
Carmelo Cascone6af4e172018-06-15 16:01:30 +020045import p4.v1.P4RuntimeOuterClass.TableEntry;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040046
47import java.net.URL;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040048import java.util.Random;
Daniele Moroc6f2f7f2020-12-18 10:55:57 +010049import java.util.stream.Collectors;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040050
51import static org.hamcrest.MatcherAssert.assertThat;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040052import static org.hamcrest.Matchers.is;
Daniele Moroc6f2f7f2020-12-18 10:55:57 +010053import static org.hamcrest.Matchers.not;
54import static org.hamcrest.Matchers.hasItem;
Carmelo Casconeca94bcf2017-10-27 14:16:59 -070055import static org.onlab.util.ImmutableByteSequence.copyFrom;
Carmelo Casconeca94bcf2017-10-27 14:16:59 -070056import static org.onlab.util.ImmutableByteSequence.ofOnes;
Carmelo Cascone8d99b172017-07-18 17:26:31 -040057import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.P4_INFO_TEXT;
Andrea Campanellafc1d34c2017-07-18 17:01:41 +020058
Yi Tseng82512da2017-08-16 19:46:36 -070059/**
60 * Test for P4 runtime table entry encoder.
61 */
Carmelo Cascone8d99b172017-07-18 17:26:31 -040062public class TableEntryEncoderTest {
Carmelo Cascone87892e22017-11-13 16:01:29 -080063 private static final String DOT = ".";
Carmelo Cascone8d99b172017-07-18 17:26:31 -040064 private static final String TABLE_0 = "table0";
Yi Tseng95390822018-01-22 17:57:22 -080065 private static final String TABLE_ECMP = "ecmp";
Carmelo Cascone8d99b172017-07-18 17:26:31 -040066 private static final String SET_EGRESS_PORT = "set_egress_port";
67 private static final String PORT = "port";
Carmelo Cascone87892e22017-11-13 16:01:29 -080068 private static final String HDR = "hdr";
Yi Tseng95390822018-01-22 17:57:22 -080069 private static final String META = "meta";
Carmelo Cascone8d99b172017-07-18 17:26:31 -040070 private static final String ETHERNET = "ethernet";
71 private static final String DST_ADDR = "dstAddr";
72 private static final String SRC_ADDR = "srcAddr";
73 private static final String STANDARD_METADATA = "standard_metadata";
Daniele Morof178b0a2020-12-15 14:13:51 +010074 private static final String LOCAL_METADATA = "local_metadata";
Yi Tseng95390822018-01-22 17:57:22 -080075 private static final String ECMP_METADATA = "ecmp_metadata";
Carmelo Cascone8d99b172017-07-18 17:26:31 -040076 private static final String INGRESS_PORT = "ingress_port";
77 private static final String ETHER_TYPE = "etherType";
Yi Tseng95390822018-01-22 17:57:22 -080078 private static final String ECMP_GROUP_ID = "ecmp_group_id";
Carmelo Cascone8d99b172017-07-18 17:26:31 -040079
steven308017632e152018-10-20 00:51:08 +080080 private static final long PACKETS = 10;
81 private static final long BYTES = 100;
82
Carmelo Cascone8d99b172017-07-18 17:26:31 -040083 private final Random rand = new Random();
Carmelo Casconeca94bcf2017-10-27 14:16:59 -070084 private final URL p4InfoUrl = this.getClass().getResource("/test.p4info");
Daniele Morof178b0a2020-12-15 14:13:51 +010085 private final URL p4InfoUrl2 = this.getClass().getResource("/test_p4runtime_translation_p4info.txt");
Carmelo Cascone8d99b172017-07-18 17:26:31 -040086
87 private final PiPipeconf defaultPipeconf = DefaultPiPipeconf.builder()
88 .withId(new PiPipeconfId("mock"))
Yi Tseng82512da2017-08-16 19:46:36 -070089 .withPipelineModel(EasyMock.niceMock(PiPipelineModel.class))
Carmelo Cascone8d99b172017-07-18 17:26:31 -040090 .addExtension(P4_INFO_TEXT, p4InfoUrl)
Carmelo Cascone8d99b172017-07-18 17:26:31 -040091 .build();
92
Daniele Morof178b0a2020-12-15 14:13:51 +010093 private final PiPipeconf defaultPipeconf2 = DefaultPiPipeconf.builder()
94 .withId(new PiPipeconfId("mock"))
95 .withPipelineModel(EasyMock.niceMock(PiPipelineModel.class))
96 .addExtension(P4_INFO_TEXT, p4InfoUrl2)
97 .build();
98
Carmelo Cascone8d99b172017-07-18 17:26:31 -040099 private final P4InfoBrowser browser = PipeconfHelper.getP4InfoBrowser(defaultPipeconf);
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100100 private final P4InfoBrowser browser2 = PipeconfHelper.getP4InfoBrowser(defaultPipeconf2);
Carmelo Cascone8a571af2018-04-06 23:17:04 -0700101 private final ImmutableByteSequence ethAddr = copyFrom(rand.nextInt()).fit(48);
Daniele Morof178b0a2020-12-15 14:13:51 +0100102 private final ImmutableByteSequence ethAddrString = ImmutableByteSequence.copyFrom(
103 "00:11:22:33:44:55:66".getBytes());
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400104 private final ImmutableByteSequence portValue = copyFrom((short) rand.nextInt());
Daniele Morof178b0a2020-12-15 14:13:51 +0100105 private final ImmutableByteSequence portValueString = ImmutableByteSequence.copyFrom(
106 String.format("Ethernet%d", rand.nextInt()).getBytes());
107 private final ImmutableByteSequence portValue32Bit = copyFrom((short) rand.nextInt()).fit(32);
Carmelo Cascone87892e22017-11-13 16:01:29 -0800108 private final PiMatchFieldId ethDstAddrFieldId = PiMatchFieldId.of(HDR + DOT + ETHERNET + DOT + DST_ADDR);
109 private final PiMatchFieldId ethSrcAddrFieldId = PiMatchFieldId.of(HDR + DOT + ETHERNET + DOT + SRC_ADDR);
110 private final PiMatchFieldId inPortFieldId = PiMatchFieldId.of(STANDARD_METADATA + DOT + INGRESS_PORT);
Daniele Morof178b0a2020-12-15 14:13:51 +0100111 private final PiMatchFieldId inPortFieldId2 = PiMatchFieldId.of(LOCAL_METADATA + DOT + INGRESS_PORT);
Carmelo Cascone87892e22017-11-13 16:01:29 -0800112 private final PiMatchFieldId ethTypeFieldId = PiMatchFieldId.of(HDR + DOT + ETHERNET + DOT + ETHER_TYPE);
Yi Tseng95390822018-01-22 17:57:22 -0800113 private final PiMatchFieldId ecmpGroupFieldId =
114 PiMatchFieldId.of(META + DOT + ECMP_METADATA + DOT + ECMP_GROUP_ID);
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400115 private final PiActionParamId portParamId = PiActionParamId.of(PORT);
116 private final PiActionId outActionId = PiActionId.of(SET_EGRESS_PORT);
Daniele Morof178b0a2020-12-15 14:13:51 +0100117 private final PiActionId outActionId2 = PiActionId.of(SET_EGRESS_PORT + "2");
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400118 private final PiTableId tableId = PiTableId.of(TABLE_0);
Yi Tseng95390822018-01-22 17:57:22 -0800119 private final PiTableId ecmpTableId = PiTableId.of(TABLE_ECMP);
steven308017632e152018-10-20 00:51:08 +0800120 private final PiCounterCellData counterCellData = new PiCounterCellData(PACKETS, BYTES);
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400121
122 private final PiTableEntry piTableEntry = PiTableEntry
123 .builder()
124 .forTable(tableId)
Carmelo Cascone0e896a02017-07-31 07:22:27 +0200125 .withMatchKey(PiMatchKey.builder()
126 .addFieldMatch(new PiTernaryFieldMatch(ethDstAddrFieldId, ethAddr, ofOnes(6)))
127 .addFieldMatch(new PiTernaryFieldMatch(ethSrcAddrFieldId, ethAddr, ofOnes(6)))
128 .addFieldMatch(new PiTernaryFieldMatch(inPortFieldId, portValue, ofOnes(2)))
129 .addFieldMatch(new PiTernaryFieldMatch(ethTypeFieldId, portValue, ofOnes(2)))
130 .build())
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400131 .withAction(PiAction
Carmelo Cascone0e896a02017-07-31 07:22:27 +0200132 .builder()
133 .withId(outActionId)
134 .withParameter(new PiActionParam(portParamId, portValue))
135 .build())
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400136 .withPriority(1)
137 .withCookie(2)
steven308017632e152018-10-20 00:51:08 +0800138 .withCounterCellData(counterCellData)
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400139 .build();
140
Daniele Morof178b0a2020-12-15 14:13:51 +0100141 private final PiTableEntry piTableEntry2 = PiTableEntry
142 .builder()
143 .forTable(tableId)
144 .withMatchKey(PiMatchKey.builder()
145 .addFieldMatch(new PiExactFieldMatch(inPortFieldId2, portValue32Bit))
146 .addFieldMatch(new PiExactFieldMatch(ethDstAddrFieldId, ethAddrString))
147 .addFieldMatch(new PiExactFieldMatch(ethSrcAddrFieldId, ethAddrString))
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100148 .addFieldMatch(new PiOptionalFieldMatch(ethTypeFieldId, portValue))
Daniele Morof178b0a2020-12-15 14:13:51 +0100149 .build())
150 .withAction(PiAction
151 .builder()
152 .withId(outActionId)
153 .withParameter(new PiActionParam(portParamId, portValueString))
154 .build())
155 .withPriority(1)
156 .withCookie(2)
157 .build();
158
159 private final PiTableEntry piTableEntry3 = PiTableEntry
160 .builder()
161 .forTable(tableId)
162 .withMatchKey(PiMatchKey.builder()
163 .addFieldMatch(new PiExactFieldMatch(inPortFieldId2, portValue32Bit))
164 .addFieldMatch(new PiExactFieldMatch(ethDstAddrFieldId, ethAddrString))
165 .addFieldMatch(new PiExactFieldMatch(ethSrcAddrFieldId, ethAddrString))
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100166 .addFieldMatch(new PiOptionalFieldMatch(ethTypeFieldId, portValue))
Daniele Morof178b0a2020-12-15 14:13:51 +0100167 .build())
168 .withAction(PiAction
169 .builder()
170 .withId(outActionId2)
171 .withParameter(new PiActionParam(portParamId, portValue32Bit))
172 .build())
173 .withPriority(1)
174 .withCookie(2)
175 .build();
176
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100177 private final PiTableEntry piTableEntryWithoutOptionalField = PiTableEntry
178 .builder()
179 .forTable(tableId)
180 .withMatchKey(PiMatchKey.builder()
181 .addFieldMatch(new PiExactFieldMatch(inPortFieldId2, portValue32Bit))
182 .addFieldMatch(new PiExactFieldMatch(ethDstAddrFieldId, ethAddrString))
183 .addFieldMatch(new PiExactFieldMatch(ethSrcAddrFieldId, ethAddrString))
184 .build())
185 .withAction(PiAction
186 .builder()
187 .withId(outActionId)
188 .withParameter(new PiActionParam(portParamId, portValueString))
189 .build())
190 .withPriority(1)
191 .withCookie(2)
192 .build();
193
Yi Tsengd28936e2018-02-23 22:11:11 +0100194 private final PiTableEntry piTableEntryWithoutAction = PiTableEntry
195 .builder()
196 .forTable(tableId)
197 .withMatchKey(PiMatchKey.builder()
198 .addFieldMatch(new PiTernaryFieldMatch(ethDstAddrFieldId, ethAddr, ofOnes(6)))
199 .addFieldMatch(new PiTernaryFieldMatch(ethSrcAddrFieldId, ethAddr, ofOnes(6)))
200 .addFieldMatch(new PiTernaryFieldMatch(inPortFieldId, portValue, ofOnes(2)))
201 .addFieldMatch(new PiTernaryFieldMatch(ethTypeFieldId, portValue, ofOnes(2)))
202 .build())
203 .withPriority(1)
204 .withCookie(2)
steven308017632e152018-10-20 00:51:08 +0800205 .withCounterCellData(counterCellData)
Yi Tsengd28936e2018-02-23 22:11:11 +0100206 .build();
207
Yi Tseng95390822018-01-22 17:57:22 -0800208 private final PiTableEntry piTableEntryWithGroupAction = PiTableEntry
209 .builder()
210 .forTable(ecmpTableId)
211 .withMatchKey(PiMatchKey.builder()
212 .addFieldMatch(new PiExactFieldMatch(ecmpGroupFieldId, ofOnes(1)))
213 .build())
Carmelo Casconecb4327a2018-09-11 15:17:23 -0700214 .withAction(PiActionProfileGroupId.of(1))
Yi Tseng95390822018-01-22 17:57:22 -0800215 .withPriority(1)
216 .withCookie(2)
steven308017632e152018-10-20 00:51:08 +0800217 .withCounterCellData(counterCellData)
Yi Tseng95390822018-01-22 17:57:22 -0800218 .build();
219
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400220 public TableEntryEncoderTest() throws ImmutableByteSequence.ByteSequenceTrimException {
221 }
222
223 @Test
224 public void testP4InfoBrowser() throws Exception {
225
226 P4InfoBrowser browser = PipeconfHelper.getP4InfoBrowser(defaultPipeconf);
227
228 assertThat(browser.tables().hasName(TABLE_0), is(true));
229 assertThat(browser.actions().hasName(SET_EGRESS_PORT), is(true));
230
Carmelo Casconecb0a49c2017-10-03 14:32:23 +0200231 int tableId = browser.tables().getByName(TABLE_0).getPreamble().getId();
232 int actionId = browser.actions().getByName(SET_EGRESS_PORT).getPreamble().getId();
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400233
Carmelo Cascone87892e22017-11-13 16:01:29 -0800234 assertThat(browser.matchFields(tableId).hasName(STANDARD_METADATA + DOT + INGRESS_PORT), is(true));
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400235 assertThat(browser.actionParams(actionId).hasName(PORT), is(true));
236
237 // TODO: improve, assert browsing other entities (counters, meters, etc.)
238 }
239
240 @Test
Carmelo Cascone5bc7e102018-02-18 18:27:55 -0800241 public void testTableEntryEncoder() throws Exception {
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400242
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800243 TableEntry tableEntryMsg = Codecs.CODECS.tableEntry().encode(
244 piTableEntry, null, defaultPipeconf);
245 PiTableEntry decodedPiTableEntry = Codecs.CODECS.tableEntry().decode(
246 tableEntryMsg, null, defaultPipeconf);
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400247
248 // Test equality for decoded entry.
249 new EqualsTester()
250 .addEqualityGroup(piTableEntry, decodedPiTableEntry)
251 .testEquals();
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400252 // Table ID.
Carmelo Casconecb0a49c2017-10-03 14:32:23 +0200253 int p4InfoTableId = browser.tables().getByName(tableId.id()).getPreamble().getId();
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400254 int encodedTableId = tableEntryMsg.getTableId();
255 assertThat(encodedTableId, is(p4InfoTableId));
256
257 // Ternary match.
258 byte[] encodedTernaryMatchValue = tableEntryMsg.getMatch(0).getTernary().getValue().toByteArray();
259 assertThat(encodedTernaryMatchValue, is(ethAddr.asArray()));
260
261 Action actionMsg = tableEntryMsg.getAction().getAction();
262
263 // Action ID.
Carmelo Cascone87892e22017-11-13 16:01:29 -0800264 int p4InfoActionId = browser.actions().getByName(outActionId.toString()).getPreamble().getId();
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400265 int encodedActionId = actionMsg.getActionId();
266 assertThat(encodedActionId, is(p4InfoActionId));
267
268 // Action param ID.
Carmelo Cascone87892e22017-11-13 16:01:29 -0800269 int p4InfoActionParamId = browser.actionParams(p4InfoActionId).getByName(portParamId.toString()).getId();
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400270 int encodedActionParamId = actionMsg.getParams(0).getParamId();
271 assertThat(encodedActionParamId, is(p4InfoActionParamId));
272
273 // Action param value.
274 byte[] encodedActionParam = actionMsg.getParams(0).getValue().toByteArray();
275 assertThat(encodedActionParam, is(portValue.asArray()));
276
steven308017632e152018-10-20 00:51:08 +0800277 // Counter
278 CounterData counterData = tableEntryMsg.getCounterData();
279 PiCounterCellData encodedCounterData = new PiCounterCellData(counterData.getPacketCount(),
280 counterData.getByteCount());
281 assertThat(encodedCounterData, is(counterCellData));
282
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400283 // TODO: improve, assert other field match types (ternary, LPM)
284 }
Yi Tseng95390822018-01-22 17:57:22 -0800285
286 @Test
Daniele Morof178b0a2020-12-15 14:13:51 +0100287 public void testTableEntryEncoderWithTranslations() throws Exception {
288 TableEntry tableEntryMsg = Codecs.CODECS.tableEntry().encode(
289 piTableEntry2, null, defaultPipeconf2);
290 PiTableEntry decodedPiTableEntry = Codecs.CODECS.tableEntry().decode(
291 tableEntryMsg, null, defaultPipeconf2);
292
293 // Test equality for decoded entry.
294 new EqualsTester()
295 .addEqualityGroup(piTableEntry2, decodedPiTableEntry)
296 .testEquals();
297
298 // Check the exact match with string
299 byte[] encodedExactMatchValueString = tableEntryMsg.getMatch(1).getExact().getValue().toByteArray();
300 assertThat(encodedExactMatchValueString, is(ethAddrString.asArray()));
301
302 Action actionMsg = tableEntryMsg.getAction().getAction();
303
304 // Check action param value with string
305 byte[] encodedActionParamString = actionMsg.getParams(0).getValue().toByteArray();
306 assertThat(encodedActionParamString, is(portValueString.asArray()));
307
308 TableEntry tableEntryMsg1 = Codecs.CODECS.tableEntry().encode(
309 piTableEntry3, null, defaultPipeconf2);
310 PiTableEntry decodedPiTableEntry1 = Codecs.CODECS.tableEntry().decode(
311 tableEntryMsg1, null, defaultPipeconf2);
312
313 // Test equality for decoded entry.
314 new EqualsTester()
315 .addEqualityGroup(piTableEntry3, decodedPiTableEntry1)
316 .testEquals();
317 }
318
319 @Test
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100320 public void testTableEntryEncoderWithoutOptionalField() throws Exception {
321 TableEntry tableEntryMsg = Codecs.CODECS.tableEntry().encode(
322 piTableEntryWithoutOptionalField, null, defaultPipeconf2);
323 PiTableEntry decodedPiTableEntry = Codecs.CODECS.tableEntry().decode(
324 tableEntryMsg, null, defaultPipeconf2);
325
326 // Table ID.
327 int p4InfoTableId = browser2.tables().getByName(tableId.id()).getPreamble().getId();
328 int encodedTableId = tableEntryMsg.getTableId();
329 assertThat(encodedTableId, is(p4InfoTableId));
330
331 // Test equality for decoded entry.
332 new EqualsTester()
333 .addEqualityGroup(piTableEntryWithoutOptionalField, decodedPiTableEntry)
334 .testEquals();
335
336 // no optional field
337 assertThat(tableEntryMsg.getMatchCount(), is(3));
338 assertThat(tableEntryMsg.getMatchList().stream()
339 .map(P4RuntimeOuterClass.FieldMatch::getFieldMatchTypeCase)
340 .collect(Collectors.toList()),
341 not(hasItem(P4RuntimeOuterClass.FieldMatch.FieldMatchTypeCase.OPTIONAL)));
342 }
343
344 @Test
Carmelo Cascone5bc7e102018-02-18 18:27:55 -0800345 public void testActopProfileGroup() throws Exception {
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800346 TableEntry tableEntryMsg = Codecs.CODECS.tableEntry().encode(
347 piTableEntryWithGroupAction, null, defaultPipeconf);
348 PiTableEntry decodedPiTableEntry = Codecs.CODECS.tableEntry().decode(
349 tableEntryMsg, null, defaultPipeconf);
Yi Tseng95390822018-01-22 17:57:22 -0800350
351 // Test equality for decoded entry.
352 new EqualsTester()
353 .addEqualityGroup(piTableEntryWithGroupAction, decodedPiTableEntry)
354 .testEquals();
355
356 // Table ID.
357 int p4InfoTableId = browser.tables().getByName(ecmpTableId.id()).getPreamble().getId();
358 int encodedTableId = tableEntryMsg.getTableId();
359 assertThat(encodedTableId, is(p4InfoTableId));
360
361 // Exact match.
362 byte[] encodedTernaryMatchValue = tableEntryMsg.getMatch(0).getExact().getValue().toByteArray();
363 assertThat(encodedTernaryMatchValue, is(new byte[]{(byte) 0xff}));
364
365 // Action profile group id
366 int actionProfileGroupId = tableEntryMsg.getAction().getActionProfileGroupId();
367 assertThat(actionProfileGroupId, is(1));
368 }
Yi Tsengd28936e2018-02-23 22:11:11 +0100369
370 @Test
371 public void testEncodeWithNoAction() throws Exception {
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800372 TableEntry tableEntryMsg = Codecs.CODECS.tableEntry().encode(
373 piTableEntryWithoutAction, null, defaultPipeconf);
374 PiTableEntry decodedPiTableEntry = Codecs.CODECS.tableEntry().decode(
375 tableEntryMsg, null, defaultPipeconf);
Yi Tsengd28936e2018-02-23 22:11:11 +0100376
377 // Test equality for decoded entry.
378 new EqualsTester()
379 .addEqualityGroup(piTableEntryWithoutAction, decodedPiTableEntry)
380 .testEquals();
381
382 // Table ID.
383 int p4InfoTableId = browser.tables().getByName(tableId.id()).getPreamble().getId();
384 int encodedTableId = tableEntryMsg.getTableId();
385 assertThat(encodedTableId, is(p4InfoTableId));
386
387 // Ternary match.
388 byte[] encodedTernaryMatchValue = tableEntryMsg.getMatch(0).getTernary().getValue().toByteArray();
389 assertThat(encodedTernaryMatchValue, is(ethAddr.asArray()));
390
391 // no action
392 assertThat(tableEntryMsg.hasAction(), is(false));
393
steven308017632e152018-10-20 00:51:08 +0800394 // Counter
395 CounterData counterData = tableEntryMsg.getCounterData();
396 PiCounterCellData encodedCounterData = new PiCounterCellData(counterData.getPacketCount(),
397 counterData.getByteCount());
398 assertThat(encodedCounterData, is(counterCellData));
399
Yi Tsengd28936e2018-02-23 22:11:11 +0100400 // TODO: improve, assert other field match types (ternary, LPM)
401 }
Carmelo Cascone8d99b172017-07-18 17:26:31 -0400402}