blob: 73ce3936d6acefbb017e86dceec0a240743fd9a6 [file] [log] [blame]
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -08001/*
2 * Copyright 2015 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 */
16package org.onosproject.net.group.impl;
17
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070018import static org.junit.Assert.assertEquals;
19import static org.junit.Assert.assertFalse;
20import static org.junit.Assert.assertNotEquals;
21import static org.junit.Assert.assertNotNull;
22import static org.junit.Assert.assertTrue;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070023import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070024
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080025import java.util.ArrayList;
26import java.util.Arrays;
27import java.util.Collections;
28import java.util.List;
29
30import org.junit.After;
31import org.junit.Before;
32import org.junit.Test;
33import org.onlab.packet.MacAddress;
Michele Santuari4b6019e2014-12-19 11:31:45 +010034import org.onlab.packet.MplsLabel;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080035import org.onosproject.core.ApplicationId;
36import org.onosproject.core.DefaultApplicationId;
37import org.onosproject.core.DefaultGroupId;
38import org.onosproject.core.GroupId;
Thomas Vachuska36002e62015-05-19 16:12:29 -070039import org.onosproject.common.event.impl.TestEventDispatcher;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080040import org.onosproject.net.DeviceId;
41import org.onosproject.net.PortNumber;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080042import org.onosproject.net.device.impl.DeviceManager;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080043import org.onosproject.net.flow.DefaultTrafficTreatment;
44import org.onosproject.net.flow.TrafficTreatment;
45import org.onosproject.net.group.DefaultGroup;
46import org.onosproject.net.group.DefaultGroupBucket;
47import org.onosproject.net.group.DefaultGroupDescription;
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070048import org.onosproject.net.group.DefaultGroupKey;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080049import org.onosproject.net.group.Group;
50import org.onosproject.net.group.GroupBucket;
51import org.onosproject.net.group.GroupBuckets;
52import org.onosproject.net.group.GroupDescription;
53import org.onosproject.net.group.GroupEvent;
54import org.onosproject.net.group.GroupKey;
55import org.onosproject.net.group.GroupListener;
56import org.onosproject.net.group.GroupOperation;
57import org.onosproject.net.group.GroupOperations;
58import org.onosproject.net.group.GroupProvider;
59import org.onosproject.net.group.GroupProviderRegistry;
60import org.onosproject.net.group.GroupProviderService;
61import org.onosproject.net.group.GroupService;
62import org.onosproject.net.group.StoredGroupEntry;
63import org.onosproject.net.provider.AbstractProvider;
64import org.onosproject.net.provider.ProviderId;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070065import org.onosproject.store.trivial.SimpleGroupStore;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080066
67import com.google.common.collect.Iterables;
68
69/**
70 * Test codifying the group service & group provider service contracts.
71 */
72public class GroupManagerTest {
73
74 private static final ProviderId PID = new ProviderId("of", "groupfoo");
75 private static final DeviceId DID = DeviceId.deviceId("of:001");
76
77 private GroupManager mgr;
78 private GroupService groupService;
79 private GroupProviderRegistry providerRegistry;
80 private TestGroupListener internalListener = new TestGroupListener();
81 private GroupListener listener = internalListener;
82 private TestGroupProvider internalProvider;
83 private GroupProvider provider;
84 private GroupProviderService providerService;
85 private ApplicationId appId;
86
87 @Before
88 public void setUp() {
89 mgr = new GroupManager();
90 groupService = mgr;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080091 mgr.deviceService = new DeviceManager();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080092 mgr.store = new SimpleGroupStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070093 injectEventDispatcher(mgr, new TestEventDispatcher());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080094 providerRegistry = mgr;
95
96 mgr.activate();
97 mgr.addListener(listener);
98
99 internalProvider = new TestGroupProvider(PID);
100 provider = internalProvider;
101 providerService = providerRegistry.register(provider);
102 appId = new DefaultApplicationId(2, "org.groupmanager.test");
103 assertTrue("provider should be registered",
104 providerRegistry.getProviders().contains(provider.id()));
105 }
106
107 @After
108 public void tearDown() {
109 providerRegistry.unregister(provider);
110 assertFalse("provider should not be registered",
111 providerRegistry.getProviders().contains(provider.id()));
112 mgr.removeListener(listener);
113 mgr.deactivate();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700114 injectEventDispatcher(mgr, null);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800115 }
116
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800117 /**
118 * Tests group service north bound and south bound interfaces.
119 * The following operations are tested:
120 * a)Tests group creation before the device group AUDIT completes
121 * b)Tests initial device group AUDIT process
122 * c)Tests deletion process of any extraneous groups
123 * d)Tests execution of any pending group creation requests
124 * after the device group AUDIT completes
125 * e)Tests re-apply process of any missing groups
126 * f)Tests event notifications after receiving confirmation for
127 * any operations from data plane
128 * g)Tests group bucket modifications (additions and deletions)
129 * h)Tests group deletion
130 */
131 @Test
132 public void testGroupService() {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800133 // Test Group creation before AUDIT process
134 testGroupCreationBeforeAudit();
135
136 // Test initial group audit process
137 testInitialAuditWithPendingGroupRequests();
138
139 // Test audit with extraneous and missing groups
140 testAuditWithExtraneousMissingGroups();
141
142 // Test audit with confirmed groups
143 testAuditWithConfirmedGroups();
144
145 // Test group add bucket operations
146 testAddBuckets();
147
148 // Test group remove bucket operations
149 testRemoveBuckets();
150
151 // Test group remove operations
152 testRemoveGroup();
153 }
154
155 // Test Group creation before AUDIT process
156 private void testGroupCreationBeforeAudit() {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800157 PortNumber[] ports1 = {PortNumber.portNumber(31),
158 PortNumber.portNumber(32)};
159 PortNumber[] ports2 = {PortNumber.portNumber(41),
160 PortNumber.portNumber(42)};
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700161 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700162 List<GroupBucket> buckets = new ArrayList<>();
163 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800164 outPorts.addAll(Arrays.asList(ports1));
165 outPorts.addAll(Arrays.asList(ports2));
166 for (PortNumber portNumber: outPorts) {
167 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
168 tBuilder.setOutput(portNumber)
169 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
170 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
171 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100172 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800173 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
174 tBuilder.build()));
175 }
176 GroupBuckets groupBuckets = new GroupBuckets(buckets);
177 GroupDescription newGroupDesc = new DefaultGroupDescription(DID,
178 Group.Type.SELECT,
179 groupBuckets,
180 key,
Saurav Das100e3b82015-04-30 11:12:10 -0700181 null,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800182 appId);
183 groupService.addGroup(newGroupDesc);
184 internalProvider.validate(DID, null);
185 assertEquals(null, groupService.getGroup(DID, key));
186 assertEquals(0, Iterables.size(groupService.getGroups(DID, appId)));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800187 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800188
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800189 // Test initial AUDIT process with pending group requests
190 private void testInitialAuditWithPendingGroupRequests() {
191 PortNumber[] ports1 = {PortNumber.portNumber(31),
192 PortNumber.portNumber(32)};
193 PortNumber[] ports2 = {PortNumber.portNumber(41),
194 PortNumber.portNumber(42)};
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800195 GroupId gId1 = new DefaultGroupId(1);
196 Group group1 = createSouthboundGroupEntry(gId1,
197 Arrays.asList(ports1),
198 0);
199 GroupId gId2 = new DefaultGroupId(2);
200 // Non zero reference count will make the group manager to queue
201 // the extraneous groups until reference count is zero.
202 Group group2 = createSouthboundGroupEntry(gId2,
203 Arrays.asList(ports2),
204 2);
205 List<Group> groupEntries = Arrays.asList(group1, group2);
206 providerService.pushGroupMetrics(DID, groupEntries);
207 // First group metrics would trigger the device audit completion
208 // post which all pending group requests are also executed.
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700209 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800210 Group createdGroup = groupService.getGroup(DID, key);
211 int createdGroupId = createdGroup.id().id();
212 assertNotEquals(gId1.id(), createdGroupId);
213 assertNotEquals(gId2.id(), createdGroupId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800214
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800215 List<GroupOperation> expectedGroupOps = Arrays.asList(
216 GroupOperation.createDeleteGroupOperation(gId1,
217 Group.Type.SELECT),
218 GroupOperation.createAddGroupOperation(
219 createdGroup.id(),
220 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800221 createdGroup.buckets()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800222 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800223 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800224
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800225 // Test AUDIT process with extraneous groups and missing groups
226 private void testAuditWithExtraneousMissingGroups() {
227 PortNumber[] ports1 = {PortNumber.portNumber(31),
228 PortNumber.portNumber(32)};
229 PortNumber[] ports2 = {PortNumber.portNumber(41),
230 PortNumber.portNumber(42)};
231 GroupId gId1 = new DefaultGroupId(1);
232 Group group1 = createSouthboundGroupEntry(gId1,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800233 Arrays.asList(ports1),
234 0);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800235 GroupId gId2 = new DefaultGroupId(2);
236 Group group2 = createSouthboundGroupEntry(gId2,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800237 Arrays.asList(ports2),
238 0);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800239 List<Group> groupEntries = Arrays.asList(group1, group2);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800240 providerService.pushGroupMetrics(DID, groupEntries);
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700241 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800242 Group createdGroup = groupService.getGroup(DID, key);
243 List<GroupOperation> expectedGroupOps = Arrays.asList(
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800244 GroupOperation.createDeleteGroupOperation(gId1,
245 Group.Type.SELECT),
246 GroupOperation.createDeleteGroupOperation(gId2,
247 Group.Type.SELECT),
248 GroupOperation.createAddGroupOperation(createdGroup.id(),
249 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800250 createdGroup.buckets()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800251 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800252 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800253
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800254 // Test AUDIT with confirmed groups
255 private void testAuditWithConfirmedGroups() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700256 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800257 Group createdGroup = groupService.getGroup(DID, key);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800258 createdGroup = new DefaultGroup(createdGroup.id(),
259 DID,
260 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800261 createdGroup.buckets());
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700262 List<Group> groupEntries = Collections.singletonList(createdGroup);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800263 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700264 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADDED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800265 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800266
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800267 // Test group add bucket operations
268 private void testAddBuckets() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700269 GroupKey addKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800270
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700271 GroupKey prevKey = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800272 Group createdGroup = groupService.getGroup(DID, prevKey);
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700273 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800274 buckets.addAll(createdGroup.buckets().buckets());
275
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800276 PortNumber[] addPorts = {PortNumber.portNumber(51),
277 PortNumber.portNumber(52)};
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700278 List<PortNumber> outPorts;
Sho SHIMIZU7a4087b2015-09-10 09:23:16 -0700279 outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800280 outPorts.addAll(Arrays.asList(addPorts));
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700281 List<GroupBucket> addBuckets;
Sho SHIMIZU7a4087b2015-09-10 09:23:16 -0700282 addBuckets = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800283 for (PortNumber portNumber: outPorts) {
284 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
285 tBuilder.setOutput(portNumber)
286 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
287 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
288 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100289 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800290 addBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
291 tBuilder.build()));
292 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
293 tBuilder.build()));
294 }
295 GroupBuckets groupAddBuckets = new GroupBuckets(addBuckets);
296 groupService.addBucketsToGroup(DID,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800297 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800298 groupAddBuckets,
299 addKey,
300 appId);
301 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700302 List<GroupOperation> expectedGroupOps = Collections.singletonList(
303 GroupOperation.createModifyGroupOperation(createdGroup.id(),
304 Group.Type.SELECT,
305 updatedBuckets));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800306 internalProvider.validate(DID, expectedGroupOps);
307 Group existingGroup = groupService.getGroup(DID, addKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700308 List<Group> groupEntries = Collections.singletonList(existingGroup);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800309 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700310 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800311 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800312
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800313 // Test group remove bucket operations
314 private void testRemoveBuckets() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700315 GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800316
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700317 GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800318 Group createdGroup = groupService.getGroup(DID, prevKey);
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700319 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800320 buckets.addAll(createdGroup.buckets().buckets());
321
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800322 PortNumber[] removePorts = {PortNumber.portNumber(31),
323 PortNumber.portNumber(32)};
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700324 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800325 outPorts.addAll(Arrays.asList(removePorts));
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700326 List<GroupBucket> removeBuckets = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800327 for (PortNumber portNumber: outPorts) {
328 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
329 tBuilder.setOutput(portNumber)
330 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
331 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
332 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100333 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800334 removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
335 tBuilder.build()));
336 buckets.remove(DefaultGroupBucket.createSelectGroupBucket(
337 tBuilder.build()));
338 }
339 GroupBuckets groupRemoveBuckets = new GroupBuckets(removeBuckets);
340 groupService.removeBucketsFromGroup(DID,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800341 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800342 groupRemoveBuckets,
343 removeKey,
344 appId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800345 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700346 List<GroupOperation> expectedGroupOps = Collections.singletonList(
347 GroupOperation.createModifyGroupOperation(createdGroup.id(),
348 Group.Type.SELECT,
349 updatedBuckets));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800350 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800351 Group existingGroup = groupService.getGroup(DID, removeKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700352 List<Group> groupEntries = Collections.singletonList(existingGroup);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800353 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700354 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800355 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800356
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800357 // Test group remove operations
358 private void testRemoveGroup() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700359 GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800360 Group existingGroup = groupService.getGroup(DID, currKey);
361 groupService.removeGroup(DID, currKey, appId);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700362 List<GroupOperation> expectedGroupOps = Collections.singletonList(
363 GroupOperation.createDeleteGroupOperation(existingGroup.id(),
364 Group.Type.SELECT));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800365 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800366 List<Group> groupEntries = Collections.emptyList();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800367 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700368 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVED));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800369 }
370
sangho7ff01812015-02-09 16:21:53 -0800371 /**
372 * Test GroupOperationFailure function in Group Manager.
373 * a)GroupAddFailure
374 * b)GroupUpdateFailure
375 * c)GroupRemoteFailure
376 */
377 @Test
378 public void testGroupOperationFailure() {
379 PortNumber[] ports1 = {PortNumber.portNumber(31),
380 PortNumber.portNumber(32)};
381 PortNumber[] ports2 = {PortNumber.portNumber(41),
382 PortNumber.portNumber(42)};
383 // Test Group creation before AUDIT process
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700384 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700385 List<GroupBucket> buckets = new ArrayList<>();
386 List<PortNumber> outPorts = new ArrayList<>();
sangho7ff01812015-02-09 16:21:53 -0800387 outPorts.addAll(Arrays.asList(ports1));
388 outPorts.addAll(Arrays.asList(ports2));
389 for (PortNumber portNumber: outPorts) {
390 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
391 tBuilder.setOutput(portNumber)
392 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
393 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
394 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100395 .setMpls(MplsLabel.mplsLabel(106));
sangho7ff01812015-02-09 16:21:53 -0800396 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
397 tBuilder.build()));
398 }
399 GroupBuckets groupBuckets = new GroupBuckets(buckets);
400 GroupDescription newGroupDesc = new DefaultGroupDescription(DID,
401 Group.Type.SELECT,
402 groupBuckets,
403 key,
Saurav Das100e3b82015-04-30 11:12:10 -0700404 null,
sangho7ff01812015-02-09 16:21:53 -0800405 appId);
406 groupService.addGroup(newGroupDesc);
407
408 // Test initial group audit process
409 GroupId gId1 = new DefaultGroupId(1);
410 Group group1 = createSouthboundGroupEntry(gId1,
411 Arrays.asList(ports1),
412 0);
413 GroupId gId2 = new DefaultGroupId(2);
414 // Non zero reference count will make the group manager to queue
415 // the extraneous groups until reference count is zero.
416 Group group2 = createSouthboundGroupEntry(gId2,
417 Arrays.asList(ports2),
418 2);
419 List<Group> groupEntries = Arrays.asList(group1, group2);
420 providerService.pushGroupMetrics(DID, groupEntries);
421 Group createdGroup = groupService.getGroup(DID, key);
422
423 // Group Add failure test
424 GroupOperation groupAddOp = GroupOperation.
425 createAddGroupOperation(createdGroup.id(),
426 createdGroup.type(),
427 createdGroup.buckets());
428 providerService.groupOperationFailed(DID, groupAddOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700429 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADD_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800430
431 // Group Mod failure test
432 groupService.addGroup(newGroupDesc);
433 createdGroup = groupService.getGroup(DID, key);
434 assertNotNull(createdGroup);
435
436 GroupOperation groupModOp = GroupOperation.
437 createModifyGroupOperation(createdGroup.id(),
438 createdGroup.type(),
439 createdGroup.buckets());
440 providerService.groupOperationFailed(DID, groupModOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700441 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800442
443 // Group Delete failure test
444 groupService.addGroup(newGroupDesc);
445 createdGroup = groupService.getGroup(DID, key);
446 assertNotNull(createdGroup);
447
448 GroupOperation groupDelOp = GroupOperation.
449 createDeleteGroupOperation(createdGroup.id(),
450 createdGroup.type());
451 providerService.groupOperationFailed(DID, groupDelOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700452 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800453
454 }
455
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800456 private Group createSouthboundGroupEntry(GroupId gId,
457 List<PortNumber> ports,
458 long referenceCount) {
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700459 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800460 outPorts.addAll(ports);
461
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700462 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800463 for (PortNumber portNumber: outPorts) {
464 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
465 tBuilder.setOutput(portNumber)
466 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
467 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
468 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100469 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800470 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
471 tBuilder.build()));
472 }
473 GroupBuckets groupBuckets = new GroupBuckets(buckets);
474 StoredGroupEntry group = new DefaultGroup(
475 gId, DID, Group.Type.SELECT, groupBuckets);
476 group.setReferenceCount(referenceCount);
477 return group;
478 }
479
480 private static class TestGroupListener implements GroupListener {
481 final List<GroupEvent> events = new ArrayList<>();
482
483 @Override
484 public void event(GroupEvent event) {
485 events.add(event);
486 }
487
488 public void validateEvent(List<GroupEvent.Type> expectedEvents) {
489 int i = 0;
490 System.err.println("events :" + events);
491 for (GroupEvent e : events) {
492 assertEquals("unexpected event", expectedEvents.get(i), e.type());
493 i++;
494 }
495 assertEquals("mispredicted number of events",
496 expectedEvents.size(), events.size());
497 events.clear();
498 }
499 }
500
501 private class TestGroupProvider
502 extends AbstractProvider implements GroupProvider {
503 DeviceId lastDeviceId;
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700504 List<GroupOperation> groupOperations = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800505
506 protected TestGroupProvider(ProviderId id) {
507 super(id);
508 }
509
510 @Override
511 public void performGroupOperation(DeviceId deviceId,
512 GroupOperations groupOps) {
513 lastDeviceId = deviceId;
514 groupOperations.addAll(groupOps.operations());
515 }
516
517 public void validate(DeviceId expectedDeviceId,
518 List<GroupOperation> expectedGroupOps) {
519 if (expectedGroupOps == null) {
520 assertTrue("events generated", groupOperations.isEmpty());
521 return;
522 }
523
524 assertEquals(lastDeviceId, expectedDeviceId);
525 assertTrue((this.groupOperations.containsAll(expectedGroupOps) &&
526 expectedGroupOps.containsAll(groupOperations)));
527
528 groupOperations.clear();
529 lastDeviceId = null;
530 }
531
532 }
533
534}
535
536