blob: 64c963b06a52c06dc48e1ede914ee3a05f8a3bcf [file] [log] [blame]
alshabibab984662014-12-04 18:56:18 -08001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.intent.impl;
Brian O'Connor427a1762014-11-19 18:40:32 -080017
Ray Milkey43a28222015-02-23 13:57:58 -080018import java.util.Collection;
19import java.util.Collections;
20import java.util.List;
21import java.util.Map;
22import java.util.Set;
23import java.util.concurrent.CountDownLatch;
24import java.util.concurrent.TimeUnit;
25
Brian O'Connor427a1762014-11-19 18:40:32 -080026import org.hamcrest.Description;
Brian O'Connor427a1762014-11-19 18:40:32 -080027import org.hamcrest.TypeSafeMatcher;
28import org.junit.After;
29import org.junit.Before;
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -080030import org.junit.Ignore;
Brian O'Connor427a1762014-11-19 18:40:32 -080031import org.junit.Test;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.TestApplicationId;
33import org.onosproject.core.ApplicationId;
34import org.onosproject.core.impl.TestCoreManager;
35import org.onosproject.event.impl.TestEventDispatcher;
36import org.onosproject.net.NetworkResource;
37import org.onosproject.net.flow.FlowRule;
Ray Milkey71ade562015-02-18 15:08:07 -080038import org.onosproject.net.flow.FlowRuleOperation;
Brian O'Connorabafb502014-12-02 22:26:20 -080039import org.onosproject.net.intent.Intent;
40import org.onosproject.net.intent.IntentCompiler;
41import org.onosproject.net.intent.IntentEvent;
42import org.onosproject.net.intent.IntentEvent.Type;
43import org.onosproject.net.intent.IntentExtensionService;
44import org.onosproject.net.intent.IntentId;
45import org.onosproject.net.intent.IntentInstaller;
46import org.onosproject.net.intent.IntentListener;
47import org.onosproject.net.intent.IntentService;
48import org.onosproject.net.intent.IntentState;
Ray Milkeyf9af43c2015-02-09 16:45:48 -080049import org.onosproject.net.intent.Key;
Brian O'Connorabafb502014-12-02 22:26:20 -080050import org.onosproject.net.resource.LinkResourceAllocations;
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -080051import org.onosproject.store.trivial.impl.SimpleIntentStore;
Brian O'Connor427a1762014-11-19 18:40:32 -080052
Ray Milkey43a28222015-02-23 13:57:58 -080053import com.google.common.collect.HashMultimap;
54import com.google.common.collect.ImmutableSet;
55import 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 Milkey43a28222015-02-23 13:57:58 -080062import static org.junit.Assert.assertEquals;
63import static org.junit.Assert.assertNotNull;
64import static org.junit.Assert.assertTrue;
Ray Milkey9f74c082015-02-11 15:40:16 -080065import static org.onlab.junit.TestTools.assertAfter;
Brian O'Connor427a1762014-11-19 18:40:32 -080066import static org.onlab.util.Tools.delay;
Ray Milkey43a28222015-02-23 13:57:58 -080067import static org.onosproject.net.intent.IntentState.FAILED;
68import static org.onosproject.net.intent.IntentState.INSTALLED;
69import static org.onosproject.net.intent.IntentState.WITHDRAWN;
70import static org.onosproject.net.intent.IntentTestsMocks.MockFlowRule;
71import static org.onosproject.net.intent.IntentTestsMocks.MockIntent;
Brian O'Connor427a1762014-11-19 18:40:32 -080072
73/**
74 * Test intent manager and transitions.
75 *
76 * TODO implement the following tests:
77 * - {submit, withdraw, update, replace} intent
Sho SHIMIZU34660962015-01-22 17:58:44 -080078 * - {submit, update, recompiling} intent with failed compilation
Brian O'Connor427a1762014-11-19 18:40:32 -080079 * - failed reservation
80 * - push timeout recovery
81 * - failed items recovery
82 *
83 * in general, verify intents store, flow store, and work queue
84 */
Ray Milkey1c166dc2015-03-02 13:32:39 -080085
Brian O'Connor427a1762014-11-19 18:40:32 -080086public class IntentManagerTest {
87
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -080088 private static final int SUBMIT_TIMEOUT_MS = 1000;
Brian O'Connor427a1762014-11-19 18:40:32 -080089 private static final ApplicationId APPID = new TestApplicationId("manager-test");
90
91 private IntentManager manager;
92 private MockFlowRuleService flowRuleService;
93
94 protected IntentService service;
95 protected IntentExtensionService extensionService;
96 protected TestListener listener = new TestListener();
97 protected TestIntentCompiler compiler = new TestIntentCompiler();
98 protected TestIntentInstaller installer = new TestIntentInstaller();
99
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
Ray Milkeye9a3e222014-12-03 16:46:06 -0800155 private static class MockInstallableIntent extends MockIntent {
156 public MockInstallableIntent(Long number) {
157 super(number);
158 }
159
160 @Override
161 public boolean isInstallable() {
162 return true;
163 }
164 }
165
166 private static class TestIntentCompiler implements IntentCompiler<MockIntent> {
167 @Override
168 public List<Intent> compile(MockIntent intent, List<Intent> installable,
169 Set<LinkResourceAllocations> resources) {
170 return Lists.newArrayList(new MockInstallableIntent(intent.number()));
171 }
172 }
173
174 private static class TestIntentCompilerError implements IntentCompiler<MockIntent> {
175 @Override
176 public List<Intent> compile(MockIntent intent, List<Intent> installable,
177 Set<LinkResourceAllocations> resources) {
178 throw new IntentCompilationException("Compilation always fails");
179 }
180 }
181
182 private static class TestIntentInstaller implements IntentInstaller<MockInstallableIntent> {
183 @Override
Brian O'Connor64a0369d2015-02-20 22:02:59 -0800184 public List<Collection<org.onosproject.net.flow.FlowRuleOperation>> install(MockInstallableIntent intent) {
Ray Milkey43a28222015-02-23 13:57:58 -0800185 FlowRule fr = new MockFlowRule(intent.number().intValue());
Ray Milkey71ade562015-02-18 15:08:07 -0800186 Set<FlowRuleOperation> rules = ImmutableSet.of(
187 new FlowRuleOperation(fr, FlowRuleOperation.Type.ADD));
188 return Lists.newArrayList(ImmutableSet.of(rules));
Ray Milkeye9a3e222014-12-03 16:46:06 -0800189 }
190
191 @Override
Brian O'Connor64a0369d2015-02-20 22:02:59 -0800192 public List<Collection<FlowRuleOperation>> uninstall(MockInstallableIntent intent) {
Ray Milkey43a28222015-02-23 13:57:58 -0800193 FlowRule fr = new MockFlowRule(intent.number().intValue());
Ray Milkey71ade562015-02-18 15:08:07 -0800194 Set<FlowRuleOperation> rules = ImmutableSet.of(
195 new FlowRuleOperation(fr, FlowRuleOperation.Type.REMOVE));
196 return Lists.newArrayList(ImmutableSet.of(rules));
Ray Milkeye9a3e222014-12-03 16:46:06 -0800197 }
198
199 @Override
Brian O'Connor64a0369d2015-02-20 22:02:59 -0800200 public List<Collection<FlowRuleOperation>> replace(MockInstallableIntent oldIntent,
201 MockInstallableIntent newIntent) {
Ray Milkey43a28222015-02-23 13:57:58 -0800202 FlowRule fr = new MockFlowRule(oldIntent.number().intValue());
203 FlowRule fr2 = new MockFlowRule(newIntent.number().intValue());
Ray Milkey71ade562015-02-18 15:08:07 -0800204 Set<FlowRuleOperation> rules = ImmutableSet.of(
205 new FlowRuleOperation(fr, FlowRuleOperation.Type.REMOVE),
206 new FlowRuleOperation(fr2, FlowRuleOperation.Type.ADD));
207 return Lists.newArrayList(ImmutableSet.of(rules));
Ray Milkeye9a3e222014-12-03 16:46:06 -0800208 }
209 }
210
211 private static class TestIntentErrorInstaller implements IntentInstaller<MockInstallableIntent> {
212 @Override
Brian O'Connor64a0369d2015-02-20 22:02:59 -0800213 public List<Collection<FlowRuleOperation>> install(MockInstallableIntent intent) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800214 throw new IntentInstallationException("install() always fails");
215 }
216
217 @Override
Brian O'Connor64a0369d2015-02-20 22:02:59 -0800218 public List<Collection<FlowRuleOperation>> uninstall(MockInstallableIntent intent) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800219 throw new IntentRemovalException("uninstall() always fails");
220 }
221
222 @Override
Brian O'Connor64a0369d2015-02-20 22:02:59 -0800223 public List<Collection<FlowRuleOperation>> replace(MockInstallableIntent oldIntent,
224 MockInstallableIntent newIntent) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800225 throw new IntentInstallationException("replace() always fails");
226 }
227 }
228
229 /**
230 * Hamcrest matcher to check that a conllection of Intents contains an
231 * Intent with the specified Intent Id.
232 */
233 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
234 private final IntentId id;
235
236 public EntryForIntentMatcher(IntentId idValue) {
237 id = idValue;
238 }
239
240 @Override
241 public boolean matchesSafely(Collection<Intent> intents) {
242 for (Intent intent : intents) {
243 if (intent.id().equals(id)) {
244 return true;
245 }
246 }
247 return false;
248 }
249
250 @Override
251 public void describeTo(Description description) {
252 description.appendText("an intent with id \" ").
253 appendText(id.toString()).
254 appendText("\"");
255 }
256 }
257
258 private static EntryForIntentMatcher hasIntentWithId(IntentId id) {
259 return new EntryForIntentMatcher(id);
260 }
261
Brian O'Connor427a1762014-11-19 18:40:32 -0800262 @Before
263 public void setUp() {
264 manager = new IntentManager();
265 flowRuleService = new MockFlowRuleService();
266 manager.store = new SimpleIntentStore();
Brian O'Connor427a1762014-11-19 18:40:32 -0800267 manager.eventDispatcher = new TestEventDispatcher();
268 manager.trackerService = new TestIntentTracker();
269 manager.flowRuleService = flowRuleService;
Brian O'Connor520c0522014-11-23 23:50:47 -0800270 manager.coreService = new TestCoreManager();
Brian O'Connor427a1762014-11-19 18:40:32 -0800271 service = manager;
272 extensionService = manager;
273
274 manager.activate();
275 service.addListener(listener);
276 extensionService.registerCompiler(MockIntent.class, compiler);
277 extensionService.registerInstaller(MockInstallableIntent.class, installer);
278
279 assertTrue("store should be empty",
280 Sets.newHashSet(service.getIntents()).isEmpty());
281 assertEquals(0L, flowRuleService.getFlowRuleCount());
282 }
283
Ray Milkey9f74c082015-02-11 15:40:16 -0800284 public void verifyState() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800285 // verify that all intents are parked and the batch operation is unblocked
286 Set<IntentState> parked = Sets.newHashSet(INSTALLED, WITHDRAWN, FAILED);
287 for (Intent i : service.getIntents()) {
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800288 IntentState state = service.getIntentState(i.key());
Brian O'Connor427a1762014-11-19 18:40:32 -0800289 assertTrue("Intent " + i.id() + " is in invalid state " + state,
290 parked.contains(state));
291 }
292 //the batch has not yet been removed when we receive the last event
293 // FIXME: this doesn't guarantee to avoid the race
Brian O'Connorb499b352015-02-03 16:46:15 -0800294
295 //FIXME
296// for (int tries = 0; tries < 10; tries++) {
297// if (manager.batchService.getPendingOperations().isEmpty()) {
298// break;
299// }
300// delay(10);
301// }
302// assertTrue("There are still pending batch operations.",
303// manager.batchService.getPendingOperations().isEmpty());
Brian O'Connor427a1762014-11-19 18:40:32 -0800304
Ray Milkey9f74c082015-02-11 15:40:16 -0800305 }
306
307 @After
308 public void tearDown() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800309 extensionService.unregisterCompiler(MockIntent.class);
310 extensionService.unregisterInstaller(MockInstallableIntent.class);
311 service.removeListener(listener);
312 manager.deactivate();
313 // TODO null the other refs?
314 }
315
316 @Test
317 public void submitIntent() {
318 flowRuleService.setFuture(true);
319
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800320 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800321 listener.setLatch(1, Type.INSTALLED);
322 Intent intent = new MockIntent(MockIntent.nextId());
323 service.submit(intent);
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800324 listener.await(Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800325 listener.await(Type.INSTALLED);
326 assertEquals(1L, service.getIntentCount());
327 assertEquals(1L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800328 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800329 }
330
331 @Test
332 public void withdrawIntent() {
333 flowRuleService.setFuture(true);
334
335 listener.setLatch(1, Type.INSTALLED);
336 Intent intent = new MockIntent(MockIntent.nextId());
337 service.submit(intent);
338 listener.await(Type.INSTALLED);
339 assertEquals(1L, service.getIntentCount());
340 assertEquals(1L, flowRuleService.getFlowRuleCount());
341
342 listener.setLatch(1, Type.WITHDRAWN);
343 service.withdraw(intent);
344 listener.await(Type.WITHDRAWN);
Brian O'Connor427a1762014-11-19 18:40:32 -0800345 assertEquals(0L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800346 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800347 }
348
349 @Test
Ray Milkey0811bdd2015-03-11 10:21:55 -0700350 @Ignore("This is disabled because we are seeing intermittent failures on Jenkins")
Ray Milkey9f74c082015-02-11 15:40:16 -0800351 public void stressSubmitWithdrawUnique() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800352 flowRuleService.setFuture(true);
353
354 int count = 500;
Ray Milkey9f74c082015-02-11 15:40:16 -0800355 Intent[] intents = new Intent[count];
Brian O'Connor427a1762014-11-19 18:40:32 -0800356
Brian O'Connor427a1762014-11-19 18:40:32 -0800357 listener.setLatch(count, Type.WITHDRAWN);
358
Ray Milkey9f74c082015-02-11 15:40:16 -0800359 for (int i = 0; i < count; i++) {
360 intents[i] = new MockIntent(MockIntent.nextId());
361 service.submit(intents[i]);
362 }
363
364 for (int i = 0; i < count; i++) {
365 service.withdraw(intents[i]);
366 }
367
368 listener.await(Type.WITHDRAWN);
369 assertEquals(0L, flowRuleService.getFlowRuleCount());
370 verifyState();
371 }
372
373 @Test
374 public void stressSubmitWithdrawSame() {
375 flowRuleService.setFuture(true);
376
377 int count = 50;
378
Brian O'Connor427a1762014-11-19 18:40:32 -0800379 Intent intent = new MockIntent(MockIntent.nextId());
380 for (int i = 0; i < count; i++) {
381 service.submit(intent);
382 service.withdraw(intent);
383 }
384
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -0800385 assertAfter(SUBMIT_TIMEOUT_MS, () -> {
Ray Milkey9f74c082015-02-11 15:40:16 -0800386 assertEquals(1L, service.getIntentCount());
387 assertEquals(0L, flowRuleService.getFlowRuleCount());
388 });
389 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800390 }
391
Ray Milkey9f74c082015-02-11 15:40:16 -0800392
Ray Milkey93508c22014-12-02 11:35:56 -0800393 /**
394 * Tests for proper behavior of installation of an intent that triggers
395 * a compilation error.
396 */
397 @Test
398 public void errorIntentCompile() {
399 final TestIntentCompilerError errorCompiler = new TestIntentCompilerError();
400 extensionService.registerCompiler(MockIntent.class, errorCompiler);
401 MockIntent intent = new MockIntent(MockIntent.nextId());
402 listener.setLatch(1, Type.INSTALL_REQ);
403 listener.setLatch(1, Type.FAILED);
404 service.submit(intent);
405 listener.await(Type.INSTALL_REQ);
406 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800407 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800408 }
409
410 /**
411 * Tests handling a future that contains an error as a result of
412 * installing an intent.
413 */
Ray Milkey9f74c082015-02-11 15:40:16 -0800414 @Ignore("skipping until we fix update ordering problem")
Ray Milkey93508c22014-12-02 11:35:56 -0800415 @Test
416 public void errorIntentInstallFromFlows() {
417 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800418 flowRuleService.setFuture(false);
Ray Milkey93508c22014-12-02 11:35:56 -0800419 MockIntent intent = new MockIntent(id);
420 listener.setLatch(1, Type.FAILED);
421 listener.setLatch(1, Type.INSTALL_REQ);
422 service.submit(intent);
423 listener.await(Type.INSTALL_REQ);
Ray Milkey93508c22014-12-02 11:35:56 -0800424 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800425 // FIXME the intent will be moved into INSTALLED immediately which overrides FAILED
426 // ... the updates come out of order
427 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800428 }
429
430 /**
431 * Tests handling of an error that is generated by the intent installer.
432 */
433 @Test
434 public void errorIntentInstallFromInstaller() {
435 final TestIntentErrorInstaller errorInstaller = new TestIntentErrorInstaller();
436 extensionService.registerInstaller(MockInstallableIntent.class, errorInstaller);
437 MockIntent intent = new MockIntent(MockIntent.nextId());
438 listener.setLatch(1, Type.INSTALL_REQ);
439 listener.setLatch(1, Type.FAILED);
440 service.submit(intent);
441 listener.await(Type.INSTALL_REQ);
442 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800443 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800444 }
445
Brian O'Connor427a1762014-11-19 18:40:32 -0800446 /**
Ray Milkeye9a3e222014-12-03 16:46:06 -0800447 * Tests handling a future that contains an unresolvable error as a result of
448 * installing an intent.
Brian O'Connor427a1762014-11-19 18:40:32 -0800449 */
Ray Milkey9f74c082015-02-11 15:40:16 -0800450 @Ignore("test needs to be rewritten, so that the intent is resubmitted")
Ray Milkeye9a3e222014-12-03 16:46:06 -0800451 @Test
452 public void errorIntentInstallNeverTrue() {
453 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800454 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800455 MockIntent intent = new MockIntent(id);
Ray Milkey9f74c082015-02-11 15:40:16 -0800456 listener.setLatch(1, Type.FAILED);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800457 listener.setLatch(1, Type.INSTALL_REQ);
458 service.submit(intent);
459 listener.await(Type.INSTALL_REQ);
460 // The delay here forces the retry loop in the intent manager to time out
461 delay(100);
Brian O'Connor5811ac22015-02-09 19:17:07 -0800462 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800463 service.withdraw(intent);
Ray Milkey9f74c082015-02-11 15:40:16 -0800464 listener.await(Type.FAILED);
465 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800466 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800467
Ray Milkeye9a3e222014-12-03 16:46:06 -0800468 /**
469 * Tests that a compiler for a subclass of an intent that already has a
470 * compiler is automatically added.
471 */
472 @Test
473 public void intentSubclassCompile() {
474 class MockIntentSubclass extends MockIntent {
475 public MockIntentSubclass(Long number) {
476 super(number);
477 }
478 }
479 flowRuleService.setFuture(true);
480
481 listener.setLatch(1, Type.INSTALL_REQ);
482 listener.setLatch(1, Type.INSTALLED);
483 Intent intent = new MockIntentSubclass(MockIntent.nextId());
484 service.submit(intent);
485 listener.await(Type.INSTALL_REQ);
486 listener.await(Type.INSTALLED);
487 assertEquals(1L, service.getIntentCount());
488 assertEquals(1L, flowRuleService.getFlowRuleCount());
489
490 final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers =
491 extensionService.getCompilers();
492 assertEquals(2, compilers.size());
493 assertNotNull(compilers.get(MockIntentSubclass.class));
494 assertNotNull(compilers.get(MockIntent.class));
Ray Milkey9f74c082015-02-11 15:40:16 -0800495 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800496 }
497
498 /**
499 * Tests an intent with no compiler.
500 */
501 @Test
502 public void intentWithoutCompiler() {
503 class IntentNoCompiler extends Intent {
504 IntentNoCompiler() {
Ray Milkeyebc5d222015-03-18 15:45:36 -0700505 super(APPID, null, Collections.emptyList(),
506 Intent.DEFAULT_INTENT_PRIORITY);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800507 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800508 }
509
Ray Milkeye9a3e222014-12-03 16:46:06 -0800510 Intent intent = new IntentNoCompiler();
511 listener.setLatch(1, Type.INSTALL_REQ);
512 listener.setLatch(1, Type.FAILED);
513 service.submit(intent);
514 listener.await(Type.INSTALL_REQ);
515 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800516 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800517 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800518
Ray Milkeye9a3e222014-12-03 16:46:06 -0800519 /**
520 * Tests an intent with no installer.
521 */
522 @Test
523 public void intentWithoutInstaller() {
524
525 extensionService.unregisterInstaller(MockInstallableIntent.class);
526
527 MockIntent intent = new MockIntent(MockIntent.nextId());
528 listener.setLatch(1, Type.INSTALL_REQ);
529 listener.setLatch(1, Type.FAILED);
530 service.submit(intent);
531 listener.await(Type.INSTALL_REQ);
532 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800533 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800534 }
535
536 /**
537 * Tests that the intent fetching methods are correct.
538 */
539 @Test
540 public void testIntentFetching() {
541 List<Intent> intents;
542
543 flowRuleService.setFuture(true);
544
545 intents = Lists.newArrayList(service.getIntents());
546 assertThat(intents, hasSize(0));
547
548 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
549 final MockIntent intent2 = new MockIntent(MockIntent.nextId());
550
551 listener.setLatch(2, Type.INSTALL_REQ);
552 listener.setLatch(2, Type.INSTALLED);
553 service.submit(intent1);
554 service.submit(intent2);
555 listener.await(Type.INSTALL_REQ);
556 listener.await(Type.INSTALL_REQ);
557 listener.await(Type.INSTALLED);
558 listener.await(Type.INSTALLED);
559
560 intents = Lists.newArrayList(service.getIntents());
561 assertThat(intents, hasSize(2));
562
563 assertThat(intents, hasIntentWithId(intent1.id()));
564 assertThat(intents, hasIntentWithId(intent2.id()));
Ray Milkey9f74c082015-02-11 15:40:16 -0800565 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800566 }
567}