blob: 568b2421c763a2cfd0adeef10b309c1943d0a269 [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;
Ray Milkey6688cd82014-03-11 16:40:46 -070027
Jonathan Harta88fd242014-04-03 11:24:54 -070028import org.hamcrest.Description;
29import org.hamcrest.Factory;
30import org.hamcrest.Matcher;
31import org.hamcrest.Matchers;
32import org.hamcrest.TypeSafeMatcher;
Ray Milkey6688cd82014-03-11 16:40:46 -070033import org.junit.After;
34import org.junit.Before;
35import org.junit.Test;
36import org.junit.runner.RunWith;
Ray Milkey6688cd82014-03-11 16:40:46 -070037import org.powermock.core.classloader.annotations.PrepareForTest;
38import org.powermock.modules.junit4.PowerMockRunner;
39
Ray Milkey6688cd82014-03-11 16:40:46 -070040/**
Ray Milkey269ffb92014-04-03 14:43:30 -070041 * Unit tests for the Path Calculation Runtime module (PathCalcRuntimeModule).
42 * These test cases check the results of creating paths, deleting paths, and
Jonathan Harte37e4e22014-05-13 19:12:02 -070043 * rerouting paths. The topology, controller registry, and data grid are
Ray Milkey269ffb92014-04-03 14:43:30 -070044 * mocked out. The individual tests check the high level intents and the
45 * resulting operation lists to be sure they match the intended APIs.
Ray Milkey6688cd82014-03-11 16:40:46 -070046 */
47@RunWith(PowerMockRunner.class)
48@PrepareForTest(PathCalcRuntimeModule.class)
49public class PathCalcRuntimeModuleTest {
Ray Milkeydc659c42014-03-28 16:30:42 -070050 private static final Long LOCAL_PORT = 0xFFFEL;
51
Ray Milkey9d671002014-05-29 17:24:29 -070052 private IntentTestMocks mocks;
53 private PathCalcRuntimeModule runtime;
Ray Milkey6688cd82014-03-11 16:40:46 -070054
Ray Milkey6688cd82014-03-11 16:40:46 -070055 @Before
56 public void setUp() throws Exception {
Ray Milkey9d671002014-05-29 17:24:29 -070057 mocks = new IntentTestMocks();
58 mocks.setUpIntentMocks();
Ray Milkey6688cd82014-03-11 16:40:46 -070059
Ray Milkey9d671002014-05-29 17:24:29 -070060 runtime = new PathCalcRuntimeModule();
61 final FloodlightModuleContext moduleContext = mocks.getModuleContext();
62 runtime.init(moduleContext);
63 runtime.startUp(moduleContext);
Ray Milkey6688cd82014-03-11 16:40:46 -070064 }
65
Ray Milkeydc659c42014-03-28 16:30:42 -070066
67 /**
68 * Hamcrest matcher to check that a collection of Intents contains an
69 * Intent with the specified Intent Id.
70 */
71 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070072 private final String id;
Ray Milkeydc659c42014-03-28 16:30:42 -070073
74 public EntryForIntentMatcher(String idValue) {
75 id = idValue;
76 }
77
78 @Override
79 public boolean matchesSafely(Collection<Intent> intents) {
Pavlin Radoslavove2238bc2014-06-09 18:05:23 -070080 return hasItem(Matchers.<Intent>hasProperty("id", equalTo(id))).matches(intents);
Ray Milkeydc659c42014-03-28 16:30:42 -070081 }
82
83 @Override
84 public void describeTo(Description description) {
85 description.appendText("an intent with id \" ").
86 appendText(id).
87 appendText("\"");
88 }
89 }
90
91
92 /**
93 * Factory method to create an Intent entry Matcher. Returns a matcher
94 * for the Intent with the given id.
Ray Milkey269ffb92014-04-03 14:43:30 -070095 *
Ray Milkeydc659c42014-03-28 16:30:42 -070096 * @param id id of the intent to match
97 * @return Matcher object
98 */
99 @Factory
100 public static Matcher<Collection<Intent>> hasIntentWithId(String id) {
101 return new EntryForIntentMatcher(id);
102 }
103
104
105 /**
106 * Matcher to determine if an IntentMap contains an entry with a given id,
107 * and that entry has a given state.
108 */
109 public static class IntentsHaveIntentWithStateMatcher extends TypeSafeMatcher<IntentMap> {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700110 private final String id;
111 private final IntentState state;
Ray Milkeydc659c42014-03-28 16:30:42 -0700112 private Intent intent;
113
114 public IntentsHaveIntentWithStateMatcher(String idValue,
115 IntentState stateValue) {
116 id = idValue;
117 state = stateValue;
118 }
119
120 @Override
121 public boolean matchesSafely(IntentMap intents) {
122 intent = intents.getIntent(id);
123
124 return intent != null && intent.getState() == state;
125 }
126
127 @Override
128 public void describeTo(Description description) {
129 if (intent == null) {
130 description.appendText("intent lookup for id \"");
131 description.appendText(id);
132 description.appendText("\"");
133 } else {
134 description.appendText("state ");
135 description.appendText(state.toString());
136 }
137 }
138
139 @Override
140 public void describeMismatchSafely(IntentMap intents,
141 Description mismatchDescription) {
142 if (intent != null) {
143 mismatchDescription.appendText("was ").
Ray Milkey269ffb92014-04-03 14:43:30 -0700144 appendText(intent.getState().toString());
Ray Milkeydc659c42014-03-28 16:30:42 -0700145 } else {
146 mismatchDescription.appendText("that intent was not found");
147 }
148 }
149 }
150
151
152 /**
153 * Factory method to create a Matcher for an IntentMap that looks for an
154 * Intent with a given id and state.
155 *
Ray Milkey269ffb92014-04-03 14:43:30 -0700156 * @param id id of the Intent to match
Ray Milkeydc659c42014-03-28 16:30:42 -0700157 * @param state if the Intent is found, its state must match this
158 * @return Matcher object
159 */
160 @Factory
161 public static Matcher<IntentMap> hasIntentWithIdAndState(String id,
162 IntentState state) {
163 return new IntentsHaveIntentWithStateMatcher(id, state);
164 }
165
166
Ray Milkey6688cd82014-03-11 16:40:46 -0700167 @After
168 public void tearDown() {
Ray Milkey9d671002014-05-29 17:24:29 -0700169 mocks.tearDownIntentMocks();
Ray Milkey6688cd82014-03-11 16:40:46 -0700170 }
171
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700172 private static final String BAD_SWITCH_INTENT_NAME = "No Such Switch Intent";
173
Ray Milkey6688cd82014-03-11 16:40:46 -0700174 /**
175 * Test the result of executing a path calculation on an
176 * Intent Operation List which contains a path that references a
177 * non-existent switch.
Ray Milkey269ffb92014-04-03 14:43:30 -0700178 * <p/>
Ray Milkey6688cd82014-03-11 16:40:46 -0700179 * A 3 path list is created where one of the paths references a switch
180 * that is not in the topology. The test checks that the resulting
181 * Operation List has entries for the 2 correct paths, and that the
182 * high level intents contain a proper error entry for the bad path.
183 */
184 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700185 public void testInvalidSwitchName() {
Ray Milkey6688cd82014-03-11 16:40:46 -0700186
187 // create shortest path intents
188 final IntentOperationList opList = new IntentOperationList();
189 opList.add(Operator.ADD,
190 new ShortestPathIntent(BAD_SWITCH_INTENT_NAME, 111L, 12L,
191 LOCAL_PORT, 2L, 21L, LOCAL_PORT));
192 opList.add(Operator.ADD,
193 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
194 LOCAL_PORT));
195 opList.add(Operator.ADD,
196 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
197 LOCAL_PORT));
198
199 // compile high-level intent operations into low-level intent
200 // operations (calculate paths)
Ray Milkey6688cd82014-03-11 16:40:46 -0700201 final IntentOperationList pathIntentOpList =
202 runtime.executeIntentOperations(opList);
203 assertThat(pathIntentOpList, notNullValue());
204
205 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
206 assertThat(highLevelIntents, notNullValue());
207
208 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
209 assertThat(allIntents, notNullValue());
210
211 // One intent had an error and should not create a path list entry
212 assertThat(pathIntentOpList, hasSize(opList.size() - 1));
213
214 // Should be a high level intent for each operation
Ray Milkeydc659c42014-03-28 16:30:42 -0700215 assertThat(allIntents, hasSize(opList.size()));
Ray Milkey6688cd82014-03-11 16:40:46 -0700216
217 // Check that we got a high level intent for each operation
Ray Milkeydc659c42014-03-28 16:30:42 -0700218 assertThat(allIntents, hasIntentWithId("3"));
219 assertThat(allIntents, hasIntentWithId("2"));
220 assertThat(allIntents, hasIntentWithId(BAD_SWITCH_INTENT_NAME));
Ray Milkey6688cd82014-03-11 16:40:46 -0700221
222 // Check that the non existent switch was NACKed
Ray Milkeydc659c42014-03-28 16:30:42 -0700223 assertThat(highLevelIntents, hasIntentWithIdAndState(BAD_SWITCH_INTENT_NAME, IntentState.INST_NACK));
Ray Milkey6688cd82014-03-11 16:40:46 -0700224
225 // Check that switch 2 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700226 assertThat(highLevelIntents, hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkey6688cd82014-03-11 16:40:46 -0700227
228 // Check that switch 3 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700229 assertThat(highLevelIntents, hasIntentWithIdAndState("3", IntentState.INST_REQ));
230
231 }
232
233
234 /**
235 * Test the result of executing a path calculation on an
236 * Intent Operation List and then removing one of the switches.
Ray Milkey269ffb92014-04-03 14:43:30 -0700237 * <p/>
Ray Milkeydc659c42014-03-28 16:30:42 -0700238 * A 3 path list is created and then one of the paths is removed.
239 * The test checks that the resulting Operation List is correct,
240 * and that the high level intents contain a proper "delete requested"
241 * entry for the deleted path.
242 */
243 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700244 public void testIntentRemoval() {
Ray Milkeydc659c42014-03-28 16:30:42 -0700245 // create shortest path intents
246 final IntentOperationList opList = new IntentOperationList();
247 opList.add(Operator.ADD,
248 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700249 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700250 opList.add(Operator.ADD,
251 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700252 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700253 opList.add(Operator.ADD,
254 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700255 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700256
257 // compile high-level intent operations into low-level intent
258 // operations (calculate paths)
Ray Milkeydc659c42014-03-28 16:30:42 -0700259 final IntentOperationList pathIntentOpList =
260 runtime.executeIntentOperations(opList);
261 assertThat(pathIntentOpList, notNullValue());
262
263 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
264 assertThat(highLevelIntents, notNullValue());
265
266 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
267 assertThat(allIntents, notNullValue());
268
269 // Should be one operation per path
270 assertThat(pathIntentOpList, hasSize(opList.size()));
271
272 // Should be a high level intent for each operation
273 assertThat(allIntents, hasSize(opList.size()));
274
275 // Check that we got a high level intent for each operation
276 assertThat(allIntents, hasIntentWithId("3"));
277 assertThat(allIntents, hasIntentWithId("2"));
278 assertThat(allIntents, hasIntentWithId("1"));
279
280 // Check that switch 1 was correctly processed
281 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700282 hasIntentWithIdAndState("1", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700283
284 // Check that switch 2 was correctly processed
285 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700286 hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700287
288 // Check that switch 3 was correctly processed
289 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700290 hasIntentWithIdAndState("3", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700291
292 // Now delete one path and check the results
293 final IntentOperationList opListForRemoval = new IntentOperationList();
294 opListForRemoval.add(Operator.REMOVE,
295 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
296 LOCAL_PORT));
297
298 final IntentOperationList pathIntentOpListAfterRemoval =
299 runtime.executeIntentOperations(opListForRemoval);
300 assertThat(pathIntentOpListAfterRemoval, notNullValue());
301 assertThat(pathIntentOpListAfterRemoval, hasSize(1));
302
303 // Check the high level intents.
304 final IntentMap highLevelIntentsAfterRemoval = runtime.getHighLevelIntents();
305 assertThat(highLevelIntentsAfterRemoval, notNullValue());
306
307 final Collection<Intent> allIntentsAfterRemoval = highLevelIntentsAfterRemoval.getAllIntents();
308 assertThat(allIntentsAfterRemoval, notNullValue());
309 assertThat(allIntentsAfterRemoval, hasSize(3));
310
311 // Check that we got a high level intent for each operation
312 assertThat(allIntentsAfterRemoval, hasIntentWithId("3"));
313 assertThat(allIntentsAfterRemoval, hasIntentWithId("2"));
314 assertThat(allIntentsAfterRemoval, hasIntentWithId("1"));
315
316 // Check the states of the high level intents
317 // Check that switch 1 was correctly processed
318 assertThat(highLevelIntents,
319 hasIntentWithIdAndState("1", IntentState.DEL_REQ));
320
321 // Check that switch 2 was correctly processed
322 assertThat(highLevelIntents,
323 hasIntentWithIdAndState("2", IntentState.INST_REQ));
324
325 // Check that switch 3 was correctly processed
326 assertThat(highLevelIntents,
327 hasIntentWithIdAndState("3", IntentState.INST_REQ));
328 }
329
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700330 // CHECKSTYLE:OFF method too long
Ray Milkeydc659c42014-03-28 16:30:42 -0700331 /**
332 * Test the result of executing a path calculation on an
333 * Intent Operation List and then forcing a reroute.
Ray Milkey269ffb92014-04-03 14:43:30 -0700334 * <p/>
Ray Milkeydc659c42014-03-28 16:30:42 -0700335 * A 3 path list is created and then one of the links is removed.
336 * The test checks that the resulting Operation List is correct,
337 * and that the high level intents contain a proper "reroute requested"
338 * entry for the deleted link.
339 */
340 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700341 public void testIntentReroute() {
Ray Milkeydc659c42014-03-28 16:30:42 -0700342 // create shortest path intents
343 final IntentOperationList opList = new IntentOperationList();
Toshio Koideee698952014-06-11 13:35:30 -0700344 opList.add(Operator.ADD,
Ray Milkeydc659c42014-03-28 16:30:42 -0700345 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
Toshio Koideee698952014-06-11 13:35:30 -0700346 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700347 opList.add(Operator.ADD,
348 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700349 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700350 opList.add(Operator.ADD,
351 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700352 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700353
354 // compile high-level intent operations into low-level intent
355 // operations (calculate paths)
Ray Milkeydc659c42014-03-28 16:30:42 -0700356 final IntentOperationList pathIntentOpList =
357 runtime.executeIntentOperations(opList);
358 assertThat(pathIntentOpList, notNullValue());
359
360 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
361 assertThat(highLevelIntents, notNullValue());
362
363 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
364 assertThat(allIntents, notNullValue());
365
366 // Should be one operation per path
367 assertThat(pathIntentOpList, hasSize(opList.size()));
368
369 // Should be a high level intent for each operation
370 assertThat(allIntents, hasSize(opList.size()));
371
372 // Check that we got a high level intent for each operation
373 assertThat(allIntents, hasIntentWithId("3"));
374 assertThat(allIntents, hasIntentWithId("2"));
375 assertThat(allIntents, hasIntentWithId("1"));
376
Toshio Koidec2112c22014-06-05 19:59:15 -0700377 // Check that the high level intent 1 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700378 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700379 hasIntentWithIdAndState("1", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700380
Toshio Koidec2112c22014-06-05 19:59:15 -0700381 // Check that the high level intent 2 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700382 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700383 hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700384
Toshio Koidec2112c22014-06-05 19:59:15 -0700385 // Check that the high level intent 3 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700386 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700387 hasIntentWithIdAndState("3", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700388
Toshio Koidec2112c22014-06-05 19:59:15 -0700389 final IntentMap pathIntents = runtime.getPathIntents();
390 assertThat(pathIntents, notNullValue());
Ray Milkeydc659c42014-03-28 16:30:42 -0700391
Toshio Koidec2112c22014-06-05 19:59:15 -0700392 final Collection<Intent> allPathIntents = pathIntents.getAllIntents();
393 assertThat(allPathIntents, notNullValue());
394
395 // Check that we got a low level intent for each operation
396 assertThat(allPathIntents, hasIntentWithId("3___0"));
397 assertThat(allPathIntents, hasIntentWithId("2___0"));
398 assertThat(allPathIntents, hasIntentWithId("1___0"));
399
400 // Check that the low level intent 1 was correctly processed
401 assertThat(pathIntents,
402 hasIntentWithIdAndState("1___0", IntentState.INST_REQ));
403
404 // Check that the low level intent 2 was correctly processed
405 assertThat(pathIntents,
406 hasIntentWithIdAndState("2___0", IntentState.INST_REQ));
407
408 // Check that the low level intent 3 was correctly processed
409 assertThat(pathIntents,
410 hasIntentWithIdAndState("3___0", IntentState.INST_REQ));
411
412 // Receive notification from south-bound
413 IntentStateList isl = new IntentStateList();
414 isl.put("1___0", IntentState.INST_ACK);
415 isl.put("2___0", IntentState.INST_ACK);
416 isl.put("3___0", IntentState.INST_ACK);
417 isl.domainSwitchDpids.add(1L);
418 isl.domainSwitchDpids.add(2L);
419 isl.domainSwitchDpids.add(3L);
420 isl.domainSwitchDpids.add(4L);
421 runtime.entryUpdated(isl);
422
423 // Now check the results
424 final IntentMap processedHighLevelIntents = runtime.getHighLevelIntents();
425 assertThat(processedHighLevelIntents, notNullValue());
426
427 // Check that the high level intent 1 was correctly processed
428 assertThat(processedHighLevelIntents,
429 hasIntentWithIdAndState("1", IntentState.INST_ACK));
430
431 // Check that the high level intent 2 was correctly processed
432 assertThat(processedHighLevelIntents,
433 hasIntentWithIdAndState("2", IntentState.INST_ACK));
434
435 // Check that the high level intent 3 was correctly processed
436 assertThat(processedHighLevelIntents,
437 hasIntentWithIdAndState("3", IntentState.INST_ACK));
438
439 final IntentMap processedPathIntents = runtime.getPathIntents();
440 assertThat(processedPathIntents, notNullValue());
441
442 // Check that the low level intent 1 was correctly processed
443 assertThat(processedPathIntents,
444 hasIntentWithIdAndState("1___0", IntentState.INST_ACK));
445
446 // Check that the low level intent 2 was correctly processed
447 assertThat(processedPathIntents,
448 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
449
450 // Check that the low level intent 3 was correctly processed
451 assertThat(processedPathIntents,
452 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
453
Toshio Koidec2112c22014-06-05 19:59:15 -0700454 // Remove one of the links and check results
Ray Milkeydc659c42014-03-28 16:30:42 -0700455 final List<SwitchEvent> emptySwitchEvents = new LinkedList<>();
456 final List<PortEvent> emptyPortEvents = new LinkedList<>();
457 final List<DeviceEvent> emptyDeviceEvents = new LinkedList<>();
458 final List<LinkEvent> addedLinkEvents = new LinkedList<>();
459 final List<LinkEvent> removedLinkEvents = new LinkedList<>();
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700460 TopologyEvents topologyEvents;
Ray Milkeydc659c42014-03-28 16:30:42 -0700461
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);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700469
470 topologyEvents = new TopologyEvents(0,
471 emptySwitchEvents,
472 emptySwitchEvents,
473 emptyPortEvents,
474 emptyPortEvents,
475 addedLinkEvents,
476 removedLinkEvents,
477 emptyDeviceEvents,
478 emptyDeviceEvents);
479
480 runtime.topologyEvents(topologyEvents);
Ray Milkeydc659c42014-03-28 16:30:42 -0700481
482 // Check the high level intents.
483 final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
484 assertThat(highLevelIntentsAfterReroute, notNullValue());
485
Ray Milkeydc659c42014-03-28 16:30:42 -0700486 // Check the states of the high level intents
Toshio Koidec2112c22014-06-05 19:59:15 -0700487 // Check that the high level intent 1 was correctly processed
488 assertThat(highLevelIntentsAfterReroute,
489 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700490
Toshio Koidec2112c22014-06-05 19:59:15 -0700491 // Check that the high level intent 2 was not affected
492 assertThat(highLevelIntentsAfterReroute,
Ray Milkeydc659c42014-03-28 16:30:42 -0700493 hasIntentWithIdAndState("2", IntentState.INST_ACK));
494
Toshio Koidec2112c22014-06-05 19:59:15 -0700495 // Check that the high level intent 3 was not affected
496 assertThat(highLevelIntentsAfterReroute,
Ray Milkeydc659c42014-03-28 16:30:42 -0700497 hasIntentWithIdAndState("3", IntentState.INST_ACK));
498
Toshio Koidec2112c22014-06-05 19:59:15 -0700499 final IntentMap pathIntentsAfterReroute = runtime.getPathIntents();
500 assertThat(pathIntentsAfterReroute, notNullValue());
Ray Milkey6688cd82014-03-11 16:40:46 -0700501
Toshio Koidec2112c22014-06-05 19:59:15 -0700502 // Check that the low level intent 1 was correctly processed
503 assertThat(pathIntentsAfterReroute,
504 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
505 assertThat(pathIntentsAfterReroute,
506 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
507
508 // Check that the low level intent 2 was not affected
509 assertThat(pathIntentsAfterReroute,
510 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
511
512 // Check that the low level intent 3 was not affected
513 assertThat(pathIntentsAfterReroute,
514 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
515
516 // Receive notification from south-bound
517 isl = new IntentStateList();
518 isl.put("1___0", IntentState.DEL_ACK);
519 isl.put("1___1", IntentState.INST_ACK);
520 isl.domainSwitchDpids.add(1L);
521 isl.domainSwitchDpids.add(2L);
522 isl.domainSwitchDpids.add(4L);
523 runtime.entryUpdated(isl);
524
525 // Now check the results
526 final IntentMap reroutedHighLevelIntents = runtime.getHighLevelIntents();
527 assertThat(reroutedHighLevelIntents, notNullValue());
528
529 // Check that the high level intent 1 was correctly processed
530 assertThat(reroutedHighLevelIntents,
531 hasIntentWithIdAndState("1", IntentState.INST_ACK));
532
533 // Check that the high level intent 2 was not affected
534 assertThat(reroutedHighLevelIntents,
535 hasIntentWithIdAndState("2", IntentState.INST_ACK));
536
537 // Check that the high level intent 3 was not affected
538 assertThat(reroutedHighLevelIntents,
539 hasIntentWithIdAndState("3", IntentState.INST_ACK));
540
541 final IntentMap reroutedPathIntents = runtime.getPathIntents();
542 assertThat(processedPathIntents, notNullValue());
543
544 // Check that the low level intent 1 was correctly processed
Pavlin Radoslavove2238bc2014-06-09 18:05:23 -0700545 assertThat(reroutedPathIntents.getAllIntents(),
546 not(hasIntentWithId("1___0")));
Toshio Koidec2112c22014-06-05 19:59:15 -0700547 assertThat(reroutedPathIntents,
548 hasIntentWithIdAndState("1___1", IntentState.INST_ACK));
549
550 // Check that the low level intent 2 was not affected
551 assertThat(reroutedPathIntents,
552 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
553
554 // Check that the low level intent 3 was not affected
555 assertThat(reroutedPathIntents,
556 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
Ray Milkey6688cd82014-03-11 16:40:46 -0700557 }
Toshio Koideee698952014-06-11 13:35:30 -0700558
559 /**
560 * Test the result of executing a path calculation on an
561 * Intent Operation List and then forcing a reroute and
562 * an interrupt of a topology change event while the reroute
563 * is processed.
564 * <p/>
565 * A 3 path list is created, one of the links is removed, then
566 * the removed link is restored.
567 * The test checks that if the high level intent was marked
568 * as stale when a topology changed event was received while
569 * processing reroute then the stale high level intent is executed
570 * once again after completion of its reroute.
571 */
572 @Test
573 public void testIntentRerouteWithTopologyEventInterrupt() {
574
575 // create shortest path intents
576 final IntentOperationList opList = new IntentOperationList();
577 opList.add(Operator.ADD,
578 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
579 LOCAL_PORT));
580 opList.add(Operator.ADD,
581 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
582 LOCAL_PORT));
583 opList.add(Operator.ADD,
584 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
585 LOCAL_PORT));
586
587 // compile high-level intent operations into low-level intent
588 // operations (calculate paths)
589 final IntentOperationList pathIntentOpList =
590 runtime.executeIntentOperations(opList);
591 assertThat(pathIntentOpList, notNullValue());
592
593 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
594 assertThat(highLevelIntents, notNullValue());
595
596 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
597 assertThat(allIntents, notNullValue());
598
599 // Should be one operation per path
600 assertThat(pathIntentOpList, hasSize(opList.size()));
601
602 // Should be a high level intent for each operation
603 assertThat(allIntents, hasSize(opList.size()));
604
605 // Check that we got a high level intent for each operation
606 assertThat(allIntents, hasIntentWithId("3"));
607 assertThat(allIntents, hasIntentWithId("2"));
608 assertThat(allIntents, hasIntentWithId("1"));
609
610 // Check that the high level intent 1 was correctly processed
611 assertThat(highLevelIntents,
612 hasIntentWithIdAndState("1", IntentState.INST_REQ));
613
614 // Check that the high level intent 2 was correctly processed
615 assertThat(highLevelIntents,
616 hasIntentWithIdAndState("2", IntentState.INST_REQ));
617
618 // Check that the high level intent 3 was correctly processed
619 assertThat(highLevelIntents,
620 hasIntentWithIdAndState("3", IntentState.INST_REQ));
621
622 final IntentMap pathIntents = runtime.getPathIntents();
623 assertThat(pathIntents, notNullValue());
624
625 final Collection<Intent> allPathIntents = pathIntents.getAllIntents();
626 assertThat(allPathIntents, notNullValue());
627
628 // Check that we got a low level intent for each operation
629 assertThat(allPathIntents, hasIntentWithId("3___0"));
630 assertThat(allPathIntents, hasIntentWithId("2___0"));
631 assertThat(allPathIntents, hasIntentWithId("1___0"));
632
633 // Check that the low level intent 1 was correctly processed
634 assertThat(pathIntents,
635 hasIntentWithIdAndState("1___0", IntentState.INST_REQ));
636
637 // Check that the low level intent 2 was correctly processed
638 assertThat(pathIntents,
639 hasIntentWithIdAndState("2___0", IntentState.INST_REQ));
640
641 // Check that the low level intent 3 was correctly processed
642 assertThat(pathIntents,
643 hasIntentWithIdAndState("3___0", IntentState.INST_REQ));
644
645 // Receive notification from south-bound
646 IntentStateList isl = new IntentStateList();
647 isl.put("1___0", IntentState.INST_ACK);
648 isl.put("2___0", IntentState.INST_ACK);
649 isl.put("3___0", IntentState.INST_ACK);
650 isl.domainSwitchDpids.add(1L);
651 isl.domainSwitchDpids.add(2L);
652 isl.domainSwitchDpids.add(3L);
653 isl.domainSwitchDpids.add(4L);
654 runtime.entryUpdated(isl);
655
656 // Now check the results
657 final IntentMap processedHighLevelIntents = runtime.getHighLevelIntents();
658 assertThat(processedHighLevelIntents, notNullValue());
659
660 // Check that the high level intent 1 was correctly processed
661 assertThat(processedHighLevelIntents,
662 hasIntentWithIdAndState("1", IntentState.INST_ACK));
663
664 // Check that the high level intent 2 was correctly processed
665 assertThat(processedHighLevelIntents,
666 hasIntentWithIdAndState("2", IntentState.INST_ACK));
667
668 // Check that the high level intent 3 was correctly processed
669 assertThat(processedHighLevelIntents,
670 hasIntentWithIdAndState("3", IntentState.INST_ACK));
671
672 final IntentMap processedPathIntents = runtime.getPathIntents();
673 assertThat(processedPathIntents, notNullValue());
674
675 // Check that the low level intent 1 was correctly processed
676 assertThat(processedPathIntents,
677 hasIntentWithIdAndState("1___0", IntentState.INST_ACK));
678
679 // Check that the low level intent 2 was correctly processed
680 assertThat(processedPathIntents,
681 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
682
683 // Check that the low level intent 3 was correctly processed
684 assertThat(processedPathIntents,
685 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
686
687
688 // Remove one of the links and check results
689 final List<SwitchEvent> emptySwitchEvents = new LinkedList<>();
690 final List<PortEvent> emptyPortEvents = new LinkedList<>();
691 final List<DeviceEvent> emptyDeviceEvents = new LinkedList<>();
692 final List<LinkEvent> addedLinkEvents = new LinkedList<>();
693 final List<LinkEvent> removedLinkEvents = new LinkedList<>();
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700694 TopologyEvents topologyEvents;
Toshio Koideee698952014-06-11 13:35:30 -0700695
696 final MockTopology topology = mocks.getTopology();
697 topology.removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
698 topology.removeLink(2L, 21L, 1L, 12L);
699 final LinkEvent linkEvent1 = new LinkEvent(1L, 12L, 2L, 21L);
700 final LinkEvent linkEvent2 = new LinkEvent(2L, 21L, 1L, 12L);
701 removedLinkEvents.add(linkEvent1);
702 removedLinkEvents.add(linkEvent2);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700703
704 topologyEvents = new TopologyEvents(0,
705 emptySwitchEvents,
706 emptySwitchEvents,
707 emptyPortEvents,
708 emptyPortEvents,
709 addedLinkEvents,
710 removedLinkEvents,
711 emptyDeviceEvents,
712 emptyDeviceEvents);
713
714 runtime.topologyEvents(topologyEvents);
Toshio Koideee698952014-06-11 13:35:30 -0700715
716 // Check the high level intents.
717 final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
718 assertThat(highLevelIntentsAfterReroute, notNullValue());
719
720 // Check the states of the high level intents
721 // Check that the high level intent 1 was correctly processed
722 assertThat(highLevelIntentsAfterReroute,
723 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
724
725 // Check that the high level intent 2 was not affected
726 assertThat(highLevelIntentsAfterReroute,
727 hasIntentWithIdAndState("2", IntentState.INST_ACK));
728
729 // Check that the high level intent 3 was not affected
730 assertThat(highLevelIntentsAfterReroute,
731 hasIntentWithIdAndState("3", IntentState.INST_ACK));
732
733 final IntentMap pathIntentsAfterReroute = runtime.getPathIntents();
734 assertThat(pathIntentsAfterReroute, notNullValue());
735
736 // Check that the low level intent 1 was correctly processed
737 assertThat(pathIntentsAfterReroute,
738 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
739 assertThat(pathIntentsAfterReroute,
740 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
741
742 // Check that the low level intent 2 was not affected
743 assertThat(pathIntentsAfterReroute,
744 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
745
746 // Check that the low level intent 3 was not affected
747 assertThat(pathIntentsAfterReroute,
748 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
749
750 // Interrupt by topology changed event while the reroute
751 removedLinkEvents.clear();
752 addedLinkEvents.clear();
753 topology.addBidirectionalLinks(1L, 12L, 2L, 21L); // Restoration of the failure
754 addedLinkEvents.add(linkEvent1);
755 addedLinkEvents.add(linkEvent2);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700756
757 topologyEvents = new TopologyEvents(0,
758 emptySwitchEvents,
759 emptySwitchEvents,
760 emptyPortEvents,
761 emptyPortEvents,
762 addedLinkEvents,
763 removedLinkEvents,
764 emptyDeviceEvents,
765 emptyDeviceEvents);
766
767 runtime.topologyEvents(topologyEvents);
Toshio Koideee698952014-06-11 13:35:30 -0700768
769 // Check the high level intents.
770 final IntentMap highLevelIntentsAfterInterrupt = runtime.getHighLevelIntents();
771 assertThat(highLevelIntentsAfterInterrupt, notNullValue());
772
773 // Check the states of the high level intents
774 // Check that the high level intent 1 was not affected
775 assertThat(highLevelIntentsAfterInterrupt,
776 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
777
778 final IntentMap pathIntentsAfterInterrupt = runtime.getPathIntents();
779 assertThat(pathIntentsAfterInterrupt, notNullValue());
780
781 // Check that the low level intent 1 was not affected
782 assertThat(pathIntentsAfterInterrupt,
783 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
784 assertThat(pathIntentsAfterInterrupt,
785 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
786
787 // Receive notification from south-bound
788 isl = new IntentStateList();
789 isl.put("1___0", IntentState.DEL_ACK);
790 isl.put("1___1", IntentState.INST_ACK);
791 isl.domainSwitchDpids.add(1L);
792 isl.domainSwitchDpids.add(2L);
793 isl.domainSwitchDpids.add(4L);
794 runtime.entryUpdated(isl);
795
796 // Now check the results
797 final IntentMap reroutedHighLevelIntents = runtime.getHighLevelIntents();
798 assertThat(reroutedHighLevelIntents, notNullValue());
799
800 // Check that the high level intent 1 was correctly processed
801 // It should be rerouted once again
802 assertThat(reroutedHighLevelIntents,
803 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
804
805 // Check that the high level intent 2 was not affected
806 assertThat(reroutedHighLevelIntents,
807 hasIntentWithIdAndState("2", IntentState.INST_ACK));
808
809 // Check that the high level intent 3 was not affected
810 assertThat(reroutedHighLevelIntents,
811 hasIntentWithIdAndState("3", IntentState.INST_ACK));
812
813 final IntentMap reroutedPathIntents = runtime.getPathIntents();
814 assertThat(processedPathIntents, notNullValue());
815
816 // Check that the low level intent 1 was correctly processed
817 assertThat(reroutedPathIntents.getAllIntents(),
818 not(hasIntentWithId("1___0")));
819 assertThat(reroutedPathIntents,
820 hasIntentWithIdAndState("1___1", IntentState.DEL_REQ));
821 assertThat(reroutedPathIntents,
822 hasIntentWithIdAndState("1___2", IntentState.INST_REQ));
823
824 // Check that the low level intent 2 was not affected
825 assertThat(reroutedPathIntents,
826 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
827
828 // Check that the low level intent 3 was not affected
829 assertThat(reroutedPathIntents,
830 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
831 }
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700832 // CHECKSTYLE:ON method too long
833
Ray Milkey6688cd82014-03-11 16:40:46 -0700834}