blob: 327296e71644e555d608a169f1d117a457a81d69 [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;
23
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080024import java.util.ArrayList;
25import java.util.Arrays;
26import java.util.Collections;
27import java.util.List;
28
29import org.junit.After;
30import org.junit.Before;
31import org.junit.Test;
32import org.onlab.packet.MacAddress;
Michele Santuari4b6019e2014-12-19 11:31:45 +010033import org.onlab.packet.MplsLabel;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080034import org.onosproject.core.ApplicationId;
35import org.onosproject.core.DefaultApplicationId;
36import org.onosproject.core.DefaultGroupId;
37import org.onosproject.core.GroupId;
Thomas Vachuska36002e62015-05-19 16:12:29 -070038import org.onosproject.common.event.impl.TestEventDispatcher;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080039import org.onosproject.net.DeviceId;
40import org.onosproject.net.PortNumber;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080041import org.onosproject.net.device.impl.DeviceManager;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080042import org.onosproject.net.flow.DefaultTrafficTreatment;
43import org.onosproject.net.flow.TrafficTreatment;
44import org.onosproject.net.group.DefaultGroup;
45import org.onosproject.net.group.DefaultGroupBucket;
46import org.onosproject.net.group.DefaultGroupDescription;
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070047import org.onosproject.net.group.DefaultGroupKey;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080048import org.onosproject.net.group.Group;
49import org.onosproject.net.group.GroupBucket;
50import org.onosproject.net.group.GroupBuckets;
51import org.onosproject.net.group.GroupDescription;
52import org.onosproject.net.group.GroupEvent;
53import org.onosproject.net.group.GroupKey;
54import org.onosproject.net.group.GroupListener;
55import org.onosproject.net.group.GroupOperation;
56import org.onosproject.net.group.GroupOperations;
57import org.onosproject.net.group.GroupProvider;
58import org.onosproject.net.group.GroupProviderRegistry;
59import org.onosproject.net.group.GroupProviderService;
60import org.onosproject.net.group.GroupService;
61import org.onosproject.net.group.StoredGroupEntry;
62import org.onosproject.net.provider.AbstractProvider;
63import org.onosproject.net.provider.ProviderId;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070064import org.onosproject.store.trivial.SimpleGroupStore;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080065
66import com.google.common.collect.Iterables;
67
68/**
69 * Test codifying the group service & group provider service contracts.
70 */
71public class GroupManagerTest {
72
73 private static final ProviderId PID = new ProviderId("of", "groupfoo");
74 private static final DeviceId DID = DeviceId.deviceId("of:001");
75
76 private GroupManager mgr;
77 private GroupService groupService;
78 private GroupProviderRegistry providerRegistry;
79 private TestGroupListener internalListener = new TestGroupListener();
80 private GroupListener listener = internalListener;
81 private TestGroupProvider internalProvider;
82 private GroupProvider provider;
83 private GroupProviderService providerService;
84 private ApplicationId appId;
85
86 @Before
87 public void setUp() {
88 mgr = new GroupManager();
89 groupService = mgr;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080090 mgr.deviceService = new DeviceManager();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080091 mgr.store = new SimpleGroupStore();
92 mgr.eventDispatcher = new TestEventDispatcher();
93 providerRegistry = mgr;
94
95 mgr.activate();
96 mgr.addListener(listener);
97
98 internalProvider = new TestGroupProvider(PID);
99 provider = internalProvider;
100 providerService = providerRegistry.register(provider);
101 appId = new DefaultApplicationId(2, "org.groupmanager.test");
102 assertTrue("provider should be registered",
103 providerRegistry.getProviders().contains(provider.id()));
104 }
105
106 @After
107 public void tearDown() {
108 providerRegistry.unregister(provider);
109 assertFalse("provider should not be registered",
110 providerRegistry.getProviders().contains(provider.id()));
111 mgr.removeListener(listener);
112 mgr.deactivate();
113 mgr.eventDispatcher = null;
114 }
115
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800116 /**
117 * Tests group service north bound and south bound interfaces.
118 * The following operations are tested:
119 * a)Tests group creation before the device group AUDIT completes
120 * b)Tests initial device group AUDIT process
121 * c)Tests deletion process of any extraneous groups
122 * d)Tests execution of any pending group creation requests
123 * after the device group AUDIT completes
124 * e)Tests re-apply process of any missing groups
125 * f)Tests event notifications after receiving confirmation for
126 * any operations from data plane
127 * g)Tests group bucket modifications (additions and deletions)
128 * h)Tests group deletion
129 */
130 @Test
131 public void testGroupService() {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800132 // Test Group creation before AUDIT process
133 testGroupCreationBeforeAudit();
134
135 // Test initial group audit process
136 testInitialAuditWithPendingGroupRequests();
137
138 // Test audit with extraneous and missing groups
139 testAuditWithExtraneousMissingGroups();
140
141 // Test audit with confirmed groups
142 testAuditWithConfirmedGroups();
143
144 // Test group add bucket operations
145 testAddBuckets();
146
147 // Test group remove bucket operations
148 testRemoveBuckets();
149
150 // Test group remove operations
151 testRemoveGroup();
152 }
153
154 // Test Group creation before AUDIT process
155 private void testGroupCreationBeforeAudit() {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800156 PortNumber[] ports1 = {PortNumber.portNumber(31),
157 PortNumber.portNumber(32)};
158 PortNumber[] ports2 = {PortNumber.portNumber(41),
159 PortNumber.portNumber(42)};
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700160 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800161 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
162 List<PortNumber> outPorts = new ArrayList<PortNumber>();
163 outPorts.addAll(Arrays.asList(ports1));
164 outPorts.addAll(Arrays.asList(ports2));
165 for (PortNumber portNumber: outPorts) {
166 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
167 tBuilder.setOutput(portNumber)
168 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
169 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
170 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100171 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800172 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
173 tBuilder.build()));
174 }
175 GroupBuckets groupBuckets = new GroupBuckets(buckets);
176 GroupDescription newGroupDesc = new DefaultGroupDescription(DID,
177 Group.Type.SELECT,
178 groupBuckets,
179 key,
Saurav Das100e3b82015-04-30 11:12:10 -0700180 null,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800181 appId);
182 groupService.addGroup(newGroupDesc);
183 internalProvider.validate(DID, null);
184 assertEquals(null, groupService.getGroup(DID, key));
185 assertEquals(0, Iterables.size(groupService.getGroups(DID, appId)));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800186 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800187
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800188 // Test initial AUDIT process with pending group requests
189 private void testInitialAuditWithPendingGroupRequests() {
190 PortNumber[] ports1 = {PortNumber.portNumber(31),
191 PortNumber.portNumber(32)};
192 PortNumber[] ports2 = {PortNumber.portNumber(41),
193 PortNumber.portNumber(42)};
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800194 GroupId gId1 = new DefaultGroupId(1);
195 Group group1 = createSouthboundGroupEntry(gId1,
196 Arrays.asList(ports1),
197 0);
198 GroupId gId2 = new DefaultGroupId(2);
199 // Non zero reference count will make the group manager to queue
200 // the extraneous groups until reference count is zero.
201 Group group2 = createSouthboundGroupEntry(gId2,
202 Arrays.asList(ports2),
203 2);
204 List<Group> groupEntries = Arrays.asList(group1, group2);
205 providerService.pushGroupMetrics(DID, groupEntries);
206 // First group metrics would trigger the device audit completion
207 // post which all pending group requests are also executed.
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700208 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800209 Group createdGroup = groupService.getGroup(DID, key);
210 int createdGroupId = createdGroup.id().id();
211 assertNotEquals(gId1.id(), createdGroupId);
212 assertNotEquals(gId2.id(), createdGroupId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800213
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800214 List<GroupOperation> expectedGroupOps = Arrays.asList(
215 GroupOperation.createDeleteGroupOperation(gId1,
216 Group.Type.SELECT),
217 GroupOperation.createAddGroupOperation(
218 createdGroup.id(),
219 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800220 createdGroup.buckets()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800221 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800222 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800223
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800224 // Test AUDIT process with extraneous groups and missing groups
225 private void testAuditWithExtraneousMissingGroups() {
226 PortNumber[] ports1 = {PortNumber.portNumber(31),
227 PortNumber.portNumber(32)};
228 PortNumber[] ports2 = {PortNumber.portNumber(41),
229 PortNumber.portNumber(42)};
230 GroupId gId1 = new DefaultGroupId(1);
231 Group group1 = createSouthboundGroupEntry(gId1,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800232 Arrays.asList(ports1),
233 0);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800234 GroupId gId2 = new DefaultGroupId(2);
235 Group group2 = createSouthboundGroupEntry(gId2,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800236 Arrays.asList(ports2),
237 0);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800238 List<Group> groupEntries = Arrays.asList(group1, group2);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800239 providerService.pushGroupMetrics(DID, groupEntries);
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700240 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800241 Group createdGroup = groupService.getGroup(DID, key);
242 List<GroupOperation> expectedGroupOps = Arrays.asList(
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800243 GroupOperation.createDeleteGroupOperation(gId1,
244 Group.Type.SELECT),
245 GroupOperation.createDeleteGroupOperation(gId2,
246 Group.Type.SELECT),
247 GroupOperation.createAddGroupOperation(createdGroup.id(),
248 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800249 createdGroup.buckets()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800250 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800251 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800252
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800253 // Test AUDIT with confirmed groups
254 private void testAuditWithConfirmedGroups() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700255 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800256 Group createdGroup = groupService.getGroup(DID, key);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800257 createdGroup = new DefaultGroup(createdGroup.id(),
258 DID,
259 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800260 createdGroup.buckets());
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700261 List<Group> groupEntries = Collections.singletonList(createdGroup);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800262 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700263 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADDED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800264 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800265
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800266 // Test group add bucket operations
267 private void testAddBuckets() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700268 GroupKey addKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800269
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700270 GroupKey prevKey = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800271 Group createdGroup = groupService.getGroup(DID, prevKey);
272 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
273 buckets.addAll(createdGroup.buckets().buckets());
274
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800275 PortNumber[] addPorts = {PortNumber.portNumber(51),
276 PortNumber.portNumber(52)};
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800277 List<PortNumber> outPorts = new ArrayList<PortNumber>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800278 outPorts.addAll(Arrays.asList(addPorts));
279 List<GroupBucket> addBuckets = new ArrayList<GroupBucket>();
280 for (PortNumber portNumber: outPorts) {
281 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
282 tBuilder.setOutput(portNumber)
283 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
284 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
285 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100286 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800287 addBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
288 tBuilder.build()));
289 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
290 tBuilder.build()));
291 }
292 GroupBuckets groupAddBuckets = new GroupBuckets(addBuckets);
293 groupService.addBucketsToGroup(DID,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800294 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800295 groupAddBuckets,
296 addKey,
297 appId);
298 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700299 List<GroupOperation> expectedGroupOps = Collections.singletonList(
300 GroupOperation.createModifyGroupOperation(createdGroup.id(),
301 Group.Type.SELECT,
302 updatedBuckets));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800303 internalProvider.validate(DID, expectedGroupOps);
304 Group existingGroup = groupService.getGroup(DID, addKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700305 List<Group> groupEntries = Collections.singletonList(existingGroup);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800306 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700307 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800308 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800309
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800310 // Test group remove bucket operations
311 private void testRemoveBuckets() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700312 GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800313
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700314 GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800315 Group createdGroup = groupService.getGroup(DID, prevKey);
316 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
317 buckets.addAll(createdGroup.buckets().buckets());
318
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800319 PortNumber[] removePorts = {PortNumber.portNumber(31),
320 PortNumber.portNumber(32)};
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800321 List<PortNumber> outPorts = new ArrayList<PortNumber>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800322 outPorts.addAll(Arrays.asList(removePorts));
323 List<GroupBucket> removeBuckets = new ArrayList<GroupBucket>();
324 for (PortNumber portNumber: outPorts) {
325 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
326 tBuilder.setOutput(portNumber)
327 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
328 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
329 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100330 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800331 removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
332 tBuilder.build()));
333 buckets.remove(DefaultGroupBucket.createSelectGroupBucket(
334 tBuilder.build()));
335 }
336 GroupBuckets groupRemoveBuckets = new GroupBuckets(removeBuckets);
337 groupService.removeBucketsFromGroup(DID,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800338 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800339 groupRemoveBuckets,
340 removeKey,
341 appId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800342 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700343 List<GroupOperation> expectedGroupOps = Collections.singletonList(
344 GroupOperation.createModifyGroupOperation(createdGroup.id(),
345 Group.Type.SELECT,
346 updatedBuckets));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800347 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800348 Group existingGroup = groupService.getGroup(DID, removeKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700349 List<Group> groupEntries = Collections.singletonList(existingGroup);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800350 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700351 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800352 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800353
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800354 // Test group remove operations
355 private void testRemoveGroup() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700356 GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800357 Group existingGroup = groupService.getGroup(DID, currKey);
358 groupService.removeGroup(DID, currKey, appId);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700359 List<GroupOperation> expectedGroupOps = Collections.singletonList(
360 GroupOperation.createDeleteGroupOperation(existingGroup.id(),
361 Group.Type.SELECT));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800362 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800363 List<Group> groupEntries = Collections.emptyList();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800364 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700365 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVED));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800366 }
367
sangho7ff01812015-02-09 16:21:53 -0800368 /**
369 * Test GroupOperationFailure function in Group Manager.
370 * a)GroupAddFailure
371 * b)GroupUpdateFailure
372 * c)GroupRemoteFailure
373 */
374 @Test
375 public void testGroupOperationFailure() {
376 PortNumber[] ports1 = {PortNumber.portNumber(31),
377 PortNumber.portNumber(32)};
378 PortNumber[] ports2 = {PortNumber.portNumber(41),
379 PortNumber.portNumber(42)};
380 // Test Group creation before AUDIT process
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700381 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
sangho7ff01812015-02-09 16:21:53 -0800382 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
383 List<PortNumber> outPorts = new ArrayList<PortNumber>();
384 outPorts.addAll(Arrays.asList(ports1));
385 outPorts.addAll(Arrays.asList(ports2));
386 for (PortNumber portNumber: outPorts) {
387 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
388 tBuilder.setOutput(portNumber)
389 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
390 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
391 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100392 .setMpls(MplsLabel.mplsLabel(106));
sangho7ff01812015-02-09 16:21:53 -0800393 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
394 tBuilder.build()));
395 }
396 GroupBuckets groupBuckets = new GroupBuckets(buckets);
397 GroupDescription newGroupDesc = new DefaultGroupDescription(DID,
398 Group.Type.SELECT,
399 groupBuckets,
400 key,
Saurav Das100e3b82015-04-30 11:12:10 -0700401 null,
sangho7ff01812015-02-09 16:21:53 -0800402 appId);
403 groupService.addGroup(newGroupDesc);
404
405 // Test initial group audit process
406 GroupId gId1 = new DefaultGroupId(1);
407 Group group1 = createSouthboundGroupEntry(gId1,
408 Arrays.asList(ports1),
409 0);
410 GroupId gId2 = new DefaultGroupId(2);
411 // Non zero reference count will make the group manager to queue
412 // the extraneous groups until reference count is zero.
413 Group group2 = createSouthboundGroupEntry(gId2,
414 Arrays.asList(ports2),
415 2);
416 List<Group> groupEntries = Arrays.asList(group1, group2);
417 providerService.pushGroupMetrics(DID, groupEntries);
418 Group createdGroup = groupService.getGroup(DID, key);
419
420 // Group Add failure test
421 GroupOperation groupAddOp = GroupOperation.
422 createAddGroupOperation(createdGroup.id(),
423 createdGroup.type(),
424 createdGroup.buckets());
425 providerService.groupOperationFailed(DID, groupAddOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700426 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADD_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800427
428 // Group Mod failure test
429 groupService.addGroup(newGroupDesc);
430 createdGroup = groupService.getGroup(DID, key);
431 assertNotNull(createdGroup);
432
433 GroupOperation groupModOp = GroupOperation.
434 createModifyGroupOperation(createdGroup.id(),
435 createdGroup.type(),
436 createdGroup.buckets());
437 providerService.groupOperationFailed(DID, groupModOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700438 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800439
440 // Group Delete failure test
441 groupService.addGroup(newGroupDesc);
442 createdGroup = groupService.getGroup(DID, key);
443 assertNotNull(createdGroup);
444
445 GroupOperation groupDelOp = GroupOperation.
446 createDeleteGroupOperation(createdGroup.id(),
447 createdGroup.type());
448 providerService.groupOperationFailed(DID, groupDelOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700449 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800450
451 }
452
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800453 private Group createSouthboundGroupEntry(GroupId gId,
454 List<PortNumber> ports,
455 long referenceCount) {
456 List<PortNumber> outPorts = new ArrayList<PortNumber>();
457 outPorts.addAll(ports);
458
459 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
460 for (PortNumber portNumber: outPorts) {
461 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
462 tBuilder.setOutput(portNumber)
463 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
464 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
465 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100466 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800467 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
468 tBuilder.build()));
469 }
470 GroupBuckets groupBuckets = new GroupBuckets(buckets);
471 StoredGroupEntry group = new DefaultGroup(
472 gId, DID, Group.Type.SELECT, groupBuckets);
473 group.setReferenceCount(referenceCount);
474 return group;
475 }
476
477 private static class TestGroupListener implements GroupListener {
478 final List<GroupEvent> events = new ArrayList<>();
479
480 @Override
481 public void event(GroupEvent event) {
482 events.add(event);
483 }
484
485 public void validateEvent(List<GroupEvent.Type> expectedEvents) {
486 int i = 0;
487 System.err.println("events :" + events);
488 for (GroupEvent e : events) {
489 assertEquals("unexpected event", expectedEvents.get(i), e.type());
490 i++;
491 }
492 assertEquals("mispredicted number of events",
493 expectedEvents.size(), events.size());
494 events.clear();
495 }
496 }
497
498 private class TestGroupProvider
499 extends AbstractProvider implements GroupProvider {
500 DeviceId lastDeviceId;
501 List<GroupOperation> groupOperations = new ArrayList<GroupOperation>();
502
503 protected TestGroupProvider(ProviderId id) {
504 super(id);
505 }
506
507 @Override
508 public void performGroupOperation(DeviceId deviceId,
509 GroupOperations groupOps) {
510 lastDeviceId = deviceId;
511 groupOperations.addAll(groupOps.operations());
512 }
513
514 public void validate(DeviceId expectedDeviceId,
515 List<GroupOperation> expectedGroupOps) {
516 if (expectedGroupOps == null) {
517 assertTrue("events generated", groupOperations.isEmpty());
518 return;
519 }
520
521 assertEquals(lastDeviceId, expectedDeviceId);
522 assertTrue((this.groupOperations.containsAll(expectedGroupOps) &&
523 expectedGroupOps.containsAll(groupOperations)));
524
525 groupOperations.clear();
526 lastDeviceId = null;
527 }
528
529 }
530
531}
532
533