blob: d0478837a5f77758391da49beec1a0c221affe28 [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;
Sho SHIMIZUd5bf1062016-02-25 10:26:02 -080031import org.onosproject.cfg.ComponentConfigService;
Thomas Vachuskac46af202015-06-03 16:43:27 -070032import org.onosproject.common.event.impl.TestEventDispatcher;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.core.ApplicationId;
34import org.onosproject.core.impl.TestCoreManager;
Brian O'Connorabafb502014-12-02 22:26:20 -080035import org.onosproject.net.NetworkResource;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080036import org.onosproject.net.intent.FlowRuleIntent;
Brian O'Connorabafb502014-12-02 22:26:20 -080037import org.onosproject.net.intent.Intent;
38import org.onosproject.net.intent.IntentCompiler;
Thomas Vachuskac46af202015-06-03 16:43:27 -070039import org.onosproject.net.intent.IntentData;
Brian O'Connorabafb502014-12-02 22:26:20 -080040import org.onosproject.net.intent.IntentEvent;
41import org.onosproject.net.intent.IntentEvent.Type;
42import org.onosproject.net.intent.IntentExtensionService;
43import org.onosproject.net.intent.IntentId;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.net.intent.IntentListener;
45import org.onosproject.net.intent.IntentService;
46import org.onosproject.net.intent.IntentState;
Ray Milkeyf9af43c2015-02-09 16:45:48 -080047import org.onosproject.net.intent.Key;
Brian O'Connor6de2e202015-05-21 14:30:41 -070048import org.onosproject.net.resource.link.LinkResourceAllocations;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070049import org.onosproject.store.trivial.SimpleIntentStore;
Brian O'Connor427a1762014-11-19 18:40:32 -080050
Brian O'Connor3c58e962015-04-28 23:21:51 -070051import java.util.Collection;
52import java.util.Collections;
53import java.util.List;
54import java.util.Map;
55import java.util.Set;
56import java.util.concurrent.CountDownLatch;
57import java.util.concurrent.TimeUnit;
58import java.util.stream.Collectors;
59import java.util.stream.IntStream;
Brian O'Connor427a1762014-11-19 18:40:32 -080060
Sho SHIMIZUd5bf1062016-02-25 10:26:02 -080061import static org.easymock.EasyMock.mock;
Ray Milkeye9a3e222014-12-03 16:46:06 -080062import static org.hamcrest.MatcherAssert.assertThat;
63import static org.hamcrest.Matchers.hasSize;
Ray Milkey77a455f2015-03-27 10:08:17 -070064import static org.hamcrest.Matchers.is;
Brian O'Connor3c58e962015-04-28 23:21:51 -070065import static org.junit.Assert.*;
Ray Milkey9f74c082015-02-11 15:40:16 -080066import static org.onlab.junit.TestTools.assertAfter;
Brian O'Connor427a1762014-11-19 18:40:32 -080067import static org.onlab.util.Tools.delay;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070068import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Brian O'Connorf0c5a052015-04-27 00:34:53 -070069import static org.onosproject.net.intent.IntentState.*;
Ray Milkey43a28222015-02-23 13:57:58 -080070import 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();
Brian O'Connor427a1762014-11-19 18:40:32 -080098
Ray Milkeye9a3e222014-12-03 16:46:06 -080099 private static class TestListener implements IntentListener {
100 final Multimap<IntentEvent.Type, IntentEvent> events = HashMultimap.create();
101 Map<IntentEvent.Type, CountDownLatch> latchMap = Maps.newHashMap();
102
103 @Override
104 public void event(IntentEvent event) {
105 events.put(event.type(), event);
106 if (latchMap.containsKey(event.type())) {
107 latchMap.get(event.type()).countDown();
108 }
109 }
110
111 public int getCounts(IntentEvent.Type type) {
112 return events.get(type).size();
113 }
114
115 public void setLatch(int count, IntentEvent.Type type) {
116 latchMap.put(type, new CountDownLatch(count));
117 }
118
119 public void await(IntentEvent.Type type) {
120 try {
121 assertTrue("Timed out waiting for: " + type,
122 latchMap.get(type).await(5, TimeUnit.SECONDS));
123 } catch (InterruptedException e) {
124 e.printStackTrace();
125 }
126 }
127 }
128
129 private static class TestIntentTracker implements ObjectiveTrackerService {
130 private TopologyChangeDelegate delegate;
131 @Override
132 public void setDelegate(TopologyChangeDelegate delegate) {
133 this.delegate = delegate;
134 }
135
136 @Override
137 public void unsetDelegate(TopologyChangeDelegate delegate) {
138 if (delegate.equals(this.delegate)) {
139 this.delegate = null;
140 }
141 }
142
143 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800144 public void addTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800145 //TODO
146 }
147
148 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800149 public void removeTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800150 //TODO
151 }
Thomas Vachuskac46af202015-06-03 16:43:27 -0700152
153 @Override
154 public void trackIntent(IntentData intentData) {
155 //TODO
156 }
Ray Milkeye9a3e222014-12-03 16:46:06 -0800157 }
158
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800159 private static class MockInstallableIntent extends FlowRuleIntent {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800160
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800161 public MockInstallableIntent() {
Sho SHIMIZUc3cf5bc2015-09-24 14:46:40 -0700162 super(APPID, Collections.singletonList(new MockFlowRule(100)), Collections.emptyList());
Ray Milkeye9a3e222014-12-03 16:46:06 -0800163 }
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) {
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800170 return Lists.newArrayList(new MockInstallableIntent());
Ray Milkeye9a3e222014-12-03 16:46:06 -0800171 }
172 }
173
Ray Milkey77a455f2015-03-27 10:08:17 -0700174 private static class TestIntentCompilerMultipleFlows implements IntentCompiler<MockIntent> {
175 @Override
176 public List<Intent> compile(MockIntent intent, List<Intent> installable,
177 Set<LinkResourceAllocations> resources) {
178
179 return IntStream.rangeClosed(1, 5)
180 .mapToObj(mock -> (new MockInstallableIntent()))
181 .collect(Collectors.toList());
182 }
183 }
184
185
Ray Milkeye9a3e222014-12-03 16:46:06 -0800186 private static class TestIntentCompilerError implements IntentCompiler<MockIntent> {
187 @Override
188 public List<Intent> compile(MockIntent intent, List<Intent> installable,
189 Set<LinkResourceAllocations> resources) {
190 throw new IntentCompilationException("Compilation always fails");
191 }
192 }
193
Ray Milkeye9a3e222014-12-03 16:46:06 -0800194 /**
Ray Milkey77a455f2015-03-27 10:08:17 -0700195 * Hamcrest matcher to check that a collection of Intents contains an
Ray Milkeye9a3e222014-12-03 16:46:06 -0800196 * Intent with the specified Intent Id.
197 */
198 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
199 private final IntentId id;
200
201 public EntryForIntentMatcher(IntentId idValue) {
202 id = idValue;
203 }
204
205 @Override
206 public boolean matchesSafely(Collection<Intent> intents) {
207 for (Intent intent : intents) {
208 if (intent.id().equals(id)) {
209 return true;
210 }
211 }
212 return false;
213 }
214
215 @Override
216 public void describeTo(Description description) {
217 description.appendText("an intent with id \" ").
218 appendText(id.toString()).
219 appendText("\"");
220 }
221 }
222
223 private static EntryForIntentMatcher hasIntentWithId(IntentId id) {
224 return new EntryForIntentMatcher(id);
225 }
226
Brian O'Connor427a1762014-11-19 18:40:32 -0800227 @Before
228 public void setUp() {
229 manager = new IntentManager();
230 flowRuleService = new MockFlowRuleService();
231 manager.store = new SimpleIntentStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700232 injectEventDispatcher(manager, new TestEventDispatcher());
Brian O'Connor427a1762014-11-19 18:40:32 -0800233 manager.trackerService = new TestIntentTracker();
234 manager.flowRuleService = flowRuleService;
Brian O'Connor520c0522014-11-23 23:50:47 -0800235 manager.coreService = new TestCoreManager();
Sho SHIMIZUd5bf1062016-02-25 10:26:02 -0800236 manager.configService = mock(ComponentConfigService.class);
Brian O'Connor427a1762014-11-19 18:40:32 -0800237 service = manager;
238 extensionService = manager;
239
240 manager.activate();
241 service.addListener(listener);
242 extensionService.registerCompiler(MockIntent.class, compiler);
Brian O'Connor427a1762014-11-19 18:40:32 -0800243
244 assertTrue("store should be empty",
245 Sets.newHashSet(service.getIntents()).isEmpty());
246 assertEquals(0L, flowRuleService.getFlowRuleCount());
247 }
248
Ray Milkey9f74c082015-02-11 15:40:16 -0800249 public void verifyState() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800250 // verify that all intents are parked and the batch operation is unblocked
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700251 Set<IntentState> parked = Sets.newHashSet(INSTALLED, WITHDRAWN, FAILED, CORRUPT);
Brian O'Connor427a1762014-11-19 18:40:32 -0800252 for (Intent i : service.getIntents()) {
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800253 IntentState state = service.getIntentState(i.key());
Brian O'Connor427a1762014-11-19 18:40:32 -0800254 assertTrue("Intent " + i.id() + " is in invalid state " + state,
255 parked.contains(state));
256 }
257 //the batch has not yet been removed when we receive the last event
258 // FIXME: this doesn't guarantee to avoid the race
Brian O'Connorb499b352015-02-03 16:46:15 -0800259
260 //FIXME
261// for (int tries = 0; tries < 10; tries++) {
262// if (manager.batchService.getPendingOperations().isEmpty()) {
263// break;
264// }
265// delay(10);
266// }
267// assertTrue("There are still pending batch operations.",
268// manager.batchService.getPendingOperations().isEmpty());
Brian O'Connor427a1762014-11-19 18:40:32 -0800269
Ray Milkey9f74c082015-02-11 15:40:16 -0800270 }
271
272 @After
273 public void tearDown() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800274 extensionService.unregisterCompiler(MockIntent.class);
Brian O'Connor427a1762014-11-19 18:40:32 -0800275 service.removeListener(listener);
276 manager.deactivate();
277 // TODO null the other refs?
278 }
279
280 @Test
281 public void submitIntent() {
282 flowRuleService.setFuture(true);
283
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800284 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800285 listener.setLatch(1, Type.INSTALLED);
286 Intent intent = new MockIntent(MockIntent.nextId());
287 service.submit(intent);
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800288 listener.await(Type.INSTALL_REQ);
Brian O'Connor427a1762014-11-19 18:40:32 -0800289 listener.await(Type.INSTALLED);
290 assertEquals(1L, service.getIntentCount());
291 assertEquals(1L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800292 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800293 }
294
295 @Test
296 public void withdrawIntent() {
297 flowRuleService.setFuture(true);
298
299 listener.setLatch(1, Type.INSTALLED);
300 Intent intent = new MockIntent(MockIntent.nextId());
301 service.submit(intent);
302 listener.await(Type.INSTALLED);
303 assertEquals(1L, service.getIntentCount());
304 assertEquals(1L, flowRuleService.getFlowRuleCount());
305
306 listener.setLatch(1, Type.WITHDRAWN);
307 service.withdraw(intent);
308 listener.await(Type.WITHDRAWN);
Brian O'Connor427a1762014-11-19 18:40:32 -0800309 assertEquals(0L, flowRuleService.getFlowRuleCount());
Ray Milkey9f74c082015-02-11 15:40:16 -0800310 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800311 }
312
313 @Test
Ray Milkey0811bdd2015-03-11 10:21:55 -0700314 @Ignore("This is disabled because we are seeing intermittent failures on Jenkins")
Ray Milkey9f74c082015-02-11 15:40:16 -0800315 public void stressSubmitWithdrawUnique() {
Brian O'Connor427a1762014-11-19 18:40:32 -0800316 flowRuleService.setFuture(true);
317
318 int count = 500;
Ray Milkey9f74c082015-02-11 15:40:16 -0800319 Intent[] intents = new Intent[count];
Brian O'Connor427a1762014-11-19 18:40:32 -0800320
Brian O'Connor427a1762014-11-19 18:40:32 -0800321 listener.setLatch(count, Type.WITHDRAWN);
322
Ray Milkey9f74c082015-02-11 15:40:16 -0800323 for (int i = 0; i < count; i++) {
324 intents[i] = new MockIntent(MockIntent.nextId());
325 service.submit(intents[i]);
326 }
327
328 for (int i = 0; i < count; i++) {
329 service.withdraw(intents[i]);
330 }
331
332 listener.await(Type.WITHDRAWN);
333 assertEquals(0L, flowRuleService.getFlowRuleCount());
334 verifyState();
335 }
336
337 @Test
338 public void stressSubmitWithdrawSame() {
339 flowRuleService.setFuture(true);
340
341 int count = 50;
342
Brian O'Connor427a1762014-11-19 18:40:32 -0800343 Intent intent = new MockIntent(MockIntent.nextId());
344 for (int i = 0; i < count; i++) {
345 service.submit(intent);
346 service.withdraw(intent);
347 }
348
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -0800349 assertAfter(SUBMIT_TIMEOUT_MS, () -> {
Ray Milkey9f74c082015-02-11 15:40:16 -0800350 assertEquals(1L, service.getIntentCount());
351 assertEquals(0L, flowRuleService.getFlowRuleCount());
352 });
353 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800354 }
355
Ray Milkey9f74c082015-02-11 15:40:16 -0800356
Ray Milkey93508c22014-12-02 11:35:56 -0800357 /**
358 * Tests for proper behavior of installation of an intent that triggers
359 * a compilation error.
360 */
361 @Test
362 public void errorIntentCompile() {
363 final TestIntentCompilerError errorCompiler = new TestIntentCompilerError();
364 extensionService.registerCompiler(MockIntent.class, errorCompiler);
365 MockIntent intent = new MockIntent(MockIntent.nextId());
366 listener.setLatch(1, Type.INSTALL_REQ);
367 listener.setLatch(1, Type.FAILED);
368 service.submit(intent);
369 listener.await(Type.INSTALL_REQ);
370 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800371 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800372 }
373
374 /**
375 * Tests handling a future that contains an error as a result of
376 * installing an intent.
377 */
Ray Milkey9f74c082015-02-11 15:40:16 -0800378 @Ignore("skipping until we fix update ordering problem")
Ray Milkey93508c22014-12-02 11:35:56 -0800379 @Test
380 public void errorIntentInstallFromFlows() {
381 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800382 flowRuleService.setFuture(false);
Ray Milkey93508c22014-12-02 11:35:56 -0800383 MockIntent intent = new MockIntent(id);
384 listener.setLatch(1, Type.FAILED);
385 listener.setLatch(1, Type.INSTALL_REQ);
386 service.submit(intent);
387 listener.await(Type.INSTALL_REQ);
Ray Milkey93508c22014-12-02 11:35:56 -0800388 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800389 // FIXME the intent will be moved into INSTALLED immediately which overrides FAILED
390 // ... the updates come out of order
391 verifyState();
Ray Milkey93508c22014-12-02 11:35:56 -0800392 }
393
394 /**
Ray Milkeye9a3e222014-12-03 16:46:06 -0800395 * Tests handling a future that contains an unresolvable error as a result of
396 * installing an intent.
Brian O'Connor427a1762014-11-19 18:40:32 -0800397 */
Ray Milkeye9a3e222014-12-03 16:46:06 -0800398 @Test
399 public void errorIntentInstallNeverTrue() {
400 final Long id = MockIntent.nextId();
Brian O'Connor5811ac22015-02-09 19:17:07 -0800401 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800402 MockIntent intent = new MockIntent(id);
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700403 listener.setLatch(1, Type.CORRUPT);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800404 listener.setLatch(1, Type.INSTALL_REQ);
405 service.submit(intent);
406 listener.await(Type.INSTALL_REQ);
407 // The delay here forces the retry loop in the intent manager to time out
408 delay(100);
Brian O'Connor5811ac22015-02-09 19:17:07 -0800409 flowRuleService.setFuture(false);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800410 service.withdraw(intent);
Brian O'Connorf0c5a052015-04-27 00:34:53 -0700411 listener.await(Type.CORRUPT);
Ray Milkey9f74c082015-02-11 15:40:16 -0800412 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800413 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800414
Ray Milkeye9a3e222014-12-03 16:46:06 -0800415 /**
416 * Tests that a compiler for a subclass of an intent that already has a
417 * compiler is automatically added.
418 */
419 @Test
420 public void intentSubclassCompile() {
421 class MockIntentSubclass extends MockIntent {
422 public MockIntentSubclass(Long number) {
423 super(number);
424 }
425 }
426 flowRuleService.setFuture(true);
427
428 listener.setLatch(1, Type.INSTALL_REQ);
429 listener.setLatch(1, Type.INSTALLED);
430 Intent intent = new MockIntentSubclass(MockIntent.nextId());
431 service.submit(intent);
432 listener.await(Type.INSTALL_REQ);
433 listener.await(Type.INSTALLED);
434 assertEquals(1L, service.getIntentCount());
435 assertEquals(1L, flowRuleService.getFlowRuleCount());
436
437 final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers =
438 extensionService.getCompilers();
439 assertEquals(2, compilers.size());
440 assertNotNull(compilers.get(MockIntentSubclass.class));
441 assertNotNull(compilers.get(MockIntent.class));
Ray Milkey9f74c082015-02-11 15:40:16 -0800442 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800443 }
444
445 /**
446 * Tests an intent with no compiler.
447 */
448 @Test
449 public void intentWithoutCompiler() {
450 class IntentNoCompiler extends Intent {
451 IntentNoCompiler() {
Ray Milkeyebc5d222015-03-18 15:45:36 -0700452 super(APPID, null, Collections.emptyList(),
453 Intent.DEFAULT_INTENT_PRIORITY);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800454 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800455 }
456
Ray Milkeye9a3e222014-12-03 16:46:06 -0800457 Intent intent = new IntentNoCompiler();
458 listener.setLatch(1, Type.INSTALL_REQ);
459 listener.setLatch(1, Type.FAILED);
460 service.submit(intent);
461 listener.await(Type.INSTALL_REQ);
462 listener.await(Type.FAILED);
Ray Milkey9f74c082015-02-11 15:40:16 -0800463 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800464 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800465
Ray Milkeye9a3e222014-12-03 16:46:06 -0800466 /**
467 * Tests an intent with no installer.
468 */
469 @Test
470 public void intentWithoutInstaller() {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800471 MockIntent intent = new MockIntent(MockIntent.nextId());
472 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700473 listener.setLatch(1, Type.CORRUPT);
Ray Milkeye9a3e222014-12-03 16:46:06 -0800474 service.submit(intent);
475 listener.await(Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700476 listener.await(Type.CORRUPT);
Ray Milkey9f74c082015-02-11 15:40:16 -0800477 verifyState();
Ray Milkeye9a3e222014-12-03 16:46:06 -0800478 }
479
480 /**
481 * Tests that the intent fetching methods are correct.
482 */
483 @Test
484 public void testIntentFetching() {
485 List<Intent> intents;
486
487 flowRuleService.setFuture(true);
488
489 intents = Lists.newArrayList(service.getIntents());
490 assertThat(intents, hasSize(0));
491
492 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
493 final MockIntent intent2 = new MockIntent(MockIntent.nextId());
494
495 listener.setLatch(2, Type.INSTALL_REQ);
496 listener.setLatch(2, Type.INSTALLED);
497 service.submit(intent1);
498 service.submit(intent2);
499 listener.await(Type.INSTALL_REQ);
500 listener.await(Type.INSTALL_REQ);
501 listener.await(Type.INSTALLED);
502 listener.await(Type.INSTALLED);
503
504 intents = Lists.newArrayList(service.getIntents());
505 assertThat(intents, hasSize(2));
506
507 assertThat(intents, hasIntentWithId(intent1.id()));
508 assertThat(intents, hasIntentWithId(intent2.id()));
Ray Milkey9f74c082015-02-11 15:40:16 -0800509 verifyState();
Brian O'Connor427a1762014-11-19 18:40:32 -0800510 }
Ray Milkey77a455f2015-03-27 10:08:17 -0700511
512 /**
513 * Tests that removing all intents results in no flows remaining.
514 */
515 @Test
516 public void testFlowRemoval() {
517 List<Intent> intents;
518
519 flowRuleService.setFuture(true);
520
521 intents = Lists.newArrayList(service.getIntents());
522 assertThat(intents, hasSize(0));
523
524 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
525 final MockIntent intent2 = new MockIntent(MockIntent.nextId());
526
527 listener.setLatch(1, Type.INSTALL_REQ);
528 listener.setLatch(1, Type.INSTALLED);
529
530 service.submit(intent1);
531 listener.await(Type.INSTALL_REQ);
532 listener.await(Type.INSTALLED);
533
534
535 listener.setLatch(1, Type.INSTALL_REQ);
536 listener.setLatch(1, Type.INSTALLED);
537
538 service.submit(intent2);
539 listener.await(Type.INSTALL_REQ);
540 listener.await(Type.INSTALLED);
541
542 assertThat(listener.getCounts(Type.INSTALLED), is(2));
543 assertThat(flowRuleService.getFlowRuleCount(), is(2));
544
545 listener.setLatch(1, Type.WITHDRAWN);
546 service.withdraw(intent1);
547 listener.await(Type.WITHDRAWN);
548
549 listener.setLatch(1, Type.WITHDRAWN);
550 service.withdraw(intent2);
551 listener.await(Type.WITHDRAWN);
552
553 assertThat(listener.getCounts(Type.WITHDRAWN), is(2));
554 assertThat(flowRuleService.getFlowRuleCount(), is(0));
555 }
556
557 /**
Brian O'Connor3c58e962015-04-28 23:21:51 -0700558 * Test failure to install an intent, then succeed on retry via IntentCleanup.
559 */
560 @Test
561 public void testCorruptCleanup() {
562 IntentCleanup cleanup = new IntentCleanup();
563 cleanup.service = manager;
564 cleanup.store = manager.store;
565 cleanup.cfgService = new ComponentConfigAdapter();
566
567 try {
568 cleanup.activate();
569
570 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
571 extensionService.registerCompiler(MockIntent.class, errorCompiler);
572 List<Intent> intents;
573
574 flowRuleService.setFuture(false);
575
576 intents = Lists.newArrayList(service.getIntents());
577 assertThat(intents, hasSize(0));
578
579 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
580
581 listener.setLatch(1, Type.INSTALL_REQ);
582 listener.setLatch(1, Type.CORRUPT);
583 listener.setLatch(1, Type.INSTALLED);
584
585 service.submit(intent1);
586
587 listener.await(Type.INSTALL_REQ);
588 listener.await(Type.CORRUPT);
589
590 flowRuleService.setFuture(true);
591
592 listener.await(Type.INSTALLED);
593
594 assertThat(listener.getCounts(Type.CORRUPT), is(1));
595 assertThat(listener.getCounts(Type.INSTALLED), is(1));
596 assertEquals(INSTALLED, manager.getIntentState(intent1.key()));
597 assertThat(flowRuleService.getFlowRuleCount(), is(5));
598 } finally {
599 cleanup.deactivate();
600 }
601 }
602
603 /**
Brian O'Connoreba4e342015-04-30 22:50:13 -0700604 * Test failure to install an intent, and verify retries.
605 */
606 @Test
607 public void testCorruptRetry() {
608 IntentCleanup cleanup = new IntentCleanup();
609 cleanup.service = manager;
610 cleanup.store = manager.store;
611 cleanup.cfgService = new ComponentConfigAdapter();
612 cleanup.period = 1_000_000;
613 cleanup.retryThreshold = 3;
614
615 try {
616 cleanup.activate();
617
618 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
619 extensionService.registerCompiler(MockIntent.class, errorCompiler);
620 List<Intent> intents;
621
622 flowRuleService.setFuture(false);
623
624 intents = Lists.newArrayList(service.getIntents());
625 assertThat(intents, hasSize(0));
626
627 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
628
629 listener.setLatch(1, Type.INSTALL_REQ);
630 listener.setLatch(cleanup.retryThreshold, Type.CORRUPT);
631 listener.setLatch(1, Type.INSTALLED);
632
633 service.submit(intent1);
634
635 listener.await(Type.INSTALL_REQ);
636 listener.await(Type.CORRUPT);
637 assertEquals(CORRUPT, manager.getIntentState(intent1.key()));
638 assertThat(listener.getCounts(Type.CORRUPT), is(cleanup.retryThreshold));
639
640 } finally {
641 cleanup.deactivate();
642 }
643 }
644
645 /**
Ray Milkey77a455f2015-03-27 10:08:17 -0700646 * Tests that an intent that fails installation results in no flows remaining.
647 */
648 @Test
Brian O'Connor3c58e962015-04-28 23:21:51 -0700649 @Ignore("MockFlowRule numbering issue") //test works if run independently
Ray Milkey77a455f2015-03-27 10:08:17 -0700650 public void testFlowRemovalInstallError() {
651 final TestIntentCompilerMultipleFlows errorCompiler = new TestIntentCompilerMultipleFlows();
652 extensionService.registerCompiler(MockIntent.class, errorCompiler);
653 List<Intent> intents;
654
655 flowRuleService.setFuture(true);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700656 //FIXME relying on "3" is brittle
Ray Milkey77a455f2015-03-27 10:08:17 -0700657 flowRuleService.setErrorFlow(3);
658
659 intents = Lists.newArrayList(service.getIntents());
660 assertThat(intents, hasSize(0));
661
662 final MockIntent intent1 = new MockIntent(MockIntent.nextId());
663
664 listener.setLatch(1, Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700665 listener.setLatch(1, Type.CORRUPT);
Ray Milkey77a455f2015-03-27 10:08:17 -0700666
667 service.submit(intent1);
668 listener.await(Type.INSTALL_REQ);
Brian O'Connor3c58e962015-04-28 23:21:51 -0700669 listener.await(Type.CORRUPT);
Ray Milkey77a455f2015-03-27 10:08:17 -0700670
Brian O'Connor3c58e962015-04-28 23:21:51 -0700671 assertThat(listener.getCounts(Type.CORRUPT), is(1));
672 // in this test, there will still be flows abandoned on the data plane
673 //assertThat(flowRuleService.getFlowRuleCount(), is(0));
Ray Milkey77a455f2015-03-27 10:08:17 -0700674 }
Brian O'Connor427a1762014-11-19 18:40:32 -0800675}