blob: d2079a8ce06c55db19b5229b13e04bc15a0e1d88 [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());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800162 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
163 List<PortNumber> outPorts = new ArrayList<PortNumber>();
164 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);
273 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
274 buckets.addAll(createdGroup.buckets().buckets());
275
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800276 PortNumber[] addPorts = {PortNumber.portNumber(51),
277 PortNumber.portNumber(52)};
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800278 List<PortNumber> outPorts = new ArrayList<PortNumber>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800279 outPorts.addAll(Arrays.asList(addPorts));
280 List<GroupBucket> addBuckets = new ArrayList<GroupBucket>();
281 for (PortNumber portNumber: outPorts) {
282 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
283 tBuilder.setOutput(portNumber)
284 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
285 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
286 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100287 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800288 addBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
289 tBuilder.build()));
290 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
291 tBuilder.build()));
292 }
293 GroupBuckets groupAddBuckets = new GroupBuckets(addBuckets);
294 groupService.addBucketsToGroup(DID,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800295 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800296 groupAddBuckets,
297 addKey,
298 appId);
299 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700300 List<GroupOperation> expectedGroupOps = Collections.singletonList(
301 GroupOperation.createModifyGroupOperation(createdGroup.id(),
302 Group.Type.SELECT,
303 updatedBuckets));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800304 internalProvider.validate(DID, expectedGroupOps);
305 Group existingGroup = groupService.getGroup(DID, addKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700306 List<Group> groupEntries = Collections.singletonList(existingGroup);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800307 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700308 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800309 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800310
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800311 // Test group remove bucket operations
312 private void testRemoveBuckets() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700313 GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800314
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700315 GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800316 Group createdGroup = groupService.getGroup(DID, prevKey);
317 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
318 buckets.addAll(createdGroup.buckets().buckets());
319
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800320 PortNumber[] removePorts = {PortNumber.portNumber(31),
321 PortNumber.portNumber(32)};
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800322 List<PortNumber> outPorts = new ArrayList<PortNumber>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800323 outPorts.addAll(Arrays.asList(removePorts));
324 List<GroupBucket> removeBuckets = new ArrayList<GroupBucket>();
325 for (PortNumber portNumber: outPorts) {
326 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
327 tBuilder.setOutput(portNumber)
328 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
329 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
330 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100331 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800332 removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
333 tBuilder.build()));
334 buckets.remove(DefaultGroupBucket.createSelectGroupBucket(
335 tBuilder.build()));
336 }
337 GroupBuckets groupRemoveBuckets = new GroupBuckets(removeBuckets);
338 groupService.removeBucketsFromGroup(DID,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800339 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800340 groupRemoveBuckets,
341 removeKey,
342 appId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800343 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700344 List<GroupOperation> expectedGroupOps = Collections.singletonList(
345 GroupOperation.createModifyGroupOperation(createdGroup.id(),
346 Group.Type.SELECT,
347 updatedBuckets));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800348 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800349 Group existingGroup = groupService.getGroup(DID, removeKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700350 List<Group> groupEntries = Collections.singletonList(existingGroup);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800351 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700352 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800353 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800354
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800355 // Test group remove operations
356 private void testRemoveGroup() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700357 GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800358 Group existingGroup = groupService.getGroup(DID, currKey);
359 groupService.removeGroup(DID, currKey, appId);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700360 List<GroupOperation> expectedGroupOps = Collections.singletonList(
361 GroupOperation.createDeleteGroupOperation(existingGroup.id(),
362 Group.Type.SELECT));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800363 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800364 List<Group> groupEntries = Collections.emptyList();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800365 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700366 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVED));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800367 }
368
sangho7ff01812015-02-09 16:21:53 -0800369 /**
370 * Test GroupOperationFailure function in Group Manager.
371 * a)GroupAddFailure
372 * b)GroupUpdateFailure
373 * c)GroupRemoteFailure
374 */
375 @Test
376 public void testGroupOperationFailure() {
377 PortNumber[] ports1 = {PortNumber.portNumber(31),
378 PortNumber.portNumber(32)};
379 PortNumber[] ports2 = {PortNumber.portNumber(41),
380 PortNumber.portNumber(42)};
381 // Test Group creation before AUDIT process
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700382 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
sangho7ff01812015-02-09 16:21:53 -0800383 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
384 List<PortNumber> outPorts = new ArrayList<PortNumber>();
385 outPorts.addAll(Arrays.asList(ports1));
386 outPorts.addAll(Arrays.asList(ports2));
387 for (PortNumber portNumber: outPorts) {
388 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
389 tBuilder.setOutput(portNumber)
390 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
391 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
392 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100393 .setMpls(MplsLabel.mplsLabel(106));
sangho7ff01812015-02-09 16:21:53 -0800394 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
395 tBuilder.build()));
396 }
397 GroupBuckets groupBuckets = new GroupBuckets(buckets);
398 GroupDescription newGroupDesc = new DefaultGroupDescription(DID,
399 Group.Type.SELECT,
400 groupBuckets,
401 key,
Saurav Das100e3b82015-04-30 11:12:10 -0700402 null,
sangho7ff01812015-02-09 16:21:53 -0800403 appId);
404 groupService.addGroup(newGroupDesc);
405
406 // Test initial group audit process
407 GroupId gId1 = new DefaultGroupId(1);
408 Group group1 = createSouthboundGroupEntry(gId1,
409 Arrays.asList(ports1),
410 0);
411 GroupId gId2 = new DefaultGroupId(2);
412 // Non zero reference count will make the group manager to queue
413 // the extraneous groups until reference count is zero.
414 Group group2 = createSouthboundGroupEntry(gId2,
415 Arrays.asList(ports2),
416 2);
417 List<Group> groupEntries = Arrays.asList(group1, group2);
418 providerService.pushGroupMetrics(DID, groupEntries);
419 Group createdGroup = groupService.getGroup(DID, key);
420
421 // Group Add failure test
422 GroupOperation groupAddOp = GroupOperation.
423 createAddGroupOperation(createdGroup.id(),
424 createdGroup.type(),
425 createdGroup.buckets());
426 providerService.groupOperationFailed(DID, groupAddOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700427 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADD_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800428
429 // Group Mod failure test
430 groupService.addGroup(newGroupDesc);
431 createdGroup = groupService.getGroup(DID, key);
432 assertNotNull(createdGroup);
433
434 GroupOperation groupModOp = GroupOperation.
435 createModifyGroupOperation(createdGroup.id(),
436 createdGroup.type(),
437 createdGroup.buckets());
438 providerService.groupOperationFailed(DID, groupModOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700439 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800440
441 // Group Delete failure test
442 groupService.addGroup(newGroupDesc);
443 createdGroup = groupService.getGroup(DID, key);
444 assertNotNull(createdGroup);
445
446 GroupOperation groupDelOp = GroupOperation.
447 createDeleteGroupOperation(createdGroup.id(),
448 createdGroup.type());
449 providerService.groupOperationFailed(DID, groupDelOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700450 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800451
452 }
453
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800454 private Group createSouthboundGroupEntry(GroupId gId,
455 List<PortNumber> ports,
456 long referenceCount) {
457 List<PortNumber> outPorts = new ArrayList<PortNumber>();
458 outPorts.addAll(ports);
459
460 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
461 for (PortNumber portNumber: outPorts) {
462 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
463 tBuilder.setOutput(portNumber)
464 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
465 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
466 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100467 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800468 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
469 tBuilder.build()));
470 }
471 GroupBuckets groupBuckets = new GroupBuckets(buckets);
472 StoredGroupEntry group = new DefaultGroup(
473 gId, DID, Group.Type.SELECT, groupBuckets);
474 group.setReferenceCount(referenceCount);
475 return group;
476 }
477
478 private static class TestGroupListener implements GroupListener {
479 final List<GroupEvent> events = new ArrayList<>();
480
481 @Override
482 public void event(GroupEvent event) {
483 events.add(event);
484 }
485
486 public void validateEvent(List<GroupEvent.Type> expectedEvents) {
487 int i = 0;
488 System.err.println("events :" + events);
489 for (GroupEvent e : events) {
490 assertEquals("unexpected event", expectedEvents.get(i), e.type());
491 i++;
492 }
493 assertEquals("mispredicted number of events",
494 expectedEvents.size(), events.size());
495 events.clear();
496 }
497 }
498
499 private class TestGroupProvider
500 extends AbstractProvider implements GroupProvider {
501 DeviceId lastDeviceId;
502 List<GroupOperation> groupOperations = new ArrayList<GroupOperation>();
503
504 protected TestGroupProvider(ProviderId id) {
505 super(id);
506 }
507
508 @Override
509 public void performGroupOperation(DeviceId deviceId,
510 GroupOperations groupOps) {
511 lastDeviceId = deviceId;
512 groupOperations.addAll(groupOps.operations());
513 }
514
515 public void validate(DeviceId expectedDeviceId,
516 List<GroupOperation> expectedGroupOps) {
517 if (expectedGroupOps == null) {
518 assertTrue("events generated", groupOperations.isEmpty());
519 return;
520 }
521
522 assertEquals(lastDeviceId, expectedDeviceId);
523 assertTrue((this.groupOperations.containsAll(expectedGroupOps) &&
524 expectedGroupOps.containsAll(groupOperations)));
525
526 groupOperations.clear();
527 lastDeviceId = null;
528 }
529
530 }
531
532}
533
534