blob: 1939c9feea921ffcd8636a68a416c1f924508a73 [file] [log] [blame]
Tunahan Sezen03e55272020-04-18 09:18:53 +00001/*
Joey Armstrong53fcac22023-01-11 13:25:01 -05002 * Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
Tunahan Sezen03e55272020-04-18 09:18:53 +00003 *
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.opencord.maclearner.app.impl;
17
Tunahan Sezen1f65c902020-09-08 13:10:16 +000018import com.fasterxml.jackson.databind.JsonNode;
Tunahan Sezen03e55272020-04-18 09:18:53 +000019import com.fasterxml.jackson.databind.ObjectMapper;
20import com.google.common.collect.ImmutableList;
Tunahan Sezen1f65c902020-09-08 13:10:16 +000021import com.google.common.collect.ImmutableSet;
Tunahan Sezen03e55272020-04-18 09:18:53 +000022import com.google.common.collect.Lists;
23import com.google.common.collect.Maps;
24import com.google.common.collect.Sets;
25import org.onlab.junit.TestUtils;
Tunahan Sezen1f65c902020-09-08 13:10:16 +000026import org.onlab.packet.ChassisId;
Tunahan Sezen03e55272020-04-18 09:18:53 +000027import org.onlab.packet.DHCP;
Tunahan Sezen1f65c902020-09-08 13:10:16 +000028import org.onlab.packet.EthType;
Tunahan Sezen03e55272020-04-18 09:18:53 +000029import org.onlab.packet.Ethernet;
30import org.onlab.packet.IPv4;
31import org.onlab.packet.Ip4Address;
Tunahan Sezen1f65c902020-09-08 13:10:16 +000032import org.onlab.packet.IpAddress;
Tunahan Sezen03e55272020-04-18 09:18:53 +000033import org.onlab.packet.MacAddress;
34import org.onlab.packet.UDP;
35import org.onlab.packet.VlanId;
36import org.onlab.packet.dhcp.DhcpOption;
37import org.onosproject.cfg.ComponentConfigAdapter;
38import org.onosproject.cfg.ComponentConfigService;
Tunahan Sezen1f65c902020-09-08 13:10:16 +000039import org.onosproject.cluster.ClusterServiceAdapter;
40import org.onosproject.cluster.ControllerNode;
41import org.onosproject.cluster.DefaultControllerNode;
42import org.onosproject.cluster.NodeId;
Tunahan Sezen03e55272020-04-18 09:18:53 +000043import org.onosproject.core.ApplicationId;
Tunahan Sezen1f65c902020-09-08 13:10:16 +000044import org.onosproject.core.CoreService;
Tunahan Sezen03e55272020-04-18 09:18:53 +000045import org.onosproject.core.CoreServiceAdapter;
46import org.onosproject.event.DefaultEventSinkRegistry;
47import org.onosproject.event.Event;
48import org.onosproject.event.EventDeliveryService;
49import org.onosproject.event.EventSink;
Harsh Awasthi6bd73602022-01-31 18:40:25 +053050import org.onosproject.net.Annotations;
Tunahan Sezen03e55272020-04-18 09:18:53 +000051import org.onosproject.net.ConnectPoint;
Tunahan Sezen1f65c902020-09-08 13:10:16 +000052import org.onosproject.net.DefaultDevice;
53import org.onosproject.net.DefaultHost;
54import org.onosproject.net.DefaultLink;
55import org.onosproject.net.Device;
56import org.onosproject.net.DeviceId;
Harsh Awasthi6bd73602022-01-31 18:40:25 +053057import org.onosproject.net.Element;
Tunahan Sezen1f65c902020-09-08 13:10:16 +000058import org.onosproject.net.Host;
59import org.onosproject.net.HostId;
60import org.onosproject.net.HostLocation;
61import org.onosproject.net.Link;
Harsh Awasthi6bd73602022-01-31 18:40:25 +053062import org.onosproject.net.Port;
63import org.onosproject.net.PortNumber;
Tunahan Sezen1f65c902020-09-08 13:10:16 +000064import org.onosproject.net.config.Config;
65import org.onosproject.net.config.ConfigApplyDelegate;
66import org.onosproject.net.config.basics.HostLearningConfig;
67import org.onosproject.net.config.basics.HostLearningConfigTest;
68import org.onosproject.net.device.DeviceListener;
69import org.onosproject.net.device.DeviceServiceAdapter;
70import org.onosproject.net.host.HostDescription;
71import org.onosproject.net.host.HostProvider;
72import org.onosproject.net.host.HostProviderService;
73import org.onosproject.net.host.HostServiceAdapter;
74import org.onosproject.net.link.LinkServiceAdapter;
Tunahan Sezen03e55272020-04-18 09:18:53 +000075import org.onosproject.net.packet.DefaultInboundPacket;
76import org.onosproject.net.packet.InboundPacket;
77import org.onosproject.net.packet.OutboundPacket;
78import org.onosproject.net.packet.PacketContext;
79import org.onosproject.net.packet.PacketContextAdapter;
80import org.onosproject.net.packet.PacketProcessor;
81import org.onosproject.net.packet.PacketServiceAdapter;
Tunahan Sezen1f65c902020-09-08 13:10:16 +000082import org.onosproject.net.provider.AbstractProviderService;
83import org.onosproject.net.provider.ProviderId;
84import org.onosproject.net.topology.Topology;
85import org.onosproject.net.topology.TopologyServiceAdapter;
Tunahan Sezen03e55272020-04-18 09:18:53 +000086import org.onosproject.store.service.AsyncConsistentMap;
87import org.onosproject.store.service.AsyncDistributedSet;
88import org.onosproject.store.service.AtomicCounter;
89import org.onosproject.store.service.ConsistentMap;
90import org.onosproject.store.service.ConsistentMapAdapter;
91import org.onosproject.store.service.ConsistentMapBuilder;
92import org.onosproject.store.service.DistributedSet;
93import org.onosproject.store.service.DistributedSetAdapter;
94import org.onosproject.store.service.DistributedSetBuilder;
95import org.onosproject.store.service.MapEvent;
96import org.onosproject.store.service.MapEventListener;
97import org.onosproject.store.service.SetEventListener;
98import org.onosproject.store.service.StorageServiceAdapter;
99import org.onosproject.store.service.Versioned;
Harsh Awasthi6bd73602022-01-31 18:40:25 +0530100import org.opencord.sadis.BandwidthProfileInformation;
101import org.opencord.sadis.BaseInformationService;
102import org.opencord.sadis.SadisService;
103import org.opencord.sadis.SubscriberAndDeviceInformation;
Tunahan Sezen03e55272020-04-18 09:18:53 +0000104
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000105import java.io.IOException;
106import java.io.InputStream;
Tunahan Sezen03e55272020-04-18 09:18:53 +0000107import java.lang.reflect.Field;
108import java.nio.ByteBuffer;
109import java.util.Collection;
110import java.util.HashMap;
111import java.util.HashSet;
112import java.util.List;
113import java.util.Map;
114import java.util.Set;
115import java.util.concurrent.Executor;
116import java.util.function.BiFunction;
117
118import static com.google.common.base.Preconditions.checkState;
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000119import static org.onosproject.cluster.NodeId.nodeId;
120import static org.onosproject.net.NetTestTools.PID;
121import static org.opencord.maclearner.app.impl.MacLearnerManagerTest.AGG_DEVICE_ID;
122import static org.opencord.maclearner.app.impl.MacLearnerManagerTest.AGG_OLT_PORT;
123import static org.opencord.maclearner.app.impl.MacLearnerManagerTest.CLIENT_CP;
Harsh Awasthi6bd73602022-01-31 18:40:25 +0530124import static org.opencord.maclearner.app.impl.MacLearnerManagerTest.CLIENT_VLAN;
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000125import static org.opencord.maclearner.app.impl.MacLearnerManagerTest.OLT_DEVICE_ID;
126import static org.opencord.maclearner.app.impl.MacLearnerManagerTest.OLT_NNI_PORT;
Harsh Awasthi6bd73602022-01-31 18:40:25 +0530127import static org.opencord.maclearner.app.impl.MacLearnerManagerTest.OLT_SERIAL_NUMBER;
Tunahan Sezen03e55272020-04-18 09:18:53 +0000128
129/**
130 * Mac Learner mock services class.
131 */
132public abstract class TestBaseMacLearner {
133
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000134 protected static final String C1 = "C1";
135 protected static final String C2 = "C2";
136 protected static final String C3 = "C3";
137
138 protected static final NodeId CNID_1 = nodeId(C1);
139 protected static final NodeId CNID_2 = nodeId(C2);
140 protected static final NodeId CNID_3 = nodeId(C3);
141
142 protected static final ControllerNode CNODE_1 = new DefaultControllerNode(CNID_1, "10.0.0.1");
143 protected static final ControllerNode CNODE_2 = new DefaultControllerNode(CNID_2, "10.0.0.2");
144 protected static final ControllerNode CNODE_3 = new DefaultControllerNode(CNID_3, "10.0.0.3");
145
Tunahan Sezen03e55272020-04-18 09:18:53 +0000146 private static final Ip4Address SERVER_IP = Ip4Address.valueOf("10.0.3.253");
147 private static final Ip4Address INTERFACE_IP = Ip4Address.valueOf("10.0.3.254");
148
149 protected MacLearnerManager macLearnerManager;
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000150 protected ApplicationId appId;
151 protected HostLearningConfig hostLearningConfig;
Tunahan Sezen03e55272020-04-18 09:18:53 +0000152
153 protected ComponentConfigService componentConfigService = new MockComponentConfigService();
154 protected MockCoreService coreService = new MockCoreService();
155 protected MockStorageService storageService = new MockStorageService();
156 protected MockPacketService packetService = new MockPacketService();
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000157 protected MockClusterService clusterService = new MockClusterService();
158 protected MockDeviceService deviceService = new MockDeviceService();
159 protected MockTopologyService topologyService = new MockTopologyService();
160 protected MockLinkService linkService = new MockLinkService();
161 protected MacLearnerHostProvider macLearnerHostProvider = new MacLearnerHostProvider();
162 protected MockHostService hostService = new MockHostService(Sets.newHashSet());
Harsh Awasthi6bd73602022-01-31 18:40:25 +0530163 protected MockSadisService sadisService = new MockSadisService();
Tunahan Sezen03e55272020-04-18 09:18:53 +0000164
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000165 public void setUpApp() throws IOException {
Tunahan Sezen03e55272020-04-18 09:18:53 +0000166 macLearnerManager = new MacLearnerManager();
167 macLearnerManager.componentConfigService = this.componentConfigService;
168 macLearnerManager.coreService = this.coreService;
169 macLearnerManager.storageService = this.storageService;
170 macLearnerManager.packetService = this.packetService;
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000171 macLearnerManager.clusterService = this.clusterService;
172 macLearnerManager.deviceService = this.deviceService;
173 macLearnerManager.topologyService = this.topologyService;
174 macLearnerManager.linkService = this.linkService;
Harsh Awasthi6bd73602022-01-31 18:40:25 +0530175 macLearnerManager.sadisService = this.sadisService;
176 macLearnerManager.hostService = this.hostService;
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000177 hostLearningConfig = new HostLearningConfig();
178 InputStream jsonStream = HostLearningConfigTest.class
179 .getResourceAsStream("/host-learning-config.json");
180
181 ConnectPoint subject = CLIENT_CP;
182 String key = CoreService.CORE_APP_NAME;
183 ObjectMapper mapper = new ObjectMapper();
184 JsonNode jsonNode = mapper.readTree(jsonStream);
185 ConfigApplyDelegate delegate = new MockDelegate();
186
187 hostLearningConfig = new HostLearningConfig();
188 hostLearningConfig.init(subject, key, jsonNode, mapper, delegate);
189 macLearnerHostProvider.providerService = new MockHostProviderService(macLearnerHostProvider);
190 macLearnerManager.hostLocService = this.macLearnerHostProvider;
Tunahan Sezen03e55272020-04-18 09:18:53 +0000191 injectEventDispatcher(macLearnerManager, new MockEventDispatcher());
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000192 appId = macLearnerManager.coreService.registerApplication("org.opencord.maclearner");
Tunahan Sezen03e55272020-04-18 09:18:53 +0000193
194 macLearnerManager.activate();
195 }
196
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000197 private class MockDelegate implements ConfigApplyDelegate {
198 @Override
199 public void onApply(Config config) {
200 }
201 }
202
Tunahan Sezen03e55272020-04-18 09:18:53 +0000203 /**
204 * Mocks an instance of {@link ApplicationId} so that the application
205 * component under test can query and use its application ID.
206 */
207 private static final class MockApplicationId implements ApplicationId {
208
209 private final short id;
210 private final String name;
211
212 public MockApplicationId(short id, String name) {
213 this.id = id;
214 this.name = name;
215 }
216
217 @Override
218 public short id() {
219 return id;
220 }
221
222 @Override
223 public String name() {
224 return name;
225 }
226 }
227
228 private static final class MockComponentConfigService extends ComponentConfigAdapter {
229
230 }
231
232 /**
233 * Mocks the core services of ONOS so that the application under test can
234 * register and query application IDs.
235 */
236 private static final class MockCoreService extends CoreServiceAdapter {
237
238 private List<ApplicationId> idList = Lists.newArrayList();
239 private Map<String, ApplicationId> idMap = Maps.newHashMap();
240
241 @Override
242 public ApplicationId getAppId(Short id) {
243 if (id >= idList.size()) {
244 return null;
245 }
246 return idList.get(id);
247 }
248
249 @Override
250 public ApplicationId getAppId(String name) {
251 return idMap.get(name);
252 }
253
254 @Override
255 public ApplicationId registerApplication(String name) {
256 ApplicationId appId = idMap.get(name);
257 if (appId == null) {
258 appId = new MockApplicationId((short) idList.size(), name);
259 idList.add(appId);
260 idMap.put(name, appId);
261 }
262 return appId;
263 }
264
265 }
266
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000267 private static class MockClusterService extends ClusterServiceAdapter {
268 private final Map<NodeId, ControllerNode> nodes = new HashMap<>();
269 private final Map<NodeId, ControllerNode.State> states = new HashMap<>();
270
271 MockClusterService() {
272 nodes.put(CNODE_1.id(), CNODE_1);
273 nodes.put(CNODE_2.id(), CNODE_2);
274 nodes.put(CNODE_3.id(), CNODE_3);
275
276 states.put(CNODE_1.id(), ControllerNode.State.READY);
277 states.put(CNODE_2.id(), ControllerNode.State.ACTIVE);
278 states.put(CNODE_3.id(), ControllerNode.State.ACTIVE);
279 }
280
281 @Override
282 public Set<ControllerNode> getNodes() {
283 return ImmutableSet.copyOf(nodes.values());
284 }
285
286 @Override
287 public ControllerNode getNode(NodeId nodeId) {
288 return nodes.get(nodeId);
289 }
290
291 @Override
292 public ControllerNode.State getState(NodeId nodeId) {
293 return states.get(nodeId);
294 }
295 }
296
297 /**
298 * Mocks the device service of ONOS so that the application under test can
299 * register listeners.
300 */
301 protected static class MockHostService extends HostServiceAdapter {
302 private Set<Host> hosts;
303
304 MockHostService(Set<Host> hosts) {
305 this.hosts = ImmutableSet.copyOf(hosts);
306 }
307
308 @Override
309 public Set<Host> getHosts() {
310 return hosts;
311 }
312
313 @Override
314 public Host getHost(HostId hostId) {
315 return hosts.stream().filter(host -> hostId.equals(host.id())).findFirst().orElse(null);
316 }
317 }
318
319 /**
320 * Mocks the device service of ONOS so that the application under test can
321 * register listeners.
322 */
323 private static class MockDeviceService extends DeviceServiceAdapter {
324
325 private List<DeviceListener> listeners = Lists.newArrayList();
326
327 @Override
328 public Device getDevice(DeviceId deviceId) {
329 if (deviceId.equals(OLT_DEVICE_ID)) {
330 return new DefaultDevice(null, OLT_DEVICE_ID, Device.Type.SWITCH,
331 "VOLTHA Project", "open_pon", "open_pon",
Harsh Awasthi6bd73602022-01-31 18:40:25 +0530332 OLT_SERIAL_NUMBER, new ChassisId("a0a0a0a0a01"));
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000333 } else {
334 return null;
335 }
336 }
337
338 @Override
Harsh Awasthi6bd73602022-01-31 18:40:25 +0530339 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
340 return new TestBaseMacLearner.MockPort(new ConnectPoint(deviceId, portNumber));
341 }
342
343 @Override
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000344 public void addListener(DeviceListener listener) {
345 listeners.add(listener);
346 }
347
348 @Override
349 public void removeListener(DeviceListener listener) {
350 listeners.remove(listener);
351 }
352 }
353
Harsh Awasthi6bd73602022-01-31 18:40:25 +0530354 static class MockPort implements Port {
355 private ConnectPoint cp;
356
357 public MockPort(ConnectPoint cp) {
358 this.cp = cp;
359 }
360 @Override
361 public boolean isEnabled() {
362 return true;
363 }
364 @Override
365 public long portSpeed() {
366 return 1000;
367 }
368 @Override
369 public Element element() {
370 return null;
371 }
372 @Override
373 public PortNumber number() {
374 return null;
375 }
376 @Override
377 public Annotations annotations() {
378 return new MockAnnotations();
379 }
380 @Override
381 public Type type() {
382 return Port.Type.FIBER;
383 }
384
385 private class MockAnnotations implements Annotations {
386
387 @Override
388 public String value(String val) {
389 if (cp.port().toLong() == 32) {
390 return "ALPHe3d1cea3-1";
391 } else if (cp.port().toLong() == 4112) {
392 return "ALPHe3d1ceb7-1";
393 } else {
394 return "PON 1/1";
395 }
396 }
397 @Override
398 public Set<String> keys() {
399 return null;
400 }
401 }
402 }
403
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000404 /**
405 * Mocks the topology service of ONOS so that the application under test can
406 * check fake topology.
407 */
408 private static class MockTopologyService extends TopologyServiceAdapter {
409
410 private final Topology topology = new MockTopology();
411
412 @Override
413 public Topology currentTopology() {
414 return topology;
415 }
416
417 @Override
418 public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) {
419 return false;
420 }
421 }
422
423 private static class MockTopology implements Topology {
424 @Override
425 public long time() {
426 return 11111L;
427 }
428
429 @Override
430 public long creationTime() {
431 return 22222L;
432 }
433
434 @Override
435 public long computeCost() {
436 return 0;
437 }
438
439 @Override
440 public int clusterCount() {
441 return 2;
442 }
443
444 @Override
445 public int deviceCount() {
446 return 6;
447 }
448
449 @Override
450 public int linkCount() {
451 return 4;
452 }
453
454 @Override
455 public ProviderId providerId() {
456 return ProviderId.NONE;
457 }
458 }
459
Tunahan Sezen03e55272020-04-18 09:18:53 +0000460 /**
461 * Mocks the storage service of ONOS so that the application under test can
462 * use consistent maps.
463 */
464 private static class MockStorageService extends StorageServiceAdapter {
465
466 @Override
467 public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() {
468 ConsistentMapBuilder<K, V> builder = new ConsistentMapBuilder<K, V>() {
469 @Override
470 public AsyncConsistentMap<K, V> buildAsyncMap() {
471 return null;
472 }
473
474 @Override
475 public ConsistentMap<K, V> build() {
476 return new TestConsistentMap<>();
477 }
478 };
479
480 return builder;
481 }
482
483 @Override
484 public <E> DistributedSetBuilder<E> setBuilder() {
485 DistributedSetBuilder<E> builder = new DistributedSetBuilder<E>() {
486 @Override
487 public AsyncDistributedSet<E> build() {
488 return new DistributedSetAdapter<E>() {
489 @Override
490 public DistributedSet<E> asDistributedSet() {
491 return new TestDistributedSet<>();
492 }
493 };
494 }
495 };
496
497 return builder;
498 }
499
500 @Override
501 public AtomicCounter getAtomicCounter(String name) {
502 return new MockAtomicCounter();
503 }
504
505 // Mock ConsistentMap that behaves as a HashMap
506 class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> {
507 private Map<K, Versioned<V>> map = new HashMap<>();
508 private Map<MapEventListener<K, V>, Executor> listeners = new HashMap<>();
509
510 public void notifyListeners(MapEvent<K, V> event) {
511 listeners.forEach((c, e) -> e.execute(() -> c.event(event)));
512 }
513
514 @Override
515 public int size() {
516 return map.size();
517 }
518
519 @Override
520 public Versioned<V> put(K key, V value) {
521 Versioned<V> oldValue = map.get(key);
522 Versioned<V> newValue = new Versioned<>(value, oldValue == null ? 0 : oldValue.version() + 1);
523 map.put(key, newValue);
524 notifyListeners(new MapEvent<>(name(), key, newValue, oldValue));
525 return newValue;
526 }
527
528 @Override
529 public Versioned<V> get(K key) {
530 return map.get(key);
531 }
532
533 @Override
534 public Versioned<V> remove(K key) {
535 Versioned<V> oldValue = map.remove(key);
536 notifyListeners(new MapEvent<>(name(), key, oldValue, null));
537 return oldValue;
538 }
539
540 @Override
541 public Versioned<V> computeIfPresent(K key,
542 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
543 Versioned<V> oldValue = map.get(key);
544 Versioned<V> newValue = new Versioned<>(remappingFunction.apply(key, oldValue.value()),
545 oldValue == null ? 0 : oldValue.version() + 1);
546 map.put(key, newValue);
547 notifyListeners(new MapEvent<>(name(), key, newValue, oldValue));
548 return newValue;
549 }
550
551 @Override
552 public Set<Map.Entry<K, Versioned<V>>> entrySet() {
553 return map.entrySet();
554 }
555
556 @Override
557 public Set<K> keySet() {
558 return map.keySet();
559 }
560
561 @Override
562 public Collection<Versioned<V>> values() {
563 return map.values();
564 }
565
566 @Override
567 public void clear() {
568 map.clear();
569 }
570
571 @Override
572 public void addListener(MapEventListener<K, V> listener, Executor executor) {
573 listeners.put(listener, executor);
574 }
575
576 @Override
577 public void removeListener(MapEventListener<K, V> listener) {
578 listeners.remove(listener);
579 }
580 }
581
582 // Mock DistributedSet that behaves as a HashSet
583 class TestDistributedSet<E> extends HashSet<E> implements DistributedSet<E> {
584
585 @Override
586 public void addListener(SetEventListener<E> listener) {
587 }
588
589 @Override
590 public void removeListener(SetEventListener<E> listener) {
591 }
592
593 @Override
594 public String name() {
595 return null;
596 }
597
598 @Override
599 public Type primitiveType() {
600 return null;
601 }
602 }
603 }
604
605 private static class MockAtomicCounter implements AtomicCounter {
606 long id = 0;
607
608 @Override
609 public long incrementAndGet() {
610 return ++id;
611 }
612
613 @Override
614 public long getAndIncrement() {
615 return id++;
616 }
617
618 @Override
619 public long getAndAdd(long delta) {
620 long oldId = id;
621 id += delta;
622 return oldId;
623 }
624
625 @Override
626 public long addAndGet(long delta) {
627 id += delta;
628 return id;
629 }
630
631 @Override
632 public void set(long value) {
633 id = value;
634 }
635
636 @Override
637 public boolean compareAndSet(long expectedValue, long updateValue) {
638 if (id == expectedValue) {
639 id = updateValue;
640 return true;
641 } else {
642 return false;
643 }
644 }
645
646 @Override
647 public long get() {
648 return id;
649 }
650
651 @Override
652 public String name() {
653 return "MockAtomicCounter";
654 }
655 }
656
657 /**
658 * Mocks the packet service of ONOS so that the application under test can
659 * observe network packets.
660 */
661 public static class MockPacketService extends PacketServiceAdapter {
662 Set<PacketProcessor> packetProcessors = Sets.newHashSet();
663 OutboundPacket emittedPacket;
664
665 @Override
666 public void addProcessor(PacketProcessor processor, int priority) {
667 packetProcessors.add(processor);
668 }
669
670 public void processPacket(PacketContext packetContext) {
671 packetProcessors.forEach(p -> p.process(packetContext));
672 }
673
674 @Override
675 public void emit(OutboundPacket packet) {
676 this.emittedPacket = packet;
677 }
678 }
679
680 /**
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000681 * Mocks the link service of ONOS so that the application under test can
682 * observe links.
683 */
684 public static class MockLinkService extends LinkServiceAdapter {
685
686 Link link = DefaultLink.builder()
687 .type(Link.Type.DIRECT)
688 .providerId(PID)
689 .src(new ConnectPoint(OLT_DEVICE_ID, OLT_NNI_PORT))
690 .dst(new ConnectPoint(AGG_DEVICE_ID, AGG_OLT_PORT)).build();
691
692 @Override
693 public Set<Link> getDeviceLinks(DeviceId deviceId) {
694 return Sets.newHashSet(link);
695 }
696 }
697
698 /**
Tunahan Sezen03e55272020-04-18 09:18:53 +0000699 * Implements event delivery system that delivers events synchronously, or
700 * in-line with the post method invocation.
701 */
702 public static class MockEventDispatcher extends DefaultEventSinkRegistry
703 implements EventDeliveryService {
704
705 @Override
706 @SuppressWarnings("unchecked")
707 public synchronized void post(Event event) {
708 EventSink sink = getSink(event.getClass());
709 checkState(sink != null, "No sink for event %s", event);
710 sink.process(event);
711 }
712
713 @Override
714 public void setDispatchTimeLimit(long millis) {
715 }
716
717 @Override
718 public long getDispatchTimeLimit() {
719 return 0;
720 }
721 }
722
723 public static void injectEventDispatcher(Object manager, EventDeliveryService svc) {
724 Class mc = manager.getClass();
725 Field[] var3 = mc.getSuperclass().getDeclaredFields();
726
727 for (Field f : var3) {
728 if (f.getType().equals(EventDeliveryService.class)) {
729 try {
730 TestUtils.setField(manager, f.getName(), svc);
731 break;
732 } catch (TestUtils.TestUtilsException var8) {
733 throw new IllegalArgumentException("Unable to inject reference", var8);
734 }
735 }
736 }
737 }
738
739 /**
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000740 * Mock HostProviderService.
741 */
742 private class MockHostProviderService
743 extends AbstractProviderService<HostProvider>
744 implements HostProviderService {
745 private HostId hostId = null;
746 private HostDescription hostDescription = null;
747 private String event = null;
748
749 public MockHostProviderService(HostProvider provider) {
750 super(provider);
751 }
752
753 @Override
754 public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) {
755 this.hostId = hostId;
756 this.hostDescription = hostDescription;
757 this.event = "hostDetected";
758 Set<Host> previousHosts = Sets.newHashSet(hostService.getHosts());
759 previousHosts.add(new DefaultHost(provider().id(), hostId, hostDescription.hwAddress(),
760 hostDescription.vlan(), hostDescription.locations(), hostDescription.auxLocations(),
761 hostDescription.ipAddress(), VlanId.NONE,
762 EthType.EtherType.UNKNOWN.ethType(), false, false));
763 hostService = new MockHostService(previousHosts);
Harsh Awasthi6bd73602022-01-31 18:40:25 +0530764 macLearnerManager.hostService = hostService;
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000765 }
766
767 @Override
768 public void hostVanished(HostId hostId) {
769 this.hostId = hostId;
770 this.event = "hostVanished";
771 Set<Host> previousHosts = Sets.newHashSet(hostService.getHosts());
772 Host removedHost = hostService.getHost(hostId);
773 previousHosts.remove(removedHost);
774 hostService = new MockHostService(previousHosts);
Harsh Awasthi6bd73602022-01-31 18:40:25 +0530775 macLearnerManager.hostService = hostService;
Tunahan Sezen1f65c902020-09-08 13:10:16 +0000776 }
777
778 @Override
779 public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
780 // not implemented
781 }
782
783 @Override
784 public void removeLocationFromHost(HostId hostId, HostLocation location) {
785 // not implemented
786 }
787
788 public void clear() {
789 this.hostId = null;
790 this.hostDescription = null;
791 this.event = null;
792 }
793 }
794
795 /**
Tunahan Sezen03e55272020-04-18 09:18:53 +0000796 * Generates DHCP REQUEST packet.
797 */
798 protected static class TestDhcpRequestPacketContext extends PacketContextAdapter {
799
800 private InboundPacket inPacket;
801
802 public TestDhcpRequestPacketContext(MacAddress clientMac, VlanId vlanId,
803 VlanId qinqQVid,
804 ConnectPoint clientCp) {
805 super(0, null, null, false);
806 byte[] dhcpMsgType = new byte[1];
807 dhcpMsgType[0] = (byte) DHCP.MsgType.DHCPREQUEST.getValue();
808
809 DhcpOption dhcpOption = new DhcpOption();
810 dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
811 dhcpOption.setData(dhcpMsgType);
812 dhcpOption.setLength((byte) 1);
813 DhcpOption endOption = new DhcpOption();
814 endOption.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
815
816 DHCP dhcp = new DHCP();
817 dhcp.setHardwareType(DHCP.HWTYPE_ETHERNET);
818 dhcp.setHardwareAddressLength((byte) 6);
819 dhcp.setClientHardwareAddress(clientMac.toBytes());
820 dhcp.setOptions(ImmutableList.of(dhcpOption, endOption));
821
822
823 UDP udp = new UDP();
824 udp.setPayload(dhcp);
825 udp.setSourcePort(UDP.DHCP_CLIENT_PORT);
826 udp.setDestinationPort(UDP.DHCP_SERVER_PORT);
827
828 IPv4 ipv4 = new IPv4();
829 ipv4.setPayload(udp);
830 ipv4.setDestinationAddress(SERVER_IP.toInt());
831 ipv4.setSourceAddress(INTERFACE_IP.toInt());
832
833 Ethernet eth = new Ethernet();
834 eth.setEtherType(Ethernet.TYPE_IPV4)
835 .setVlanID(vlanId.toShort())
836 .setQinQVID(qinqQVid.toShort())
837 .setSourceMACAddress(clientMac)
838 .setDestinationMACAddress(MacAddress.BROADCAST)
839 .setPayload(ipv4);
840
841 this.inPacket = new DefaultInboundPacket(clientCp, eth,
842 ByteBuffer.wrap(eth.serialize()));
843 }
844
845 @Override
846 public InboundPacket inPacket() {
847 return this.inPacket;
848 }
849 }
850
Harsh Awasthi6bd73602022-01-31 18:40:25 +0530851 /**
852 * Generates DHCP RESPONSE packet.
853 */
854 protected static class TestDhcpResponsePacketContext extends PacketContextAdapter {
855
856 private InboundPacket inPacket;
857
858 public TestDhcpResponsePacketContext(MacAddress clientMacAddress, MacAddress serverMacAddress, VlanId vlanId,
859 VlanId qinqQVid, ConnectPoint connectPoint) {
860 super(0, null, null, false);
861 byte[] dhcpMsgType = new byte[1];
862 dhcpMsgType[0] = (byte) DHCP.MsgType.DHCPOFFER.getValue();
863
864 DhcpOption dhcpOption = new DhcpOption();
865 dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
866 dhcpOption.setData(dhcpMsgType);
867 dhcpOption.setLength((byte) 1);
868 DhcpOption endOption = new DhcpOption();
869 endOption.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
870
871 DHCP dhcp = new DHCP();
872 dhcp.setHardwareType(DHCP.HWTYPE_ETHERNET);
873 dhcp.setHardwareAddressLength((byte) 6);
874 dhcp.setClientHardwareAddress(clientMacAddress.toBytes());
875 dhcp.setOptions(ImmutableList.of(dhcpOption, endOption));
876 dhcp.setYourIPAddress(Ip4Address.valueOf("1.1.1.1").toInt());
877
878 UDP udp = new UDP();
879 udp.setPayload(dhcp);
880 udp.setSourcePort(UDP.DHCP_SERVER_PORT);
881 udp.setDestinationPort(UDP.DHCP_CLIENT_PORT);
882
883 IPv4 ipv4 = new IPv4();
884 ipv4.setPayload(udp);
885 ipv4.setDestinationAddress(INTERFACE_IP.toInt());
886 ipv4.setSourceAddress(SERVER_IP.toInt());
887
888 Ethernet eth = new Ethernet();
889 eth.setEtherType(Ethernet.TYPE_IPV4)
890 .setVlanID(vlanId.toShort())
891 .setQinQVID(qinqQVid.toShort())
892 .setSourceMACAddress(serverMacAddress)
893 .setDestinationMACAddress(clientMacAddress)
894 .setPayload(ipv4);
895
896 this.inPacket = new DefaultInboundPacket(connectPoint, eth,
897 ByteBuffer.wrap(eth.serialize()));
898 }
899
900 @Override
901 public InboundPacket inPacket() {
902 return this.inPacket;
903 }
904 }
905
906 /**
907 * Mock Sadis service.
908 */
909 static class MockSadisService implements SadisService {
910 @Override
911 public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
912 return new TestBaseMacLearner.MockSubService();
913 }
914
915 @Override
916 public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
917 return null;
918 }
919 }
920
921 static class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
922 TestBaseMacLearner.MockSubscriberAndDeviceInformation device =
923 new TestBaseMacLearner.MockSubscriberAndDeviceInformation(OLT_SERIAL_NUMBER, CLIENT_VLAN, VlanId.NONE,
924 null, null, null, null, (int) OLT_NNI_PORT.toLong());
925 @Override
926 public SubscriberAndDeviceInformation get(String id) {
927 if (id.equals(OLT_SERIAL_NUMBER)) {
928 return device;
929 }
930 return null;
931 }
932
933 @Override
934 public void clearLocalData() {}
935 @Override
936 public void invalidateAll() {}
937 @Override
938 public void invalidateId(String id) {}
939 @Override
940 public SubscriberAndDeviceInformation getfromCache(String id) {
941 return null;
942 }
943 }
944
945 static class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
946
947 MockSubscriberAndDeviceInformation(String id, VlanId cTag,
948 VlanId sTag, String nasPortId,
949 String circuitId, MacAddress hardId,
950 Ip4Address ipAddress, int uplinkPort) {
951 this.setHardwareIdentifier(hardId);
952 this.setId(id);
953 this.setIPAddress(ipAddress);
954 this.setNasPortId(nasPortId);
955 this.setUplinkPort(uplinkPort);
956 this.setCircuitId(circuitId);
957 }
958 }
Tunahan Sezen03e55272020-04-18 09:18:53 +0000959}