blob: ab0a57e4e1d71af9095b514d0b754ddf403592fd [file] [log] [blame]
Carmelo Casconec8e84982017-07-26 15:34:42 -04001/*
2 * Copyright 2017-present Open Networking Laboratory
3 *
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.p4runtime.test;
18
19import io.grpc.ManagedChannelBuilder;
20import io.grpc.netty.NettyChannelBuilder;
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040021import org.junit.Before;
Carmelo Casconec8e84982017-07-26 15:34:42 -040022import org.junit.Ignore;
23import org.junit.Test;
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040024import org.onlab.util.ImmutableByteSequence;
Carmelo Casconec8e84982017-07-26 15:34:42 -040025import org.onosproject.bmv2.model.Bmv2PipelineModelParser;
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040026import org.onosproject.drivers.bmv2.Bmv2DefaultInterpreter;
Carmelo Casconec8e84982017-07-26 15:34:42 -040027import org.onosproject.grpc.ctl.GrpcControllerImpl;
28import org.onosproject.net.DeviceId;
29import org.onosproject.net.pi.model.DefaultPiPipeconf;
30import org.onosproject.net.pi.model.PiPipeconf;
31import org.onosproject.net.pi.model.PiPipeconfId;
32import org.onosproject.net.pi.model.PiPipelineInterpreter;
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040033import org.onosproject.net.pi.runtime.PiPacketMetadata;
34import org.onosproject.net.pi.runtime.PiPacketMetadataId;
35import org.onosproject.net.pi.runtime.PiPacketOperation;
36import org.onosproject.net.pi.runtime.PiTableId;
37import org.onosproject.p4runtime.ctl.P4RuntimeClientImpl;
Carmelo Casconec8e84982017-07-26 15:34:42 -040038import org.onosproject.p4runtime.ctl.P4RuntimeControllerImpl;
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040039import p4.P4RuntimeGrpc;
40import p4.P4RuntimeOuterClass;
Carmelo Casconec8e84982017-07-26 15:34:42 -040041
42import java.net.URL;
43import java.util.concurrent.ExecutionException;
44
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040045import static org.onlab.util.ImmutableByteSequence.copyFrom;
46import static org.onlab.util.ImmutableByteSequence.fit;
Carmelo Casconec8e84982017-07-26 15:34:42 -040047import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.BMV2_JSON;
48import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.P4_INFO_TEXT;
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040049import static org.onosproject.net.pi.runtime.PiPacketOperation.Type.PACKET_OUT;
50import static p4.P4RuntimeOuterClass.ActionProfileGroup.Type.SELECT;
51import static p4.P4RuntimeOuterClass.Update.Type.INSERT;
Carmelo Casconec8e84982017-07-26 15:34:42 -040052
53/**
54 * Class used for quick testing of P4Runtime with real devices. To be removed before release.
55 */
56public class P4RuntimeTest {
57
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040058 private static final String GRPC_SERVER_ADDR = "192.168.56.102";
59 private static final int GRPC_SERVER_PORT = 55044;
60
61 private final URL p4InfoUrl = this.getClass().getResource("/bmv2/default.p4info");
62 private final URL jsonUrl = this.getClass().getResource("/bmv2/default.json");
Carmelo Casconec8e84982017-07-26 15:34:42 -040063
64 private final PiPipeconf bmv2DefaultPipeconf = DefaultPiPipeconf.builder()
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040065 .withId(new PiPipeconfId("mock-bmv2"))
Carmelo Casconec8e84982017-07-26 15:34:42 -040066 .withPipelineModel(Bmv2PipelineModelParser.parse(jsonUrl))
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040067 .addBehaviour(PiPipelineInterpreter.class, Bmv2DefaultInterpreter.class)
Carmelo Casconec8e84982017-07-26 15:34:42 -040068 .addExtension(P4_INFO_TEXT, p4InfoUrl)
69 .addExtension(BMV2_JSON, jsonUrl)
70 .build();
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040071 private final P4RuntimeControllerImpl controller = new P4RuntimeControllerImpl();
72 private final GrpcControllerImpl grpcController = new GrpcControllerImpl();
73 private final DeviceId deviceId = DeviceId.deviceId("dummy:1");
74 private final ManagedChannelBuilder channelBuilder = NettyChannelBuilder
75 .forAddress(GRPC_SERVER_ADDR, GRPC_SERVER_PORT)
76 .usePlaintext(true);
77 private P4RuntimeClientImpl client;
Carmelo Casconec8e84982017-07-26 15:34:42 -040078
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040079 @Before
80 public void setUp() throws Exception {
Carmelo Casconec8e84982017-07-26 15:34:42 -040081 controller.grpcController = grpcController;
82 GrpcControllerImpl.enableMessageLog = true;
83 grpcController.activate();
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040084 }
Carmelo Casconec8e84982017-07-26 15:34:42 -040085
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040086 private void createClientAndSetPipelineConfig(PiPipeconf pipeconf, PiPipeconf.ExtensionType extensionType)
87 throws ExecutionException, InterruptedException, PiPipelineInterpreter.PiInterpreterException,
88 IllegalAccessException, InstantiationException {
Carmelo Casconec8e84982017-07-26 15:34:42 -040089
90 assert (controller.createClient(deviceId, 1, channelBuilder));
91
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040092 client = (P4RuntimeClientImpl) controller.getClient(deviceId);
Carmelo Casconec8e84982017-07-26 15:34:42 -040093
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040094 assert (client.setPipelineConfig(pipeconf, extensionType).get());
Carmelo Casconec8e84982017-07-26 15:34:42 -040095 assert (client.initStreamChannel().get());
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040096 }
Carmelo Casconec8e84982017-07-26 15:34:42 -040097
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040098 private void testActionProfile(int actionProfileId) {
99
100 P4RuntimeGrpc.P4RuntimeBlockingStub stub = client.blockingStub();
101
102 P4RuntimeOuterClass.ActionProfileMember profileMemberMsg = P4RuntimeOuterClass.ActionProfileMember.newBuilder()
103 .setActionProfileId(actionProfileId)
104 // .setMemberId(1)
105 .setAction(P4RuntimeOuterClass.Action.newBuilder()
106 .setActionId(16793508)
107 .build())
108 .build();
109
110 P4RuntimeOuterClass.ActionProfileGroup groupMsg = P4RuntimeOuterClass.ActionProfileGroup.newBuilder()
111 .setActionProfileId(actionProfileId)
112 .setGroupId(1)
113 .setType(SELECT)
114 .addMembers(P4RuntimeOuterClass.ActionProfileGroup.Member.newBuilder()
115 .setMemberId(1)
116 .setWeight(1)
117 .build())
118 .setMaxSize(3)
119 .build();
120
121 P4RuntimeOuterClass.WriteRequest writeRequest = P4RuntimeOuterClass.WriteRequest.newBuilder()
122 .setDeviceId(client.p4DeviceId())
123 .addUpdates(P4RuntimeOuterClass.Update.newBuilder()
124 .setType(INSERT)
125 .setEntity(P4RuntimeOuterClass.Entity.newBuilder()
126 .setActionProfileGroup(groupMsg)
127 .build())
128 .build())
129 .addUpdates(P4RuntimeOuterClass.Update.newBuilder()
130 .setType(INSERT)
131 .setEntity(P4RuntimeOuterClass.Entity.newBuilder()
132 .setActionProfileMember(profileMemberMsg)
133 .build())
134 .build())
135 .build();
136
137 stub.write(writeRequest);
138 }
139
140 private void testPacketOut() throws IllegalAccessException, InstantiationException, ExecutionException,
141 InterruptedException, ImmutableByteSequence.ByteSequenceTrimException {
142
143 PiPacketOperation packetOperation = PiPacketOperation.builder()
144 .withData(ImmutableByteSequence.ofOnes(10))
145 .withType(PACKET_OUT)
146 .withMetadata(PiPacketMetadata.builder()
147 .withId(PiPacketMetadataId.of("egress_port"))
148 .withValue(fit(copyFrom(1), 9))
149 .build())
150 .build();
151
152 assert (client.packetOut(packetOperation, bmv2DefaultPipeconf).get());
153 }
154
155 private void testDumpTable(String tableName, PiPipeconf pipeconf) throws ExecutionException, InterruptedException {
156 assert (client.dumpTable(PiTableId.of(tableName), pipeconf).get().size() == 0);
157 }
158
159 @Test
160 @Ignore
161 public void testBmv2() throws Exception {
162
163 createClientAndSetPipelineConfig(bmv2DefaultPipeconf, BMV2_JSON);
164
165 testDumpTable("table0", bmv2DefaultPipeconf);
166
167 // testPacketOut();
168
169 testActionProfile(285261835);
170 }
171
172 @Test
173 @Ignore
174 public void testTofino() throws Exception {
175
176 createClientAndSetPipelineConfig(bmv2DefaultPipeconf, null);
177 }
178
179// OLD STUFF
Carmelo Casconec8e84982017-07-26 15:34:42 -0400180// log.info("++++++++++++++++++++++++++++");
181//
182// PiPipelineInterpreter interpreter = (PiPipelineInterpreter) defaultPipeconf
183// .implementation(PiPipelineInterpreter.class)
184// .orElse(null)
185// .newInstance();
186//
187// TrafficTreatment t = DefaultTrafficTreatment.builder()
188// .setOutput(PortNumber.portNumber(830L)).build();
189// byte[] payload = new byte[1000];
190//// payload[0] = 1;
191// Arrays.fill( payload, (byte) 1 );
192//
193// OutboundPacket packet = new DefaultOutboundPacket(
194// deviceId, t, ByteBuffer.wrap(payload));
195//
196//
197// Collection<PiPacketOperation> operations = interpreter.mapOutboundPacket(packet,defaultPipeconf);
198// log.info("{}", operations);
199// operations.forEach(piPacketOperation -> {
200// try {
201// client.packetOut(piPacketOperation, defaultPipeconf).get();
202// } catch (InterruptedException | ExecutionException e) {
203// log.error("{}",e);
204// }
205// });
206
207// assert(client.dumpTable(PiTableId.of(TABLE_0), defaultPipeconf).get().size() == 0);
208
209// assert(client.writeTableEntries(Lists.newArrayList(piTableEntry), INSERT, defaultPipeconf).get());
210
211// assert(client.dumpTable(PiTableId.of(TABLE_0), defaultPipeconf).get().size() == 1);
Carmelo Casconec8e84982017-07-26 15:34:42 -0400212}