Added unit tests for OpenstackNode

Change-Id: I4e852145c945cd11586b39e06972fcba23942660
This commit is contained in:
Hyunsun Moon 2017-07-05 17:48:37 +09:00 committed by Thomas Vachuska
parent a946564b2b
commit 090d77d7c1
7 changed files with 1644 additions and 19 deletions

View File

@ -7,8 +7,15 @@ COMPILE_DEPS = [
'//core/store/serializers:onos-core-serializers',
]
TEST_DEPS = [
'//lib:TEST_ADAPTERS',
'//core/api:onos-api-tests',
'//core/common:onos-core-common-tests',
]
osgi_jar_with_tests (
deps = COMPILE_DEPS,
test_deps = TEST_DEPS,
)
onos_app (

View File

@ -41,7 +41,7 @@ import static org.onosproject.openstacknode.api.Constants.PATCH_INTG_BRIDGE;
/**
* Representation of a openstack node.
*/
public final class DefaultOpenstackNode implements OpenstackNode {
public class DefaultOpenstackNode implements OpenstackNode {
private final String hostname;
private final NodeType type;
@ -52,7 +52,7 @@ public final class DefaultOpenstackNode implements OpenstackNode {
private final String vlanIntf;
private final NodeState state;
private DefaultOpenstackNode(String hostname,
protected DefaultOpenstackNode(String hostname,
NodeType type,
DeviceId intgBridge,
DeviceId routerBridge,
@ -254,6 +254,7 @@ public final class DefaultOpenstackNode implements OpenstackNode {
public static Builder from(OpenstackNode osNode) {
return new Builder()
.hostname(osNode.hostname())
.type(osNode.type())
.intgBridge(osNode.intgBridge())
.routerBridge(osNode.routerBridge())
.managementIp(osNode.managementIp())

View File

@ -34,7 +34,6 @@ import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.GroupId;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
@ -492,7 +491,7 @@ public class DefaultOpenstackNodeHandler implements OpenstackNodeHandler {
!device.is(BridgeConfig.class)) {
return false;
}
BridgeConfig bridgeConfig = device.as(BridgeConfig.class);
BridgeConfig bridgeConfig = device.as(BridgeConfig.class);
return bridgeConfig.getBridges().stream()
.anyMatch(bridge -> bridge.name().equals(bridgeName));
}
@ -742,22 +741,17 @@ public class DefaultOpenstackNodeHandler implements OpenstackNodeHandler {
public void event(GroupEvent event) {
switch (event.type()) {
case GROUP_ADDED:
log.trace("Group added, ID:{} state:{}", event.subject().id(),
event.subject().state());
eventExecutor.execute(() -> {
OpenstackNode osNode = osNodeByGroupId(event.subject().id());
if (osNode != null && osNode.state() == PORT_CREATED) {
setState(osNode, COMPLETE);
}
log.trace("Group added, ID:{} state:{}", event.subject().id(),
event.subject().state());
processGroup(event.subject());
});
break;
case GROUP_UPDATED:
log.trace("Group updated, ID:{} state:{}", event.subject().id(),
event.subject().state());
eventExecutor.execute(() -> {
osNodeService.nodes(GATEWAY).stream()
.filter(osNode -> osNode.state() == PORT_CREATED)
.forEach(osNode -> bootstrapNode(osNode));
log.trace("Group updated, ID:{} state:{}", event.subject().id(),
event.subject().state());
processGroup(event.subject());
});
break;
case GROUP_REMOVED:
@ -768,11 +762,17 @@ public class DefaultOpenstackNodeHandler implements OpenstackNodeHandler {
}
}
private OpenstackNode osNodeByGroupId(GroupId groupId) {
return osNodeService.nodes().stream()
.filter(n -> n.gatewayGroupId(VXLAN).equals(groupId) ||
n.gatewayGroupId(VLAN).equals(groupId))
private void processGroup(Group group) {
OpenstackNode osNode = osNodeService.nodes().stream()
.filter(n -> n.gatewayGroupId(VXLAN).equals(group.id()) ||
n.gatewayGroupId(VLAN).equals(group.id()))
.findAny().orElse(null);
if (osNode != null && osNode.state() == PORT_CREATED) {
bootstrapNode(osNode);
}
osNodeService.nodes(GATEWAY).stream()
.filter(gNode -> gNode.state() == PORT_CREATED)
.forEach(DefaultOpenstackNodeHandler.this::bootstrapNode);
}
}

View File

@ -0,0 +1,152 @@
/*
* Copyright 2017-present 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.openstacknode.impl;
import com.google.common.testing.EqualsTester;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.net.Device;
import org.onosproject.openstacknode.api.NodeState;
import org.onosproject.openstacknode.api.OpenstackNode;
/**
* Unit tests for DefaultOpenstackNode.
*/
public class DefaultOpenstackNodeTest extends OpenstackNodeTest {
private static final IpAddress TEST_IP = IpAddress.valueOf("10.100.0.3");
private static final String HOSTNAME_1 = "hostname_1";
private static final String HOSTNAME_2 = "hostname_2";
private static final Device DEVICE_1 = createDevice(1);
private static final Device DEVICE_2 = createDevice(2);
private static final OpenstackNode OS_NODE_1 = createNode(
HOSTNAME_1,
OpenstackNode.NodeType.COMPUTE,
DEVICE_1,
TEST_IP,
NodeState.INIT);
private static final OpenstackNode OS_NODE_2 = createNode(
HOSTNAME_1,
OpenstackNode.NodeType.COMPUTE,
DEVICE_1,
TEST_IP,
NodeState.COMPLETE);
private static final OpenstackNode OS_NODE_3 = createNode(
HOSTNAME_2,
OpenstackNode.NodeType.COMPUTE,
DEVICE_2,
TEST_IP,
NodeState.INIT);
/**
* Checks equals method works as expected.
*/
@Test
public void testEquality() {
new EqualsTester().addEqualityGroup(OS_NODE_1, OS_NODE_2)
.addEqualityGroup(OS_NODE_3)
.testEquals();
}
/**
* Checks building a node without hostname fails with proper exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testBuildWithoutHostname() {
DefaultOpenstackNode.builder()
.type(OpenstackNode.NodeType.COMPUTE)
.intgBridge(DEVICE_1.id())
.managementIp(TEST_IP)
.dataIp(TEST_IP)
.state(NodeState.INIT)
.build();
}
/**
* Checks building a node without type fails with proper exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testBuildWithoutType() {
DefaultOpenstackNode.builder()
.hostname(HOSTNAME_1)
.intgBridge(DEVICE_1.id())
.managementIp(TEST_IP)
.dataIp(TEST_IP)
.state(NodeState.INIT)
.build();
}
/**
* Checks building a node without integration bridge ID fails with
* proper exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testBuildWithoutIntegrationBridgeId() {
DefaultOpenstackNode.builder()
.hostname(HOSTNAME_1)
.type(OpenstackNode.NodeType.COMPUTE)
.managementIp(TEST_IP)
.dataIp(TEST_IP)
.state(NodeState.INIT)
.build();
}
/**
* Checks building a node without management IP address fails with
* proper exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testBuildWithoutManagementIp() {
DefaultOpenstackNode.builder()
.hostname(HOSTNAME_1)
.type(OpenstackNode.NodeType.COMPUTE)
.intgBridge(DEVICE_1.id())
.dataIp(TEST_IP)
.state(NodeState.INIT)
.build();
}
/**
* Checks building a node without data IP nor VLAN interface name
* fails with proper exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testBuildWithoutDataIpNorVlanIntf() {
DefaultOpenstackNode.builder()
.hostname(HOSTNAME_1)
.type(OpenstackNode.NodeType.COMPUTE)
.intgBridge(DEVICE_1.id())
.state(NodeState.INIT)
.build();
}
/**
* Checks building a gateway type node without router bridge ID
* fails with proper exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testGatewayWithoutRouterBridgeId() {
DefaultOpenstackNode.builder()
.hostname(HOSTNAME_1)
.type(OpenstackNode.NodeType.GATEWAY)
.intgBridge(DEVICE_1.id())
.managementIp(TEST_IP)
.dataIp(TEST_IP)
.state(NodeState.INIT)
.build();
}
}

View File

@ -0,0 +1,331 @@
/*
* Copyright 2017-present 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.openstacknode.impl;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.MoreExecutors;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.packet.IpAddress;
import org.onosproject.cluster.ClusterServiceAdapter;
import org.onosproject.cluster.LeadershipServiceAdapter;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.event.Event;
import org.onosproject.net.Device;
import org.onosproject.net.config.NetworkConfigRegistryAdapter;
import org.onosproject.openstacknode.api.NodeState;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.store.service.TestStorageService;
import java.util.List;
import java.util.Objects;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
import static org.onosproject.openstacknode.api.OpenstackNodeEvent.Type.*;
/**
* Unit tests for OpenStack node manager.
*/
public class OpenstackNodeManagerTest extends OpenstackNodeTest {
private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");
private static final String ERR_SIZE = "Number of nodes did not match";
private static final String ERR_NOT_MATCH = "Node did not match";
private static final String ERR_NOT_FOUND = "Node did not exist";
private static final String COMPUTE_1_HOSTNAME = "compute_1";
private static final String COMPUTE_2_HOSTNAME = "compute_2";
private static final String COMPUTE_3_HOSTNAME = "compute_3";
private static final String GATEWAY_1_HOSTNAME = "gateway_1";
private static final Device COMPUTE_1_INTG_DEVICE = createDevice(1);
private static final Device COMPUTE_2_INTG_DEVICE = createDevice(2);
private static final Device COMPUTE_3_INTG_DEVICE = createDevice(3);
private static final Device GATEWAY_1_INTG_DEVICE = createDevice(4);
private static final Device GATEWAY_1_ROUT_DEVICE = createDevice(5);
private static final OpenstackNode COMPUTE_1 = createNode(
COMPUTE_1_HOSTNAME,
COMPUTE,
COMPUTE_1_INTG_DEVICE,
IpAddress.valueOf("10.100.0.1"),
NodeState.INIT
);
private static final OpenstackNode COMPUTE_2 = createNode(
COMPUTE_2_HOSTNAME,
COMPUTE,
COMPUTE_2_INTG_DEVICE,
IpAddress.valueOf("10.100.0.2"),
NodeState.INIT
);
private static final OpenstackNode COMPUTE_3 = createNode(
COMPUTE_3_HOSTNAME,
COMPUTE,
COMPUTE_3_INTG_DEVICE,
IpAddress.valueOf("10.100.0.3"),
NodeState.COMPLETE
);
private static final OpenstackNode GATEWAY_1 = createNode(
GATEWAY_1_HOSTNAME,
OpenstackNode.NodeType.GATEWAY,
GATEWAY_1_INTG_DEVICE,
GATEWAY_1_ROUT_DEVICE,
IpAddress.valueOf("10.100.0.4"),
NodeState.COMPLETE
);
private final TestOpenstackNodeListener testListener = new TestOpenstackNodeListener();
private OpenstackNodeManager target;
private DistributedOpenstackNodeStore osNodeStore;
@Before
public void setUp() {
osNodeStore = new DistributedOpenstackNodeStore();
TestUtils.setField(osNodeStore, "coreService", new TestCoreService());
TestUtils.setField(osNodeStore, "storageService", new TestStorageService());
TestUtils.setField(osNodeStore, "eventExecutor", MoreExecutors.newDirectExecutorService());
osNodeStore.activate();
osNodeStore.createNode(COMPUTE_2);
osNodeStore.createNode(COMPUTE_3);
osNodeStore.createNode(GATEWAY_1);
target = new OpenstackNodeManager();
target.coreService = new TestCoreService();
target.clusterService = new TestClusterService();
target.leadershipService = new TestLeadershipService();
target.configRegistry = new TestConfigService();
target.osNodeStore = osNodeStore;
target.addListener(testListener);
target.activate();
testListener.events.clear();
}
@After
public void tearDown() {
target.removeListener(testListener);
target.deactivate();
osNodeStore.deactivate();
osNodeStore = null;
target = null;
}
/**
* Checks if creating and removing a node work well with proper events.
*/
@Test
public void testCreateAndRemoveNode() {
target.createNode(COMPUTE_1);
assertEquals(ERR_SIZE, 4, target.nodes().size());
assertTrue(target.node(COMPUTE_1_HOSTNAME) != null);
target.removeNode(COMPUTE_1_HOSTNAME);
assertEquals(ERR_SIZE, 3, target.nodes().size());
assertTrue(target.node(COMPUTE_1_HOSTNAME) == null);
validateEvents(OPENSTACK_NODE_CREATED, OPENSTACK_NODE_REMOVED);
}
/**
* Checks if creating null node fails with proper exception.
*/
@Test(expected = NullPointerException.class)
public void testCreateNullNode() {
target.createNode(null);
}
/**
* Checks if creating a duplicated node fails with proper exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testCreateDuplicateNode() {
target.createNode(COMPUTE_1);
target.createNode(COMPUTE_1);
}
/**
* Checks if removing null node fails with proper exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testRemoveNullNode() {
target.removeNode(null);
}
/**
* Checks if updating a node works well with proper event.
*/
@Test
public void testUpdateNode() {
OpenstackNode updated = DefaultOpenstackNode.from(COMPUTE_2)
.dataIp(IpAddress.valueOf("10.200.0.100"))
.build();
target.updateNode(updated);
assertEquals(ERR_NOT_MATCH, updated, target.node(COMPUTE_2_INTG_DEVICE.id()));
validateEvents(OPENSTACK_NODE_UPDATED);
}
/**
* Checks if updating a node state to complete generates proper events.
*/
@Test
public void testUpdateNodeStateComplete() {
OpenstackNode updated = DefaultOpenstackNode.from(COMPUTE_2)
.state(NodeState.COMPLETE)
.build();
target.updateNode(updated);
assertEquals(ERR_NOT_MATCH, updated, target.node(COMPUTE_2_HOSTNAME));
validateEvents(OPENSTACK_NODE_UPDATED, OPENSTACK_NODE_COMPLETE);
}
/**
* Checks if updating a node state to incomplete generates proper events.
*/
@Test
public void testUpdateNodeStateIncomplete() {
OpenstackNode updated = DefaultOpenstackNode.from(COMPUTE_3)
.state(NodeState.INCOMPLETE)
.build();
target.updateNode(updated);
assertEquals(ERR_NOT_MATCH, updated, target.node(COMPUTE_3_HOSTNAME));
validateEvents(OPENSTACK_NODE_UPDATED, OPENSTACK_NODE_INCOMPLETE);
}
/**
* Checks if updating a null node fails with proper exception.
*/
@Test(expected = NullPointerException.class)
public void testUpdateNullNode() {
target.updateNode(null);
}
/**
* Checks if updating not existing node fails with proper exception.
*/
@Test(expected = IllegalArgumentException.class)
public void testUpdateNotExistingNode() {
target.updateNode(COMPUTE_1);
}
/**
* Checks if getting all nodes method returns correct set of nodes.
*/
@Test
public void testGetAllNodes() {
assertEquals(ERR_SIZE, 3, target.nodes().size());
assertTrue(ERR_NOT_FOUND, target.nodes().contains(COMPUTE_2));
assertTrue(ERR_NOT_FOUND, target.nodes().contains(COMPUTE_3));
assertTrue(ERR_NOT_FOUND, target.nodes().contains(GATEWAY_1));
}
/**
* Checks if getting complete nodes method returns correct set of nodes.
*/
@Test
public void testGetCompleteNodes() {
assertEquals(ERR_SIZE, 2, target.completeNodes().size());
assertTrue(ERR_NOT_FOUND, target.completeNodes().contains(COMPUTE_3));
assertTrue(ERR_NOT_FOUND, target.completeNodes().contains(GATEWAY_1));
}
/**
* Checks if getting nodes by type method returns correct set of nodes.
*/
@Test
public void testGetNodesByType() {
assertEquals(ERR_SIZE, 2, target.nodes(COMPUTE).size());
assertTrue(ERR_NOT_FOUND, target.nodes(COMPUTE).contains(COMPUTE_2));
assertTrue(ERR_NOT_FOUND, target.nodes(COMPUTE).contains(COMPUTE_3));
assertEquals(ERR_SIZE, 1, target.nodes(GATEWAY).size());
assertTrue(ERR_NOT_FOUND, target.nodes(GATEWAY).contains(GATEWAY_1));
}
/**
* Checks if getting a node by hostname returns correct node.
*/
@Test
public void testGetNodeByHostname() {
assertTrue(ERR_NOT_FOUND, Objects.equals(
target.node(COMPUTE_2_HOSTNAME), COMPUTE_2));
assertTrue(ERR_NOT_FOUND, Objects.equals(
target.node(COMPUTE_3_HOSTNAME), COMPUTE_3));
assertTrue(ERR_NOT_FOUND, Objects.equals(
target.node(GATEWAY_1_HOSTNAME), GATEWAY_1));
}
/**
* Checks if getting a node by device ID returns correct node.
*/
@Test
public void testGetNodeByDeviceId() {
assertTrue(ERR_NOT_FOUND, Objects.equals(
target.node(GATEWAY_1_INTG_DEVICE.id()), GATEWAY_1));
assertTrue(ERR_NOT_FOUND, Objects.equals(
target.node(GATEWAY_1.ovsdb()), GATEWAY_1));
assertTrue(ERR_NOT_FOUND, Objects.equals(
target.node(GATEWAY_1.routerBridge()), GATEWAY_1));
}
private void validateEvents(Enum... types) {
int i = 0;
assertEquals("Number of events did not match", types.length, testListener.events.size());
for (Event event : testListener.events) {
assertEquals("Incorrect event received", types[i], event.type());
i++;
}
testListener.events.clear();
}
private static class TestOpenstackNodeListener implements OpenstackNodeListener {
private List<OpenstackNodeEvent> events = Lists.newArrayList();
@Override
public void event(OpenstackNodeEvent event) {
events.add(event);
}
}
private static class TestCoreService extends CoreServiceAdapter {
@Override
public ApplicationId registerApplication(String name) {
return TEST_APP_ID;
}
}
private class TestConfigService extends NetworkConfigRegistryAdapter {
}
private class TestClusterService extends ClusterServiceAdapter {
}
private static class TestLeadershipService extends LeadershipServiceAdapter {
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 2017-present 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.openstacknode.impl;
import org.onlab.packet.ChassisId;
import org.onlab.packet.IpAddress;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.openstacknode.api.NodeState;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNode.NodeType;
import static org.onosproject.net.Device.Type.SWITCH;
/**
* Provides a set of test OpenstackNode parameters for use with OpenstackNode related tests.
*/
abstract class OpenstackNodeTest {
protected static Device createDevice(long devIdNum) {
return new DefaultDevice(new ProviderId("of", "foo"),
DeviceId.deviceId(String.format("of:%016d", devIdNum)),
SWITCH,
"manufacturer",
"hwVersion",
"swVersion",
"serialNumber",
new ChassisId(1));
}
protected static OpenstackNode createNode(String hostname, NodeType type,
Device intgBridge, IpAddress ipAddr,
NodeState state) {
return DefaultOpenstackNode.builder()
.hostname(hostname)
.type(type)
.intgBridge(intgBridge.id())
.managementIp(ipAddr)
.dataIp(ipAddr)
.state(state)
.build();
}
protected static OpenstackNode createNode(String hostname, NodeType type,
Device intgBridge, Device routerBridge,
IpAddress ipAddr, NodeState state) {
return DefaultOpenstackNode.builder()
.hostname(hostname)
.type(type)
.intgBridge(intgBridge.id())
.routerBridge(routerBridge.id())
.managementIp(ipAddr)
.dataIp(ipAddr)
.state(state)
.build();
}
}