blob: 27aaaf9b7058e455f12d9d7dea1557ca817ff383 [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;
Charles Chan0c7c43b2016-01-14 17:39:20 -080035import org.onosproject.cfg.ComponentConfigAdapter;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080036import org.onosproject.core.ApplicationId;
37import org.onosproject.core.DefaultApplicationId;
38import org.onosproject.core.DefaultGroupId;
39import org.onosproject.core.GroupId;
Thomas Vachuska36002e62015-05-19 16:12:29 -070040import org.onosproject.common.event.impl.TestEventDispatcher;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080041import org.onosproject.net.DeviceId;
42import org.onosproject.net.PortNumber;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080043import org.onosproject.net.device.impl.DeviceManager;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080044import org.onosproject.net.flow.DefaultTrafficTreatment;
45import org.onosproject.net.flow.TrafficTreatment;
46import org.onosproject.net.group.DefaultGroup;
47import org.onosproject.net.group.DefaultGroupBucket;
48import org.onosproject.net.group.DefaultGroupDescription;
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070049import org.onosproject.net.group.DefaultGroupKey;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080050import org.onosproject.net.group.Group;
51import org.onosproject.net.group.GroupBucket;
52import org.onosproject.net.group.GroupBuckets;
53import org.onosproject.net.group.GroupDescription;
54import org.onosproject.net.group.GroupEvent;
55import org.onosproject.net.group.GroupKey;
56import org.onosproject.net.group.GroupListener;
57import org.onosproject.net.group.GroupOperation;
58import org.onosproject.net.group.GroupOperations;
59import org.onosproject.net.group.GroupProvider;
60import org.onosproject.net.group.GroupProviderRegistry;
61import org.onosproject.net.group.GroupProviderService;
62import org.onosproject.net.group.GroupService;
63import org.onosproject.net.group.StoredGroupEntry;
64import org.onosproject.net.provider.AbstractProvider;
65import org.onosproject.net.provider.ProviderId;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070066import org.onosproject.store.trivial.SimpleGroupStore;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080067
68import com.google.common.collect.Iterables;
69
70/**
71 * Test codifying the group service & group provider service contracts.
72 */
73public class GroupManagerTest {
74
75 private static final ProviderId PID = new ProviderId("of", "groupfoo");
76 private static final DeviceId DID = DeviceId.deviceId("of:001");
77
78 private GroupManager mgr;
79 private GroupService groupService;
80 private GroupProviderRegistry providerRegistry;
81 private TestGroupListener internalListener = new TestGroupListener();
82 private GroupListener listener = internalListener;
83 private TestGroupProvider internalProvider;
84 private GroupProvider provider;
85 private GroupProviderService providerService;
86 private ApplicationId appId;
87
88 @Before
89 public void setUp() {
90 mgr = new GroupManager();
91 groupService = mgr;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080092 mgr.deviceService = new DeviceManager();
Charles Chan0c7c43b2016-01-14 17:39:20 -080093 mgr.cfgService = new ComponentConfigAdapter();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080094 mgr.store = new SimpleGroupStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070095 injectEventDispatcher(mgr, new TestEventDispatcher());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080096 providerRegistry = mgr;
97
Charles Chan0c7c43b2016-01-14 17:39:20 -080098 mgr.activate(null);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080099 mgr.addListener(listener);
100
101 internalProvider = new TestGroupProvider(PID);
102 provider = internalProvider;
103 providerService = providerRegistry.register(provider);
104 appId = new DefaultApplicationId(2, "org.groupmanager.test");
105 assertTrue("provider should be registered",
106 providerRegistry.getProviders().contains(provider.id()));
107 }
108
109 @After
110 public void tearDown() {
111 providerRegistry.unregister(provider);
112 assertFalse("provider should not be registered",
113 providerRegistry.getProviders().contains(provider.id()));
114 mgr.removeListener(listener);
115 mgr.deactivate();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700116 injectEventDispatcher(mgr, null);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800117 }
118
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800119 /**
120 * Tests group service north bound and south bound interfaces.
121 * The following operations are tested:
122 * a)Tests group creation before the device group AUDIT completes
123 * b)Tests initial device group AUDIT process
124 * c)Tests deletion process of any extraneous groups
125 * d)Tests execution of any pending group creation requests
126 * after the device group AUDIT completes
127 * e)Tests re-apply process of any missing groups
128 * f)Tests event notifications after receiving confirmation for
129 * any operations from data plane
130 * g)Tests group bucket modifications (additions and deletions)
131 * h)Tests group deletion
132 */
133 @Test
134 public void testGroupService() {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800135 // Test Group creation before AUDIT process
136 testGroupCreationBeforeAudit();
137
138 // Test initial group audit process
139 testInitialAuditWithPendingGroupRequests();
140
141 // Test audit with extraneous and missing groups
142 testAuditWithExtraneousMissingGroups();
143
144 // Test audit with confirmed groups
145 testAuditWithConfirmedGroups();
146
147 // Test group add bucket operations
148 testAddBuckets();
149
150 // Test group remove bucket operations
151 testRemoveBuckets();
152
153 // Test group remove operations
154 testRemoveGroup();
155 }
156
157 // Test Group creation before AUDIT process
158 private void testGroupCreationBeforeAudit() {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800159 PortNumber[] ports1 = {PortNumber.portNumber(31),
160 PortNumber.portNumber(32)};
161 PortNumber[] ports2 = {PortNumber.portNumber(41),
162 PortNumber.portNumber(42)};
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700163 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700164 List<GroupBucket> buckets = new ArrayList<>();
165 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800166 outPorts.addAll(Arrays.asList(ports1));
167 outPorts.addAll(Arrays.asList(ports2));
168 for (PortNumber portNumber: outPorts) {
169 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
170 tBuilder.setOutput(portNumber)
171 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
172 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
173 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100174 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800175 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
176 tBuilder.build()));
177 }
178 GroupBuckets groupBuckets = new GroupBuckets(buckets);
179 GroupDescription newGroupDesc = new DefaultGroupDescription(DID,
180 Group.Type.SELECT,
181 groupBuckets,
182 key,
Saurav Das100e3b82015-04-30 11:12:10 -0700183 null,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800184 appId);
185 groupService.addGroup(newGroupDesc);
186 internalProvider.validate(DID, null);
187 assertEquals(null, groupService.getGroup(DID, key));
188 assertEquals(0, Iterables.size(groupService.getGroups(DID, appId)));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800189 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800190
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800191 // Test initial AUDIT process with pending group requests
192 private void testInitialAuditWithPendingGroupRequests() {
193 PortNumber[] ports1 = {PortNumber.portNumber(31),
194 PortNumber.portNumber(32)};
195 PortNumber[] ports2 = {PortNumber.portNumber(41),
196 PortNumber.portNumber(42)};
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800197 GroupId gId1 = new DefaultGroupId(1);
198 Group group1 = createSouthboundGroupEntry(gId1,
199 Arrays.asList(ports1),
200 0);
201 GroupId gId2 = new DefaultGroupId(2);
202 // Non zero reference count will make the group manager to queue
203 // the extraneous groups until reference count is zero.
204 Group group2 = createSouthboundGroupEntry(gId2,
205 Arrays.asList(ports2),
206 2);
207 List<Group> groupEntries = Arrays.asList(group1, group2);
208 providerService.pushGroupMetrics(DID, groupEntries);
209 // First group metrics would trigger the device audit completion
210 // post which all pending group requests are also executed.
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700211 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800212 Group createdGroup = groupService.getGroup(DID, key);
213 int createdGroupId = createdGroup.id().id();
214 assertNotEquals(gId1.id(), createdGroupId);
215 assertNotEquals(gId2.id(), createdGroupId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800216
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800217 List<GroupOperation> expectedGroupOps = Arrays.asList(
218 GroupOperation.createDeleteGroupOperation(gId1,
219 Group.Type.SELECT),
220 GroupOperation.createAddGroupOperation(
221 createdGroup.id(),
222 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800223 createdGroup.buckets()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800224 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800225 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800226
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800227 // Test AUDIT process with extraneous groups and missing groups
228 private void testAuditWithExtraneousMissingGroups() {
229 PortNumber[] ports1 = {PortNumber.portNumber(31),
230 PortNumber.portNumber(32)};
231 PortNumber[] ports2 = {PortNumber.portNumber(41),
232 PortNumber.portNumber(42)};
233 GroupId gId1 = new DefaultGroupId(1);
234 Group group1 = createSouthboundGroupEntry(gId1,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800235 Arrays.asList(ports1),
236 0);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800237 GroupId gId2 = new DefaultGroupId(2);
238 Group group2 = createSouthboundGroupEntry(gId2,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800239 Arrays.asList(ports2),
240 0);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800241 List<Group> groupEntries = Arrays.asList(group1, group2);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800242 providerService.pushGroupMetrics(DID, groupEntries);
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700243 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800244 Group createdGroup = groupService.getGroup(DID, key);
245 List<GroupOperation> expectedGroupOps = Arrays.asList(
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800246 GroupOperation.createDeleteGroupOperation(gId1,
247 Group.Type.SELECT),
248 GroupOperation.createDeleteGroupOperation(gId2,
249 Group.Type.SELECT),
250 GroupOperation.createAddGroupOperation(createdGroup.id(),
251 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800252 createdGroup.buckets()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800253 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800254 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800255
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800256 // Test AUDIT with confirmed groups
257 private void testAuditWithConfirmedGroups() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700258 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800259 Group createdGroup = groupService.getGroup(DID, key);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800260 createdGroup = new DefaultGroup(createdGroup.id(),
261 DID,
262 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800263 createdGroup.buckets());
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700264 List<Group> groupEntries = Collections.singletonList(createdGroup);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800265 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700266 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADDED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800267 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800268
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800269 // Test group add bucket operations
270 private void testAddBuckets() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700271 GroupKey addKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800272
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700273 GroupKey prevKey = new DefaultGroupKey("group1BeforeAudit".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800274 Group createdGroup = groupService.getGroup(DID, prevKey);
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700275 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800276 buckets.addAll(createdGroup.buckets().buckets());
277
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800278 PortNumber[] addPorts = {PortNumber.portNumber(51),
279 PortNumber.portNumber(52)};
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700280 List<PortNumber> outPorts;
Sho SHIMIZU7a4087b2015-09-10 09:23:16 -0700281 outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800282 outPorts.addAll(Arrays.asList(addPorts));
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700283 List<GroupBucket> addBuckets;
Sho SHIMIZU7a4087b2015-09-10 09:23:16 -0700284 addBuckets = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800285 for (PortNumber portNumber: outPorts) {
286 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
287 tBuilder.setOutput(portNumber)
288 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
289 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
290 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100291 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800292 addBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
293 tBuilder.build()));
294 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
295 tBuilder.build()));
296 }
297 GroupBuckets groupAddBuckets = new GroupBuckets(addBuckets);
298 groupService.addBucketsToGroup(DID,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800299 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800300 groupAddBuckets,
301 addKey,
302 appId);
303 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700304 List<GroupOperation> expectedGroupOps = Collections.singletonList(
305 GroupOperation.createModifyGroupOperation(createdGroup.id(),
306 Group.Type.SELECT,
307 updatedBuckets));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800308 internalProvider.validate(DID, expectedGroupOps);
309 Group existingGroup = groupService.getGroup(DID, addKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700310 List<Group> groupEntries = Collections.singletonList(existingGroup);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800311 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700312 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800313 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800314
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800315 // Test group remove bucket operations
316 private void testRemoveBuckets() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700317 GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800318
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700319 GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800320 Group createdGroup = groupService.getGroup(DID, prevKey);
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700321 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800322 buckets.addAll(createdGroup.buckets().buckets());
323
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800324 PortNumber[] removePorts = {PortNumber.portNumber(31),
325 PortNumber.portNumber(32)};
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700326 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800327 outPorts.addAll(Arrays.asList(removePorts));
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700328 List<GroupBucket> removeBuckets = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800329 for (PortNumber portNumber: outPorts) {
330 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
331 tBuilder.setOutput(portNumber)
332 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
333 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
334 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100335 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800336 removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
337 tBuilder.build()));
338 buckets.remove(DefaultGroupBucket.createSelectGroupBucket(
339 tBuilder.build()));
340 }
341 GroupBuckets groupRemoveBuckets = new GroupBuckets(removeBuckets);
342 groupService.removeBucketsFromGroup(DID,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800343 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800344 groupRemoveBuckets,
345 removeKey,
346 appId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800347 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700348 List<GroupOperation> expectedGroupOps = Collections.singletonList(
349 GroupOperation.createModifyGroupOperation(createdGroup.id(),
350 Group.Type.SELECT,
351 updatedBuckets));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800352 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800353 Group existingGroup = groupService.getGroup(DID, removeKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700354 List<Group> groupEntries = Collections.singletonList(existingGroup);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800355 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700356 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800357 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800358
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800359 // Test group remove operations
360 private void testRemoveGroup() {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700361 GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800362 Group existingGroup = groupService.getGroup(DID, currKey);
363 groupService.removeGroup(DID, currKey, appId);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700364 List<GroupOperation> expectedGroupOps = Collections.singletonList(
365 GroupOperation.createDeleteGroupOperation(existingGroup.id(),
366 Group.Type.SELECT));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800367 internalProvider.validate(DID, expectedGroupOps);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800368 List<Group> groupEntries = Collections.emptyList();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800369 providerService.pushGroupMetrics(DID, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700370 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVED));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800371 }
372
sangho7ff01812015-02-09 16:21:53 -0800373 /**
374 * Test GroupOperationFailure function in Group Manager.
375 * a)GroupAddFailure
376 * b)GroupUpdateFailure
377 * c)GroupRemoteFailure
378 */
379 @Test
380 public void testGroupOperationFailure() {
381 PortNumber[] ports1 = {PortNumber.portNumber(31),
382 PortNumber.portNumber(32)};
383 PortNumber[] ports2 = {PortNumber.portNumber(41),
384 PortNumber.portNumber(42)};
385 // Test Group creation before AUDIT process
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700386 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700387 List<GroupBucket> buckets = new ArrayList<>();
388 List<PortNumber> outPorts = new ArrayList<>();
sangho7ff01812015-02-09 16:21:53 -0800389 outPorts.addAll(Arrays.asList(ports1));
390 outPorts.addAll(Arrays.asList(ports2));
391 for (PortNumber portNumber: outPorts) {
392 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
393 tBuilder.setOutput(portNumber)
394 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
395 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
396 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100397 .setMpls(MplsLabel.mplsLabel(106));
sangho7ff01812015-02-09 16:21:53 -0800398 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
399 tBuilder.build()));
400 }
401 GroupBuckets groupBuckets = new GroupBuckets(buckets);
402 GroupDescription newGroupDesc = new DefaultGroupDescription(DID,
403 Group.Type.SELECT,
404 groupBuckets,
405 key,
Saurav Das100e3b82015-04-30 11:12:10 -0700406 null,
sangho7ff01812015-02-09 16:21:53 -0800407 appId);
408 groupService.addGroup(newGroupDesc);
409
410 // Test initial group audit process
411 GroupId gId1 = new DefaultGroupId(1);
412 Group group1 = createSouthboundGroupEntry(gId1,
413 Arrays.asList(ports1),
414 0);
415 GroupId gId2 = new DefaultGroupId(2);
416 // Non zero reference count will make the group manager to queue
417 // the extraneous groups until reference count is zero.
418 Group group2 = createSouthboundGroupEntry(gId2,
419 Arrays.asList(ports2),
420 2);
421 List<Group> groupEntries = Arrays.asList(group1, group2);
422 providerService.pushGroupMetrics(DID, groupEntries);
423 Group createdGroup = groupService.getGroup(DID, key);
424
425 // Group Add failure test
426 GroupOperation groupAddOp = GroupOperation.
427 createAddGroupOperation(createdGroup.id(),
428 createdGroup.type(),
429 createdGroup.buckets());
430 providerService.groupOperationFailed(DID, groupAddOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700431 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADD_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800432
433 // Group Mod failure test
434 groupService.addGroup(newGroupDesc);
435 createdGroup = groupService.getGroup(DID, key);
436 assertNotNull(createdGroup);
437
438 GroupOperation groupModOp = GroupOperation.
439 createModifyGroupOperation(createdGroup.id(),
440 createdGroup.type(),
441 createdGroup.buckets());
442 providerService.groupOperationFailed(DID, groupModOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700443 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800444
445 // Group Delete failure test
446 groupService.addGroup(newGroupDesc);
447 createdGroup = groupService.getGroup(DID, key);
448 assertNotNull(createdGroup);
449
450 GroupOperation groupDelOp = GroupOperation.
451 createDeleteGroupOperation(createdGroup.id(),
452 createdGroup.type());
453 providerService.groupOperationFailed(DID, groupDelOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700454 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800455
456 }
457
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800458 private Group createSouthboundGroupEntry(GroupId gId,
459 List<PortNumber> ports,
460 long referenceCount) {
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700461 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800462 outPorts.addAll(ports);
463
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700464 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800465 for (PortNumber portNumber: outPorts) {
466 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
467 tBuilder.setOutput(portNumber)
468 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
469 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
470 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100471 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800472 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
473 tBuilder.build()));
474 }
475 GroupBuckets groupBuckets = new GroupBuckets(buckets);
476 StoredGroupEntry group = new DefaultGroup(
477 gId, DID, Group.Type.SELECT, groupBuckets);
478 group.setReferenceCount(referenceCount);
479 return group;
480 }
481
482 private static class TestGroupListener implements GroupListener {
483 final List<GroupEvent> events = new ArrayList<>();
484
485 @Override
486 public void event(GroupEvent event) {
487 events.add(event);
488 }
489
490 public void validateEvent(List<GroupEvent.Type> expectedEvents) {
491 int i = 0;
492 System.err.println("events :" + events);
493 for (GroupEvent e : events) {
494 assertEquals("unexpected event", expectedEvents.get(i), e.type());
495 i++;
496 }
497 assertEquals("mispredicted number of events",
498 expectedEvents.size(), events.size());
499 events.clear();
500 }
501 }
502
503 private class TestGroupProvider
504 extends AbstractProvider implements GroupProvider {
505 DeviceId lastDeviceId;
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700506 List<GroupOperation> groupOperations = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800507
508 protected TestGroupProvider(ProviderId id) {
509 super(id);
510 }
511
512 @Override
513 public void performGroupOperation(DeviceId deviceId,
514 GroupOperations groupOps) {
515 lastDeviceId = deviceId;
516 groupOperations.addAll(groupOps.operations());
517 }
518
519 public void validate(DeviceId expectedDeviceId,
520 List<GroupOperation> expectedGroupOps) {
521 if (expectedGroupOps == null) {
522 assertTrue("events generated", groupOperations.isEmpty());
523 return;
524 }
525
526 assertEquals(lastDeviceId, expectedDeviceId);
527 assertTrue((this.groupOperations.containsAll(expectedGroupOps) &&
528 expectedGroupOps.containsAll(groupOperations)));
529
530 groupOperations.clear();
531 lastDeviceId = null;
532 }
533
534 }
535
536}
537
538