Andrea Campanella
Committed by Gerrit Code Review

ONOS-3759 Group default provider

Change-Id: I318c8036a1836d13f57187bfd28464c740e09f08
1 +/*
2 + * Copyright 2016 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 + */
16 +
17 +package org.onosproject.net.group;
18 +
19 +import org.onosproject.net.DeviceId;
20 +import org.onosproject.net.driver.HandlerBehaviour;
21 +
22 +/**
23 + * Group programmable device behaviour.
24 + */
25 +public interface GroupProgrammable extends HandlerBehaviour {
26 +
27 + /**
28 + * Performs the Group operations for the specified device.
29 + *
30 + * @param deviceId ID of the device
31 + * @param groupOps operations to be performed
32 + */
33 + void performGroupOperation(DeviceId deviceId, GroupOperations groupOps);
34 +}
1 +/*
2 + * Copyright 2016 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 + */
16 +
17 +package org.onosproject.net.group.impl;
18 +
19 +import org.onosproject.net.DeviceId;
20 +import org.onosproject.net.device.DeviceService;
21 +import org.onosproject.net.group.GroupOperations;
22 +import org.onosproject.net.group.GroupProgrammable;
23 +import org.onosproject.net.group.GroupProvider;
24 +import org.onosproject.net.provider.AbstractProvider;
25 +import org.onosproject.net.provider.ProviderId;
26 +import org.slf4j.Logger;
27 +import org.slf4j.LoggerFactory;
28 +
29 +/**
30 + * Driver-based Group rule provider.
31 + */
32 +public class GroupDriverProvider extends AbstractProvider implements GroupProvider {
33 +
34 + private final Logger log = LoggerFactory.getLogger(getClass());
35 +
36 + // To be extracted for reuse as we deal with other.
37 + private static final String SCHEME = "default";
38 + private static final String PROVIDER_NAME = "org.onosproject.provider";
39 + protected DeviceService deviceService;
40 +
41 + public GroupDriverProvider() {
42 + super(new ProviderId(SCHEME, PROVIDER_NAME));
43 + }
44 +
45 + /**
46 + * Initializes the provider with the necessary device service.
47 + *
48 + * @param deviceService device service
49 + */
50 + void init(DeviceService deviceService) {
51 + this.deviceService = deviceService;
52 + }
53 +
54 + @Override
55 + public void performGroupOperation(DeviceId deviceId, GroupOperations groupOps) {
56 + GroupProgrammable programmable = getGroupProgrammable(deviceId);
57 + if (programmable != null) {
58 + programmable.performGroupOperation(deviceId, groupOps);
59 + }
60 + }
61 +
62 + private GroupProgrammable getGroupProgrammable(DeviceId deviceId) {
63 + GroupProgrammable programmable = deviceService.getDevice(deviceId).as(GroupProgrammable.class);
64 + if (programmable == null) {
65 + log.warn("Device {} is not group programmable");
66 + }
67 + return programmable;
68 + }
69 +}
...@@ -87,6 +87,7 @@ public class GroupManager ...@@ -87,6 +87,7 @@ public class GroupManager
87 @Property(name = "purgeOnDisconnection", boolValue = false, 87 @Property(name = "purgeOnDisconnection", boolValue = false,
88 label = "Purge entries associated with a device when the device goes offline") 88 label = "Purge entries associated with a device when the device goes offline")
89 private boolean purgeOnDisconnection = false; 89 private boolean purgeOnDisconnection = false;
90 + private final GroupDriverProvider defaultProvider = new GroupDriverProvider();
90 91
91 @Activate 92 @Activate
92 public void activate(ComponentContext context) { 93 public void activate(ComponentContext context) {
...@@ -111,6 +112,12 @@ public class GroupManager ...@@ -111,6 +112,12 @@ public class GroupManager
111 if (context != null) { 112 if (context != null) {
112 readComponentConfiguration(context); 113 readComponentConfiguration(context);
113 } 114 }
115 + defaultProvider.init(deviceService);
116 + }
117 +
118 + @Override
119 + protected GroupProvider defaultProvider() {
120 + return defaultProvider;
114 } 121 }
115 122
116 /** 123 /**
......
...@@ -15,32 +15,30 @@ ...@@ -15,32 +15,30 @@
15 */ 15 */
16 package org.onosproject.net.group.impl; 16 package org.onosproject.net.group.impl;
17 17
18 -import static org.junit.Assert.assertEquals; 18 +import com.google.common.collect.ImmutableList;
19 -import static org.junit.Assert.assertFalse; 19 +import com.google.common.collect.ImmutableMap;
20 -import static org.junit.Assert.assertNotEquals; 20 +import com.google.common.collect.Iterables;
21 -import static org.junit.Assert.assertNotNull;
22 -import static org.junit.Assert.assertTrue;
23 -import static org.onosproject.net.NetTestTools.injectEventDispatcher;
24 -
25 -import java.util.ArrayList;
26 -import java.util.Arrays;
27 -import java.util.Collections;
28 -import java.util.List;
29 -
30 import org.junit.After; 21 import org.junit.After;
31 import org.junit.Before; 22 import org.junit.Before;
32 import org.junit.Test; 23 import org.junit.Test;
33 import org.onlab.packet.MacAddress; 24 import org.onlab.packet.MacAddress;
34 import org.onlab.packet.MplsLabel; 25 import org.onlab.packet.MplsLabel;
35 import org.onosproject.cfg.ComponentConfigAdapter; 26 import org.onosproject.cfg.ComponentConfigAdapter;
27 +import org.onosproject.common.event.impl.TestEventDispatcher;
36 import org.onosproject.core.ApplicationId; 28 import org.onosproject.core.ApplicationId;
37 import org.onosproject.core.DefaultApplicationId; 29 import org.onosproject.core.DefaultApplicationId;
38 import org.onosproject.core.DefaultGroupId; 30 import org.onosproject.core.DefaultGroupId;
39 import org.onosproject.core.GroupId; 31 import org.onosproject.core.GroupId;
40 -import org.onosproject.common.event.impl.TestEventDispatcher; 32 +import org.onosproject.net.AnnotationKeys;
33 +import org.onosproject.net.DefaultAnnotations;
34 +import org.onosproject.net.DefaultDevice;
35 +import org.onosproject.net.Device;
41 import org.onosproject.net.DeviceId; 36 import org.onosproject.net.DeviceId;
42 import org.onosproject.net.PortNumber; 37 import org.onosproject.net.PortNumber;
43 -import org.onosproject.net.device.impl.DeviceManager; 38 +import org.onosproject.net.device.DeviceServiceAdapter;
39 +import org.onosproject.net.driver.AbstractHandlerBehaviour;
40 +import org.onosproject.net.driver.DefaultDriver;
41 +import org.onosproject.net.driver.impl.DriverManager;
44 import org.onosproject.net.flow.DefaultTrafficTreatment; 42 import org.onosproject.net.flow.DefaultTrafficTreatment;
45 import org.onosproject.net.flow.TrafficTreatment; 43 import org.onosproject.net.flow.TrafficTreatment;
46 import org.onosproject.net.group.DefaultGroup; 44 import org.onosproject.net.group.DefaultGroup;
...@@ -56,6 +54,7 @@ import org.onosproject.net.group.GroupKey; ...@@ -56,6 +54,7 @@ import org.onosproject.net.group.GroupKey;
56 import org.onosproject.net.group.GroupListener; 54 import org.onosproject.net.group.GroupListener;
57 import org.onosproject.net.group.GroupOperation; 55 import org.onosproject.net.group.GroupOperation;
58 import org.onosproject.net.group.GroupOperations; 56 import org.onosproject.net.group.GroupOperations;
57 +import org.onosproject.net.group.GroupProgrammable;
59 import org.onosproject.net.group.GroupProvider; 58 import org.onosproject.net.group.GroupProvider;
60 import org.onosproject.net.group.GroupProviderRegistry; 59 import org.onosproject.net.group.GroupProviderRegistry;
61 import org.onosproject.net.group.GroupProviderService; 60 import org.onosproject.net.group.GroupProviderService;
...@@ -65,7 +64,13 @@ import org.onosproject.net.provider.AbstractProvider; ...@@ -65,7 +64,13 @@ import org.onosproject.net.provider.AbstractProvider;
65 import org.onosproject.net.provider.ProviderId; 64 import org.onosproject.net.provider.ProviderId;
66 import org.onosproject.store.trivial.SimpleGroupStore; 65 import org.onosproject.store.trivial.SimpleGroupStore;
67 66
68 -import com.google.common.collect.Iterables; 67 +import java.util.ArrayList;
68 +import java.util.Arrays;
69 +import java.util.Collections;
70 +import java.util.List;
71 +
72 +import static org.junit.Assert.*;
73 +import static org.onosproject.net.NetTestTools.injectEventDispatcher;
69 74
70 /** 75 /**
71 * Test codifying the group service & group provider service contracts. 76 * Test codifying the group service & group provider service contracts.
...@@ -74,6 +79,14 @@ public class GroupManagerTest { ...@@ -74,6 +79,14 @@ public class GroupManagerTest {
74 79
75 private static final ProviderId PID = new ProviderId("of", "groupfoo"); 80 private static final ProviderId PID = new ProviderId("of", "groupfoo");
76 private static final DeviceId DID = DeviceId.deviceId("of:001"); 81 private static final DeviceId DID = DeviceId.deviceId("of:001");
82 + private static final ProviderId FOO_PID = new ProviderId("foo", "foo");
83 + private static final DeviceId FOO_DID = DeviceId.deviceId("foo:002");
84 +
85 + private static final DefaultAnnotations ANNOTATIONS =
86 + DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, "foo").build();
87 +
88 + private static final Device FOO_DEV =
89 + new DefaultDevice(FOO_PID, FOO_DID, Device.Type.SWITCH, "", "", "", "", null, ANNOTATIONS);
77 90
78 private GroupManager mgr; 91 private GroupManager mgr;
79 private GroupService groupService; 92 private GroupService groupService;
...@@ -84,12 +97,14 @@ public class GroupManagerTest { ...@@ -84,12 +97,14 @@ public class GroupManagerTest {
84 private GroupProvider provider; 97 private GroupProvider provider;
85 private GroupProviderService providerService; 98 private GroupProviderService providerService;
86 private ApplicationId appId; 99 private ApplicationId appId;
100 + private TestDriverManager driverService;
87 101
88 @Before 102 @Before
89 public void setUp() { 103 public void setUp() {
90 mgr = new GroupManager(); 104 mgr = new GroupManager();
91 groupService = mgr; 105 groupService = mgr;
92 - mgr.deviceService = new DeviceManager(); 106 + //mgr.deviceService = new DeviceManager();
107 + mgr.deviceService = new TestDeviceService();
93 mgr.cfgService = new ComponentConfigAdapter(); 108 mgr.cfgService = new ComponentConfigAdapter();
94 mgr.store = new SimpleGroupStore(); 109 mgr.store = new SimpleGroupStore();
95 injectEventDispatcher(mgr, new TestEventDispatcher()); 110 injectEventDispatcher(mgr, new TestEventDispatcher());
...@@ -98,6 +113,12 @@ public class GroupManagerTest { ...@@ -98,6 +113,12 @@ public class GroupManagerTest {
98 mgr.activate(null); 113 mgr.activate(null);
99 mgr.addListener(listener); 114 mgr.addListener(listener);
100 115
116 + driverService = new TestDriverManager();
117 + driverService.addDriver(new DefaultDriver("foo", ImmutableList.of(), "", "", "",
118 + ImmutableMap.of(GroupProgrammable.class,
119 + TestGroupProgrammable.class),
120 + ImmutableMap.of()));
121 +
101 internalProvider = new TestGroupProvider(PID); 122 internalProvider = new TestGroupProvider(PID);
102 provider = internalProvider; 123 provider = internalProvider;
103 providerService = providerRegistry.register(provider); 124 providerService = providerRegistry.register(provider);
...@@ -117,55 +138,170 @@ public class GroupManagerTest { ...@@ -117,55 +138,170 @@ public class GroupManagerTest {
117 } 138 }
118 139
119 /** 140 /**
120 - * Tests group service north bound and south bound interfaces. 141 + * Tests group creation before the device group AUDIT completes.
121 - * The following operations are tested: 142 + */
122 - * a)Tests group creation before the device group AUDIT completes 143 + @Test
123 - * b)Tests initial device group AUDIT process 144 + public void testGroupServiceBasics() {
124 - * c)Tests deletion process of any extraneous groups 145 + // Test Group creation before AUDIT process
125 - * d)Tests execution of any pending group creation requests 146 + testGroupCreationBeforeAudit(DID);
126 - * after the device group AUDIT completes 147 + }
127 - * e)Tests re-apply process of any missing groups 148 +
128 - * f)Tests event notifications after receiving confirmation for 149 + /**
129 - * any operations from data plane 150 + * Tests initial device group AUDIT process.
130 - * g)Tests group bucket modifications (additions and deletions) 151 + */
131 - * h)Tests group deletion 152 + @Test
153 + public void testGroupServiceInitialAudit() {
154 + // Test Group creation before AUDIT process
155 + testGroupCreationBeforeAudit(DID);
156 + // Test initial group audit process
157 + testInitialAuditWithPendingGroupRequests(DID);
158 + }
159 +
160 + /**
161 + * Tests deletion process of any extraneous groups.
162 + */
163 + @Test
164 + public void testGroupServiceAuditExtraneous() {
165 + // Test Group creation before AUDIT process
166 + testGroupCreationBeforeAudit(DID);
167 +
168 + // Test audit with extraneous and missing groups
169 + testAuditWithExtraneousMissingGroups(DID);
170 + }
171 +
172 + /**
173 + * Tests re-apply process of any missing groups tests execution of
174 + * any pending group creation request after the device group AUDIT completes
175 + * and tests event notifications after receiving confirmation for any
176 + * operations from data plane.
177 + */
178 + @Test
179 + public void testGroupServiceAuditConfirmed() {
180 + // Test Group creation before AUDIT process
181 + testGroupCreationBeforeAudit(DID);
182 +
183 + // Test audit with extraneous and missing groups
184 + testAuditWithExtraneousMissingGroups(DID);
185 +
186 + // Test audit with confirmed groups
187 + testAuditWithConfirmedGroups(DID);
188 + }
189 +
190 + /**
191 + * Tests group bucket modifications (additions and deletions) and
192 + * Tests group deletion.
193 + */
194 + @Test
195 + public void testGroupServiceBuckets() {
196 + // Test Group creation before AUDIT process
197 + testGroupCreationBeforeAudit(DID);
198 + programmableTestCleanUp();
199 +
200 + testAuditWithExtraneousMissingGroups(DID);
201 + // Test group add bucket operations
202 + testAddBuckets(DID);
203 +
204 + // Test group remove bucket operations
205 + testRemoveBuckets(DID);
206 +
207 + // Test group remove operations
208 + testRemoveGroup(DID);
209 + }
210 +
211 + /**
212 + * Tests group creation before the device group AUDIT completes with fallback
213 + * provider.
132 */ 214 */
133 @Test 215 @Test
134 - public void testGroupService() { 216 + public void testGroupServiceFallbackBasics() {
135 // Test Group creation before AUDIT process 217 // Test Group creation before AUDIT process
136 - testGroupCreationBeforeAudit(); 218 + testGroupCreationBeforeAudit(FOO_DID);
219 + programmableTestCleanUp();
220 +
221 + }
137 222
223 + /**
224 + * Tests initial device group AUDIT process with fallback provider.
225 + */
226 + @Test
227 + public void testGroupServiceFallbackInitialAudit() {
228 + // Test Group creation before AUDIT process
229 + testGroupCreationBeforeAudit(FOO_DID);
230 + programmableTestCleanUp();
138 // Test initial group audit process 231 // Test initial group audit process
139 - testInitialAuditWithPendingGroupRequests(); 232 + testInitialAuditWithPendingGroupRequests(FOO_DID);
233 + }
234 +
235 + /**
236 + * Tests deletion process of any extraneous groups with fallback provider.
237 + */
238 + @Test
239 + public void testGroupServiceFallbackAuditExtraneous() {
240 + // Test Group creation before AUDIT process
241 + testGroupCreationBeforeAudit(FOO_DID);
242 + programmableTestCleanUp();
243 +
244 + // Test audit with extraneous and missing groups
245 + testAuditWithExtraneousMissingGroups(FOO_DID);
246 + }
247 +
248 + /**
249 + * Tests re-apply process of any missing groups tests execution of
250 + * any pending group creation request after the device group AUDIT completes
251 + * and tests event notifications after receiving confirmation for any
252 + * operations from data plane with fallback provider.
253 + */
254 + @Test
255 + public void testGroupServiceFallbackAuditConfirmed() {
256 + // Test Group creation before AUDIT process
257 + testGroupCreationBeforeAudit(FOO_DID);
258 + programmableTestCleanUp();
140 259
141 // Test audit with extraneous and missing groups 260 // Test audit with extraneous and missing groups
142 - testAuditWithExtraneousMissingGroups(); 261 + testAuditWithExtraneousMissingGroups(FOO_DID);
143 262
144 // Test audit with confirmed groups 263 // Test audit with confirmed groups
145 - testAuditWithConfirmedGroups(); 264 + testAuditWithConfirmedGroups(FOO_DID);
265 + }
266 +
267 + /**
268 + * Tests group bucket modifications (additions and deletions) and
269 + * Tests group deletion with fallback provider.
270 + */
271 + @Test
272 + public void testGroupServiceFallbackBuckets() {
273 + // Test Group creation before AUDIT process
274 + testGroupCreationBeforeAudit(FOO_DID);
275 + programmableTestCleanUp();
146 276
277 + testAuditWithExtraneousMissingGroups(FOO_DID);
147 // Test group add bucket operations 278 // Test group add bucket operations
148 - testAddBuckets(); 279 + testAddBuckets(FOO_DID);
149 280
150 // Test group remove bucket operations 281 // Test group remove bucket operations
151 - testRemoveBuckets(); 282 + testRemoveBuckets(FOO_DID);
152 283
153 // Test group remove operations 284 // Test group remove operations
154 - testRemoveGroup(); 285 + testRemoveGroup(FOO_DID);
286 + }
287 +
288 + private void programmableTestCleanUp() {
289 + groupOperations.clear();
290 + lastDeviceIdProgrammable = null;
155 } 291 }
156 292
157 // Test Group creation before AUDIT process 293 // Test Group creation before AUDIT process
158 - private void testGroupCreationBeforeAudit() { 294 + private void testGroupCreationBeforeAudit(DeviceId deviceId) {
159 PortNumber[] ports1 = {PortNumber.portNumber(31), 295 PortNumber[] ports1 = {PortNumber.portNumber(31),
160 - PortNumber.portNumber(32)}; 296 + PortNumber.portNumber(32)};
161 PortNumber[] ports2 = {PortNumber.portNumber(41), 297 PortNumber[] ports2 = {PortNumber.portNumber(41),
162 - PortNumber.portNumber(42)}; 298 + PortNumber.portNumber(42)};
163 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes()); 299 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
164 List<GroupBucket> buckets = new ArrayList<>(); 300 List<GroupBucket> buckets = new ArrayList<>();
165 List<PortNumber> outPorts = new ArrayList<>(); 301 List<PortNumber> outPorts = new ArrayList<>();
166 outPorts.addAll(Arrays.asList(ports1)); 302 outPorts.addAll(Arrays.asList(ports1));
167 outPorts.addAll(Arrays.asList(ports2)); 303 outPorts.addAll(Arrays.asList(ports2));
168 - for (PortNumber portNumber: outPorts) { 304 + for (PortNumber portNumber : outPorts) {
169 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); 305 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
170 tBuilder.setOutput(portNumber) 306 tBuilder.setOutput(portNumber)
171 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 307 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
...@@ -173,75 +309,78 @@ public class GroupManagerTest { ...@@ -173,75 +309,78 @@ public class GroupManagerTest {
173 .pushMpls() 309 .pushMpls()
174 .setMpls(MplsLabel.mplsLabel(106)); 310 .setMpls(MplsLabel.mplsLabel(106));
175 buckets.add(DefaultGroupBucket.createSelectGroupBucket( 311 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
176 - tBuilder.build())); 312 + tBuilder.build()));
177 } 313 }
178 GroupBuckets groupBuckets = new GroupBuckets(buckets); 314 GroupBuckets groupBuckets = new GroupBuckets(buckets);
179 - GroupDescription newGroupDesc = new DefaultGroupDescription(DID, 315 + GroupDescription newGroupDesc = new DefaultGroupDescription(deviceId,
180 Group.Type.SELECT, 316 Group.Type.SELECT,
181 groupBuckets, 317 groupBuckets,
182 key, 318 key,
183 null, 319 null,
184 appId); 320 appId);
185 groupService.addGroup(newGroupDesc); 321 groupService.addGroup(newGroupDesc);
186 - internalProvider.validate(DID, null); 322 + assertEquals(null, groupService.getGroup(deviceId, key));
187 - assertEquals(null, groupService.getGroup(DID, key)); 323 + assertEquals(0, Iterables.size(groupService.getGroups(deviceId, appId)));
188 - assertEquals(0, Iterables.size(groupService.getGroups(DID, appId)));
189 } 324 }
190 325
191 // Test initial AUDIT process with pending group requests 326 // Test initial AUDIT process with pending group requests
192 - private void testInitialAuditWithPendingGroupRequests() { 327 + private void testInitialAuditWithPendingGroupRequests(DeviceId deviceId) {
193 PortNumber[] ports1 = {PortNumber.portNumber(31), 328 PortNumber[] ports1 = {PortNumber.portNumber(31),
194 - PortNumber.portNumber(32)}; 329 + PortNumber.portNumber(32)};
195 PortNumber[] ports2 = {PortNumber.portNumber(41), 330 PortNumber[] ports2 = {PortNumber.portNumber(41),
196 - PortNumber.portNumber(42)}; 331 + PortNumber.portNumber(42)};
197 GroupId gId1 = new DefaultGroupId(1); 332 GroupId gId1 = new DefaultGroupId(1);
198 Group group1 = createSouthboundGroupEntry(gId1, 333 Group group1 = createSouthboundGroupEntry(gId1,
199 Arrays.asList(ports1), 334 Arrays.asList(ports1),
200 - 0); 335 + 0, deviceId);
201 GroupId gId2 = new DefaultGroupId(2); 336 GroupId gId2 = new DefaultGroupId(2);
202 // Non zero reference count will make the group manager to queue 337 // Non zero reference count will make the group manager to queue
203 // the extraneous groups until reference count is zero. 338 // the extraneous groups until reference count is zero.
204 Group group2 = createSouthboundGroupEntry(gId2, 339 Group group2 = createSouthboundGroupEntry(gId2,
205 Arrays.asList(ports2), 340 Arrays.asList(ports2),
206 - 2); 341 + 2, deviceId);
207 List<Group> groupEntries = Arrays.asList(group1, group2); 342 List<Group> groupEntries = Arrays.asList(group1, group2);
208 - providerService.pushGroupMetrics(DID, groupEntries); 343 + providerService.pushGroupMetrics(deviceId, groupEntries);
209 // First group metrics would trigger the device audit completion 344 // First group metrics would trigger the device audit completion
210 // post which all pending group requests are also executed. 345 // post which all pending group requests are also executed.
211 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes()); 346 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
212 - Group createdGroup = groupService.getGroup(DID, key); 347 + Group createdGroup = groupService.getGroup(deviceId, key);
213 int createdGroupId = createdGroup.id().id(); 348 int createdGroupId = createdGroup.id().id();
214 assertNotEquals(gId1.id(), createdGroupId); 349 assertNotEquals(gId1.id(), createdGroupId);
215 assertNotEquals(gId2.id(), createdGroupId); 350 assertNotEquals(gId2.id(), createdGroupId);
216 351
217 List<GroupOperation> expectedGroupOps = Arrays.asList( 352 List<GroupOperation> expectedGroupOps = Arrays.asList(
218 - GroupOperation.createDeleteGroupOperation(gId1, 353 + GroupOperation.createDeleteGroupOperation(gId1,
219 Group.Type.SELECT), 354 Group.Type.SELECT),
220 - GroupOperation.createAddGroupOperation( 355 + GroupOperation.createAddGroupOperation(
221 - createdGroup.id(), 356 + createdGroup.id(),
222 - Group.Type.SELECT, 357 + Group.Type.SELECT,
223 - createdGroup.buckets())); 358 + createdGroup.buckets()));
224 - internalProvider.validate(DID, expectedGroupOps); 359 + if (deviceId.equals(DID)) {
360 + internalProvider.validate(deviceId, expectedGroupOps);
361 + } else {
362 + this.validate(deviceId, expectedGroupOps);
363 + }
225 } 364 }
226 365
227 // Test AUDIT process with extraneous groups and missing groups 366 // Test AUDIT process with extraneous groups and missing groups
228 - private void testAuditWithExtraneousMissingGroups() { 367 + private void testAuditWithExtraneousMissingGroups(DeviceId deviceId) {
229 PortNumber[] ports1 = {PortNumber.portNumber(31), 368 PortNumber[] ports1 = {PortNumber.portNumber(31),
230 - PortNumber.portNumber(32)}; 369 + PortNumber.portNumber(32)};
231 PortNumber[] ports2 = {PortNumber.portNumber(41), 370 PortNumber[] ports2 = {PortNumber.portNumber(41),
232 - PortNumber.portNumber(42)}; 371 + PortNumber.portNumber(42)};
233 GroupId gId1 = new DefaultGroupId(1); 372 GroupId gId1 = new DefaultGroupId(1);
234 Group group1 = createSouthboundGroupEntry(gId1, 373 Group group1 = createSouthboundGroupEntry(gId1,
235 - Arrays.asList(ports1), 374 + Arrays.asList(ports1),
236 - 0); 375 + 0, deviceId);
237 GroupId gId2 = new DefaultGroupId(2); 376 GroupId gId2 = new DefaultGroupId(2);
238 Group group2 = createSouthboundGroupEntry(gId2, 377 Group group2 = createSouthboundGroupEntry(gId2,
239 - Arrays.asList(ports2), 378 + Arrays.asList(ports2),
240 - 0); 379 + 0, deviceId);
241 List<Group> groupEntries = Arrays.asList(group1, group2); 380 List<Group> groupEntries = Arrays.asList(group1, group2);
242 - providerService.pushGroupMetrics(DID, groupEntries); 381 + providerService.pushGroupMetrics(deviceId, groupEntries);
243 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes()); 382 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
244 - Group createdGroup = groupService.getGroup(DID, key); 383 + Group createdGroup = groupService.getGroup(deviceId, key);
245 List<GroupOperation> expectedGroupOps = Arrays.asList( 384 List<GroupOperation> expectedGroupOps = Arrays.asList(
246 GroupOperation.createDeleteGroupOperation(gId1, 385 GroupOperation.createDeleteGroupOperation(gId1,
247 Group.Type.SELECT), 386 Group.Type.SELECT),
...@@ -250,39 +389,43 @@ public class GroupManagerTest { ...@@ -250,39 +389,43 @@ public class GroupManagerTest {
250 GroupOperation.createAddGroupOperation(createdGroup.id(), 389 GroupOperation.createAddGroupOperation(createdGroup.id(),
251 Group.Type.SELECT, 390 Group.Type.SELECT,
252 createdGroup.buckets())); 391 createdGroup.buckets()));
253 - internalProvider.validate(DID, expectedGroupOps); 392 + if (deviceId.equals(DID)) {
393 + internalProvider.validate(deviceId, expectedGroupOps);
394 + } else {
395 + this.validate(deviceId, expectedGroupOps);
396 + }
254 } 397 }
255 398
256 // Test AUDIT with confirmed groups 399 // Test AUDIT with confirmed groups
257 - private void testAuditWithConfirmedGroups() { 400 + private void testAuditWithConfirmedGroups(DeviceId deviceId) {
258 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes()); 401 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
259 - Group createdGroup = groupService.getGroup(DID, key); 402 + Group createdGroup = groupService.getGroup(deviceId, key);
260 createdGroup = new DefaultGroup(createdGroup.id(), 403 createdGroup = new DefaultGroup(createdGroup.id(),
261 - DID, 404 + deviceId,
262 Group.Type.SELECT, 405 Group.Type.SELECT,
263 createdGroup.buckets()); 406 createdGroup.buckets());
264 List<Group> groupEntries = Collections.singletonList(createdGroup); 407 List<Group> groupEntries = Collections.singletonList(createdGroup);
265 - providerService.pushGroupMetrics(DID, groupEntries); 408 + providerService.pushGroupMetrics(deviceId, groupEntries);
266 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADDED)); 409 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADDED));
267 } 410 }
268 411
269 // Test group add bucket operations 412 // Test group add bucket operations
270 - private void testAddBuckets() { 413 + private void testAddBuckets(DeviceId deviceId) {
271 GroupKey addKey = new DefaultGroupKey("group1AddBuckets".getBytes()); 414 GroupKey addKey = new DefaultGroupKey("group1AddBuckets".getBytes());
272 415
273 GroupKey prevKey = new DefaultGroupKey("group1BeforeAudit".getBytes()); 416 GroupKey prevKey = new DefaultGroupKey("group1BeforeAudit".getBytes());
274 - Group createdGroup = groupService.getGroup(DID, prevKey); 417 + Group createdGroup = groupService.getGroup(deviceId, prevKey);
275 List<GroupBucket> buckets = new ArrayList<>(); 418 List<GroupBucket> buckets = new ArrayList<>();
276 buckets.addAll(createdGroup.buckets().buckets()); 419 buckets.addAll(createdGroup.buckets().buckets());
277 420
278 PortNumber[] addPorts = {PortNumber.portNumber(51), 421 PortNumber[] addPorts = {PortNumber.portNumber(51),
279 - PortNumber.portNumber(52)}; 422 + PortNumber.portNumber(52)};
280 List<PortNumber> outPorts; 423 List<PortNumber> outPorts;
281 outPorts = new ArrayList<>(); 424 outPorts = new ArrayList<>();
282 outPorts.addAll(Arrays.asList(addPorts)); 425 outPorts.addAll(Arrays.asList(addPorts));
283 List<GroupBucket> addBuckets; 426 List<GroupBucket> addBuckets;
284 addBuckets = new ArrayList<>(); 427 addBuckets = new ArrayList<>();
285 - for (PortNumber portNumber: outPorts) { 428 + for (PortNumber portNumber : outPorts) {
286 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); 429 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
287 tBuilder.setOutput(portNumber) 430 tBuilder.setOutput(portNumber)
288 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 431 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
...@@ -290,12 +433,12 @@ public class GroupManagerTest { ...@@ -290,12 +433,12 @@ public class GroupManagerTest {
290 .pushMpls() 433 .pushMpls()
291 .setMpls(MplsLabel.mplsLabel(106)); 434 .setMpls(MplsLabel.mplsLabel(106));
292 addBuckets.add(DefaultGroupBucket.createSelectGroupBucket( 435 addBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
293 - tBuilder.build())); 436 + tBuilder.build()));
294 buckets.add(DefaultGroupBucket.createSelectGroupBucket( 437 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
295 - tBuilder.build())); 438 + tBuilder.build()));
296 } 439 }
297 GroupBuckets groupAddBuckets = new GroupBuckets(addBuckets); 440 GroupBuckets groupAddBuckets = new GroupBuckets(addBuckets);
298 - groupService.addBucketsToGroup(DID, 441 + groupService.addBucketsToGroup(deviceId,
299 prevKey, 442 prevKey,
300 groupAddBuckets, 443 groupAddBuckets,
301 addKey, 444 addKey,
...@@ -303,30 +446,34 @@ public class GroupManagerTest { ...@@ -303,30 +446,34 @@ public class GroupManagerTest {
303 GroupBuckets updatedBuckets = new GroupBuckets(buckets); 446 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
304 List<GroupOperation> expectedGroupOps = Collections.singletonList( 447 List<GroupOperation> expectedGroupOps = Collections.singletonList(
305 GroupOperation.createModifyGroupOperation(createdGroup.id(), 448 GroupOperation.createModifyGroupOperation(createdGroup.id(),
306 - Group.Type.SELECT, 449 + Group.Type.SELECT,
307 - updatedBuckets)); 450 + updatedBuckets));
308 - internalProvider.validate(DID, expectedGroupOps); 451 + if (deviceId.equals(DID)) {
309 - Group existingGroup = groupService.getGroup(DID, addKey); 452 + internalProvider.validate(deviceId, expectedGroupOps);
453 + } else {
454 + this.validate(deviceId, expectedGroupOps);
455 + }
456 + Group existingGroup = groupService.getGroup(deviceId, addKey);
310 List<Group> groupEntries = Collections.singletonList(existingGroup); 457 List<Group> groupEntries = Collections.singletonList(existingGroup);
311 - providerService.pushGroupMetrics(DID, groupEntries); 458 + providerService.pushGroupMetrics(deviceId, groupEntries);
312 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED)); 459 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
313 } 460 }
314 461
315 // Test group remove bucket operations 462 // Test group remove bucket operations
316 - private void testRemoveBuckets() { 463 + private void testRemoveBuckets(DeviceId deviceId) {
317 GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes()); 464 GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
318 465
319 GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes()); 466 GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes());
320 - Group createdGroup = groupService.getGroup(DID, prevKey); 467 + Group createdGroup = groupService.getGroup(deviceId, prevKey);
321 List<GroupBucket> buckets = new ArrayList<>(); 468 List<GroupBucket> buckets = new ArrayList<>();
322 buckets.addAll(createdGroup.buckets().buckets()); 469 buckets.addAll(createdGroup.buckets().buckets());
323 470
324 PortNumber[] removePorts = {PortNumber.portNumber(31), 471 PortNumber[] removePorts = {PortNumber.portNumber(31),
325 - PortNumber.portNumber(32)}; 472 + PortNumber.portNumber(32)};
326 List<PortNumber> outPorts = new ArrayList<>(); 473 List<PortNumber> outPorts = new ArrayList<>();
327 outPorts.addAll(Arrays.asList(removePorts)); 474 outPorts.addAll(Arrays.asList(removePorts));
328 List<GroupBucket> removeBuckets = new ArrayList<>(); 475 List<GroupBucket> removeBuckets = new ArrayList<>();
329 - for (PortNumber portNumber: outPorts) { 476 + for (PortNumber portNumber : outPorts) {
330 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); 477 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
331 tBuilder.setOutput(portNumber) 478 tBuilder.setOutput(portNumber)
332 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 479 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
...@@ -334,12 +481,12 @@ public class GroupManagerTest { ...@@ -334,12 +481,12 @@ public class GroupManagerTest {
334 .pushMpls() 481 .pushMpls()
335 .setMpls(MplsLabel.mplsLabel(106)); 482 .setMpls(MplsLabel.mplsLabel(106));
336 removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket( 483 removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
337 - tBuilder.build())); 484 + tBuilder.build()));
338 buckets.remove(DefaultGroupBucket.createSelectGroupBucket( 485 buckets.remove(DefaultGroupBucket.createSelectGroupBucket(
339 - tBuilder.build())); 486 + tBuilder.build()));
340 } 487 }
341 GroupBuckets groupRemoveBuckets = new GroupBuckets(removeBuckets); 488 GroupBuckets groupRemoveBuckets = new GroupBuckets(removeBuckets);
342 - groupService.removeBucketsFromGroup(DID, 489 + groupService.removeBucketsFromGroup(deviceId,
343 prevKey, 490 prevKey,
344 groupRemoveBuckets, 491 groupRemoveBuckets,
345 removeKey, 492 removeKey,
...@@ -347,26 +494,34 @@ public class GroupManagerTest { ...@@ -347,26 +494,34 @@ public class GroupManagerTest {
347 GroupBuckets updatedBuckets = new GroupBuckets(buckets); 494 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
348 List<GroupOperation> expectedGroupOps = Collections.singletonList( 495 List<GroupOperation> expectedGroupOps = Collections.singletonList(
349 GroupOperation.createModifyGroupOperation(createdGroup.id(), 496 GroupOperation.createModifyGroupOperation(createdGroup.id(),
350 - Group.Type.SELECT, 497 + Group.Type.SELECT,
351 - updatedBuckets)); 498 + updatedBuckets));
352 - internalProvider.validate(DID, expectedGroupOps); 499 + if (deviceId.equals(DID)) {
353 - Group existingGroup = groupService.getGroup(DID, removeKey); 500 + internalProvider.validate(deviceId, expectedGroupOps);
501 + } else {
502 + this.validate(deviceId, expectedGroupOps);
503 + }
504 + Group existingGroup = groupService.getGroup(deviceId, removeKey);
354 List<Group> groupEntries = Collections.singletonList(existingGroup); 505 List<Group> groupEntries = Collections.singletonList(existingGroup);
355 - providerService.pushGroupMetrics(DID, groupEntries); 506 + providerService.pushGroupMetrics(deviceId, groupEntries);
356 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED)); 507 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
357 } 508 }
358 509
359 // Test group remove operations 510 // Test group remove operations
360 - private void testRemoveGroup() { 511 + private void testRemoveGroup(DeviceId deviceId) {
361 GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes()); 512 GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
362 - Group existingGroup = groupService.getGroup(DID, currKey); 513 + Group existingGroup = groupService.getGroup(deviceId, currKey);
363 - groupService.removeGroup(DID, currKey, appId); 514 + groupService.removeGroup(deviceId, currKey, appId);
364 List<GroupOperation> expectedGroupOps = Collections.singletonList( 515 List<GroupOperation> expectedGroupOps = Collections.singletonList(
365 GroupOperation.createDeleteGroupOperation(existingGroup.id(), 516 GroupOperation.createDeleteGroupOperation(existingGroup.id(),
366 - Group.Type.SELECT)); 517 + Group.Type.SELECT));
367 - internalProvider.validate(DID, expectedGroupOps); 518 + if (deviceId.equals(DID)) {
519 + internalProvider.validate(deviceId, expectedGroupOps);
520 + } else {
521 + this.validate(deviceId, expectedGroupOps);
522 + }
368 List<Group> groupEntries = Collections.emptyList(); 523 List<Group> groupEntries = Collections.emptyList();
369 - providerService.pushGroupMetrics(DID, groupEntries); 524 + providerService.pushGroupMetrics(deviceId, groupEntries);
370 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVED)); 525 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVED));
371 } 526 }
372 527
...@@ -378,6 +533,22 @@ public class GroupManagerTest { ...@@ -378,6 +533,22 @@ public class GroupManagerTest {
378 */ 533 */
379 @Test 534 @Test
380 public void testGroupOperationFailure() { 535 public void testGroupOperationFailure() {
536 + groupOperationFaliure(DID);
537 + }
538 +
539 + /**
540 + * Test GroupOperationFailure function in Group Manager
541 + * with fallback provider.
542 + * a)GroupAddFailure
543 + * b)GroupUpdateFailure
544 + * c)GroupRemoteFailure
545 + */
546 + @Test
547 + public void testGroupOperationFailureFallBack() {
548 + groupOperationFaliure(FOO_DID);
549 + }
550 +
551 + private void groupOperationFaliure(DeviceId deviceId) {
381 PortNumber[] ports1 = {PortNumber.portNumber(31), 552 PortNumber[] ports1 = {PortNumber.portNumber(31),
382 PortNumber.portNumber(32)}; 553 PortNumber.portNumber(32)};
383 PortNumber[] ports2 = {PortNumber.portNumber(41), 554 PortNumber[] ports2 = {PortNumber.portNumber(41),
...@@ -388,7 +559,7 @@ public class GroupManagerTest { ...@@ -388,7 +559,7 @@ public class GroupManagerTest {
388 List<PortNumber> outPorts = new ArrayList<>(); 559 List<PortNumber> outPorts = new ArrayList<>();
389 outPorts.addAll(Arrays.asList(ports1)); 560 outPorts.addAll(Arrays.asList(ports1));
390 outPorts.addAll(Arrays.asList(ports2)); 561 outPorts.addAll(Arrays.asList(ports2));
391 - for (PortNumber portNumber: outPorts) { 562 + for (PortNumber portNumber : outPorts) {
392 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); 563 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
393 tBuilder.setOutput(portNumber) 564 tBuilder.setOutput(portNumber)
394 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 565 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
...@@ -399,70 +570,69 @@ public class GroupManagerTest { ...@@ -399,70 +570,69 @@ public class GroupManagerTest {
399 tBuilder.build())); 570 tBuilder.build()));
400 } 571 }
401 GroupBuckets groupBuckets = new GroupBuckets(buckets); 572 GroupBuckets groupBuckets = new GroupBuckets(buckets);
402 - GroupDescription newGroupDesc = new DefaultGroupDescription(DID, 573 + GroupDescription newGroupDesc = new DefaultGroupDescription(deviceId,
403 - Group.Type.SELECT, 574 + Group.Type.SELECT,
404 - groupBuckets, 575 + groupBuckets,
405 - key, 576 + key,
406 - null, 577 + null,
407 - appId); 578 + appId);
408 groupService.addGroup(newGroupDesc); 579 groupService.addGroup(newGroupDesc);
409 580
410 // Test initial group audit process 581 // Test initial group audit process
411 GroupId gId1 = new DefaultGroupId(1); 582 GroupId gId1 = new DefaultGroupId(1);
412 Group group1 = createSouthboundGroupEntry(gId1, 583 Group group1 = createSouthboundGroupEntry(gId1,
413 - Arrays.asList(ports1), 584 + Arrays.asList(ports1),
414 - 0); 585 + 0, deviceId);
415 GroupId gId2 = new DefaultGroupId(2); 586 GroupId gId2 = new DefaultGroupId(2);
416 // Non zero reference count will make the group manager to queue 587 // Non zero reference count will make the group manager to queue
417 // the extraneous groups until reference count is zero. 588 // the extraneous groups until reference count is zero.
418 Group group2 = createSouthboundGroupEntry(gId2, 589 Group group2 = createSouthboundGroupEntry(gId2,
419 - Arrays.asList(ports2), 590 + Arrays.asList(ports2),
420 - 2); 591 + 2, deviceId);
421 List<Group> groupEntries = Arrays.asList(group1, group2); 592 List<Group> groupEntries = Arrays.asList(group1, group2);
422 - providerService.pushGroupMetrics(DID, groupEntries); 593 + providerService.pushGroupMetrics(deviceId, groupEntries);
423 - Group createdGroup = groupService.getGroup(DID, key); 594 + Group createdGroup = groupService.getGroup(deviceId, key);
424 595
425 // Group Add failure test 596 // Group Add failure test
426 GroupOperation groupAddOp = GroupOperation. 597 GroupOperation groupAddOp = GroupOperation.
427 createAddGroupOperation(createdGroup.id(), 598 createAddGroupOperation(createdGroup.id(),
428 - createdGroup.type(), 599 + createdGroup.type(),
429 - createdGroup.buckets()); 600 + createdGroup.buckets());
430 - providerService.groupOperationFailed(DID, groupAddOp); 601 + providerService.groupOperationFailed(deviceId, groupAddOp);
431 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADD_FAILED)); 602 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADD_FAILED));
432 603
433 // Group Mod failure test 604 // Group Mod failure test
434 groupService.addGroup(newGroupDesc); 605 groupService.addGroup(newGroupDesc);
435 - createdGroup = groupService.getGroup(DID, key); 606 + createdGroup = groupService.getGroup(deviceId, key);
436 assertNotNull(createdGroup); 607 assertNotNull(createdGroup);
437 608
438 GroupOperation groupModOp = GroupOperation. 609 GroupOperation groupModOp = GroupOperation.
439 createModifyGroupOperation(createdGroup.id(), 610 createModifyGroupOperation(createdGroup.id(),
440 - createdGroup.type(), 611 + createdGroup.type(),
441 - createdGroup.buckets()); 612 + createdGroup.buckets());
442 - providerService.groupOperationFailed(DID, groupModOp); 613 + providerService.groupOperationFailed(deviceId, groupModOp);
443 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATE_FAILED)); 614 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATE_FAILED));
444 615
445 // Group Delete failure test 616 // Group Delete failure test
446 groupService.addGroup(newGroupDesc); 617 groupService.addGroup(newGroupDesc);
447 - createdGroup = groupService.getGroup(DID, key); 618 + createdGroup = groupService.getGroup(deviceId, key);
448 assertNotNull(createdGroup); 619 assertNotNull(createdGroup);
449 620
450 GroupOperation groupDelOp = GroupOperation. 621 GroupOperation groupDelOp = GroupOperation.
451 createDeleteGroupOperation(createdGroup.id(), 622 createDeleteGroupOperation(createdGroup.id(),
452 - createdGroup.type()); 623 + createdGroup.type());
453 - providerService.groupOperationFailed(DID, groupDelOp); 624 + providerService.groupOperationFailed(deviceId, groupDelOp);
454 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVE_FAILED)); 625 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVE_FAILED));
455 -
456 } 626 }
457 627
458 private Group createSouthboundGroupEntry(GroupId gId, 628 private Group createSouthboundGroupEntry(GroupId gId,
459 List<PortNumber> ports, 629 List<PortNumber> ports,
460 - long referenceCount) { 630 + long referenceCount, DeviceId deviceId) {
461 List<PortNumber> outPorts = new ArrayList<>(); 631 List<PortNumber> outPorts = new ArrayList<>();
462 outPorts.addAll(ports); 632 outPorts.addAll(ports);
463 633
464 List<GroupBucket> buckets = new ArrayList<>(); 634 List<GroupBucket> buckets = new ArrayList<>();
465 - for (PortNumber portNumber: outPorts) { 635 + for (PortNumber portNumber : outPorts) {
466 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); 636 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
467 tBuilder.setOutput(portNumber) 637 tBuilder.setOutput(portNumber)
468 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 638 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
...@@ -470,11 +640,11 @@ public class GroupManagerTest { ...@@ -470,11 +640,11 @@ public class GroupManagerTest {
470 .pushMpls() 640 .pushMpls()
471 .setMpls(MplsLabel.mplsLabel(106)); 641 .setMpls(MplsLabel.mplsLabel(106));
472 buckets.add(DefaultGroupBucket.createSelectGroupBucket( 642 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
473 - tBuilder.build())); 643 + tBuilder.build()));
474 } 644 }
475 GroupBuckets groupBuckets = new GroupBuckets(buckets); 645 GroupBuckets groupBuckets = new GroupBuckets(buckets);
476 StoredGroupEntry group = new DefaultGroup( 646 StoredGroupEntry group = new DefaultGroup(
477 - gId, DID, Group.Type.SELECT, groupBuckets); 647 + gId, deviceId, Group.Type.SELECT, groupBuckets);
478 group.setReferenceCount(referenceCount); 648 group.setReferenceCount(referenceCount);
479 return group; 649 return group;
480 } 650 }
...@@ -501,7 +671,7 @@ public class GroupManagerTest { ...@@ -501,7 +671,7 @@ public class GroupManagerTest {
501 } 671 }
502 672
503 private class TestGroupProvider 673 private class TestGroupProvider
504 - extends AbstractProvider implements GroupProvider { 674 + extends AbstractProvider implements GroupProvider {
505 DeviceId lastDeviceId; 675 DeviceId lastDeviceId;
506 List<GroupOperation> groupOperations = new ArrayList<>(); 676 List<GroupOperation> groupOperations = new ArrayList<>();
507 677
...@@ -533,6 +703,60 @@ public class GroupManagerTest { ...@@ -533,6 +703,60 @@ public class GroupManagerTest {
533 703
534 } 704 }
535 705
706 + private static class TestDeviceService extends DeviceServiceAdapter {
707 + @Override
708 + public int getDeviceCount() {
709 + return 1;
710 + }
711 +
712 + @Override
713 + public Iterable<Device> getDevices() {
714 + return ImmutableList.of(FOO_DEV);
715 + }
716 +
717 + @Override
718 + public Iterable<Device> getAvailableDevices() {
719 + return getDevices();
720 + }
721 +
722 + @Override
723 + public Device getDevice(DeviceId deviceId) {
724 + return FOO_DEV;
725 + }
726 + }
727 +
728 + private class TestDriverManager extends DriverManager {
729 + TestDriverManager() {
730 + this.deviceService = mgr.deviceService;
731 + activate();
732 + }
733 + }
734 +
735 + private static DeviceId lastDeviceIdProgrammable;
736 + private static List<GroupOperation> groupOperations = new ArrayList<>();
737 +
738 + public static class TestGroupProgrammable extends AbstractHandlerBehaviour implements GroupProgrammable {
739 + @Override
740 + public void performGroupOperation(DeviceId deviceId, GroupOperations groupOps) {
741 + lastDeviceIdProgrammable = deviceId;
742 + groupOperations.addAll(groupOps.operations());
743 + }
744 + }
745 +
746 + public void validate(DeviceId expectedDeviceId,
747 + List<GroupOperation> expectedGroupOps) {
748 + if (expectedGroupOps == null) {
749 + assertTrue("events generated", groupOperations.isEmpty());
750 + return;
751 + }
752 +
753 + assertEquals(lastDeviceIdProgrammable, expectedDeviceId);
754 + assertTrue((this.groupOperations.containsAll(expectedGroupOps) &&
755 + expectedGroupOps.containsAll(groupOperations)));
756 +
757 + groupOperations.clear();
758 + lastDeviceIdProgrammable = null;
759 + }
536 } 760 }
537 761
538 762
......