blob: a8e222e74cdf985caa7dbee5e607dac2b6c2c404 [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;
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -070021import net.onrc.onos.core.metrics.OnosMetrics;
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -070022import net.onrc.onos.core.topology.HostEvent;
Jonathan Hart472062d2014-04-03 10:56:48 -070023import net.onrc.onos.core.topology.LinkEvent;
TeruU5d2c9392014-06-09 20:02:02 -070024import net.onrc.onos.core.topology.MockTopology;
Jonathan Hart472062d2014-04-03 10:56:48 -070025import net.onrc.onos.core.topology.PortEvent;
26import net.onrc.onos.core.topology.SwitchEvent;
Yuta HIGUCHIb8093642014-07-16 13:17:07 -070027import net.onrc.onos.core.topology.TopologyElement;
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -070028import net.onrc.onos.core.topology.TopologyEvents;
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -070029import net.onrc.onos.core.util.SwitchPort;
Ray Milkey6688cd82014-03-11 16:40:46 -070030
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -070031import com.codahale.metrics.MetricFilter;
Jonathan Harta88fd242014-04-03 11:24:54 -070032import org.hamcrest.Description;
33import org.hamcrest.Factory;
34import org.hamcrest.Matcher;
35import org.hamcrest.Matchers;
36import org.hamcrest.TypeSafeMatcher;
Ray Milkey6688cd82014-03-11 16:40:46 -070037import org.junit.After;
38import org.junit.Before;
39import org.junit.Test;
40import org.junit.runner.RunWith;
Ray Milkey6688cd82014-03-11 16:40:46 -070041import org.powermock.core.classloader.annotations.PrepareForTest;
42import org.powermock.modules.junit4.PowerMockRunner;
43
Ray Milkey6688cd82014-03-11 16:40:46 -070044/**
Ray Milkey269ffb92014-04-03 14:43:30 -070045 * Unit tests for the Path Calculation Runtime module (PathCalcRuntimeModule).
46 * These test cases check the results of creating paths, deleting paths, and
Jonathan Harte37e4e22014-05-13 19:12:02 -070047 * rerouting paths. The topology, controller registry, and data grid are
Ray Milkey269ffb92014-04-03 14:43:30 -070048 * mocked out. The individual tests check the high level intents and the
49 * resulting operation lists to be sure they match the intended APIs.
Ray Milkey6688cd82014-03-11 16:40:46 -070050 */
51@RunWith(PowerMockRunner.class)
52@PrepareForTest(PathCalcRuntimeModule.class)
53public class PathCalcRuntimeModuleTest {
Ray Milkeydc659c42014-03-28 16:30:42 -070054 private static final Long LOCAL_PORT = 0xFFFEL;
55
Ray Milkey9d671002014-05-29 17:24:29 -070056 private IntentTestMocks mocks;
57 private PathCalcRuntimeModule runtime;
Ray Milkey6688cd82014-03-11 16:40:46 -070058
Ray Milkey6688cd82014-03-11 16:40:46 -070059 @Before
60 public void setUp() throws Exception {
Ray Milkey9d671002014-05-29 17:24:29 -070061 mocks = new IntentTestMocks();
62 mocks.setUpIntentMocks();
Ray Milkey6688cd82014-03-11 16:40:46 -070063
Ray Milkey9d671002014-05-29 17:24:29 -070064 runtime = new PathCalcRuntimeModule();
65 final FloodlightModuleContext moduleContext = mocks.getModuleContext();
66 runtime.init(moduleContext);
67 runtime.startUp(moduleContext);
Ray Milkey6688cd82014-03-11 16:40:46 -070068 }
69
Ray Milkeydc659c42014-03-28 16:30:42 -070070
71 /**
72 * Hamcrest matcher to check that a collection of Intents contains an
73 * Intent with the specified Intent Id.
74 */
75 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070076 private final String id;
Ray Milkeydc659c42014-03-28 16:30:42 -070077
78 public EntryForIntentMatcher(String idValue) {
79 id = idValue;
80 }
81
82 @Override
83 public boolean matchesSafely(Collection<Intent> intents) {
Pavlin Radoslavove2238bc2014-06-09 18:05:23 -070084 return hasItem(Matchers.<Intent>hasProperty("id", equalTo(id))).matches(intents);
Ray Milkeydc659c42014-03-28 16:30:42 -070085 }
86
87 @Override
88 public void describeTo(Description description) {
89 description.appendText("an intent with id \" ").
90 appendText(id).
91 appendText("\"");
92 }
93 }
94
95
96 /**
97 * Factory method to create an Intent entry Matcher. Returns a matcher
98 * for the Intent with the given id.
Ray Milkey269ffb92014-04-03 14:43:30 -070099 *
Ray Milkeydc659c42014-03-28 16:30:42 -0700100 * @param id id of the intent to match
101 * @return Matcher object
102 */
103 @Factory
104 public static Matcher<Collection<Intent>> hasIntentWithId(String id) {
105 return new EntryForIntentMatcher(id);
106 }
107
108
109 /**
110 * Matcher to determine if an IntentMap contains an entry with a given id,
111 * and that entry has a given state.
112 */
113 public static class IntentsHaveIntentWithStateMatcher extends TypeSafeMatcher<IntentMap> {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700114 private final String id;
115 private final IntentState state;
Ray Milkeydc659c42014-03-28 16:30:42 -0700116 private Intent intent;
117
118 public IntentsHaveIntentWithStateMatcher(String idValue,
119 IntentState stateValue) {
120 id = idValue;
121 state = stateValue;
122 }
123
124 @Override
125 public boolean matchesSafely(IntentMap intents) {
126 intent = intents.getIntent(id);
127
128 return intent != null && intent.getState() == state;
129 }
130
131 @Override
132 public void describeTo(Description description) {
133 if (intent == null) {
134 description.appendText("intent lookup for id \"");
135 description.appendText(id);
136 description.appendText("\"");
137 } else {
138 description.appendText("state ");
139 description.appendText(state.toString());
140 }
141 }
142
143 @Override
144 public void describeMismatchSafely(IntentMap intents,
145 Description mismatchDescription) {
146 if (intent != null) {
147 mismatchDescription.appendText("was ").
Ray Milkey269ffb92014-04-03 14:43:30 -0700148 appendText(intent.getState().toString());
Ray Milkeydc659c42014-03-28 16:30:42 -0700149 } else {
150 mismatchDescription.appendText("that intent was not found");
151 }
152 }
153 }
154
155
156 /**
157 * Factory method to create a Matcher for an IntentMap that looks for an
158 * Intent with a given id and state.
159 *
Ray Milkey269ffb92014-04-03 14:43:30 -0700160 * @param id id of the Intent to match
Ray Milkeydc659c42014-03-28 16:30:42 -0700161 * @param state if the Intent is found, its state must match this
162 * @return Matcher object
163 */
164 @Factory
165 public static Matcher<IntentMap> hasIntentWithIdAndState(String id,
166 IntentState state) {
167 return new IntentsHaveIntentWithStateMatcher(id, state);
168 }
169
170
Ray Milkey6688cd82014-03-11 16:40:46 -0700171 @After
172 public void tearDown() {
Ray Milkey9d671002014-05-29 17:24:29 -0700173 mocks.tearDownIntentMocks();
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -0700174 OnosMetrics.removeMatching(MetricFilter.ALL);
Ray Milkey6688cd82014-03-11 16:40:46 -0700175 }
176
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700177 private static final String BAD_SWITCH_INTENT_NAME = "No Such Switch Intent";
178
Ray Milkey6688cd82014-03-11 16:40:46 -0700179 /**
180 * Test the result of executing a path calculation on an
181 * Intent Operation List which contains a path that references a
182 * non-existent switch.
Ray Milkey269ffb92014-04-03 14:43:30 -0700183 * <p/>
Ray Milkey6688cd82014-03-11 16:40:46 -0700184 * A 3 path list is created where one of the paths references a switch
185 * that is not in the topology. The test checks that the resulting
186 * Operation List has entries for the 2 correct paths, and that the
187 * high level intents contain a proper error entry for the bad path.
188 */
189 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700190 public void testInvalidSwitchName() {
Ray Milkey6688cd82014-03-11 16:40:46 -0700191
192 // create shortest path intents
193 final IntentOperationList opList = new IntentOperationList();
194 opList.add(Operator.ADD,
195 new ShortestPathIntent(BAD_SWITCH_INTENT_NAME, 111L, 12L,
196 LOCAL_PORT, 2L, 21L, LOCAL_PORT));
197 opList.add(Operator.ADD,
198 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
199 LOCAL_PORT));
200 opList.add(Operator.ADD,
201 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
202 LOCAL_PORT));
203
204 // compile high-level intent operations into low-level intent
205 // operations (calculate paths)
Ray Milkey6688cd82014-03-11 16:40:46 -0700206 final IntentOperationList pathIntentOpList =
207 runtime.executeIntentOperations(opList);
208 assertThat(pathIntentOpList, notNullValue());
209
210 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
211 assertThat(highLevelIntents, notNullValue());
212
213 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
214 assertThat(allIntents, notNullValue());
215
216 // One intent had an error and should not create a path list entry
217 assertThat(pathIntentOpList, hasSize(opList.size() - 1));
218
219 // Should be a high level intent for each operation
Ray Milkeydc659c42014-03-28 16:30:42 -0700220 assertThat(allIntents, hasSize(opList.size()));
Ray Milkey6688cd82014-03-11 16:40:46 -0700221
222 // Check that we got a high level intent for each operation
Ray Milkeydc659c42014-03-28 16:30:42 -0700223 assertThat(allIntents, hasIntentWithId("3"));
224 assertThat(allIntents, hasIntentWithId("2"));
225 assertThat(allIntents, hasIntentWithId(BAD_SWITCH_INTENT_NAME));
Ray Milkey6688cd82014-03-11 16:40:46 -0700226
227 // Check that the non existent switch was NACKed
Ray Milkeydc659c42014-03-28 16:30:42 -0700228 assertThat(highLevelIntents, hasIntentWithIdAndState(BAD_SWITCH_INTENT_NAME, IntentState.INST_NACK));
Ray Milkey6688cd82014-03-11 16:40:46 -0700229
230 // Check that switch 2 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700231 assertThat(highLevelIntents, hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkey6688cd82014-03-11 16:40:46 -0700232
233 // Check that switch 3 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700234 assertThat(highLevelIntents, hasIntentWithIdAndState("3", IntentState.INST_REQ));
235
236 }
237
238
239 /**
240 * Test the result of executing a path calculation on an
241 * Intent Operation List and then removing one of the switches.
Ray Milkey269ffb92014-04-03 14:43:30 -0700242 * <p/>
Ray Milkeydc659c42014-03-28 16:30:42 -0700243 * A 3 path list is created and then one of the paths is removed.
244 * The test checks that the resulting Operation List is correct,
245 * and that the high level intents contain a proper "delete requested"
246 * entry for the deleted path.
247 */
248 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700249 public void testIntentRemoval() {
Ray Milkeydc659c42014-03-28 16:30:42 -0700250 // create shortest path intents
251 final IntentOperationList opList = new IntentOperationList();
252 opList.add(Operator.ADD,
253 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700254 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700255 opList.add(Operator.ADD,
256 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700257 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700258 opList.add(Operator.ADD,
259 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700260 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700261
262 // compile high-level intent operations into low-level intent
263 // operations (calculate paths)
Ray Milkeydc659c42014-03-28 16:30:42 -0700264 final IntentOperationList pathIntentOpList =
265 runtime.executeIntentOperations(opList);
266 assertThat(pathIntentOpList, notNullValue());
267
268 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
269 assertThat(highLevelIntents, notNullValue());
270
271 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
272 assertThat(allIntents, notNullValue());
273
274 // Should be one operation per path
275 assertThat(pathIntentOpList, hasSize(opList.size()));
276
277 // Should be a high level intent for each operation
278 assertThat(allIntents, hasSize(opList.size()));
279
280 // Check that we got a high level intent for each operation
281 assertThat(allIntents, hasIntentWithId("3"));
282 assertThat(allIntents, hasIntentWithId("2"));
283 assertThat(allIntents, hasIntentWithId("1"));
284
285 // Check that switch 1 was correctly processed
286 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700287 hasIntentWithIdAndState("1", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700288
289 // Check that switch 2 was correctly processed
290 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700291 hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700292
293 // Check that switch 3 was correctly processed
294 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700295 hasIntentWithIdAndState("3", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700296
297 // Now delete one path and check the results
298 final IntentOperationList opListForRemoval = new IntentOperationList();
299 opListForRemoval.add(Operator.REMOVE,
300 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
301 LOCAL_PORT));
302
303 final IntentOperationList pathIntentOpListAfterRemoval =
304 runtime.executeIntentOperations(opListForRemoval);
305 assertThat(pathIntentOpListAfterRemoval, notNullValue());
306 assertThat(pathIntentOpListAfterRemoval, hasSize(1));
307
308 // Check the high level intents.
309 final IntentMap highLevelIntentsAfterRemoval = runtime.getHighLevelIntents();
310 assertThat(highLevelIntentsAfterRemoval, notNullValue());
311
312 final Collection<Intent> allIntentsAfterRemoval = highLevelIntentsAfterRemoval.getAllIntents();
313 assertThat(allIntentsAfterRemoval, notNullValue());
314 assertThat(allIntentsAfterRemoval, hasSize(3));
315
316 // Check that we got a high level intent for each operation
317 assertThat(allIntentsAfterRemoval, hasIntentWithId("3"));
318 assertThat(allIntentsAfterRemoval, hasIntentWithId("2"));
319 assertThat(allIntentsAfterRemoval, hasIntentWithId("1"));
320
321 // Check the states of the high level intents
322 // Check that switch 1 was correctly processed
323 assertThat(highLevelIntents,
324 hasIntentWithIdAndState("1", IntentState.DEL_REQ));
325
326 // Check that switch 2 was correctly processed
327 assertThat(highLevelIntents,
328 hasIntentWithIdAndState("2", IntentState.INST_REQ));
329
330 // Check that switch 3 was correctly processed
331 assertThat(highLevelIntents,
332 hasIntentWithIdAndState("3", IntentState.INST_REQ));
333 }
334
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700335 // CHECKSTYLE:OFF method too long
Ray Milkeydc659c42014-03-28 16:30:42 -0700336 /**
337 * Test the result of executing a path calculation on an
338 * Intent Operation List and then forcing a reroute.
Ray Milkey269ffb92014-04-03 14:43:30 -0700339 * <p/>
Ray Milkeydc659c42014-03-28 16:30:42 -0700340 * A 3 path list is created and then one of the links is removed.
341 * The test checks that the resulting Operation List is correct,
342 * and that the high level intents contain a proper "reroute requested"
343 * entry for the deleted link.
344 */
345 @Test
Toshio Koideee698952014-06-11 13:35:30 -0700346 public void testIntentReroute() {
Ray Milkeydc659c42014-03-28 16:30:42 -0700347 // create shortest path intents
348 final IntentOperationList opList = new IntentOperationList();
Toshio Koideee698952014-06-11 13:35:30 -0700349 opList.add(Operator.ADD,
Ray Milkeydc659c42014-03-28 16:30:42 -0700350 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
Toshio Koideee698952014-06-11 13:35:30 -0700351 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700352 opList.add(Operator.ADD,
353 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700354 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700355 opList.add(Operator.ADD,
356 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700357 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700358
359 // compile high-level intent operations into low-level intent
360 // operations (calculate paths)
Ray Milkeydc659c42014-03-28 16:30:42 -0700361 final IntentOperationList pathIntentOpList =
362 runtime.executeIntentOperations(opList);
363 assertThat(pathIntentOpList, notNullValue());
364
365 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
366 assertThat(highLevelIntents, notNullValue());
367
368 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
369 assertThat(allIntents, notNullValue());
370
371 // Should be one operation per path
372 assertThat(pathIntentOpList, hasSize(opList.size()));
373
374 // Should be a high level intent for each operation
375 assertThat(allIntents, hasSize(opList.size()));
376
377 // Check that we got a high level intent for each operation
378 assertThat(allIntents, hasIntentWithId("3"));
379 assertThat(allIntents, hasIntentWithId("2"));
380 assertThat(allIntents, hasIntentWithId("1"));
381
Toshio Koidec2112c22014-06-05 19:59:15 -0700382 // Check that the high level intent 1 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700383 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700384 hasIntentWithIdAndState("1", 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 2 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700387 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700388 hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700389
Toshio Koidec2112c22014-06-05 19:59:15 -0700390 // Check that the high level intent 3 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700391 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700392 hasIntentWithIdAndState("3", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700393
Toshio Koidec2112c22014-06-05 19:59:15 -0700394 final IntentMap pathIntents = runtime.getPathIntents();
395 assertThat(pathIntents, notNullValue());
Ray Milkeydc659c42014-03-28 16:30:42 -0700396
Toshio Koidec2112c22014-06-05 19:59:15 -0700397 final Collection<Intent> allPathIntents = pathIntents.getAllIntents();
398 assertThat(allPathIntents, notNullValue());
399
400 // Check that we got a low level intent for each operation
401 assertThat(allPathIntents, hasIntentWithId("3___0"));
402 assertThat(allPathIntents, hasIntentWithId("2___0"));
403 assertThat(allPathIntents, hasIntentWithId("1___0"));
404
405 // Check that the low level intent 1 was correctly processed
406 assertThat(pathIntents,
407 hasIntentWithIdAndState("1___0", IntentState.INST_REQ));
408
409 // Check that the low level intent 2 was correctly processed
410 assertThat(pathIntents,
411 hasIntentWithIdAndState("2___0", IntentState.INST_REQ));
412
413 // Check that the low level intent 3 was correctly processed
414 assertThat(pathIntents,
415 hasIntentWithIdAndState("3___0", IntentState.INST_REQ));
416
417 // Receive notification from south-bound
418 IntentStateList isl = new IntentStateList();
419 isl.put("1___0", IntentState.INST_ACK);
420 isl.put("2___0", IntentState.INST_ACK);
421 isl.put("3___0", IntentState.INST_ACK);
422 isl.domainSwitchDpids.add(1L);
423 isl.domainSwitchDpids.add(2L);
424 isl.domainSwitchDpids.add(3L);
425 isl.domainSwitchDpids.add(4L);
426 runtime.entryUpdated(isl);
427
428 // Now check the results
429 final IntentMap processedHighLevelIntents = runtime.getHighLevelIntents();
430 assertThat(processedHighLevelIntents, notNullValue());
431
432 // Check that the high level intent 1 was correctly processed
433 assertThat(processedHighLevelIntents,
434 hasIntentWithIdAndState("1", IntentState.INST_ACK));
435
436 // Check that the high level intent 2 was correctly processed
437 assertThat(processedHighLevelIntents,
438 hasIntentWithIdAndState("2", IntentState.INST_ACK));
439
440 // Check that the high level intent 3 was correctly processed
441 assertThat(processedHighLevelIntents,
442 hasIntentWithIdAndState("3", IntentState.INST_ACK));
443
444 final IntentMap processedPathIntents = runtime.getPathIntents();
445 assertThat(processedPathIntents, notNullValue());
446
447 // Check that the low level intent 1 was correctly processed
448 assertThat(processedPathIntents,
449 hasIntentWithIdAndState("1___0", IntentState.INST_ACK));
450
451 // Check that the low level intent 2 was correctly processed
452 assertThat(processedPathIntents,
453 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
454
455 // Check that the low level intent 3 was correctly processed
456 assertThat(processedPathIntents,
457 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
458
Toshio Koidec2112c22014-06-05 19:59:15 -0700459 // Remove one of the links and check results
Ray Milkeydc659c42014-03-28 16:30:42 -0700460 final List<SwitchEvent> emptySwitchEvents = new LinkedList<>();
461 final List<PortEvent> emptyPortEvents = new LinkedList<>();
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700462 final List<HostEvent> emptyHostEvents = new LinkedList<>();
Ray Milkeydc659c42014-03-28 16:30:42 -0700463 final List<LinkEvent> addedLinkEvents = new LinkedList<>();
464 final List<LinkEvent> removedLinkEvents = new LinkedList<>();
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700465 TopologyEvents topologyEvents;
Ray Milkeydc659c42014-03-28 16:30:42 -0700466
Ray Milkey9d671002014-05-29 17:24:29 -0700467 final MockTopology topology = mocks.getTopology();
Jonathan Harte37e4e22014-05-13 19:12:02 -0700468 topology.removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
469 topology.removeLink(2L, 21L, 1L, 12L);
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700470 LinkEvent linkEvent1 = new LinkEvent(new SwitchPort(1L, 12L), new SwitchPort(2L, 21L));
471 LinkEvent linkEvent2 = new LinkEvent(new SwitchPort(2L, 21L), new SwitchPort(1L, 12L));
Yuta HIGUCHIb8093642014-07-16 13:17:07 -0700472 linkEvent1.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_PACKET_LAYER);
473 linkEvent2.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_PACKET_LAYER);
Ray Milkeydc659c42014-03-28 16:30:42 -0700474 removedLinkEvents.add(linkEvent1);
475 removedLinkEvents.add(linkEvent2);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700476
477 topologyEvents = new TopologyEvents(0,
478 emptySwitchEvents,
479 emptySwitchEvents,
480 emptyPortEvents,
481 emptyPortEvents,
482 addedLinkEvents,
483 removedLinkEvents,
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700484 emptyHostEvents,
485 emptyHostEvents);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700486
487 runtime.topologyEvents(topologyEvents);
Ray Milkeydc659c42014-03-28 16:30:42 -0700488
489 // Check the high level intents.
490 final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
491 assertThat(highLevelIntentsAfterReroute, notNullValue());
492
Ray Milkeydc659c42014-03-28 16:30:42 -0700493 // Check the states of the high level intents
Toshio Koidec2112c22014-06-05 19:59:15 -0700494 // Check that the high level intent 1 was correctly processed
495 assertThat(highLevelIntentsAfterReroute,
496 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700497
Toshio Koidec2112c22014-06-05 19:59:15 -0700498 // Check that the high level intent 2 was not affected
499 assertThat(highLevelIntentsAfterReroute,
Ray Milkeydc659c42014-03-28 16:30:42 -0700500 hasIntentWithIdAndState("2", IntentState.INST_ACK));
501
Toshio Koidec2112c22014-06-05 19:59:15 -0700502 // Check that the high level intent 3 was not affected
503 assertThat(highLevelIntentsAfterReroute,
Ray Milkeydc659c42014-03-28 16:30:42 -0700504 hasIntentWithIdAndState("3", IntentState.INST_ACK));
505
Toshio Koidec2112c22014-06-05 19:59:15 -0700506 final IntentMap pathIntentsAfterReroute = runtime.getPathIntents();
507 assertThat(pathIntentsAfterReroute, notNullValue());
Ray Milkey6688cd82014-03-11 16:40:46 -0700508
Toshio Koidec2112c22014-06-05 19:59:15 -0700509 // Check that the low level intent 1 was correctly processed
510 assertThat(pathIntentsAfterReroute,
511 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
512 assertThat(pathIntentsAfterReroute,
513 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
514
515 // Check that the low level intent 2 was not affected
516 assertThat(pathIntentsAfterReroute,
517 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
518
519 // Check that the low level intent 3 was not affected
520 assertThat(pathIntentsAfterReroute,
521 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
522
523 // Receive notification from south-bound
524 isl = new IntentStateList();
525 isl.put("1___0", IntentState.DEL_ACK);
526 isl.put("1___1", IntentState.INST_ACK);
527 isl.domainSwitchDpids.add(1L);
528 isl.domainSwitchDpids.add(2L);
529 isl.domainSwitchDpids.add(4L);
530 runtime.entryUpdated(isl);
531
532 // Now check the results
533 final IntentMap reroutedHighLevelIntents = runtime.getHighLevelIntents();
534 assertThat(reroutedHighLevelIntents, notNullValue());
535
536 // Check that the high level intent 1 was correctly processed
537 assertThat(reroutedHighLevelIntents,
538 hasIntentWithIdAndState("1", IntentState.INST_ACK));
539
540 // Check that the high level intent 2 was not affected
541 assertThat(reroutedHighLevelIntents,
542 hasIntentWithIdAndState("2", IntentState.INST_ACK));
543
544 // Check that the high level intent 3 was not affected
545 assertThat(reroutedHighLevelIntents,
546 hasIntentWithIdAndState("3", IntentState.INST_ACK));
547
548 final IntentMap reroutedPathIntents = runtime.getPathIntents();
549 assertThat(processedPathIntents, notNullValue());
550
551 // Check that the low level intent 1 was correctly processed
Pavlin Radoslavove2238bc2014-06-09 18:05:23 -0700552 assertThat(reroutedPathIntents.getAllIntents(),
553 not(hasIntentWithId("1___0")));
Toshio Koidec2112c22014-06-05 19:59:15 -0700554 assertThat(reroutedPathIntents,
555 hasIntentWithIdAndState("1___1", IntentState.INST_ACK));
556
557 // Check that the low level intent 2 was not affected
558 assertThat(reroutedPathIntents,
559 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
560
561 // Check that the low level intent 3 was not affected
562 assertThat(reroutedPathIntents,
563 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
Ray Milkey6688cd82014-03-11 16:40:46 -0700564 }
Toshio Koideee698952014-06-11 13:35:30 -0700565
566 /**
567 * Test the result of executing a path calculation on an
568 * Intent Operation List and then forcing a reroute and
569 * an interrupt of a topology change event while the reroute
570 * is processed.
571 * <p/>
572 * A 3 path list is created, one of the links is removed, then
573 * the removed link is restored.
574 * The test checks that if the high level intent was marked
575 * as stale when a topology changed event was received while
576 * processing reroute then the stale high level intent is executed
577 * once again after completion of its reroute.
578 */
579 @Test
580 public void testIntentRerouteWithTopologyEventInterrupt() {
581
582 // create shortest path intents
583 final IntentOperationList opList = new IntentOperationList();
584 opList.add(Operator.ADD,
585 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
586 LOCAL_PORT));
587 opList.add(Operator.ADD,
588 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
589 LOCAL_PORT));
590 opList.add(Operator.ADD,
591 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
592 LOCAL_PORT));
593
594 // compile high-level intent operations into low-level intent
595 // operations (calculate paths)
596 final IntentOperationList pathIntentOpList =
597 runtime.executeIntentOperations(opList);
598 assertThat(pathIntentOpList, notNullValue());
599
600 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
601 assertThat(highLevelIntents, notNullValue());
602
603 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
604 assertThat(allIntents, notNullValue());
605
606 // Should be one operation per path
607 assertThat(pathIntentOpList, hasSize(opList.size()));
608
609 // Should be a high level intent for each operation
610 assertThat(allIntents, hasSize(opList.size()));
611
612 // Check that we got a high level intent for each operation
613 assertThat(allIntents, hasIntentWithId("3"));
614 assertThat(allIntents, hasIntentWithId("2"));
615 assertThat(allIntents, hasIntentWithId("1"));
616
617 // Check that the high level intent 1 was correctly processed
618 assertThat(highLevelIntents,
619 hasIntentWithIdAndState("1", IntentState.INST_REQ));
620
621 // Check that the high level intent 2 was correctly processed
622 assertThat(highLevelIntents,
623 hasIntentWithIdAndState("2", IntentState.INST_REQ));
624
625 // Check that the high level intent 3 was correctly processed
626 assertThat(highLevelIntents,
627 hasIntentWithIdAndState("3", IntentState.INST_REQ));
628
629 final IntentMap pathIntents = runtime.getPathIntents();
630 assertThat(pathIntents, notNullValue());
631
632 final Collection<Intent> allPathIntents = pathIntents.getAllIntents();
633 assertThat(allPathIntents, notNullValue());
634
635 // Check that we got a low level intent for each operation
636 assertThat(allPathIntents, hasIntentWithId("3___0"));
637 assertThat(allPathIntents, hasIntentWithId("2___0"));
638 assertThat(allPathIntents, hasIntentWithId("1___0"));
639
640 // Check that the low level intent 1 was correctly processed
641 assertThat(pathIntents,
642 hasIntentWithIdAndState("1___0", IntentState.INST_REQ));
643
644 // Check that the low level intent 2 was correctly processed
645 assertThat(pathIntents,
646 hasIntentWithIdAndState("2___0", IntentState.INST_REQ));
647
648 // Check that the low level intent 3 was correctly processed
649 assertThat(pathIntents,
650 hasIntentWithIdAndState("3___0", IntentState.INST_REQ));
651
652 // Receive notification from south-bound
653 IntentStateList isl = new IntentStateList();
654 isl.put("1___0", IntentState.INST_ACK);
655 isl.put("2___0", IntentState.INST_ACK);
656 isl.put("3___0", IntentState.INST_ACK);
657 isl.domainSwitchDpids.add(1L);
658 isl.domainSwitchDpids.add(2L);
659 isl.domainSwitchDpids.add(3L);
660 isl.domainSwitchDpids.add(4L);
661 runtime.entryUpdated(isl);
662
663 // Now check the results
664 final IntentMap processedHighLevelIntents = runtime.getHighLevelIntents();
665 assertThat(processedHighLevelIntents, notNullValue());
666
667 // Check that the high level intent 1 was correctly processed
668 assertThat(processedHighLevelIntents,
669 hasIntentWithIdAndState("1", IntentState.INST_ACK));
670
671 // Check that the high level intent 2 was correctly processed
672 assertThat(processedHighLevelIntents,
673 hasIntentWithIdAndState("2", IntentState.INST_ACK));
674
675 // Check that the high level intent 3 was correctly processed
676 assertThat(processedHighLevelIntents,
677 hasIntentWithIdAndState("3", IntentState.INST_ACK));
678
679 final IntentMap processedPathIntents = runtime.getPathIntents();
680 assertThat(processedPathIntents, notNullValue());
681
682 // Check that the low level intent 1 was correctly processed
683 assertThat(processedPathIntents,
684 hasIntentWithIdAndState("1___0", IntentState.INST_ACK));
685
686 // Check that the low level intent 2 was correctly processed
687 assertThat(processedPathIntents,
688 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
689
690 // Check that the low level intent 3 was correctly processed
691 assertThat(processedPathIntents,
692 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
693
694
695 // Remove one of the links and check results
696 final List<SwitchEvent> emptySwitchEvents = new LinkedList<>();
697 final List<PortEvent> emptyPortEvents = new LinkedList<>();
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700698 final List<HostEvent> emptyHostEvents = new LinkedList<>();
Toshio Koideee698952014-06-11 13:35:30 -0700699 final List<LinkEvent> addedLinkEvents = new LinkedList<>();
700 final List<LinkEvent> removedLinkEvents = new LinkedList<>();
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700701 TopologyEvents topologyEvents;
Toshio Koideee698952014-06-11 13:35:30 -0700702
703 final MockTopology topology = mocks.getTopology();
704 topology.removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
705 topology.removeLink(2L, 21L, 1L, 12L);
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700706 final LinkEvent linkEvent1 = new LinkEvent(new SwitchPort(1L, 12L), new SwitchPort(2L, 21L));
707 final LinkEvent linkEvent2 = new LinkEvent(new SwitchPort(2L, 21L), new SwitchPort(1L, 12L));
Yuta HIGUCHIb8093642014-07-16 13:17:07 -0700708 linkEvent1.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_PACKET_LAYER);
709 linkEvent2.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_PACKET_LAYER);
Toshio Koideee698952014-06-11 13:35:30 -0700710 removedLinkEvents.add(linkEvent1);
711 removedLinkEvents.add(linkEvent2);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700712
713 topologyEvents = new TopologyEvents(0,
714 emptySwitchEvents,
715 emptySwitchEvents,
716 emptyPortEvents,
717 emptyPortEvents,
718 addedLinkEvents,
719 removedLinkEvents,
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700720 emptyHostEvents,
721 emptyHostEvents);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700722
723 runtime.topologyEvents(topologyEvents);
Toshio Koideee698952014-06-11 13:35:30 -0700724
725 // Check the high level intents.
726 final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
727 assertThat(highLevelIntentsAfterReroute, notNullValue());
728
729 // Check the states of the high level intents
730 // Check that the high level intent 1 was correctly processed
731 assertThat(highLevelIntentsAfterReroute,
732 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
733
734 // Check that the high level intent 2 was not affected
735 assertThat(highLevelIntentsAfterReroute,
736 hasIntentWithIdAndState("2", IntentState.INST_ACK));
737
738 // Check that the high level intent 3 was not affected
739 assertThat(highLevelIntentsAfterReroute,
740 hasIntentWithIdAndState("3", IntentState.INST_ACK));
741
742 final IntentMap pathIntentsAfterReroute = runtime.getPathIntents();
743 assertThat(pathIntentsAfterReroute, notNullValue());
744
745 // Check that the low level intent 1 was correctly processed
746 assertThat(pathIntentsAfterReroute,
747 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
748 assertThat(pathIntentsAfterReroute,
749 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
750
751 // Check that the low level intent 2 was not affected
752 assertThat(pathIntentsAfterReroute,
753 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
754
755 // Check that the low level intent 3 was not affected
756 assertThat(pathIntentsAfterReroute,
757 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
758
759 // Interrupt by topology changed event while the reroute
760 removedLinkEvents.clear();
761 addedLinkEvents.clear();
762 topology.addBidirectionalLinks(1L, 12L, 2L, 21L); // Restoration of the failure
763 addedLinkEvents.add(linkEvent1);
764 addedLinkEvents.add(linkEvent2);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700765
766 topologyEvents = new TopologyEvents(0,
767 emptySwitchEvents,
768 emptySwitchEvents,
769 emptyPortEvents,
770 emptyPortEvents,
771 addedLinkEvents,
772 removedLinkEvents,
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700773 emptyHostEvents,
774 emptyHostEvents);
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700775
776 runtime.topologyEvents(topologyEvents);
Toshio Koideee698952014-06-11 13:35:30 -0700777
778 // Check the high level intents.
779 final IntentMap highLevelIntentsAfterInterrupt = runtime.getHighLevelIntents();
780 assertThat(highLevelIntentsAfterInterrupt, notNullValue());
781
782 // Check the states of the high level intents
783 // Check that the high level intent 1 was not affected
784 assertThat(highLevelIntentsAfterInterrupt,
785 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
786
787 final IntentMap pathIntentsAfterInterrupt = runtime.getPathIntents();
788 assertThat(pathIntentsAfterInterrupt, notNullValue());
789
790 // Check that the low level intent 1 was not affected
791 assertThat(pathIntentsAfterInterrupt,
792 hasIntentWithIdAndState("1___0", IntentState.DEL_REQ));
793 assertThat(pathIntentsAfterInterrupt,
794 hasIntentWithIdAndState("1___1", IntentState.INST_REQ));
795
796 // Receive notification from south-bound
797 isl = new IntentStateList();
798 isl.put("1___0", IntentState.DEL_ACK);
799 isl.put("1___1", IntentState.INST_ACK);
800 isl.domainSwitchDpids.add(1L);
801 isl.domainSwitchDpids.add(2L);
802 isl.domainSwitchDpids.add(4L);
803 runtime.entryUpdated(isl);
804
805 // Now check the results
806 final IntentMap reroutedHighLevelIntents = runtime.getHighLevelIntents();
807 assertThat(reroutedHighLevelIntents, notNullValue());
808
809 // Check that the high level intent 1 was correctly processed
810 // It should be rerouted once again
811 assertThat(reroutedHighLevelIntents,
812 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
813
814 // Check that the high level intent 2 was not affected
815 assertThat(reroutedHighLevelIntents,
816 hasIntentWithIdAndState("2", IntentState.INST_ACK));
817
818 // Check that the high level intent 3 was not affected
819 assertThat(reroutedHighLevelIntents,
820 hasIntentWithIdAndState("3", IntentState.INST_ACK));
821
822 final IntentMap reroutedPathIntents = runtime.getPathIntents();
823 assertThat(processedPathIntents, notNullValue());
824
825 // Check that the low level intent 1 was correctly processed
826 assertThat(reroutedPathIntents.getAllIntents(),
827 not(hasIntentWithId("1___0")));
828 assertThat(reroutedPathIntents,
829 hasIntentWithIdAndState("1___1", IntentState.DEL_REQ));
830 assertThat(reroutedPathIntents,
831 hasIntentWithIdAndState("1___2", IntentState.INST_REQ));
832
833 // Check that the low level intent 2 was not affected
834 assertThat(reroutedPathIntents,
835 hasIntentWithIdAndState("2___0", IntentState.INST_ACK));
836
837 // Check that the low level intent 3 was not affected
838 assertThat(reroutedPathIntents,
839 hasIntentWithIdAndState("3___0", IntentState.INST_ACK));
840 }
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700841 // CHECKSTYLE:ON method too long
842
Ray Milkey6688cd82014-03-11 16:40:46 -0700843}