blob: 4bf32f43867aefaf170d0ea7a6015285b4f870c1 [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;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070048import org.onosproject.store.trivial.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;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070066import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Brian O'Connorf0c5a052015-04-27 00:34:53 -070067import static org.onosproject.net.intent.IntentState.*;
Ray Milkey43a28222015-02-23 13:57:58 -080068import static org.onosproject.net.intent.IntentTestsMocks.MockFlowRule;
69import static org.onosproject.net.intent.IntentTestsMocks.MockIntent;
Brian O'Connor427a1762014-11-19 18:40:32 -080070
71/**
72 * Test intent manager and transitions.
73 *
74 * TODO implement the following tests:
75 * - {submit, withdraw, update, replace} intent
Sho SHIMIZU34660962015-01-22 17:58:44 -080076 * - {submit, update, recompiling} intent with failed compilation
Brian O'Connor427a1762014-11-19 18:40:32 -080077 * - failed reservation
78 * - push timeout recovery
79 * - failed items recovery
80 *
81 * in general, verify intents store, flow store, and work queue
82 */
Ray Milkey1c166dc2015-03-02 13:32:39 -080083
Brian O'Connor427a1762014-11-19 18:40:32 -080084public class IntentManagerTest {
85
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -080086 private static final int SUBMIT_TIMEOUT_MS = 1000;
Brian O'Connor427a1762014-11-19 18:40:32 -080087 private static final ApplicationId APPID = new TestApplicationId("manager-test");
88
89 private IntentManager manager;
90 private MockFlowRuleService flowRuleService;
91
92 protected IntentService service;
93 protected IntentExtensionService extensionService;
94 protected TestListener listener = new TestListener();
95 protected TestIntentCompiler compiler = new TestIntentCompiler();
Brian O'Connor427a1762014-11-19 18:40:32 -080096
Ray Milkeye9a3e222014-12-03 16:46:06 -080097 private static class TestListener implements IntentListener {
98 final Multimap<IntentEvent.Type, IntentEvent> events = HashMultimap.create();
99 Map<IntentEvent.Type, CountDownLatch> latchMap = Maps.newHashMap();
100
101 @Override
102 public void event(IntentEvent event) {
103 events.put(event.type(), event);
104 if (latchMap.containsKey(event.type())) {
105 latchMap.get(event.type()).countDown();
106 }
107 }
108
109 public int getCounts(IntentEvent.Type type) {
110 return events.get(type).size();
111 }
112
113 public void setLatch(int count, IntentEvent.Type type) {
114 latchMap.put(type, new CountDownLatch(count));
115 }
116
117 public void await(IntentEvent.Type type) {
118 try {
119 assertTrue("Timed out waiting for: " + type,
120 latchMap.get(type).await(5, TimeUnit.SECONDS));
121 } catch (InterruptedException e) {
122 e.printStackTrace();
123 }
124 }
125 }
126
127 private static class TestIntentTracker implements ObjectiveTrackerService {
128 private TopologyChangeDelegate delegate;
129 @Override
130 public void setDelegate(TopologyChangeDelegate delegate) {
131 this.delegate = delegate;
132 }
133
134 @Override
135 public void unsetDelegate(TopologyChangeDelegate delegate) {
136 if (delegate.equals(this.delegate)) {
137 this.delegate = null;
138 }
139 }
140
141 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800142 public void addTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800143 //TODO
144 }
145
146 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800147 public void removeTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800148 //TODO
149 }
Thomas Vachuskac46af202015-06-03 16:43:27 -0700150
151 @Override
152 public void trackIntent(IntentData intentData) {
153 //TODO
154 }
Ray Milkeye9a3e222014-12-03 16:46:06 -0800155 }
156
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800157 private static class MockInstallableIntent extends FlowRuleIntent {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800158
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800159 public MockInstallableIntent() {
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700160 super(APPID, Collections.singletonList(new MockFlowRule(100)));
Ray Milkeye9a3e222014-12-03 16:46:06 -0800161 }
162 }
163
164 private static class TestIntentCompiler implements IntentCompiler<MockIntent> {
165 @Override
166 public List<Intent> compile(MockIntent intent, List<Intent> installable,
167 Set<LinkResourceAllocations> resources) {
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800168 return Lists.newArrayList(new MockInstallableIntent());
Ray Milkeye9a3e222014-12-03 16:46:06 -0800169 }
170 }
171
Ray Milkey77a455f2015-03-27 10:08:17 -0700172 private static class TestIntentCompilerMultipleFlows implements IntentCompiler<MockIntent> {
173 @Override
174 public List<Intent> compile(MockIntent intent, List<Intent> installable,
175 Set<LinkResourceAllocations> resources) {
176
177 return IntStream.rangeClosed(1, 5)
178 .mapToObj(mock -> (new MockInstallableIntent()))
179 .collect(Collectors.toList());
180 }
181 }
182
183
Ray Milkeye9a3e222014-12-03 16:46:06 -0800184 private static class TestIntentCompilerError implements IntentCompiler<MockIntent> {
185 @Override
186 public List<Intent> compile(MockIntent intent, List<Intent> installable,
187 Set<LinkResourceAllocations> resources) {
188 throw new IntentCompilationException("Compilation always fails");
189 }
190 }
191
Ray Milkeye9a3e222014-12-03 16:46:06 -0800192 /**
Ray Milkey77a455f2015-03-27 10:08:17 -0700193 * Hamcrest matcher to check that a collection of Intents contains an
Ray Milkeye9a3e222014-12-03 16:46:06 -0800194 * Intent with the specified Intent Id.
195 */
196 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
197 private final IntentId id;
198
199 public EntryForIntentMatcher(IntentId idValue) {
200 id = idValue;
201 }
202
203 @Override
204 public boolean matchesSafely(Collection<Intent> intents) {
205 for (Intent intent : intents) {
206 if (intent.id().equals(id)) {
207 return true;
208 }
209 }
210 return false;
211 }
212
213 @Override
214 public void describeTo(Description description) {
215 description.appendText("an intent with id \" ").
216 appendText(id.toString()).
217 appendText("\"");
218 }
219 }
220
221 private static EntryForIntentMatcher hasIntentWithId(IntentId id) {
222 return new EntryForIntentMatcher(id);
223 }
224
Brian O'Connor427a1762014-11-19 18:40:32 -0800225 @Before
226 public void setUp() {
227 manager = new IntentManager();
228 flowRuleService = new MockFlowRuleService();
229 manager.store = new SimpleIntentStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700230 injectEventDispatcher(manager, new TestEventDispatcher());
Brian O'Connor427a1762014-11-19 18:40:32 -0800231 manager.trackerService = new TestIntentTracker();
232 manager.flowRuleService = flowRuleService;
Brian O'Connor520c0522014-11-23 23:50:47 -0800233 manager.coreService = new TestCoreManager();
Brian O'Connor427a1762014-11-19 18:40:32 -0800234 service = manager;
235 extensionService = manager;
236
237 manager.activate();
238 service.addListener(listener);
239 extensionService.registerCompiler(MockIntent.class, compiler);
Brian O'Connor427a1762014-11-19 18:40:32 -0800240
241 assertTrue("store should be empty",
242 Sets.newHashSet(service.getIntents()).isEmpty());
243 assertEquals(0L, flowRuleService.getFlowRuleCount());
244 }
245
Ray Milkey9f74c082015-02-11 15:40:16 -0800246 public void verifyState() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800247 // verify that all intents are parked and the batch operation is unblocked
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700248 Set<IntentState> parked = Sets.newHashSet(INSTALLED, WITHDRAWN, FAILED, CORRUPT);
Brian O'Connor427a1762014-11-19 18:40:32 -0800249 for (Intent i : service.getIntents()) {
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800250 IntentState state = service.getIntentState(i.key());
Brian O'Connor427a1762014-11-19 18:40:32 -0800251 assertTrue("Intent " + i.id() + " is in invalid state " + state,
252 parked.contains(state));
253 }
254 //the batch has not yet been removed when we receive the last event
255 // FIXME: this doesn't guarantee to avoid the race
Brian O'Connorb499b352015-02-03 16:46:15 -0800256
257 //FIXME
258// for (int tries = 0; tries < 10; tries++) {
259// if (manager.batchService.getPendingOperations().isEmpty()) {
260// break;
261// }
262// delay(10);
263// }
264// assertTrue("There are still pending batch operations.",
265// manager.batchService.getPendingOperations().isEmpty());
Brian O'Connor427a1762014-11-19 18:40:32 -0800266
Ray Milkey9f74c082015-02-11 15:40:16 -0800267 }
268
269 @After
270 public void tearDown() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800271 extensionService.unregisterCompiler(MockIntent.class);
Brian O'Connor427a1762014-11-19 18:40:32 -0800272 service.removeListener(listener);
273 manager.deactivate();
274 // TODO null the other refs?
275 }
276
277 @Test
278 public void submitIntent() {
279 flowRuleService.setFuture(true);
280
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800281 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800282 listener.setLatch(1, Type.INSTALLED);
283 Intent intent = new MockIntent(MockIntent.nextId());
284 service.submit(intent);
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800285 listener.await(Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800286 listener.await(Type.INSTALLED);
287 assertEquals(1L, service.getIntentCount());
288 assertEquals(1L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800289 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800290 }
291
292 @Test
293 public void withdrawIntent() {
294 flowRuleService.setFuture(true);
295
296 listener.setLatch(1, Type.INSTALLED);
297 Intent intent = new MockIntent(MockIntent.nextId());
298 service.submit(intent);
299 listener.await(Type.INSTALLED);
300 assertEquals(1L, service.getIntentCount());
301 assertEquals(1L, flowRuleService.getFlowRuleCount());
302
303 listener.setLatch(1, Type.WITHDRAWN);
304 service.withdraw(intent);
305 listener.await(Type.WITHDRAWN);
Brian O'Connor427a1762014-11-19 18:40:32 -0800306 assertEquals(0L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800307 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800308 }
309
310 @Test
Ray Milkey0811bdd2015-03-11 10:21:55 -0700311 @Ignore("This is disabled because we are seeing intermittent failures on Jenkins")
Ray Milkey9f74c082015-02-11 15:40:16 -0800312 public void stressSubmitWithdrawUnique() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800313 flowRuleService.setFuture(true);
314
315 int count = 500;
Ray Milkey9f74c082015-02-11 15:40:16 -0800316 Intent[] intents = new Intent[count];
Brian O'Connor427a1762014-11-19 18:40:32 -0800317
Brian O'Connor427a1762014-11-19 18:40:32 -0800318 listener.setLatch(count, Type.WITHDRAWN);
319
Ray Milkey9f74c082015-02-11 15:40:16 -0800320 for (int i = 0; i < count; i++) {
321 intents[i] = new MockIntent(MockIntent.nextId());
322 service.submit(intents[i]);
323 }
324
325 for (int i = 0; i < count; i++) {
326 service.withdraw(intents[i]);
327 }
328
329 listener.await(Type.WITHDRAWN);
330 assertEquals(0L, flowRuleService.getFlowRuleCount());
331 verifyState();
332 }
333
334 @Test
335 public void stressSubmitWithdrawSame() {
336 flowRuleService.setFuture(true);
337
338 int count = 50;
339
Brian O'Connor427a1762014-11-19 18:40:32 -0800340 Intent intent = new MockIntent(MockIntent.nextId());
341 for (int i = 0; i < count; i++) {
342 service.submit(intent);
343 service.withdraw(intent);
344 }
345
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -0800346 assertAfter(SUBMIT_TIMEOUT_MS, () -> {
Ray Milkey9f74c082015-02-11 15:40:16 -0800347 assertEquals(1L, service.getIntentCount());
348 assertEquals(0L, flowRuleService.getFlowRuleCount());
349 });
350 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800351 }
352
Ray Milkey9f74c082015-02-11 15:40:16 -0800353
Ray Milkey93508c22014-12-02 11:35:56 -0800354 /**
355 * Tests for proper behavior of installation of an intent that triggers
356 * a compilation error.
357 */
358 @Test
359 public void errorIntentCompile() {
360 final TestIntentCompilerError errorCompiler = new TestIntentCompilerError();
361 extensionService.registerCompiler(MockIntent.class, errorCompiler);
362 MockIntent intent = new MockIntent(MockIntent.nextId());
363 listener.setLatch(1, Type.INSTALL_REQ);
364 listener.setLatch(1, Type.FAILED);
365 service.submit(intent);
366 listener.await(Type.INSTALL_REQ);
367 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800368 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800369 }
370
371 /**
372 * Tests handling a future that contains an error as a result of
373 * installing an intent.
374 */
Ray Milkey9f74c082015-02-11 15:40:16 -0800375 @Ignore("skipping until we fix update ordering problem")
Ray Milkey93508c22014-12-02 11:35:56 -0800376 @Test
377 public void errorIntentInstallFromFlows() {
378 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800379 flowRuleService.setFuture(false);
Ray Milkey93508c22014-12-02 11:35:56 -0800380 MockIntent intent = new MockIntent(id);
381 listener.setLatch(1, Type.FAILED);
382 listener.setLatch(1, Type.INSTALL_REQ);
383 service.submit(intent);
384 listener.await(Type.INSTALL_REQ);
Ray Milkey93508c22014-12-02 11:35:56 -0800385 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800386 // FIXME the intent will be moved into INSTALLED immediately which overrides FAILED
387 // ... the updates come out of order
388 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800389 }
390
391 /**
Ray Milkeye9a3e222014-12-03 16:46:06 -0800392 * Tests handling a future that contains an unresolvable error as a result of
393 * installing an intent.
Brian O'Connor427a1762014-11-19 18:40:32 -0800394 */
Ray Milkeye9a3e222014-12-03 16:46:06 -0800395 @Test
396 public void errorIntentInstallNeverTrue() {
397 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800398 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800399 MockIntent intent = new MockIntent(id);
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700400 listener.setLatch(1, Type.CORRUPT);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800401 listener.setLatch(1, Type.INSTALL_REQ);
402 service.submit(intent);
403 listener.await(Type.INSTALL_REQ);
404 // The delay here forces the retry loop in the intent manager to time out
405 delay(100);
Brian O'Connor5811ac22015-02-09 19:17:07 -0800406 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800407 service.withdraw(intent);
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700408 listener.await(Type.CORRUPT);
Ray Milkey9f74c082015-02-11 15:40:16 -0800409 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800410 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800411
Ray Milkeye9a3e222014-12-03 16:46:06 -0800412 /**
413 * Tests that a compiler for a subclass of an intent that already has a
414 * compiler is automatically added.
415 */
416 @Test
417 public void intentSubclassCompile() {
418 class MockIntentSubclass extends MockIntent {
419 public MockIntentSubclass(Long number) {
420 super(number);
421 }
422 }
423 flowRuleService.setFuture(true);
424
425 listener.setLatch(1, Type.INSTALL_REQ);
426 listener.setLatch(1, Type.INSTALLED);
427 Intent intent = new MockIntentSubclass(MockIntent.nextId());
428 service.submit(intent);
429 listener.await(Type.INSTALL_REQ);
430 listener.await(Type.INSTALLED);
431 assertEquals(1L, service.getIntentCount());
432 assertEquals(1L, flowRuleService.getFlowRuleCount());
433
434 final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers =
435 extensionService.getCompilers();
436 assertEquals(2, compilers.size());
437 assertNotNull(compilers.get(MockIntentSubclass.class));
438 assertNotNull(compilers.get(MockIntent.class));
Ray Milkey9f74c082015-02-11 15:40:16 -0800439 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800440 }
441
442 /**
443 * Tests an intent with no compiler.
444 */
445 @Test
446 public void intentWithoutCompiler() {
447 class IntentNoCompiler extends Intent {
448 IntentNoCompiler() {
Ray Milkeyebc5d222015-03-18 15:45:36 -0700449 super(APPID, null, Collections.emptyList(),
450 Intent.DEFAULT_INTENT_PRIORITY);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800451 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800452 }
453
Ray Milkeye9a3e222014-12-03 16:46:06 -0800454 Intent intent = new IntentNoCompiler();
455 listener.setLatch(1, Type.INSTALL_REQ);
456 listener.setLatch(1, Type.FAILED);
457 service.submit(intent);
458 listener.await(Type.INSTALL_REQ);
459 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800460 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800461 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800462
Ray Milkeye9a3e222014-12-03 16:46:06 -0800463 /**
464 * Tests an intent with no installer.
465 */
466 @Test
467 public void intentWithoutInstaller() {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800468 MockIntent intent = new MockIntent(MockIntent.nextId());
469 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700470 listener.setLatch(1, Type.CORRUPT);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800471 service.submit(intent);
472 listener.await(Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700473 listener.await(Type.CORRUPT);
Ray Milkey9f74c082015-02-11 15:40:16 -0800474 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800475 }
476
477 /**
478 * Tests that the intent fetching methods are correct.
479 */
480 @Test
481 public void testIntentFetching() {
482 List<Intent> intents;
483
484 flowRuleService.setFuture(true);
485
486 intents = Lists.newArrayList(service.getIntents());
487 assertThat(intents, hasSize(0));
488
489 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
490 final MockIntent intent2 = new MockIntent(MockIntent.nextId());
491
492 listener.setLatch(2, Type.INSTALL_REQ);
493 listener.setLatch(2, Type.INSTALLED);
494 service.submit(intent1);
495 service.submit(intent2);
496 listener.await(Type.INSTALL_REQ);
497 listener.await(Type.INSTALL_REQ);
498 listener.await(Type.INSTALLED);
499 listener.await(Type.INSTALLED);
500
501 intents = Lists.newArrayList(service.getIntents());
502 assertThat(intents, hasSize(2));
503
504 assertThat(intents, hasIntentWithId(intent1.id()));
505 assertThat(intents, hasIntentWithId(intent2.id()));
Ray Milkey9f74c082015-02-11 15:40:16 -0800506 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800507 }
Ray Milkey77a455f2015-03-27 10:08:17 -0700508
509 /**
510 * Tests that removing all intents results in no flows remaining.
511 */
512 @Test
513 public void testFlowRemoval() {
514 List<Intent> intents;
515
516 flowRuleService.setFuture(true);
517
518 intents = Lists.newArrayList(service.getIntents());
519 assertThat(intents, hasSize(0));
520
521 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
522 final MockIntent intent2 = new MockIntent(MockIntent.nextId());
523
524 listener.setLatch(1, Type.INSTALL_REQ);
525 listener.setLatch(1, Type.INSTALLED);
526
527 service.submit(intent1);
528 listener.await(Type.INSTALL_REQ);
529 listener.await(Type.INSTALLED);
530
531
532 listener.setLatch(1, Type.INSTALL_REQ);
533 listener.setLatch(1, Type.INSTALLED);
534
535 service.submit(intent2);
536 listener.await(Type.INSTALL_REQ);
537 listener.await(Type.INSTALLED);
538
539 assertThat(listener.getCounts(Type.INSTALLED), is(2));
540 assertThat(flowRuleService.getFlowRuleCount(), is(2));
541
542 listener.setLatch(1, Type.WITHDRAWN);
543 service.withdraw(intent1);
544 listener.await(Type.WITHDRAWN);
545
546 listener.setLatch(1, Type.WITHDRAWN);
547 service.withdraw(intent2);
548 listener.await(Type.WITHDRAWN);
549
550 assertThat(listener.getCounts(Type.WITHDRAWN), is(2));
551 assertThat(flowRuleService.getFlowRuleCount(), is(0));
552 }
553
554 /**
Brian O'Connor3c58e962015-04-28 23:21:51 -0700555 * Test failure to install an intent, then succeed on retry via IntentCleanup.
556 */
557 @Test
558 public void testCorruptCleanup() {
559 IntentCleanup cleanup = new IntentCleanup();
560 cleanup.service = manager;
561 cleanup.store = manager.store;
562 cleanup.cfgService = new ComponentConfigAdapter();
563
564 try {
565 cleanup.activate();
566
567 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
568 extensionService.registerCompiler(MockIntent.class, errorCompiler);
569 List<Intent> intents;
570
571 flowRuleService.setFuture(false);
572
573 intents = Lists.newArrayList(service.getIntents());
574 assertThat(intents, hasSize(0));
575
576 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
577
578 listener.setLatch(1, Type.INSTALL_REQ);
579 listener.setLatch(1, Type.CORRUPT);
580 listener.setLatch(1, Type.INSTALLED);
581
582 service.submit(intent1);
583
584 listener.await(Type.INSTALL_REQ);
585 listener.await(Type.CORRUPT);
586
587 flowRuleService.setFuture(true);
588
589 listener.await(Type.INSTALLED);
590
591 assertThat(listener.getCounts(Type.CORRUPT), is(1));
592 assertThat(listener.getCounts(Type.INSTALLED), is(1));
593 assertEquals(INSTALLED, manager.getIntentState(intent1.key()));
594 assertThat(flowRuleService.getFlowRuleCount(), is(5));
595 } finally {
596 cleanup.deactivate();
597 }
598 }
599
600 /**
Brian O'Connoreba4e342015-04-30 22:50:13 -0700601 * Test failure to install an intent, and verify retries.
602 */
603 @Test
604 public void testCorruptRetry() {
605 IntentCleanup cleanup = new IntentCleanup();
606 cleanup.service = manager;
607 cleanup.store = manager.store;
608 cleanup.cfgService = new ComponentConfigAdapter();
609 cleanup.period = 1_000_000;
610 cleanup.retryThreshold = 3;
611
612 try {
613 cleanup.activate();
614
615 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
616 extensionService.registerCompiler(MockIntent.class, errorCompiler);
617 List<Intent> intents;
618
619 flowRuleService.setFuture(false);
620
621 intents = Lists.newArrayList(service.getIntents());
622 assertThat(intents, hasSize(0));
623
624 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
625
626 listener.setLatch(1, Type.INSTALL_REQ);
627 listener.setLatch(cleanup.retryThreshold, Type.CORRUPT);
628 listener.setLatch(1, Type.INSTALLED);
629
630 service.submit(intent1);
631
632 listener.await(Type.INSTALL_REQ);
633 listener.await(Type.CORRUPT);
634 assertEquals(CORRUPT, manager.getIntentState(intent1.key()));
635 assertThat(listener.getCounts(Type.CORRUPT), is(cleanup.retryThreshold));
636
637 } finally {
638 cleanup.deactivate();
639 }
640 }
641
642 /**
Ray Milkey77a455f2015-03-27 10:08:17 -0700643 * Tests that an intent that fails installation results in no flows remaining.
644 */
645 @Test
Brian O'Connor3c58e962015-04-28 23:21:51 -0700646 @Ignore("MockFlowRule numbering issue") //test works if run independently
Ray Milkey77a455f2015-03-27 10:08:17 -0700647 public void testFlowRemovalInstallError() {
648 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
649 extensionService.registerCompiler(MockIntent.class, errorCompiler);
650 List<Intent> intents;
651
652 flowRuleService.setFuture(true);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700653 //FIXME relying on "3" is brittle
Ray Milkey77a455f2015-03-27 10:08:17 -0700654 flowRuleService.setErrorFlow(3);
655
656 intents = Lists.newArrayList(service.getIntents());
657 assertThat(intents, hasSize(0));
658
659 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
660
661 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700662 listener.setLatch(1, Type.CORRUPT);
Ray Milkey77a455f2015-03-27 10:08:17 -0700663
664 service.submit(intent1);
665 listener.await(Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700666 listener.await(Type.CORRUPT);
Ray Milkey77a455f2015-03-27 10:08:17 -0700667
Brian O'Connor3c58e962015-04-28 23:21:51 -0700668 assertThat(listener.getCounts(Type.CORRUPT), is(1));
669 // in this test, there will still be flows abandoned on the data plane
670 //assertThat(flowRuleService.getFlowRuleCount(), is(0));
Ray Milkey77a455f2015-03-27 10:08:17 -0700671 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800672}