blob: 857f49a6d3adc47e38698d65b05a0b924b5e6408 [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;
20import org.junit.Test;
21import org.onlab.junit.TestUtils;
22import org.onlab.junit.TestUtils.TestUtilsException;
Jonathan Hart6cd2f352015-01-13 17:44:45 -080023import org.onlab.packet.Ethernet;
24import org.onlab.packet.Ip4Address;
25import org.onlab.packet.Ip4Prefix;
26import org.onlab.packet.IpAddress;
27import org.onlab.packet.IpPrefix;
28import org.onlab.packet.MacAddress;
29import org.onlab.packet.VlanId;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.core.ApplicationId;
31import org.onosproject.net.ConnectPoint;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.net.DeviceId;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.net.PortNumber;
34import org.onosproject.net.flow.DefaultTrafficSelector;
35import org.onosproject.net.flow.DefaultTrafficTreatment;
36import org.onosproject.net.flow.TrafficSelector;
37import org.onosproject.net.flow.TrafficTreatment;
Brian O'Connorabafb502014-12-02 22:26:20 -080038import org.onosproject.net.host.InterfaceIpAddress;
39import org.onosproject.net.intent.AbstractIntentTest;
40import org.onosproject.net.intent.Intent;
Brian O'Connorabafb502014-12-02 22:26:20 -080041import org.onosproject.net.intent.IntentService;
42import org.onosproject.net.intent.IntentState;
43import org.onosproject.net.intent.MultiPointToSinglePointIntent;
Jonathan Hart41349e92015-02-09 14:14:02 -080044import org.onosproject.routingapi.FibEntry;
45import org.onosproject.routingapi.FibUpdate;
46import org.onosproject.routingapi.RouteEntry;
47import org.onosproject.sdnip.IntentSynchronizer.IntentKey;
48import org.onosproject.sdnip.config.BgpPeer;
Brian O'Connorabafb502014-12-02 22:26:20 -080049import org.onosproject.sdnip.config.Interface;
Jonathan Hart41349e92015-02-09 14:14:02 -080050import org.onosproject.sdnip.config.SdnIpConfigurationService;
Pingpingf5d90932014-10-27 10:50:04 -070051
Jonathan Hart41349e92015-02-09 14:14:02 -080052import java.util.Collections;
53import java.util.HashMap;
Jonathan Hart552e31f2015-02-06 11:11:59 -080054import java.util.HashSet;
Jonathan Hart41349e92015-02-09 14:14:02 -080055import java.util.Map;
Jonathan Hart552e31f2015-02-06 11:11:59 -080056import java.util.Set;
57import java.util.concurrent.ConcurrentHashMap;
58
59import static org.easymock.EasyMock.*;
60import static org.hamcrest.Matchers.is;
Jonathan Hartcb726fc2015-02-13 16:26:22 -080061import static org.junit.Assert.assertEquals;
62import static org.junit.Assert.assertFalse;
63import static org.junit.Assert.assertThat;
64import static org.junit.Assert.assertTrue;
65import static org.onosproject.sdnip.TestIntentServiceHelper.eqExceptId;
Pingpingf5d90932014-10-27 10:50:04 -070066
67/**
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080068 * This class tests the intent synchronization function in the
69 * IntentSynchronizer class.
Pingpingf5d90932014-10-27 10:50:04 -070070 */
Brian O'Connor520c0522014-11-23 23:50:47 -080071public class IntentSyncTest extends AbstractIntentTest {
Pingpingf5d90932014-10-27 10:50:04 -070072
Jonathan Hart41349e92015-02-09 14:14:02 -080073 private SdnIpConfigurationService sdnIpConfigService;
Pingpingf5d90932014-10-27 10:50:04 -070074 private InterfaceService interfaceService;
75 private IntentService intentService;
Pingpingf5d90932014-10-27 10:50:04 -070076
77 private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
78 DeviceId.deviceId("of:0000000000000001"),
79 PortNumber.portNumber(1));
80
81 private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
82 DeviceId.deviceId("of:0000000000000002"),
83 PortNumber.portNumber(1));
84
85 private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
86 DeviceId.deviceId("of:0000000000000003"),
87 PortNumber.portNumber(1));
88
Jonathan Hart41349e92015-02-09 14:14:02 -080089 private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
90 DeviceId.deviceId("of:0000000000000004"),
91 PortNumber.portNumber(1));
92
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080093 private IntentSynchronizer intentSynchronizer;
Pingpingf5d90932014-10-27 10:50:04 -070094
95 private static final ApplicationId APPID = new ApplicationId() {
96 @Override
97 public short id() {
98 return 1;
99 }
100
101 @Override
102 public String name() {
103 return "SDNIP";
104 }
105 };
106
107 @Before
108 public void setUp() throws Exception {
Brian O'Connor520c0522014-11-23 23:50:47 -0800109 super.setUp();
Pingpingf5d90932014-10-27 10:50:04 -0700110 setUpInterfaceService();
Jonathan Hart41349e92015-02-09 14:14:02 -0800111
112 setUpBgpPeers();
Pingpingf5d90932014-10-27 10:50:04 -0700113 intentService = createMock(IntentService.class);
114
Jonathan Hart552e31f2015-02-06 11:11:59 -0800115 intentSynchronizer = new IntentSynchronizer(APPID, intentService,
Jonathan Hart41349e92015-02-09 14:14:02 -0800116 sdnIpConfigService, interfaceService);
117 }
118
119 /**
120 * Sets up BGP peers in external networks.
121 */
122 private void setUpBgpPeers() {
123
124 Map<IpAddress, BgpPeer> peers = new HashMap<>();
125
126 String peerSw1Eth1 = "192.168.10.1";
127 peers.put(IpAddress.valueOf(peerSw1Eth1),
128 new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
129
130 // Two BGP peers are connected to switch 2 port 1.
131 String peer1Sw2Eth1 = "192.168.20.1";
132 peers.put(IpAddress.valueOf(peer1Sw2Eth1),
133 new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
134
135 String peer2Sw2Eth1 = "192.168.20.2";
136 peers.put(IpAddress.valueOf(peer2Sw2Eth1),
137 new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
138
139 String peer1Sw4Eth1 = "192.168.40.1";
140 peers.put(IpAddress.valueOf(peer1Sw4Eth1),
141 new BgpPeer("00:00:00:00:00:00:00:04", 1, peer1Sw4Eth1));
142
143 sdnIpConfigService = createMock(SdnIpConfigurationService.class);
144 expect(sdnIpConfigService.getBgpPeers()).andReturn(peers).anyTimes();
Brian O'Connor03406a42015-02-03 17:28:57 -0800145 replay(sdnIpConfigService);
Jonathan Hart41349e92015-02-09 14:14:02 -0800146
Pingpingf5d90932014-10-27 10:50:04 -0700147 }
148
149 /**
150 * Sets up InterfaceService.
151 */
152 private void setUpInterfaceService() {
153
154 interfaceService = createMock(InterfaceService.class);
155
156 Set<Interface> interfaces = Sets.newHashSet();
157
158 Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
159 interfaceIpAddresses1.add(new InterfaceIpAddress(
160 IpAddress.valueOf("192.168.10.101"),
161 IpPrefix.valueOf("192.168.10.0/24")));
162 Interface sw1Eth1 = new Interface(SW1_ETH1,
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800163 interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
164 VlanId.NONE);
Pingpingf5d90932014-10-27 10:50:04 -0700165 interfaces.add(sw1Eth1);
166
167 Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
Jonathan Hart41349e92015-02-09 14:14:02 -0800168 interfaceIpAddresses2.add(
169 new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
170 IpPrefix.valueOf("192.168.20.0/24")));
Pingpingf5d90932014-10-27 10:50:04 -0700171 Interface sw2Eth1 = new Interface(SW2_ETH1,
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800172 interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
173 VlanId.NONE);
Pingpingf5d90932014-10-27 10:50:04 -0700174 interfaces.add(sw2Eth1);
175
176 Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
Jonathan Hart41349e92015-02-09 14:14:02 -0800177 interfaceIpAddresses3.add(
178 new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
179 IpPrefix.valueOf("192.168.30.0/24")));
Pingpingf5d90932014-10-27 10:50:04 -0700180 Interface sw3Eth1 = new Interface(SW3_ETH1,
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800181 interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
182 VlanId.NONE);
Pingpingf5d90932014-10-27 10:50:04 -0700183 interfaces.add(sw3Eth1);
184
Jonathan Hart41349e92015-02-09 14:14:02 -0800185 InterfaceIpAddress interfaceIpAddress4 =
186 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"),
187 IpPrefix.valueOf("192.168.40.0/24"));
188 Interface sw4Eth1 = new Interface(SW4_ETH1,
189 Sets.newHashSet(interfaceIpAddress4),
190 MacAddress.valueOf("00:00:00:00:00:04"),
191 VlanId.vlanId((short) 1));
192
193 expect(interfaceService.getInterface(SW4_ETH1)).andReturn(sw4Eth1).anyTimes();
194 interfaces.add(sw4Eth1);
195
Pingpingf5d90932014-10-27 10:50:04 -0700196 expect(interfaceService.getInterface(SW1_ETH1)).andReturn(
197 sw1Eth1).anyTimes();
198 expect(interfaceService.getInterface(SW2_ETH1)).andReturn(
199 sw2Eth1).anyTimes();
200 expect(interfaceService.getInterface(SW3_ETH1)).andReturn(
201 sw3Eth1).anyTimes();
Jonathan Hart41349e92015-02-09 14:14:02 -0800202 expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700203 replay(interfaceService);
204 }
205
206 /**
Jonathan Hart41349e92015-02-09 14:14:02 -0800207 * Tests adding a FIB entry to the IntentSynchronizer.
208 *
209 * We verify that the synchronizer records the correct state and that the
210 * correct intent is submitted to the IntentService.
211 *
212 * @throws TestUtilsException
Pingpingf5d90932014-10-27 10:50:04 -0700213 */
Jonathan Hart41349e92015-02-09 14:14:02 -0800214 @Test
215 public void testFibAdd() throws TestUtilsException {
216 FibEntry fibEntry = new FibEntry(
217 Ip4Prefix.valueOf("1.1.1.0/24"),
218 Ip4Address.valueOf("192.168.10.1"),
219 MacAddress.valueOf("00:00:00:00:00:01"));
Pingpingf5d90932014-10-27 10:50:04 -0700220
Jonathan Hart41349e92015-02-09 14:14:02 -0800221 // Construct a MultiPointToSinglePointIntent intent
222 TrafficSelector.Builder selectorBuilder =
223 DefaultTrafficSelector.builder();
224 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
225 fibEntry.prefix());
Pingpingf5d90932014-10-27 10:50:04 -0700226
Jonathan Hart41349e92015-02-09 14:14:02 -0800227 TrafficTreatment.Builder treatmentBuilder =
228 DefaultTrafficTreatment.builder();
229 treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
Pingpingf5d90932014-10-27 10:50:04 -0700230
Jonathan Hart41349e92015-02-09 14:14:02 -0800231 Set<ConnectPoint> ingressPoints = new HashSet<>();
232 ingressPoints.add(SW2_ETH1);
233 ingressPoints.add(SW3_ETH1);
234 ingressPoints.add(SW4_ETH1);
235
236 MultiPointToSinglePointIntent intent =
237 new MultiPointToSinglePointIntent(APPID,
238 selectorBuilder.build(), treatmentBuilder.build(),
239 ingressPoints, SW1_ETH1);
240
241 // Setup the expected intents
Jonathan Hartcb726fc2015-02-13 16:26:22 -0800242 intentService.submit(eqExceptId(intent));
Jonathan Hart41349e92015-02-09 14:14:02 -0800243 replay(intentService);
244
245 intentSynchronizer.leaderChanged(true);
246 TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
247
248 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
249 fibEntry);
250 intentSynchronizer.update(Collections.singleton(fibUpdate),
251 Collections.emptyList());
252
Brian O'Connor03406a42015-02-03 17:28:57 -0800253 assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
Jonathan Hart41349e92015-02-09 14:14:02 -0800254 Intent firstIntent =
255 intentSynchronizer.getRouteIntents().iterator().next();
256 IntentKey firstIntentKey = new IntentKey(firstIntent);
257 IntentKey intentKey = new IntentKey(intent);
258 assertTrue(firstIntentKey.equals(intentKey));
259 verify(intentService);
260 }
261
262 /**
263 * Tests adding a FIB entry with to a next hop in a VLAN.
264 *
265 * We verify that the synchronizer records the correct state and that the
266 * correct intent is submitted to the IntentService.
267 *
268 * @throws TestUtilsException
269 */
270 @Test
271 public void testFibAddWithVlan() throws TestUtilsException {
272 FibEntry fibEntry = new FibEntry(
273 Ip4Prefix.valueOf("3.3.3.0/24"),
274 Ip4Address.valueOf("192.168.40.1"),
275 MacAddress.valueOf("00:00:00:00:00:04"));
276
277 // Construct a MultiPointToSinglePointIntent intent
278 TrafficSelector.Builder selectorBuilder =
279 DefaultTrafficSelector.builder();
280 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)
281 .matchIPDst(fibEntry.prefix())
282 .matchVlanId(VlanId.ANY);
283
284 TrafficTreatment.Builder treatmentBuilder =
285 DefaultTrafficTreatment.builder();
286 treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:04"))
287 .setVlanId(VlanId.vlanId((short) 1));
288
289 Set<ConnectPoint> ingressPoints = new HashSet<>();
290 ingressPoints.add(SW1_ETH1);
291 ingressPoints.add(SW2_ETH1);
292 ingressPoints.add(SW3_ETH1);
293
294 MultiPointToSinglePointIntent intent =
295 new MultiPointToSinglePointIntent(APPID,
296 selectorBuilder.build(), treatmentBuilder.build(),
297 ingressPoints, SW4_ETH1);
298
299 // Setup the expected intents
Jonathan Hartcb726fc2015-02-13 16:26:22 -0800300 intentService.submit(eqExceptId(intent));
301
Jonathan Hart41349e92015-02-09 14:14:02 -0800302 replay(intentService);
303
304 // Run the test
305 intentSynchronizer.leaderChanged(true);
306 TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
307 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
308
309 intentSynchronizer.update(Collections.singleton(fibUpdate),
310 Collections.emptyList());
311
312 // Verify
Brian O'Connor03406a42015-02-03 17:28:57 -0800313 assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
Jonathan Hart41349e92015-02-09 14:14:02 -0800314 Intent firstIntent =
315 intentSynchronizer.getRouteIntents().iterator().next();
316 IntentKey firstIntentKey = new IntentKey(firstIntent);
317 IntentKey intentKey = new IntentKey(intent);
318 assertTrue(firstIntentKey.equals(intentKey));
319 verify(intentService);
320 }
321
322 /**
323 * Tests updating a FIB entry.
324 *
325 * We verify that the synchronizer records the correct state and that the
326 * correct intent is submitted to the IntentService.
327 *
328 * @throws TestUtilsException
329 */
330 @Test
331 public void testFibUpdate() throws TestUtilsException {
332 // Firstly add a route
333 testFibAdd();
334
335 Intent addedIntent =
336 intentSynchronizer.getRouteIntents().iterator().next();
337
338 // Start to construct a new route entry and new intent
339 FibEntry fibEntryUpdate = new FibEntry(
340 Ip4Prefix.valueOf("1.1.1.0/24"),
341 Ip4Address.valueOf("192.168.20.1"),
342 MacAddress.valueOf("00:00:00:00:00:02"));
343
344 // Construct a new MultiPointToSinglePointIntent intent
345 TrafficSelector.Builder selectorBuilderNew =
346 DefaultTrafficSelector.builder();
347 selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
348 fibEntryUpdate.prefix());
349
350 TrafficTreatment.Builder treatmentBuilderNew =
351 DefaultTrafficTreatment.builder();
352 treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
Pingpingf5d90932014-10-27 10:50:04 -0700353
354
Jonathan Hart41349e92015-02-09 14:14:02 -0800355 Set<ConnectPoint> ingressPointsNew = new HashSet<>();
356 ingressPointsNew.add(SW1_ETH1);
357 ingressPointsNew.add(SW3_ETH1);
358 ingressPointsNew.add(SW4_ETH1);
Pingpingf5d90932014-10-27 10:50:04 -0700359
Jonathan Hart41349e92015-02-09 14:14:02 -0800360 MultiPointToSinglePointIntent intentNew =
361 new MultiPointToSinglePointIntent(APPID,
362 selectorBuilderNew.build(),
363 treatmentBuilderNew.build(),
364 ingressPointsNew, SW2_ETH1);
Pingpingf5d90932014-10-27 10:50:04 -0700365
Jonathan Hart41349e92015-02-09 14:14:02 -0800366 // Set up test expectation
367 reset(intentService);
368 // Setup the expected intents
Jonathan Hartcb726fc2015-02-13 16:26:22 -0800369 intentService.withdraw(eqExceptId(addedIntent));
370 intentService.submit(eqExceptId(intentNew));
Jonathan Hart41349e92015-02-09 14:14:02 -0800371 replay(intentService);
Pingpingf5d90932014-10-27 10:50:04 -0700372
Jonathan Hart41349e92015-02-09 14:14:02 -0800373 // Call the update() method in IntentSynchronizer class
374 intentSynchronizer.leaderChanged(true);
375 TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
376 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
377 fibEntryUpdate);
378 intentSynchronizer.update(Collections.singletonList(fibUpdate),
379 Collections.emptyList());
Pingpingf5d90932014-10-27 10:50:04 -0700380
Jonathan Hart41349e92015-02-09 14:14:02 -0800381 // Verify
Brian O'Connor03406a42015-02-03 17:28:57 -0800382 assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
Jonathan Hart41349e92015-02-09 14:14:02 -0800383 Intent firstIntent =
384 intentSynchronizer.getRouteIntents().iterator().next();
385 IntentKey firstIntentKey = new IntentKey(firstIntent);
386 IntentKey intentNewKey = new IntentKey(intentNew);
387 assertTrue(firstIntentKey.equals(intentNewKey));
388 verify(intentService);
389 }
Pingpingf5d90932014-10-27 10:50:04 -0700390
Jonathan Hart41349e92015-02-09 14:14:02 -0800391 /**
392 * Tests deleting a FIB entry.
393 *
394 * We verify that the synchronizer records the correct state and that the
395 * correct intent is withdrawn from the IntentService.
396 *
397 * @throws TestUtilsException
398 */
399 @Test
400 public void testFibDelete() throws TestUtilsException {
401 // Firstly add a route
402 testFibAdd();
Pingpingf5d90932014-10-27 10:50:04 -0700403
Jonathan Hart41349e92015-02-09 14:14:02 -0800404 Intent addedIntent =
405 intentSynchronizer.getRouteIntents().iterator().next();
406
407 // Construct the existing route entry
408 FibEntry fibEntry = new FibEntry(
409 Ip4Prefix.valueOf("1.1.1.0/24"), null, null);
410
411 // Set up expectation
412 reset(intentService);
413 // Setup the expected intents
Jonathan Hartcb726fc2015-02-13 16:26:22 -0800414 intentService.withdraw(eqExceptId(addedIntent));
Jonathan Hart41349e92015-02-09 14:14:02 -0800415 replay(intentService);
416
417 // Call the update() method in IntentSynchronizer class
418 intentSynchronizer.leaderChanged(true);
419 TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
420 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);
421 intentSynchronizer.update(Collections.emptyList(),
422 Collections.singletonList(fibUpdate));
423
424 // Verify
Brian O'Connor03406a42015-02-03 17:28:57 -0800425 assertEquals(intentSynchronizer.getRouteIntents().size(), 0);
Jonathan Hart41349e92015-02-09 14:14:02 -0800426 verify(intentService);
Pingpingf5d90932014-10-27 10:50:04 -0700427 }
428
429 /**
430 * This method tests the behavior of intent Synchronizer.
431 *
432 * @throws TestUtilsException
433 */
434 @Test
435 public void testIntentSync() throws TestUtilsException {
436
437 //
438 // Construct routes and intents.
439 // This test simulates the following cases during the master change
440 // time interval:
441 // 1. RouteEntry1 did not change and the intent also did not change.
442 // 2. RouteEntry2 was deleted, but the intent was not deleted.
443 // 3. RouteEntry3 was newly added, and the intent was also submitted.
444 // 4. RouteEntry4 was updated to RouteEntry4Update, and the intent was
445 // also updated to a new one.
446 // 5. RouteEntry5 did not change, but its intent id changed.
447 // 6. RouteEntry6 was newly added, but the intent was not submitted.
448 //
449 RouteEntry routeEntry1 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800450 Ip4Prefix.valueOf("1.1.1.0/24"),
451 Ip4Address.valueOf("192.168.10.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700452
453 RouteEntry routeEntry2 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800454 Ip4Prefix.valueOf("2.2.2.0/24"),
455 Ip4Address.valueOf("192.168.20.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700456
457 RouteEntry routeEntry3 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800458 Ip4Prefix.valueOf("3.3.3.0/24"),
459 Ip4Address.valueOf("192.168.30.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700460
461 RouteEntry routeEntry4 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800462 Ip4Prefix.valueOf("4.4.4.0/24"),
463 Ip4Address.valueOf("192.168.30.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700464
465 RouteEntry routeEntry4Update = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800466 Ip4Prefix.valueOf("4.4.4.0/24"),
467 Ip4Address.valueOf("192.168.20.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700468
469 RouteEntry routeEntry5 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800470 Ip4Prefix.valueOf("5.5.5.0/24"),
471 Ip4Address.valueOf("192.168.10.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700472
473 RouteEntry routeEntry6 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800474 Ip4Prefix.valueOf("6.6.6.0/24"),
475 Ip4Address.valueOf("192.168.10.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700476
Jonathan Hartec2df012014-10-23 16:40:24 -0700477 RouteEntry routeEntry7 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800478 Ip4Prefix.valueOf("7.7.7.0/24"),
479 Ip4Address.valueOf("192.168.10.1"));
Jonathan Hartec2df012014-10-23 16:40:24 -0700480
Pingpingf5d90932014-10-27 10:50:04 -0700481 MultiPointToSinglePointIntent intent1 = intentBuilder(
482 routeEntry1.prefix(), "00:00:00:00:00:01", SW1_ETH1);
483 MultiPointToSinglePointIntent intent2 = intentBuilder(
484 routeEntry2.prefix(), "00:00:00:00:00:02", SW2_ETH1);
485 MultiPointToSinglePointIntent intent3 = intentBuilder(
486 routeEntry3.prefix(), "00:00:00:00:00:03", SW3_ETH1);
487 MultiPointToSinglePointIntent intent4 = intentBuilder(
488 routeEntry4.prefix(), "00:00:00:00:00:03", SW3_ETH1);
489 MultiPointToSinglePointIntent intent4Update = intentBuilder(
490 routeEntry4Update.prefix(), "00:00:00:00:00:02", SW2_ETH1);
491 MultiPointToSinglePointIntent intent5 = intentBuilder(
492 routeEntry5.prefix(), "00:00:00:00:00:01", SW1_ETH1);
Jonathan Hartec2df012014-10-23 16:40:24 -0700493 MultiPointToSinglePointIntent intent7 = intentBuilder(
494 routeEntry7.prefix(), "00:00:00:00:00:01", SW1_ETH1);
Pingpingf5d90932014-10-27 10:50:04 -0700495
496 // Compose a intent, which is equal to intent5 but the id is different.
497 MultiPointToSinglePointIntent intent5New =
498 staticIntentBuilder(intent5, routeEntry5, "00:00:00:00:00:01");
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800499 assertThat(IntentSynchronizer.IntentKey.equalIntents(
500 intent5, intent5New),
501 is(true));
Jonathan Hartec2df012014-10-23 16:40:24 -0700502 assertFalse(intent5.equals(intent5New));
Pingpingf5d90932014-10-27 10:50:04 -0700503
504 MultiPointToSinglePointIntent intent6 = intentBuilder(
505 routeEntry6.prefix(), "00:00:00:00:00:01", SW1_ETH1);
506
Jonathan Hart41349e92015-02-09 14:14:02 -0800507 // Set up the routeIntents field in IntentSynchronizer class
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800508 ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent>
509 routeIntents = new ConcurrentHashMap<>();
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800510 routeIntents.put(routeEntry1.prefix(), intent1);
511 routeIntents.put(routeEntry3.prefix(), intent3);
512 routeIntents.put(routeEntry4Update.prefix(), intent4Update);
513 routeIntents.put(routeEntry5.prefix(), intent5New);
514 routeIntents.put(routeEntry6.prefix(), intent6);
515 routeIntents.put(routeEntry7.prefix(), intent7);
516 TestUtils.setField(intentSynchronizer, "routeIntents", routeIntents);
Pingpingf5d90932014-10-27 10:50:04 -0700517
518 // Set up expectation
519 reset(intentService);
520 Set<Intent> intents = new HashSet<Intent>();
521 intents.add(intent1);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800522 expect(intentService.getIntentState(intent1.key()))
Jonathan Hartec2df012014-10-23 16:40:24 -0700523 .andReturn(IntentState.INSTALLED).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700524 intents.add(intent2);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800525 expect(intentService.getIntentState(intent2.key()))
Jonathan Hartec2df012014-10-23 16:40:24 -0700526 .andReturn(IntentState.INSTALLED).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700527 intents.add(intent4);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800528 expect(intentService.getIntentState(intent4.key()))
Jonathan Hartec2df012014-10-23 16:40:24 -0700529 .andReturn(IntentState.INSTALLED).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700530 intents.add(intent5);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800531 expect(intentService.getIntentState(intent5.key()))
Jonathan Hartec2df012014-10-23 16:40:24 -0700532 .andReturn(IntentState.INSTALLED).anyTimes();
533 intents.add(intent7);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800534 expect(intentService.getIntentState(intent7.key()))
Jonathan Hartec2df012014-10-23 16:40:24 -0700535 .andReturn(IntentState.WITHDRAWING).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700536 expect(intentService.getIntents()).andReturn(intents).anyTimes();
537
Brian O'Connor03406a42015-02-03 17:28:57 -0800538 intentService.withdraw(intent2);
539 intentService.withdraw(intent4);
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800540
Brian O'Connor03406a42015-02-03 17:28:57 -0800541 intentService.submit(intent3);
542 intentService.submit(intent4Update);
543 intentService.submit(intent6);
544 intentService.submit(intent7);
Pingpingf5d90932014-10-27 10:50:04 -0700545 replay(intentService);
546
547 // Start the test
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -0800548 intentSynchronizer.leaderChanged(true);
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800549 intentSynchronizer.synchronizeIntents();
Pingpingf5d90932014-10-27 10:50:04 -0700550
551 // Verify
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800552 assertEquals(intentSynchronizer.getRouteIntents().size(), 6);
553 assertTrue(intentSynchronizer.getRouteIntents().contains(intent1));
554 assertTrue(intentSynchronizer.getRouteIntents().contains(intent3));
555 assertTrue(intentSynchronizer.getRouteIntents().contains(intent4Update));
556 assertTrue(intentSynchronizer.getRouteIntents().contains(intent5));
557 assertTrue(intentSynchronizer.getRouteIntents().contains(intent6));
Pingpingf5d90932014-10-27 10:50:04 -0700558
559 verify(intentService);
560 }
561
562 /**
563 * MultiPointToSinglePointIntent builder.
564 *
565 * @param ipPrefix the ipPrefix to match
566 * @param nextHopMacAddress to which the destination MAC address in packet
567 * should be rewritten
568 * @param egressPoint to which packets should be sent
569 * @return the constructed MultiPointToSinglePointIntent
570 */
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800571 private MultiPointToSinglePointIntent intentBuilder(IpPrefix ipPrefix,
Pingpingf5d90932014-10-27 10:50:04 -0700572 String nextHopMacAddress, ConnectPoint egressPoint) {
573
574 TrafficSelector.Builder selectorBuilder =
575 DefaultTrafficSelector.builder();
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800576 if (ipPrefix.version() == Ip4Address.VERSION) {
577 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4); // IPv4
578 } else {
579 selectorBuilder.matchEthType(Ethernet.TYPE_IPV6); // IPv6
580 }
581 selectorBuilder.matchIPDst(ipPrefix);
Pingpingf5d90932014-10-27 10:50:04 -0700582
583 TrafficTreatment.Builder treatmentBuilder =
584 DefaultTrafficTreatment.builder();
585 treatmentBuilder.setEthDst(MacAddress.valueOf(nextHopMacAddress));
586
587 Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
588 for (Interface intf : interfaceService.getInterfaces()) {
589 if (!intf.equals(interfaceService.getInterface(egressPoint))) {
590 ConnectPoint srcPort = intf.connectPoint();
591 ingressPoints.add(srcPort);
592 }
593 }
594 MultiPointToSinglePointIntent intent =
595 new MultiPointToSinglePointIntent(APPID,
596 selectorBuilder.build(), treatmentBuilder.build(),
597 ingressPoints, egressPoint);
598 return intent;
599 }
600
601 /**
602 * A static MultiPointToSinglePointIntent builder, the returned intent is
603 * equal to the input intent except that the id is different.
604 *
605 *
606 * @param intent the intent to be used for building a new intent
607 * @param routeEntry the relative routeEntry of the intent
608 * @return the newly constructed MultiPointToSinglePointIntent
609 * @throws TestUtilsException
610 */
611 private MultiPointToSinglePointIntent staticIntentBuilder(
612 MultiPointToSinglePointIntent intent, RouteEntry routeEntry,
613 String nextHopMacAddress) throws TestUtilsException {
614
615 // Use a different egress ConnectPoint with that in intent
616 // to generate a different id
617 MultiPointToSinglePointIntent intentNew = intentBuilder(
618 routeEntry.prefix(), nextHopMacAddress, SW2_ETH1);
619 TestUtils.setField(intentNew, "egressPoint", intent.egressPoint());
620 TestUtils.setField(intentNew,
621 "ingressPoints", intent.ingressPoints());
622 return intentNew;
623 }
Pingpingf5d90932014-10-27 10:50:04 -0700624}