blob: ff25bac80416bb6ba3d11cb4bf2111beca915e73 [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.easymock.EasyMock.anyObject;
4import static org.easymock.EasyMock.createMock;
5import static org.easymock.EasyMock.eq;
6import static org.easymock.EasyMock.expect;
7import static org.easymock.EasyMock.expectLastCall;
8import static org.easymock.EasyMock.replay;
9import static org.easymock.EasyMock.verify;
10import static org.hamcrest.MatcherAssert.assertThat;
11import static org.hamcrest.Matchers.equalTo;
12import static org.hamcrest.Matchers.hasItem;
13import static org.hamcrest.Matchers.hasSize;
14import static org.hamcrest.Matchers.notNullValue;
15
16import java.util.Collection;
17import java.util.LinkedList;
18import java.util.List;
19
Ray Milkey6688cd82014-03-11 16:40:46 -070020import net.floodlightcontroller.core.module.FloodlightModuleContext;
21import net.floodlightcontroller.core.module.FloodlightModuleException;
Pavlin Radoslavov13669052014-05-13 10:33:39 -070022import net.floodlightcontroller.restserver.IRestApiService;
Jonathan Hart6df90172014-04-03 10:13:11 -070023import net.onrc.onos.core.datagrid.IDatagridService;
24import net.onrc.onos.core.datagrid.IEventChannel;
25import net.onrc.onos.core.datagrid.IEventChannelListener;
Jonathan Hartaa380972014-04-03 10:24:46 -070026import net.onrc.onos.core.intent.Intent;
Jonathan Harta88fd242014-04-03 11:24:54 -070027import net.onrc.onos.core.intent.Intent.IntentState;
Jonathan Hartaa380972014-04-03 10:24:46 -070028import net.onrc.onos.core.intent.IntentMap;
Jonathan Harta88fd242014-04-03 11:24:54 -070029import net.onrc.onos.core.intent.IntentOperation.Operator;
Jonathan Hartaa380972014-04-03 10:24:46 -070030import net.onrc.onos.core.intent.IntentOperationList;
Jonathan Harte37e4e22014-05-13 19:12:02 -070031import net.onrc.onos.core.intent.MockTopology;
Jonathan Hartaa380972014-04-03 10:24:46 -070032import net.onrc.onos.core.intent.ShortestPathIntent;
Pavlin Radoslavov13669052014-05-13 10:33:39 -070033import net.onrc.onos.core.intent.runtime.web.IntentWebRoutable;
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070034import net.onrc.onos.core.registry.IControllerRegistryService;
Jonathan Hart472062d2014-04-03 10:56:48 -070035import net.onrc.onos.core.topology.DeviceEvent;
Jonathan Harte37e4e22014-05-13 19:12:02 -070036import net.onrc.onos.core.topology.ITopologyListener;
37import net.onrc.onos.core.topology.ITopologyService;
Jonathan Hart472062d2014-04-03 10:56:48 -070038import net.onrc.onos.core.topology.LinkEvent;
39import net.onrc.onos.core.topology.PortEvent;
40import net.onrc.onos.core.topology.SwitchEvent;
Ray Milkey6688cd82014-03-11 16:40:46 -070041
Jonathan Harta88fd242014-04-03 11:24:54 -070042import org.hamcrest.Description;
43import org.hamcrest.Factory;
44import org.hamcrest.Matcher;
45import org.hamcrest.Matchers;
46import org.hamcrest.TypeSafeMatcher;
Ray Milkey6688cd82014-03-11 16:40:46 -070047import org.junit.After;
48import org.junit.Before;
49import org.junit.Test;
50import org.junit.runner.RunWith;
51import org.powermock.api.easymock.PowerMock;
52import org.powermock.core.classloader.annotations.PrepareForTest;
53import org.powermock.modules.junit4.PowerMockRunner;
54
Ray Milkey6688cd82014-03-11 16:40:46 -070055/**
56 * @author Ray Milkey (ray@onlab.us)
Ray Milkey269ffb92014-04-03 14:43:30 -070057 * <p/>
58 * Unit tests for the Path Calculation Runtime module (PathCalcRuntimeModule).
59 * These test cases check the results of creating paths, deleting paths, and
Jonathan Harte37e4e22014-05-13 19:12:02 -070060 * rerouting paths. The topology, controller registry, and data grid are
Ray Milkey269ffb92014-04-03 14:43:30 -070061 * mocked out. The individual tests check the high level intents and the
62 * resulting operation lists to be sure they match the intended APIs.
Ray Milkey6688cd82014-03-11 16:40:46 -070063 */
64@RunWith(PowerMockRunner.class)
65@PrepareForTest(PathCalcRuntimeModule.class)
66public class PathCalcRuntimeModuleTest {
Ray Milkeydc659c42014-03-28 16:30:42 -070067 private static final Long LOCAL_PORT = 0xFFFEL;
68
Ray Milkey6688cd82014-03-11 16:40:46 -070069 private FloodlightModuleContext modContext;
70 private IDatagridService datagridService;
Jonathan Harte37e4e22014-05-13 19:12:02 -070071 private ITopologyService topologyService;
Ray Milkey6688cd82014-03-11 16:40:46 -070072 private IControllerRegistryService controllerRegistryService;
73 private PersistIntent persistIntent;
Pavlin Radoslavov13669052014-05-13 10:33:39 -070074 private IRestApiService restApi;
Jonathan Harte37e4e22014-05-13 19:12:02 -070075 private MockTopology topology;
Toshio Koidee04a9df2014-05-01 15:49:28 -070076 private IEventChannel<Long, IntentOperationList> intentOperationChannel;
77 private IEventChannel<Long, IntentStateList> intentStateChannel;
Ray Milkey6688cd82014-03-11 16:40:46 -070078
79 @SuppressWarnings("unchecked")
80 @Before
81 public void setUp() throws Exception {
Jonathan Harte37e4e22014-05-13 19:12:02 -070082 topology = new MockTopology();
83 topology.createSampleTopology1();
Ray Milkey6688cd82014-03-11 16:40:46 -070084
85 datagridService = createMock(IDatagridService.class);
Jonathan Harte37e4e22014-05-13 19:12:02 -070086 topologyService = createMock(ITopologyService.class);
Ray Milkey6688cd82014-03-11 16:40:46 -070087 controllerRegistryService = createMock(IControllerRegistryService.class);
88 modContext = createMock(FloodlightModuleContext.class);
Toshio Koidee04a9df2014-05-01 15:49:28 -070089 intentOperationChannel = createMock(IEventChannel.class);
90 intentStateChannel = createMock(IEventChannel.class);
Ray Milkey6688cd82014-03-11 16:40:46 -070091 persistIntent = PowerMock.createMock(PersistIntent.class);
Pavlin Radoslavov13669052014-05-13 10:33:39 -070092 restApi = createMock(IRestApiService.class);
Ray Milkey6688cd82014-03-11 16:40:46 -070093
94 PowerMock.expectNew(PersistIntent.class,
Pavlin Radoslavov0294e052014-04-10 13:36:45 -070095 anyObject(IControllerRegistryService.class)).andReturn(persistIntent);
Ray Milkey6688cd82014-03-11 16:40:46 -070096
97 expect(modContext.getServiceImpl(IDatagridService.class))
98 .andReturn(datagridService).once();
Jonathan Harte37e4e22014-05-13 19:12:02 -070099 expect(modContext.getServiceImpl(ITopologyService.class))
100 .andReturn(topologyService).once();
Ray Milkey6688cd82014-03-11 16:40:46 -0700101 expect(modContext.getServiceImpl(IControllerRegistryService.class))
102 .andReturn(controllerRegistryService).once();
103 expect(persistIntent.getKey()).andReturn(1L).anyTimes();
104 expect(persistIntent.persistIfLeader(eq(1L),
105 anyObject(IntentOperationList.class))).andReturn(true)
106 .anyTimes();
Pavlin Radoslavov13669052014-05-13 10:33:39 -0700107 expect(modContext.getServiceImpl(IRestApiService.class))
108 .andReturn(restApi).once();
Ray Milkey6688cd82014-03-11 16:40:46 -0700109
Jonathan Harte37e4e22014-05-13 19:12:02 -0700110 expect(topologyService.getTopology()).andReturn(topology)
Ray Milkey6688cd82014-03-11 16:40:46 -0700111 .anyTimes();
Jonathan Harte37e4e22014-05-13 19:12:02 -0700112 topologyService.registerTopologyListener(
113 anyObject(ITopologyListener.class));
Ray Milkey6688cd82014-03-11 16:40:46 -0700114 expectLastCall();
115
116 expect(datagridService.createChannel("onos.pathintent",
117 Long.class, IntentOperationList.class))
Toshio Koidee04a9df2014-05-01 15:49:28 -0700118 .andReturn(intentOperationChannel).once();
Ray Milkey6688cd82014-03-11 16:40:46 -0700119
120 expect(datagridService.addListener(
121 eq("onos.pathintent_state"),
122 anyObject(IEventChannelListener.class),
123 eq(Long.class),
124 eq(IntentStateList.class)))
Toshio Koidee04a9df2014-05-01 15:49:28 -0700125 .andReturn(intentStateChannel).once();
Pavlin Radoslavov13669052014-05-13 10:33:39 -0700126 restApi.addRestletRoutable(anyObject(IntentWebRoutable.class));
Ray Milkey6688cd82014-03-11 16:40:46 -0700127
128 replay(datagridService);
Jonathan Harte37e4e22014-05-13 19:12:02 -0700129 replay(topologyService);
Ray Milkey6688cd82014-03-11 16:40:46 -0700130 replay(modContext);
131 replay(controllerRegistryService);
132 PowerMock.replay(persistIntent, PersistIntent.class);
Pavlin Radoslavov13669052014-05-13 10:33:39 -0700133 replay(restApi);
Ray Milkey6688cd82014-03-11 16:40:46 -0700134 }
135
Ray Milkeydc659c42014-03-28 16:30:42 -0700136
137 /**
138 * Hamcrest matcher to check that a collection of Intents contains an
139 * Intent with the specified Intent Id.
140 */
141 public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700142 private final String id;
Ray Milkeydc659c42014-03-28 16:30:42 -0700143
144 public EntryForIntentMatcher(String idValue) {
145 id = idValue;
146 }
147
148 @Override
149 public boolean matchesSafely(Collection<Intent> intents) {
150 assertThat(intents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700151 hasItem(Matchers.<Intent>hasProperty("id", equalTo(id))));
Ray Milkeydc659c42014-03-28 16:30:42 -0700152 return true;
153 }
154
155 @Override
156 public void describeTo(Description description) {
157 description.appendText("an intent with id \" ").
158 appendText(id).
159 appendText("\"");
160 }
161 }
162
163
164 /**
165 * Factory method to create an Intent entry Matcher. Returns a matcher
166 * for the Intent with the given id.
Ray Milkey269ffb92014-04-03 14:43:30 -0700167 *
Ray Milkeydc659c42014-03-28 16:30:42 -0700168 * @param id id of the intent to match
169 * @return Matcher object
170 */
171 @Factory
172 public static Matcher<Collection<Intent>> hasIntentWithId(String id) {
173 return new EntryForIntentMatcher(id);
174 }
175
176
177 /**
178 * Matcher to determine if an IntentMap contains an entry with a given id,
179 * and that entry has a given state.
180 */
181 public static class IntentsHaveIntentWithStateMatcher extends TypeSafeMatcher<IntentMap> {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700182 private final String id;
183 private final IntentState state;
Ray Milkeydc659c42014-03-28 16:30:42 -0700184 private Intent intent;
185
186 public IntentsHaveIntentWithStateMatcher(String idValue,
187 IntentState stateValue) {
188 id = idValue;
189 state = stateValue;
190 }
191
192 @Override
193 public boolean matchesSafely(IntentMap intents) {
194 intent = intents.getIntent(id);
195
196 return intent != null && intent.getState() == state;
197 }
198
199 @Override
200 public void describeTo(Description description) {
201 if (intent == null) {
202 description.appendText("intent lookup for id \"");
203 description.appendText(id);
204 description.appendText("\"");
205 } else {
206 description.appendText("state ");
207 description.appendText(state.toString());
208 }
209 }
210
211 @Override
212 public void describeMismatchSafely(IntentMap intents,
213 Description mismatchDescription) {
214 if (intent != null) {
215 mismatchDescription.appendText("was ").
Ray Milkey269ffb92014-04-03 14:43:30 -0700216 appendText(intent.getState().toString());
Ray Milkeydc659c42014-03-28 16:30:42 -0700217 } else {
218 mismatchDescription.appendText("that intent was not found");
219 }
220 }
221 }
222
223
224 /**
225 * Factory method to create a Matcher for an IntentMap that looks for an
226 * Intent with a given id and state.
227 *
Ray Milkey269ffb92014-04-03 14:43:30 -0700228 * @param id id of the Intent to match
Ray Milkeydc659c42014-03-28 16:30:42 -0700229 * @param state if the Intent is found, its state must match this
230 * @return Matcher object
231 */
232 @Factory
233 public static Matcher<IntentMap> hasIntentWithIdAndState(String id,
234 IntentState state) {
235 return new IntentsHaveIntentWithStateMatcher(id, state);
236 }
237
238
Ray Milkey6688cd82014-03-11 16:40:46 -0700239 @After
240 public void tearDown() {
241 verify(datagridService);
Jonathan Harte37e4e22014-05-13 19:12:02 -0700242 verify(topologyService);
Ray Milkey6688cd82014-03-11 16:40:46 -0700243 verify(modContext);
244 verify(controllerRegistryService);
245 PowerMock.verify(persistIntent, PersistIntent.class);
Pavlin Radoslavov13669052014-05-13 10:33:39 -0700246 verify(restApi);
Ray Milkey6688cd82014-03-11 16:40:46 -0700247 }
248
249 /**
250 * Test the result of executing a path calculation on an
251 * Intent Operation List which contains a path that references a
252 * non-existent switch.
Ray Milkey269ffb92014-04-03 14:43:30 -0700253 * <p/>
Ray Milkey6688cd82014-03-11 16:40:46 -0700254 * A 3 path list is created where one of the paths references a switch
255 * that is not in the topology. The test checks that the resulting
256 * Operation List has entries for the 2 correct paths, and that the
257 * high level intents contain a proper error entry for the bad path.
258 */
259 @Test
260 public void testInvalidSwitchName() throws FloodlightModuleException {
Ray Milkey6688cd82014-03-11 16:40:46 -0700261 final String BAD_SWITCH_INTENT_NAME = "No Such Switch Intent";
262
263 // create shortest path intents
264 final IntentOperationList opList = new IntentOperationList();
265 opList.add(Operator.ADD,
266 new ShortestPathIntent(BAD_SWITCH_INTENT_NAME, 111L, 12L,
267 LOCAL_PORT, 2L, 21L, LOCAL_PORT));
268 opList.add(Operator.ADD,
269 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
270 LOCAL_PORT));
271 opList.add(Operator.ADD,
272 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
273 LOCAL_PORT));
274
275 // compile high-level intent operations into low-level intent
276 // operations (calculate paths)
277 final PathCalcRuntimeModule runtime = new PathCalcRuntimeModule();
278 runtime.init(modContext);
279 runtime.startUp(modContext);
280 final IntentOperationList pathIntentOpList =
281 runtime.executeIntentOperations(opList);
282 assertThat(pathIntentOpList, notNullValue());
283
284 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
285 assertThat(highLevelIntents, notNullValue());
286
287 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
288 assertThat(allIntents, notNullValue());
289
290 // One intent had an error and should not create a path list entry
291 assertThat(pathIntentOpList, hasSize(opList.size() - 1));
292
293 // Should be a high level intent for each operation
Ray Milkeydc659c42014-03-28 16:30:42 -0700294 assertThat(allIntents, hasSize(opList.size()));
Ray Milkey6688cd82014-03-11 16:40:46 -0700295
296 // Check that we got a high level intent for each operation
Ray Milkeydc659c42014-03-28 16:30:42 -0700297 assertThat(allIntents, hasIntentWithId("3"));
298 assertThat(allIntents, hasIntentWithId("2"));
299 assertThat(allIntents, hasIntentWithId(BAD_SWITCH_INTENT_NAME));
Ray Milkey6688cd82014-03-11 16:40:46 -0700300
301 // Check that the non existent switch was NACKed
Ray Milkeydc659c42014-03-28 16:30:42 -0700302 assertThat(highLevelIntents, hasIntentWithIdAndState(BAD_SWITCH_INTENT_NAME, IntentState.INST_NACK));
Ray Milkey6688cd82014-03-11 16:40:46 -0700303
304 // Check that switch 2 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700305 assertThat(highLevelIntents, hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkey6688cd82014-03-11 16:40:46 -0700306
307 // Check that switch 3 was correctly processed
Ray Milkeydc659c42014-03-28 16:30:42 -0700308 assertThat(highLevelIntents, hasIntentWithIdAndState("3", IntentState.INST_REQ));
309
310 }
311
312
313 /**
314 * Test the result of executing a path calculation on an
315 * Intent Operation List and then removing one of the switches.
Ray Milkey269ffb92014-04-03 14:43:30 -0700316 * <p/>
Ray Milkeydc659c42014-03-28 16:30:42 -0700317 * A 3 path list is created and then one of the paths is removed.
318 * The test checks that the resulting Operation List is correct,
319 * and that the high level intents contain a proper "delete requested"
320 * entry for the deleted path.
321 */
322 @Test
323 public void testIntentRemoval() throws FloodlightModuleException {
324
325 // create shortest path intents
326 final IntentOperationList opList = new IntentOperationList();
327 opList.add(Operator.ADD,
328 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700329 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700330 opList.add(Operator.ADD,
331 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700332 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700333 opList.add(Operator.ADD,
334 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700335 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700336
337 // compile high-level intent operations into low-level intent
338 // operations (calculate paths)
339 final PathCalcRuntimeModule runtime = new PathCalcRuntimeModule();
340 runtime.init(modContext);
341 runtime.startUp(modContext);
342 final IntentOperationList pathIntentOpList =
343 runtime.executeIntentOperations(opList);
344 assertThat(pathIntentOpList, notNullValue());
345
346 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
347 assertThat(highLevelIntents, notNullValue());
348
349 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
350 assertThat(allIntents, notNullValue());
351
352 // Should be one operation per path
353 assertThat(pathIntentOpList, hasSize(opList.size()));
354
355 // Should be a high level intent for each operation
356 assertThat(allIntents, hasSize(opList.size()));
357
358 // Check that we got a high level intent for each operation
359 assertThat(allIntents, hasIntentWithId("3"));
360 assertThat(allIntents, hasIntentWithId("2"));
361 assertThat(allIntents, hasIntentWithId("1"));
362
363 // Check that switch 1 was correctly processed
364 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700365 hasIntentWithIdAndState("1", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700366
367 // Check that switch 2 was correctly processed
368 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700369 hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700370
371 // Check that switch 3 was correctly processed
372 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700373 hasIntentWithIdAndState("3", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700374
375 // Now delete one path and check the results
376 final IntentOperationList opListForRemoval = new IntentOperationList();
377 opListForRemoval.add(Operator.REMOVE,
378 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
379 LOCAL_PORT));
380
381 final IntentOperationList pathIntentOpListAfterRemoval =
382 runtime.executeIntentOperations(opListForRemoval);
383 assertThat(pathIntentOpListAfterRemoval, notNullValue());
384 assertThat(pathIntentOpListAfterRemoval, hasSize(1));
385
386 // Check the high level intents.
387 final IntentMap highLevelIntentsAfterRemoval = runtime.getHighLevelIntents();
388 assertThat(highLevelIntentsAfterRemoval, notNullValue());
389
390 final Collection<Intent> allIntentsAfterRemoval = highLevelIntentsAfterRemoval.getAllIntents();
391 assertThat(allIntentsAfterRemoval, notNullValue());
392 assertThat(allIntentsAfterRemoval, hasSize(3));
393
394 // Check that we got a high level intent for each operation
395 assertThat(allIntentsAfterRemoval, hasIntentWithId("3"));
396 assertThat(allIntentsAfterRemoval, hasIntentWithId("2"));
397 assertThat(allIntentsAfterRemoval, hasIntentWithId("1"));
398
399 // Check the states of the high level intents
400 // Check that switch 1 was correctly processed
401 assertThat(highLevelIntents,
402 hasIntentWithIdAndState("1", IntentState.DEL_REQ));
403
404 // Check that switch 2 was correctly processed
405 assertThat(highLevelIntents,
406 hasIntentWithIdAndState("2", IntentState.INST_REQ));
407
408 // Check that switch 3 was correctly processed
409 assertThat(highLevelIntents,
410 hasIntentWithIdAndState("3", IntentState.INST_REQ));
411 }
412
413 /**
414 * Test the result of executing a path calculation on an
415 * Intent Operation List and then forcing a reroute.
Ray Milkey269ffb92014-04-03 14:43:30 -0700416 * <p/>
Ray Milkeydc659c42014-03-28 16:30:42 -0700417 * A 3 path list is created and then one of the links is removed.
418 * The test checks that the resulting Operation List is correct,
419 * and that the high level intents contain a proper "reroute requested"
420 * entry for the deleted link.
421 */
422 @Test
423 public void testIntentReroute() throws FloodlightModuleException {
424
425 // create shortest path intents
426 final IntentOperationList opList = new IntentOperationList();
427 final ShortestPathIntent pathIntent1 =
428 new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700429 LOCAL_PORT);
Ray Milkeydc659c42014-03-28 16:30:42 -0700430
431 opList.add(Operator.ADD, pathIntent1);
432 opList.add(Operator.ADD,
433 new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700434 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700435 opList.add(Operator.ADD,
436 new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
Ray Milkey269ffb92014-04-03 14:43:30 -0700437 LOCAL_PORT));
Ray Milkeydc659c42014-03-28 16:30:42 -0700438
439 // compile high-level intent operations into low-level intent
440 // operations (calculate paths)
441 final PathCalcRuntimeModule runtime = new PathCalcRuntimeModule();
442 runtime.init(modContext);
443 runtime.startUp(modContext);
444 final IntentOperationList pathIntentOpList =
445 runtime.executeIntentOperations(opList);
446 assertThat(pathIntentOpList, notNullValue());
447
448 final IntentMap highLevelIntents = runtime.getHighLevelIntents();
449 assertThat(highLevelIntents, notNullValue());
450
451 final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
452 assertThat(allIntents, notNullValue());
453
454 // Should be one operation per path
455 assertThat(pathIntentOpList, hasSize(opList.size()));
456
457 // Should be a high level intent for each operation
458 assertThat(allIntents, hasSize(opList.size()));
459
460 // Check that we got a high level intent for each operation
461 assertThat(allIntents, hasIntentWithId("3"));
462 assertThat(allIntents, hasIntentWithId("2"));
463 assertThat(allIntents, hasIntentWithId("1"));
464
465 // Check that switch 1 was correctly processed
466 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700467 hasIntentWithIdAndState("1", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700468
469 // Check that switch 2 was correctly processed
470 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700471 hasIntentWithIdAndState("2", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700472
473 // Check that switch 3 was correctly processed
474 assertThat(highLevelIntents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700475 hasIntentWithIdAndState("3", IntentState.INST_REQ));
Ray Milkeydc659c42014-03-28 16:30:42 -0700476
477 // Now add a different path to one of the switches path and check
478 // the results
479 IntentStateList states = new IntentStateList();
480 states.put("1", IntentState.INST_ACK);
481 states.put("2", IntentState.INST_ACK);
482 states.put("3", IntentState.INST_ACK);
483 runtime.getHighLevelIntents().changeStates(states);
484 states.clear();
485 states.put("1___0", IntentState.INST_ACK);
486 states.put("2___0", IntentState.INST_ACK);
487 states.put("3___0", IntentState.INST_ACK);
488 runtime.getPathIntents().changeStates(states);
489
490 final List<SwitchEvent> emptySwitchEvents = new LinkedList<>();
491 final List<PortEvent> emptyPortEvents = new LinkedList<>();
492 final List<DeviceEvent> emptyDeviceEvents = new LinkedList<>();
493 final List<LinkEvent> addedLinkEvents = new LinkedList<>();
494 final List<LinkEvent> removedLinkEvents = new LinkedList<>();
495
Jonathan Harte37e4e22014-05-13 19:12:02 -0700496 topology.removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
497 topology.removeLink(2L, 21L, 1L, 12L);
Ray Milkeydc659c42014-03-28 16:30:42 -0700498 LinkEvent linkEvent1 = new LinkEvent(1L, 12L, 2L, 21L);
499 LinkEvent linkEvent2 = new LinkEvent(2L, 21L, 1L, 12L);
500 removedLinkEvents.add(linkEvent1);
501 removedLinkEvents.add(linkEvent2);
Jonathan Harte37e4e22014-05-13 19:12:02 -0700502 runtime.topologyEvents(
Ray Milkeydc659c42014-03-28 16:30:42 -0700503 emptySwitchEvents,
504 emptySwitchEvents,
505 emptyPortEvents,
506 emptyPortEvents,
507 addedLinkEvents,
508 removedLinkEvents,
509 emptyDeviceEvents,
510 emptyDeviceEvents);
511 final IntentOperationList opListForReroute = new IntentOperationList();
512 opListForReroute.add(Operator.ADD, pathIntent1);
513
514 final IntentOperationList pathIntentOpListAfterReroute =
515 runtime.executeIntentOperations(opListForReroute);
516 assertThat(pathIntentOpListAfterReroute, notNullValue());
517 assertThat(pathIntentOpListAfterReroute, hasSize(2));
518
519 // Check the high level intents.
520 final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
521 assertThat(highLevelIntentsAfterReroute, notNullValue());
522
523 final Collection<Intent> allIntentsAfterReroute = highLevelIntentsAfterReroute.getAllIntents();
524 assertThat(allIntentsAfterReroute, notNullValue());
525 assertThat(allIntentsAfterReroute, hasSize(3));
526
527 // Check that we got a high level intent for each operation
528 assertThat(allIntentsAfterReroute, hasIntentWithId("3"));
529 assertThat(allIntentsAfterReroute, hasIntentWithId("2"));
530 assertThat(allIntentsAfterReroute, hasIntentWithId("1"));
531
532 // Check the states of the high level intents
533 // Check that switch 1 was correctly processed
534 assertThat(highLevelIntents,
535 hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
536
537 // Check that switch 2 was correctly processed
538 assertThat(highLevelIntents,
539 hasIntentWithIdAndState("2", IntentState.INST_ACK));
540
541 // Check that switch 3 was correctly processed
542 assertThat(highLevelIntents,
543 hasIntentWithIdAndState("3", IntentState.INST_ACK));
544
Ray Milkey6688cd82014-03-11 16:40:46 -0700545
546 }
547
548
549}