blob: 10c20bde27c8152d7fafc6614ae6a44392fe145d [file] [log] [blame]
Charles Chand66d6712018-03-29 16:03:41 -07001/*
2 * Copyright 2018-present Open Networking Foundation
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 */
16package org.onosproject.segmentrouting;
17
Charles Chand66d6712018-03-29 16:03:41 -070018import org.junit.Before;
19import org.junit.Test;
20import org.onlab.packet.IpAddress;
21import org.onosproject.cluster.ClusterService;
22import org.onosproject.cluster.DefaultControllerNode;
pierventre37dcf4c2021-09-16 18:43:06 +020023import org.onosproject.cluster.Leader;
24import org.onosproject.cluster.Leadership;
25import org.onosproject.cluster.LeadershipService;
Charles Chand66d6712018-03-29 16:03:41 -070026import org.onosproject.cluster.NodeId;
Charles Chand66d6712018-03-29 16:03:41 -070027import org.onosproject.net.DeviceId;
28import org.onosproject.net.device.DeviceService;
Charles Chand66d6712018-03-29 16:03:41 -070029import org.onosproject.store.service.StorageService;
30import org.onosproject.store.service.TestConsistentMap;
pierf331a492020-01-07 15:39:39 +010031import org.onosproject.store.service.TestConsistentMultimap;
Charles Chand66d6712018-03-29 16:03:41 -070032
pierventre37dcf4c2021-09-16 18:43:06 +020033import java.util.List;
Charles Chand66d6712018-03-29 16:03:41 -070034import java.util.Optional;
35
36import static org.easymock.EasyMock.createMock;
37import static org.easymock.EasyMock.expect;
38import static org.easymock.EasyMock.replay;
39import static org.easymock.EasyMock.reset;
40import static org.junit.Assert.*;
pierventre37dcf4c2021-09-16 18:43:06 +020041import static org.onosproject.segmentrouting.DefaultRoutingHandler.HASH_FUNCTION;
Charles Chand66d6712018-03-29 16:03:41 -070042
43public class DefaultRoutingHandlerTest {
44 private SegmentRoutingManager srManager;
45 private DefaultRoutingHandler dfh;
pierventre37dcf4c2021-09-16 18:43:06 +020046 private MockWorkPartitionService mockWps;
Charles Chand66d6712018-03-29 16:03:41 -070047
48 private static final DeviceId DEV1A = DeviceId.deviceId("of:1a");
49 private static final DeviceId DEV1B = DeviceId.deviceId("of:1b");
50 private static final DeviceId DEV2 = DeviceId.deviceId("of:2");
51
pierventre37dcf4c2021-09-16 18:43:06 +020052 private static final EdgePair EDGE_PAIR_1 = new EdgePair(DEV1A, DEV1B);
53 private static final EdgePair EDGE_PAIR_2 = new EdgePair(DEV1B, DEV1A);
54 private static final EdgePair EDGE_PAIR_3 = new EdgePair(DEV2, DeviceId.NONE);
55
Charles Chand66d6712018-03-29 16:03:41 -070056 private static final NodeId NODE1 = NodeId.nodeId("192.168.1.1");
57 private static final NodeId NODE2 = NodeId.nodeId("192.168.1.2");
58 private static final NodeId NODE3 = NodeId.nodeId("192.168.1.3");
59 private static final IpAddress IP1 = IpAddress.valueOf("192.168.1.1");
60 private static final IpAddress IP2 = IpAddress.valueOf("192.168.1.2");
61 private static final IpAddress IP3 = IpAddress.valueOf("192.168.1.3");
62
pierventre37dcf4c2021-09-16 18:43:06 +020063 /* This is generated by manually applying the hash function.
64 It depends on the number of partitions defined in the MockWorkPartitionService */
65 private static final String DEV1A_PARTITION_ID = String.valueOf(Math.abs(HASH_FUNCTION.apply(
66 EDGE_PAIR_1).intValue()) % MockWorkPartitionService.NUM_PARTITIONS);
67 private static final String DEV1B_PARTITION_ID = String.valueOf(Math.abs(HASH_FUNCTION.apply(
68 EDGE_PAIR_2).intValue()) % MockWorkPartitionService.NUM_PARTITIONS);
69 private static final String DEV2_PARTITION_ID = String.valueOf(Math.abs(HASH_FUNCTION.apply(
70 EDGE_PAIR_3).intValue()) % MockWorkPartitionService.NUM_PARTITIONS);
71
Charles Chand66d6712018-03-29 16:03:41 -070072 @Before
73 public void setUp() {
74 srManager = createMock(SegmentRoutingManager.class);
75 srManager.storageService = createMock(StorageService.class);
pierventre37dcf4c2021-09-16 18:43:06 +020076 expect(srManager.storageService.consistentMapBuilder()).andReturn(
77 new TestConsistentMap.Builder<>()).anyTimes();
pierf331a492020-01-07 15:39:39 +010078 expect(srManager.storageService.consistentMultimapBuilder()).andReturn(
79 new TestConsistentMultimap.Builder<>()).anyTimes();
Charles Chand66d6712018-03-29 16:03:41 -070080 replay(srManager.storageService);
81 srManager.routingRulePopulator = createMock(RoutingRulePopulator.class);
82 srManager.deviceService = createMock(DeviceService.class);
83 srManager.deviceConfiguration = createMock(DeviceConfiguration.class);
pierventre37dcf4c2021-09-16 18:43:06 +020084 mockWps = new MockWorkPartitionService();
85 mockWps.leadershipService = createMock(LeadershipService.class);
86 srManager.workPartitionService = mockWps;
Charles Chand66d6712018-03-29 16:03:41 -070087 srManager.clusterService = createMock(ClusterService.class);
88 dfh = new DefaultRoutingHandler(srManager);
89 }
90
pierventre37dcf4c2021-09-16 18:43:06 +020091 private void clearShouldProgram() {
92 dfh.invalidateShouldProgram(DEV1A);
93 dfh.invalidateShouldProgram(DEV1B);
94 dfh.invalidateShouldProgram(DEV2);
Charles Chanfbcb8812018-04-18 18:41:05 -070095 }
96
pierventre37dcf4c2021-09-16 18:43:06 +020097 // Node 1 is the leader of switch 1A, 1B, and 2
Charles Chand66d6712018-03-29 16:03:41 -070098 @Test
99 public void testShouldHandleRoutingCase1() {
pierventre37dcf4c2021-09-16 18:43:06 +0200100 expect(mockWps.leadershipService.getLeadership(DEV1A_PARTITION_ID)).andReturn(new Leadership(
101 DEV1A_PARTITION_ID, new Leader(NODE1, 0, 0), List.of(NODE2, NODE3))).anyTimes();
102 expect(mockWps.leadershipService.getLeadership(DEV1B_PARTITION_ID)).andReturn(new Leadership(
103 DEV1B_PARTITION_ID, new Leader(NODE1, 0, 0), List.of(NODE2, NODE3))).anyTimes();
104 expect(mockWps.leadershipService.getLeadership(DEV2_PARTITION_ID)).andReturn(new Leadership(
105 DEV2_PARTITION_ID, new Leader(NODE1, 0, 0), List.of(NODE2, NODE3))).anyTimes();
106 replay(mockWps.leadershipService);
Charles Chand66d6712018-03-29 16:03:41 -0700107
108 expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
109 expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
110 expect(srManager.getPairDeviceId(DEV2)).andReturn(Optional.empty()).anyTimes();
111 replay(srManager);
112
113 // Node 1 should program every device
114 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
115 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200116
117 // shouldProgram is initially empty
118 assertNull(dfh.shouldProgram.get(DEV1A));
119 assertNull(dfh.shouldProgram.get(DEV1B));
120 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700121 assertTrue(dfh.shouldProgram(DEV1A));
122 assertTrue(dfh.shouldProgram(DEV1B));
123 assertTrue(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200124 assertEquals(NODE1, dfh.shouldProgram.get(DEV1A));
125 assertEquals(NODE1, dfh.shouldProgram.get(DEV1B));
126 assertEquals(NODE1, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700127
128 reset(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200129 clearShouldProgram();
Charles Chand66d6712018-03-29 16:03:41 -0700130
131 // Node 2 should program no device
132 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
133 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200134 assertNull(dfh.shouldProgram.get(DEV1A));
135 assertNull(dfh.shouldProgram.get(DEV1B));
136 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700137 assertFalse(dfh.shouldProgram(DEV1A));
138 assertFalse(dfh.shouldProgram(DEV1B));
139 assertFalse(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200140 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV1A));
141 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV1B));
142 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700143
144 reset(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200145 clearShouldProgram();
Charles Chand66d6712018-03-29 16:03:41 -0700146
147 // Node 3 should program no device
148 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE3, IP3)).anyTimes();
149 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200150 assertNull(dfh.shouldProgram.get(DEV1A));
151 assertNull(dfh.shouldProgram.get(DEV1B));
152 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700153 assertFalse(dfh.shouldProgram(DEV1A));
154 assertFalse(dfh.shouldProgram(DEV1B));
155 assertFalse(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200156 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV1A));
157 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV1B));
158 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700159 }
160
pierventre37dcf4c2021-09-16 18:43:06 +0200161 /*
162 * Node 1 is the leader of switch 1A, 1B
163 * Node 2 is the leader of switch 2
164 */
Charles Chand66d6712018-03-29 16:03:41 -0700165 @Test
166 public void testShouldHandleRoutingCase2() {
pierventre37dcf4c2021-09-16 18:43:06 +0200167 expect(mockWps.leadershipService.getLeadership(DEV1A_PARTITION_ID)).andReturn(new Leadership(
168 DEV1A_PARTITION_ID, new Leader(NODE1, 0, 0), List.of(NODE2, NODE3))).anyTimes();
169 expect(mockWps.leadershipService.getLeadership(DEV1B_PARTITION_ID)).andReturn(new Leadership(
170 DEV1B_PARTITION_ID, new Leader(NODE1, 0, 0), List.of(NODE2, NODE3))).anyTimes();
171 expect(mockWps.leadershipService.getLeadership(DEV2_PARTITION_ID)).andReturn(new Leadership(
172 DEV2_PARTITION_ID, new Leader(NODE2, 0, 0), List.of(NODE2, NODE3))).anyTimes();
173 replay(mockWps.leadershipService);
Charles Chand66d6712018-03-29 16:03:41 -0700174
175 expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
176 expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
177 expect(srManager.getPairDeviceId(DEV2)).andReturn(Optional.empty()).anyTimes();
178 replay(srManager);
179
180 // Node 1 should program 1A, 1B
181 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
182 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200183 assertNull(dfh.shouldProgram.get(DEV1A));
184 assertNull(dfh.shouldProgram.get(DEV1B));
185 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700186 assertTrue(dfh.shouldProgram(DEV1A));
187 assertTrue(dfh.shouldProgram(DEV1B));
188 assertFalse(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200189 assertEquals(NODE1, dfh.shouldProgram.get(DEV1A));
190 assertEquals(NODE1, dfh.shouldProgram.get(DEV1B));
191 assertNotEquals(NODE1, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700192
193 reset(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200194 clearShouldProgram();
Charles Chand66d6712018-03-29 16:03:41 -0700195
196 // Node 2 should program 2
197 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
198 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200199 assertNull(dfh.shouldProgram.get(DEV1A));
200 assertNull(dfh.shouldProgram.get(DEV1B));
201 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700202 assertFalse(dfh.shouldProgram(DEV1A));
203 assertFalse(dfh.shouldProgram(DEV1B));
204 assertTrue(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200205 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV1A));
206 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV1B));
207 assertEquals(NODE2, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700208
209 reset(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200210 clearShouldProgram();
Charles Chand66d6712018-03-29 16:03:41 -0700211
212 // Node 3 should program no device
213 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE3, IP3)).anyTimes();
214 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200215 assertNull(dfh.shouldProgram.get(DEV1A));
216 assertNull(dfh.shouldProgram.get(DEV1B));
217 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700218 assertFalse(dfh.shouldProgram(DEV1A));
219 assertFalse(dfh.shouldProgram(DEV1B));
220 assertFalse(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200221 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV1A));
222 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV1B));
223 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700224 }
225
pierventre37dcf4c2021-09-16 18:43:06 +0200226 /*
227 * Node 1 is the leader of switch 1A, 1B
228 * Node 3 is the leader of switch 2
229 */
Charles Chand66d6712018-03-29 16:03:41 -0700230 @Test
231 public void testShouldHandleRoutingCase3() {
pierventre37dcf4c2021-09-16 18:43:06 +0200232 expect(mockWps.leadershipService.getLeadership(DEV1A_PARTITION_ID)).andReturn(new Leadership(
233 DEV1A_PARTITION_ID, new Leader(NODE1, 0, 0), List.of(NODE2, NODE3))).anyTimes();
234 expect(mockWps.leadershipService.getLeadership(DEV1B_PARTITION_ID)).andReturn(new Leadership(
235 DEV1B_PARTITION_ID, new Leader(NODE1, 0, 0), List.of(NODE2, NODE3))).anyTimes();
236 expect(mockWps.leadershipService.getLeadership(DEV2_PARTITION_ID)).andReturn(new Leadership(
237 DEV2_PARTITION_ID, new Leader(NODE3, 0, 0), List.of(NODE2, NODE3))).anyTimes();
238 replay(mockWps.leadershipService);
Charles Chand66d6712018-03-29 16:03:41 -0700239
240 expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
241 expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
242 expect(srManager.getPairDeviceId(DEV2)).andReturn(Optional.empty()).anyTimes();
243 replay(srManager);
244
245 // Node 1 should program 1A, 1B
246 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
247 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200248 assertNull(dfh.shouldProgram.get(DEV1A));
249 assertNull(dfh.shouldProgram.get(DEV1B));
250 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700251 assertTrue(dfh.shouldProgram(DEV1A));
252 assertTrue(dfh.shouldProgram(DEV1B));
253 assertFalse(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200254 assertEquals(NODE1, dfh.shouldProgram.get(DEV1A));
255 assertEquals(NODE1, dfh.shouldProgram.get(DEV1B));
256 assertNotEquals(NODE1, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700257
258 reset(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200259 clearShouldProgram();
Charles Chand66d6712018-03-29 16:03:41 -0700260
261 // Node 2 should program no device
262 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
263 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200264 assertNull(dfh.shouldProgram.get(DEV1A));
265 assertNull(dfh.shouldProgram.get(DEV1B));
266 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700267 assertFalse(dfh.shouldProgram(DEV1A));
268 assertFalse(dfh.shouldProgram(DEV1B));
269 assertFalse(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200270 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV1A));
271 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV1B));
272 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700273
274 reset(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200275 clearShouldProgram();
Charles Chand66d6712018-03-29 16:03:41 -0700276
277 // Node 3 should program 2
278 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE3, IP3)).anyTimes();
279 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200280 assertNull(dfh.shouldProgram.get(DEV1A));
281 assertNull(dfh.shouldProgram.get(DEV1B));
282 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700283 assertFalse(dfh.shouldProgram(DEV1A));
284 assertFalse(dfh.shouldProgram(DEV1B));
285 assertTrue(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200286 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV1A));
287 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV1B));
288 assertEquals(NODE3, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700289 }
290
pierventre37dcf4c2021-09-16 18:43:06 +0200291 /*
292 * Node 2 is the leader of switch 1A, 1B and Node 3 is the leader of 2.
293 * Later on, node 1 becomes the leader of 1A, 1B
294 */
Charles Chand66d6712018-03-29 16:03:41 -0700295 @Test
296 public void testShouldHandleRoutingCase4() {
pierventre37dcf4c2021-09-16 18:43:06 +0200297 expect(mockWps.leadershipService.getLeadership(DEV1A_PARTITION_ID)).andReturn(new Leadership(
298 DEV1A_PARTITION_ID, new Leader(NODE2, 0, 0), List.of(NODE2, NODE3))).anyTimes();
299 expect(mockWps.leadershipService.getLeadership(DEV1B_PARTITION_ID)).andReturn(new Leadership(
300 DEV1B_PARTITION_ID, new Leader(NODE2, 0, 0), List.of(NODE2, NODE3))).anyTimes();
301 expect(mockWps.leadershipService.getLeadership(DEV2_PARTITION_ID)).andReturn(new Leadership(
302 DEV2_PARTITION_ID, new Leader(NODE3, 0, 0), List.of(NODE2, NODE3))).anyTimes();
303 replay(mockWps.leadershipService);
Charles Chand66d6712018-03-29 16:03:41 -0700304
305 expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
306 expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
307 expect(srManager.getPairDeviceId(DEV2)).andReturn(Optional.empty()).anyTimes();
308 replay(srManager);
309
310 // Node 1 should program no device
311 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
312 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200313 assertNull(dfh.shouldProgram.get(DEV1A));
314 assertNull(dfh.shouldProgram.get(DEV1B));
315 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700316 assertFalse(dfh.shouldProgram(DEV1A));
317 assertFalse(dfh.shouldProgram(DEV1B));
318 assertFalse(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200319 assertNotEquals(NODE1, dfh.shouldProgram.get(DEV1A));
320 assertNotEquals(NODE1, dfh.shouldProgram.get(DEV1B));
321 assertNotEquals(NODE1, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700322
323 reset(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200324 clearShouldProgram();
Charles Chand66d6712018-03-29 16:03:41 -0700325
pierventre37dcf4c2021-09-16 18:43:06 +0200326 // Node 2 should program 1A and 1B
Charles Chand66d6712018-03-29 16:03:41 -0700327 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
328 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200329 assertNull(dfh.shouldProgram.get(DEV1A));
330 assertNull(dfh.shouldProgram.get(DEV1B));
331 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700332 assertTrue(dfh.shouldProgram(DEV1A));
333 assertTrue(dfh.shouldProgram(DEV1B));
334 assertFalse(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200335 assertEquals(NODE2, dfh.shouldProgram.get(DEV1A));
336 assertEquals(NODE2, dfh.shouldProgram.get(DEV1B));
337 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700338
339 reset(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200340 clearShouldProgram();
Charles Chand66d6712018-03-29 16:03:41 -0700341
342 // Node 3 should program 2
343 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE3, IP3)).anyTimes();
344 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200345 assertNull(dfh.shouldProgram.get(DEV1A));
346 assertNull(dfh.shouldProgram.get(DEV1B));
347 assertNull(dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700348 assertFalse(dfh.shouldProgram(DEV1A));
349 assertFalse(dfh.shouldProgram(DEV1B));
350 assertTrue(dfh.shouldProgram(DEV2));
pierventre37dcf4c2021-09-16 18:43:06 +0200351 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV1A));
352 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV1B));
353 assertEquals(NODE3, dfh.shouldProgram.get(DEV2));
354
355 // Partition of switch 1A moves to Node 1. This can happen for a cluster event
356 reset(mockWps.leadershipService);
357 expect(mockWps.leadershipService.getLeadership(DEV1A_PARTITION_ID)).andReturn(new Leadership(
358 DEV1A_PARTITION_ID, new Leader(NODE1, 0, 0), List.of(NODE2, NODE3))).anyTimes();
359 expect(mockWps.leadershipService.getLeadership(DEV1B_PARTITION_ID)).andReturn(new Leadership(
360 DEV1B_PARTITION_ID, new Leader(NODE1, 0, 0), List.of(NODE2, NODE3))).anyTimes();
361 expect(mockWps.leadershipService.getLeadership(DEV2_PARTITION_ID)).andReturn(new Leadership(
362 DEV2_PARTITION_ID, new Leader(NODE3, 0, 0), List.of(NODE2, NODE3))).anyTimes();
363 replay(mockWps.leadershipService);
364
365 reset(srManager.clusterService);
366 clearShouldProgram();
367
368 // Node 1 should program 1A, 1B
369 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
370 replay(srManager.clusterService);
371 assertNull(dfh.shouldProgram.get(DEV1A));
372 assertNull(dfh.shouldProgram.get(DEV1B));
373 assertNull(dfh.shouldProgram.get(DEV2));
374 assertTrue(dfh.shouldProgram(DEV1A));
375 assertTrue(dfh.shouldProgram(DEV1B));
376 assertFalse(dfh.shouldProgram(DEV2));
377 assertEquals(NODE1, dfh.shouldProgram.get(DEV1A));
378 assertEquals(NODE1, dfh.shouldProgram.get(DEV1B));
379 assertNotEquals(NODE1, dfh.shouldProgram.get(DEV2));
380
381 reset(srManager.clusterService);
382 clearShouldProgram();
383
384 // Node 2 should program no device
385 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
386 replay(srManager.clusterService);
387 assertNull(dfh.shouldProgram.get(DEV1A));
388 assertNull(dfh.shouldProgram.get(DEV1B));
389 assertNull(dfh.shouldProgram.get(DEV2));
390 assertFalse(dfh.shouldProgram(DEV1A));
391 assertFalse(dfh.shouldProgram(DEV1B));
392 assertFalse(dfh.shouldProgram(DEV2));
393 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV1A));
394 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV1B));
395 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV2));
396
397 reset(srManager.clusterService);
398 clearShouldProgram();
399
400 // Node 3 should program 2
401 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE3, IP3)).anyTimes();
402 replay(srManager.clusterService);
403 assertNull(dfh.shouldProgram.get(DEV1A));
404 assertNull(dfh.shouldProgram.get(DEV1B));
405 assertNull(dfh.shouldProgram.get(DEV2));
406 assertFalse(dfh.shouldProgram(DEV1A));
407 assertFalse(dfh.shouldProgram(DEV1B));
408 assertTrue(dfh.shouldProgram(DEV2));
409 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV1A));
410 assertNotEquals(NODE3, dfh.shouldProgram.get(DEV1B));
411 assertEquals(NODE3, dfh.shouldProgram.get(DEV2));
Charles Chand66d6712018-03-29 16:03:41 -0700412 }
413
pierventre37dcf4c2021-09-16 18:43:06 +0200414 /*
415 * Node 1 is the leader of 1A, 1B. Node 2 becomes the leader of 1A, 1B later
416 * shouldP is not purged in time. This can easily happen if we dont get in
417 * time cluster/mastership events. shouldProgram absorbs this negative scenario.
418 */
Charles Chand66d6712018-03-29 16:03:41 -0700419 @Test
420 public void testShouldHandleRoutingCase5() {
pierventre37dcf4c2021-09-16 18:43:06 +0200421 expect(mockWps.leadershipService.getLeadership(DEV1A_PARTITION_ID)).andReturn(new Leadership(
422 DEV1A_PARTITION_ID, new Leader(NODE1, 0, 0), List.of(NODE2, NODE3))).anyTimes();
423 expect(mockWps.leadershipService.getLeadership(DEV1B_PARTITION_ID)).andReturn(new Leadership(
424 DEV1B_PARTITION_ID, new Leader(NODE1, 0, 0), List.of(NODE2, NODE3))).anyTimes();
425 replay(mockWps.leadershipService);
Charles Chand66d6712018-03-29 16:03:41 -0700426
427 expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
428 expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
429 replay(srManager);
430
431 // Node 1 should program both 1A and 1B
432 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
433 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200434 assertNull(dfh.shouldProgram.get(DEV1A));
435 assertNull(dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700436 assertTrue(dfh.shouldProgram(DEV1A));
437 assertTrue(dfh.shouldProgram(DEV1B));
pierventre37dcf4c2021-09-16 18:43:06 +0200438 assertEquals(NODE1, dfh.shouldProgram.get(DEV1A));
439 assertEquals(NODE1, dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700440
441 reset(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200442 clearShouldProgram();
Charles Chand66d6712018-03-29 16:03:41 -0700443
444 // Node 2 should program no device
445 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
446 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200447 assertNull(dfh.shouldProgram.get(DEV1A));
448 assertNull(dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700449 assertFalse(dfh.shouldProgram(DEV1A));
450 assertFalse(dfh.shouldProgram(DEV1B));
pierventre37dcf4c2021-09-16 18:43:06 +0200451 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV1A));
452 assertNotEquals(NODE2, dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700453
pierventre37dcf4c2021-09-16 18:43:06 +0200454 // Leadership moves to Node 2
455 reset(mockWps.leadershipService);
456 expect(mockWps.leadershipService.getLeadership(DEV1A_PARTITION_ID)).andReturn(new Leadership(
457 DEV1A_PARTITION_ID, new Leader(NODE2, 0, 0), List.of(NODE2, NODE3))).anyTimes();
458 expect(mockWps.leadershipService.getLeadership(DEV1B_PARTITION_ID)).andReturn(new Leadership(
459 DEV1B_PARTITION_ID, new Leader(NODE2, 0, 0), List.of(NODE2, NODE3))).anyTimes();
460 replay(mockWps.leadershipService);
Charles Chand66d6712018-03-29 16:03:41 -0700461
462 reset(srManager.clusterService);
463
464 // Node 1 should program 1A, 1B
465 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
466 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200467 assertNotNull(dfh.shouldProgram.get(DEV1A));
468 assertNotNull(dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700469 assertTrue(dfh.shouldProgram(DEV1A));
470 assertTrue(dfh.shouldProgram(DEV1B));
pierventre37dcf4c2021-09-16 18:43:06 +0200471 assertEquals(NODE1, dfh.shouldProgram.get(DEV1A));
472 assertEquals(NODE1, dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700473
474 reset(srManager.clusterService);
475
476 // Node 2 should program no device
477 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
478 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200479 assertNotNull(dfh.shouldProgram.get(DEV1A));
480 assertNotNull(dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700481 assertFalse(dfh.shouldProgram(DEV1A));
482 assertFalse(dfh.shouldProgram(DEV1B));
pierventre37dcf4c2021-09-16 18:43:06 +0200483 assertEquals(NODE1, dfh.shouldProgram.get(DEV1A));
484 assertEquals(NODE1, dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700485 }
486
pierventre37dcf4c2021-09-16 18:43:06 +0200487 // There is no leadership for 1A, 1B. Super-damaged cluster.
488 @Test(expected = NullPointerException.class)
Charles Chand66d6712018-03-29 16:03:41 -0700489 public void testShouldHandleRoutingCase6() {
pierventre37dcf4c2021-09-16 18:43:06 +0200490 expect(mockWps.leadershipService.getLeadership(DEV1A_PARTITION_ID)).andReturn(null).anyTimes();
491 expect(mockWps.leadershipService.getLeadership(DEV1B_PARTITION_ID)).andReturn(null).anyTimes();
492 replay(mockWps.leadershipService);
Charles Chand66d6712018-03-29 16:03:41 -0700493
494 expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
495 expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
496 replay(srManager);
497
498 // Node 1 should program no device
499 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
500 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200501 assertNull(dfh.shouldProgram.get(DEV1A));
502 assertNull(dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700503 assertFalse(dfh.shouldProgram(DEV1A));
504 assertFalse(dfh.shouldProgram(DEV1B));
pierventre37dcf4c2021-09-16 18:43:06 +0200505 assertNull(dfh.shouldProgram.get(DEV1A));
506 assertNull(dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700507
508 reset(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200509 clearShouldProgram();
Charles Chand66d6712018-03-29 16:03:41 -0700510
511 // Node 2 should program no device
512 expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
513 replay(srManager.clusterService);
pierventre37dcf4c2021-09-16 18:43:06 +0200514 assertNull(dfh.shouldProgram.get(DEV1A));
515 assertNull(dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700516 assertFalse(dfh.shouldProgram(DEV1A));
517 assertFalse(dfh.shouldProgram(DEV1B));
pierventre37dcf4c2021-09-16 18:43:06 +0200518 assertNull(dfh.shouldProgram.get(DEV1A));
519 assertNull(dfh.shouldProgram.get(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700520
pierventre37dcf4c2021-09-16 18:43:06 +0200521 assertFalse(dfh.shouldProgram.containsKey(DEV1A));
522 assertFalse(dfh.shouldProgram.containsKey(DEV1B));
Charles Chand66d6712018-03-29 16:03:41 -0700523 }
524}