blob: b92b0933304090584dc9157befe84456c14ca026 [file] [log] [blame]
alshabibab984662014-12-04 18:56:18 -08001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.sdnip;
Pingpingf5d90932014-10-27 10:50:04 -070017
Jonathan Hart552e31f2015-02-06 11:11:59 -080018import com.google.common.collect.Sets;
Pingpingf5d90932014-10-27 10:50:04 -070019import org.junit.Before;
Brian O'Connor03406a42015-02-03 17:28:57 -080020import org.junit.Ignore;
Pingpingf5d90932014-10-27 10:50:04 -070021import org.junit.Test;
22import org.onlab.junit.TestUtils;
23import org.onlab.junit.TestUtils.TestUtilsException;
Jonathan Hart6cd2f352015-01-13 17:44:45 -080024import org.onlab.packet.Ethernet;
25import org.onlab.packet.Ip4Address;
26import org.onlab.packet.Ip4Prefix;
27import org.onlab.packet.IpAddress;
28import org.onlab.packet.IpPrefix;
29import org.onlab.packet.MacAddress;
30import org.onlab.packet.VlanId;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.core.ApplicationId;
32import org.onosproject.net.ConnectPoint;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.net.DeviceId;
Brian O'Connorabafb502014-12-02 22:26:20 -080034import org.onosproject.net.PortNumber;
35import org.onosproject.net.flow.DefaultTrafficSelector;
36import org.onosproject.net.flow.DefaultTrafficTreatment;
37import org.onosproject.net.flow.TrafficSelector;
38import org.onosproject.net.flow.TrafficTreatment;
Brian O'Connorabafb502014-12-02 22:26:20 -080039import org.onosproject.net.host.InterfaceIpAddress;
40import org.onosproject.net.intent.AbstractIntentTest;
41import org.onosproject.net.intent.Intent;
Brian O'Connorabafb502014-12-02 22:26:20 -080042import org.onosproject.net.intent.IntentService;
43import org.onosproject.net.intent.IntentState;
44import org.onosproject.net.intent.MultiPointToSinglePointIntent;
Jonathan Hart41349e92015-02-09 14:14:02 -080045import org.onosproject.routingapi.FibEntry;
46import org.onosproject.routingapi.FibUpdate;
47import org.onosproject.routingapi.RouteEntry;
48import org.onosproject.sdnip.IntentSynchronizer.IntentKey;
49import org.onosproject.sdnip.config.BgpPeer;
Brian O'Connorabafb502014-12-02 22:26:20 -080050import org.onosproject.sdnip.config.Interface;
Jonathan Hart41349e92015-02-09 14:14:02 -080051import org.onosproject.sdnip.config.SdnIpConfigurationService;
Pingpingf5d90932014-10-27 10:50:04 -070052
Jonathan Hart41349e92015-02-09 14:14:02 -080053import java.util.Collections;
54import java.util.HashMap;
Jonathan Hart552e31f2015-02-06 11:11:59 -080055import java.util.HashSet;
Jonathan Hart41349e92015-02-09 14:14:02 -080056import java.util.Map;
Jonathan Hart552e31f2015-02-06 11:11:59 -080057import java.util.Set;
58import java.util.concurrent.ConcurrentHashMap;
59
60import static org.easymock.EasyMock.*;
61import static org.hamcrest.Matchers.is;
Brian O'Connor03406a42015-02-03 17:28:57 -080062import static org.junit.Assert.*;
Pingpingf5d90932014-10-27 10:50:04 -070063
64/**
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080065 * This class tests the intent synchronization function in the
66 * IntentSynchronizer class.
Pingpingf5d90932014-10-27 10:50:04 -070067 */
Brian O'Connor03406a42015-02-03 17:28:57 -080068@Ignore //FIXME
Brian O'Connor520c0522014-11-23 23:50:47 -080069public class IntentSyncTest extends AbstractIntentTest {
Pingpingf5d90932014-10-27 10:50:04 -070070
Jonathan Hart41349e92015-02-09 14:14:02 -080071 private SdnIpConfigurationService sdnIpConfigService;
Pingpingf5d90932014-10-27 10:50:04 -070072 private InterfaceService interfaceService;
73 private IntentService intentService;
Pingpingf5d90932014-10-27 10:50:04 -070074
75 private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
76 DeviceId.deviceId("of:0000000000000001"),
77 PortNumber.portNumber(1));
78
79 private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
80 DeviceId.deviceId("of:0000000000000002"),
81 PortNumber.portNumber(1));
82
83 private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
84 DeviceId.deviceId("of:0000000000000003"),
85 PortNumber.portNumber(1));
86
Jonathan Hart41349e92015-02-09 14:14:02 -080087 private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
88 DeviceId.deviceId("of:0000000000000004"),
89 PortNumber.portNumber(1));
90
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080091 private IntentSynchronizer intentSynchronizer;
Pingpingf5d90932014-10-27 10:50:04 -070092
93 private static final ApplicationId APPID = new ApplicationId() {
94 @Override
95 public short id() {
96 return 1;
97 }
98
99 @Override
100 public String name() {
101 return "SDNIP";
102 }
103 };
104
105 @Before
106 public void setUp() throws Exception {
Brian O'Connor520c0522014-11-23 23:50:47 -0800107 super.setUp();
Pingpingf5d90932014-10-27 10:50:04 -0700108 setUpInterfaceService();
Jonathan Hart41349e92015-02-09 14:14:02 -0800109
110 setUpBgpPeers();
Pingpingf5d90932014-10-27 10:50:04 -0700111 intentService = createMock(IntentService.class);
112
Jonathan Hart552e31f2015-02-06 11:11:59 -0800113 intentSynchronizer = new IntentSynchronizer(APPID, intentService,
Jonathan Hart41349e92015-02-09 14:14:02 -0800114 sdnIpConfigService, interfaceService);
115 }
116
117 /**
118 * Sets up BGP peers in external networks.
119 */
120 private void setUpBgpPeers() {
121
122 Map<IpAddress, BgpPeer> peers = new HashMap<>();
123
124 String peerSw1Eth1 = "192.168.10.1";
125 peers.put(IpAddress.valueOf(peerSw1Eth1),
126 new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
127
128 // Two BGP peers are connected to switch 2 port 1.
129 String peer1Sw2Eth1 = "192.168.20.1";
130 peers.put(IpAddress.valueOf(peer1Sw2Eth1),
131 new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
132
133 String peer2Sw2Eth1 = "192.168.20.2";
134 peers.put(IpAddress.valueOf(peer2Sw2Eth1),
135 new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
136
137 String peer1Sw4Eth1 = "192.168.40.1";
138 peers.put(IpAddress.valueOf(peer1Sw4Eth1),
139 new BgpPeer("00:00:00:00:00:00:00:04", 1, peer1Sw4Eth1));
140
141 sdnIpConfigService = createMock(SdnIpConfigurationService.class);
142 expect(sdnIpConfigService.getBgpPeers()).andReturn(peers).anyTimes();
Brian O'Connor03406a42015-02-03 17:28:57 -0800143 replay(sdnIpConfigService);
Jonathan Hart41349e92015-02-09 14:14:02 -0800144
Pingpingf5d90932014-10-27 10:50:04 -0700145 }
146
147 /**
148 * Sets up InterfaceService.
149 */
150 private void setUpInterfaceService() {
151
152 interfaceService = createMock(InterfaceService.class);
153
154 Set<Interface> interfaces = Sets.newHashSet();
155
156 Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
157 interfaceIpAddresses1.add(new InterfaceIpAddress(
158 IpAddress.valueOf("192.168.10.101"),
159 IpPrefix.valueOf("192.168.10.0/24")));
160 Interface sw1Eth1 = new Interface(SW1_ETH1,
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800161 interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
162 VlanId.NONE);
Pingpingf5d90932014-10-27 10:50:04 -0700163 interfaces.add(sw1Eth1);
164
165 Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
Jonathan Hart41349e92015-02-09 14:14:02 -0800166 interfaceIpAddresses2.add(
167 new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
168 IpPrefix.valueOf("192.168.20.0/24")));
Pingpingf5d90932014-10-27 10:50:04 -0700169 Interface sw2Eth1 = new Interface(SW2_ETH1,
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800170 interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
171 VlanId.NONE);
Pingpingf5d90932014-10-27 10:50:04 -0700172 interfaces.add(sw2Eth1);
173
174 Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
Jonathan Hart41349e92015-02-09 14:14:02 -0800175 interfaceIpAddresses3.add(
176 new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
177 IpPrefix.valueOf("192.168.30.0/24")));
Pingpingf5d90932014-10-27 10:50:04 -0700178 Interface sw3Eth1 = new Interface(SW3_ETH1,
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800179 interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
180 VlanId.NONE);
Pingpingf5d90932014-10-27 10:50:04 -0700181 interfaces.add(sw3Eth1);
182
Jonathan Hart41349e92015-02-09 14:14:02 -0800183 InterfaceIpAddress interfaceIpAddress4 =
184 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"),
185 IpPrefix.valueOf("192.168.40.0/24"));
186 Interface sw4Eth1 = new Interface(SW4_ETH1,
187 Sets.newHashSet(interfaceIpAddress4),
188 MacAddress.valueOf("00:00:00:00:00:04"),
189 VlanId.vlanId((short) 1));
190
191 expect(interfaceService.getInterface(SW4_ETH1)).andReturn(sw4Eth1).anyTimes();
192 interfaces.add(sw4Eth1);
193
Pingpingf5d90932014-10-27 10:50:04 -0700194 expect(interfaceService.getInterface(SW1_ETH1)).andReturn(
195 sw1Eth1).anyTimes();
196 expect(interfaceService.getInterface(SW2_ETH1)).andReturn(
197 sw2Eth1).anyTimes();
198 expect(interfaceService.getInterface(SW3_ETH1)).andReturn(
199 sw3Eth1).anyTimes();
Jonathan Hart41349e92015-02-09 14:14:02 -0800200 expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700201 replay(interfaceService);
202 }
203
204 /**
Jonathan Hart41349e92015-02-09 14:14:02 -0800205 * Tests adding a FIB entry to the IntentSynchronizer.
206 *
207 * We verify that the synchronizer records the correct state and that the
208 * correct intent is submitted to the IntentService.
209 *
210 * @throws TestUtilsException
Pingpingf5d90932014-10-27 10:50:04 -0700211 */
Jonathan Hart41349e92015-02-09 14:14:02 -0800212 @Test
213 public void testFibAdd() throws TestUtilsException {
214 FibEntry fibEntry = new FibEntry(
215 Ip4Prefix.valueOf("1.1.1.0/24"),
216 Ip4Address.valueOf("192.168.10.1"),
217 MacAddress.valueOf("00:00:00:00:00:01"));
Pingpingf5d90932014-10-27 10:50:04 -0700218
Jonathan Hart41349e92015-02-09 14:14:02 -0800219 // Construct a MultiPointToSinglePointIntent intent
220 TrafficSelector.Builder selectorBuilder =
221 DefaultTrafficSelector.builder();
222 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
223 fibEntry.prefix());
Pingpingf5d90932014-10-27 10:50:04 -0700224
Jonathan Hart41349e92015-02-09 14:14:02 -0800225 TrafficTreatment.Builder treatmentBuilder =
226 DefaultTrafficTreatment.builder();
227 treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
Pingpingf5d90932014-10-27 10:50:04 -0700228
Jonathan Hart41349e92015-02-09 14:14:02 -0800229 Set<ConnectPoint> ingressPoints = new HashSet<>();
230 ingressPoints.add(SW2_ETH1);
231 ingressPoints.add(SW3_ETH1);
232 ingressPoints.add(SW4_ETH1);
233
234 MultiPointToSinglePointIntent intent =
235 new MultiPointToSinglePointIntent(APPID,
236 selectorBuilder.build(), treatmentBuilder.build(),
237 ingressPoints, SW1_ETH1);
238
239 // Setup the expected intents
Brian O'Connor03406a42015-02-03 17:28:57 -0800240// FIXME Jono needs to refactor
241// IntentOperations.Builder builder = IntentOperations.builder(APPID);
242// builder.addSubmitOperation(intent);
243// intentService.execute(TestIntentServiceHelper.eqExceptId(
244// builder.build()));
Jonathan Hart41349e92015-02-09 14:14:02 -0800245 replay(intentService);
246
247 intentSynchronizer.leaderChanged(true);
248 TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
249
250 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
251 fibEntry);
252 intentSynchronizer.update(Collections.singleton(fibUpdate),
253 Collections.emptyList());
254
Brian O'Connor03406a42015-02-03 17:28:57 -0800255 assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
Jonathan Hart41349e92015-02-09 14:14:02 -0800256 Intent firstIntent =
257 intentSynchronizer.getRouteIntents().iterator().next();
258 IntentKey firstIntentKey = new IntentKey(firstIntent);
259 IntentKey intentKey = new IntentKey(intent);
260 assertTrue(firstIntentKey.equals(intentKey));
261 verify(intentService);
262 }
263
264 /**
265 * Tests adding a FIB entry with to a next hop in a VLAN.
266 *
267 * We verify that the synchronizer records the correct state and that the
268 * correct intent is submitted to the IntentService.
269 *
270 * @throws TestUtilsException
271 */
272 @Test
273 public void testFibAddWithVlan() throws TestUtilsException {
274 FibEntry fibEntry = new FibEntry(
275 Ip4Prefix.valueOf("3.3.3.0/24"),
276 Ip4Address.valueOf("192.168.40.1"),
277 MacAddress.valueOf("00:00:00:00:00:04"));
278
279 // Construct a MultiPointToSinglePointIntent intent
280 TrafficSelector.Builder selectorBuilder =
281 DefaultTrafficSelector.builder();
282 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)
283 .matchIPDst(fibEntry.prefix())
284 .matchVlanId(VlanId.ANY);
285
286 TrafficTreatment.Builder treatmentBuilder =
287 DefaultTrafficTreatment.builder();
288 treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:04"))
289 .setVlanId(VlanId.vlanId((short) 1));
290
291 Set<ConnectPoint> ingressPoints = new HashSet<>();
292 ingressPoints.add(SW1_ETH1);
293 ingressPoints.add(SW2_ETH1);
294 ingressPoints.add(SW3_ETH1);
295
296 MultiPointToSinglePointIntent intent =
297 new MultiPointToSinglePointIntent(APPID,
298 selectorBuilder.build(), treatmentBuilder.build(),
299 ingressPoints, SW4_ETH1);
300
301 // Setup the expected intents
Brian O'Connor03406a42015-02-03 17:28:57 -0800302// FIXME Jono needs to refactor
303// IntentOperations.Builder builder = IntentOperations.builder(APPID);
304// builder.addSubmitOperation(intent);
305// intentService.execute(
306// TestIntentServiceHelper.eqExceptId(builder.build()));
Jonathan Hart41349e92015-02-09 14:14:02 -0800307 replay(intentService);
308
309 // Run the test
310 intentSynchronizer.leaderChanged(true);
311 TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
312 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
313
314 intentSynchronizer.update(Collections.singleton(fibUpdate),
315 Collections.emptyList());
316
317 // Verify
Brian O'Connor03406a42015-02-03 17:28:57 -0800318 assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
Jonathan Hart41349e92015-02-09 14:14:02 -0800319 Intent firstIntent =
320 intentSynchronizer.getRouteIntents().iterator().next();
321 IntentKey firstIntentKey = new IntentKey(firstIntent);
322 IntentKey intentKey = new IntentKey(intent);
323 assertTrue(firstIntentKey.equals(intentKey));
324 verify(intentService);
325 }
326
327 /**
328 * Tests updating a FIB entry.
329 *
330 * We verify that the synchronizer records the correct state and that the
331 * correct intent is submitted to the IntentService.
332 *
333 * @throws TestUtilsException
334 */
335 @Test
336 public void testFibUpdate() throws TestUtilsException {
337 // Firstly add a route
338 testFibAdd();
339
340 Intent addedIntent =
341 intentSynchronizer.getRouteIntents().iterator().next();
342
343 // Start to construct a new route entry and new intent
344 FibEntry fibEntryUpdate = new FibEntry(
345 Ip4Prefix.valueOf("1.1.1.0/24"),
346 Ip4Address.valueOf("192.168.20.1"),
347 MacAddress.valueOf("00:00:00:00:00:02"));
348
349 // Construct a new MultiPointToSinglePointIntent intent
350 TrafficSelector.Builder selectorBuilderNew =
351 DefaultTrafficSelector.builder();
352 selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
353 fibEntryUpdate.prefix());
354
355 TrafficTreatment.Builder treatmentBuilderNew =
356 DefaultTrafficTreatment.builder();
357 treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
Pingpingf5d90932014-10-27 10:50:04 -0700358
359
Jonathan Hart41349e92015-02-09 14:14:02 -0800360 Set<ConnectPoint> ingressPointsNew = new HashSet<>();
361 ingressPointsNew.add(SW1_ETH1);
362 ingressPointsNew.add(SW3_ETH1);
363 ingressPointsNew.add(SW4_ETH1);
Pingpingf5d90932014-10-27 10:50:04 -0700364
Jonathan Hart41349e92015-02-09 14:14:02 -0800365 MultiPointToSinglePointIntent intentNew =
366 new MultiPointToSinglePointIntent(APPID,
367 selectorBuilderNew.build(),
368 treatmentBuilderNew.build(),
369 ingressPointsNew, SW2_ETH1);
Pingpingf5d90932014-10-27 10:50:04 -0700370
Jonathan Hart41349e92015-02-09 14:14:02 -0800371 // Set up test expectation
372 reset(intentService);
373 // Setup the expected intents
Brian O'Connor03406a42015-02-03 17:28:57 -0800374// FIXME Jono needs to refactor
375// IntentOperations.Builder builder = IntentOperations.builder(APPID);
376// builder.addWithdrawOperation(addedIntent.id());
377// intentService.execute(TestIntentServiceHelper.eqExceptId(
378// builder.build()));
379// builder = IntentOperations.builder(APPID);
380// builder.addSubmitOperation(intentNew);
381// intentService.execute(TestIntentServiceHelper.eqExceptId(
382// builder.build()));
Jonathan Hart41349e92015-02-09 14:14:02 -0800383 replay(intentService);
Pingpingf5d90932014-10-27 10:50:04 -0700384
Jonathan Hart41349e92015-02-09 14:14:02 -0800385 // Call the update() method in IntentSynchronizer class
386 intentSynchronizer.leaderChanged(true);
387 TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
388 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
389 fibEntryUpdate);
390 intentSynchronizer.update(Collections.singletonList(fibUpdate),
391 Collections.emptyList());
Pingpingf5d90932014-10-27 10:50:04 -0700392
Jonathan Hart41349e92015-02-09 14:14:02 -0800393 // Verify
Brian O'Connor03406a42015-02-03 17:28:57 -0800394 assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
Jonathan Hart41349e92015-02-09 14:14:02 -0800395 Intent firstIntent =
396 intentSynchronizer.getRouteIntents().iterator().next();
397 IntentKey firstIntentKey = new IntentKey(firstIntent);
398 IntentKey intentNewKey = new IntentKey(intentNew);
399 assertTrue(firstIntentKey.equals(intentNewKey));
400 verify(intentService);
401 }
Pingpingf5d90932014-10-27 10:50:04 -0700402
Jonathan Hart41349e92015-02-09 14:14:02 -0800403 /**
404 * Tests deleting a FIB entry.
405 *
406 * We verify that the synchronizer records the correct state and that the
407 * correct intent is withdrawn from the IntentService.
408 *
409 * @throws TestUtilsException
410 */
411 @Test
412 public void testFibDelete() throws TestUtilsException {
413 // Firstly add a route
414 testFibAdd();
Pingpingf5d90932014-10-27 10:50:04 -0700415
Jonathan Hart41349e92015-02-09 14:14:02 -0800416 Intent addedIntent =
417 intentSynchronizer.getRouteIntents().iterator().next();
418
419 // Construct the existing route entry
420 FibEntry fibEntry = new FibEntry(
421 Ip4Prefix.valueOf("1.1.1.0/24"), null, null);
422
423 // Set up expectation
424 reset(intentService);
425 // Setup the expected intents
Brian O'Connor03406a42015-02-03 17:28:57 -0800426// FIXME Jono needs to refactor
427// IntentOperations.Builder builder = IntentOperations.builder(APPID);
428// builder.addWithdrawOperation(addedIntent.id());
429// intentService.execute(TestIntentServiceHelper.eqExceptId(
430// builder.build()));
Jonathan Hart41349e92015-02-09 14:14:02 -0800431 replay(intentService);
432
433 // Call the update() method in IntentSynchronizer class
434 intentSynchronizer.leaderChanged(true);
435 TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
436 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);
437 intentSynchronizer.update(Collections.emptyList(),
438 Collections.singletonList(fibUpdate));
439
440 // Verify
Brian O'Connor03406a42015-02-03 17:28:57 -0800441 assertEquals(intentSynchronizer.getRouteIntents().size(), 0);
Jonathan Hart41349e92015-02-09 14:14:02 -0800442 verify(intentService);
Pingpingf5d90932014-10-27 10:50:04 -0700443 }
444
445 /**
446 * This method tests the behavior of intent Synchronizer.
447 *
448 * @throws TestUtilsException
449 */
450 @Test
451 public void testIntentSync() throws TestUtilsException {
452
453 //
454 // Construct routes and intents.
455 // This test simulates the following cases during the master change
456 // time interval:
457 // 1. RouteEntry1 did not change and the intent also did not change.
458 // 2. RouteEntry2 was deleted, but the intent was not deleted.
459 // 3. RouteEntry3 was newly added, and the intent was also submitted.
460 // 4. RouteEntry4 was updated to RouteEntry4Update, and the intent was
461 // also updated to a new one.
462 // 5. RouteEntry5 did not change, but its intent id changed.
463 // 6. RouteEntry6 was newly added, but the intent was not submitted.
464 //
465 RouteEntry routeEntry1 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800466 Ip4Prefix.valueOf("1.1.1.0/24"),
467 Ip4Address.valueOf("192.168.10.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700468
469 RouteEntry routeEntry2 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800470 Ip4Prefix.valueOf("2.2.2.0/24"),
471 Ip4Address.valueOf("192.168.20.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700472
473 RouteEntry routeEntry3 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800474 Ip4Prefix.valueOf("3.3.3.0/24"),
475 Ip4Address.valueOf("192.168.30.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700476
477 RouteEntry routeEntry4 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800478 Ip4Prefix.valueOf("4.4.4.0/24"),
479 Ip4Address.valueOf("192.168.30.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700480
481 RouteEntry routeEntry4Update = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800482 Ip4Prefix.valueOf("4.4.4.0/24"),
483 Ip4Address.valueOf("192.168.20.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700484
485 RouteEntry routeEntry5 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800486 Ip4Prefix.valueOf("5.5.5.0/24"),
487 Ip4Address.valueOf("192.168.10.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700488
489 RouteEntry routeEntry6 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800490 Ip4Prefix.valueOf("6.6.6.0/24"),
491 Ip4Address.valueOf("192.168.10.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700492
Jonathan Hartec2df012014-10-23 16:40:24 -0700493 RouteEntry routeEntry7 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800494 Ip4Prefix.valueOf("7.7.7.0/24"),
495 Ip4Address.valueOf("192.168.10.1"));
Jonathan Hartec2df012014-10-23 16:40:24 -0700496
Pingpingf5d90932014-10-27 10:50:04 -0700497 MultiPointToSinglePointIntent intent1 = intentBuilder(
498 routeEntry1.prefix(), "00:00:00:00:00:01", SW1_ETH1);
499 MultiPointToSinglePointIntent intent2 = intentBuilder(
500 routeEntry2.prefix(), "00:00:00:00:00:02", SW2_ETH1);
501 MultiPointToSinglePointIntent intent3 = intentBuilder(
502 routeEntry3.prefix(), "00:00:00:00:00:03", SW3_ETH1);
503 MultiPointToSinglePointIntent intent4 = intentBuilder(
504 routeEntry4.prefix(), "00:00:00:00:00:03", SW3_ETH1);
505 MultiPointToSinglePointIntent intent4Update = intentBuilder(
506 routeEntry4Update.prefix(), "00:00:00:00:00:02", SW2_ETH1);
507 MultiPointToSinglePointIntent intent5 = intentBuilder(
508 routeEntry5.prefix(), "00:00:00:00:00:01", SW1_ETH1);
Jonathan Hartec2df012014-10-23 16:40:24 -0700509 MultiPointToSinglePointIntent intent7 = intentBuilder(
510 routeEntry7.prefix(), "00:00:00:00:00:01", SW1_ETH1);
Pingpingf5d90932014-10-27 10:50:04 -0700511
512 // Compose a intent, which is equal to intent5 but the id is different.
513 MultiPointToSinglePointIntent intent5New =
514 staticIntentBuilder(intent5, routeEntry5, "00:00:00:00:00:01");
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800515 assertThat(IntentSynchronizer.IntentKey.equalIntents(
516 intent5, intent5New),
517 is(true));
Jonathan Hartec2df012014-10-23 16:40:24 -0700518 assertFalse(intent5.equals(intent5New));
Pingpingf5d90932014-10-27 10:50:04 -0700519
520 MultiPointToSinglePointIntent intent6 = intentBuilder(
521 routeEntry6.prefix(), "00:00:00:00:00:01", SW1_ETH1);
522
Jonathan Hart41349e92015-02-09 14:14:02 -0800523 // Set up the routeIntents field in IntentSynchronizer class
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800524 ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent>
525 routeIntents = new ConcurrentHashMap<>();
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800526 routeIntents.put(routeEntry1.prefix(), intent1);
527 routeIntents.put(routeEntry3.prefix(), intent3);
528 routeIntents.put(routeEntry4Update.prefix(), intent4Update);
529 routeIntents.put(routeEntry5.prefix(), intent5New);
530 routeIntents.put(routeEntry6.prefix(), intent6);
531 routeIntents.put(routeEntry7.prefix(), intent7);
532 TestUtils.setField(intentSynchronizer, "routeIntents", routeIntents);
Pingpingf5d90932014-10-27 10:50:04 -0700533
534 // Set up expectation
535 reset(intentService);
536 Set<Intent> intents = new HashSet<Intent>();
537 intents.add(intent1);
Jonathan Hartec2df012014-10-23 16:40:24 -0700538 expect(intentService.getIntentState(intent1.id()))
539 .andReturn(IntentState.INSTALLED).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700540 intents.add(intent2);
Jonathan Hartec2df012014-10-23 16:40:24 -0700541 expect(intentService.getIntentState(intent2.id()))
542 .andReturn(IntentState.INSTALLED).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700543 intents.add(intent4);
Jonathan Hartec2df012014-10-23 16:40:24 -0700544 expect(intentService.getIntentState(intent4.id()))
545 .andReturn(IntentState.INSTALLED).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700546 intents.add(intent5);
Jonathan Hartec2df012014-10-23 16:40:24 -0700547 expect(intentService.getIntentState(intent5.id()))
548 .andReturn(IntentState.INSTALLED).anyTimes();
549 intents.add(intent7);
550 expect(intentService.getIntentState(intent7.id()))
551 .andReturn(IntentState.WITHDRAWING).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700552 expect(intentService.getIntents()).andReturn(intents).anyTimes();
553
Brian O'Connor03406a42015-02-03 17:28:57 -0800554 intentService.withdraw(intent2);
555 intentService.withdraw(intent4);
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800556
Brian O'Connor03406a42015-02-03 17:28:57 -0800557 intentService.submit(intent3);
558 intentService.submit(intent4Update);
559 intentService.submit(intent6);
560 intentService.submit(intent7);
Pingpingf5d90932014-10-27 10:50:04 -0700561 replay(intentService);
562
563 // Start the test
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -0800564 intentSynchronizer.leaderChanged(true);
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800565 intentSynchronizer.synchronizeIntents();
Pingpingf5d90932014-10-27 10:50:04 -0700566
567 // Verify
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800568 assertEquals(intentSynchronizer.getRouteIntents().size(), 6);
569 assertTrue(intentSynchronizer.getRouteIntents().contains(intent1));
570 assertTrue(intentSynchronizer.getRouteIntents().contains(intent3));
571 assertTrue(intentSynchronizer.getRouteIntents().contains(intent4Update));
572 assertTrue(intentSynchronizer.getRouteIntents().contains(intent5));
573 assertTrue(intentSynchronizer.getRouteIntents().contains(intent6));
Pingpingf5d90932014-10-27 10:50:04 -0700574
575 verify(intentService);
576 }
577
578 /**
579 * MultiPointToSinglePointIntent builder.
580 *
581 * @param ipPrefix the ipPrefix to match
582 * @param nextHopMacAddress to which the destination MAC address in packet
583 * should be rewritten
584 * @param egressPoint to which packets should be sent
585 * @return the constructed MultiPointToSinglePointIntent
586 */
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800587 private MultiPointToSinglePointIntent intentBuilder(IpPrefix ipPrefix,
Pingpingf5d90932014-10-27 10:50:04 -0700588 String nextHopMacAddress, ConnectPoint egressPoint) {
589
590 TrafficSelector.Builder selectorBuilder =
591 DefaultTrafficSelector.builder();
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800592 if (ipPrefix.version() == Ip4Address.VERSION) {
593 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4); // IPv4
594 } else {
595 selectorBuilder.matchEthType(Ethernet.TYPE_IPV6); // IPv6
596 }
597 selectorBuilder.matchIPDst(ipPrefix);
Pingpingf5d90932014-10-27 10:50:04 -0700598
599 TrafficTreatment.Builder treatmentBuilder =
600 DefaultTrafficTreatment.builder();
601 treatmentBuilder.setEthDst(MacAddress.valueOf(nextHopMacAddress));
602
603 Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
604 for (Interface intf : interfaceService.getInterfaces()) {
605 if (!intf.equals(interfaceService.getInterface(egressPoint))) {
606 ConnectPoint srcPort = intf.connectPoint();
607 ingressPoints.add(srcPort);
608 }
609 }
610 MultiPointToSinglePointIntent intent =
611 new MultiPointToSinglePointIntent(APPID,
612 selectorBuilder.build(), treatmentBuilder.build(),
613 ingressPoints, egressPoint);
614 return intent;
615 }
616
617 /**
618 * A static MultiPointToSinglePointIntent builder, the returned intent is
619 * equal to the input intent except that the id is different.
620 *
621 *
622 * @param intent the intent to be used for building a new intent
623 * @param routeEntry the relative routeEntry of the intent
624 * @return the newly constructed MultiPointToSinglePointIntent
625 * @throws TestUtilsException
626 */
627 private MultiPointToSinglePointIntent staticIntentBuilder(
628 MultiPointToSinglePointIntent intent, RouteEntry routeEntry,
629 String nextHopMacAddress) throws TestUtilsException {
630
631 // Use a different egress ConnectPoint with that in intent
632 // to generate a different id
633 MultiPointToSinglePointIntent intentNew = intentBuilder(
634 routeEntry.prefix(), nextHopMacAddress, SW2_ETH1);
635 TestUtils.setField(intentNew, "egressPoint", intent.egressPoint());
636 TestUtils.setField(intentNew,
637 "ingressPoints", intent.ingressPoints());
638 return intentNew;
639 }
Pingpingf5d90932014-10-27 10:50:04 -0700640}