blob: 645ffe59af8e90921dd96a7c1e9d0557fc1e23fc [file] [log] [blame]
Jonathan Hartaa380972014-04-03 10:24:46 -07001package net.onrc.onos.core.intent.runtime;
Toshio Koidec87810e2014-02-11 13:03:21 -08002
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;
Toshio Koide066506e2014-02-20 19:52:09 -080010
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -080011import java.util.LinkedList;
Brian O'Connor12861f72014-02-19 20:40:32 -080012import java.util.List;
13import java.util.Set;
14
Toshio Koide27ffd412014-02-18 19:15:27 -080015import net.floodlightcontroller.core.module.FloodlightModuleContext;
16import net.floodlightcontroller.core.module.FloodlightModuleException;
Jonathan Hart6df90172014-04-03 10:13:11 -070017import net.onrc.onos.core.datagrid.IDatagridService;
18import net.onrc.onos.core.datagrid.IEventChannel;
19import net.onrc.onos.core.datagrid.IEventChannelListener;
Jonathan Hartaa380972014-04-03 10:24:46 -070020import net.onrc.onos.core.intent.ConstrainedShortestPathIntent;
21import net.onrc.onos.core.intent.FlowEntry;
22import net.onrc.onos.core.intent.Intent;
Jonathan Harta88fd242014-04-03 11:24:54 -070023import net.onrc.onos.core.intent.Intent.IntentState;
24import net.onrc.onos.core.intent.IntentOperation.Operator;
Jonathan Hartaa380972014-04-03 10:24:46 -070025import net.onrc.onos.core.intent.IntentOperationList;
26import net.onrc.onos.core.intent.MockNetworkGraph;
27import net.onrc.onos.core.intent.PathIntent;
28import net.onrc.onos.core.intent.PathIntentMap;
29import net.onrc.onos.core.intent.ShortestPathIntent;
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070030import net.onrc.onos.core.registry.IControllerRegistryService;
Jonathan Hart472062d2014-04-03 10:56:48 -070031import net.onrc.onos.core.topology.DeviceEvent;
32import net.onrc.onos.core.topology.INetworkGraphListener;
33import net.onrc.onos.core.topology.INetworkGraphService;
34import net.onrc.onos.core.topology.LinkEvent;
35import net.onrc.onos.core.topology.NetworkGraph;
36import net.onrc.onos.core.topology.PortEvent;
37import net.onrc.onos.core.topology.SwitchEvent;
Toshio Koidec87810e2014-02-11 13:03:21 -080038
39import org.junit.After;
40import org.junit.Before;
41import org.junit.Test;
Nick Karanatsios8abe7172014-02-19 20:31:48 -080042import org.junit.runner.RunWith;
43import org.powermock.api.easymock.PowerMock;
44import org.powermock.core.classloader.annotations.PrepareForTest;
45import org.powermock.modules.junit4.PowerMockRunner;
Toshio Koidec87810e2014-02-11 13:03:21 -080046
47/**
48 * @author Toshio Koide (t-koide@onlab.us)
49 */
Nick Karanatsios8abe7172014-02-19 20:31:48 -080050@RunWith(PowerMockRunner.class)
51@PrepareForTest(PathCalcRuntimeModule.class)
Toshio Koidec87810e2014-02-11 13:03:21 -080052public class UseCaseTest {
Toshio Koide27ffd412014-02-18 19:15:27 -080053 private NetworkGraph g;
54 private FloodlightModuleContext modContext;
55 private IDatagridService datagridService;
56 private INetworkGraphService networkGraphService;
Toshio Koide798bc1b2014-02-20 14:02:40 -080057 private IControllerRegistryService controllerRegistryService;
58 private PersistIntent persistIntent;
Toshio Koide27ffd412014-02-18 19:15:27 -080059 @SuppressWarnings("rawtypes")
60 private IEventChannel eventChannel;
Toshio Koidec87810e2014-02-11 13:03:21 -080061
Toshio Koidefe1d5d92014-02-26 20:09:48 -080062 private static Long LOCAL_PORT = 0xFFFEL;
63
Toshio Koide27ffd412014-02-18 19:15:27 -080064 @SuppressWarnings("unchecked")
Toshio Koidec87810e2014-02-11 13:03:21 -080065 @Before
Nick Karanatsios8abe7172014-02-19 20:31:48 -080066 public void setUp() throws Exception {
Toshio Koideebdbb622014-02-12 20:28:38 -080067 MockNetworkGraph graph = new MockNetworkGraph();
Toshio Koidefe1d5d92014-02-26 20:09:48 -080068 graph.createSampleTopology1();
Toshio Koideebdbb622014-02-12 20:28:38 -080069 g = graph;
Toshio Koide27ffd412014-02-18 19:15:27 -080070
Toshio Koide066506e2014-02-20 19:52:09 -080071 datagridService = createMock(IDatagridService.class);
72 networkGraphService = createMock(INetworkGraphService.class);
73 controllerRegistryService = createMock(IControllerRegistryService.class);
74 modContext = createMock(FloodlightModuleContext.class);
75 eventChannel = createMock(IEventChannel.class);
Toshio Koide798bc1b2014-02-20 14:02:40 -080076 persistIntent = PowerMock.createMock(PersistIntent.class);
77
78 PowerMock.expectNew(PersistIntent.class,
Toshio Koide066506e2014-02-20 19:52:09 -080079 anyObject(IControllerRegistryService.class),
80 anyObject(INetworkGraphService.class)).andReturn(persistIntent);
Toshio Koide27ffd412014-02-18 19:15:27 -080081
Toshio Koide066506e2014-02-20 19:52:09 -080082 expect(modContext.getServiceImpl(IDatagridService.class))
Toshio Koide27ffd412014-02-18 19:15:27 -080083 .andReturn(datagridService).once();
Toshio Koide066506e2014-02-20 19:52:09 -080084 expect(modContext.getServiceImpl(INetworkGraphService.class))
Toshio Koide27ffd412014-02-18 19:15:27 -080085 .andReturn(networkGraphService).once();
Toshio Koide066506e2014-02-20 19:52:09 -080086 expect(modContext.getServiceImpl(IControllerRegistryService.class))
Toshio Koide798bc1b2014-02-20 14:02:40 -080087 .andReturn(controllerRegistryService).once();
Toshio Koide066506e2014-02-20 19:52:09 -080088 expect(persistIntent.getKey()).andReturn(1L).anyTimes();
89 expect(persistIntent.persistIfLeader(eq(1L),
90 anyObject(IntentOperationList.class))).andReturn(true).anyTimes();
Toshio Koide0c9106d2014-02-19 15:26:38 -080091
Toshio Koide066506e2014-02-20 19:52:09 -080092 expect(networkGraphService.getNetworkGraph()).andReturn(g).anyTimes();
93 networkGraphService.registerNetworkGraphListener(anyObject(INetworkGraphListener.class));
94 expectLastCall();
Toshio Koide0c9106d2014-02-19 15:26:38 -080095
Toshio Koide066506e2014-02-20 19:52:09 -080096 expect(datagridService.createChannel("onos.pathintent", Long.class, IntentOperationList.class))
Toshio Koide27ffd412014-02-18 19:15:27 -080097 .andReturn(eventChannel).once();
98
Toshio Koide066506e2014-02-20 19:52:09 -080099 expect(datagridService.addListener(
100 eq("onos.pathintent_state"),
101 anyObject(IEventChannelListener.class),
102 eq(Long.class),
103 eq(IntentStateList.class)))
104 .andReturn(eventChannel).once();
105
106 replay(datagridService);
107 replay(networkGraphService);
108 replay(modContext);
109 replay(controllerRegistryService);
Toshio Koide798bc1b2014-02-20 14:02:40 -0800110 PowerMock.replay(persistIntent, PersistIntent.class);
Toshio Koidec87810e2014-02-11 13:03:21 -0800111 }
112
113 @After
114 public void tearDown() {
Toshio Koide066506e2014-02-20 19:52:09 -0800115 verify(datagridService);
116 verify(networkGraphService);
117 verify(modContext);
118 verify(controllerRegistryService);
Toshio Koide798bc1b2014-02-20 14:02:40 -0800119 PowerMock.verify(persistIntent, PersistIntent.class);
Toshio Koidec87810e2014-02-11 13:03:21 -0800120 }
121
Toshio Koide4f308732014-02-18 15:19:48 -0800122 private void showResult(PathIntentMap intents) {
123 for (Intent intent: intents.getAllIntents()) {
124 PathIntent pathIntent = (PathIntent)intent;
Toshio Koidebf875662014-02-24 12:19:15 -0800125 System.out.println("Path intent:" + pathIntent);
Toshio Koidec87810e2014-02-11 13:03:21 -0800126 System.out.println("Parent intent: " + pathIntent.getParentIntent().toString());
Toshio Koidec87810e2014-02-11 13:03:21 -0800127 }
128 }
129
130 @Test
Toshio Koide0c9106d2014-02-19 15:26:38 -0800131 public void createShortestPaths() throws FloodlightModuleException {
Toshio Koidec87810e2014-02-11 13:03:21 -0800132 // create shortest path intents
Toshio Koide27ffd412014-02-18 19:15:27 -0800133 IntentOperationList opList = new IntentOperationList();
Toshio Koidefe1d5d92014-02-26 20:09:48 -0800134 opList.add(Operator.ADD, new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L, LOCAL_PORT));
135 opList.add(Operator.ADD, new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L, LOCAL_PORT));
136 opList.add(Operator.ADD, new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L, LOCAL_PORT));
Toshio Koidec87810e2014-02-11 13:03:21 -0800137
Toshio Koide27ffd412014-02-18 19:15:27 -0800138 // compile high-level intent operations into low-level intent operations (calculate paths)
139 PathCalcRuntimeModule runtime1 = new PathCalcRuntimeModule();
140 runtime1.init(modContext);
141 runtime1.startUp(modContext);
142 IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
143
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800144 // compile low-level intents into flow entry installation plan
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800145 PlanCalcRuntime runtime2 = new PlanCalcRuntime();
Brian O'Connor12861f72014-02-19 20:40:32 -0800146 List<Set<FlowEntry>> plan = runtime2.computePlan(pathIntentOpList);
Toshio Koidec87810e2014-02-11 13:03:21 -0800147
148 // show results
Toshio Koide27ffd412014-02-18 19:15:27 -0800149 showResult((PathIntentMap) runtime1.getPathIntents());
Brian O'Connor12861f72014-02-19 20:40:32 -0800150 System.out.println(plan);
Toshio Koidec87810e2014-02-11 13:03:21 -0800151 }
152
153 @Test
Toshio Koide0c9106d2014-02-19 15:26:38 -0800154 public void createConstrainedShortestPaths() throws FloodlightModuleException {
Toshio Koidec87810e2014-02-11 13:03:21 -0800155 // create constrained shortest path intents
Toshio Koide27ffd412014-02-18 19:15:27 -0800156 IntentOperationList opList = new IntentOperationList();
Toshio Koidefe1d5d92014-02-26 20:09:48 -0800157 opList.add(Operator.ADD, new ConstrainedShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L, LOCAL_PORT, 400.0));
158 opList.add(Operator.ADD, new ConstrainedShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L, LOCAL_PORT, 400.0));
159 opList.add(Operator.ADD, new ConstrainedShortestPathIntent("3", 2L, 24L, LOCAL_PORT, 4L, 42L, LOCAL_PORT, 400.0));
160 opList.add(Operator.ADD, new ConstrainedShortestPathIntent("4", 2L, 23L, LOCAL_PORT, 3L, 32L, LOCAL_PORT, 400.0));
161 opList.add(Operator.ADD, new ConstrainedShortestPathIntent("5", 3L, 34L, LOCAL_PORT, 4L, 43L, LOCAL_PORT, 400.0));
Toshio Koidec87810e2014-02-11 13:03:21 -0800162
Toshio Koide27ffd412014-02-18 19:15:27 -0800163 // compile high-level intent operations into low-level intent operations (calculate paths)
164 PathCalcRuntimeModule runtime1 = new PathCalcRuntimeModule();
165 runtime1.init(modContext);
166 runtime1.startUp(modContext);
167 IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
Toshio Koidec87810e2014-02-11 13:03:21 -0800168
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800169 // compile low-level intents into flow entry installation plan
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800170 PlanCalcRuntime runtime2 = new PlanCalcRuntime();
Brian O'Connor12861f72014-02-19 20:40:32 -0800171 List<Set<FlowEntry>> plan = runtime2.computePlan(pathIntentOpList);
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800172
Toshio Koidec87810e2014-02-11 13:03:21 -0800173 // show results
Toshio Koide27ffd412014-02-18 19:15:27 -0800174 showResult((PathIntentMap) runtime1.getPathIntents());
Brian O'Connor12861f72014-02-19 20:40:32 -0800175 System.out.println(plan);
Toshio Koidec87810e2014-02-11 13:03:21 -0800176 }
177
178 @Test
Toshio Koide0c9106d2014-02-19 15:26:38 -0800179 public void createMixedShortestPaths() throws FloodlightModuleException {
180 // create constrained & best effort shortest path intents
Toshio Koide27ffd412014-02-18 19:15:27 -0800181 IntentOperationList opList = new IntentOperationList();
Toshio Koidefe1d5d92014-02-26 20:09:48 -0800182 opList.add(Operator.ADD, new ConstrainedShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L, LOCAL_PORT, 400.0));
183 opList.add(Operator.ADD, new ConstrainedShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L, LOCAL_PORT, 400.0));
184 opList.add(Operator.ADD, new ShortestPathIntent("3", 2L, 24L, LOCAL_PORT, 4L, 42L, LOCAL_PORT));
185 opList.add(Operator.ADD, new ShortestPathIntent("4", 2L, 23L, LOCAL_PORT, 3L, 32L, LOCAL_PORT));
186 opList.add(Operator.ADD, new ConstrainedShortestPathIntent("5", 3L, 34L, LOCAL_PORT, 4L, 43L, LOCAL_PORT, 400.0));
Toshio Koidec87810e2014-02-11 13:03:21 -0800187
Toshio Koide27ffd412014-02-18 19:15:27 -0800188 // compile high-level intent operations into low-level intent operations (calculate paths)
189 PathCalcRuntimeModule runtime1 = new PathCalcRuntimeModule();
190 runtime1.init(modContext);
191 runtime1.startUp(modContext);
192 IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
Toshio Koidec87810e2014-02-11 13:03:21 -0800193
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800194 // compile low-level intents into flow entry installation plan
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800195 PlanCalcRuntime runtime2 = new PlanCalcRuntime();
Brian O'Connor12861f72014-02-19 20:40:32 -0800196 List<Set<FlowEntry>> plan = runtime2.computePlan(pathIntentOpList);
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800197
Toshio Koidec87810e2014-02-11 13:03:21 -0800198 // show results
Toshio Koide27ffd412014-02-18 19:15:27 -0800199 showResult((PathIntentMap) runtime1.getPathIntents());
Brian O'Connor12861f72014-02-19 20:40:32 -0800200 System.out.println(plan);
Toshio Koidec87810e2014-02-11 13:03:21 -0800201 }
Toshio Koided9fa2a82014-02-19 17:35:18 -0800202
Toshio Koide0c9106d2014-02-19 15:26:38 -0800203 @Test
204 public void rerouteShortestPaths() throws FloodlightModuleException {
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800205 List<SwitchEvent> addedSwitchEvents = new LinkedList<>();
206 List<SwitchEvent> removedSwitchEvents = new LinkedList<>();
207 List<PortEvent> addedPortEvents = new LinkedList<>();
208 List<PortEvent> removedPortEvents = new LinkedList<>();
209 List<LinkEvent> addedLinkEvents = new LinkedList<>();
210 List<LinkEvent> removedLinkEvents = new LinkedList<>();
211 List<DeviceEvent> addedDeviceEvents = new LinkedList<>();
212 List<DeviceEvent> removedDeviceEvents = new LinkedList<>();
213
Toshio Koide0c9106d2014-02-19 15:26:38 -0800214 // create shortest path intents
215 IntentOperationList opList = new IntentOperationList();
Toshio Koidefe1d5d92014-02-26 20:09:48 -0800216 opList.add(Operator.ADD, new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L, LOCAL_PORT));
217 opList.add(Operator.ADD, new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L, LOCAL_PORT));
218 opList.add(Operator.ADD, new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L, LOCAL_PORT));
Toshio Koide0c9106d2014-02-19 15:26:38 -0800219
220 // compile high-level intent operations into low-level intent operations (calculate paths)
221 PathCalcRuntimeModule runtime1 = new PathCalcRuntimeModule();
222 runtime1.init(modContext);
223 runtime1.startUp(modContext);
224 IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
225
226 // compile low-level intents into flow entry installation plan
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800227 PlanCalcRuntime runtime2 = new PlanCalcRuntime();
Brian O'Connor12861f72014-02-19 20:40:32 -0800228 List<Set<FlowEntry>> plan = runtime2.computePlan(pathIntentOpList);
Toshio Koide0c9106d2014-02-19 15:26:38 -0800229
230 // show results step1
231 showResult((PathIntentMap) runtime1.getPathIntents());
Brian O'Connor12861f72014-02-19 20:40:32 -0800232 System.out.println(plan);
Toshio Koide0c9106d2014-02-19 15:26:38 -0800233
Toshio Koidea10c0372014-02-20 17:28:10 -0800234 // TODO this state changes should be triggered by notification of plan module
Toshio Koide066506e2014-02-20 19:52:09 -0800235 IntentStateList states = new IntentStateList();
Toshio Koidea10c0372014-02-20 17:28:10 -0800236 states.put("1", IntentState.INST_ACK);
237 states.put("2", IntentState.INST_ACK);
238 states.put("3", IntentState.INST_ACK);
239 runtime1.getHighLevelIntents().changeStates(states);
Toshio Koidebf875662014-02-24 12:19:15 -0800240 states.clear();
241 states.put("1___0", IntentState.INST_ACK);
242 states.put("2___0", IntentState.INST_ACK);
243 states.put("3___0", IntentState.INST_ACK);
244 runtime1.getPathIntents().changeStates(states);
Toshio Koidea10c0372014-02-20 17:28:10 -0800245
Toshio Koide0c9106d2014-02-19 15:26:38 -0800246 // link down
Toshio Koidefe1d5d92014-02-26 20:09:48 -0800247 ((MockNetworkGraph)g).removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
248 ((MockNetworkGraph)g).removeLink(2L, 21L, 1L, 12L);
249 LinkEvent linkEvent1 = new LinkEvent(1L, 12L, 2L, 21L);
250 LinkEvent linkEvent2 = new LinkEvent(2L, 21L, 1L, 12L);
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800251 removedLinkEvents.clear();
Toshio Koidea10c0372014-02-20 17:28:10 -0800252 removedLinkEvents.add(linkEvent1);
253 removedLinkEvents.add(linkEvent2);
Toshio Koide798bc1b2014-02-20 14:02:40 -0800254 runtime1.networkGraphEvents(
255 addedSwitchEvents,
256 removedSwitchEvents,
257 addedPortEvents,
258 removedPortEvents,
259 addedLinkEvents,
260 removedLinkEvents,
261 addedDeviceEvents,
262 removedDeviceEvents);
Toshio Koide0c9106d2014-02-19 15:26:38 -0800263 System.out.println("Link goes down.");
264
265 // show results step2
266 showResult((PathIntentMap) runtime1.getPathIntents());
Brian O'Connor12861f72014-02-19 20:40:32 -0800267 // TODO: show results of plan computation
Toshio Koide0c9106d2014-02-19 15:26:38 -0800268 }
Toshio Koidefa735a12014-03-28 10:49:07 -0700269
270
271 @Test
272 public void createAndRemoveShortestPaths() throws FloodlightModuleException {
273 // create shortest path intents
274 IntentOperationList opList = new IntentOperationList();
275 opList.add(Operator.ADD, new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L, LOCAL_PORT));
276 opList.add(Operator.ADD, new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L, LOCAL_PORT));
277 opList.add(Operator.ADD, new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L, LOCAL_PORT));
278
279 // compile high-level intent operations into low-level intent operations (calculate paths)
280 PathCalcRuntimeModule runtime1 = new PathCalcRuntimeModule();
281 runtime1.init(modContext);
282 runtime1.startUp(modContext);
283 IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
284
285 // compile low-level intents into flow entry installation plan
286 PlanCalcRuntime runtime2 = new PlanCalcRuntime();
287 List<Set<FlowEntry>> plan = runtime2.computePlan(pathIntentOpList);
288
289 // show results
290 showResult((PathIntentMap) runtime1.getPathIntents());
291 System.out.println(plan);
292
293 // create remove operations
294 opList.clear();
295 opList.add(Operator.REMOVE, new Intent("1"));
296 opList.add(Operator.REMOVE, new Intent("2"));
297
298 // compile
299 runtime1.executeIntentOperations(opList);
300
301 // show results
302 showResult((PathIntentMap) runtime1.getPathIntents());
303 System.out.println(plan);
304 }
305
Toshio Koidec87810e2014-02-11 13:03:21 -0800306}