blob: b1e6376c0940341ea46d454b791d3a96b9e64cf5 [file] [log] [blame]
alshabibab984662014-12-04 18:56:18 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present 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;
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
Sho SHIMIZUd5bf1062016-02-25 10:26:02 -080060import static org.easymock.EasyMock.mock;
Ray Milkeye9a3e222014-12-03 16:46:06 -080061import static org.hamcrest.MatcherAssert.assertThat;
62import static org.hamcrest.Matchers.hasSize;
Ray Milkey77a455f2015-03-27 10:08:17 -070063import static org.hamcrest.Matchers.is;
Brian O'Connor3c58e962015-04-28 23:21:51 -070064import static org.junit.Assert.*;
Ray Milkey9f74c082015-02-11 15:40:16 -080065import static org.onlab.junit.TestTools.assertAfter;
Brian O'Connor427a1762014-11-19 18:40:32 -080066import static org.onlab.util.Tools.delay;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070067import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Brian O'Connorf0c5a052015-04-27 00:34:53 -070068import static org.onosproject.net.intent.IntentState.*;
Ray Milkey43a28222015-02-23 13:57:58 -080069import static org.onosproject.net.intent.IntentTestsMocks.MockFlowRule;
70import static org.onosproject.net.intent.IntentTestsMocks.MockIntent;
Brian O'Connor427a1762014-11-19 18:40:32 -080071
72/**
73 * Test intent manager and transitions.
74 *
75 * TODO implement the following tests:
76 * - {submit, withdraw, update, replace} intent
Sho SHIMIZU34660962015-01-22 17:58:44 -080077 * - {submit, update, recompiling} intent with failed compilation
Brian O'Connor427a1762014-11-19 18:40:32 -080078 * - failed reservation
79 * - push timeout recovery
80 * - failed items recovery
81 *
82 * in general, verify intents store, flow store, and work queue
83 */
Ray Milkey1c166dc2015-03-02 13:32:39 -080084
Brian O'Connor427a1762014-11-19 18:40:32 -080085public class IntentManagerTest {
86
Pavlin Radoslavov35b4ecb2015-03-03 15:06:04 -080087 private static final int SUBMIT_TIMEOUT_MS = 1000;
Brian O'Connor427a1762014-11-19 18:40:32 -080088 private static final ApplicationId APPID = new TestApplicationId("manager-test");
89
90 private IntentManager manager;
91 private MockFlowRuleService flowRuleService;
92
93 protected IntentService service;
94 protected IntentExtensionService extensionService;
95 protected TestListener listener = new TestListener();
96 protected TestIntentCompiler compiler = new TestIntentCompiler();
Brian O'Connor427a1762014-11-19 18:40:32 -080097
Ray Milkeye9a3e222014-12-03 16:46:06 -080098 private static class TestListener implements IntentListener {
99 final Multimap<IntentEvent.Type, IntentEvent> events = HashMultimap.create();
100 Map<IntentEvent.Type, CountDownLatch> latchMap = Maps.newHashMap();
101
102 @Override
103 public void event(IntentEvent event) {
104 events.put(event.type(), event);
105 if (latchMap.containsKey(event.type())) {
106 latchMap.get(event.type()).countDown();
107 }
108 }
109
110 public int getCounts(IntentEvent.Type type) {
111 return events.get(type).size();
112 }
113
114 public void setLatch(int count, IntentEvent.Type type) {
115 latchMap.put(type, new CountDownLatch(count));
116 }
117
118 public void await(IntentEvent.Type type) {
119 try {
120 assertTrue("Timed out waiting for: " + type,
121 latchMap.get(type).await(5, TimeUnit.SECONDS));
122 } catch (InterruptedException e) {
123 e.printStackTrace();
124 }
125 }
126 }
127
128 private static class TestIntentTracker implements ObjectiveTrackerService {
129 private TopologyChangeDelegate delegate;
130 @Override
131 public void setDelegate(TopologyChangeDelegate delegate) {
132 this.delegate = delegate;
133 }
134
135 @Override
136 public void unsetDelegate(TopologyChangeDelegate delegate) {
137 if (delegate.equals(this.delegate)) {
138 this.delegate = null;
139 }
140 }
141
142 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800143 public void addTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800144 //TODO
145 }
146
147 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800148 public void removeTrackedResources(Key key, Collection<NetworkResource> resources) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800149 //TODO
150 }
Thomas Vachuskac46af202015-06-03 16:43:27 -0700151
152 @Override
153 public void trackIntent(IntentData intentData) {
154 //TODO
155 }
Ray Milkeye9a3e222014-12-03 16:46:06 -0800156 }
157
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800158 private static class MockInstallableIntent extends FlowRuleIntent {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800159
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800160 public MockInstallableIntent() {
Sho SHIMIZUc3cf5bc2015-09-24 14:46:40 -0700161 super(APPID, Collections.singletonList(new MockFlowRule(100)), Collections.emptyList());
Ray Milkeye9a3e222014-12-03 16:46:06 -0800162 }
163 }
164
165 private static class TestIntentCompiler implements IntentCompiler<MockIntent> {
166 @Override
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800167 public List<Intent> compile(MockIntent intent, List<Intent> installable) {
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
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800174 public List<Intent> compile(MockIntent intent, List<Intent> installable) {
Ray Milkey77a455f2015-03-27 10:08:17 -0700175
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
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800185 public List<Intent> compile(MockIntent intent, List<Intent> installable) {
Ray Milkeye9a3e222014-12-03 16:46:06 -0800186 throw new IntentCompilationException("Compilation always fails");
187 }
188 }
189
Ray Milkeye9a3e222014-12-03 16:46:06 -0800190 /**
Ray Milkey77a455f2015-03-27 10:08:17 -0700191 * Hamcrest matcher to check that a collection of Intents contains an
Ray Milkeye9a3e222014-12-03 16:46:06 -0800192 * Intent with the specified Intent Id.
193 */
194 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
195 private final IntentId id;
196
197 public EntryForIntentMatcher(IntentId idValue) {
198 id = idValue;
199 }
200
201 @Override
202 public boolean matchesSafely(Collection<Intent> intents) {
203 for (Intent intent : intents) {
204 if (intent.id().equals(id)) {
205 return true;
206 }
207 }
208 return false;
209 }
210
211 @Override
212 public void describeTo(Description description) {
213 description.appendText("an intent with id \" ").
214 appendText(id.toString()).
215 appendText("\"");
216 }
217 }
218
219 private static EntryForIntentMatcher hasIntentWithId(IntentId id) {
220 return new EntryForIntentMatcher(id);
221 }
222
Brian O'Connor427a1762014-11-19 18:40:32 -0800223 @Before
224 public void setUp() {
225 manager = new IntentManager();
226 flowRuleService = new MockFlowRuleService();
227 manager.store = new SimpleIntentStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700228 injectEventDispatcher(manager, new TestEventDispatcher());
Brian O'Connor427a1762014-11-19 18:40:32 -0800229 manager.trackerService = new TestIntentTracker();
230 manager.flowRuleService = flowRuleService;
Brian O'Connor520c0522014-11-23 23:50:47 -0800231 manager.coreService = new TestCoreManager();
Sho SHIMIZUd5bf1062016-02-25 10:26:02 -0800232 manager.configService = mock(ComponentConfigService.class);
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}