blob: 1de8dd755b623a0f8cf03dacd38f8a50731afff4 [file] [log] [blame]
alshabibab984662014-12-04 18:56:18 -08001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
alshabibab984662014-12-04 18:56:18 -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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.intent.impl;
Brian O'Connor427a1762014-11-19 18:40:32 -080017
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080018import java.util.Arrays;
Ray Milkey43a28222015-02-23 13:57:58 -080019import java.util.Collection;
20import java.util.Collections;
21import java.util.List;
22import java.util.Map;
23import java.util.Set;
24import java.util.concurrent.CountDownLatch;
25import java.util.concurrent.TimeUnit;
Ray Milkey77a455f2015-03-27 10:08:17 -070026import java.util.stream.Collectors;
27import java.util.stream.IntStream;
Ray Milkey43a28222015-02-23 13:57:58 -080028
Brian O'Connor427a1762014-11-19 18:40:32 -080029import org.hamcrest.Description;
Brian O'Connor427a1762014-11-19 18:40:32 -080030import org.hamcrest.TypeSafeMatcher;
31import org.junit.After;
32import org.junit.Before;
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -080033import org.junit.Ignore;
Brian O'Connor427a1762014-11-19 18:40:32 -080034import org.junit.Test;
Brian O'Connorabafb502014-12-02 22:26:20 -080035import org.onosproject.TestApplicationId;
36import org.onosproject.core.ApplicationId;
37import org.onosproject.core.impl.TestCoreManager;
38import org.onosproject.event.impl.TestEventDispatcher;
39import org.onosproject.net.NetworkResource;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080040import org.onosproject.net.intent.FlowRuleIntent;
Brian O'Connorabafb502014-12-02 22:26:20 -080041import org.onosproject.net.intent.Intent;
42import org.onosproject.net.intent.IntentCompiler;
43import org.onosproject.net.intent.IntentEvent;
44import org.onosproject.net.intent.IntentEvent.Type;
45import org.onosproject.net.intent.IntentExtensionService;
46import org.onosproject.net.intent.IntentId;
Brian O'Connorabafb502014-12-02 22:26:20 -080047import org.onosproject.net.intent.IntentListener;
48import org.onosproject.net.intent.IntentService;
49import org.onosproject.net.intent.IntentState;
Ray Milkeyf9af43c2015-02-09 16:45:48 -080050import org.onosproject.net.intent.Key;
Brian O'Connorabafb502014-12-02 22:26:20 -080051import org.onosproject.net.resource.LinkResourceAllocations;
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -080052import org.onosproject.store.trivial.impl.SimpleIntentStore;
Brian O'Connor427a1762014-11-19 18:40:32 -080053
Ray Milkey43a28222015-02-23 13:57:58 -080054import com.google.common.collect.HashMultimap;
Ray Milkey43a28222015-02-23 13:57:58 -080055import com.google.common.collect.Lists;
56import com.google.common.collect.Maps;
57import com.google.common.collect.Multimap;
58import com.google.common.collect.Sets;
Brian O'Connor427a1762014-11-19 18:40:32 -080059
Ray Milkeye9a3e222014-12-03 16:46:06 -080060import static org.hamcrest.MatcherAssert.assertThat;
61import static org.hamcrest.Matchers.hasSize;
Ray Milkey77a455f2015-03-27 10:08:17 -070062import static org.hamcrest.Matchers.is;
Ray Milkey43a28222015-02-23 13:57:58 -080063import static org.junit.Assert.assertEquals;
64import static org.junit.Assert.assertNotNull;
65import static org.junit.Assert.assertTrue;
Ray Milkey9f74c082015-02-11 15:40:16 -080066import static org.onlab.junit.TestTools.assertAfter;
Brian O'Connor427a1762014-11-19 18:40:32 -080067import static org.onlab.util.Tools.delay;
Ray Milkey43a28222015-02-23 13:57:58 -080068import static org.onosproject.net.intent.IntentState.FAILED;
69import static org.onosproject.net.intent.IntentState.INSTALLED;
70import static org.onosproject.net.intent.IntentState.WITHDRAWN;
71import static org.onosproject.net.intent.IntentTestsMocks.MockFlowRule;
72import static org.onosproject.net.intent.IntentTestsMocks.MockIntent;
Brian O'Connor427a1762014-11-19 18:40:32 -080073
74/**
75 * Test intent manager and transitions.
76 *
77 * TODO implement the following tests:
78 * - {submit, withdraw, update, replace} intent
Sho SHIMIZU34660962015-01-22 17:58:44 -080079 * - {submit, update, recompiling} intent with failed compilation
Brian O'Connor427a1762014-11-19 18:40:32 -080080 * - failed reservation
81 * - push timeout recovery
82 * - failed items recovery
83 *
84 * in general, verify intents store, flow store, and work queue
85 */
Ray Milkey1c166dc2015-03-02 13:32:39 -080086
Brian O'Connor427a1762014-11-19 18:40:32 -080087public class IntentManagerTest {
88
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -080089 private static final int SUBMIT_TIMEOUT_MS = 1000;
Brian O'Connor427a1762014-11-19 18:40:32 -080090 private static final ApplicationId APPID = new TestApplicationId("manager-test");
91
92 private IntentManager manager;
93 private MockFlowRuleService flowRuleService;
94
95 protected IntentService service;
96 protected IntentExtensionService extensionService;
97 protected TestListener listener = new TestListener();
98 protected TestIntentCompiler compiler = new TestIntentCompiler();
Brian O'Connor427a1762014-11-19 18:40:32 -080099
Ray Milkeye9a3e222014-12-03 16:46:06 -0800100 private static class TestListener implements IntentListener {
101 final Multimap<IntentEvent.Type, IntentEvent> events = HashMultimap.create();
102 Map<IntentEvent.Type, CountDownLatch> latchMap = Maps.newHashMap();
103
104 @Override
105 public void event(IntentEvent event) {
106 events.put(event.type(), event);
107 if (latchMap.containsKey(event.type())) {
108 latchMap.get(event.type()).countDown();
109 }
110 }
111
112 public int getCounts(IntentEvent.Type type) {
113 return events.get(type).size();
114 }
115
116 public void setLatch(int count, IntentEvent.Type type) {
117 latchMap.put(type, new CountDownLatch(count));
118 }
119
120 public void await(IntentEvent.Type type) {
121 try {
122 assertTrue("Timed out waiting for: " + type,
123 latchMap.get(type).await(5, TimeUnit.SECONDS));
124 } catch (InterruptedException e) {
125 e.printStackTrace();
126 }
127 }
128 }
129
130 private static class TestIntentTracker implements ObjectiveTrackerService {
131 private TopologyChangeDelegate delegate;
132 @Override
133 public void setDelegate(TopologyChangeDelegate delegate) {
134 this.delegate = delegate;
135 }
136
137 @Override
138 public void unsetDelegate(TopologyChangeDelegate delegate) {
139 if (delegate.equals(this.delegate)) {
140 this.delegate = null;
141 }
142 }
143
144 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800145 public void addTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800146 //TODO
147 }
148
149 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800150 public void removeTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800151 //TODO
152 }
153 }
154
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800155 private static class MockInstallableIntent extends FlowRuleIntent {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800156
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800157 public MockInstallableIntent() {
158 super(APPID, Arrays.asList(new MockFlowRule(100)));
Ray Milkeye9a3e222014-12-03 16:46:06 -0800159 }
160 }
161
162 private static class TestIntentCompiler implements IntentCompiler<MockIntent> {
163 @Override
164 public List<Intent> compile(MockIntent intent, List<Intent> installable,
165 Set<LinkResourceAllocations> resources) {
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800166 return Lists.newArrayList(new MockInstallableIntent());
Ray Milkeye9a3e222014-12-03 16:46:06 -0800167 }
168 }
169
Ray Milkey77a455f2015-03-27 10:08:17 -0700170 private static class TestIntentCompilerMultipleFlows implements IntentCompiler<MockIntent> {
171 @Override
172 public List<Intent> compile(MockIntent intent, List<Intent> installable,
173 Set<LinkResourceAllocations> resources) {
174
175 return IntStream.rangeClosed(1, 5)
176 .mapToObj(mock -> (new MockInstallableIntent()))
177 .collect(Collectors.toList());
178 }
179 }
180
181
Ray Milkeye9a3e222014-12-03 16:46:06 -0800182 private static class TestIntentCompilerError implements IntentCompiler<MockIntent> {
183 @Override
184 public List<Intent> compile(MockIntent intent, List<Intent> installable,
185 Set<LinkResourceAllocations> resources) {
186 throw new IntentCompilationException("Compilation always fails");
187 }
188 }
189
Ray Milkeye9a3e222014-12-03 16:46:06 -0800190 /**
Ray Milkey77a455f2015-03-27 10:08:17 -0700191 * Hamcrest matcher to check that a collection of Intents contains an
Ray Milkeye9a3e222014-12-03 16:46:06 -0800192 * Intent with the specified Intent Id.
193 */
194 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
195 private final IntentId id;
196
197 public EntryForIntentMatcher(IntentId idValue) {
198 id = idValue;
199 }
200
201 @Override
202 public boolean matchesSafely(Collection<Intent> intents) {
203 for (Intent intent : intents) {
204 if (intent.id().equals(id)) {
205 return true;
206 }
207 }
208 return false;
209 }
210
211 @Override
212 public void describeTo(Description description) {
213 description.appendText("an intent with id \" ").
214 appendText(id.toString()).
215 appendText("\"");
216 }
217 }
218
219 private static EntryForIntentMatcher hasIntentWithId(IntentId id) {
220 return new EntryForIntentMatcher(id);
221 }
222
Brian O'Connor427a1762014-11-19 18:40:32 -0800223 @Before
224 public void setUp() {
225 manager = new IntentManager();
226 flowRuleService = new MockFlowRuleService();
227 manager.store = new SimpleIntentStore();
Brian O'Connor427a1762014-11-19 18:40:32 -0800228 manager.eventDispatcher = new TestEventDispatcher();
229 manager.trackerService = new TestIntentTracker();
230 manager.flowRuleService = flowRuleService;
Brian O'Connor520c0522014-11-23 23:50:47 -0800231 manager.coreService = new TestCoreManager();
Brian O'Connor427a1762014-11-19 18:40:32 -0800232 service = manager;
233 extensionService = manager;
234
235 manager.activate();
236 service.addListener(listener);
237 extensionService.registerCompiler(MockIntent.class, compiler);
Brian O'Connor427a1762014-11-19 18:40:32 -0800238
239 assertTrue("store should be empty",
240 Sets.newHashSet(service.getIntents()).isEmpty());
241 assertEquals(0L, flowRuleService.getFlowRuleCount());
242 }
243
Ray Milkey9f74c082015-02-11 15:40:16 -0800244 public void verifyState() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800245 // verify that all intents are parked and the batch operation is unblocked
246 Set<IntentState> parked = Sets.newHashSet(INSTALLED, WITHDRAWN, FAILED);
247 for (Intent i : service.getIntents()) {
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800248 IntentState state = service.getIntentState(i.key());
Brian O'Connor427a1762014-11-19 18:40:32 -0800249 assertTrue("Intent " + i.id() + " is in invalid state " + state,
250 parked.contains(state));
251 }
252 //the batch has not yet been removed when we receive the last event
253 // FIXME: this doesn't guarantee to avoid the race
Brian O'Connorb499b352015-02-03 16:46:15 -0800254
255 //FIXME
256// for (int tries = 0; tries < 10; tries++) {
257// if (manager.batchService.getPendingOperations().isEmpty()) {
258// break;
259// }
260// delay(10);
261// }
262// assertTrue("There are still pending batch operations.",
263// manager.batchService.getPendingOperations().isEmpty());
Brian O'Connor427a1762014-11-19 18:40:32 -0800264
Ray Milkey9f74c082015-02-11 15:40:16 -0800265 }
266
267 @After
268 public void tearDown() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800269 extensionService.unregisterCompiler(MockIntent.class);
Brian O'Connor427a1762014-11-19 18:40:32 -0800270 service.removeListener(listener);
271 manager.deactivate();
272 // TODO null the other refs?
273 }
274
275 @Test
276 public void submitIntent() {
277 flowRuleService.setFuture(true);
278
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800279 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800280 listener.setLatch(1, Type.INSTALLED);
281 Intent intent = new MockIntent(MockIntent.nextId());
282 service.submit(intent);
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800283 listener.await(Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800284 listener.await(Type.INSTALLED);
285 assertEquals(1L, service.getIntentCount());
286 assertEquals(1L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800287 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800288 }
289
290 @Test
291 public void withdrawIntent() {
292 flowRuleService.setFuture(true);
293
294 listener.setLatch(1, Type.INSTALLED);
295 Intent intent = new MockIntent(MockIntent.nextId());
296 service.submit(intent);
297 listener.await(Type.INSTALLED);
298 assertEquals(1L, service.getIntentCount());
299 assertEquals(1L, flowRuleService.getFlowRuleCount());
300
301 listener.setLatch(1, Type.WITHDRAWN);
302 service.withdraw(intent);
303 listener.await(Type.WITHDRAWN);
Brian O'Connor427a1762014-11-19 18:40:32 -0800304 assertEquals(0L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800305 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800306 }
307
308 @Test
Ray Milkey0811bdd2015-03-11 10:21:55 -0700309 @Ignore("This is disabled because we are seeing intermittent failures on Jenkins")
Ray Milkey9f74c082015-02-11 15:40:16 -0800310 public void stressSubmitWithdrawUnique() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800311 flowRuleService.setFuture(true);
312
313 int count = 500;
Ray Milkey9f74c082015-02-11 15:40:16 -0800314 Intent[] intents = new Intent[count];
Brian O'Connor427a1762014-11-19 18:40:32 -0800315
Brian O'Connor427a1762014-11-19 18:40:32 -0800316 listener.setLatch(count, Type.WITHDRAWN);
317
Ray Milkey9f74c082015-02-11 15:40:16 -0800318 for (int i = 0; i < count; i++) {
319 intents[i] = new MockIntent(MockIntent.nextId());
320 service.submit(intents[i]);
321 }
322
323 for (int i = 0; i < count; i++) {
324 service.withdraw(intents[i]);
325 }
326
327 listener.await(Type.WITHDRAWN);
328 assertEquals(0L, flowRuleService.getFlowRuleCount());
329 verifyState();
330 }
331
332 @Test
333 public void stressSubmitWithdrawSame() {
334 flowRuleService.setFuture(true);
335
336 int count = 50;
337
Brian O'Connor427a1762014-11-19 18:40:32 -0800338 Intent intent = new MockIntent(MockIntent.nextId());
339 for (int i = 0; i < count; i++) {
340 service.submit(intent);
341 service.withdraw(intent);
342 }
343
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -0800344 assertAfter(SUBMIT_TIMEOUT_MS, () -> {
Ray Milkey9f74c082015-02-11 15:40:16 -0800345 assertEquals(1L, service.getIntentCount());
346 assertEquals(0L, flowRuleService.getFlowRuleCount());
347 });
348 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800349 }
350
Ray Milkey9f74c082015-02-11 15:40:16 -0800351
Ray Milkey93508c22014-12-02 11:35:56 -0800352 /**
353 * Tests for proper behavior of installation of an intent that triggers
354 * a compilation error.
355 */
356 @Test
357 public void errorIntentCompile() {
358 final TestIntentCompilerError errorCompiler = new TestIntentCompilerError();
359 extensionService.registerCompiler(MockIntent.class, errorCompiler);
360 MockIntent intent = new MockIntent(MockIntent.nextId());
361 listener.setLatch(1, Type.INSTALL_REQ);
362 listener.setLatch(1, Type.FAILED);
363 service.submit(intent);
364 listener.await(Type.INSTALL_REQ);
365 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800366 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800367 }
368
369 /**
370 * Tests handling a future that contains an error as a result of
371 * installing an intent.
372 */
Ray Milkey9f74c082015-02-11 15:40:16 -0800373 @Ignore("skipping until we fix update ordering problem")
Ray Milkey93508c22014-12-02 11:35:56 -0800374 @Test
375 public void errorIntentInstallFromFlows() {
376 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800377 flowRuleService.setFuture(false);
Ray Milkey93508c22014-12-02 11:35:56 -0800378 MockIntent intent = new MockIntent(id);
379 listener.setLatch(1, Type.FAILED);
380 listener.setLatch(1, Type.INSTALL_REQ);
381 service.submit(intent);
382 listener.await(Type.INSTALL_REQ);
Ray Milkey93508c22014-12-02 11:35:56 -0800383 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800384 // FIXME the intent will be moved into INSTALLED immediately which overrides FAILED
385 // ... the updates come out of order
386 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800387 }
388
389 /**
Ray Milkeye9a3e222014-12-03 16:46:06 -0800390 * Tests handling a future that contains an unresolvable error as a result of
391 * installing an intent.
Brian O'Connor427a1762014-11-19 18:40:32 -0800392 */
Ray Milkeye9a3e222014-12-03 16:46:06 -0800393 @Test
394 public void errorIntentInstallNeverTrue() {
395 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800396 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800397 MockIntent intent = new MockIntent(id);
Ray Milkey9f74c082015-02-11 15:40:16 -0800398 listener.setLatch(1, Type.FAILED);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800399 listener.setLatch(1, Type.INSTALL_REQ);
400 service.submit(intent);
401 listener.await(Type.INSTALL_REQ);
402 // The delay here forces the retry loop in the intent manager to time out
403 delay(100);
Brian O'Connor5811ac22015-02-09 19:17:07 -0800404 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800405 service.withdraw(intent);
Ray Milkey9f74c082015-02-11 15:40:16 -0800406 listener.await(Type.FAILED);
407 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800408 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800409
Ray Milkeye9a3e222014-12-03 16:46:06 -0800410 /**
411 * Tests that a compiler for a subclass of an intent that already has a
412 * compiler is automatically added.
413 */
414 @Test
415 public void intentSubclassCompile() {
416 class MockIntentSubclass extends MockIntent {
417 public MockIntentSubclass(Long number) {
418 super(number);
419 }
420 }
421 flowRuleService.setFuture(true);
422
423 listener.setLatch(1, Type.INSTALL_REQ);
424 listener.setLatch(1, Type.INSTALLED);
425 Intent intent = new MockIntentSubclass(MockIntent.nextId());
426 service.submit(intent);
427 listener.await(Type.INSTALL_REQ);
428 listener.await(Type.INSTALLED);
429 assertEquals(1L, service.getIntentCount());
430 assertEquals(1L, flowRuleService.getFlowRuleCount());
431
432 final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers =
433 extensionService.getCompilers();
434 assertEquals(2, compilers.size());
435 assertNotNull(compilers.get(MockIntentSubclass.class));
436 assertNotNull(compilers.get(MockIntent.class));
Ray Milkey9f74c082015-02-11 15:40:16 -0800437 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800438 }
439
440 /**
441 * Tests an intent with no compiler.
442 */
443 @Test
444 public void intentWithoutCompiler() {
445 class IntentNoCompiler extends Intent {
446 IntentNoCompiler() {
Ray Milkeyebc5d222015-03-18 15:45:36 -0700447 super(APPID, null, Collections.emptyList(),
448 Intent.DEFAULT_INTENT_PRIORITY);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800449 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800450 }
451
Ray Milkeye9a3e222014-12-03 16:46:06 -0800452 Intent intent = new IntentNoCompiler();
453 listener.setLatch(1, Type.INSTALL_REQ);
454 listener.setLatch(1, Type.FAILED);
455 service.submit(intent);
456 listener.await(Type.INSTALL_REQ);
457 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800458 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800459 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800460
Ray Milkeye9a3e222014-12-03 16:46:06 -0800461 /**
462 * Tests an intent with no installer.
463 */
464 @Test
465 public void intentWithoutInstaller() {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800466 MockIntent intent = new MockIntent(MockIntent.nextId());
467 listener.setLatch(1, Type.INSTALL_REQ);
468 listener.setLatch(1, Type.FAILED);
469 service.submit(intent);
470 listener.await(Type.INSTALL_REQ);
471 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800472 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800473 }
474
475 /**
476 * Tests that the intent fetching methods are correct.
477 */
478 @Test
479 public void testIntentFetching() {
480 List<Intent> intents;
481
482 flowRuleService.setFuture(true);
483
484 intents = Lists.newArrayList(service.getIntents());
485 assertThat(intents, hasSize(0));
486
487 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
488 final MockIntent intent2 = new MockIntent(MockIntent.nextId());
489
490 listener.setLatch(2, Type.INSTALL_REQ);
491 listener.setLatch(2, Type.INSTALLED);
492 service.submit(intent1);
493 service.submit(intent2);
494 listener.await(Type.INSTALL_REQ);
495 listener.await(Type.INSTALL_REQ);
496 listener.await(Type.INSTALLED);
497 listener.await(Type.INSTALLED);
498
499 intents = Lists.newArrayList(service.getIntents());
500 assertThat(intents, hasSize(2));
501
502 assertThat(intents, hasIntentWithId(intent1.id()));
503 assertThat(intents, hasIntentWithId(intent2.id()));
Ray Milkey9f74c082015-02-11 15:40:16 -0800504 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800505 }
Ray Milkey77a455f2015-03-27 10:08:17 -0700506
507 /**
508 * Tests that removing all intents results in no flows remaining.
509 */
510 @Test
511 public void testFlowRemoval() {
512 List<Intent> intents;
513
514 flowRuleService.setFuture(true);
515
516 intents = Lists.newArrayList(service.getIntents());
517 assertThat(intents, hasSize(0));
518
519 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
520 final MockIntent intent2 = new MockIntent(MockIntent.nextId());
521
522 listener.setLatch(1, Type.INSTALL_REQ);
523 listener.setLatch(1, Type.INSTALLED);
524
525 service.submit(intent1);
526 listener.await(Type.INSTALL_REQ);
527 listener.await(Type.INSTALLED);
528
529
530 listener.setLatch(1, Type.INSTALL_REQ);
531 listener.setLatch(1, Type.INSTALLED);
532
533 service.submit(intent2);
534 listener.await(Type.INSTALL_REQ);
535 listener.await(Type.INSTALLED);
536
537 assertThat(listener.getCounts(Type.INSTALLED), is(2));
538 assertThat(flowRuleService.getFlowRuleCount(), is(2));
539
540 listener.setLatch(1, Type.WITHDRAWN);
541 service.withdraw(intent1);
542 listener.await(Type.WITHDRAWN);
543
544 listener.setLatch(1, Type.WITHDRAWN);
545 service.withdraw(intent2);
546 listener.await(Type.WITHDRAWN);
547
548 assertThat(listener.getCounts(Type.WITHDRAWN), is(2));
549 assertThat(flowRuleService.getFlowRuleCount(), is(0));
550 }
551
552 /**
553 * Tests that an intent that fails installation results in no flows remaining.
554 */
555 @Test
556 @Ignore("Cleanup state is not yet implemented in the intent manager")
557 public void testFlowRemovalInstallError() {
558 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
559 extensionService.registerCompiler(MockIntent.class, errorCompiler);
560 List<Intent> intents;
561
562 flowRuleService.setFuture(true);
563 flowRuleService.setErrorFlow(3);
564
565 intents = Lists.newArrayList(service.getIntents());
566 assertThat(intents, hasSize(0));
567
568 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
569
570 listener.setLatch(1, Type.INSTALL_REQ);
571 listener.setLatch(1, Type.FAILED);
572
573 service.submit(intent1);
574 listener.await(Type.INSTALL_REQ);
575 listener.await(Type.FAILED);
576
577 assertThat(listener.getCounts(Type.FAILED), is(1));
578 assertThat(flowRuleService.getFlowRuleCount(), is(0));
579 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800580}