blob: 1ae1bb9374b4e941158841fcc785306dfa4d25c3 [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;
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -070026import net.onrc.onos.core.topology.TopologyEvents;
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -070027import net.onrc.onos.core.util.SwitchPort;
Ray Milkey6688cd82014-03-11 16:40:46 -070028
Jonathan Harta88fd242014-04-03 11:24:54 -070029import org.hamcrest.Description;
30import org.hamcrest.Factory;
31import org.hamcrest.Matcher;
32import org.hamcrest.Matchers;
33import org.hamcrest.TypeSafeMatcher;
Ray Milkey6688cd82014-03-11 16:40:46 -070034import org.junit.After;
35import org.junit.Before;
36import org.junit.Test;
37import org.junit.runner.RunWith;
Ray Milkey6688cd82014-03-11 16:40:46 -070038import org.powermock.core.classloader.annotations.PrepareForTest;
39import org.powermock.modules.junit4.PowerMockRunner;
40
Ray Milkey6688cd82014-03-11 16:40:46 -070041/**
Ray Milkey269ffb92014-04-03 14:43:30 -070042 * 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<>();
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700461 TopologyEvents topologyEvents;
Ray Milkeydc659c42014-03-28 16:30:42 -0700462
Ray Milkey9d671002014-05-29 17:24:29 -0700463 final MockTopology topology = mocks.getTopology();
Jonathan Harte37e4e22014-05-13 19:12:02 -0700464 topology.removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
465 topology.removeLink(2L, 21L, 1L, 12L);
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700466 LinkEvent linkEvent1 = new LinkEvent(new SwitchPort(1L, 12L), new SwitchPort(2L, 21L));
467 LinkEvent linkEvent2 = new LinkEvent(new SwitchPort(2L, 21L), new SwitchPort(1L, 12L));
Ray Milkeydc659c42014-03-28 16:30:42 -0700468 removedLinkEvents.add(linkEvent1);
469 removedLinkEvents.add(linkEvent2);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700470
471 topologyEvents = new TopologyEvents(0,
472 emptySwitchEvents,
473 emptySwitchEvents,
474 emptyPortEvents,
475 emptyPortEvents,
476 addedLinkEvents,
477 removedLinkEvents,
478 emptyDeviceEvents,
479 emptyDeviceEvents);
480
481 runtime.topologyEvents(topologyEvents);
Ray Milkeydc659c42014-03-28 16:30:42 -0700482
483 // Check the high level intents.
484 final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
485 assertThat(highLevelIntentsAfterReroute, notNullValue());
486
Ray Milkeydc659c42014-03-28 16:30:42 -0700487 // Check the states of the high level intents
Toshio Koidec2112c22014-06-05 19:59:15 -0700488 // Check that the high level intent 1 was correctly processed
489 assertThat(highLevelIntentsAfterReroute,
490 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700491
Toshio Koidec2112c22014-06-05 19:59:15 -0700492 // Check that the high level intent 2 was not affected
493 assertThat(highLevelIntentsAfterReroute,
Ray Milkeydc659c42014-03-28 16:30:42 -0700494 hasIntentWithIdAndState("2", IntentState.INST_ACK));
495
Toshio Koidec2112c22014-06-05 19:59:15 -0700496 // Check that the high level intent 3 was not affected
497 assertThat(highLevelIntentsAfterReroute,
Ray Milkeydc659c42014-03-28 16:30:42 -0700498 hasIntentWithIdAndState("3", IntentState.INST_ACK));
499
Toshio Koidec2112c22014-06-05 19:59:15 -0700500 final IntentMap pathIntentsAfterReroute = runtime.getPathIntents();
501 assertThat(pathIntentsAfterReroute, notNullValue());
Ray Milkey6688cd82014-03-11 16:40:46 -0700502
Toshio Koidec2112c22014-06-05 19:59:15 -0700503 // Check that the low level intent 1 was correctly processed
504 assertThat(pathIntentsAfterReroute,
505 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
506 assertThat(pathIntentsAfterReroute,
507 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
508
509 // Check that the low level intent 2 was not affected
510 assertThat(pathIntentsAfterReroute,
511 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
512
513 // Check that the low level intent 3 was not affected
514 assertThat(pathIntentsAfterReroute,
515 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
516
517 // Receive notification from south-bound
518 isl = new IntentStateList();
519 isl.put("1___0", IntentState.DEL_ACK);
520 isl.put("1___1", IntentState.INST_ACK);
521 isl.domainSwitchDpids.add(1L);
522 isl.domainSwitchDpids.add(2L);
523 isl.domainSwitchDpids.add(4L);
524 runtime.entryUpdated(isl);
525
526 // Now check the results
527 final IntentMap reroutedHighLevelIntents = runtime.getHighLevelIntents();
528 assertThat(reroutedHighLevelIntents, notNullValue());
529
530 // Check that the high level intent 1 was correctly processed
531 assertThat(reroutedHighLevelIntents,
532 hasIntentWithIdAndState("1", IntentState.INST_ACK));
533
534 // Check that the high level intent 2 was not affected
535 assertThat(reroutedHighLevelIntents,
536 hasIntentWithIdAndState("2", IntentState.INST_ACK));
537
538 // Check that the high level intent 3 was not affected
539 assertThat(reroutedHighLevelIntents,
540 hasIntentWithIdAndState("3", IntentState.INST_ACK));
541
542 final IntentMap reroutedPathIntents = runtime.getPathIntents();
543 assertThat(processedPathIntents, notNullValue());
544
545 // Check that the low level intent 1 was correctly processed
Pavlin Radoslavove2238bc2014-06-09 18:05:23 -0700546 assertThat(reroutedPathIntents.getAllIntents(),
547 not(hasIntentWithId("1___0")));
Toshio Koidec2112c22014-06-05 19:59:15 -0700548 assertThat(reroutedPathIntents,
549 hasIntentWithIdAndState("1___1", IntentState.INST_ACK));
550
551 // Check that the low level intent 2 was not affected
552 assertThat(reroutedPathIntents,
553 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
554
555 // Check that the low level intent 3 was not affected
556 assertThat(reroutedPathIntents,
557 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
Ray Milkey6688cd82014-03-11 16:40:46 -0700558 }
Toshio Koideee698952014-06-11 13:35:30 -0700559
560 /**
561 * Test the result of executing a path calculation on an
562 * Intent Operation List and then forcing a reroute and
563 * an interrupt of a topology change event while the reroute
564 * is processed.
565 * <p/>
566 * A 3 path list is created, one of the links is removed, then
567 * the removed link is restored.
568 * The test checks that if the high level intent was marked
569 * as stale when a topology changed event was received while
570 * processing reroute then the stale high level intent is executed
571 * once again after completion of its reroute.
572 */
573 @Test
574 public void testIntentRerouteWithTopologyEventInterrupt() {
575
576 // create shortest path intents
577 final IntentOperationList opList = new IntentOperationList();
578 opList.add(Operator.ADD,
579 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
580 LOCAL_PORT));
581 opList.add(Operator.ADD,
582 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
583 LOCAL_PORT));
584 opList.add(Operator.ADD,
585 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
586 LOCAL_PORT));
587
588 // compile high-level intent operations into low-level intent
589 // operations (calculate paths)
590 final IntentOperationList pathIntentOpList =
591 runtime.executeIntentOperations(opList);
592 assertThat(pathIntentOpList, notNullValue());
593
594 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
595 assertThat(highLevelIntents, notNullValue());
596
597 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
598 assertThat(allIntents, notNullValue());
599
600 // Should be one operation per path
601 assertThat(pathIntentOpList, hasSize(opList.size()));
602
603 // Should be a high level intent for each operation
604 assertThat(allIntents, hasSize(opList.size()));
605
606 // Check that we got a high level intent for each operation
607 assertThat(allIntents, hasIntentWithId("3"));
608 assertThat(allIntents, hasIntentWithId("2"));
609 assertThat(allIntents, hasIntentWithId("1"));
610
611 // Check that the high level intent 1 was correctly processed
612 assertThat(highLevelIntents,
613 hasIntentWithIdAndState("1", IntentState.INST_REQ));
614
615 // Check that the high level intent 2 was correctly processed
616 assertThat(highLevelIntents,
617 hasIntentWithIdAndState("2", IntentState.INST_REQ));
618
619 // Check that the high level intent 3 was correctly processed
620 assertThat(highLevelIntents,
621 hasIntentWithIdAndState("3", IntentState.INST_REQ));
622
623 final IntentMap pathIntents = runtime.getPathIntents();
624 assertThat(pathIntents, notNullValue());
625
626 final Collection<Intent> allPathIntents = pathIntents.getAllIntents();
627 assertThat(allPathIntents, notNullValue());
628
629 // Check that we got a low level intent for each operation
630 assertThat(allPathIntents, hasIntentWithId("3___0"));
631 assertThat(allPathIntents, hasIntentWithId("2___0"));
632 assertThat(allPathIntents, hasIntentWithId("1___0"));
633
634 // Check that the low level intent 1 was correctly processed
635 assertThat(pathIntents,
636 hasIntentWithIdAndState("1___0", IntentState.INST_REQ));
637
638 // Check that the low level intent 2 was correctly processed
639 assertThat(pathIntents,
640 hasIntentWithIdAndState("2___0", IntentState.INST_REQ));
641
642 // Check that the low level intent 3 was correctly processed
643 assertThat(pathIntents,
644 hasIntentWithIdAndState("3___0", IntentState.INST_REQ));
645
646 // Receive notification from south-bound
647 IntentStateList isl = new IntentStateList();
648 isl.put("1___0", IntentState.INST_ACK);
649 isl.put("2___0", IntentState.INST_ACK);
650 isl.put("3___0", IntentState.INST_ACK);
651 isl.domainSwitchDpids.add(1L);
652 isl.domainSwitchDpids.add(2L);
653 isl.domainSwitchDpids.add(3L);
654 isl.domainSwitchDpids.add(4L);
655 runtime.entryUpdated(isl);
656
657 // Now check the results
658 final IntentMap processedHighLevelIntents = runtime.getHighLevelIntents();
659 assertThat(processedHighLevelIntents, notNullValue());
660
661 // Check that the high level intent 1 was correctly processed
662 assertThat(processedHighLevelIntents,
663 hasIntentWithIdAndState("1", IntentState.INST_ACK));
664
665 // Check that the high level intent 2 was correctly processed
666 assertThat(processedHighLevelIntents,
667 hasIntentWithIdAndState("2", IntentState.INST_ACK));
668
669 // Check that the high level intent 3 was correctly processed
670 assertThat(processedHighLevelIntents,
671 hasIntentWithIdAndState("3", IntentState.INST_ACK));
672
673 final IntentMap processedPathIntents = runtime.getPathIntents();
674 assertThat(processedPathIntents, notNullValue());
675
676 // Check that the low level intent 1 was correctly processed
677 assertThat(processedPathIntents,
678 hasIntentWithIdAndState("1___0", IntentState.INST_ACK));
679
680 // Check that the low level intent 2 was correctly processed
681 assertThat(processedPathIntents,
682 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
683
684 // Check that the low level intent 3 was correctly processed
685 assertThat(processedPathIntents,
686 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
687
688
689 // Remove one of the links and check results
690 final List<SwitchEvent> emptySwitchEvents = new LinkedList<>();
691 final List<PortEvent> emptyPortEvents = new LinkedList<>();
692 final List<DeviceEvent> emptyDeviceEvents = new LinkedList<>();
693 final List<LinkEvent> addedLinkEvents = new LinkedList<>();
694 final List<LinkEvent> removedLinkEvents = new LinkedList<>();
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700695 TopologyEvents topologyEvents;
Toshio Koideee698952014-06-11 13:35:30 -0700696
697 final MockTopology topology = mocks.getTopology();
698 topology.removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
699 topology.removeLink(2L, 21L, 1L, 12L);
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700700 final LinkEvent linkEvent1 = new LinkEvent(new SwitchPort(1L, 12L), new SwitchPort(2L, 21L));
701 final LinkEvent linkEvent2 = new LinkEvent(new SwitchPort(2L, 21L), new SwitchPort(1L, 12L));
Toshio Koideee698952014-06-11 13:35:30 -0700702 removedLinkEvents.add(linkEvent1);
703 removedLinkEvents.add(linkEvent2);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700704
705 topologyEvents = new TopologyEvents(0,
706 emptySwitchEvents,
707 emptySwitchEvents,
708 emptyPortEvents,
709 emptyPortEvents,
710 addedLinkEvents,
711 removedLinkEvents,
712 emptyDeviceEvents,
713 emptyDeviceEvents);
714
715 runtime.topologyEvents(topologyEvents);
Toshio Koideee698952014-06-11 13:35:30 -0700716
717 // Check the high level intents.
718 final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
719 assertThat(highLevelIntentsAfterReroute, notNullValue());
720
721 // Check the states of the high level intents
722 // Check that the high level intent 1 was correctly processed
723 assertThat(highLevelIntentsAfterReroute,
724 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
725
726 // Check that the high level intent 2 was not affected
727 assertThat(highLevelIntentsAfterReroute,
728 hasIntentWithIdAndState("2", IntentState.INST_ACK));
729
730 // Check that the high level intent 3 was not affected
731 assertThat(highLevelIntentsAfterReroute,
732 hasIntentWithIdAndState("3", IntentState.INST_ACK));
733
734 final IntentMap pathIntentsAfterReroute = runtime.getPathIntents();
735 assertThat(pathIntentsAfterReroute, notNullValue());
736
737 // Check that the low level intent 1 was correctly processed
738 assertThat(pathIntentsAfterReroute,
739 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
740 assertThat(pathIntentsAfterReroute,
741 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
742
743 // Check that the low level intent 2 was not affected
744 assertThat(pathIntentsAfterReroute,
745 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
746
747 // Check that the low level intent 3 was not affected
748 assertThat(pathIntentsAfterReroute,
749 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
750
751 // Interrupt by topology changed event while the reroute
752 removedLinkEvents.clear();
753 addedLinkEvents.clear();
754 topology.addBidirectionalLinks(1L, 12L, 2L, 21L); // Restoration of the failure
755 addedLinkEvents.add(linkEvent1);
756 addedLinkEvents.add(linkEvent2);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700757
758 topologyEvents = new TopologyEvents(0,
759 emptySwitchEvents,
760 emptySwitchEvents,
761 emptyPortEvents,
762 emptyPortEvents,
763 addedLinkEvents,
764 removedLinkEvents,
765 emptyDeviceEvents,
766 emptyDeviceEvents);
767
768 runtime.topologyEvents(topologyEvents);
Toshio Koideee698952014-06-11 13:35:30 -0700769
770 // Check the high level intents.
771 final IntentMap highLevelIntentsAfterInterrupt = runtime.getHighLevelIntents();
772 assertThat(highLevelIntentsAfterInterrupt, notNullValue());
773
774 // Check the states of the high level intents
775 // Check that the high level intent 1 was not affected
776 assertThat(highLevelIntentsAfterInterrupt,
777 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
778
779 final IntentMap pathIntentsAfterInterrupt = runtime.getPathIntents();
780 assertThat(pathIntentsAfterInterrupt, notNullValue());
781
782 // Check that the low level intent 1 was not affected
783 assertThat(pathIntentsAfterInterrupt,
784 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
785 assertThat(pathIntentsAfterInterrupt,
786 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
787
788 // Receive notification from south-bound
789 isl = new IntentStateList();
790 isl.put("1___0", IntentState.DEL_ACK);
791 isl.put("1___1", IntentState.INST_ACK);
792 isl.domainSwitchDpids.add(1L);
793 isl.domainSwitchDpids.add(2L);
794 isl.domainSwitchDpids.add(4L);
795 runtime.entryUpdated(isl);
796
797 // Now check the results
798 final IntentMap reroutedHighLevelIntents = runtime.getHighLevelIntents();
799 assertThat(reroutedHighLevelIntents, notNullValue());
800
801 // Check that the high level intent 1 was correctly processed
802 // It should be rerouted once again
803 assertThat(reroutedHighLevelIntents,
804 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
805
806 // Check that the high level intent 2 was not affected
807 assertThat(reroutedHighLevelIntents,
808 hasIntentWithIdAndState("2", IntentState.INST_ACK));
809
810 // Check that the high level intent 3 was not affected
811 assertThat(reroutedHighLevelIntents,
812 hasIntentWithIdAndState("3", IntentState.INST_ACK));
813
814 final IntentMap reroutedPathIntents = runtime.getPathIntents();
815 assertThat(processedPathIntents, notNullValue());
816
817 // Check that the low level intent 1 was correctly processed
818 assertThat(reroutedPathIntents.getAllIntents(),
819 not(hasIntentWithId("1___0")));
820 assertThat(reroutedPathIntents,
821 hasIntentWithIdAndState("1___1", IntentState.DEL_REQ));
822 assertThat(reroutedPathIntents,
823 hasIntentWithIdAndState("1___2", IntentState.INST_REQ));
824
825 // Check that the low level intent 2 was not affected
826 assertThat(reroutedPathIntents,
827 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
828
829 // Check that the low level intent 3 was not affected
830 assertThat(reroutedPathIntents,
831 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
832 }
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700833 // CHECKSTYLE:ON method too long
834
Ray Milkey6688cd82014-03-11 16:40:46 -0700835}