blob: ac9817d072837631e2530f2a695ebbf01edd0b6d [file] [log] [blame]
Carmelo Cascone58136812018-07-19 03:40:16 +02001/*
2 * Copyright 2018-present Open Networking Foundation
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.net.pi.impl;
18
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.ImmutableSet;
21import com.google.common.testing.EqualsTester;
22import org.junit.Before;
23import org.junit.Test;
24import org.onlab.util.ImmutableByteSequence;
25import org.onosproject.TestApplicationId;
26import org.onosproject.core.ApplicationId;
27import org.onosproject.core.GroupId;
28import org.onosproject.net.DeviceId;
29import org.onosproject.net.flow.DefaultTrafficTreatment;
30import org.onosproject.net.flow.TrafficTreatment;
31import org.onosproject.net.flow.instructions.Instructions;
32import org.onosproject.net.group.DefaultGroup;
33import org.onosproject.net.group.DefaultGroupBucket;
34import org.onosproject.net.group.DefaultGroupDescription;
35import org.onosproject.net.group.Group;
36import org.onosproject.net.group.GroupBucket;
37import org.onosproject.net.group.GroupBuckets;
38import org.onosproject.net.group.GroupDescription;
39import org.onosproject.net.pi.model.PiPipeconf;
40import org.onosproject.net.pi.runtime.PiAction;
Carmelo Cascone58136812018-07-19 03:40:16 +020041import org.onosproject.net.pi.runtime.PiActionParam;
Carmelo Casconecb4327a2018-09-11 15:17:23 -070042import org.onosproject.net.pi.runtime.PiActionProfileGroup;
43import org.onosproject.net.pi.runtime.PiActionProfileMember;
44import org.onosproject.net.pi.runtime.PiActionProfileMemberId;
Carmelo Cascone58136812018-07-19 03:40:16 +020045import org.onosproject.net.pi.runtime.PiGroupKey;
46import org.onosproject.net.pi.runtime.PiTableAction;
47import org.onosproject.pipelines.basic.PipeconfLoader;
48
49import java.util.Collection;
50import java.util.List;
Carmelo Cascone99c59db2019-01-17 15:39:35 -080051import java.util.Objects;
52import java.util.stream.Collectors;
Carmelo Cascone58136812018-07-19 03:40:16 +020053
54import static org.hamcrest.CoreMatchers.equalTo;
55import static org.hamcrest.CoreMatchers.is;
56import static org.hamcrest.MatcherAssert.assertThat;
57import static org.onlab.util.ImmutableByteSequence.copyFrom;
58import static org.onosproject.net.group.GroupDescription.Type.SELECT;
Carmelo Cascone99c59db2019-01-17 15:39:35 -080059import static org.onosproject.net.pi.runtime.PiActionProfileGroup.WeightedMember.DEFAULT_WEIGHT;
Carmelo Cascone776be382018-12-12 19:03:57 -080060import static org.onosproject.pipelines.basic.BasicConstants.INGRESS_WCMP_CONTROL_SET_EGRESS_PORT;
61import static org.onosproject.pipelines.basic.BasicConstants.INGRESS_WCMP_CONTROL_WCMP_SELECTOR;
62import static org.onosproject.pipelines.basic.BasicConstants.INGRESS_WCMP_CONTROL_WCMP_TABLE;
63import static org.onosproject.pipelines.basic.BasicConstants.PORT;
Carmelo Cascone58136812018-07-19 03:40:16 +020064
65/**
66 * Test for {@link PiGroupTranslatorImpl}.
67 */
68public class PiGroupTranslatorImplTest {
69
70 private static final DeviceId DEVICE_ID = DeviceId.deviceId("device:dummy:1");
71 private static final ApplicationId APP_ID = TestApplicationId.create("dummy");
72 private static final GroupId GROUP_ID = GroupId.valueOf(1);
73 private static final PiGroupKey GROUP_KEY = new PiGroupKey(
Carmelo Cascone776be382018-12-12 19:03:57 -080074 INGRESS_WCMP_CONTROL_WCMP_TABLE, INGRESS_WCMP_CONTROL_WCMP_SELECTOR, GROUP_ID.id());
Carmelo Cascone58136812018-07-19 03:40:16 +020075 private static final List<GroupBucket> BUCKET_LIST = ImmutableList.of(
76 selectOutputBucket(1),
77 selectOutputBucket(2),
78 selectOutputBucket(3));
79 private static final GroupBuckets BUCKETS = new GroupBuckets(BUCKET_LIST);
80 private static final GroupDescription SELECT_GROUP_DESC = new DefaultGroupDescription(
81 DEVICE_ID, SELECT, BUCKETS, GROUP_KEY, GROUP_ID.id(), APP_ID);
82 private static final Group SELECT_GROUP = new DefaultGroup(GROUP_ID, SELECT_GROUP_DESC);
83 private static final int DEFAULT_MEMBER_WEIGHT = 1;
Carmelo Casconea4a89fb2019-08-20 02:03:10 -070084 private static final int BASE_MEM_ID = 991;
Carmelo Cascone776be382018-12-12 19:03:57 -080085 private static final int PORT_BITWIDTH = 9;
Carmelo Cascone99c59db2019-01-17 15:39:35 -080086 private Collection<PiActionProfileMember> expectedMemberInstances;
87 private Collection<PiActionProfileGroup.WeightedMember> expectedWeightedMembers;
Carmelo Cascone58136812018-07-19 03:40:16 +020088
89 private PiPipeconf pipeconf;
90
91 @Before
92 public void setUp() throws Exception {
93 pipeconf = PipeconfLoader.BASIC_PIPECONF;
Carmelo Cascone99c59db2019-01-17 15:39:35 -080094 expectedMemberInstances = ImmutableSet.of(outputMember(1),
95 outputMember(2),
96 outputMember(3));
97 expectedWeightedMembers = expectedMemberInstances.stream()
98 .map(m -> new PiActionProfileGroup.WeightedMember(m, DEFAULT_WEIGHT))
99 .collect(Collectors.toSet());
100
Carmelo Cascone58136812018-07-19 03:40:16 +0200101 }
102
103 private static GroupBucket selectOutputBucket(int portNum) {
104 ImmutableByteSequence paramVal = copyFrom(portNum);
Carmelo Cascone776be382018-12-12 19:03:57 -0800105 PiActionParam param = new PiActionParam(PORT, paramVal);
106 PiTableAction action = PiAction.builder()
107 .withId(INGRESS_WCMP_CONTROL_SET_EGRESS_PORT)
108 .withParameter(param).build();
Carmelo Cascone58136812018-07-19 03:40:16 +0200109 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
110 .add(Instructions.piTableAction(action))
111 .build();
112 return DefaultGroupBucket.createSelectGroupBucket(treatment);
113 }
114
Carmelo Casconecb4327a2018-09-11 15:17:23 -0700115 private static PiActionProfileMember outputMember(int portNum)
Carmelo Cascone58136812018-07-19 03:40:16 +0200116 throws ImmutableByteSequence.ByteSequenceTrimException {
Carmelo Cascone776be382018-12-12 19:03:57 -0800117 PiActionParam param = new PiActionParam(PORT, copyFrom(portNum).fit(PORT_BITWIDTH));
Carmelo Cascone58136812018-07-19 03:40:16 +0200118 PiAction piAction = PiAction.builder()
Carmelo Cascone776be382018-12-12 19:03:57 -0800119 .withId(INGRESS_WCMP_CONTROL_SET_EGRESS_PORT)
Carmelo Cascone58136812018-07-19 03:40:16 +0200120 .withParameter(param).build();
Carmelo Casconecb4327a2018-09-11 15:17:23 -0700121 return PiActionProfileMember.builder()
Carmelo Cascone776be382018-12-12 19:03:57 -0800122 .forActionProfile(INGRESS_WCMP_CONTROL_WCMP_SELECTOR)
Carmelo Cascone58136812018-07-19 03:40:16 +0200123 .withAction(piAction)
Carmelo Casconecb4327a2018-09-11 15:17:23 -0700124 .withId(PiActionProfileMemberId.of(BASE_MEM_ID + portNum))
Carmelo Cascone58136812018-07-19 03:40:16 +0200125 .build();
126 }
127
128 /**
129 * Test add group with buckets.
130 */
131 @Test
132 public void testTranslateGroups() throws Exception {
133
Carmelo Casconecb4327a2018-09-11 15:17:23 -0700134 PiActionProfileGroup piGroup1 = PiGroupTranslatorImpl.translate(SELECT_GROUP, pipeconf, null);
135 PiActionProfileGroup piGroup2 = PiGroupTranslatorImpl.translate(SELECT_GROUP, pipeconf, null);
Carmelo Cascone58136812018-07-19 03:40:16 +0200136
137 new EqualsTester()
138 .addEqualityGroup(piGroup1, piGroup2)
139 .testEquals();
140
141 assertThat("Group ID must be equal",
142 piGroup1.id().id(), is(equalTo(GROUP_ID.id())));
143 assertThat("Action profile ID must be equal",
Carmelo Cascone99c59db2019-01-17 15:39:35 -0800144 piGroup1.actionProfile(), is(equalTo(INGRESS_WCMP_CONTROL_WCMP_SELECTOR)));
Carmelo Cascone58136812018-07-19 03:40:16 +0200145
146 // members installed
Carmelo Cascone99c59db2019-01-17 15:39:35 -0800147 Collection<PiActionProfileGroup.WeightedMember> weightedMembers = piGroup1.members();
148 Collection<PiActionProfileMember> memberInstances = weightedMembers.stream()
149 .map(PiActionProfileGroup.WeightedMember::instance)
150 .filter(Objects::nonNull)
151 .collect(Collectors.toSet());
Carmelo Cascone58136812018-07-19 03:40:16 +0200152 assertThat("The number of group members must be equal",
Carmelo Cascone99c59db2019-01-17 15:39:35 -0800153 piGroup1.members().size(), is(expectedWeightedMembers.size()));
154 assertThat("Group weighted members must be equal",
155 weightedMembers.containsAll(expectedWeightedMembers)
156 && expectedWeightedMembers.containsAll(weightedMembers));
157 assertThat("Group member instances must be equal",
158 memberInstances.containsAll(expectedMemberInstances)
159 && expectedMemberInstances.containsAll(memberInstances));
160
Carmelo Cascone58136812018-07-19 03:40:16 +0200161 }
162}