blob: 065da4ddeecae0ded1a2e7134fb748bf88c82921 [file] [log] [blame]
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -08003 *
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
Andrea Campanella6ee73922016-02-03 18:00:00 -080018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.ImmutableMap;
20import com.google.common.collect.Iterables;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080021import org.junit.After;
22import org.junit.Before;
23import org.junit.Test;
24import org.onlab.packet.MacAddress;
Michele Santuari4b6019e2014-12-19 11:31:45 +010025import org.onlab.packet.MplsLabel;
Charles Chan0c7c43b2016-01-14 17:39:20 -080026import org.onosproject.cfg.ComponentConfigAdapter;
Andrea Campanella6ee73922016-02-03 18:00:00 -080027import org.onosproject.common.event.impl.TestEventDispatcher;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080028import org.onosproject.core.ApplicationId;
29import org.onosproject.core.DefaultApplicationId;
30import org.onosproject.core.DefaultGroupId;
31import org.onosproject.core.GroupId;
Andrea Campanella6ee73922016-02-03 18:00:00 -080032import org.onosproject.net.AnnotationKeys;
33import org.onosproject.net.DefaultAnnotations;
34import org.onosproject.net.DefaultDevice;
35import org.onosproject.net.Device;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080036import org.onosproject.net.DeviceId;
37import org.onosproject.net.PortNumber;
Andrea Campanella6ee73922016-02-03 18:00:00 -080038import org.onosproject.net.device.DeviceServiceAdapter;
39import org.onosproject.net.driver.AbstractHandlerBehaviour;
40import org.onosproject.net.driver.DefaultDriver;
41import org.onosproject.net.driver.impl.DriverManager;
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;
Andrea Campanella6ee73922016-02-03 18:00:00 -080057import org.onosproject.net.group.GroupProgrammable;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080058import org.onosproject.net.group.GroupProvider;
59import org.onosproject.net.group.GroupProviderRegistry;
60import org.onosproject.net.group.GroupProviderService;
61import org.onosproject.net.group.GroupService;
62import org.onosproject.net.group.StoredGroupEntry;
63import org.onosproject.net.provider.AbstractProvider;
64import org.onosproject.net.provider.ProviderId;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070065import org.onosproject.store.trivial.SimpleGroupStore;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080066
Andrea Campanella6ee73922016-02-03 18:00:00 -080067import java.util.ArrayList;
68import java.util.Arrays;
69import java.util.Collections;
70import java.util.List;
71
72import static org.junit.Assert.*;
73import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080074
75/**
76 * Test codifying the group service & group provider service contracts.
77 */
78public class GroupManagerTest {
79
80 private static final ProviderId PID = new ProviderId("of", "groupfoo");
81 private static final DeviceId DID = DeviceId.deviceId("of:001");
Andrea Campanella6ee73922016-02-03 18:00:00 -080082 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);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080090
91 private GroupManager mgr;
92 private GroupService groupService;
93 private GroupProviderRegistry providerRegistry;
94 private TestGroupListener internalListener = new TestGroupListener();
95 private GroupListener listener = internalListener;
96 private TestGroupProvider internalProvider;
97 private GroupProvider provider;
98 private GroupProviderService providerService;
99 private ApplicationId appId;
Andrea Campanella6ee73922016-02-03 18:00:00 -0800100 private TestDriverManager driverService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800101
102 @Before
103 public void setUp() {
104 mgr = new GroupManager();
105 groupService = mgr;
Andrea Campanella6ee73922016-02-03 18:00:00 -0800106 //mgr.deviceService = new DeviceManager();
107 mgr.deviceService = new TestDeviceService();
Charles Chan0c7c43b2016-01-14 17:39:20 -0800108 mgr.cfgService = new ComponentConfigAdapter();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800109 mgr.store = new SimpleGroupStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700110 injectEventDispatcher(mgr, new TestEventDispatcher());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800111 providerRegistry = mgr;
112
Charles Chan0c7c43b2016-01-14 17:39:20 -0800113 mgr.activate(null);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800114 mgr.addListener(listener);
115
Andrea Campanella6ee73922016-02-03 18:00:00 -0800116 driverService = new TestDriverManager();
117 driverService.addDriver(new DefaultDriver("foo", ImmutableList.of(), "", "", "",
118 ImmutableMap.of(GroupProgrammable.class,
119 TestGroupProgrammable.class),
120 ImmutableMap.of()));
121
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800122 internalProvider = new TestGroupProvider(PID);
123 provider = internalProvider;
124 providerService = providerRegistry.register(provider);
125 appId = new DefaultApplicationId(2, "org.groupmanager.test");
126 assertTrue("provider should be registered",
127 providerRegistry.getProviders().contains(provider.id()));
128 }
129
130 @After
131 public void tearDown() {
132 providerRegistry.unregister(provider);
133 assertFalse("provider should not be registered",
134 providerRegistry.getProviders().contains(provider.id()));
135 mgr.removeListener(listener);
136 mgr.deactivate();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700137 injectEventDispatcher(mgr, null);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800138 }
139
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800140 /**
Andrea Campanella6ee73922016-02-03 18:00:00 -0800141 * Tests group creation before the device group AUDIT completes.
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800142 */
143 @Test
Andrea Campanella6ee73922016-02-03 18:00:00 -0800144 public void testGroupServiceBasics() {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800145 // Test Group creation before AUDIT process
Andrea Campanella6ee73922016-02-03 18:00:00 -0800146 testGroupCreationBeforeAudit(DID);
147 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800148
Andrea Campanella6ee73922016-02-03 18:00:00 -0800149 /**
150 * Tests initial device group AUDIT process.
151 */
152 @Test
153 public void testGroupServiceInitialAudit() {
154 // Test Group creation before AUDIT process
155 testGroupCreationBeforeAudit(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800156 // Test initial group audit process
Andrea Campanella6ee73922016-02-03 18:00:00 -0800157 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);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800167
168 // Test audit with extraneous and missing groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800169 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);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800185
186 // Test audit with confirmed groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800187 testAuditWithConfirmedGroups(DID);
188 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800189
Andrea Campanella6ee73922016-02-03 18:00:00 -0800190 /**
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530191 * Tests group Purge Operation.
192 */
193 @Test
194 public void testPurgeGroups() {
195 //Test Group creation before AUDIT process
196 testGroupCreationBeforeAudit(DID);
197 programmableTestCleanUp();
198 testAuditWithExtraneousMissingGroups(DID);
199 // Test group add bucket operations
200 testAddBuckets(DID);
201 // Test group Purge operations
202 testPurgeGroupEntry(DID);
203 }
204
205 /**
Andrea Campanella6ee73922016-02-03 18:00:00 -0800206 * Tests group bucket modifications (additions and deletions) and
207 * Tests group deletion.
208 */
209 @Test
210 public void testGroupServiceBuckets() {
211 // Test Group creation before AUDIT process
212 testGroupCreationBeforeAudit(DID);
213 programmableTestCleanUp();
214
215 testAuditWithExtraneousMissingGroups(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800216 // Test group add bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800217 testAddBuckets(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800218
219 // Test group remove bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800220 testRemoveBuckets(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800221
222 // Test group remove operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800223 testRemoveGroup(DID);
224 }
225
226 /**
227 * Tests group creation before the device group AUDIT completes with fallback
228 * provider.
229 */
230 @Test
231 public void testGroupServiceFallbackBasics() {
232 // Test Group creation before AUDIT process
233 testGroupCreationBeforeAudit(FOO_DID);
234 programmableTestCleanUp();
235
236 }
237
238 /**
239 * Tests initial device group AUDIT process with fallback provider.
240 */
241 @Test
242 public void testGroupServiceFallbackInitialAudit() {
243 // Test Group creation before AUDIT process
244 testGroupCreationBeforeAudit(FOO_DID);
245 programmableTestCleanUp();
246 // Test initial group audit process
247 testInitialAuditWithPendingGroupRequests(FOO_DID);
248 }
249
250 /**
251 * Tests deletion process of any extraneous groups with fallback provider.
252 */
253 @Test
254 public void testGroupServiceFallbackAuditExtraneous() {
255 // Test Group creation before AUDIT process
256 testGroupCreationBeforeAudit(FOO_DID);
257 programmableTestCleanUp();
258
259 // Test audit with extraneous and missing groups
260 testAuditWithExtraneousMissingGroups(FOO_DID);
261 }
262
263 /**
264 * Tests re-apply process of any missing groups tests execution of
265 * any pending group creation request after the device group AUDIT completes
266 * and tests event notifications after receiving confirmation for any
267 * operations from data plane with fallback provider.
268 */
269 @Test
270 public void testGroupServiceFallbackAuditConfirmed() {
271 // Test Group creation before AUDIT process
272 testGroupCreationBeforeAudit(FOO_DID);
273 programmableTestCleanUp();
274
275 // Test audit with extraneous and missing groups
276 testAuditWithExtraneousMissingGroups(FOO_DID);
277
278 // Test audit with confirmed groups
279 testAuditWithConfirmedGroups(FOO_DID);
280 }
281
282 /**
283 * Tests group bucket modifications (additions and deletions) and
284 * Tests group deletion with fallback provider.
285 */
286 @Test
287 public void testGroupServiceFallbackBuckets() {
288 // Test Group creation before AUDIT process
289 testGroupCreationBeforeAudit(FOO_DID);
290 programmableTestCleanUp();
291
292 testAuditWithExtraneousMissingGroups(FOO_DID);
293 // Test group add bucket operations
294 testAddBuckets(FOO_DID);
295
296 // Test group remove bucket operations
297 testRemoveBuckets(FOO_DID);
298
299 // Test group remove operations
300 testRemoveGroup(FOO_DID);
301 }
302
303 private void programmableTestCleanUp() {
304 groupOperations.clear();
305 lastDeviceIdProgrammable = null;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800306 }
307
308 // Test Group creation before AUDIT process
Andrea Campanella6ee73922016-02-03 18:00:00 -0800309 private void testGroupCreationBeforeAudit(DeviceId deviceId) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800310 PortNumber[] ports1 = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800311 PortNumber.portNumber(32)};
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800312 PortNumber[] ports2 = {PortNumber.portNumber(41),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800313 PortNumber.portNumber(42)};
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700314 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700315 List<GroupBucket> buckets = new ArrayList<>();
316 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800317 outPorts.addAll(Arrays.asList(ports1));
318 outPorts.addAll(Arrays.asList(ports2));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800319 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800320 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
321 tBuilder.setOutput(portNumber)
322 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
323 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
324 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100325 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800326 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800327 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800328 }
329 GroupBuckets groupBuckets = new GroupBuckets(buckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800330 GroupDescription newGroupDesc = new DefaultGroupDescription(deviceId,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800331 Group.Type.SELECT,
332 groupBuckets,
333 key,
Saurav Das100e3b82015-04-30 11:12:10 -0700334 null,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800335 appId);
336 groupService.addGroup(newGroupDesc);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800337 assertEquals(null, groupService.getGroup(deviceId, key));
338 assertEquals(0, Iterables.size(groupService.getGroups(deviceId, appId)));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800339 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800340
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800341 // Test initial AUDIT process with pending group requests
Andrea Campanella6ee73922016-02-03 18:00:00 -0800342 private void testInitialAuditWithPendingGroupRequests(DeviceId deviceId) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800343 PortNumber[] ports1 = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800344 PortNumber.portNumber(32)};
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800345 PortNumber[] ports2 = {PortNumber.portNumber(41),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800346 PortNumber.portNumber(42)};
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800347 GroupId gId1 = new DefaultGroupId(1);
348 Group group1 = createSouthboundGroupEntry(gId1,
349 Arrays.asList(ports1),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800350 0, deviceId);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800351 GroupId gId2 = new DefaultGroupId(2);
352 // Non zero reference count will make the group manager to queue
353 // the extraneous groups until reference count is zero.
354 Group group2 = createSouthboundGroupEntry(gId2,
355 Arrays.asList(ports2),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800356 2, deviceId);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800357 List<Group> groupEntries = Arrays.asList(group1, group2);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800358 providerService.pushGroupMetrics(deviceId, groupEntries);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800359 // First group metrics would trigger the device audit completion
360 // post which all pending group requests are also executed.
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700361 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800362 Group createdGroup = groupService.getGroup(deviceId, key);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800363 int createdGroupId = createdGroup.id().id();
364 assertNotEquals(gId1.id(), createdGroupId);
365 assertNotEquals(gId2.id(), createdGroupId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800366
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800367 List<GroupOperation> expectedGroupOps = Arrays.asList(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800368 GroupOperation.createDeleteGroupOperation(gId1,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800369 Group.Type.SELECT),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800370 GroupOperation.createAddGroupOperation(
371 createdGroup.id(),
372 Group.Type.SELECT,
373 createdGroup.buckets()));
374 if (deviceId.equals(DID)) {
375 internalProvider.validate(deviceId, expectedGroupOps);
376 } else {
377 this.validate(deviceId, expectedGroupOps);
378 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800379 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800380
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800381 // Test AUDIT process with extraneous groups and missing groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800382 private void testAuditWithExtraneousMissingGroups(DeviceId deviceId) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800383 PortNumber[] ports1 = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800384 PortNumber.portNumber(32)};
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800385 PortNumber[] ports2 = {PortNumber.portNumber(41),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800386 PortNumber.portNumber(42)};
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800387 GroupId gId1 = new DefaultGroupId(1);
388 Group group1 = createSouthboundGroupEntry(gId1,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800389 Arrays.asList(ports1),
390 0, deviceId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800391 GroupId gId2 = new DefaultGroupId(2);
392 Group group2 = createSouthboundGroupEntry(gId2,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800393 Arrays.asList(ports2),
394 0, deviceId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800395 List<Group> groupEntries = Arrays.asList(group1, group2);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800396 providerService.pushGroupMetrics(deviceId, groupEntries);
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700397 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800398 Group createdGroup = groupService.getGroup(deviceId, key);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800399 List<GroupOperation> expectedGroupOps = Arrays.asList(
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800400 GroupOperation.createDeleteGroupOperation(gId1,
401 Group.Type.SELECT),
402 GroupOperation.createDeleteGroupOperation(gId2,
403 Group.Type.SELECT),
404 GroupOperation.createAddGroupOperation(createdGroup.id(),
405 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800406 createdGroup.buckets()));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800407 if (deviceId.equals(DID)) {
408 internalProvider.validate(deviceId, expectedGroupOps);
409 } else {
410 this.validate(deviceId, expectedGroupOps);
411 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800412 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800413
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800414 // Test AUDIT with confirmed groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800415 private void testAuditWithConfirmedGroups(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700416 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800417 Group createdGroup = groupService.getGroup(deviceId, key);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800418 createdGroup = new DefaultGroup(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800419 deviceId,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800420 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800421 createdGroup.buckets());
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700422 List<Group> groupEntries = Collections.singletonList(createdGroup);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800423 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700424 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADDED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800425 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800426
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800427 // Test group add bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800428 private void testAddBuckets(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700429 GroupKey addKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800430
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700431 GroupKey prevKey = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800432 Group createdGroup = groupService.getGroup(deviceId, prevKey);
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700433 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800434 buckets.addAll(createdGroup.buckets().buckets());
435
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800436 PortNumber[] addPorts = {PortNumber.portNumber(51),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800437 PortNumber.portNumber(52)};
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700438 List<PortNumber> outPorts;
Sho SHIMIZU7a4087b2015-09-10 09:23:16 -0700439 outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800440 outPorts.addAll(Arrays.asList(addPorts));
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700441 List<GroupBucket> addBuckets;
Sho SHIMIZU7a4087b2015-09-10 09:23:16 -0700442 addBuckets = new ArrayList<>();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800443 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800444 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
445 tBuilder.setOutput(portNumber)
446 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
447 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
448 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100449 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800450 addBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800451 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800452 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800453 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800454 }
455 GroupBuckets groupAddBuckets = new GroupBuckets(addBuckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800456 groupService.addBucketsToGroup(deviceId,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800457 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800458 groupAddBuckets,
459 addKey,
460 appId);
461 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700462 List<GroupOperation> expectedGroupOps = Collections.singletonList(
463 GroupOperation.createModifyGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800464 Group.Type.SELECT,
465 updatedBuckets));
466 if (deviceId.equals(DID)) {
467 internalProvider.validate(deviceId, expectedGroupOps);
468 } else {
469 this.validate(deviceId, expectedGroupOps);
470 }
471 Group existingGroup = groupService.getGroup(deviceId, addKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700472 List<Group> groupEntries = Collections.singletonList(existingGroup);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800473 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700474 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800475 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800476
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800477 // Test group remove bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800478 private void testRemoveBuckets(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700479 GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800480
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700481 GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800482 Group createdGroup = groupService.getGroup(deviceId, prevKey);
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700483 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800484 buckets.addAll(createdGroup.buckets().buckets());
485
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800486 PortNumber[] removePorts = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800487 PortNumber.portNumber(32)};
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700488 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800489 outPorts.addAll(Arrays.asList(removePorts));
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700490 List<GroupBucket> removeBuckets = new ArrayList<>();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800491 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800492 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
493 tBuilder.setOutput(portNumber)
494 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
495 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
496 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100497 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800498 removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800499 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800500 buckets.remove(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800501 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800502 }
503 GroupBuckets groupRemoveBuckets = new GroupBuckets(removeBuckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800504 groupService.removeBucketsFromGroup(deviceId,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800505 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800506 groupRemoveBuckets,
507 removeKey,
508 appId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800509 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700510 List<GroupOperation> expectedGroupOps = Collections.singletonList(
511 GroupOperation.createModifyGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800512 Group.Type.SELECT,
513 updatedBuckets));
514 if (deviceId.equals(DID)) {
515 internalProvider.validate(deviceId, expectedGroupOps);
516 } else {
517 this.validate(deviceId, expectedGroupOps);
518 }
519 Group existingGroup = groupService.getGroup(deviceId, removeKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700520 List<Group> groupEntries = Collections.singletonList(existingGroup);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800521 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700522 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800523 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800524
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530525 // Test purge group entry operations
526 private void testPurgeGroupEntry(DeviceId deviceId) {
527 assertEquals(1, Iterables.size(groupService.getGroups(deviceId, appId)));
528 groupService.purgeGroupEntries(deviceId);
529 assertEquals(0, Iterables.size(groupService.getGroups(deviceId, appId)));
530 }
531
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800532 // Test group remove operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800533 private void testRemoveGroup(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700534 GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800535 Group existingGroup = groupService.getGroup(deviceId, currKey);
536 groupService.removeGroup(deviceId, currKey, appId);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700537 List<GroupOperation> expectedGroupOps = Collections.singletonList(
538 GroupOperation.createDeleteGroupOperation(existingGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800539 Group.Type.SELECT));
540 if (deviceId.equals(DID)) {
541 internalProvider.validate(deviceId, expectedGroupOps);
542 } else {
543 this.validate(deviceId, expectedGroupOps);
544 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800545 List<Group> groupEntries = Collections.emptyList();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800546 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700547 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVED));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800548 }
549
sangho7ff01812015-02-09 16:21:53 -0800550 /**
551 * Test GroupOperationFailure function in Group Manager.
552 * a)GroupAddFailure
553 * b)GroupUpdateFailure
554 * c)GroupRemoteFailure
555 */
556 @Test
557 public void testGroupOperationFailure() {
Andrea Campanella6ee73922016-02-03 18:00:00 -0800558 groupOperationFaliure(DID);
559 }
560
561 /**
562 * Test GroupOperationFailure function in Group Manager
563 * with fallback provider.
564 * a)GroupAddFailure
565 * b)GroupUpdateFailure
566 * c)GroupRemoteFailure
567 */
568 @Test
569 public void testGroupOperationFailureFallBack() {
570 groupOperationFaliure(FOO_DID);
571 }
572
573 private void groupOperationFaliure(DeviceId deviceId) {
sangho7ff01812015-02-09 16:21:53 -0800574 PortNumber[] ports1 = {PortNumber.portNumber(31),
575 PortNumber.portNumber(32)};
576 PortNumber[] ports2 = {PortNumber.portNumber(41),
577 PortNumber.portNumber(42)};
578 // Test Group creation before AUDIT process
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700579 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700580 List<GroupBucket> buckets = new ArrayList<>();
581 List<PortNumber> outPorts = new ArrayList<>();
sangho7ff01812015-02-09 16:21:53 -0800582 outPorts.addAll(Arrays.asList(ports1));
583 outPorts.addAll(Arrays.asList(ports2));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800584 for (PortNumber portNumber : outPorts) {
sangho7ff01812015-02-09 16:21:53 -0800585 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
586 tBuilder.setOutput(portNumber)
587 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
588 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
589 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100590 .setMpls(MplsLabel.mplsLabel(106));
sangho7ff01812015-02-09 16:21:53 -0800591 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
592 tBuilder.build()));
593 }
594 GroupBuckets groupBuckets = new GroupBuckets(buckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800595 GroupDescription newGroupDesc = new DefaultGroupDescription(deviceId,
596 Group.Type.SELECT,
597 groupBuckets,
598 key,
599 null,
600 appId);
sangho7ff01812015-02-09 16:21:53 -0800601 groupService.addGroup(newGroupDesc);
602
603 // Test initial group audit process
604 GroupId gId1 = new DefaultGroupId(1);
605 Group group1 = createSouthboundGroupEntry(gId1,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800606 Arrays.asList(ports1),
607 0, deviceId);
sangho7ff01812015-02-09 16:21:53 -0800608 GroupId gId2 = new DefaultGroupId(2);
609 // Non zero reference count will make the group manager to queue
610 // the extraneous groups until reference count is zero.
611 Group group2 = createSouthboundGroupEntry(gId2,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800612 Arrays.asList(ports2),
613 2, deviceId);
sangho7ff01812015-02-09 16:21:53 -0800614 List<Group> groupEntries = Arrays.asList(group1, group2);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800615 providerService.pushGroupMetrics(deviceId, groupEntries);
616 Group createdGroup = groupService.getGroup(deviceId, key);
sangho7ff01812015-02-09 16:21:53 -0800617
618 // Group Add failure test
619 GroupOperation groupAddOp = GroupOperation.
620 createAddGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800621 createdGroup.type(),
622 createdGroup.buckets());
623 providerService.groupOperationFailed(deviceId, groupAddOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700624 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADD_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800625
626 // Group Mod failure test
627 groupService.addGroup(newGroupDesc);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800628 createdGroup = groupService.getGroup(deviceId, key);
sangho7ff01812015-02-09 16:21:53 -0800629 assertNotNull(createdGroup);
630
631 GroupOperation groupModOp = GroupOperation.
632 createModifyGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800633 createdGroup.type(),
634 createdGroup.buckets());
635 providerService.groupOperationFailed(deviceId, groupModOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700636 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800637
638 // Group Delete failure test
639 groupService.addGroup(newGroupDesc);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800640 createdGroup = groupService.getGroup(deviceId, key);
sangho7ff01812015-02-09 16:21:53 -0800641 assertNotNull(createdGroup);
642
643 GroupOperation groupDelOp = GroupOperation.
644 createDeleteGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800645 createdGroup.type());
646 providerService.groupOperationFailed(deviceId, groupDelOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700647 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800648 }
649
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800650 private Group createSouthboundGroupEntry(GroupId gId,
651 List<PortNumber> ports,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800652 long referenceCount, DeviceId deviceId) {
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700653 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800654 outPorts.addAll(ports);
655
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700656 List<GroupBucket> buckets = new ArrayList<>();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800657 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800658 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
659 tBuilder.setOutput(portNumber)
660 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
661 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
662 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100663 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800664 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800665 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800666 }
667 GroupBuckets groupBuckets = new GroupBuckets(buckets);
668 StoredGroupEntry group = new DefaultGroup(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800669 gId, deviceId, Group.Type.SELECT, groupBuckets);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800670 group.setReferenceCount(referenceCount);
671 return group;
672 }
673
674 private static class TestGroupListener implements GroupListener {
675 final List<GroupEvent> events = new ArrayList<>();
676
677 @Override
678 public void event(GroupEvent event) {
679 events.add(event);
680 }
681
682 public void validateEvent(List<GroupEvent.Type> expectedEvents) {
683 int i = 0;
684 System.err.println("events :" + events);
685 for (GroupEvent e : events) {
686 assertEquals("unexpected event", expectedEvents.get(i), e.type());
687 i++;
688 }
689 assertEquals("mispredicted number of events",
690 expectedEvents.size(), events.size());
691 events.clear();
692 }
693 }
694
695 private class TestGroupProvider
Andrea Campanella6ee73922016-02-03 18:00:00 -0800696 extends AbstractProvider implements GroupProvider {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800697 DeviceId lastDeviceId;
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700698 List<GroupOperation> groupOperations = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800699
700 protected TestGroupProvider(ProviderId id) {
701 super(id);
702 }
703
704 @Override
705 public void performGroupOperation(DeviceId deviceId,
706 GroupOperations groupOps) {
707 lastDeviceId = deviceId;
708 groupOperations.addAll(groupOps.operations());
709 }
710
711 public void validate(DeviceId expectedDeviceId,
712 List<GroupOperation> expectedGroupOps) {
713 if (expectedGroupOps == null) {
714 assertTrue("events generated", groupOperations.isEmpty());
715 return;
716 }
717
718 assertEquals(lastDeviceId, expectedDeviceId);
719 assertTrue((this.groupOperations.containsAll(expectedGroupOps) &&
720 expectedGroupOps.containsAll(groupOperations)));
721
722 groupOperations.clear();
723 lastDeviceId = null;
724 }
725
726 }
727
Andrea Campanella6ee73922016-02-03 18:00:00 -0800728 private static class TestDeviceService extends DeviceServiceAdapter {
729 @Override
730 public int getDeviceCount() {
731 return 1;
732 }
733
734 @Override
735 public Iterable<Device> getDevices() {
736 return ImmutableList.of(FOO_DEV);
737 }
738
739 @Override
740 public Iterable<Device> getAvailableDevices() {
741 return getDevices();
742 }
743
744 @Override
745 public Device getDevice(DeviceId deviceId) {
746 return FOO_DEV;
747 }
748 }
749
750 private class TestDriverManager extends DriverManager {
751 TestDriverManager() {
752 this.deviceService = mgr.deviceService;
753 activate();
754 }
755 }
756
757 private static DeviceId lastDeviceIdProgrammable;
758 private static List<GroupOperation> groupOperations = new ArrayList<>();
759
760 public static class TestGroupProgrammable extends AbstractHandlerBehaviour implements GroupProgrammable {
761 @Override
762 public void performGroupOperation(DeviceId deviceId, GroupOperations groupOps) {
763 lastDeviceIdProgrammable = deviceId;
764 groupOperations.addAll(groupOps.operations());
765 }
766 }
767
768 public void validate(DeviceId expectedDeviceId,
769 List<GroupOperation> expectedGroupOps) {
770 if (expectedGroupOps == null) {
771 assertTrue("events generated", groupOperations.isEmpty());
772 return;
773 }
774
775 assertEquals(lastDeviceIdProgrammable, expectedDeviceId);
776 assertTrue((this.groupOperations.containsAll(expectedGroupOps) &&
777 expectedGroupOps.containsAll(groupOperations)));
778
779 groupOperations.clear();
780 lastDeviceIdProgrammable = null;
781 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800782}
783
784