blob: ca75a20f4115146fd1d9ab365782e6137683b7c3 [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
Brian O'Connor3c58e962015-04-28 23:21:51 -070018import com.google.common.collect.HashMultimap;
19import com.google.common.collect.Lists;
20import com.google.common.collect.Maps;
21import com.google.common.collect.Multimap;
22import com.google.common.collect.Sets;
Brian O'Connor427a1762014-11-19 18:40:32 -080023import org.hamcrest.Description;
Brian O'Connor427a1762014-11-19 18:40:32 -080024import org.hamcrest.TypeSafeMatcher;
25import org.junit.After;
26import org.junit.Before;
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -080027import org.junit.Ignore;
Brian O'Connor427a1762014-11-19 18:40:32 -080028import org.junit.Test;
Brian O'Connorabafb502014-12-02 22:26:20 -080029import org.onosproject.TestApplicationId;
Brian O'Connor3c58e962015-04-28 23:21:51 -070030import org.onosproject.cfg.ComponentConfigAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.core.ApplicationId;
32import org.onosproject.core.impl.TestCoreManager;
Thomas Vachuska36002e62015-05-19 16:12:29 -070033import org.onosproject.common.event.impl.TestEventDispatcher;
Brian O'Connorabafb502014-12-02 22:26:20 -080034import org.onosproject.net.NetworkResource;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080035import org.onosproject.net.intent.FlowRuleIntent;
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.net.intent.Intent;
37import org.onosproject.net.intent.IntentCompiler;
38import org.onosproject.net.intent.IntentEvent;
39import org.onosproject.net.intent.IntentEvent.Type;
40import org.onosproject.net.intent.IntentExtensionService;
41import org.onosproject.net.intent.IntentId;
Brian O'Connorabafb502014-12-02 22:26:20 -080042import org.onosproject.net.intent.IntentListener;
43import org.onosproject.net.intent.IntentService;
44import org.onosproject.net.intent.IntentState;
Ray Milkeyf9af43c2015-02-09 16:45:48 -080045import org.onosproject.net.intent.Key;
Brian O'Connor6de2e202015-05-21 14:30:41 -070046import org.onosproject.net.resource.link.LinkResourceAllocations;
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -080047import org.onosproject.store.trivial.impl.SimpleIntentStore;
Brian O'Connor427a1762014-11-19 18:40:32 -080048
Brian O'Connor3c58e962015-04-28 23:21:51 -070049import java.util.Collection;
50import java.util.Collections;
51import java.util.List;
52import java.util.Map;
53import java.util.Set;
54import java.util.concurrent.CountDownLatch;
55import java.util.concurrent.TimeUnit;
56import java.util.stream.Collectors;
57import java.util.stream.IntStream;
Brian O'Connor427a1762014-11-19 18:40:32 -080058
Ray Milkeye9a3e222014-12-03 16:46:06 -080059import static org.hamcrest.MatcherAssert.assertThat;
60import static org.hamcrest.Matchers.hasSize;
Ray Milkey77a455f2015-03-27 10:08:17 -070061import static org.hamcrest.Matchers.is;
Brian O'Connor3c58e962015-04-28 23:21:51 -070062import static org.junit.Assert.*;
Ray Milkey9f74c082015-02-11 15:40:16 -080063import static org.onlab.junit.TestTools.assertAfter;
Brian O'Connor427a1762014-11-19 18:40:32 -080064import static org.onlab.util.Tools.delay;
Brian O'Connorf0c5a052015-04-27 00:34:53 -070065import static org.onosproject.net.intent.IntentState.*;
Ray Milkey43a28222015-02-23 13:57:58 -080066import static org.onosproject.net.intent.IntentTestsMocks.MockFlowRule;
67import static org.onosproject.net.intent.IntentTestsMocks.MockIntent;
Brian O'Connor427a1762014-11-19 18:40:32 -080068
69/**
70 * Test intent manager and transitions.
71 *
72 * TODO implement the following tests:
73 * - {submit, withdraw, update, replace} intent
Sho SHIMIZU34660962015-01-22 17:58:44 -080074 * - {submit, update, recompiling} intent with failed compilation
Brian O'Connor427a1762014-11-19 18:40:32 -080075 * - failed reservation
76 * - push timeout recovery
77 * - failed items recovery
78 *
79 * in general, verify intents store, flow store, and work queue
80 */
Ray Milkey1c166dc2015-03-02 13:32:39 -080081
Brian O'Connor427a1762014-11-19 18:40:32 -080082public class IntentManagerTest {
83
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -080084 private static final int SUBMIT_TIMEOUT_MS = 1000;
Brian O'Connor427a1762014-11-19 18:40:32 -080085 private static final ApplicationId APPID = new TestApplicationId("manager-test");
86
87 private IntentManager manager;
88 private MockFlowRuleService flowRuleService;
89
90 protected IntentService service;
91 protected IntentExtensionService extensionService;
92 protected TestListener listener = new TestListener();
93 protected TestIntentCompiler compiler = new TestIntentCompiler();
Brian O'Connor427a1762014-11-19 18:40:32 -080094
Ray Milkeye9a3e222014-12-03 16:46:06 -080095 private static class TestListener implements IntentListener {
96 final Multimap<IntentEvent.Type, IntentEvent> events = HashMultimap.create();
97 Map<IntentEvent.Type, CountDownLatch> latchMap = Maps.newHashMap();
98
99 @Override
100 public void event(IntentEvent event) {
101 events.put(event.type(), event);
102 if (latchMap.containsKey(event.type())) {
103 latchMap.get(event.type()).countDown();
104 }
105 }
106
107 public int getCounts(IntentEvent.Type type) {
108 return events.get(type).size();
109 }
110
111 public void setLatch(int count, IntentEvent.Type type) {
112 latchMap.put(type, new CountDownLatch(count));
113 }
114
115 public void await(IntentEvent.Type type) {
116 try {
117 assertTrue("Timed out waiting for: " + type,
118 latchMap.get(type).await(5, TimeUnit.SECONDS));
119 } catch (InterruptedException e) {
120 e.printStackTrace();
121 }
122 }
123 }
124
125 private static class TestIntentTracker implements ObjectiveTrackerService {
126 private TopologyChangeDelegate delegate;
127 @Override
128 public void setDelegate(TopologyChangeDelegate delegate) {
129 this.delegate = delegate;
130 }
131
132 @Override
133 public void unsetDelegate(TopologyChangeDelegate delegate) {
134 if (delegate.equals(this.delegate)) {
135 this.delegate = null;
136 }
137 }
138
139 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800140 public void addTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800141 //TODO
142 }
143
144 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800145 public void removeTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800146 //TODO
147 }
148 }
149
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800150 private static class MockInstallableIntent extends FlowRuleIntent {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800151
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800152 public MockInstallableIntent() {
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700153 super(APPID, Collections.singletonList(new MockFlowRule(100)));
Ray Milkeye9a3e222014-12-03 16:46:06 -0800154 }
155 }
156
157 private static class TestIntentCompiler implements IntentCompiler<MockIntent> {
158 @Override
159 public List<Intent> compile(MockIntent intent, List<Intent> installable,
160 Set<LinkResourceAllocations> resources) {
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800161 return Lists.newArrayList(new MockInstallableIntent());
Ray Milkeye9a3e222014-12-03 16:46:06 -0800162 }
163 }
164
Ray Milkey77a455f2015-03-27 10:08:17 -0700165 private static class TestIntentCompilerMultipleFlows implements IntentCompiler<MockIntent> {
166 @Override
167 public List<Intent> compile(MockIntent intent, List<Intent> installable,
168 Set<LinkResourceAllocations> resources) {
169
170 return IntStream.rangeClosed(1, 5)
171 .mapToObj(mock -> (new MockInstallableIntent()))
172 .collect(Collectors.toList());
173 }
174 }
175
176
Ray Milkeye9a3e222014-12-03 16:46:06 -0800177 private static class TestIntentCompilerError implements IntentCompiler<MockIntent> {
178 @Override
179 public List<Intent> compile(MockIntent intent, List<Intent> installable,
180 Set<LinkResourceAllocations> resources) {
181 throw new IntentCompilationException("Compilation always fails");
182 }
183 }
184
Ray Milkeye9a3e222014-12-03 16:46:06 -0800185 /**
Ray Milkey77a455f2015-03-27 10:08:17 -0700186 * Hamcrest matcher to check that a collection of Intents contains an
Ray Milkeye9a3e222014-12-03 16:46:06 -0800187 * Intent with the specified Intent Id.
188 */
189 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
190 private final IntentId id;
191
192 public EntryForIntentMatcher(IntentId idValue) {
193 id = idValue;
194 }
195
196 @Override
197 public boolean matchesSafely(Collection<Intent> intents) {
198 for (Intent intent : intents) {
199 if (intent.id().equals(id)) {
200 return true;
201 }
202 }
203 return false;
204 }
205
206 @Override
207 public void describeTo(Description description) {
208 description.appendText("an intent with id \" ").
209 appendText(id.toString()).
210 appendText("\"");
211 }
212 }
213
214 private static EntryForIntentMatcher hasIntentWithId(IntentId id) {
215 return new EntryForIntentMatcher(id);
216 }
217
Brian O'Connor427a1762014-11-19 18:40:32 -0800218 @Before
219 public void setUp() {
220 manager = new IntentManager();
221 flowRuleService = new MockFlowRuleService();
222 manager.store = new SimpleIntentStore();
Brian O'Connor427a1762014-11-19 18:40:32 -0800223 manager.eventDispatcher = new TestEventDispatcher();
224 manager.trackerService = new TestIntentTracker();
225 manager.flowRuleService = flowRuleService;
Brian O'Connor520c0522014-11-23 23:50:47 -0800226 manager.coreService = new TestCoreManager();
Brian O'Connor427a1762014-11-19 18:40:32 -0800227 service = manager;
228 extensionService = manager;
229
230 manager.activate();
231 service.addListener(listener);
232 extensionService.registerCompiler(MockIntent.class, compiler);
Brian O'Connor427a1762014-11-19 18:40:32 -0800233
234 assertTrue("store should be empty",
235 Sets.newHashSet(service.getIntents()).isEmpty());
236 assertEquals(0L, flowRuleService.getFlowRuleCount());
237 }
238
Ray Milkey9f74c082015-02-11 15:40:16 -0800239 public void verifyState() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800240 // verify that all intents are parked and the batch operation is unblocked
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700241 Set<IntentState> parked = Sets.newHashSet(INSTALLED, WITHDRAWN, FAILED, CORRUPT);
Brian O'Connor427a1762014-11-19 18:40:32 -0800242 for (Intent i : service.getIntents()) {
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800243 IntentState state = service.getIntentState(i.key());
Brian O'Connor427a1762014-11-19 18:40:32 -0800244 assertTrue("Intent " + i.id() + " is in invalid state " + state,
245 parked.contains(state));
246 }
247 //the batch has not yet been removed when we receive the last event
248 // FIXME: this doesn't guarantee to avoid the race
Brian O'Connorb499b352015-02-03 16:46:15 -0800249
250 //FIXME
251// for (int tries = 0; tries < 10; tries++) {
252// if (manager.batchService.getPendingOperations().isEmpty()) {
253// break;
254// }
255// delay(10);
256// }
257// assertTrue("There are still pending batch operations.",
258// manager.batchService.getPendingOperations().isEmpty());
Brian O'Connor427a1762014-11-19 18:40:32 -0800259
Ray Milkey9f74c082015-02-11 15:40:16 -0800260 }
261
262 @After
263 public void tearDown() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800264 extensionService.unregisterCompiler(MockIntent.class);
Brian O'Connor427a1762014-11-19 18:40:32 -0800265 service.removeListener(listener);
266 manager.deactivate();
267 // TODO null the other refs?
268 }
269
270 @Test
271 public void submitIntent() {
272 flowRuleService.setFuture(true);
273
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800274 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800275 listener.setLatch(1, Type.INSTALLED);
276 Intent intent = new MockIntent(MockIntent.nextId());
277 service.submit(intent);
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800278 listener.await(Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800279 listener.await(Type.INSTALLED);
280 assertEquals(1L, service.getIntentCount());
281 assertEquals(1L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800282 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800283 }
284
285 @Test
286 public void withdrawIntent() {
287 flowRuleService.setFuture(true);
288
289 listener.setLatch(1, Type.INSTALLED);
290 Intent intent = new MockIntent(MockIntent.nextId());
291 service.submit(intent);
292 listener.await(Type.INSTALLED);
293 assertEquals(1L, service.getIntentCount());
294 assertEquals(1L, flowRuleService.getFlowRuleCount());
295
296 listener.setLatch(1, Type.WITHDRAWN);
297 service.withdraw(intent);
298 listener.await(Type.WITHDRAWN);
Brian O'Connor427a1762014-11-19 18:40:32 -0800299 assertEquals(0L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800300 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800301 }
302
303 @Test
Ray Milkey0811bdd2015-03-11 10:21:55 -0700304 @Ignore("This is disabled because we are seeing intermittent failures on Jenkins")
Ray Milkey9f74c082015-02-11 15:40:16 -0800305 public void stressSubmitWithdrawUnique() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800306 flowRuleService.setFuture(true);
307
308 int count = 500;
Ray Milkey9f74c082015-02-11 15:40:16 -0800309 Intent[] intents = new Intent[count];
Brian O'Connor427a1762014-11-19 18:40:32 -0800310
Brian O'Connor427a1762014-11-19 18:40:32 -0800311 listener.setLatch(count, Type.WITHDRAWN);
312
Ray Milkey9f74c082015-02-11 15:40:16 -0800313 for (int i = 0; i < count; i++) {
314 intents[i] = new MockIntent(MockIntent.nextId());
315 service.submit(intents[i]);
316 }
317
318 for (int i = 0; i < count; i++) {
319 service.withdraw(intents[i]);
320 }
321
322 listener.await(Type.WITHDRAWN);
323 assertEquals(0L, flowRuleService.getFlowRuleCount());
324 verifyState();
325 }
326
327 @Test
328 public void stressSubmitWithdrawSame() {
329 flowRuleService.setFuture(true);
330
331 int count = 50;
332
Brian O'Connor427a1762014-11-19 18:40:32 -0800333 Intent intent = new MockIntent(MockIntent.nextId());
334 for (int i = 0; i < count; i++) {
335 service.submit(intent);
336 service.withdraw(intent);
337 }
338
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -0800339 assertAfter(SUBMIT_TIMEOUT_MS, () -> {
Ray Milkey9f74c082015-02-11 15:40:16 -0800340 assertEquals(1L, service.getIntentCount());
341 assertEquals(0L, flowRuleService.getFlowRuleCount());
342 });
343 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800344 }
345
Ray Milkey9f74c082015-02-11 15:40:16 -0800346
Ray Milkey93508c22014-12-02 11:35:56 -0800347 /**
348 * Tests for proper behavior of installation of an intent that triggers
349 * a compilation error.
350 */
351 @Test
352 public void errorIntentCompile() {
353 final TestIntentCompilerError errorCompiler = new TestIntentCompilerError();
354 extensionService.registerCompiler(MockIntent.class, errorCompiler);
355 MockIntent intent = new MockIntent(MockIntent.nextId());
356 listener.setLatch(1, Type.INSTALL_REQ);
357 listener.setLatch(1, Type.FAILED);
358 service.submit(intent);
359 listener.await(Type.INSTALL_REQ);
360 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800361 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800362 }
363
364 /**
365 * Tests handling a future that contains an error as a result of
366 * installing an intent.
367 */
Ray Milkey9f74c082015-02-11 15:40:16 -0800368 @Ignore("skipping until we fix update ordering problem")
Ray Milkey93508c22014-12-02 11:35:56 -0800369 @Test
370 public void errorIntentInstallFromFlows() {
371 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800372 flowRuleService.setFuture(false);
Ray Milkey93508c22014-12-02 11:35:56 -0800373 MockIntent intent = new MockIntent(id);
374 listener.setLatch(1, Type.FAILED);
375 listener.setLatch(1, Type.INSTALL_REQ);
376 service.submit(intent);
377 listener.await(Type.INSTALL_REQ);
Ray Milkey93508c22014-12-02 11:35:56 -0800378 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800379 // FIXME the intent will be moved into INSTALLED immediately which overrides FAILED
380 // ... the updates come out of order
381 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800382 }
383
384 /**
Ray Milkeye9a3e222014-12-03 16:46:06 -0800385 * Tests handling a future that contains an unresolvable error as a result of
386 * installing an intent.
Brian O'Connor427a1762014-11-19 18:40:32 -0800387 */
Ray Milkeye9a3e222014-12-03 16:46:06 -0800388 @Test
389 public void errorIntentInstallNeverTrue() {
390 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800391 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800392 MockIntent intent = new MockIntent(id);
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700393 listener.setLatch(1, Type.CORRUPT);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800394 listener.setLatch(1, Type.INSTALL_REQ);
395 service.submit(intent);
396 listener.await(Type.INSTALL_REQ);
397 // The delay here forces the retry loop in the intent manager to time out
398 delay(100);
Brian O'Connor5811ac22015-02-09 19:17:07 -0800399 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800400 service.withdraw(intent);
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700401 listener.await(Type.CORRUPT);
Ray Milkey9f74c082015-02-11 15:40:16 -0800402 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800403 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800404
Ray Milkeye9a3e222014-12-03 16:46:06 -0800405 /**
406 * Tests that a compiler for a subclass of an intent that already has a
407 * compiler is automatically added.
408 */
409 @Test
410 public void intentSubclassCompile() {
411 class MockIntentSubclass extends MockIntent {
412 public MockIntentSubclass(Long number) {
413 super(number);
414 }
415 }
416 flowRuleService.setFuture(true);
417
418 listener.setLatch(1, Type.INSTALL_REQ);
419 listener.setLatch(1, Type.INSTALLED);
420 Intent intent = new MockIntentSubclass(MockIntent.nextId());
421 service.submit(intent);
422 listener.await(Type.INSTALL_REQ);
423 listener.await(Type.INSTALLED);
424 assertEquals(1L, service.getIntentCount());
425 assertEquals(1L, flowRuleService.getFlowRuleCount());
426
427 final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers =
428 extensionService.getCompilers();
429 assertEquals(2, compilers.size());
430 assertNotNull(compilers.get(MockIntentSubclass.class));
431 assertNotNull(compilers.get(MockIntent.class));
Ray Milkey9f74c082015-02-11 15:40:16 -0800432 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800433 }
434
435 /**
436 * Tests an intent with no compiler.
437 */
438 @Test
439 public void intentWithoutCompiler() {
440 class IntentNoCompiler extends Intent {
441 IntentNoCompiler() {
Ray Milkeyebc5d222015-03-18 15:45:36 -0700442 super(APPID, null, Collections.emptyList(),
443 Intent.DEFAULT_INTENT_PRIORITY);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800444 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800445 }
446
Ray Milkeye9a3e222014-12-03 16:46:06 -0800447 Intent intent = new IntentNoCompiler();
448 listener.setLatch(1, Type.INSTALL_REQ);
449 listener.setLatch(1, Type.FAILED);
450 service.submit(intent);
451 listener.await(Type.INSTALL_REQ);
452 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800453 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800454 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800455
Ray Milkeye9a3e222014-12-03 16:46:06 -0800456 /**
457 * Tests an intent with no installer.
458 */
459 @Test
460 public void intentWithoutInstaller() {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800461 MockIntent intent = new MockIntent(MockIntent.nextId());
462 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700463 listener.setLatch(1, Type.CORRUPT);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800464 service.submit(intent);
465 listener.await(Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700466 listener.await(Type.CORRUPT);
Ray Milkey9f74c082015-02-11 15:40:16 -0800467 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800468 }
469
470 /**
471 * Tests that the intent fetching methods are correct.
472 */
473 @Test
474 public void testIntentFetching() {
475 List<Intent> intents;
476
477 flowRuleService.setFuture(true);
478
479 intents = Lists.newArrayList(service.getIntents());
480 assertThat(intents, hasSize(0));
481
482 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
483 final MockIntent intent2 = new MockIntent(MockIntent.nextId());
484
485 listener.setLatch(2, Type.INSTALL_REQ);
486 listener.setLatch(2, Type.INSTALLED);
487 service.submit(intent1);
488 service.submit(intent2);
489 listener.await(Type.INSTALL_REQ);
490 listener.await(Type.INSTALL_REQ);
491 listener.await(Type.INSTALLED);
492 listener.await(Type.INSTALLED);
493
494 intents = Lists.newArrayList(service.getIntents());
495 assertThat(intents, hasSize(2));
496
497 assertThat(intents, hasIntentWithId(intent1.id()));
498 assertThat(intents, hasIntentWithId(intent2.id()));
Ray Milkey9f74c082015-02-11 15:40:16 -0800499 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800500 }
Ray Milkey77a455f2015-03-27 10:08:17 -0700501
502 /**
503 * Tests that removing all intents results in no flows remaining.
504 */
505 @Test
506 public void testFlowRemoval() {
507 List<Intent> intents;
508
509 flowRuleService.setFuture(true);
510
511 intents = Lists.newArrayList(service.getIntents());
512 assertThat(intents, hasSize(0));
513
514 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
515 final MockIntent intent2 = new MockIntent(MockIntent.nextId());
516
517 listener.setLatch(1, Type.INSTALL_REQ);
518 listener.setLatch(1, Type.INSTALLED);
519
520 service.submit(intent1);
521 listener.await(Type.INSTALL_REQ);
522 listener.await(Type.INSTALLED);
523
524
525 listener.setLatch(1, Type.INSTALL_REQ);
526 listener.setLatch(1, Type.INSTALLED);
527
528 service.submit(intent2);
529 listener.await(Type.INSTALL_REQ);
530 listener.await(Type.INSTALLED);
531
532 assertThat(listener.getCounts(Type.INSTALLED), is(2));
533 assertThat(flowRuleService.getFlowRuleCount(), is(2));
534
535 listener.setLatch(1, Type.WITHDRAWN);
536 service.withdraw(intent1);
537 listener.await(Type.WITHDRAWN);
538
539 listener.setLatch(1, Type.WITHDRAWN);
540 service.withdraw(intent2);
541 listener.await(Type.WITHDRAWN);
542
543 assertThat(listener.getCounts(Type.WITHDRAWN), is(2));
544 assertThat(flowRuleService.getFlowRuleCount(), is(0));
545 }
546
547 /**
Brian O'Connor3c58e962015-04-28 23:21:51 -0700548 * Test failure to install an intent, then succeed on retry via IntentCleanup.
549 */
550 @Test
551 public void testCorruptCleanup() {
552 IntentCleanup cleanup = new IntentCleanup();
553 cleanup.service = manager;
554 cleanup.store = manager.store;
555 cleanup.cfgService = new ComponentConfigAdapter();
556
557 try {
558 cleanup.activate();
559
560 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
561 extensionService.registerCompiler(MockIntent.class, errorCompiler);
562 List<Intent> intents;
563
564 flowRuleService.setFuture(false);
565
566 intents = Lists.newArrayList(service.getIntents());
567 assertThat(intents, hasSize(0));
568
569 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
570
571 listener.setLatch(1, Type.INSTALL_REQ);
572 listener.setLatch(1, Type.CORRUPT);
573 listener.setLatch(1, Type.INSTALLED);
574
575 service.submit(intent1);
576
577 listener.await(Type.INSTALL_REQ);
578 listener.await(Type.CORRUPT);
579
580 flowRuleService.setFuture(true);
581
582 listener.await(Type.INSTALLED);
583
584 assertThat(listener.getCounts(Type.CORRUPT), is(1));
585 assertThat(listener.getCounts(Type.INSTALLED), is(1));
586 assertEquals(INSTALLED, manager.getIntentState(intent1.key()));
587 assertThat(flowRuleService.getFlowRuleCount(), is(5));
588 } finally {
589 cleanup.deactivate();
590 }
591 }
592
593 /**
Brian O'Connoreba4e342015-04-30 22:50:13 -0700594 * Test failure to install an intent, and verify retries.
595 */
596 @Test
597 public void testCorruptRetry() {
598 IntentCleanup cleanup = new IntentCleanup();
599 cleanup.service = manager;
600 cleanup.store = manager.store;
601 cleanup.cfgService = new ComponentConfigAdapter();
602 cleanup.period = 1_000_000;
603 cleanup.retryThreshold = 3;
604
605 try {
606 cleanup.activate();
607
608 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
609 extensionService.registerCompiler(MockIntent.class, errorCompiler);
610 List<Intent> intents;
611
612 flowRuleService.setFuture(false);
613
614 intents = Lists.newArrayList(service.getIntents());
615 assertThat(intents, hasSize(0));
616
617 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
618
619 listener.setLatch(1, Type.INSTALL_REQ);
620 listener.setLatch(cleanup.retryThreshold, Type.CORRUPT);
621 listener.setLatch(1, Type.INSTALLED);
622
623 service.submit(intent1);
624
625 listener.await(Type.INSTALL_REQ);
626 listener.await(Type.CORRUPT);
627 assertEquals(CORRUPT, manager.getIntentState(intent1.key()));
628 assertThat(listener.getCounts(Type.CORRUPT), is(cleanup.retryThreshold));
629
630 } finally {
631 cleanup.deactivate();
632 }
633 }
634
635 /**
Ray Milkey77a455f2015-03-27 10:08:17 -0700636 * Tests that an intent that fails installation results in no flows remaining.
637 */
638 @Test
Brian O'Connor3c58e962015-04-28 23:21:51 -0700639 @Ignore("MockFlowRule numbering issue") //test works if run independently
Ray Milkey77a455f2015-03-27 10:08:17 -0700640 public void testFlowRemovalInstallError() {
641 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
642 extensionService.registerCompiler(MockIntent.class, errorCompiler);
643 List<Intent> intents;
644
645 flowRuleService.setFuture(true);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700646 //FIXME relying on "3" is brittle
Ray Milkey77a455f2015-03-27 10:08:17 -0700647 flowRuleService.setErrorFlow(3);
648
649 intents = Lists.newArrayList(service.getIntents());
650 assertThat(intents, hasSize(0));
651
652 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
653
654 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700655 listener.setLatch(1, Type.CORRUPT);
Ray Milkey77a455f2015-03-27 10:08:17 -0700656
657 service.submit(intent1);
658 listener.await(Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700659 listener.await(Type.CORRUPT);
Ray Milkey77a455f2015-03-27 10:08:17 -0700660
Brian O'Connor3c58e962015-04-28 23:21:51 -0700661 assertThat(listener.getCounts(Type.CORRUPT), is(1));
662 // in this test, there will still be flows abandoned on the data plane
663 //assertThat(flowRuleService.getFlowRuleCount(), is(0));
Ray Milkey77a455f2015-03-27 10:08:17 -0700664 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800665}