blob: 5d4adb8aee91ce2209331f6a2fdc8be4fe1a3085 [file] [log] [blame]
Jonathan Hartaa380972014-04-03 10:24:46 -07001package net.onrc.onos.core.intent.runtime;
Ray Milkey6688cd82014-03-11 16:40:46 -07002
Jonathan Harta88fd242014-04-03 11:24:54 -07003import static org.hamcrest.MatcherAssert.assertThat;
4import static org.hamcrest.Matchers.equalTo;
5import static org.hamcrest.Matchers.hasItem;
6import static org.hamcrest.Matchers.hasSize;
Pavlin Radoslavove2238bc2014-06-09 18:05:23 -07007import static org.hamcrest.Matchers.not;
Jonathan Harta88fd242014-04-03 11:24:54 -07008import static org.hamcrest.Matchers.notNullValue;
9
10import java.util.Collection;
11import java.util.LinkedList;
12import java.util.List;
13
Ray Milkey6688cd82014-03-11 16:40:46 -070014import net.floodlightcontroller.core.module.FloodlightModuleContext;
Jonathan Hartaa380972014-04-03 10:24:46 -070015import net.onrc.onos.core.intent.Intent;
Jonathan Harta88fd242014-04-03 11:24:54 -070016import net.onrc.onos.core.intent.Intent.IntentState;
Jonathan Hartaa380972014-04-03 10:24:46 -070017import net.onrc.onos.core.intent.IntentMap;
Jonathan Harta88fd242014-04-03 11:24:54 -070018import net.onrc.onos.core.intent.IntentOperation.Operator;
Jonathan Hartaa380972014-04-03 10:24:46 -070019import net.onrc.onos.core.intent.IntentOperationList;
Jonathan Hartaa380972014-04-03 10:24:46 -070020import net.onrc.onos.core.intent.ShortestPathIntent;
Jonathan Hart472062d2014-04-03 10:56:48 -070021import net.onrc.onos.core.topology.DeviceEvent;
Jonathan Hart472062d2014-04-03 10:56:48 -070022import net.onrc.onos.core.topology.LinkEvent;
TeruU5d2c9392014-06-09 20:02:02 -070023import net.onrc.onos.core.topology.MockTopology;
Jonathan Hart472062d2014-04-03 10:56:48 -070024import net.onrc.onos.core.topology.PortEvent;
25import net.onrc.onos.core.topology.SwitchEvent;
Ray Milkey6688cd82014-03-11 16:40:46 -070026
Jonathan Harta88fd242014-04-03 11:24:54 -070027import org.hamcrest.Description;
28import org.hamcrest.Factory;
29import org.hamcrest.Matcher;
30import org.hamcrest.Matchers;
31import org.hamcrest.TypeSafeMatcher;
Ray Milkey6688cd82014-03-11 16:40:46 -070032import org.junit.After;
33import org.junit.Before;
34import org.junit.Test;
35import org.junit.runner.RunWith;
Ray Milkey6688cd82014-03-11 16:40:46 -070036import org.powermock.core.classloader.annotations.PrepareForTest;
37import org.powermock.modules.junit4.PowerMockRunner;
38
Ray Milkey6688cd82014-03-11 16:40:46 -070039/**
Ray Milkey269ffb92014-04-03 14:43:30 -070040 * Unit tests for the Path Calculation Runtime module (PathCalcRuntimeModule).
41 * These test cases check the results of creating paths, deleting paths, and
Jonathan Harte37e4e22014-05-13 19:12:02 -070042 * rerouting paths. The topology, controller registry, and data grid are
Ray Milkey269ffb92014-04-03 14:43:30 -070043 * mocked out. The individual tests check the high level intents and the
44 * resulting operation lists to be sure they match the intended APIs.
Ray Milkey6688cd82014-03-11 16:40:46 -070045 */
46@RunWith(PowerMockRunner.class)
47@PrepareForTest(PathCalcRuntimeModule.class)
48public class PathCalcRuntimeModuleTest {
Ray Milkeydc659c42014-03-28 16:30:42 -070049 private static final Long LOCAL_PORT = 0xFFFEL;
50
Ray Milkey9d671002014-05-29 17:24:29 -070051 private IntentTestMocks mocks;
52 private PathCalcRuntimeModule runtime;
Ray Milkey6688cd82014-03-11 16:40:46 -070053
Ray Milkey6688cd82014-03-11 16:40:46 -070054 @Before
55 public void setUp() throws Exception {
Ray Milkey9d671002014-05-29 17:24:29 -070056 mocks = new IntentTestMocks();
57 mocks.setUpIntentMocks();
Ray Milkey6688cd82014-03-11 16:40:46 -070058
Ray Milkey9d671002014-05-29 17:24:29 -070059 runtime = new PathCalcRuntimeModule();
60 final FloodlightModuleContext moduleContext = mocks.getModuleContext();
61 runtime.init(moduleContext);
62 runtime.startUp(moduleContext);
Ray Milkey6688cd82014-03-11 16:40:46 -070063 }
64
Ray Milkeydc659c42014-03-28 16:30:42 -070065
66 /**
67 * Hamcrest matcher to check that a collection of Intents contains an
68 * Intent with the specified Intent Id.
69 */
70 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070071 private final String id;
Ray Milkeydc659c42014-03-28 16:30:42 -070072
73 public EntryForIntentMatcher(String idValue) {
74 id = idValue;
75 }
76
77 @Override
78 public boolean matchesSafely(Collection<Intent> intents) {
Pavlin Radoslavove2238bc2014-06-09 18:05:23 -070079 return hasItem(Matchers.<Intent>hasProperty("id", equalTo(id))).matches(intents);
Ray Milkeydc659c42014-03-28 16:30:42 -070080 }
81
82 @Override
83 public void describeTo(Description description) {
84 description.appendText("an intent with id \" ").
85 appendText(id).
86 appendText("\"");
87 }
88 }
89
90
91 /**
92 * Factory method to create an Intent entry Matcher. Returns a matcher
93 * for the Intent with the given id.
Ray Milkey269ffb92014-04-03 14:43:30 -070094 *
Ray Milkeydc659c42014-03-28 16:30:42 -070095 * @param id id of the intent to match
96 * @return Matcher object
97 */
98 @Factory
99 public static Matcher<Collection<Intent>> hasIntentWithId(String id) {
100 return new EntryForIntentMatcher(id);
101 }
102
103
104 /**
105 * Matcher to determine if an IntentMap contains an entry with a given id,
106 * and that entry has a given state.
107 */
108 public static class IntentsHaveIntentWithStateMatcher extends TypeSafeMatcher<IntentMap> {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700109 private final String id;
110 private final IntentState state;
Ray Milkeydc659c42014-03-28 16:30:42 -0700111 private Intent intent;
112
113 public IntentsHaveIntentWithStateMatcher(String idValue,
114 IntentState stateValue) {
115 id = idValue;
116 state = stateValue;
117 }
118
119 @Override
120 public boolean matchesSafely(IntentMap intents) {
121 intent = intents.getIntent(id);
122
123 return intent != null && intent.getState() == state;
124 }
125
126 @Override
127 public void describeTo(Description description) {
128 if (intent == null) {
129 description.appendText("intent lookup for id \"");
130 description.appendText(id);
131 description.appendText("\"");
132 } else {
133 description.appendText("state ");
134 description.appendText(state.toString());
135 }
136 }
137
138 @Override
139 public void describeMismatchSafely(IntentMap intents,
140 Description mismatchDescription) {
141 if (intent != null) {
142 mismatchDescription.appendText("was ").
Ray Milkey269ffb92014-04-03 14:43:30 -0700143 appendText(intent.getState().toString());
Ray Milkeydc659c42014-03-28 16:30:42 -0700144 } else {
145 mismatchDescription.appendText("that intent was not found");
146 }
147 }
148 }
149
150
151 /**
152 * Factory method to create a Matcher for an IntentMap that looks for an
153 * Intent with a given id and state.
154 *
Ray Milkey269ffb92014-04-03 14:43:30 -0700155 * @param id id of the Intent to match
Ray Milkeydc659c42014-03-28 16:30:42 -0700156 * @param state if the Intent is found, its state must match this
157 * @return Matcher object
158 */
159 @Factory
160 public static Matcher<IntentMap> hasIntentWithIdAndState(String id,
161 IntentState state) {
162 return new IntentsHaveIntentWithStateMatcher(id, state);
163 }
164
165
Ray Milkey6688cd82014-03-11 16:40:46 -0700166 @After
167 public void tearDown() {
Ray Milkey9d671002014-05-29 17:24:29 -0700168 mocks.tearDownIntentMocks();
Ray Milkey6688cd82014-03-11 16:40:46 -0700169 }
170
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700171 private static final String BAD_SWITCH_INTENT_NAME = "No Such Switch Intent";
172
Ray Milkey6688cd82014-03-11 16:40:46 -0700173 /**
174 * Test the result of executing a path calculation on an
175 * Intent Operation List which contains a path that references a
176 * non-existent switch.
Ray Milkey269ffb92014-04-03 14:43:30 -0700177 * <p/>
Ray Milkey6688cd82014-03-11 16:40:46 -0700178 * A 3 path list is created where one of the paths references a switch
179 * that is not in the topology. The test checks that the resulting
180 * Operation List has entries for the 2 correct paths, and that the
181 * high level intents contain a proper error entry for the bad path.
182 */
183 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700184 public void testInvalidSwitchName() {
Ray Milkey6688cd82014-03-11 16:40:46 -0700185
186 // create shortest path intents
187 final IntentOperationList opList = new IntentOperationList();
188 opList.add(Operator.ADD,
189 new ShortestPathIntent(BAD_SWITCH_INTENT_NAME, 111L, 12L,
190 LOCAL_PORT, 2L, 21L, LOCAL_PORT));
191 opList.add(Operator.ADD,
192 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
193 LOCAL_PORT));
194 opList.add(Operator.ADD,
195 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
196 LOCAL_PORT));
197
198 // compile high-level intent operations into low-level intent
199 // operations (calculate paths)
Ray Milkey6688cd82014-03-11 16:40:46 -0700200 final IntentOperationList pathIntentOpList =
201 runtime.executeIntentOperations(opList);
202 assertThat(pathIntentOpList, notNullValue());
203
204 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
205 assertThat(highLevelIntents, notNullValue());
206
207 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
208 assertThat(allIntents, notNullValue());
209
210 // One intent had an error and should not create a path list entry
211 assertThat(pathIntentOpList, hasSize(opList.size() - 1));
212
213 // Should be a high level intent for each operation
Ray Milkeydc659c42014-03-28 16:30:42 -0700214 assertThat(allIntents, hasSize(opList.size()));
Ray Milkey6688cd82014-03-11 16:40:46 -0700215
216 // Check that we got a high level intent for each operation
Ray Milkeydc659c42014-03-28 16:30:42 -0700217 assertThat(allIntents, hasIntentWithId("3"));
218 assertThat(allIntents, hasIntentWithId("2"));
219 assertThat(allIntents, hasIntentWithId(BAD_SWITCH_INTENT_NAME));
Ray Milkey6688cd82014-03-11 16:40:46 -0700220
221 // Check that the non existent switch was NACKed
Ray Milkeydc659c42014-03-28 16:30:42 -0700222 assertThat(highLevelIntents, hasIntentWithIdAndState(BAD_SWITCH_INTENT_NAME, IntentState.INST_NACK));
Ray Milkey6688cd82014-03-11 16:40:46 -0700223
224 // Check that switch 2 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700225 assertThat(highLevelIntents, hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkey6688cd82014-03-11 16:40:46 -0700226
227 // Check that switch 3 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700228 assertThat(highLevelIntents, hasIntentWithIdAndState("3", IntentState.INST_REQ));
229
230 }
231
232
233 /**
234 * Test the result of executing a path calculation on an
235 * Intent Operation List and then removing one of the switches.
Ray Milkey269ffb92014-04-03 14:43:30 -0700236 * <p/>
Ray Milkeydc659c42014-03-28 16:30:42 -0700237 * A 3 path list is created and then one of the paths is removed.
238 * The test checks that the resulting Operation List is correct,
239 * and that the high level intents contain a proper "delete requested"
240 * entry for the deleted path.
241 */
242 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700243 public void testIntentRemoval() {
Ray Milkeydc659c42014-03-28 16:30:42 -0700244 // create shortest path intents
245 final IntentOperationList opList = new IntentOperationList();
246 opList.add(Operator.ADD,
247 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700248 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700249 opList.add(Operator.ADD,
250 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700251 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700252 opList.add(Operator.ADD,
253 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700254 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700255
256 // compile high-level intent operations into low-level intent
257 // operations (calculate paths)
Ray Milkeydc659c42014-03-28 16:30:42 -0700258 final IntentOperationList pathIntentOpList =
259 runtime.executeIntentOperations(opList);
260 assertThat(pathIntentOpList, notNullValue());
261
262 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
263 assertThat(highLevelIntents, notNullValue());
264
265 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
266 assertThat(allIntents, notNullValue());
267
268 // Should be one operation per path
269 assertThat(pathIntentOpList, hasSize(opList.size()));
270
271 // Should be a high level intent for each operation
272 assertThat(allIntents, hasSize(opList.size()));
273
274 // Check that we got a high level intent for each operation
275 assertThat(allIntents, hasIntentWithId("3"));
276 assertThat(allIntents, hasIntentWithId("2"));
277 assertThat(allIntents, hasIntentWithId("1"));
278
279 // Check that switch 1 was correctly processed
280 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700281 hasIntentWithIdAndState("1", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700282
283 // Check that switch 2 was correctly processed
284 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700285 hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700286
287 // Check that switch 3 was correctly processed
288 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700289 hasIntentWithIdAndState("3", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700290
291 // Now delete one path and check the results
292 final IntentOperationList opListForRemoval = new IntentOperationList();
293 opListForRemoval.add(Operator.REMOVE,
294 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
295 LOCAL_PORT));
296
297 final IntentOperationList pathIntentOpListAfterRemoval =
298 runtime.executeIntentOperations(opListForRemoval);
299 assertThat(pathIntentOpListAfterRemoval, notNullValue());
300 assertThat(pathIntentOpListAfterRemoval, hasSize(1));
301
302 // Check the high level intents.
303 final IntentMap highLevelIntentsAfterRemoval = runtime.getHighLevelIntents();
304 assertThat(highLevelIntentsAfterRemoval, notNullValue());
305
306 final Collection<Intent> allIntentsAfterRemoval = highLevelIntentsAfterRemoval.getAllIntents();
307 assertThat(allIntentsAfterRemoval, notNullValue());
308 assertThat(allIntentsAfterRemoval, hasSize(3));
309
310 // Check that we got a high level intent for each operation
311 assertThat(allIntentsAfterRemoval, hasIntentWithId("3"));
312 assertThat(allIntentsAfterRemoval, hasIntentWithId("2"));
313 assertThat(allIntentsAfterRemoval, hasIntentWithId("1"));
314
315 // Check the states of the high level intents
316 // Check that switch 1 was correctly processed
317 assertThat(highLevelIntents,
318 hasIntentWithIdAndState("1", IntentState.DEL_REQ));
319
320 // Check that switch 2 was correctly processed
321 assertThat(highLevelIntents,
322 hasIntentWithIdAndState("2", IntentState.INST_REQ));
323
324 // Check that switch 3 was correctly processed
325 assertThat(highLevelIntents,
326 hasIntentWithIdAndState("3", IntentState.INST_REQ));
327 }
328
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700329 // CHECKSTYLE:OFF method too long
Ray Milkeydc659c42014-03-28 16:30:42 -0700330 /**
331 * Test the result of executing a path calculation on an
332 * Intent Operation List and then forcing a reroute.
Ray Milkey269ffb92014-04-03 14:43:30 -0700333 * <p/>
Ray Milkeydc659c42014-03-28 16:30:42 -0700334 * A 3 path list is created and then one of the links is removed.
335 * The test checks that the resulting Operation List is correct,
336 * and that the high level intents contain a proper "reroute requested"
337 * entry for the deleted link.
338 */
339 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700340 public void testIntentReroute() {
Ray Milkeydc659c42014-03-28 16:30:42 -0700341 // create shortest path intents
342 final IntentOperationList opList = new IntentOperationList();
Toshio Koideee698952014-06-11 13:35:30 -0700343 opList.add(Operator.ADD,
Ray Milkeydc659c42014-03-28 16:30:42 -0700344 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
Toshio Koideee698952014-06-11 13:35:30 -0700345 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700346 opList.add(Operator.ADD,
347 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700348 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700349 opList.add(Operator.ADD,
350 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700351 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700352
353 // compile high-level intent operations into low-level intent
354 // operations (calculate paths)
Ray Milkeydc659c42014-03-28 16:30:42 -0700355 final IntentOperationList pathIntentOpList =
356 runtime.executeIntentOperations(opList);
357 assertThat(pathIntentOpList, notNullValue());
358
359 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
360 assertThat(highLevelIntents, notNullValue());
361
362 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
363 assertThat(allIntents, notNullValue());
364
365 // Should be one operation per path
366 assertThat(pathIntentOpList, hasSize(opList.size()));
367
368 // Should be a high level intent for each operation
369 assertThat(allIntents, hasSize(opList.size()));
370
371 // Check that we got a high level intent for each operation
372 assertThat(allIntents, hasIntentWithId("3"));
373 assertThat(allIntents, hasIntentWithId("2"));
374 assertThat(allIntents, hasIntentWithId("1"));
375
Toshio Koidec2112c22014-06-05 19:59:15 -0700376 // Check that the high level intent 1 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700377 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700378 hasIntentWithIdAndState("1", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700379
Toshio Koidec2112c22014-06-05 19:59:15 -0700380 // Check that the high level intent 2 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700381 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700382 hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700383
Toshio Koidec2112c22014-06-05 19:59:15 -0700384 // Check that the high level intent 3 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700385 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700386 hasIntentWithIdAndState("3", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700387
Toshio Koidec2112c22014-06-05 19:59:15 -0700388 final IntentMap pathIntents = runtime.getPathIntents();
389 assertThat(pathIntents, notNullValue());
Ray Milkeydc659c42014-03-28 16:30:42 -0700390
Toshio Koidec2112c22014-06-05 19:59:15 -0700391 final Collection<Intent> allPathIntents = pathIntents.getAllIntents();
392 assertThat(allPathIntents, notNullValue());
393
394 // Check that we got a low level intent for each operation
395 assertThat(allPathIntents, hasIntentWithId("3___0"));
396 assertThat(allPathIntents, hasIntentWithId("2___0"));
397 assertThat(allPathIntents, hasIntentWithId("1___0"));
398
399 // Check that the low level intent 1 was correctly processed
400 assertThat(pathIntents,
401 hasIntentWithIdAndState("1___0", IntentState.INST_REQ));
402
403 // Check that the low level intent 2 was correctly processed
404 assertThat(pathIntents,
405 hasIntentWithIdAndState("2___0", IntentState.INST_REQ));
406
407 // Check that the low level intent 3 was correctly processed
408 assertThat(pathIntents,
409 hasIntentWithIdAndState("3___0", IntentState.INST_REQ));
410
411 // Receive notification from south-bound
412 IntentStateList isl = new IntentStateList();
413 isl.put("1___0", IntentState.INST_ACK);
414 isl.put("2___0", IntentState.INST_ACK);
415 isl.put("3___0", IntentState.INST_ACK);
416 isl.domainSwitchDpids.add(1L);
417 isl.domainSwitchDpids.add(2L);
418 isl.domainSwitchDpids.add(3L);
419 isl.domainSwitchDpids.add(4L);
420 runtime.entryUpdated(isl);
421
422 // Now check the results
423 final IntentMap processedHighLevelIntents = runtime.getHighLevelIntents();
424 assertThat(processedHighLevelIntents, notNullValue());
425
426 // Check that the high level intent 1 was correctly processed
427 assertThat(processedHighLevelIntents,
428 hasIntentWithIdAndState("1", IntentState.INST_ACK));
429
430 // Check that the high level intent 2 was correctly processed
431 assertThat(processedHighLevelIntents,
432 hasIntentWithIdAndState("2", IntentState.INST_ACK));
433
434 // Check that the high level intent 3 was correctly processed
435 assertThat(processedHighLevelIntents,
436 hasIntentWithIdAndState("3", IntentState.INST_ACK));
437
438 final IntentMap processedPathIntents = runtime.getPathIntents();
439 assertThat(processedPathIntents, notNullValue());
440
441 // Check that the low level intent 1 was correctly processed
442 assertThat(processedPathIntents,
443 hasIntentWithIdAndState("1___0", IntentState.INST_ACK));
444
445 // Check that the low level intent 2 was correctly processed
446 assertThat(processedPathIntents,
447 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
448
449 // Check that the low level intent 3 was correctly processed
450 assertThat(processedPathIntents,
451 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
452
Toshio Koidec2112c22014-06-05 19:59:15 -0700453 // Remove one of the links and check results
Ray Milkeydc659c42014-03-28 16:30:42 -0700454 final List<SwitchEvent> emptySwitchEvents = new LinkedList<>();
455 final List<PortEvent> emptyPortEvents = new LinkedList<>();
456 final List<DeviceEvent> emptyDeviceEvents = new LinkedList<>();
457 final List<LinkEvent> addedLinkEvents = new LinkedList<>();
458 final List<LinkEvent> removedLinkEvents = new LinkedList<>();
459
Ray Milkey9d671002014-05-29 17:24:29 -0700460 final MockTopology topology = mocks.getTopology();
Jonathan Harte37e4e22014-05-13 19:12:02 -0700461 topology.removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
462 topology.removeLink(2L, 21L, 1L, 12L);
Ray Milkeydc659c42014-03-28 16:30:42 -0700463 LinkEvent linkEvent1 = new LinkEvent(1L, 12L, 2L, 21L);
464 LinkEvent linkEvent2 = new LinkEvent(2L, 21L, 1L, 12L);
465 removedLinkEvents.add(linkEvent1);
466 removedLinkEvents.add(linkEvent2);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700467 runtime.topologyEvents(emptySwitchEvents, emptySwitchEvents,
468 emptyPortEvents, emptyPortEvents,
469 addedLinkEvents, removedLinkEvents,
470 emptyDeviceEvents, emptyDeviceEvents);
Ray Milkeydc659c42014-03-28 16:30:42 -0700471
472 // Check the high level intents.
473 final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
474 assertThat(highLevelIntentsAfterReroute, notNullValue());
475
Ray Milkeydc659c42014-03-28 16:30:42 -0700476 // Check the states of the high level intents
Toshio Koidec2112c22014-06-05 19:59:15 -0700477 // Check that the high level intent 1 was correctly processed
478 assertThat(highLevelIntentsAfterReroute,
479 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700480
Toshio Koidec2112c22014-06-05 19:59:15 -0700481 // Check that the high level intent 2 was not affected
482 assertThat(highLevelIntentsAfterReroute,
Ray Milkeydc659c42014-03-28 16:30:42 -0700483 hasIntentWithIdAndState("2", IntentState.INST_ACK));
484
Toshio Koidec2112c22014-06-05 19:59:15 -0700485 // Check that the high level intent 3 was not affected
486 assertThat(highLevelIntentsAfterReroute,
Ray Milkeydc659c42014-03-28 16:30:42 -0700487 hasIntentWithIdAndState("3", IntentState.INST_ACK));
488
Toshio Koidec2112c22014-06-05 19:59:15 -0700489 final IntentMap pathIntentsAfterReroute = runtime.getPathIntents();
490 assertThat(pathIntentsAfterReroute, notNullValue());
Ray Milkey6688cd82014-03-11 16:40:46 -0700491
Toshio Koidec2112c22014-06-05 19:59:15 -0700492 // Check that the low level intent 1 was correctly processed
493 assertThat(pathIntentsAfterReroute,
494 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
495 assertThat(pathIntentsAfterReroute,
496 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
497
498 // Check that the low level intent 2 was not affected
499 assertThat(pathIntentsAfterReroute,
500 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
501
502 // Check that the low level intent 3 was not affected
503 assertThat(pathIntentsAfterReroute,
504 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
505
506 // Receive notification from south-bound
507 isl = new IntentStateList();
508 isl.put("1___0", IntentState.DEL_ACK);
509 isl.put("1___1", IntentState.INST_ACK);
510 isl.domainSwitchDpids.add(1L);
511 isl.domainSwitchDpids.add(2L);
512 isl.domainSwitchDpids.add(4L);
513 runtime.entryUpdated(isl);
514
515 // Now check the results
516 final IntentMap reroutedHighLevelIntents = runtime.getHighLevelIntents();
517 assertThat(reroutedHighLevelIntents, notNullValue());
518
519 // Check that the high level intent 1 was correctly processed
520 assertThat(reroutedHighLevelIntents,
521 hasIntentWithIdAndState("1", IntentState.INST_ACK));
522
523 // Check that the high level intent 2 was not affected
524 assertThat(reroutedHighLevelIntents,
525 hasIntentWithIdAndState("2", IntentState.INST_ACK));
526
527 // Check that the high level intent 3 was not affected
528 assertThat(reroutedHighLevelIntents,
529 hasIntentWithIdAndState("3", IntentState.INST_ACK));
530
531 final IntentMap reroutedPathIntents = runtime.getPathIntents();
532 assertThat(processedPathIntents, notNullValue());
533
534 // Check that the low level intent 1 was correctly processed
Pavlin Radoslavove2238bc2014-06-09 18:05:23 -0700535 assertThat(reroutedPathIntents.getAllIntents(),
536 not(hasIntentWithId("1___0")));
Toshio Koidec2112c22014-06-05 19:59:15 -0700537 assertThat(reroutedPathIntents,
538 hasIntentWithIdAndState("1___1", IntentState.INST_ACK));
539
540 // Check that the low level intent 2 was not affected
541 assertThat(reroutedPathIntents,
542 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
543
544 // Check that the low level intent 3 was not affected
545 assertThat(reroutedPathIntents,
546 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
Ray Milkey6688cd82014-03-11 16:40:46 -0700547 }
Toshio Koideee698952014-06-11 13:35:30 -0700548
549 /**
550 * Test the result of executing a path calculation on an
551 * Intent Operation List and then forcing a reroute and
552 * an interrupt of a topology change event while the reroute
553 * is processed.
554 * <p/>
555 * A 3 path list is created, one of the links is removed, then
556 * the removed link is restored.
557 * The test checks that if the high level intent was marked
558 * as stale when a topology changed event was received while
559 * processing reroute then the stale high level intent is executed
560 * once again after completion of its reroute.
561 */
562 @Test
563 public void testIntentRerouteWithTopologyEventInterrupt() {
564
565 // create shortest path intents
566 final IntentOperationList opList = new IntentOperationList();
567 opList.add(Operator.ADD,
568 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
569 LOCAL_PORT));
570 opList.add(Operator.ADD,
571 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
572 LOCAL_PORT));
573 opList.add(Operator.ADD,
574 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
575 LOCAL_PORT));
576
577 // compile high-level intent operations into low-level intent
578 // operations (calculate paths)
579 final IntentOperationList pathIntentOpList =
580 runtime.executeIntentOperations(opList);
581 assertThat(pathIntentOpList, notNullValue());
582
583 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
584 assertThat(highLevelIntents, notNullValue());
585
586 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
587 assertThat(allIntents, notNullValue());
588
589 // Should be one operation per path
590 assertThat(pathIntentOpList, hasSize(opList.size()));
591
592 // Should be a high level intent for each operation
593 assertThat(allIntents, hasSize(opList.size()));
594
595 // Check that we got a high level intent for each operation
596 assertThat(allIntents, hasIntentWithId("3"));
597 assertThat(allIntents, hasIntentWithId("2"));
598 assertThat(allIntents, hasIntentWithId("1"));
599
600 // Check that the high level intent 1 was correctly processed
601 assertThat(highLevelIntents,
602 hasIntentWithIdAndState("1", IntentState.INST_REQ));
603
604 // Check that the high level intent 2 was correctly processed
605 assertThat(highLevelIntents,
606 hasIntentWithIdAndState("2", IntentState.INST_REQ));
607
608 // Check that the high level intent 3 was correctly processed
609 assertThat(highLevelIntents,
610 hasIntentWithIdAndState("3", IntentState.INST_REQ));
611
612 final IntentMap pathIntents = runtime.getPathIntents();
613 assertThat(pathIntents, notNullValue());
614
615 final Collection<Intent> allPathIntents = pathIntents.getAllIntents();
616 assertThat(allPathIntents, notNullValue());
617
618 // Check that we got a low level intent for each operation
619 assertThat(allPathIntents, hasIntentWithId("3___0"));
620 assertThat(allPathIntents, hasIntentWithId("2___0"));
621 assertThat(allPathIntents, hasIntentWithId("1___0"));
622
623 // Check that the low level intent 1 was correctly processed
624 assertThat(pathIntents,
625 hasIntentWithIdAndState("1___0", IntentState.INST_REQ));
626
627 // Check that the low level intent 2 was correctly processed
628 assertThat(pathIntents,
629 hasIntentWithIdAndState("2___0", IntentState.INST_REQ));
630
631 // Check that the low level intent 3 was correctly processed
632 assertThat(pathIntents,
633 hasIntentWithIdAndState("3___0", IntentState.INST_REQ));
634
635 // Receive notification from south-bound
636 IntentStateList isl = new IntentStateList();
637 isl.put("1___0", IntentState.INST_ACK);
638 isl.put("2___0", IntentState.INST_ACK);
639 isl.put("3___0", IntentState.INST_ACK);
640 isl.domainSwitchDpids.add(1L);
641 isl.domainSwitchDpids.add(2L);
642 isl.domainSwitchDpids.add(3L);
643 isl.domainSwitchDpids.add(4L);
644 runtime.entryUpdated(isl);
645
646 // Now check the results
647 final IntentMap processedHighLevelIntents = runtime.getHighLevelIntents();
648 assertThat(processedHighLevelIntents, notNullValue());
649
650 // Check that the high level intent 1 was correctly processed
651 assertThat(processedHighLevelIntents,
652 hasIntentWithIdAndState("1", IntentState.INST_ACK));
653
654 // Check that the high level intent 2 was correctly processed
655 assertThat(processedHighLevelIntents,
656 hasIntentWithIdAndState("2", IntentState.INST_ACK));
657
658 // Check that the high level intent 3 was correctly processed
659 assertThat(processedHighLevelIntents,
660 hasIntentWithIdAndState("3", IntentState.INST_ACK));
661
662 final IntentMap processedPathIntents = runtime.getPathIntents();
663 assertThat(processedPathIntents, notNullValue());
664
665 // Check that the low level intent 1 was correctly processed
666 assertThat(processedPathIntents,
667 hasIntentWithIdAndState("1___0", IntentState.INST_ACK));
668
669 // Check that the low level intent 2 was correctly processed
670 assertThat(processedPathIntents,
671 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
672
673 // Check that the low level intent 3 was correctly processed
674 assertThat(processedPathIntents,
675 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
676
677
678 // Remove one of the links and check results
679 final List<SwitchEvent> emptySwitchEvents = new LinkedList<>();
680 final List<PortEvent> emptyPortEvents = new LinkedList<>();
681 final List<DeviceEvent> emptyDeviceEvents = new LinkedList<>();
682 final List<LinkEvent> addedLinkEvents = new LinkedList<>();
683 final List<LinkEvent> removedLinkEvents = new LinkedList<>();
684
685 final MockTopology topology = mocks.getTopology();
686 topology.removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
687 topology.removeLink(2L, 21L, 1L, 12L);
688 final LinkEvent linkEvent1 = new LinkEvent(1L, 12L, 2L, 21L);
689 final LinkEvent linkEvent2 = new LinkEvent(2L, 21L, 1L, 12L);
690 removedLinkEvents.add(linkEvent1);
691 removedLinkEvents.add(linkEvent2);
692 runtime.topologyEvents(
693 emptySwitchEvents,
694 emptySwitchEvents,
695 emptyPortEvents,
696 emptyPortEvents,
697 addedLinkEvents,
698 removedLinkEvents,
699 emptyDeviceEvents,
700 emptyDeviceEvents);
701
702 // Check the high level intents.
703 final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
704 assertThat(highLevelIntentsAfterReroute, notNullValue());
705
706 // Check the states of the high level intents
707 // Check that the high level intent 1 was correctly processed
708 assertThat(highLevelIntentsAfterReroute,
709 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
710
711 // Check that the high level intent 2 was not affected
712 assertThat(highLevelIntentsAfterReroute,
713 hasIntentWithIdAndState("2", IntentState.INST_ACK));
714
715 // Check that the high level intent 3 was not affected
716 assertThat(highLevelIntentsAfterReroute,
717 hasIntentWithIdAndState("3", IntentState.INST_ACK));
718
719 final IntentMap pathIntentsAfterReroute = runtime.getPathIntents();
720 assertThat(pathIntentsAfterReroute, notNullValue());
721
722 // Check that the low level intent 1 was correctly processed
723 assertThat(pathIntentsAfterReroute,
724 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
725 assertThat(pathIntentsAfterReroute,
726 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
727
728 // Check that the low level intent 2 was not affected
729 assertThat(pathIntentsAfterReroute,
730 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
731
732 // Check that the low level intent 3 was not affected
733 assertThat(pathIntentsAfterReroute,
734 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
735
736 // Interrupt by topology changed event while the reroute
737 removedLinkEvents.clear();
738 addedLinkEvents.clear();
739 topology.addBidirectionalLinks(1L, 12L, 2L, 21L); // Restoration of the failure
740 addedLinkEvents.add(linkEvent1);
741 addedLinkEvents.add(linkEvent2);
742 runtime.topologyEvents(
743 emptySwitchEvents,
744 emptySwitchEvents,
745 emptyPortEvents,
746 emptyPortEvents,
747 addedLinkEvents,
748 removedLinkEvents,
749 emptyDeviceEvents,
750 emptyDeviceEvents);
751
752 // Check the high level intents.
753 final IntentMap highLevelIntentsAfterInterrupt = runtime.getHighLevelIntents();
754 assertThat(highLevelIntentsAfterInterrupt, notNullValue());
755
756 // Check the states of the high level intents
757 // Check that the high level intent 1 was not affected
758 assertThat(highLevelIntentsAfterInterrupt,
759 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
760
761 final IntentMap pathIntentsAfterInterrupt = runtime.getPathIntents();
762 assertThat(pathIntentsAfterInterrupt, notNullValue());
763
764 // Check that the low level intent 1 was not affected
765 assertThat(pathIntentsAfterInterrupt,
766 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
767 assertThat(pathIntentsAfterInterrupt,
768 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
769
770 // Receive notification from south-bound
771 isl = new IntentStateList();
772 isl.put("1___0", IntentState.DEL_ACK);
773 isl.put("1___1", IntentState.INST_ACK);
774 isl.domainSwitchDpids.add(1L);
775 isl.domainSwitchDpids.add(2L);
776 isl.domainSwitchDpids.add(4L);
777 runtime.entryUpdated(isl);
778
779 // Now check the results
780 final IntentMap reroutedHighLevelIntents = runtime.getHighLevelIntents();
781 assertThat(reroutedHighLevelIntents, notNullValue());
782
783 // Check that the high level intent 1 was correctly processed
784 // It should be rerouted once again
785 assertThat(reroutedHighLevelIntents,
786 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
787
788 // Check that the high level intent 2 was not affected
789 assertThat(reroutedHighLevelIntents,
790 hasIntentWithIdAndState("2", IntentState.INST_ACK));
791
792 // Check that the high level intent 3 was not affected
793 assertThat(reroutedHighLevelIntents,
794 hasIntentWithIdAndState("3", IntentState.INST_ACK));
795
796 final IntentMap reroutedPathIntents = runtime.getPathIntents();
797 assertThat(processedPathIntents, notNullValue());
798
799 // Check that the low level intent 1 was correctly processed
800 assertThat(reroutedPathIntents.getAllIntents(),
801 not(hasIntentWithId("1___0")));
802 assertThat(reroutedPathIntents,
803 hasIntentWithIdAndState("1___1", IntentState.DEL_REQ));
804 assertThat(reroutedPathIntents,
805 hasIntentWithIdAndState("1___2", IntentState.INST_REQ));
806
807 // Check that the low level intent 2 was not affected
808 assertThat(reroutedPathIntents,
809 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
810
811 // Check that the low level intent 3 was not affected
812 assertThat(reroutedPathIntents,
813 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
814 }
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700815 // CHECKSTYLE:ON method too long
816
Ray Milkey6688cd82014-03-11 16:40:46 -0700817}