blob: a85046b308652c2d5960fc958363390eca47a739 [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;
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;
40import org.onosproject.net.driver.impl.DriverManager;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080041import org.onosproject.net.flow.DefaultTrafficTreatment;
42import org.onosproject.net.flow.TrafficTreatment;
43import org.onosproject.net.group.DefaultGroup;
44import org.onosproject.net.group.DefaultGroupBucket;
45import org.onosproject.net.group.DefaultGroupDescription;
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070046import org.onosproject.net.group.DefaultGroupKey;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080047import org.onosproject.net.group.Group;
48import org.onosproject.net.group.GroupBucket;
49import org.onosproject.net.group.GroupBuckets;
50import org.onosproject.net.group.GroupDescription;
51import org.onosproject.net.group.GroupEvent;
52import org.onosproject.net.group.GroupKey;
53import org.onosproject.net.group.GroupListener;
54import org.onosproject.net.group.GroupOperation;
55import org.onosproject.net.group.GroupOperations;
Andrea Campanella6ee73922016-02-03 18:00:00 -080056import org.onosproject.net.group.GroupProgrammable;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080057import org.onosproject.net.group.GroupProvider;
58import org.onosproject.net.group.GroupProviderRegistry;
59import org.onosproject.net.group.GroupProviderService;
60import org.onosproject.net.group.GroupService;
61import org.onosproject.net.group.StoredGroupEntry;
62import org.onosproject.net.provider.AbstractProvider;
63import org.onosproject.net.provider.ProviderId;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070064import org.onosproject.store.trivial.SimpleGroupStore;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080065
Andrea Campanella6ee73922016-02-03 18:00:00 -080066import java.util.ArrayList;
67import java.util.Arrays;
68import java.util.Collections;
69import java.util.List;
70
71import static org.junit.Assert.*;
72import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080073
74/**
75 * Test codifying the group service & group provider service contracts.
76 */
77public class GroupManagerTest {
78
79 private static final ProviderId PID = new ProviderId("of", "groupfoo");
80 private static final DeviceId DID = DeviceId.deviceId("of:001");
Andrea Campanella6ee73922016-02-03 18:00:00 -080081 private static final ProviderId FOO_PID = new ProviderId("foo", "foo");
82 private static final DeviceId FOO_DID = DeviceId.deviceId("foo:002");
83
84 private static final DefaultAnnotations ANNOTATIONS =
85 DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, "foo").build();
86
87 private static final Device FOO_DEV =
88 new DefaultDevice(FOO_PID, FOO_DID, Device.Type.SWITCH, "", "", "", "", null, ANNOTATIONS);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080089
90 private GroupManager mgr;
91 private GroupService groupService;
92 private GroupProviderRegistry providerRegistry;
93 private TestGroupListener internalListener = new TestGroupListener();
94 private GroupListener listener = internalListener;
95 private TestGroupProvider internalProvider;
96 private GroupProvider provider;
97 private GroupProviderService providerService;
98 private ApplicationId appId;
Andrea Campanella6ee73922016-02-03 18:00:00 -080099 private TestDriverManager driverService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800100
101 @Before
102 public void setUp() {
103 mgr = new GroupManager();
104 groupService = mgr;
Andrea Campanella6ee73922016-02-03 18:00:00 -0800105 //mgr.deviceService = new DeviceManager();
106 mgr.deviceService = new TestDeviceService();
Charles Chan0c7c43b2016-01-14 17:39:20 -0800107 mgr.cfgService = new ComponentConfigAdapter();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800108 mgr.store = new SimpleGroupStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700109 injectEventDispatcher(mgr, new TestEventDispatcher());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800110 providerRegistry = mgr;
111
Charles Chan0c7c43b2016-01-14 17:39:20 -0800112 mgr.activate(null);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800113 mgr.addListener(listener);
114
Andrea Campanella6ee73922016-02-03 18:00:00 -0800115 driverService = new TestDriverManager();
116 driverService.addDriver(new DefaultDriver("foo", ImmutableList.of(), "", "", "",
117 ImmutableMap.of(GroupProgrammable.class,
118 TestGroupProgrammable.class),
119 ImmutableMap.of()));
120
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800121 internalProvider = new TestGroupProvider(PID);
122 provider = internalProvider;
123 providerService = providerRegistry.register(provider);
124 appId = new DefaultApplicationId(2, "org.groupmanager.test");
125 assertTrue("provider should be registered",
126 providerRegistry.getProviders().contains(provider.id()));
127 }
128
129 @After
130 public void tearDown() {
131 providerRegistry.unregister(provider);
132 assertFalse("provider should not be registered",
133 providerRegistry.getProviders().contains(provider.id()));
134 mgr.removeListener(listener);
135 mgr.deactivate();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700136 injectEventDispatcher(mgr, null);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800137 }
138
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800139 /**
Andrea Campanella6ee73922016-02-03 18:00:00 -0800140 * Tests group creation before the device group AUDIT completes.
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800141 */
142 @Test
Andrea Campanella6ee73922016-02-03 18:00:00 -0800143 public void testGroupServiceBasics() {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800144 // Test Group creation before AUDIT process
Andrea Campanella6ee73922016-02-03 18:00:00 -0800145 testGroupCreationBeforeAudit(DID);
146 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800147
Andrea Campanella6ee73922016-02-03 18:00:00 -0800148 /**
149 * Tests initial device group AUDIT process.
150 */
151 @Test
152 public void testGroupServiceInitialAudit() {
153 // Test Group creation before AUDIT process
154 testGroupCreationBeforeAudit(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800155 // Test initial group audit process
Andrea Campanella6ee73922016-02-03 18:00:00 -0800156 testInitialAuditWithPendingGroupRequests(DID);
157 }
158
159 /**
160 * Tests deletion process of any extraneous groups.
161 */
162 @Test
163 public void testGroupServiceAuditExtraneous() {
164 // Test Group creation before AUDIT process
165 testGroupCreationBeforeAudit(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800166
167 // Test audit with extraneous and missing groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800168 testAuditWithExtraneousMissingGroups(DID);
169 }
170
171 /**
172 * Tests re-apply process of any missing groups tests execution of
173 * any pending group creation request after the device group AUDIT completes
174 * and tests event notifications after receiving confirmation for any
175 * operations from data plane.
176 */
177 @Test
178 public void testGroupServiceAuditConfirmed() {
179 // Test Group creation before AUDIT process
180 testGroupCreationBeforeAudit(DID);
181
182 // Test audit with extraneous and missing groups
183 testAuditWithExtraneousMissingGroups(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800184
185 // Test audit with confirmed groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800186 testAuditWithConfirmedGroups(DID);
187 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800188
Andrea Campanella6ee73922016-02-03 18:00:00 -0800189 /**
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530190 * Tests group Purge Operation.
191 */
192 @Test
193 public void testPurgeGroups() {
194 //Test Group creation before AUDIT process
195 testGroupCreationBeforeAudit(DID);
196 programmableTestCleanUp();
197 testAuditWithExtraneousMissingGroups(DID);
198 // Test group add bucket operations
199 testAddBuckets(DID);
200 // Test group Purge operations
201 testPurgeGroupEntry(DID);
202 }
203
204 /**
Andrea Campanella6ee73922016-02-03 18:00:00 -0800205 * Tests group bucket modifications (additions and deletions) and
206 * Tests group deletion.
207 */
208 @Test
209 public void testGroupServiceBuckets() {
210 // Test Group creation before AUDIT process
211 testGroupCreationBeforeAudit(DID);
212 programmableTestCleanUp();
213
214 testAuditWithExtraneousMissingGroups(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800215 // Test group add bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800216 testAddBuckets(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800217
218 // Test group remove bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800219 testRemoveBuckets(DID);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800220
221 // Test group remove operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800222 testRemoveGroup(DID);
223 }
224
225 /**
226 * Tests group creation before the device group AUDIT completes with fallback
227 * provider.
228 */
229 @Test
230 public void testGroupServiceFallbackBasics() {
231 // Test Group creation before AUDIT process
232 testGroupCreationBeforeAudit(FOO_DID);
233 programmableTestCleanUp();
234
235 }
236
237 /**
238 * Tests initial device group AUDIT process with fallback provider.
239 */
240 @Test
241 public void testGroupServiceFallbackInitialAudit() {
242 // Test Group creation before AUDIT process
243 testGroupCreationBeforeAudit(FOO_DID);
244 programmableTestCleanUp();
245 // Test initial group audit process
246 testInitialAuditWithPendingGroupRequests(FOO_DID);
247 }
248
249 /**
250 * Tests deletion process of any extraneous groups with fallback provider.
251 */
252 @Test
253 public void testGroupServiceFallbackAuditExtraneous() {
254 // Test Group creation before AUDIT process
255 testGroupCreationBeforeAudit(FOO_DID);
256 programmableTestCleanUp();
257
258 // Test audit with extraneous and missing groups
259 testAuditWithExtraneousMissingGroups(FOO_DID);
260 }
261
262 /**
263 * Tests re-apply process of any missing groups tests execution of
264 * any pending group creation request after the device group AUDIT completes
265 * and tests event notifications after receiving confirmation for any
266 * operations from data plane with fallback provider.
267 */
268 @Test
269 public void testGroupServiceFallbackAuditConfirmed() {
270 // Test Group creation before AUDIT process
271 testGroupCreationBeforeAudit(FOO_DID);
272 programmableTestCleanUp();
273
274 // Test audit with extraneous and missing groups
275 testAuditWithExtraneousMissingGroups(FOO_DID);
276
277 // Test audit with confirmed groups
278 testAuditWithConfirmedGroups(FOO_DID);
279 }
280
281 /**
282 * Tests group bucket modifications (additions and deletions) and
283 * Tests group deletion with fallback provider.
284 */
285 @Test
286 public void testGroupServiceFallbackBuckets() {
287 // Test Group creation before AUDIT process
288 testGroupCreationBeforeAudit(FOO_DID);
289 programmableTestCleanUp();
290
291 testAuditWithExtraneousMissingGroups(FOO_DID);
292 // Test group add bucket operations
293 testAddBuckets(FOO_DID);
294
295 // Test group remove bucket operations
296 testRemoveBuckets(FOO_DID);
297
298 // Test group remove operations
299 testRemoveGroup(FOO_DID);
300 }
301
302 private void programmableTestCleanUp() {
303 groupOperations.clear();
304 lastDeviceIdProgrammable = null;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800305 }
306
307 // Test Group creation before AUDIT process
Andrea Campanella6ee73922016-02-03 18:00:00 -0800308 private void testGroupCreationBeforeAudit(DeviceId deviceId) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800309 PortNumber[] ports1 = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800310 PortNumber.portNumber(32)};
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800311 PortNumber[] ports2 = {PortNumber.portNumber(41),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800312 PortNumber.portNumber(42)};
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700313 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700314 List<GroupBucket> buckets = new ArrayList<>();
315 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800316 outPorts.addAll(Arrays.asList(ports1));
317 outPorts.addAll(Arrays.asList(ports2));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800318 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800319 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
320 tBuilder.setOutput(portNumber)
321 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
322 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
323 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100324 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800325 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800326 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800327 }
328 GroupBuckets groupBuckets = new GroupBuckets(buckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800329 GroupDescription newGroupDesc = new DefaultGroupDescription(deviceId,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800330 Group.Type.SELECT,
331 groupBuckets,
332 key,
Saurav Das100e3b82015-04-30 11:12:10 -0700333 null,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800334 appId);
335 groupService.addGroup(newGroupDesc);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800336 assertEquals(null, groupService.getGroup(deviceId, key));
337 assertEquals(0, Iterables.size(groupService.getGroups(deviceId, appId)));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800338 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800339
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800340 // Test initial AUDIT process with pending group requests
Andrea Campanella6ee73922016-02-03 18:00:00 -0800341 private void testInitialAuditWithPendingGroupRequests(DeviceId deviceId) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800342 PortNumber[] ports1 = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800343 PortNumber.portNumber(32)};
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800344 PortNumber[] ports2 = {PortNumber.portNumber(41),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800345 PortNumber.portNumber(42)};
Yi Tsengfa394de2017-02-01 11:26:40 -0800346 GroupId gId1 = new GroupId(1);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800347 Group group1 = createSouthboundGroupEntry(gId1,
348 Arrays.asList(ports1),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800349 0, deviceId);
Yi Tsengfa394de2017-02-01 11:26:40 -0800350 GroupId gId2 = new GroupId(2);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800351 // Non zero reference count will make the group manager to queue
352 // the extraneous groups until reference count is zero.
353 Group group2 = createSouthboundGroupEntry(gId2,
354 Arrays.asList(ports2),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800355 2, deviceId);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800356 List<Group> groupEntries = Arrays.asList(group1, group2);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800357 providerService.pushGroupMetrics(deviceId, groupEntries);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800358 // First group metrics would trigger the device audit completion
359 // post which all pending group requests are also executed.
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700360 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800361 Group createdGroup = groupService.getGroup(deviceId, key);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800362 int createdGroupId = createdGroup.id().id();
Prince Pereira3ff504c2016-08-30 14:23:43 +0530363 assertNotEquals(gId1.id().intValue(), createdGroupId);
364 assertNotEquals(gId2.id().intValue(), createdGroupId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800365
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800366 List<GroupOperation> expectedGroupOps = Arrays.asList(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800367 GroupOperation.createDeleteGroupOperation(gId1,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800368 Group.Type.SELECT),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800369 GroupOperation.createAddGroupOperation(
370 createdGroup.id(),
371 Group.Type.SELECT,
372 createdGroup.buckets()));
373 if (deviceId.equals(DID)) {
374 internalProvider.validate(deviceId, expectedGroupOps);
375 } else {
376 this.validate(deviceId, expectedGroupOps);
377 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800378 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800379
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800380 // Test AUDIT process with extraneous groups and missing groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800381 private void testAuditWithExtraneousMissingGroups(DeviceId deviceId) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800382 PortNumber[] ports1 = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800383 PortNumber.portNumber(32)};
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800384 PortNumber[] ports2 = {PortNumber.portNumber(41),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800385 PortNumber.portNumber(42)};
Yi Tsengfa394de2017-02-01 11:26:40 -0800386 GroupId gId1 = new GroupId(1);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800387 Group group1 = createSouthboundGroupEntry(gId1,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800388 Arrays.asList(ports1),
389 0, deviceId);
Yi Tsengfa394de2017-02-01 11:26:40 -0800390 GroupId gId2 = new GroupId(2);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800391 Group group2 = createSouthboundGroupEntry(gId2,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800392 Arrays.asList(ports2),
393 0, deviceId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800394 List<Group> groupEntries = Arrays.asList(group1, group2);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800395 providerService.pushGroupMetrics(deviceId, groupEntries);
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700396 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800397 Group createdGroup = groupService.getGroup(deviceId, key);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800398 List<GroupOperation> expectedGroupOps = Arrays.asList(
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800399 GroupOperation.createDeleteGroupOperation(gId1,
400 Group.Type.SELECT),
401 GroupOperation.createDeleteGroupOperation(gId2,
402 Group.Type.SELECT),
403 GroupOperation.createAddGroupOperation(createdGroup.id(),
404 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800405 createdGroup.buckets()));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800406 if (deviceId.equals(DID)) {
407 internalProvider.validate(deviceId, expectedGroupOps);
408 } else {
409 this.validate(deviceId, expectedGroupOps);
410 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800411 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800412
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800413 // Test AUDIT with confirmed groups
Andrea Campanella6ee73922016-02-03 18:00:00 -0800414 private void testAuditWithConfirmedGroups(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700415 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800416 Group createdGroup = groupService.getGroup(deviceId, key);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800417 createdGroup = new DefaultGroup(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800418 deviceId,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800419 Group.Type.SELECT,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800420 createdGroup.buckets());
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700421 List<Group> groupEntries = Collections.singletonList(createdGroup);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800422 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700423 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADDED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800424 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800425
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800426 // Test group add bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800427 private void testAddBuckets(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700428 GroupKey addKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800429
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700430 GroupKey prevKey = new DefaultGroupKey("group1BeforeAudit".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800431 Group createdGroup = groupService.getGroup(deviceId, prevKey);
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700432 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800433 buckets.addAll(createdGroup.buckets().buckets());
434
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800435 PortNumber[] addPorts = {PortNumber.portNumber(51),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800436 PortNumber.portNumber(52)};
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700437 List<PortNumber> outPorts;
Sho SHIMIZU7a4087b2015-09-10 09:23:16 -0700438 outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800439 outPorts.addAll(Arrays.asList(addPorts));
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700440 List<GroupBucket> addBuckets;
Sho SHIMIZU7a4087b2015-09-10 09:23:16 -0700441 addBuckets = new ArrayList<>();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800442 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800443 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
444 tBuilder.setOutput(portNumber)
445 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
446 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
447 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100448 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800449 addBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800450 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800451 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800452 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800453 }
454 GroupBuckets groupAddBuckets = new GroupBuckets(addBuckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800455 groupService.addBucketsToGroup(deviceId,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800456 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800457 groupAddBuckets,
458 addKey,
459 appId);
460 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700461 List<GroupOperation> expectedGroupOps = Collections.singletonList(
462 GroupOperation.createModifyGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800463 Group.Type.SELECT,
464 updatedBuckets));
465 if (deviceId.equals(DID)) {
466 internalProvider.validate(deviceId, expectedGroupOps);
467 } else {
468 this.validate(deviceId, expectedGroupOps);
469 }
470 Group existingGroup = groupService.getGroup(deviceId, addKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700471 List<Group> groupEntries = Collections.singletonList(existingGroup);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800472 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700473 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800474 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800475
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800476 // Test group remove bucket operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800477 private void testRemoveBuckets(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700478 GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800479
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700480 GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800481 Group createdGroup = groupService.getGroup(deviceId, prevKey);
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700482 List<GroupBucket> buckets = new ArrayList<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800483 buckets.addAll(createdGroup.buckets().buckets());
484
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800485 PortNumber[] removePorts = {PortNumber.portNumber(31),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800486 PortNumber.portNumber(32)};
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700487 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800488 outPorts.addAll(Arrays.asList(removePorts));
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700489 List<GroupBucket> removeBuckets = new ArrayList<>();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800490 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800491 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
492 tBuilder.setOutput(portNumber)
493 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
494 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
495 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100496 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800497 removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800498 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800499 buckets.remove(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800500 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800501 }
502 GroupBuckets groupRemoveBuckets = new GroupBuckets(removeBuckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800503 groupService.removeBucketsFromGroup(deviceId,
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800504 prevKey,
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800505 groupRemoveBuckets,
506 removeKey,
507 appId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800508 GroupBuckets updatedBuckets = new GroupBuckets(buckets);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700509 List<GroupOperation> expectedGroupOps = Collections.singletonList(
510 GroupOperation.createModifyGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800511 Group.Type.SELECT,
512 updatedBuckets));
513 if (deviceId.equals(DID)) {
514 internalProvider.validate(deviceId, expectedGroupOps);
515 } else {
516 this.validate(deviceId, expectedGroupOps);
517 }
518 Group existingGroup = groupService.getGroup(deviceId, removeKey);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700519 List<Group> groupEntries = Collections.singletonList(existingGroup);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800520 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700521 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800522 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800523
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530524 // Test purge group entry operations
525 private void testPurgeGroupEntry(DeviceId deviceId) {
526 assertEquals(1, Iterables.size(groupService.getGroups(deviceId, appId)));
527 groupService.purgeGroupEntries(deviceId);
528 assertEquals(0, Iterables.size(groupService.getGroups(deviceId, appId)));
529 }
530
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800531 // Test group remove operations
Andrea Campanella6ee73922016-02-03 18:00:00 -0800532 private void testRemoveGroup(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700533 GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
Andrea Campanella6ee73922016-02-03 18:00:00 -0800534 Group existingGroup = groupService.getGroup(deviceId, currKey);
535 groupService.removeGroup(deviceId, currKey, appId);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700536 List<GroupOperation> expectedGroupOps = Collections.singletonList(
537 GroupOperation.createDeleteGroupOperation(existingGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800538 Group.Type.SELECT));
539 if (deviceId.equals(DID)) {
540 internalProvider.validate(deviceId, expectedGroupOps);
541 } else {
542 this.validate(deviceId, expectedGroupOps);
543 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800544 List<Group> groupEntries = Collections.emptyList();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800545 providerService.pushGroupMetrics(deviceId, groupEntries);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700546 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVED));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800547 }
548
sangho7ff01812015-02-09 16:21:53 -0800549 /**
550 * Test GroupOperationFailure function in Group Manager.
551 * a)GroupAddFailure
552 * b)GroupUpdateFailure
553 * c)GroupRemoteFailure
554 */
555 @Test
556 public void testGroupOperationFailure() {
Andrea Campanella6ee73922016-02-03 18:00:00 -0800557 groupOperationFaliure(DID);
558 }
559
560 /**
561 * Test GroupOperationFailure function in Group Manager
562 * with fallback provider.
563 * a)GroupAddFailure
564 * b)GroupUpdateFailure
565 * c)GroupRemoteFailure
566 */
567 @Test
568 public void testGroupOperationFailureFallBack() {
569 groupOperationFaliure(FOO_DID);
570 }
571
572 private void groupOperationFaliure(DeviceId deviceId) {
sangho7ff01812015-02-09 16:21:53 -0800573 PortNumber[] ports1 = {PortNumber.portNumber(31),
574 PortNumber.portNumber(32)};
575 PortNumber[] ports2 = {PortNumber.portNumber(41),
576 PortNumber.portNumber(42)};
577 // Test Group creation before AUDIT process
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700578 GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700579 List<GroupBucket> buckets = new ArrayList<>();
580 List<PortNumber> outPorts = new ArrayList<>();
sangho7ff01812015-02-09 16:21:53 -0800581 outPorts.addAll(Arrays.asList(ports1));
582 outPorts.addAll(Arrays.asList(ports2));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800583 for (PortNumber portNumber : outPorts) {
sangho7ff01812015-02-09 16:21:53 -0800584 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
585 tBuilder.setOutput(portNumber)
586 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
587 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
588 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100589 .setMpls(MplsLabel.mplsLabel(106));
sangho7ff01812015-02-09 16:21:53 -0800590 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
591 tBuilder.build()));
592 }
593 GroupBuckets groupBuckets = new GroupBuckets(buckets);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800594 GroupDescription newGroupDesc = new DefaultGroupDescription(deviceId,
595 Group.Type.SELECT,
596 groupBuckets,
597 key,
598 null,
599 appId);
sangho7ff01812015-02-09 16:21:53 -0800600 groupService.addGroup(newGroupDesc);
601
602 // Test initial group audit process
Yi Tsengfa394de2017-02-01 11:26:40 -0800603 GroupId gId1 = new GroupId(1);
sangho7ff01812015-02-09 16:21:53 -0800604 Group group1 = createSouthboundGroupEntry(gId1,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800605 Arrays.asList(ports1),
606 0, deviceId);
Yi Tsengfa394de2017-02-01 11:26:40 -0800607 GroupId gId2 = new GroupId(2);
sangho7ff01812015-02-09 16:21:53 -0800608 // Non zero reference count will make the group manager to queue
609 // the extraneous groups until reference count is zero.
610 Group group2 = createSouthboundGroupEntry(gId2,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800611 Arrays.asList(ports2),
612 2, deviceId);
sangho7ff01812015-02-09 16:21:53 -0800613 List<Group> groupEntries = Arrays.asList(group1, group2);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800614 providerService.pushGroupMetrics(deviceId, groupEntries);
615 Group createdGroup = groupService.getGroup(deviceId, key);
sangho7ff01812015-02-09 16:21:53 -0800616
617 // Group Add failure test
618 GroupOperation groupAddOp = GroupOperation.
619 createAddGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800620 createdGroup.type(),
621 createdGroup.buckets());
622 providerService.groupOperationFailed(deviceId, groupAddOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700623 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADD_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800624
625 // Group Mod failure test
626 groupService.addGroup(newGroupDesc);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800627 createdGroup = groupService.getGroup(deviceId, key);
sangho7ff01812015-02-09 16:21:53 -0800628 assertNotNull(createdGroup);
629
630 GroupOperation groupModOp = GroupOperation.
631 createModifyGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800632 createdGroup.type(),
633 createdGroup.buckets());
634 providerService.groupOperationFailed(deviceId, groupModOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700635 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800636
637 // Group Delete failure test
638 groupService.addGroup(newGroupDesc);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800639 createdGroup = groupService.getGroup(deviceId, key);
sangho7ff01812015-02-09 16:21:53 -0800640 assertNotNull(createdGroup);
641
642 GroupOperation groupDelOp = GroupOperation.
643 createDeleteGroupOperation(createdGroup.id(),
Andrea Campanella6ee73922016-02-03 18:00:00 -0800644 createdGroup.type());
645 providerService.groupOperationFailed(deviceId, groupDelOp);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700646 internalListener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVE_FAILED));
sangho7ff01812015-02-09 16:21:53 -0800647 }
648
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800649 private Group createSouthboundGroupEntry(GroupId gId,
650 List<PortNumber> ports,
Andrea Campanella6ee73922016-02-03 18:00:00 -0800651 long referenceCount, DeviceId deviceId) {
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700652 List<PortNumber> outPorts = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800653 outPorts.addAll(ports);
654
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700655 List<GroupBucket> buckets = new ArrayList<>();
Andrea Campanella6ee73922016-02-03 18:00:00 -0800656 for (PortNumber portNumber : outPorts) {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800657 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
658 tBuilder.setOutput(portNumber)
659 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
660 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
661 .pushMpls()
Michele Santuari4b6019e2014-12-19 11:31:45 +0100662 .setMpls(MplsLabel.mplsLabel(106));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800663 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800664 tBuilder.build()));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800665 }
666 GroupBuckets groupBuckets = new GroupBuckets(buckets);
667 StoredGroupEntry group = new DefaultGroup(
Andrea Campanella6ee73922016-02-03 18:00:00 -0800668 gId, deviceId, Group.Type.SELECT, groupBuckets);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800669 group.setReferenceCount(referenceCount);
670 return group;
671 }
672
673 private static class TestGroupListener implements GroupListener {
674 final List<GroupEvent> events = new ArrayList<>();
675
676 @Override
677 public void event(GroupEvent event) {
678 events.add(event);
679 }
680
681 public void validateEvent(List<GroupEvent.Type> expectedEvents) {
682 int i = 0;
683 System.err.println("events :" + events);
684 for (GroupEvent e : events) {
685 assertEquals("unexpected event", expectedEvents.get(i), e.type());
686 i++;
687 }
688 assertEquals("mispredicted number of events",
689 expectedEvents.size(), events.size());
690 events.clear();
691 }
692 }
693
694 private class TestGroupProvider
Andrea Campanella6ee73922016-02-03 18:00:00 -0800695 extends AbstractProvider implements GroupProvider {
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800696 DeviceId lastDeviceId;
Sho SHIMIZUd88db6f2015-09-09 14:22:06 -0700697 List<GroupOperation> groupOperations = new ArrayList<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800698
699 protected TestGroupProvider(ProviderId id) {
700 super(id);
701 }
702
703 @Override
704 public void performGroupOperation(DeviceId deviceId,
705 GroupOperations groupOps) {
706 lastDeviceId = deviceId;
707 groupOperations.addAll(groupOps.operations());
708 }
709
710 public void validate(DeviceId expectedDeviceId,
711 List<GroupOperation> expectedGroupOps) {
712 if (expectedGroupOps == null) {
713 assertTrue("events generated", groupOperations.isEmpty());
714 return;
715 }
716
717 assertEquals(lastDeviceId, expectedDeviceId);
718 assertTrue((this.groupOperations.containsAll(expectedGroupOps) &&
719 expectedGroupOps.containsAll(groupOperations)));
720
721 groupOperations.clear();
722 lastDeviceId = null;
723 }
724
725 }
726
Andrea Campanella6ee73922016-02-03 18:00:00 -0800727 private static class TestDeviceService extends DeviceServiceAdapter {
728 @Override
729 public int getDeviceCount() {
730 return 1;
731 }
732
733 @Override
734 public Iterable<Device> getDevices() {
735 return ImmutableList.of(FOO_DEV);
736 }
737
738 @Override
739 public Iterable<Device> getAvailableDevices() {
740 return getDevices();
741 }
742
743 @Override
744 public Device getDevice(DeviceId deviceId) {
745 return FOO_DEV;
746 }
747 }
748
749 private class TestDriverManager extends DriverManager {
750 TestDriverManager() {
751 this.deviceService = mgr.deviceService;
752 activate();
753 }
754 }
755
756 private static DeviceId lastDeviceIdProgrammable;
757 private static List<GroupOperation> groupOperations = new ArrayList<>();
758
759 public static class TestGroupProgrammable extends AbstractHandlerBehaviour implements GroupProgrammable {
760 @Override
761 public void performGroupOperation(DeviceId deviceId, GroupOperations groupOps) {
762 lastDeviceIdProgrammable = deviceId;
763 groupOperations.addAll(groupOps.operations());
764 }
765 }
766
767 public void validate(DeviceId expectedDeviceId,
768 List<GroupOperation> expectedGroupOps) {
769 if (expectedGroupOps == null) {
770 assertTrue("events generated", groupOperations.isEmpty());
771 return;
772 }
773
774 assertEquals(lastDeviceIdProgrammable, expectedDeviceId);
Sho SHIMIZU970d6e22016-08-12 15:13:22 -0700775 assertTrue(groupOperations.containsAll(expectedGroupOps) &&
776 expectedGroupOps.containsAll(groupOperations));
Andrea Campanella6ee73922016-02-03 18:00:00 -0800777
778 groupOperations.clear();
779 lastDeviceIdProgrammable = null;
780 }
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800781}
782
783