blob: c04b8c3eacb70652f27812a6293f884b6371e23d [file] [log] [blame]
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.rpc.grpc;
import static org.junit.Assert.*;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.PortNumber.portNumber;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestTools;
import org.onlab.packet.ChassisId;
import org.onosproject.incubator.rpc.RemoteServiceContext;
import org.onosproject.incubator.rpc.RemoteServiceContextProvider;
import org.onosproject.incubator.rpc.RemoteServiceContextProviderService;
import org.onosproject.incubator.rpc.RemoteServiceProviderRegistry;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Device.Type;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
import org.onosproject.net.link.DefaultLinkDescription;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.net.link.LinkProvider;
import org.onosproject.net.link.LinkProviderRegistry;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.provider.AbstractProviderRegistry;
import org.onosproject.net.provider.AbstractProviderService;
import org.onosproject.net.provider.ProviderId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableList;
/**
* Set of tests of the gRPC RemoteService components.
*/
public class GrpcRemoteServiceTest {
private static final DeviceId DEVICE_ID = deviceId("dev:000001");
private final Logger log = LoggerFactory.getLogger(getClass());
private static final ProviderId PID = new ProviderId("test", "com.exmaple.test");
private static final URI DURI = URI.create("dev:000001");
private static final String MFR = "mfr";
private static final String HW = "hw";
private static final String SW = "sw";
private static final String SN = "serial";
private static final ChassisId CHASSIS = new ChassisId(42);
private static final SparseAnnotations ANON = DefaultAnnotations.builder()
.set("foo", "var")
.build();
private static final PortNumber PORT = PortNumber.portNumber(99);
private static final DeviceDescription DDESC
= new DefaultDeviceDescription(DURI, Type.SWITCH, MFR, HW, SW, SN,
CHASSIS, ANON);
private GrpcRemoteServiceServer server;
private GrpcRemoteServiceProvider client;
private DeviceProvider svSideDeviceProvider;
private MTestDeviceProviderService svDeviceProviderService;
private ServerSideLinkProviderService svLinkProviderService;
private CountDownLatch serverReady;
private URI uri;
@Before
public void setUp() throws Exception {
serverReady = new CountDownLatch(1);
server = new GrpcRemoteServiceServer();
server.deviceProviderRegistry = new MTestDeviceProviderRegistry();
server.linkProviderRegistry = new ServerSideLinkProviderRegistry();
server.listenPort = TestTools.findAvailablePort(11984);
uri = URI.create("grpc://localhost:" + server.listenPort);
// todo: pass proper ComponentContext
server.activate(null);
client = new GrpcRemoteServiceProvider();
client.rpcRegistry = new NoOpRemoteServiceProviderRegistry();
client.activate();
}
@After
public void tearDown() {
client.deactivate();
server.deactivate();
svLinkProviderService = null;
}
private static void assertEqualsButNotSame(Object expected, Object actual) {
assertEquals(expected, actual);
assertNotSame("Cannot be same instance if it properly went through gRPC",
expected, actual);
}
@Test
public void deviceServiceBasics() throws InterruptedException {
RemoteServiceContext remoteServiceContext = client.get(uri);
assertNotNull(remoteServiceContext);
DeviceProviderRegistry deviceProviderRegistry = remoteServiceContext.get(DeviceProviderRegistry.class);
assertNotNull(deviceProviderRegistry);
CTestDeviceProvider clDeviceProvider = new CTestDeviceProvider();
DeviceProviderService clDeviceProviderService = deviceProviderRegistry.register(clDeviceProvider);
assertTrue(serverReady.await(10, TimeUnit.SECONDS));
// client to server communication
clDeviceProviderService.deviceConnected(DEVICE_ID, DDESC);
assertTrue(svDeviceProviderService.deviceConnected.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.deviceConnectedDid);
assertEqualsButNotSame(DDESC, svDeviceProviderService.deviceConnectedDesc);
PortDescription portDescription = new DefaultPortDescription(PORT, true, ANON);
List<PortDescription> portDescriptions = ImmutableList.of(portDescription);
clDeviceProviderService.updatePorts(DEVICE_ID, portDescriptions);
assertTrue(svDeviceProviderService.updatePorts.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.updatePortsDid);
assertEqualsButNotSame(portDescriptions, svDeviceProviderService.updatePortsDescs);
MastershipRole cRole = MastershipRole.MASTER;
MastershipRole dRole = MastershipRole.STANDBY;
clDeviceProviderService.receivedRoleReply(DEVICE_ID, cRole, dRole);
assertTrue(svDeviceProviderService.receivedRoleReply.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.receivedRoleReplyDid);
assertEquals(cRole, svDeviceProviderService.receivedRoleReplyRequested);
assertEquals(dRole, svDeviceProviderService.receivedRoleReplyResponse);
clDeviceProviderService.portStatusChanged(DEVICE_ID, portDescription);
assertTrue(svDeviceProviderService.portStatusChanged.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.portStatusChangedDid);
assertEqualsButNotSame(portDescription, svDeviceProviderService.portStatusChangedDesc);
Collection<PortStatistics> portStatistics = Collections.emptyList();
clDeviceProviderService.updatePortStatistics(DEVICE_ID, portStatistics);
assertTrue(svDeviceProviderService.updatePortStatistics.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.updatePortStatisticsDid);
assertEqualsButNotSame(portStatistics, svDeviceProviderService.updatePortStatisticsStats);
clDeviceProviderService.deviceDisconnected(DEVICE_ID);
assertTrue(svDeviceProviderService.deviceDisconnected.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.deviceDisconnectedDid);
// server to client communication
svSideDeviceProvider.triggerProbe(DEVICE_ID);
assertTrue(clDeviceProvider.triggerProbe.await(10, TimeUnit.SECONDS));
assertEquals(DEVICE_ID, clDeviceProvider.triggerProbeDid);
assertNotSame("Cannot be same instance if it properly went through gRPC",
DEVICE_ID, clDeviceProvider.triggerProbeDid);
svSideDeviceProvider.roleChanged(DEVICE_ID, MastershipRole.STANDBY);
assertTrue(clDeviceProvider.roleChanged.await(10, TimeUnit.SECONDS));
assertEquals(DEVICE_ID, clDeviceProvider.roleChangedDid);
assertNotSame("Cannot be same instance if it properly went through gRPC",
DEVICE_ID, clDeviceProvider.roleChangedDid);
assertEquals(MastershipRole.STANDBY, clDeviceProvider.roleChangedNewRole);
clDeviceProvider.isReachableReply = false;
assertEquals(clDeviceProvider.isReachableReply,
svSideDeviceProvider.isReachable(DEVICE_ID));
assertTrue(clDeviceProvider.isReachable.await(10, TimeUnit.SECONDS));
assertEquals(DEVICE_ID, clDeviceProvider.isReachableDid);
assertNotSame("Cannot be same instance if it properly went through gRPC",
DEVICE_ID, clDeviceProvider.isReachableDid);
}
@Test
public void linkVanishedDevice() throws InterruptedException {
RemoteServiceContext remoteServiceContext = client.get(uri);
assertNotNull(remoteServiceContext);
LinkProviderRegistry providerRegistry = remoteServiceContext.get(LinkProviderRegistry.class);
assertNotNull(providerRegistry);
final String schemeTest = "test";
LinkProviderService client = providerRegistry.register(new StubLinkProvider(schemeTest));
assertNotNull(client);
client.linksVanished(DEVICE_ID);
assertEquals(schemeTest, svLinkProviderService.provider().id().scheme());
assertTrue(svLinkProviderService.calls.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(DEVICE_ID, svLinkProviderService.arg);
}
@Test
public void linkVanishedPort() throws InterruptedException {
RemoteServiceContext remoteServiceContext = client.get(uri);
assertNotNull(remoteServiceContext);
LinkProviderRegistry providerRegistry = remoteServiceContext.get(LinkProviderRegistry.class);
assertNotNull(providerRegistry);
final String schemeTest = "test";
LinkProviderService client = providerRegistry.register(new StubLinkProvider(schemeTest));
assertNotNull(client);
final ConnectPoint cp = new ConnectPoint(DEVICE_ID, PORT);
client.linksVanished(cp);
assertEquals(schemeTest, svLinkProviderService.provider().id().scheme());
assertTrue(svLinkProviderService.calls.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(cp, svLinkProviderService.arg);
}
@Test
public void linkVanishedDescription() throws InterruptedException {
RemoteServiceContext remoteServiceContext = client.get(uri);
assertNotNull(remoteServiceContext);
LinkProviderRegistry providerRegistry = remoteServiceContext.get(LinkProviderRegistry.class);
assertNotNull(providerRegistry);
final String schemeTest = "test";
LinkProviderService client = providerRegistry.register(new StubLinkProvider(schemeTest));
assertNotNull(client);
ConnectPoint src = new ConnectPoint(deviceId("dev:1"), portNumber(10));
ConnectPoint dst = new ConnectPoint(deviceId("dev:2"), portNumber(20));
LinkDescription linkDescription = new DefaultLinkDescription(src, dst, Link.Type.DIRECT, ANON);
client.linkVanished(linkDescription);
assertEquals(schemeTest, svLinkProviderService.provider().id().scheme());
assertTrue(svLinkProviderService.calls.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(linkDescription, svLinkProviderService.arg);
}
@Test
public void linkDetected() throws InterruptedException {
RemoteServiceContext remoteServiceContext = client.get(uri);
assertNotNull(remoteServiceContext);
LinkProviderRegistry providerRegistry = remoteServiceContext.get(LinkProviderRegistry.class);
assertNotNull(providerRegistry);
final String schemeTest = "test";
LinkProviderService client = providerRegistry.register(new StubLinkProvider(schemeTest));
assertNotNull(client);
ConnectPoint src = new ConnectPoint(deviceId("dev:1"), portNumber(10));
ConnectPoint dst = new ConnectPoint(deviceId("dev:2"), portNumber(20));
LinkDescription linkDescription = new DefaultLinkDescription(src, dst, Link.Type.DIRECT, ANON);
client.linkDetected(linkDescription);
assertEquals(schemeTest, svLinkProviderService.provider().id().scheme());
assertTrue(svLinkProviderService.calls.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(linkDescription, svLinkProviderService.arg);
}
@Test
public void linkServiceBasics() throws InterruptedException {
RemoteServiceContext remoteServiceContext = client.get(uri);
assertNotNull(remoteServiceContext);
LinkProviderRegistry providerRegistry = remoteServiceContext.get(LinkProviderRegistry.class);
assertNotNull(providerRegistry);
final String schemeTest = "test";
LinkProviderService client = providerRegistry.register(new StubLinkProvider(schemeTest));
assertNotNull(client);
ConnectPoint src = new ConnectPoint(deviceId("dev:1"), portNumber(10));
ConnectPoint dst = new ConnectPoint(deviceId("dev:2"), portNumber(20));
LinkDescription linkDescription = new DefaultLinkDescription(src, dst, Link.Type.DIRECT, ANON);
client.linkDetected(linkDescription);
assertEquals(schemeTest, svLinkProviderService.provider().id().scheme());
assertTrue(svLinkProviderService.calls.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(linkDescription, svLinkProviderService.arg);
svLinkProviderService.reset();
client.linkVanished(linkDescription);
assertEquals(schemeTest, svLinkProviderService.provider().id().scheme());
assertTrue(svLinkProviderService.calls.await(10, TimeUnit.SECONDS));
assertEqualsButNotSame(linkDescription, svLinkProviderService.arg);
}
/**
* Device Provider on CO side.
*/
public class CTestDeviceProvider implements DeviceProvider {
final CountDownLatch triggerProbe = new CountDownLatch(1);
DeviceId triggerProbeDid;
final CountDownLatch roleChanged = new CountDownLatch(1);
DeviceId roleChangedDid;
MastershipRole roleChangedNewRole;
final CountDownLatch isReachable = new CountDownLatch(1);
DeviceId isReachableDid;
boolean isReachableReply = false;
final CountDownLatch portStateChanged = new CountDownLatch(1);
DeviceId portStateChangedDid;
PortNumber portStateChangedPort;
@Override
public ProviderId id() {
return PID;
}
@Override
public void triggerProbe(DeviceId deviceId) {
log.info("triggerProbe({}) on Client called", deviceId);
triggerProbeDid = deviceId;
triggerProbe.countDown();
}
@Override
public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
log.info("roleChanged({},{}) on Client called", deviceId, newRole);
roleChangedDid = deviceId;
roleChangedNewRole = newRole;
roleChanged.countDown();
}
@Override
public boolean isReachable(DeviceId deviceId) {
log.info("isReachable({}) on Client called", deviceId);
isReachableDid = deviceId;
isReachable.countDown();
return isReachableReply;
}
@Override
public void changePortState(DeviceId deviceId, PortNumber portNumber,
boolean enable) {
log.info("portState change to {} on ({},{}) on Client called", enable,
deviceId, portNumber);
portStateChangedDid = deviceId;
portStateChangedPort = portNumber;
portStateChanged.countDown();
}
}
class NoOpRemoteServiceProviderRegistry
implements RemoteServiceProviderRegistry {
@Override
public RemoteServiceContextProviderService register(RemoteServiceContextProvider provider) {
return new RemoteServiceContextProviderService() {
@Override
public RemoteServiceContextProvider provider() {
return provider;
}
};
}
@Override
public void unregister(RemoteServiceContextProvider provider) {
}
@Override
public Set<ProviderId> getProviders() {
return Collections.emptySet();
}
}
/**
* DeviceProvider on Metro side.
*/
public class MTestDeviceProviderRegistry
extends AbstractProviderRegistry<DeviceProvider, DeviceProviderService>
implements DeviceProviderRegistry {
@Override
protected DeviceProviderService createProviderService(DeviceProvider provider) {
log.info("createProviderService({})", provider);
svSideDeviceProvider = provider;
svDeviceProviderService = new MTestDeviceProviderService(provider);
serverReady.countDown();
return svDeviceProviderService;
}
}
private final class MTestDeviceProviderService
extends AbstractProviderService<DeviceProvider>
implements DeviceProviderService {
public MTestDeviceProviderService(DeviceProvider provider) {
super(provider);
}
final CountDownLatch deviceConnected = new CountDownLatch(1);
DeviceId deviceConnectedDid;
DeviceDescription deviceConnectedDesc;
@Override
public void deviceConnected(DeviceId deviceId,
DeviceDescription deviceDescription) {
log.info("deviceConnected({}, {}) on Server called", deviceId, deviceDescription);
deviceConnectedDid = deviceId;
deviceConnectedDesc = deviceDescription;
deviceConnected.countDown();
}
final CountDownLatch updatePorts = new CountDownLatch(1);
DeviceId updatePortsDid;
List<PortDescription> updatePortsDescs;
@Override
public void updatePorts(DeviceId deviceId,
List<PortDescription> portDescriptions) {
log.info("updatePorts({}, {}) on Server called", deviceId, portDescriptions);
updatePortsDid = deviceId;
updatePortsDescs = portDescriptions;
updatePorts.countDown();
}
final CountDownLatch receivedRoleReply = new CountDownLatch(1);
DeviceId receivedRoleReplyDid;
MastershipRole receivedRoleReplyRequested;
MastershipRole receivedRoleReplyResponse;
@Override
public void receivedRoleReply(DeviceId deviceId, MastershipRole requested,
MastershipRole response) {
log.info("receivedRoleReply({}, {}, {}) on Server called", deviceId, requested, response);
receivedRoleReplyDid = deviceId;
receivedRoleReplyRequested = requested;
receivedRoleReplyResponse = response;
receivedRoleReply.countDown();
}
final CountDownLatch portStatusChanged = new CountDownLatch(1);
DeviceId portStatusChangedDid;
PortDescription portStatusChangedDesc;
@Override
public void portStatusChanged(DeviceId deviceId,
PortDescription portDescription) {
log.info("portStatusChanged({}, {}) on Server called", deviceId, portDescription);
portStatusChangedDid = deviceId;
portStatusChangedDesc = portDescription;
portStatusChanged.countDown();
}
final CountDownLatch updatePortStatistics = new CountDownLatch(1);
DeviceId updatePortStatisticsDid;
Collection<PortStatistics> updatePortStatisticsStats;
@Override
public void updatePortStatistics(DeviceId deviceId,
Collection<PortStatistics> portStatistics) {
log.info("updatePortStatistics({}, {}) on Server called", deviceId, portStatistics);
updatePortStatisticsDid = deviceId;
updatePortStatisticsStats = portStatistics;
updatePortStatistics.countDown();
}
final CountDownLatch deviceDisconnected = new CountDownLatch(1);
DeviceId deviceDisconnectedDid;
@Override
public void deviceDisconnected(DeviceId deviceId) {
log.info("deviceDisconnected({}) on Server called", deviceId);
deviceDisconnectedDid = deviceId;
deviceDisconnected.countDown();
}
}
public class ServerSideLinkProviderRegistry
extends AbstractProviderRegistry<LinkProvider, LinkProviderService>
implements LinkProviderRegistry {
@Override
protected LinkProviderService createProviderService(LinkProvider provider) {
svLinkProviderService = new ServerSideLinkProviderService(provider);
return svLinkProviderService;
}
}
public class ServerSideLinkProviderService
extends AbstractProviderService<LinkProvider>
implements LinkProviderService {
CountDownLatch calls = new CountDownLatch(1);
Object arg = null;
public void reset() {
calls = new CountDownLatch(1);
arg = null;
}
public ServerSideLinkProviderService(LinkProvider provider) {
super(provider);
}
@Override
public void linksVanished(DeviceId deviceId) {
log.info("linksVanished({})", deviceId);
arg = deviceId;
calls.countDown();
}
@Override
public void linksVanished(ConnectPoint connectPoint) {
log.info("linksVanished({})", connectPoint);
arg = connectPoint;
calls.countDown();
}
@Override
public void linkVanished(LinkDescription linkDescription) {
log.info("linksVanished({})", linkDescription);
arg = linkDescription;
calls.countDown();
}
@Override
public void linkDetected(LinkDescription linkDescription) {
log.info("linkDetected({})", linkDescription);
arg = linkDescription;
calls.countDown();
}
}
}