blob: 2415eea2f0fbef5e2011b2fb473256fd3fc61c14 [file] [log] [blame]
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
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;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080030import org.onosproject.core.GroupId;
Andrea Campanella6ee73922016-02-03 18:00:00 -080031import org.onosproject.net.AnnotationKeys;
32import org.onosproject.net.DefaultAnnotations;
33import org.onosproject.net.DefaultDevice;
34import org.onosproject.net.Device;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080035import org.onosproject.net.DeviceId;
36import org.onosproject.net.PortNumber;
Andrea Campanella6ee73922016-02-03 18:00:00 -080037import org.onosproject.net.device.DeviceServiceAdapter;
38import org.onosproject.net.driver.AbstractHandlerBehaviour;
39import org.onosproject.net.driver.DefaultDriver;
Thomas Vachuska11b99fc2017-04-27 12:51:04 -070040import org.onosproject.net.driver.DriverRegistry;
Andrea Campanella6ee73922016-02-03 18:00:00 -080041import org.onosproject.net.driver.impl.DriverManager;
Thomas Vachuska11b99fc2017-04-27 12:51:04 -070042import org.onosproject.net.driver.impl.DriverRegistryManager;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080043import org.onosproject.net.flow.DefaultTrafficTreatment;
44import org.onosproject.net.flow.TrafficTreatment;
45import org.onosproject.net.group.DefaultGroup;
46import org.onosproject.net.group.DefaultGroupBucket;
47import org.onosproject.net.group.DefaultGroupDescription;
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070048import org.onosproject.net.group.DefaultGroupKey;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080049import org.onosproject.net.group.Group;
50import org.onosproject.net.group.GroupBucket;
51import org.onosproject.net.group.GroupBuckets;
52import org.onosproject.net.group.GroupDescription;
53import org.onosproject.net.group.GroupEvent;
54import org.onosproject.net.group.GroupKey;
55import org.onosproject.net.group.GroupListener;
56import org.onosproject.net.group.GroupOperation;
57import org.onosproject.net.group.GroupOperations;
Andrea Campanella6ee73922016-02-03 18:00:00 -080058import org.onosproject.net.group.GroupProgrammable;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080059import 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
Andrea Campanella6ee73922016-02-03 18:00:00 -080068import java.util.ArrayList;
69import java.util.Arrays;
70import java.util.Collections;
71import java.util.List;
72
73import static org.junit.Assert.*;
74import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080075
76/**
77 * Test codifying the group service & group provider service contracts.
78 */
79public class GroupManagerTest {
80
81 private static final ProviderId PID = new ProviderId("of", "groupfoo");
82 private static final DeviceId DID = DeviceId.deviceId("of:001");
Andrea Campanella6ee73922016-02-03 18:00:00 -080083 private static final ProviderId FOO_PID = new ProviderId("foo", "foo");
84 private static final DeviceId FOO_DID = DeviceId.deviceId("foo:002");
85
86 private static final DefaultAnnotations ANNOTATIONS =
87 DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, "foo").build();
88
89 private static final Device FOO_DEV =
90 new DefaultDevice(FOO_PID, FOO_DID, Device.Type.SWITCH, "", "", "", "", null, ANNOTATIONS);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080091
92 private GroupManager mgr;
93 private GroupService groupService;
94 private GroupProviderRegistry providerRegistry;
95 private TestGroupListener internalListener = new TestGroupListener();
96 private GroupListener listener = internalListener;
97 private TestGroupProvider internalProvider;
98 private GroupProvider provider;
99 private GroupProviderService providerService;
100 private ApplicationId appId;
Andrea Campanella6ee73922016-02-03 18:00:00 -0800101 private TestDriverManager driverService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800102
103 @Before
104 public void setUp() {
105 mgr = new GroupManager();
106 groupService = mgr;
Andrea Campanella6ee73922016-02-03 18:00:00 -0800107 //mgr.deviceService = new DeviceManager();
108 mgr.deviceService = new TestDeviceService();
Charles Chan0c7c43b2016-01-14 17:39:20 -0800109 mgr.cfgService = new ComponentConfigAdapter();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800110 mgr.store = new SimpleGroupStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700111 injectEventDispatcher(mgr, new TestEventDispatcher());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800112 providerRegistry = mgr;
113
Charles Chan0c7c43b2016-01-14 17:39:20 -0800114 mgr.activate(null);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800115 mgr.addListener(listener);
116
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700117 DriverRegistryManager driverRegistry = new DriverRegistryManager();
118 driverService = new TestDriverManager(driverRegistry);
119 driverRegistry.addDriver(new DefaultDriver("foo", ImmutableList.of(), "", "", "",
120 ImmutableMap.of(GroupProgrammable.class,
121 TestGroupProgrammable.class),
122 ImmutableMap.of()));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800123
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800124 internalProvider = new TestGroupProvider(PID);
125 provider = internalProvider;
126 providerService = providerRegistry.register(provider);
127 appId = new DefaultApplicationId(2, "org.groupmanager.test");
128 assertTrue("provider should be registered",
129 providerRegistry.getProviders().contains(provider.id()));
130 }
131
132 @After
133 public void tearDown() {
134 providerRegistry.unregister(provider);
135 assertFalse("provider should not be registered",
136 providerRegistry.getProviders().contains(provider.id()));
137 mgr.removeListener(listener);
138 mgr.deactivate();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700139 injectEventDispatcher(mgr, null);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800140 }
141
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800142 /**
Andrea Campanella6ee73922016-02-03 18:00:00 -0800143 * Tests group creation before the device group AUDIT completes.
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800144 */
145 @Test
Andrea Campanella6ee73922016-02-03 18:00:00 -0800146 public void testGroupServiceBasics() {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800147 // Test Group creation before AUDIT process
Andrea Campanella6ee73922016-02-03 18:00:00 -0800148 testGroupCreationBeforeAudit(DID);
149 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800150
Andrea Campanella6ee73922016-02-03 18:00:00 -0800151 /**
152 * Tests initial device group AUDIT process.
153 */
154 @Test
155 public void testGroupServiceInitialAudit() {
156 // Test Group creation before AUDIT process
157 testGroupCreationBeforeAudit(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800158 // Test initial group audit process
Andrea Campanella6ee73922016-02-03 18:00:00 -0800159 testInitialAuditWithPendingGroupRequests(DID);
160 }
161
162 /**
163 * Tests deletion process of any extraneous groups.
164 */
165 @Test
166 public void testGroupServiceAuditExtraneous() {
167 // Test Group creation before AUDIT process
168 testGroupCreationBeforeAudit(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800169
170 // Test audit with extraneous and missing groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800171 testAuditWithExtraneousMissingGroups(DID);
172 }
173
174 /**
175 * Tests re-apply process of any missing groups tests execution of
176 * any pending group creation request after the device group AUDIT completes
177 * and tests event notifications after receiving confirmation for any
178 * operations from data plane.
179 */
180 @Test
181 public void testGroupServiceAuditConfirmed() {
182 // Test Group creation before AUDIT process
183 testGroupCreationBeforeAudit(DID);
184
185 // Test audit with extraneous and missing groups
186 testAuditWithExtraneousMissingGroups(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800187
188 // Test audit with confirmed groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800189 testAuditWithConfirmedGroups(DID);
190 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800191
Andrea Campanella6ee73922016-02-03 18:00:00 -0800192 /**
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530193 * Tests group Purge Operation.
194 */
195 @Test
196 public void testPurgeGroups() {
197 //Test Group creation before AUDIT process
198 testGroupCreationBeforeAudit(DID);
199 programmableTestCleanUp();
200 testAuditWithExtraneousMissingGroups(DID);
201 // Test group add bucket operations
202 testAddBuckets(DID);
203 // Test group Purge operations
204 testPurgeGroupEntry(DID);
205 }
206
207 /**
Andrea Campanella6ee73922016-02-03 18:00:00 -0800208 * Tests group bucket modifications (additions and deletions) and
209 * Tests group deletion.
210 */
211 @Test
212 public void testGroupServiceBuckets() {
213 // Test Group creation before AUDIT process
214 testGroupCreationBeforeAudit(DID);
215 programmableTestCleanUp();
216
217 testAuditWithExtraneousMissingGroups(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800218 // Test group add bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800219 testAddBuckets(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800220
221 // Test group remove bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800222 testRemoveBuckets(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800223
224 // Test group remove operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800225 testRemoveGroup(DID);
226 }
227
228 /**
229 * Tests group creation before the device group AUDIT completes with fallback
230 * provider.
231 */
232 @Test
233 public void testGroupServiceFallbackBasics() {
234 // Test Group creation before AUDIT process
235 testGroupCreationBeforeAudit(FOO_DID);
236 programmableTestCleanUp();
237
238 }
239
240 /**
241 * Tests initial device group AUDIT process with fallback provider.
242 */
243 @Test
244 public void testGroupServiceFallbackInitialAudit() {
245 // Test Group creation before AUDIT process
246 testGroupCreationBeforeAudit(FOO_DID);
247 programmableTestCleanUp();
248 // Test initial group audit process
249 testInitialAuditWithPendingGroupRequests(FOO_DID);
250 }
251
252 /**
253 * Tests deletion process of any extraneous groups with fallback provider.
254 */
255 @Test
256 public void testGroupServiceFallbackAuditExtraneous() {
257 // Test Group creation before AUDIT process
258 testGroupCreationBeforeAudit(FOO_DID);
259 programmableTestCleanUp();
260
261 // Test audit with extraneous and missing groups
262 testAuditWithExtraneousMissingGroups(FOO_DID);
263 }
264
265 /**
266 * Tests re-apply process of any missing groups tests execution of
267 * any pending group creation request after the device group AUDIT completes
268 * and tests event notifications after receiving confirmation for any
269 * operations from data plane with fallback provider.
270 */
271 @Test
272 public void testGroupServiceFallbackAuditConfirmed() {
273 // Test Group creation before AUDIT process
274 testGroupCreationBeforeAudit(FOO_DID);
275 programmableTestCleanUp();
276
277 // Test audit with extraneous and missing groups
278 testAuditWithExtraneousMissingGroups(FOO_DID);
279
280 // Test audit with confirmed groups
281 testAuditWithConfirmedGroups(FOO_DID);
282 }
283
284 /**
285 * Tests group bucket modifications (additions and deletions) and
286 * Tests group deletion with fallback provider.
287 */
288 @Test
289 public void testGroupServiceFallbackBuckets() {
290 // Test Group creation before AUDIT process
291 testGroupCreationBeforeAudit(FOO_DID);
292 programmableTestCleanUp();
293
294 testAuditWithExtraneousMissingGroups(FOO_DID);
295 // Test group add bucket operations
296 testAddBuckets(FOO_DID);
297
298 // Test group remove bucket operations
299 testRemoveBuckets(FOO_DID);
300
301 // Test group remove operations
302 testRemoveGroup(FOO_DID);
303 }
304
305 private void programmableTestCleanUp() {
306 groupOperations.clear();
307 lastDeviceIdProgrammable = null;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800308 }
309
310 // Test Group creation before AUDIT process
Andrea Campanella6ee73922016-02-03 18:00:00 -0800311 private void testGroupCreationBeforeAudit(DeviceId deviceId) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800312 PortNumber[] ports1 = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800313 PortNumber.portNumber(32)};
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800314 PortNumber[] ports2 = {PortNumber.portNumber(41),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800315 PortNumber.portNumber(42)};
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700316 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700317 List<GroupBucket> buckets = new ArrayList<>();
318 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800319 outPorts.addAll(Arrays.asList(ports1));
320 outPorts.addAll(Arrays.asList(ports2));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800321 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800322 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
323 tBuilder.setOutput(portNumber)
324 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
325 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
326 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100327 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800328 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800329 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800330 }
331 GroupBuckets groupBuckets = new GroupBuckets(buckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800332 GroupDescription newGroupDesc = new DefaultGroupDescription(deviceId,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800333 Group.Type.SELECT,
334 groupBuckets,
335 key,
Saurav Das100e3b82015-04-30 11:12:10 -0700336 null,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800337 appId);
338 groupService.addGroup(newGroupDesc);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800339 assertEquals(null, groupService.getGroup(deviceId, key));
340 assertEquals(0, Iterables.size(groupService.getGroups(deviceId, appId)));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800341 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800342
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800343 // Test initial AUDIT process with pending group requests
Andrea Campanella6ee73922016-02-03 18:00:00 -0800344 private void testInitialAuditWithPendingGroupRequests(DeviceId deviceId) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800345 PortNumber[] ports1 = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800346 PortNumber.portNumber(32)};
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800347 PortNumber[] ports2 = {PortNumber.portNumber(41),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800348 PortNumber.portNumber(42)};
Yi Tsengfa394de2017-02-01 11:26:40 -0800349 GroupId gId1 = new GroupId(1);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800350 Group group1 = createSouthboundGroupEntry(gId1,
351 Arrays.asList(ports1),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800352 0, deviceId);
Yi Tsengfa394de2017-02-01 11:26:40 -0800353 GroupId gId2 = new GroupId(2);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800354 // Non zero reference count will make the group manager to queue
355 // the extraneous groups until reference count is zero.
356 Group group2 = createSouthboundGroupEntry(gId2,
357 Arrays.asList(ports2),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800358 2, deviceId);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800359 List<Group> groupEntries = Arrays.asList(group1, group2);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800360 providerService.pushGroupMetrics(deviceId, groupEntries);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800361 // First group metrics would trigger the device audit completion
362 // post which all pending group requests are also executed.
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700363 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800364 Group createdGroup = groupService.getGroup(deviceId, key);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800365 int createdGroupId = createdGroup.id().id();
Prince Pereira3ff504c2016-08-30 14:23:43 +0530366 assertNotEquals(gId1.id().intValue(), createdGroupId);
367 assertNotEquals(gId2.id().intValue(), createdGroupId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800368
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800369 List<GroupOperation> expectedGroupOps = Arrays.asList(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800370 GroupOperation.createDeleteGroupOperation(gId1,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800371 Group.Type.SELECT),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800372 GroupOperation.createAddGroupOperation(
373 createdGroup.id(),
374 Group.Type.SELECT,
375 createdGroup.buckets()));
376 if (deviceId.equals(DID)) {
377 internalProvider.validate(deviceId, expectedGroupOps);
378 } else {
379 this.validate(deviceId, expectedGroupOps);
380 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800381 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800382
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800383 // Test AUDIT process with extraneous groups and missing groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800384 private void testAuditWithExtraneousMissingGroups(DeviceId deviceId) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800385 PortNumber[] ports1 = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800386 PortNumber.portNumber(32)};
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800387 PortNumber[] ports2 = {PortNumber.portNumber(41),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800388 PortNumber.portNumber(42)};
Yi Tsengfa394de2017-02-01 11:26:40 -0800389 GroupId gId1 = new GroupId(1);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800390 Group group1 = createSouthboundGroupEntry(gId1,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800391 Arrays.asList(ports1),
392 0, deviceId);
Yi Tsengfa394de2017-02-01 11:26:40 -0800393 GroupId gId2 = new GroupId(2);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800394 Group group2 = createSouthboundGroupEntry(gId2,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800395 Arrays.asList(ports2),
396 0, deviceId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800397 List<Group> groupEntries = Arrays.asList(group1, group2);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800398 providerService.pushGroupMetrics(deviceId, groupEntries);
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700399 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800400 Group createdGroup = groupService.getGroup(deviceId, key);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800401 List<GroupOperation> expectedGroupOps = Arrays.asList(
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800402 GroupOperation.createDeleteGroupOperation(gId1,
403 Group.Type.SELECT),
404 GroupOperation.createDeleteGroupOperation(gId2,
405 Group.Type.SELECT),
406 GroupOperation.createAddGroupOperation(createdGroup.id(),
407 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800408 createdGroup.buckets()));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800409 if (deviceId.equals(DID)) {
410 internalProvider.validate(deviceId, expectedGroupOps);
411 } else {
412 this.validate(deviceId, expectedGroupOps);
413 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800414 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800415
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800416 // Test AUDIT with confirmed groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800417 private void testAuditWithConfirmedGroups(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700418 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800419 Group createdGroup = groupService.getGroup(deviceId, key);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800420 createdGroup = new DefaultGroup(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800421 deviceId,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800422 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800423 createdGroup.buckets());
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700424 List<Group> groupEntries = Collections.singletonList(createdGroup);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800425 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700426 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADDED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800427 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800428
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800429 // Test group add bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800430 private void testAddBuckets(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700431 GroupKey addKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800432
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700433 GroupKey prevKey = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800434 Group createdGroup = groupService.getGroup(deviceId, prevKey);
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700435 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800436 buckets.addAll(createdGroup.buckets().buckets());
437
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800438 PortNumber[] addPorts = {PortNumber.portNumber(51),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800439 PortNumber.portNumber(52)};
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700440 List<PortNumber> outPorts;
Sho SHIMIZU7a4087b2015-09-10 09:23:16 -0700441 outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800442 outPorts.addAll(Arrays.asList(addPorts));
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700443 List<GroupBucket> addBuckets;
Sho SHIMIZU7a4087b2015-09-10 09:23:16 -0700444 addBuckets = new ArrayList<>();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800445 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800446 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
447 tBuilder.setOutput(portNumber)
448 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
449 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
450 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100451 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800452 addBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800453 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800454 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800455 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800456 }
457 GroupBuckets groupAddBuckets = new GroupBuckets(addBuckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800458 groupService.addBucketsToGroup(deviceId,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800459 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800460 groupAddBuckets,
461 addKey,
462 appId);
463 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700464 List<GroupOperation> expectedGroupOps = Collections.singletonList(
465 GroupOperation.createModifyGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800466 Group.Type.SELECT,
467 updatedBuckets));
468 if (deviceId.equals(DID)) {
469 internalProvider.validate(deviceId, expectedGroupOps);
470 } else {
471 this.validate(deviceId, expectedGroupOps);
472 }
473 Group existingGroup = groupService.getGroup(deviceId, addKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700474 List<Group> groupEntries = Collections.singletonList(existingGroup);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800475 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700476 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800477 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800478
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800479 // Test group remove bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800480 private void testRemoveBuckets(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700481 GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800482
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700483 GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800484 Group createdGroup = groupService.getGroup(deviceId, prevKey);
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700485 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800486 buckets.addAll(createdGroup.buckets().buckets());
487
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800488 PortNumber[] removePorts = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800489 PortNumber.portNumber(32)};
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700490 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800491 outPorts.addAll(Arrays.asList(removePorts));
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700492 List<GroupBucket> removeBuckets = new ArrayList<>();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800493 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800494 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
495 tBuilder.setOutput(portNumber)
496 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
497 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
498 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100499 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800500 removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800501 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800502 buckets.remove(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800503 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800504 }
505 GroupBuckets groupRemoveBuckets = new GroupBuckets(removeBuckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800506 groupService.removeBucketsFromGroup(deviceId,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800507 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800508 groupRemoveBuckets,
509 removeKey,
510 appId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800511 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700512 List<GroupOperation> expectedGroupOps = Collections.singletonList(
513 GroupOperation.createModifyGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800514 Group.Type.SELECT,
515 updatedBuckets));
516 if (deviceId.equals(DID)) {
517 internalProvider.validate(deviceId, expectedGroupOps);
518 } else {
519 this.validate(deviceId, expectedGroupOps);
520 }
521 Group existingGroup = groupService.getGroup(deviceId, removeKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700522 List<Group> groupEntries = Collections.singletonList(existingGroup);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800523 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700524 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800525 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800526
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530527 // Test purge group entry operations
528 private void testPurgeGroupEntry(DeviceId deviceId) {
529 assertEquals(1, Iterables.size(groupService.getGroups(deviceId, appId)));
530 groupService.purgeGroupEntries(deviceId);
531 assertEquals(0, Iterables.size(groupService.getGroups(deviceId, appId)));
532 }
533
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800534 // Test group remove operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800535 private void testRemoveGroup(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700536 GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800537 Group existingGroup = groupService.getGroup(deviceId, currKey);
538 groupService.removeGroup(deviceId, currKey, appId);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700539 List<GroupOperation> expectedGroupOps = Collections.singletonList(
540 GroupOperation.createDeleteGroupOperation(existingGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800541 Group.Type.SELECT));
542 if (deviceId.equals(DID)) {
543 internalProvider.validate(deviceId, expectedGroupOps);
544 } else {
545 this.validate(deviceId, expectedGroupOps);
546 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800547 List<Group> groupEntries = Collections.emptyList();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800548 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700549 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVED));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800550 }
551
sangho7ff01812015-02-09 16:21:53 -0800552 /**
553 * Test GroupOperationFailure function in Group Manager.
554 * a)GroupAddFailure
555 * b)GroupUpdateFailure
556 * c)GroupRemoteFailure
557 */
558 @Test
559 public void testGroupOperationFailure() {
Andrea Campanella6ee73922016-02-03 18:00:00 -0800560 groupOperationFaliure(DID);
561 }
562
563 /**
564 * Test GroupOperationFailure function in Group Manager
565 * with fallback provider.
566 * a)GroupAddFailure
567 * b)GroupUpdateFailure
568 * c)GroupRemoteFailure
569 */
570 @Test
571 public void testGroupOperationFailureFallBack() {
572 groupOperationFaliure(FOO_DID);
573 }
574
575 private void groupOperationFaliure(DeviceId deviceId) {
sangho7ff01812015-02-09 16:21:53 -0800576 PortNumber[] ports1 = {PortNumber.portNumber(31),
577 PortNumber.portNumber(32)};
578 PortNumber[] ports2 = {PortNumber.portNumber(41),
579 PortNumber.portNumber(42)};
580 // Test Group creation before AUDIT process
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700581 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700582 List<GroupBucket> buckets = new ArrayList<>();
583 List<PortNumber> outPorts = new ArrayList<>();
sangho7ff01812015-02-09 16:21:53 -0800584 outPorts.addAll(Arrays.asList(ports1));
585 outPorts.addAll(Arrays.asList(ports2));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800586 for (PortNumber portNumber : outPorts) {
sangho7ff01812015-02-09 16:21:53 -0800587 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
588 tBuilder.setOutput(portNumber)
589 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
590 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
591 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100592 .setMpls(MplsLabel.mplsLabel(106));
sangho7ff01812015-02-09 16:21:53 -0800593 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
594 tBuilder.build()));
595 }
596 GroupBuckets groupBuckets = new GroupBuckets(buckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800597 GroupDescription newGroupDesc = new DefaultGroupDescription(deviceId,
598 Group.Type.SELECT,
599 groupBuckets,
600 key,
601 null,
602 appId);
sangho7ff01812015-02-09 16:21:53 -0800603 groupService.addGroup(newGroupDesc);
604
605 // Test initial group audit process
Yi Tsengfa394de2017-02-01 11:26:40 -0800606 GroupId gId1 = new GroupId(1);
sangho7ff01812015-02-09 16:21:53 -0800607 Group group1 = createSouthboundGroupEntry(gId1,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800608 Arrays.asList(ports1),
609 0, deviceId);
Yi Tsengfa394de2017-02-01 11:26:40 -0800610 GroupId gId2 = new GroupId(2);
sangho7ff01812015-02-09 16:21:53 -0800611 // Non zero reference count will make the group manager to queue
612 // the extraneous groups until reference count is zero.
613 Group group2 = createSouthboundGroupEntry(gId2,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800614 Arrays.asList(ports2),
615 2, deviceId);
sangho7ff01812015-02-09 16:21:53 -0800616 List<Group> groupEntries = Arrays.asList(group1, group2);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800617 providerService.pushGroupMetrics(deviceId, groupEntries);
618 Group createdGroup = groupService.getGroup(deviceId, key);
sangho7ff01812015-02-09 16:21:53 -0800619
620 // Group Add failure test
621 GroupOperation groupAddOp = GroupOperation.
622 createAddGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800623 createdGroup.type(),
624 createdGroup.buckets());
625 providerService.groupOperationFailed(deviceId, groupAddOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700626 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADD_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800627
628 // Group Mod failure test
629 groupService.addGroup(newGroupDesc);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800630 createdGroup = groupService.getGroup(deviceId, key);
sangho7ff01812015-02-09 16:21:53 -0800631 assertNotNull(createdGroup);
632
633 GroupOperation groupModOp = GroupOperation.
634 createModifyGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800635 createdGroup.type(),
636 createdGroup.buckets());
637 providerService.groupOperationFailed(deviceId, groupModOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700638 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800639
640 // Group Delete failure test
641 groupService.addGroup(newGroupDesc);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800642 createdGroup = groupService.getGroup(deviceId, key);
sangho7ff01812015-02-09 16:21:53 -0800643 assertNotNull(createdGroup);
644
645 GroupOperation groupDelOp = GroupOperation.
646 createDeleteGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800647 createdGroup.type());
648 providerService.groupOperationFailed(deviceId, groupDelOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700649 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800650 }
651
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800652 private Group createSouthboundGroupEntry(GroupId gId,
653 List<PortNumber> ports,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800654 long referenceCount, DeviceId deviceId) {
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700655 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800656 outPorts.addAll(ports);
657
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700658 List<GroupBucket> buckets = new ArrayList<>();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800659 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800660 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
661 tBuilder.setOutput(portNumber)
662 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
663 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
664 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100665 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800666 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800667 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800668 }
669 GroupBuckets groupBuckets = new GroupBuckets(buckets);
670 StoredGroupEntry group = new DefaultGroup(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800671 gId, deviceId, Group.Type.SELECT, groupBuckets);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800672 group.setReferenceCount(referenceCount);
673 return group;
674 }
675
676 private static class TestGroupListener implements GroupListener {
677 final List<GroupEvent> events = new ArrayList<>();
678
679 @Override
680 public void event(GroupEvent event) {
681 events.add(event);
682 }
683
684 public void validateEvent(List<GroupEvent.Type> expectedEvents) {
685 int i = 0;
686 System.err.println("events :" + events);
687 for (GroupEvent e : events) {
688 assertEquals("unexpected event", expectedEvents.get(i), e.type());
689 i++;
690 }
691 assertEquals("mispredicted number of events",
692 expectedEvents.size(), events.size());
693 events.clear();
694 }
695 }
696
697 private class TestGroupProvider
Andrea Campanella6ee73922016-02-03 18:00:00 -0800698 extends AbstractProvider implements GroupProvider {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800699 DeviceId lastDeviceId;
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700700 List<GroupOperation> groupOperations = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800701
702 protected TestGroupProvider(ProviderId id) {
703 super(id);
704 }
705
706 @Override
707 public void performGroupOperation(DeviceId deviceId,
708 GroupOperations groupOps) {
709 lastDeviceId = deviceId;
710 groupOperations.addAll(groupOps.operations());
711 }
712
713 public void validate(DeviceId expectedDeviceId,
714 List<GroupOperation> expectedGroupOps) {
715 if (expectedGroupOps == null) {
716 assertTrue("events generated", groupOperations.isEmpty());
717 return;
718 }
719
720 assertEquals(lastDeviceId, expectedDeviceId);
721 assertTrue((this.groupOperations.containsAll(expectedGroupOps) &&
722 expectedGroupOps.containsAll(groupOperations)));
723
724 groupOperations.clear();
725 lastDeviceId = null;
726 }
727
728 }
729
Andrea Campanella6ee73922016-02-03 18:00:00 -0800730 private static class TestDeviceService extends DeviceServiceAdapter {
731 @Override
732 public int getDeviceCount() {
733 return 1;
734 }
735
736 @Override
737 public Iterable<Device> getDevices() {
738 return ImmutableList.of(FOO_DEV);
739 }
740
741 @Override
742 public Iterable<Device> getAvailableDevices() {
743 return getDevices();
744 }
745
746 @Override
747 public Device getDevice(DeviceId deviceId) {
748 return FOO_DEV;
749 }
750 }
751
752 private class TestDriverManager extends DriverManager {
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700753 TestDriverManager(DriverRegistry registry) {
754 this.registry = registry;
Andrea Campanella6ee73922016-02-03 18:00:00 -0800755 this.deviceService = mgr.deviceService;
756 activate();
757 }
758 }
759
760 private static DeviceId lastDeviceIdProgrammable;
761 private static List<GroupOperation> groupOperations = new ArrayList<>();
762
763 public static class TestGroupProgrammable extends AbstractHandlerBehaviour implements GroupProgrammable {
764 @Override
765 public void performGroupOperation(DeviceId deviceId, GroupOperations groupOps) {
766 lastDeviceIdProgrammable = deviceId;
767 groupOperations.addAll(groupOps.operations());
768 }
769 }
770
771 public void validate(DeviceId expectedDeviceId,
772 List<GroupOperation> expectedGroupOps) {
773 if (expectedGroupOps == null) {
774 assertTrue("events generated", groupOperations.isEmpty());
775 return;
776 }
777
778 assertEquals(lastDeviceIdProgrammable, expectedDeviceId);
Sho SHIMIZU970d6e22016-08-12 15:13:22 -0700779 assertTrue(groupOperations.containsAll(expectedGroupOps) &&
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700780 expectedGroupOps.containsAll(groupOperations));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800781
782 groupOperations.clear();
783 lastDeviceIdProgrammable = null;
784 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800785}
786
787