blob: 4ddb332bcd0d11ebbf2c04199c426d321e84e87e [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;
Thomas Vachuskac46af202015-06-03 16:43:27 -070031import org.onosproject.common.event.impl.TestEventDispatcher;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.core.ApplicationId;
33import org.onosproject.core.impl.TestCoreManager;
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;
Thomas Vachuskac46af202015-06-03 16:43:27 -070038import org.onosproject.net.intent.IntentData;
Brian O'Connorabafb502014-12-02 22:26:20 -080039import org.onosproject.net.intent.IntentEvent;
40import org.onosproject.net.intent.IntentEvent.Type;
41import org.onosproject.net.intent.IntentExtensionService;
42import org.onosproject.net.intent.IntentId;
Brian O'Connorabafb502014-12-02 22:26:20 -080043import org.onosproject.net.intent.IntentListener;
44import org.onosproject.net.intent.IntentService;
45import org.onosproject.net.intent.IntentState;
Ray Milkeyf9af43c2015-02-09 16:45:48 -080046import org.onosproject.net.intent.Key;
Brian O'Connor6de2e202015-05-21 14:30:41 -070047import org.onosproject.net.resource.link.LinkResourceAllocations;
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -080048import org.onosproject.store.trivial.impl.SimpleIntentStore;
Brian O'Connor427a1762014-11-19 18:40:32 -080049
Brian O'Connor3c58e962015-04-28 23:21:51 -070050import java.util.Collection;
51import java.util.Collections;
52import java.util.List;
53import java.util.Map;
54import java.util.Set;
55import java.util.concurrent.CountDownLatch;
56import java.util.concurrent.TimeUnit;
57import java.util.stream.Collectors;
58import java.util.stream.IntStream;
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;
Brian O'Connor3c58e962015-04-28 23:21:51 -070063import static org.junit.Assert.*;
Ray Milkey9f74c082015-02-11 15:40:16 -080064import static org.onlab.junit.TestTools.assertAfter;
Brian O'Connor427a1762014-11-19 18:40:32 -080065import static org.onlab.util.Tools.delay;
Brian O'Connorf0c5a052015-04-27 00:34:53 -070066import static org.onosproject.net.intent.IntentState.*;
Ray Milkey43a28222015-02-23 13:57:58 -080067import static org.onosproject.net.intent.IntentTestsMocks.MockFlowRule;
68import static org.onosproject.net.intent.IntentTestsMocks.MockIntent;
Brian O'Connor427a1762014-11-19 18:40:32 -080069
70/**
71 * Test intent manager and transitions.
72 *
73 * TODO implement the following tests:
74 * - {submit, withdraw, update, replace} intent
Sho SHIMIZU34660962015-01-22 17:58:44 -080075 * - {submit, update, recompiling} intent with failed compilation
Brian O'Connor427a1762014-11-19 18:40:32 -080076 * - failed reservation
77 * - push timeout recovery
78 * - failed items recovery
79 *
80 * in general, verify intents store, flow store, and work queue
81 */
Ray Milkey1c166dc2015-03-02 13:32:39 -080082
Brian O'Connor427a1762014-11-19 18:40:32 -080083public class IntentManagerTest {
84
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -080085 private static final int SUBMIT_TIMEOUT_MS = 1000;
Brian O'Connor427a1762014-11-19 18:40:32 -080086 private static final ApplicationId APPID = new TestApplicationId("manager-test");
87
88 private IntentManager manager;
89 private MockFlowRuleService flowRuleService;
90
91 protected IntentService service;
92 protected IntentExtensionService extensionService;
93 protected TestListener listener = new TestListener();
94 protected TestIntentCompiler compiler = new TestIntentCompiler();
Brian O'Connor427a1762014-11-19 18:40:32 -080095
Ray Milkeye9a3e222014-12-03 16:46:06 -080096 private static class TestListener implements IntentListener {
97 final Multimap<IntentEvent.Type, IntentEvent> events = HashMultimap.create();
98 Map<IntentEvent.Type, CountDownLatch> latchMap = Maps.newHashMap();
99
100 @Override
101 public void event(IntentEvent event) {
102 events.put(event.type(), event);
103 if (latchMap.containsKey(event.type())) {
104 latchMap.get(event.type()).countDown();
105 }
106 }
107
108 public int getCounts(IntentEvent.Type type) {
109 return events.get(type).size();
110 }
111
112 public void setLatch(int count, IntentEvent.Type type) {
113 latchMap.put(type, new CountDownLatch(count));
114 }
115
116 public void await(IntentEvent.Type type) {
117 try {
118 assertTrue("Timed out waiting for: " + type,
119 latchMap.get(type).await(5, TimeUnit.SECONDS));
120 } catch (InterruptedException e) {
121 e.printStackTrace();
122 }
123 }
124 }
125
126 private static class TestIntentTracker implements ObjectiveTrackerService {
127 private TopologyChangeDelegate delegate;
128 @Override
129 public void setDelegate(TopologyChangeDelegate delegate) {
130 this.delegate = delegate;
131 }
132
133 @Override
134 public void unsetDelegate(TopologyChangeDelegate delegate) {
135 if (delegate.equals(this.delegate)) {
136 this.delegate = null;
137 }
138 }
139
140 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800141 public void addTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800142 //TODO
143 }
144
145 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800146 public void removeTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800147 //TODO
148 }
Thomas Vachuskac46af202015-06-03 16:43:27 -0700149
150 @Override
151 public void trackIntent(IntentData intentData) {
152 //TODO
153 }
Ray Milkeye9a3e222014-12-03 16:46:06 -0800154 }
155
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800156 private static class MockInstallableIntent extends FlowRuleIntent {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800157
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800158 public MockInstallableIntent() {
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700159 super(APPID, Collections.singletonList(new MockFlowRule(100)));
Ray Milkeye9a3e222014-12-03 16:46:06 -0800160 }
161 }
162
163 private static class TestIntentCompiler implements IntentCompiler<MockIntent> {
164 @Override
165 public List<Intent> compile(MockIntent intent, List<Intent> installable,
166 Set<LinkResourceAllocations> resources) {
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800167 return Lists.newArrayList(new MockInstallableIntent());
Ray Milkeye9a3e222014-12-03 16:46:06 -0800168 }
169 }
170
Ray Milkey77a455f2015-03-27 10:08:17 -0700171 private static class TestIntentCompilerMultipleFlows implements IntentCompiler<MockIntent> {
172 @Override
173 public List<Intent> compile(MockIntent intent, List<Intent> installable,
174 Set<LinkResourceAllocations> resources) {
175
176 return IntStream.rangeClosed(1, 5)
177 .mapToObj(mock -> (new MockInstallableIntent()))
178 .collect(Collectors.toList());
179 }
180 }
181
182
Ray Milkeye9a3e222014-12-03 16:46:06 -0800183 private static class TestIntentCompilerError implements IntentCompiler<MockIntent> {
184 @Override
185 public List<Intent> compile(MockIntent intent, List<Intent> installable,
186 Set<LinkResourceAllocations> resources) {
187 throw new IntentCompilationException("Compilation always fails");
188 }
189 }
190
Ray Milkeye9a3e222014-12-03 16:46:06 -0800191 /**
Ray Milkey77a455f2015-03-27 10:08:17 -0700192 * Hamcrest matcher to check that a collection of Intents contains an
Ray Milkeye9a3e222014-12-03 16:46:06 -0800193 * Intent with the specified Intent Id.
194 */
195 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
196 private final IntentId id;
197
198 public EntryForIntentMatcher(IntentId idValue) {
199 id = idValue;
200 }
201
202 @Override
203 public boolean matchesSafely(Collection<Intent> intents) {
204 for (Intent intent : intents) {
205 if (intent.id().equals(id)) {
206 return true;
207 }
208 }
209 return false;
210 }
211
212 @Override
213 public void describeTo(Description description) {
214 description.appendText("an intent with id \" ").
215 appendText(id.toString()).
216 appendText("\"");
217 }
218 }
219
220 private static EntryForIntentMatcher hasIntentWithId(IntentId id) {
221 return new EntryForIntentMatcher(id);
222 }
223
Brian O'Connor427a1762014-11-19 18:40:32 -0800224 @Before
225 public void setUp() {
226 manager = new IntentManager();
227 flowRuleService = new MockFlowRuleService();
228 manager.store = new SimpleIntentStore();
Brian O'Connor427a1762014-11-19 18:40:32 -0800229 manager.eventDispatcher = new TestEventDispatcher();
230 manager.trackerService = new TestIntentTracker();
231 manager.flowRuleService = flowRuleService;
Brian O'Connor520c0522014-11-23 23:50:47 -0800232 manager.coreService = new TestCoreManager();
Brian O'Connor427a1762014-11-19 18:40:32 -0800233 service = manager;
234 extensionService = manager;
235
236 manager.activate();
237 service.addListener(listener);
238 extensionService.registerCompiler(MockIntent.class, compiler);
Brian O'Connor427a1762014-11-19 18:40:32 -0800239
240 assertTrue("store should be empty",
241 Sets.newHashSet(service.getIntents()).isEmpty());
242 assertEquals(0L, flowRuleService.getFlowRuleCount());
243 }
244
Ray Milkey9f74c082015-02-11 15:40:16 -0800245 public void verifyState() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800246 // verify that all intents are parked and the batch operation is unblocked
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700247 Set<IntentState> parked = Sets.newHashSet(INSTALLED, WITHDRAWN, FAILED, CORRUPT);
Brian O'Connor427a1762014-11-19 18:40:32 -0800248 for (Intent i : service.getIntents()) {
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800249 IntentState state = service.getIntentState(i.key());
Brian O'Connor427a1762014-11-19 18:40:32 -0800250 assertTrue("Intent " + i.id() + " is in invalid state " + state,
251 parked.contains(state));
252 }
253 //the batch has not yet been removed when we receive the last event
254 // FIXME: this doesn't guarantee to avoid the race
Brian O'Connorb499b352015-02-03 16:46:15 -0800255
256 //FIXME
257// for (int tries = 0; tries < 10; tries++) {
258// if (manager.batchService.getPendingOperations().isEmpty()) {
259// break;
260// }
261// delay(10);
262// }
263// assertTrue("There are still pending batch operations.",
264// manager.batchService.getPendingOperations().isEmpty());
Brian O'Connor427a1762014-11-19 18:40:32 -0800265
Ray Milkey9f74c082015-02-11 15:40:16 -0800266 }
267
268 @After
269 public void tearDown() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800270 extensionService.unregisterCompiler(MockIntent.class);
Brian O'Connor427a1762014-11-19 18:40:32 -0800271 service.removeListener(listener);
272 manager.deactivate();
273 // TODO null the other refs?
274 }
275
276 @Test
277 public void submitIntent() {
278 flowRuleService.setFuture(true);
279
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800280 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800281 listener.setLatch(1, Type.INSTALLED);
282 Intent intent = new MockIntent(MockIntent.nextId());
283 service.submit(intent);
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800284 listener.await(Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800285 listener.await(Type.INSTALLED);
286 assertEquals(1L, service.getIntentCount());
287 assertEquals(1L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800288 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800289 }
290
291 @Test
292 public void withdrawIntent() {
293 flowRuleService.setFuture(true);
294
295 listener.setLatch(1, Type.INSTALLED);
296 Intent intent = new MockIntent(MockIntent.nextId());
297 service.submit(intent);
298 listener.await(Type.INSTALLED);
299 assertEquals(1L, service.getIntentCount());
300 assertEquals(1L, flowRuleService.getFlowRuleCount());
301
302 listener.setLatch(1, Type.WITHDRAWN);
303 service.withdraw(intent);
304 listener.await(Type.WITHDRAWN);
Brian O'Connor427a1762014-11-19 18:40:32 -0800305 assertEquals(0L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800306 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800307 }
308
309 @Test
Ray Milkey0811bdd2015-03-11 10:21:55 -0700310 @Ignore("This is disabled because we are seeing intermittent failures on Jenkins")
Ray Milkey9f74c082015-02-11 15:40:16 -0800311 public void stressSubmitWithdrawUnique() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800312 flowRuleService.setFuture(true);
313
314 int count = 500;
Ray Milkey9f74c082015-02-11 15:40:16 -0800315 Intent[] intents = new Intent[count];
Brian O'Connor427a1762014-11-19 18:40:32 -0800316
Brian O'Connor427a1762014-11-19 18:40:32 -0800317 listener.setLatch(count, Type.WITHDRAWN);
318
Ray Milkey9f74c082015-02-11 15:40:16 -0800319 for (int i = 0; i < count; i++) {
320 intents[i] = new MockIntent(MockIntent.nextId());
321 service.submit(intents[i]);
322 }
323
324 for (int i = 0; i < count; i++) {
325 service.withdraw(intents[i]);
326 }
327
328 listener.await(Type.WITHDRAWN);
329 assertEquals(0L, flowRuleService.getFlowRuleCount());
330 verifyState();
331 }
332
333 @Test
334 public void stressSubmitWithdrawSame() {
335 flowRuleService.setFuture(true);
336
337 int count = 50;
338
Brian O'Connor427a1762014-11-19 18:40:32 -0800339 Intent intent = new MockIntent(MockIntent.nextId());
340 for (int i = 0; i < count; i++) {
341 service.submit(intent);
342 service.withdraw(intent);
343 }
344
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -0800345 assertAfter(SUBMIT_TIMEOUT_MS, () -> {
Ray Milkey9f74c082015-02-11 15:40:16 -0800346 assertEquals(1L, service.getIntentCount());
347 assertEquals(0L, flowRuleService.getFlowRuleCount());
348 });
349 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800350 }
351
Ray Milkey9f74c082015-02-11 15:40:16 -0800352
Ray Milkey93508c22014-12-02 11:35:56 -0800353 /**
354 * Tests for proper behavior of installation of an intent that triggers
355 * a compilation error.
356 */
357 @Test
358 public void errorIntentCompile() {
359 final TestIntentCompilerError errorCompiler = new TestIntentCompilerError();
360 extensionService.registerCompiler(MockIntent.class, errorCompiler);
361 MockIntent intent = new MockIntent(MockIntent.nextId());
362 listener.setLatch(1, Type.INSTALL_REQ);
363 listener.setLatch(1, Type.FAILED);
364 service.submit(intent);
365 listener.await(Type.INSTALL_REQ);
366 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800367 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800368 }
369
370 /**
371 * Tests handling a future that contains an error as a result of
372 * installing an intent.
373 */
Ray Milkey9f74c082015-02-11 15:40:16 -0800374 @Ignore("skipping until we fix update ordering problem")
Ray Milkey93508c22014-12-02 11:35:56 -0800375 @Test
376 public void errorIntentInstallFromFlows() {
377 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800378 flowRuleService.setFuture(false);
Ray Milkey93508c22014-12-02 11:35:56 -0800379 MockIntent intent = new MockIntent(id);
380 listener.setLatch(1, Type.FAILED);
381 listener.setLatch(1, Type.INSTALL_REQ);
382 service.submit(intent);
383 listener.await(Type.INSTALL_REQ);
Ray Milkey93508c22014-12-02 11:35:56 -0800384 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800385 // FIXME the intent will be moved into INSTALLED immediately which overrides FAILED
386 // ... the updates come out of order
387 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800388 }
389
390 /**
Ray Milkeye9a3e222014-12-03 16:46:06 -0800391 * Tests handling a future that contains an unresolvable error as a result of
392 * installing an intent.
Brian O'Connor427a1762014-11-19 18:40:32 -0800393 */
Ray Milkeye9a3e222014-12-03 16:46:06 -0800394 @Test
395 public void errorIntentInstallNeverTrue() {
396 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800397 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800398 MockIntent intent = new MockIntent(id);
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700399 listener.setLatch(1, Type.CORRUPT);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800400 listener.setLatch(1, Type.INSTALL_REQ);
401 service.submit(intent);
402 listener.await(Type.INSTALL_REQ);
403 // The delay here forces the retry loop in the intent manager to time out
404 delay(100);
Brian O'Connor5811ac22015-02-09 19:17:07 -0800405 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800406 service.withdraw(intent);
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700407 listener.await(Type.CORRUPT);
Ray Milkey9f74c082015-02-11 15:40:16 -0800408 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800409 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800410
Ray Milkeye9a3e222014-12-03 16:46:06 -0800411 /**
412 * Tests that a compiler for a subclass of an intent that already has a
413 * compiler is automatically added.
414 */
415 @Test
416 public void intentSubclassCompile() {
417 class MockIntentSubclass extends MockIntent {
418 public MockIntentSubclass(Long number) {
419 super(number);
420 }
421 }
422 flowRuleService.setFuture(true);
423
424 listener.setLatch(1, Type.INSTALL_REQ);
425 listener.setLatch(1, Type.INSTALLED);
426 Intent intent = new MockIntentSubclass(MockIntent.nextId());
427 service.submit(intent);
428 listener.await(Type.INSTALL_REQ);
429 listener.await(Type.INSTALLED);
430 assertEquals(1L, service.getIntentCount());
431 assertEquals(1L, flowRuleService.getFlowRuleCount());
432
433 final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers =
434 extensionService.getCompilers();
435 assertEquals(2, compilers.size());
436 assertNotNull(compilers.get(MockIntentSubclass.class));
437 assertNotNull(compilers.get(MockIntent.class));
Ray Milkey9f74c082015-02-11 15:40:16 -0800438 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800439 }
440
441 /**
442 * Tests an intent with no compiler.
443 */
444 @Test
445 public void intentWithoutCompiler() {
446 class IntentNoCompiler extends Intent {
447 IntentNoCompiler() {
Ray Milkeyebc5d222015-03-18 15:45:36 -0700448 super(APPID, null, Collections.emptyList(),
449 Intent.DEFAULT_INTENT_PRIORITY);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800450 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800451 }
452
Ray Milkeye9a3e222014-12-03 16:46:06 -0800453 Intent intent = new IntentNoCompiler();
454 listener.setLatch(1, Type.INSTALL_REQ);
455 listener.setLatch(1, Type.FAILED);
456 service.submit(intent);
457 listener.await(Type.INSTALL_REQ);
458 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800459 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800460 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800461
Ray Milkeye9a3e222014-12-03 16:46:06 -0800462 /**
463 * Tests an intent with no installer.
464 */
465 @Test
466 public void intentWithoutInstaller() {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800467 MockIntent intent = new MockIntent(MockIntent.nextId());
468 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700469 listener.setLatch(1, Type.CORRUPT);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800470 service.submit(intent);
471 listener.await(Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700472 listener.await(Type.CORRUPT);
Ray Milkey9f74c082015-02-11 15:40:16 -0800473 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800474 }
475
476 /**
477 * Tests that the intent fetching methods are correct.
478 */
479 @Test
480 public void testIntentFetching() {
481 List<Intent> intents;
482
483 flowRuleService.setFuture(true);
484
485 intents = Lists.newArrayList(service.getIntents());
486 assertThat(intents, hasSize(0));
487
488 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
489 final MockIntent intent2 = new MockIntent(MockIntent.nextId());
490
491 listener.setLatch(2, Type.INSTALL_REQ);
492 listener.setLatch(2, Type.INSTALLED);
493 service.submit(intent1);
494 service.submit(intent2);
495 listener.await(Type.INSTALL_REQ);
496 listener.await(Type.INSTALL_REQ);
497 listener.await(Type.INSTALLED);
498 listener.await(Type.INSTALLED);
499
500 intents = Lists.newArrayList(service.getIntents());
501 assertThat(intents, hasSize(2));
502
503 assertThat(intents, hasIntentWithId(intent1.id()));
504 assertThat(intents, hasIntentWithId(intent2.id()));
Ray Milkey9f74c082015-02-11 15:40:16 -0800505 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800506 }
Ray Milkey77a455f2015-03-27 10:08:17 -0700507
508 /**
509 * Tests that removing all intents results in no flows remaining.
510 */
511 @Test
512 public void testFlowRemoval() {
513 List<Intent> intents;
514
515 flowRuleService.setFuture(true);
516
517 intents = Lists.newArrayList(service.getIntents());
518 assertThat(intents, hasSize(0));
519
520 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
521 final MockIntent intent2 = new MockIntent(MockIntent.nextId());
522
523 listener.setLatch(1, Type.INSTALL_REQ);
524 listener.setLatch(1, Type.INSTALLED);
525
526 service.submit(intent1);
527 listener.await(Type.INSTALL_REQ);
528 listener.await(Type.INSTALLED);
529
530
531 listener.setLatch(1, Type.INSTALL_REQ);
532 listener.setLatch(1, Type.INSTALLED);
533
534 service.submit(intent2);
535 listener.await(Type.INSTALL_REQ);
536 listener.await(Type.INSTALLED);
537
538 assertThat(listener.getCounts(Type.INSTALLED), is(2));
539 assertThat(flowRuleService.getFlowRuleCount(), is(2));
540
541 listener.setLatch(1, Type.WITHDRAWN);
542 service.withdraw(intent1);
543 listener.await(Type.WITHDRAWN);
544
545 listener.setLatch(1, Type.WITHDRAWN);
546 service.withdraw(intent2);
547 listener.await(Type.WITHDRAWN);
548
549 assertThat(listener.getCounts(Type.WITHDRAWN), is(2));
550 assertThat(flowRuleService.getFlowRuleCount(), is(0));
551 }
552
553 /**
Brian O'Connor3c58e962015-04-28 23:21:51 -0700554 * Test failure to install an intent, then succeed on retry via IntentCleanup.
555 */
556 @Test
557 public void testCorruptCleanup() {
558 IntentCleanup cleanup = new IntentCleanup();
559 cleanup.service = manager;
560 cleanup.store = manager.store;
561 cleanup.cfgService = new ComponentConfigAdapter();
562
563 try {
564 cleanup.activate();
565
566 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
567 extensionService.registerCompiler(MockIntent.class, errorCompiler);
568 List<Intent> intents;
569
570 flowRuleService.setFuture(false);
571
572 intents = Lists.newArrayList(service.getIntents());
573 assertThat(intents, hasSize(0));
574
575 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
576
577 listener.setLatch(1, Type.INSTALL_REQ);
578 listener.setLatch(1, Type.CORRUPT);
579 listener.setLatch(1, Type.INSTALLED);
580
581 service.submit(intent1);
582
583 listener.await(Type.INSTALL_REQ);
584 listener.await(Type.CORRUPT);
585
586 flowRuleService.setFuture(true);
587
588 listener.await(Type.INSTALLED);
589
590 assertThat(listener.getCounts(Type.CORRUPT), is(1));
591 assertThat(listener.getCounts(Type.INSTALLED), is(1));
592 assertEquals(INSTALLED, manager.getIntentState(intent1.key()));
593 assertThat(flowRuleService.getFlowRuleCount(), is(5));
594 } finally {
595 cleanup.deactivate();
596 }
597 }
598
599 /**
Brian O'Connoreba4e342015-04-30 22:50:13 -0700600 * Test failure to install an intent, and verify retries.
601 */
602 @Test
603 public void testCorruptRetry() {
604 IntentCleanup cleanup = new IntentCleanup();
605 cleanup.service = manager;
606 cleanup.store = manager.store;
607 cleanup.cfgService = new ComponentConfigAdapter();
608 cleanup.period = 1_000_000;
609 cleanup.retryThreshold = 3;
610
611 try {
612 cleanup.activate();
613
614 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
615 extensionService.registerCompiler(MockIntent.class, errorCompiler);
616 List<Intent> intents;
617
618 flowRuleService.setFuture(false);
619
620 intents = Lists.newArrayList(service.getIntents());
621 assertThat(intents, hasSize(0));
622
623 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
624
625 listener.setLatch(1, Type.INSTALL_REQ);
626 listener.setLatch(cleanup.retryThreshold, Type.CORRUPT);
627 listener.setLatch(1, Type.INSTALLED);
628
629 service.submit(intent1);
630
631 listener.await(Type.INSTALL_REQ);
632 listener.await(Type.CORRUPT);
633 assertEquals(CORRUPT, manager.getIntentState(intent1.key()));
634 assertThat(listener.getCounts(Type.CORRUPT), is(cleanup.retryThreshold));
635
636 } finally {
637 cleanup.deactivate();
638 }
639 }
640
641 /**
Ray Milkey77a455f2015-03-27 10:08:17 -0700642 * Tests that an intent that fails installation results in no flows remaining.
643 */
644 @Test
Brian O'Connor3c58e962015-04-28 23:21:51 -0700645 @Ignore("MockFlowRule numbering issue") //test works if run independently
Ray Milkey77a455f2015-03-27 10:08:17 -0700646 public void testFlowRemovalInstallError() {
647 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
648 extensionService.registerCompiler(MockIntent.class, errorCompiler);
649 List<Intent> intents;
650
651 flowRuleService.setFuture(true);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700652 //FIXME relying on "3" is brittle
Ray Milkey77a455f2015-03-27 10:08:17 -0700653 flowRuleService.setErrorFlow(3);
654
655 intents = Lists.newArrayList(service.getIntents());
656 assertThat(intents, hasSize(0));
657
658 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
659
660 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700661 listener.setLatch(1, Type.CORRUPT);
Ray Milkey77a455f2015-03-27 10:08:17 -0700662
663 service.submit(intent1);
664 listener.await(Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700665 listener.await(Type.CORRUPT);
Ray Milkey77a455f2015-03-27 10:08:17 -0700666
Brian O'Connor3c58e962015-04-28 23:21:51 -0700667 assertThat(listener.getCounts(Type.CORRUPT), is(1));
668 // in this test, there will still be flows abandoned on the data plane
669 //assertThat(flowRuleService.getFlowRuleCount(), is(0));
Ray Milkey77a455f2015-03-27 10:08:17 -0700670 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800671}