blob: 262042f67f4fe1b19ce7a68200e9617cf9970efa [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 Harte37e4e22014-05-13 19:12:02 -070020import net.onrc.onos.core.intent.MockTopology;
Jonathan Hartaa380972014-04-03 10:24:46 -070021import net.onrc.onos.core.intent.ShortestPathIntent;
Jonathan Hart472062d2014-04-03 10:56:48 -070022import net.onrc.onos.core.topology.DeviceEvent;
Jonathan Hart472062d2014-04-03 10:56:48 -070023import net.onrc.onos.core.topology.LinkEvent;
24import 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/**
40 * @author Ray Milkey (ray@onlab.us)
Ray Milkey269ffb92014-04-03 14:43:30 -070041 * <p/>
42 * Unit tests for the Path Calculation Runtime module (PathCalcRuntimeModule).
43 * These test cases check the results of creating paths, deleting paths, and
Jonathan Harte37e4e22014-05-13 19:12:02 -070044 * rerouting paths. The topology, controller registry, and data grid are
Ray Milkey269ffb92014-04-03 14:43:30 -070045 * mocked out. The individual tests check the high level intents and the
46 * resulting operation lists to be sure they match the intended APIs.
Ray Milkey6688cd82014-03-11 16:40:46 -070047 */
48@RunWith(PowerMockRunner.class)
49@PrepareForTest(PathCalcRuntimeModule.class)
50public class PathCalcRuntimeModuleTest {
Ray Milkeydc659c42014-03-28 16:30:42 -070051 private static final Long LOCAL_PORT = 0xFFFEL;
52
Ray Milkey9d671002014-05-29 17:24:29 -070053 private IntentTestMocks mocks;
54 private PathCalcRuntimeModule runtime;
Ray Milkey6688cd82014-03-11 16:40:46 -070055
Ray Milkey6688cd82014-03-11 16:40:46 -070056 @Before
57 public void setUp() throws Exception {
Ray Milkey9d671002014-05-29 17:24:29 -070058 mocks = new IntentTestMocks();
59 mocks.setUpIntentMocks();
Ray Milkey6688cd82014-03-11 16:40:46 -070060
Ray Milkey9d671002014-05-29 17:24:29 -070061 runtime = new PathCalcRuntimeModule();
62 final FloodlightModuleContext moduleContext = mocks.getModuleContext();
63 runtime.init(moduleContext);
64 runtime.startUp(moduleContext);
Ray Milkey6688cd82014-03-11 16:40:46 -070065 }
66
Ray Milkeydc659c42014-03-28 16:30:42 -070067
68 /**
69 * Hamcrest matcher to check that a collection of Intents contains an
70 * Intent with the specified Intent Id.
71 */
72 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070073 private final String id;
Ray Milkeydc659c42014-03-28 16:30:42 -070074
75 public EntryForIntentMatcher(String idValue) {
76 id = idValue;
77 }
78
79 @Override
80 public boolean matchesSafely(Collection<Intent> intents) {
Pavlin Radoslavove2238bc2014-06-09 18:05:23 -070081 return hasItem(Matchers.<Intent>hasProperty("id", equalTo(id))).matches(intents);
Ray Milkeydc659c42014-03-28 16:30:42 -070082 }
83
84 @Override
85 public void describeTo(Description description) {
86 description.appendText("an intent with id \" ").
87 appendText(id).
88 appendText("\"");
89 }
90 }
91
92
93 /**
94 * Factory method to create an Intent entry Matcher. Returns a matcher
95 * for the Intent with the given id.
Ray Milkey269ffb92014-04-03 14:43:30 -070096 *
Ray Milkeydc659c42014-03-28 16:30:42 -070097 * @param id id of the intent to match
98 * @return Matcher object
99 */
100 @Factory
101 public static Matcher<Collection<Intent>> hasIntentWithId(String id) {
102 return new EntryForIntentMatcher(id);
103 }
104
105
106 /**
107 * Matcher to determine if an IntentMap contains an entry with a given id,
108 * and that entry has a given state.
109 */
110 public static class IntentsHaveIntentWithStateMatcher extends TypeSafeMatcher<IntentMap> {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700111 private final String id;
112 private final IntentState state;
Ray Milkeydc659c42014-03-28 16:30:42 -0700113 private Intent intent;
114
115 public IntentsHaveIntentWithStateMatcher(String idValue,
116 IntentState stateValue) {
117 id = idValue;
118 state = stateValue;
119 }
120
121 @Override
122 public boolean matchesSafely(IntentMap intents) {
123 intent = intents.getIntent(id);
124
125 return intent != null && intent.getState() == state;
126 }
127
128 @Override
129 public void describeTo(Description description) {
130 if (intent == null) {
131 description.appendText("intent lookup for id \"");
132 description.appendText(id);
133 description.appendText("\"");
134 } else {
135 description.appendText("state ");
136 description.appendText(state.toString());
137 }
138 }
139
140 @Override
141 public void describeMismatchSafely(IntentMap intents,
142 Description mismatchDescription) {
143 if (intent != null) {
144 mismatchDescription.appendText("was ").
Ray Milkey269ffb92014-04-03 14:43:30 -0700145 appendText(intent.getState().toString());
Ray Milkeydc659c42014-03-28 16:30:42 -0700146 } else {
147 mismatchDescription.appendText("that intent was not found");
148 }
149 }
150 }
151
152
153 /**
154 * Factory method to create a Matcher for an IntentMap that looks for an
155 * Intent with a given id and state.
156 *
Ray Milkey269ffb92014-04-03 14:43:30 -0700157 * @param id id of the Intent to match
Ray Milkeydc659c42014-03-28 16:30:42 -0700158 * @param state if the Intent is found, its state must match this
159 * @return Matcher object
160 */
161 @Factory
162 public static Matcher<IntentMap> hasIntentWithIdAndState(String id,
163 IntentState state) {
164 return new IntentsHaveIntentWithStateMatcher(id, state);
165 }
166
167
Ray Milkey6688cd82014-03-11 16:40:46 -0700168 @After
169 public void tearDown() {
Ray Milkey9d671002014-05-29 17:24:29 -0700170 mocks.tearDownIntentMocks();
Ray Milkey6688cd82014-03-11 16:40:46 -0700171 }
172
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700173 private static final String BAD_SWITCH_INTENT_NAME = "No Such Switch Intent";
174
Ray Milkey6688cd82014-03-11 16:40:46 -0700175 /**
176 * Test the result of executing a path calculation on an
177 * Intent Operation List which contains a path that references a
178 * non-existent switch.
Ray Milkey269ffb92014-04-03 14:43:30 -0700179 * <p/>
Ray Milkey6688cd82014-03-11 16:40:46 -0700180 * A 3 path list is created where one of the paths references a switch
181 * that is not in the topology. The test checks that the resulting
182 * Operation List has entries for the 2 correct paths, and that the
183 * high level intents contain a proper error entry for the bad path.
184 */
185 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700186 public void testInvalidSwitchName() {
Ray Milkey6688cd82014-03-11 16:40:46 -0700187
188 // create shortest path intents
189 final IntentOperationList opList = new IntentOperationList();
190 opList.add(Operator.ADD,
191 new ShortestPathIntent(BAD_SWITCH_INTENT_NAME, 111L, 12L,
192 LOCAL_PORT, 2L, 21L, LOCAL_PORT));
193 opList.add(Operator.ADD,
194 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
195 LOCAL_PORT));
196 opList.add(Operator.ADD,
197 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
198 LOCAL_PORT));
199
200 // compile high-level intent operations into low-level intent
201 // operations (calculate paths)
Ray Milkey6688cd82014-03-11 16:40:46 -0700202 final IntentOperationList pathIntentOpList =
203 runtime.executeIntentOperations(opList);
204 assertThat(pathIntentOpList, notNullValue());
205
206 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
207 assertThat(highLevelIntents, notNullValue());
208
209 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
210 assertThat(allIntents, notNullValue());
211
212 // One intent had an error and should not create a path list entry
213 assertThat(pathIntentOpList, hasSize(opList.size() - 1));
214
215 // Should be a high level intent for each operation
Ray Milkeydc659c42014-03-28 16:30:42 -0700216 assertThat(allIntents, hasSize(opList.size()));
Ray Milkey6688cd82014-03-11 16:40:46 -0700217
218 // Check that we got a high level intent for each operation
Ray Milkeydc659c42014-03-28 16:30:42 -0700219 assertThat(allIntents, hasIntentWithId("3"));
220 assertThat(allIntents, hasIntentWithId("2"));
221 assertThat(allIntents, hasIntentWithId(BAD_SWITCH_INTENT_NAME));
Ray Milkey6688cd82014-03-11 16:40:46 -0700222
223 // Check that the non existent switch was NACKed
Ray Milkeydc659c42014-03-28 16:30:42 -0700224 assertThat(highLevelIntents, hasIntentWithIdAndState(BAD_SWITCH_INTENT_NAME, IntentState.INST_NACK));
Ray Milkey6688cd82014-03-11 16:40:46 -0700225
226 // Check that switch 2 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700227 assertThat(highLevelIntents, hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkey6688cd82014-03-11 16:40:46 -0700228
229 // Check that switch 3 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700230 assertThat(highLevelIntents, hasIntentWithIdAndState("3", IntentState.INST_REQ));
231
232 }
233
234
235 /**
236 * Test the result of executing a path calculation on an
237 * Intent Operation List and then removing one of the switches.
Ray Milkey269ffb92014-04-03 14:43:30 -0700238 * <p/>
Ray Milkeydc659c42014-03-28 16:30:42 -0700239 * A 3 path list is created and then one of the paths is removed.
240 * The test checks that the resulting Operation List is correct,
241 * and that the high level intents contain a proper "delete requested"
242 * entry for the deleted path.
243 */
244 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700245 public void testIntentRemoval() {
Ray Milkeydc659c42014-03-28 16:30:42 -0700246 // create shortest path intents
247 final IntentOperationList opList = new IntentOperationList();
248 opList.add(Operator.ADD,
249 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700250 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700251 opList.add(Operator.ADD,
252 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700253 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700254 opList.add(Operator.ADD,
255 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700256 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700257
258 // compile high-level intent operations into low-level intent
259 // operations (calculate paths)
Ray Milkeydc659c42014-03-28 16:30:42 -0700260 final IntentOperationList pathIntentOpList =
261 runtime.executeIntentOperations(opList);
262 assertThat(pathIntentOpList, notNullValue());
263
264 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
265 assertThat(highLevelIntents, notNullValue());
266
267 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
268 assertThat(allIntents, notNullValue());
269
270 // Should be one operation per path
271 assertThat(pathIntentOpList, hasSize(opList.size()));
272
273 // Should be a high level intent for each operation
274 assertThat(allIntents, hasSize(opList.size()));
275
276 // Check that we got a high level intent for each operation
277 assertThat(allIntents, hasIntentWithId("3"));
278 assertThat(allIntents, hasIntentWithId("2"));
279 assertThat(allIntents, hasIntentWithId("1"));
280
281 // Check that switch 1 was correctly processed
282 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700283 hasIntentWithIdAndState("1", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700284
285 // Check that switch 2 was correctly processed
286 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700287 hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700288
289 // Check that switch 3 was correctly processed
290 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700291 hasIntentWithIdAndState("3", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700292
293 // Now delete one path and check the results
294 final IntentOperationList opListForRemoval = new IntentOperationList();
295 opListForRemoval.add(Operator.REMOVE,
296 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
297 LOCAL_PORT));
298
299 final IntentOperationList pathIntentOpListAfterRemoval =
300 runtime.executeIntentOperations(opListForRemoval);
301 assertThat(pathIntentOpListAfterRemoval, notNullValue());
302 assertThat(pathIntentOpListAfterRemoval, hasSize(1));
303
304 // Check the high level intents.
305 final IntentMap highLevelIntentsAfterRemoval = runtime.getHighLevelIntents();
306 assertThat(highLevelIntentsAfterRemoval, notNullValue());
307
308 final Collection<Intent> allIntentsAfterRemoval = highLevelIntentsAfterRemoval.getAllIntents();
309 assertThat(allIntentsAfterRemoval, notNullValue());
310 assertThat(allIntentsAfterRemoval, hasSize(3));
311
312 // Check that we got a high level intent for each operation
313 assertThat(allIntentsAfterRemoval, hasIntentWithId("3"));
314 assertThat(allIntentsAfterRemoval, hasIntentWithId("2"));
315 assertThat(allIntentsAfterRemoval, hasIntentWithId("1"));
316
317 // Check the states of the high level intents
318 // Check that switch 1 was correctly processed
319 assertThat(highLevelIntents,
320 hasIntentWithIdAndState("1", IntentState.DEL_REQ));
321
322 // Check that switch 2 was correctly processed
323 assertThat(highLevelIntents,
324 hasIntentWithIdAndState("2", IntentState.INST_REQ));
325
326 // Check that switch 3 was correctly processed
327 assertThat(highLevelIntents,
328 hasIntentWithIdAndState("3", IntentState.INST_REQ));
329 }
330
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700331 // CHECKSTYLE:OFF method too long
Ray Milkeydc659c42014-03-28 16:30:42 -0700332 /**
333 * Test the result of executing a path calculation on an
334 * Intent Operation List and then forcing a reroute.
Ray Milkey269ffb92014-04-03 14:43:30 -0700335 * <p/>
Ray Milkeydc659c42014-03-28 16:30:42 -0700336 * A 3 path list is created and then one of the links is removed.
337 * The test checks that the resulting Operation List is correct,
338 * and that the high level intents contain a proper "reroute requested"
339 * entry for the deleted link.
340 */
341 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700342 public void testIntentReroute() {
Ray Milkeydc659c42014-03-28 16:30:42 -0700343 // create shortest path intents
344 final IntentOperationList opList = new IntentOperationList();
Toshio Koideee698952014-06-11 13:35:30 -0700345 opList.add(Operator.ADD,
Ray Milkeydc659c42014-03-28 16:30:42 -0700346 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
Toshio Koideee698952014-06-11 13:35:30 -0700347 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700348 opList.add(Operator.ADD,
349 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700350 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700351 opList.add(Operator.ADD,
352 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700353 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700354
355 // compile high-level intent operations into low-level intent
356 // operations (calculate paths)
Ray Milkeydc659c42014-03-28 16:30:42 -0700357 final IntentOperationList pathIntentOpList =
358 runtime.executeIntentOperations(opList);
359 assertThat(pathIntentOpList, notNullValue());
360
361 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
362 assertThat(highLevelIntents, notNullValue());
363
364 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
365 assertThat(allIntents, notNullValue());
366
367 // Should be one operation per path
368 assertThat(pathIntentOpList, hasSize(opList.size()));
369
370 // Should be a high level intent for each operation
371 assertThat(allIntents, hasSize(opList.size()));
372
373 // Check that we got a high level intent for each operation
374 assertThat(allIntents, hasIntentWithId("3"));
375 assertThat(allIntents, hasIntentWithId("2"));
376 assertThat(allIntents, hasIntentWithId("1"));
377
Toshio Koidec2112c22014-06-05 19:59:15 -0700378 // Check that the high level intent 1 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700379 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700380 hasIntentWithIdAndState("1", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700381
Toshio Koidec2112c22014-06-05 19:59:15 -0700382 // Check that the high level intent 2 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700383 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700384 hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700385
Toshio Koidec2112c22014-06-05 19:59:15 -0700386 // Check that the high level intent 3 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700387 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700388 hasIntentWithIdAndState("3", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700389
Toshio Koidec2112c22014-06-05 19:59:15 -0700390 final IntentMap pathIntents = runtime.getPathIntents();
391 assertThat(pathIntents, notNullValue());
Ray Milkeydc659c42014-03-28 16:30:42 -0700392
Toshio Koidec2112c22014-06-05 19:59:15 -0700393 final Collection<Intent> allPathIntents = pathIntents.getAllIntents();
394 assertThat(allPathIntents, notNullValue());
395
396 // Check that we got a low level intent for each operation
397 assertThat(allPathIntents, hasIntentWithId("3___0"));
398 assertThat(allPathIntents, hasIntentWithId("2___0"));
399 assertThat(allPathIntents, hasIntentWithId("1___0"));
400
401 // Check that the low level intent 1 was correctly processed
402 assertThat(pathIntents,
403 hasIntentWithIdAndState("1___0", IntentState.INST_REQ));
404
405 // Check that the low level intent 2 was correctly processed
406 assertThat(pathIntents,
407 hasIntentWithIdAndState("2___0", IntentState.INST_REQ));
408
409 // Check that the low level intent 3 was correctly processed
410 assertThat(pathIntents,
411 hasIntentWithIdAndState("3___0", IntentState.INST_REQ));
412
413 // Receive notification from south-bound
414 IntentStateList isl = new IntentStateList();
415 isl.put("1___0", IntentState.INST_ACK);
416 isl.put("2___0", IntentState.INST_ACK);
417 isl.put("3___0", IntentState.INST_ACK);
418 isl.domainSwitchDpids.add(1L);
419 isl.domainSwitchDpids.add(2L);
420 isl.domainSwitchDpids.add(3L);
421 isl.domainSwitchDpids.add(4L);
422 runtime.entryUpdated(isl);
423
424 // Now check the results
425 final IntentMap processedHighLevelIntents = runtime.getHighLevelIntents();
426 assertThat(processedHighLevelIntents, notNullValue());
427
428 // Check that the high level intent 1 was correctly processed
429 assertThat(processedHighLevelIntents,
430 hasIntentWithIdAndState("1", IntentState.INST_ACK));
431
432 // Check that the high level intent 2 was correctly processed
433 assertThat(processedHighLevelIntents,
434 hasIntentWithIdAndState("2", IntentState.INST_ACK));
435
436 // Check that the high level intent 3 was correctly processed
437 assertThat(processedHighLevelIntents,
438 hasIntentWithIdAndState("3", IntentState.INST_ACK));
439
440 final IntentMap processedPathIntents = runtime.getPathIntents();
441 assertThat(processedPathIntents, notNullValue());
442
443 // Check that the low level intent 1 was correctly processed
444 assertThat(processedPathIntents,
445 hasIntentWithIdAndState("1___0", IntentState.INST_ACK));
446
447 // Check that the low level intent 2 was correctly processed
448 assertThat(processedPathIntents,
449 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
450
451 // Check that the low level intent 3 was correctly processed
452 assertThat(processedPathIntents,
453 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
454
Toshio Koidec2112c22014-06-05 19:59:15 -0700455 // Remove one of the links and check results
Ray Milkeydc659c42014-03-28 16:30:42 -0700456 final List<SwitchEvent> emptySwitchEvents = new LinkedList<>();
457 final List<PortEvent> emptyPortEvents = new LinkedList<>();
458 final List<DeviceEvent> emptyDeviceEvents = new LinkedList<>();
459 final List<LinkEvent> addedLinkEvents = new LinkedList<>();
460 final List<LinkEvent> removedLinkEvents = new LinkedList<>();
461
Ray Milkey9d671002014-05-29 17:24:29 -0700462 final MockTopology topology = mocks.getTopology();
Jonathan Harte37e4e22014-05-13 19:12:02 -0700463 topology.removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
464 topology.removeLink(2L, 21L, 1L, 12L);
Ray Milkeydc659c42014-03-28 16:30:42 -0700465 LinkEvent linkEvent1 = new LinkEvent(1L, 12L, 2L, 21L);
466 LinkEvent linkEvent2 = new LinkEvent(2L, 21L, 1L, 12L);
467 removedLinkEvents.add(linkEvent1);
468 removedLinkEvents.add(linkEvent2);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700469 runtime.topologyEvents(emptySwitchEvents, emptySwitchEvents,
470 emptyPortEvents, emptyPortEvents,
471 addedLinkEvents, removedLinkEvents,
472 emptyDeviceEvents, emptyDeviceEvents);
Ray Milkeydc659c42014-03-28 16:30:42 -0700473
474 // Check the high level intents.
475 final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
476 assertThat(highLevelIntentsAfterReroute, notNullValue());
477
Ray Milkeydc659c42014-03-28 16:30:42 -0700478 // Check the states of the high level intents
Toshio Koidec2112c22014-06-05 19:59:15 -0700479 // Check that the high level intent 1 was correctly processed
480 assertThat(highLevelIntentsAfterReroute,
481 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700482
Toshio Koidec2112c22014-06-05 19:59:15 -0700483 // Check that the high level intent 2 was not affected
484 assertThat(highLevelIntentsAfterReroute,
Ray Milkeydc659c42014-03-28 16:30:42 -0700485 hasIntentWithIdAndState("2", IntentState.INST_ACK));
486
Toshio Koidec2112c22014-06-05 19:59:15 -0700487 // Check that the high level intent 3 was not affected
488 assertThat(highLevelIntentsAfterReroute,
Ray Milkeydc659c42014-03-28 16:30:42 -0700489 hasIntentWithIdAndState("3", IntentState.INST_ACK));
490
Toshio Koidec2112c22014-06-05 19:59:15 -0700491 final IntentMap pathIntentsAfterReroute = runtime.getPathIntents();
492 assertThat(pathIntentsAfterReroute, notNullValue());
Ray Milkey6688cd82014-03-11 16:40:46 -0700493
Toshio Koidec2112c22014-06-05 19:59:15 -0700494 // Check that the low level intent 1 was correctly processed
495 assertThat(pathIntentsAfterReroute,
496 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
497 assertThat(pathIntentsAfterReroute,
498 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
499
500 // Check that the low level intent 2 was not affected
501 assertThat(pathIntentsAfterReroute,
502 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
503
504 // Check that the low level intent 3 was not affected
505 assertThat(pathIntentsAfterReroute,
506 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
507
508 // Receive notification from south-bound
509 isl = new IntentStateList();
510 isl.put("1___0", IntentState.DEL_ACK);
511 isl.put("1___1", IntentState.INST_ACK);
512 isl.domainSwitchDpids.add(1L);
513 isl.domainSwitchDpids.add(2L);
514 isl.domainSwitchDpids.add(4L);
515 runtime.entryUpdated(isl);
516
517 // Now check the results
518 final IntentMap reroutedHighLevelIntents = runtime.getHighLevelIntents();
519 assertThat(reroutedHighLevelIntents, notNullValue());
520
521 // Check that the high level intent 1 was correctly processed
522 assertThat(reroutedHighLevelIntents,
523 hasIntentWithIdAndState("1", IntentState.INST_ACK));
524
525 // Check that the high level intent 2 was not affected
526 assertThat(reroutedHighLevelIntents,
527 hasIntentWithIdAndState("2", IntentState.INST_ACK));
528
529 // Check that the high level intent 3 was not affected
530 assertThat(reroutedHighLevelIntents,
531 hasIntentWithIdAndState("3", IntentState.INST_ACK));
532
533 final IntentMap reroutedPathIntents = runtime.getPathIntents();
534 assertThat(processedPathIntents, notNullValue());
535
536 // Check that the low level intent 1 was correctly processed
Pavlin Radoslavove2238bc2014-06-09 18:05:23 -0700537 assertThat(reroutedPathIntents.getAllIntents(),
538 not(hasIntentWithId("1___0")));
Toshio Koidec2112c22014-06-05 19:59:15 -0700539 assertThat(reroutedPathIntents,
540 hasIntentWithIdAndState("1___1", IntentState.INST_ACK));
541
542 // Check that the low level intent 2 was not affected
543 assertThat(reroutedPathIntents,
544 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
545
546 // Check that the low level intent 3 was not affected
547 assertThat(reroutedPathIntents,
548 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
Ray Milkey6688cd82014-03-11 16:40:46 -0700549 }
Toshio Koideee698952014-06-11 13:35:30 -0700550
551 /**
552 * Test the result of executing a path calculation on an
553 * Intent Operation List and then forcing a reroute and
554 * an interrupt of a topology change event while the reroute
555 * is processed.
556 * <p/>
557 * A 3 path list is created, one of the links is removed, then
558 * the removed link is restored.
559 * The test checks that if the high level intent was marked
560 * as stale when a topology changed event was received while
561 * processing reroute then the stale high level intent is executed
562 * once again after completion of its reroute.
563 */
564 @Test
565 public void testIntentRerouteWithTopologyEventInterrupt() {
566
567 // create shortest path intents
568 final IntentOperationList opList = new IntentOperationList();
569 opList.add(Operator.ADD,
570 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
571 LOCAL_PORT));
572 opList.add(Operator.ADD,
573 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
574 LOCAL_PORT));
575 opList.add(Operator.ADD,
576 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
577 LOCAL_PORT));
578
579 // compile high-level intent operations into low-level intent
580 // operations (calculate paths)
581 final IntentOperationList pathIntentOpList =
582 runtime.executeIntentOperations(opList);
583 assertThat(pathIntentOpList, notNullValue());
584
585 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
586 assertThat(highLevelIntents, notNullValue());
587
588 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
589 assertThat(allIntents, notNullValue());
590
591 // Should be one operation per path
592 assertThat(pathIntentOpList, hasSize(opList.size()));
593
594 // Should be a high level intent for each operation
595 assertThat(allIntents, hasSize(opList.size()));
596
597 // Check that we got a high level intent for each operation
598 assertThat(allIntents, hasIntentWithId("3"));
599 assertThat(allIntents, hasIntentWithId("2"));
600 assertThat(allIntents, hasIntentWithId("1"));
601
602 // Check that the high level intent 1 was correctly processed
603 assertThat(highLevelIntents,
604 hasIntentWithIdAndState("1", IntentState.INST_REQ));
605
606 // Check that the high level intent 2 was correctly processed
607 assertThat(highLevelIntents,
608 hasIntentWithIdAndState("2", IntentState.INST_REQ));
609
610 // Check that the high level intent 3 was correctly processed
611 assertThat(highLevelIntents,
612 hasIntentWithIdAndState("3", IntentState.INST_REQ));
613
614 final IntentMap pathIntents = runtime.getPathIntents();
615 assertThat(pathIntents, notNullValue());
616
617 final Collection<Intent> allPathIntents = pathIntents.getAllIntents();
618 assertThat(allPathIntents, notNullValue());
619
620 // Check that we got a low level intent for each operation
621 assertThat(allPathIntents, hasIntentWithId("3___0"));
622 assertThat(allPathIntents, hasIntentWithId("2___0"));
623 assertThat(allPathIntents, hasIntentWithId("1___0"));
624
625 // Check that the low level intent 1 was correctly processed
626 assertThat(pathIntents,
627 hasIntentWithIdAndState("1___0", IntentState.INST_REQ));
628
629 // Check that the low level intent 2 was correctly processed
630 assertThat(pathIntents,
631 hasIntentWithIdAndState("2___0", IntentState.INST_REQ));
632
633 // Check that the low level intent 3 was correctly processed
634 assertThat(pathIntents,
635 hasIntentWithIdAndState("3___0", IntentState.INST_REQ));
636
637 // Receive notification from south-bound
638 IntentStateList isl = new IntentStateList();
639 isl.put("1___0", IntentState.INST_ACK);
640 isl.put("2___0", IntentState.INST_ACK);
641 isl.put("3___0", IntentState.INST_ACK);
642 isl.domainSwitchDpids.add(1L);
643 isl.domainSwitchDpids.add(2L);
644 isl.domainSwitchDpids.add(3L);
645 isl.domainSwitchDpids.add(4L);
646 runtime.entryUpdated(isl);
647
648 // Now check the results
649 final IntentMap processedHighLevelIntents = runtime.getHighLevelIntents();
650 assertThat(processedHighLevelIntents, notNullValue());
651
652 // Check that the high level intent 1 was correctly processed
653 assertThat(processedHighLevelIntents,
654 hasIntentWithIdAndState("1", IntentState.INST_ACK));
655
656 // Check that the high level intent 2 was correctly processed
657 assertThat(processedHighLevelIntents,
658 hasIntentWithIdAndState("2", IntentState.INST_ACK));
659
660 // Check that the high level intent 3 was correctly processed
661 assertThat(processedHighLevelIntents,
662 hasIntentWithIdAndState("3", IntentState.INST_ACK));
663
664 final IntentMap processedPathIntents = runtime.getPathIntents();
665 assertThat(processedPathIntents, notNullValue());
666
667 // Check that the low level intent 1 was correctly processed
668 assertThat(processedPathIntents,
669 hasIntentWithIdAndState("1___0", IntentState.INST_ACK));
670
671 // Check that the low level intent 2 was correctly processed
672 assertThat(processedPathIntents,
673 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
674
675 // Check that the low level intent 3 was correctly processed
676 assertThat(processedPathIntents,
677 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
678
679
680 // Remove one of the links and check results
681 final List<SwitchEvent> emptySwitchEvents = new LinkedList<>();
682 final List<PortEvent> emptyPortEvents = new LinkedList<>();
683 final List<DeviceEvent> emptyDeviceEvents = new LinkedList<>();
684 final List<LinkEvent> addedLinkEvents = new LinkedList<>();
685 final List<LinkEvent> removedLinkEvents = new LinkedList<>();
686
687 final MockTopology topology = mocks.getTopology();
688 topology.removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
689 topology.removeLink(2L, 21L, 1L, 12L);
690 final LinkEvent linkEvent1 = new LinkEvent(1L, 12L, 2L, 21L);
691 final LinkEvent linkEvent2 = new LinkEvent(2L, 21L, 1L, 12L);
692 removedLinkEvents.add(linkEvent1);
693 removedLinkEvents.add(linkEvent2);
694 runtime.topologyEvents(
695 emptySwitchEvents,
696 emptySwitchEvents,
697 emptyPortEvents,
698 emptyPortEvents,
699 addedLinkEvents,
700 removedLinkEvents,
701 emptyDeviceEvents,
702 emptyDeviceEvents);
703
704 // Check the high level intents.
705 final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
706 assertThat(highLevelIntentsAfterReroute, notNullValue());
707
708 // Check the states of the high level intents
709 // Check that the high level intent 1 was correctly processed
710 assertThat(highLevelIntentsAfterReroute,
711 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
712
713 // Check that the high level intent 2 was not affected
714 assertThat(highLevelIntentsAfterReroute,
715 hasIntentWithIdAndState("2", IntentState.INST_ACK));
716
717 // Check that the high level intent 3 was not affected
718 assertThat(highLevelIntentsAfterReroute,
719 hasIntentWithIdAndState("3", IntentState.INST_ACK));
720
721 final IntentMap pathIntentsAfterReroute = runtime.getPathIntents();
722 assertThat(pathIntentsAfterReroute, notNullValue());
723
724 // Check that the low level intent 1 was correctly processed
725 assertThat(pathIntentsAfterReroute,
726 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
727 assertThat(pathIntentsAfterReroute,
728 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
729
730 // Check that the low level intent 2 was not affected
731 assertThat(pathIntentsAfterReroute,
732 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
733
734 // Check that the low level intent 3 was not affected
735 assertThat(pathIntentsAfterReroute,
736 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
737
738 // Interrupt by topology changed event while the reroute
739 removedLinkEvents.clear();
740 addedLinkEvents.clear();
741 topology.addBidirectionalLinks(1L, 12L, 2L, 21L); // Restoration of the failure
742 addedLinkEvents.add(linkEvent1);
743 addedLinkEvents.add(linkEvent2);
744 runtime.topologyEvents(
745 emptySwitchEvents,
746 emptySwitchEvents,
747 emptyPortEvents,
748 emptyPortEvents,
749 addedLinkEvents,
750 removedLinkEvents,
751 emptyDeviceEvents,
752 emptyDeviceEvents);
753
754 // Check the high level intents.
755 final IntentMap highLevelIntentsAfterInterrupt = runtime.getHighLevelIntents();
756 assertThat(highLevelIntentsAfterInterrupt, notNullValue());
757
758 // Check the states of the high level intents
759 // Check that the high level intent 1 was not affected
760 assertThat(highLevelIntentsAfterInterrupt,
761 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
762
763 final IntentMap pathIntentsAfterInterrupt = runtime.getPathIntents();
764 assertThat(pathIntentsAfterInterrupt, notNullValue());
765
766 // Check that the low level intent 1 was not affected
767 assertThat(pathIntentsAfterInterrupt,
768 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
769 assertThat(pathIntentsAfterInterrupt,
770 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
771
772 // Receive notification from south-bound
773 isl = new IntentStateList();
774 isl.put("1___0", IntentState.DEL_ACK);
775 isl.put("1___1", IntentState.INST_ACK);
776 isl.domainSwitchDpids.add(1L);
777 isl.domainSwitchDpids.add(2L);
778 isl.domainSwitchDpids.add(4L);
779 runtime.entryUpdated(isl);
780
781 // Now check the results
782 final IntentMap reroutedHighLevelIntents = runtime.getHighLevelIntents();
783 assertThat(reroutedHighLevelIntents, notNullValue());
784
785 // Check that the high level intent 1 was correctly processed
786 // It should be rerouted once again
787 assertThat(reroutedHighLevelIntents,
788 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
789
790 // Check that the high level intent 2 was not affected
791 assertThat(reroutedHighLevelIntents,
792 hasIntentWithIdAndState("2", IntentState.INST_ACK));
793
794 // Check that the high level intent 3 was not affected
795 assertThat(reroutedHighLevelIntents,
796 hasIntentWithIdAndState("3", IntentState.INST_ACK));
797
798 final IntentMap reroutedPathIntents = runtime.getPathIntents();
799 assertThat(processedPathIntents, notNullValue());
800
801 // Check that the low level intent 1 was correctly processed
802 assertThat(reroutedPathIntents.getAllIntents(),
803 not(hasIntentWithId("1___0")));
804 assertThat(reroutedPathIntents,
805 hasIntentWithIdAndState("1___1", IntentState.DEL_REQ));
806 assertThat(reroutedPathIntents,
807 hasIntentWithIdAndState("1___2", IntentState.INST_REQ));
808
809 // Check that the low level intent 2 was not affected
810 assertThat(reroutedPathIntents,
811 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
812
813 // Check that the low level intent 3 was not affected
814 assertThat(reroutedPathIntents,
815 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
816 }
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700817 // CHECKSTYLE:ON method too long
818
Ray Milkey6688cd82014-03-11 16:40:46 -0700819}