blob: 49b67a5c9995c45e5d87d4950bf17af4bd486787 [file] [log] [blame]
Jian Li5b402c72018-02-27 14:27:34 +09001/*
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.openstacknode.codec;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.ObjectMapper;
20import com.fasterxml.jackson.databind.node.ObjectNode;
Jian Lie6312162018-03-21 21:41:00 +090021import com.google.common.collect.ImmutableList;
Jian Li5b402c72018-02-27 14:27:34 +090022import org.hamcrest.MatcherAssert;
23import org.junit.Before;
24import org.junit.Test;
25import org.onlab.packet.IpAddress;
26import org.onosproject.codec.CodecContext;
27import org.onosproject.codec.JsonCodec;
28import org.onosproject.codec.impl.CodecManager;
29import org.onosproject.core.CoreService;
30import org.onosproject.net.DeviceId;
Jian Li789fadb2018-07-10 13:59:47 +090031import org.onosproject.net.behaviour.ControllerInfo;
Jian Li5b402c72018-02-27 14:27:34 +090032import org.onosproject.openstacknode.api.NodeState;
Jian Li27841662018-04-14 01:59:47 +090033import org.onosproject.openstacknode.api.OpenstackAuth;
Jian Li5b402c72018-02-27 14:27:34 +090034import org.onosproject.openstacknode.api.OpenstackNode;
Jian Lie6312162018-03-21 21:41:00 +090035import org.onosproject.openstacknode.api.OpenstackPhyInterface;
Daniel Parkdeefa702018-07-17 17:55:51 +090036import org.onosproject.openstacknode.api.OpenstackSshAuth;
Daniel Park2ff66b42018-08-01 11:52:45 +090037import org.onosproject.openstacknode.api.DefaultOpenstackAuth;
Jian Li5a38ab62018-07-02 22:34:11 +090038import org.onosproject.openstacknode.api.DefaultOpenstackNode;
Jian Lie6312162018-03-21 21:41:00 +090039import org.onosproject.openstacknode.impl.DefaultOpenstackPhyInterface;
Daniel Parkdeefa702018-07-17 17:55:51 +090040import org.onosproject.openstacknode.impl.DefaultOpenstackSshAuth;
Jian Li5b402c72018-02-27 14:27:34 +090041
42import java.io.IOException;
43import java.io.InputStream;
44import java.util.HashMap;
45import java.util.Map;
46
47import static org.easymock.EasyMock.createMock;
48import static org.easymock.EasyMock.expect;
49import static org.easymock.EasyMock.replay;
50import static org.hamcrest.MatcherAssert.assertThat;
51import static org.hamcrest.Matchers.is;
52import static org.hamcrest.Matchers.notNullValue;
53import static org.onosproject.net.NetTestTools.APP_ID;
54import static org.onosproject.openstacknode.codec.OpenstackNodeJsonMatcher.matchesOpenstackNode;
55
56/**
57 * Unit tests for OpenstackNode codec.
58 */
59public class OpenstackNodeCodecTest {
60 MockCodecContext context;
61 JsonCodec<OpenstackNode> openstackNodeCodec;
Jian Lie6312162018-03-21 21:41:00 +090062 JsonCodec<OpenstackPhyInterface> openstackPhyIntfJsonCodec;
Jian Li789fadb2018-07-10 13:59:47 +090063 JsonCodec<ControllerInfo> openstackControllerJsonCodec;
Jian Li27841662018-04-14 01:59:47 +090064 JsonCodec<OpenstackAuth> openstackAuthJsonCodec;
Daniel Parkdeefa702018-07-17 17:55:51 +090065 JsonCodec<OpenstackSshAuth> openstackSshAuthJsonCodec;
66
Jian Li5b402c72018-02-27 14:27:34 +090067 final CoreService mockCoreService = createMock(CoreService.class);
68 private static final String REST_APP_ID = "org.onosproject.rest";
69
70 @Before
71 public void setUp() {
72 context = new MockCodecContext();
73 openstackNodeCodec = new OpenstackNodeCodec();
Jian Lie6312162018-03-21 21:41:00 +090074 openstackPhyIntfJsonCodec = new OpenstackPhyInterfaceCodec();
Jian Li789fadb2018-07-10 13:59:47 +090075 openstackControllerJsonCodec = new OpenstackControllerCodec();
Jian Li27841662018-04-14 01:59:47 +090076 openstackAuthJsonCodec = new OpenstackAuthCodec();
Daniel Parkdeefa702018-07-17 17:55:51 +090077 openstackSshAuthJsonCodec = new OpenstackSshAuthCodec();
Jian Lie6312162018-03-21 21:41:00 +090078
Jian Li5b402c72018-02-27 14:27:34 +090079 assertThat(openstackNodeCodec, notNullValue());
Jian Lie6312162018-03-21 21:41:00 +090080 assertThat(openstackPhyIntfJsonCodec, notNullValue());
Jian Li789fadb2018-07-10 13:59:47 +090081 assertThat(openstackControllerJsonCodec, notNullValue());
Jian Li27841662018-04-14 01:59:47 +090082 assertThat(openstackAuthJsonCodec, notNullValue());
Daniel Parkdeefa702018-07-17 17:55:51 +090083 assertThat(openstackSshAuthJsonCodec, notNullValue());
Jian Li5b402c72018-02-27 14:27:34 +090084
85 expect(mockCoreService.registerApplication(REST_APP_ID))
86 .andReturn(APP_ID).anyTimes();
87 replay(mockCoreService);
88 context.registerService(CoreService.class, mockCoreService);
89 }
90
Jian Li27841662018-04-14 01:59:47 +090091 /**
92 * Tests the openstack compute node encoding.
93 */
Jian Li5b402c72018-02-27 14:27:34 +090094 @Test
Jian Li27841662018-04-14 01:59:47 +090095 public void testOpenstackComputeNodeEncode() {
Jian Lie6312162018-03-21 21:41:00 +090096
97 OpenstackPhyInterface phyIntf1 = DefaultOpenstackPhyInterface.builder()
98 .network("mgmtnetwork")
99 .intf("eth3")
100 .build();
101 OpenstackPhyInterface phyIntf2 = DefaultOpenstackPhyInterface.builder()
102 .network("oamnetwork")
103 .intf("eth4")
104 .build();
105
Daniel Parkdeefa702018-07-17 17:55:51 +0900106 OpenstackSshAuth sshAuth = DefaultOpenstackSshAuth.builder()
107 .id("sdn")
108 .password("sdn")
109 .build();
110
Jian Li789fadb2018-07-10 13:59:47 +0900111 ControllerInfo controller1 =
112 new ControllerInfo(IpAddress.valueOf("10.10.10.2"), 6653, "tcp");
113 ControllerInfo controller2 =
114 new ControllerInfo(IpAddress.valueOf("10.10.10.3"), 6663, "tcp");
115
Jian Li5b402c72018-02-27 14:27:34 +0900116 OpenstackNode node = DefaultOpenstackNode.builder()
117 .hostname("compute")
118 .type(OpenstackNode.NodeType.COMPUTE)
119 .state(NodeState.INIT)
120 .managementIp(IpAddress.valueOf("10.10.10.1"))
121 .intgBridge(DeviceId.deviceId("br-int"))
122 .vlanIntf("vxlan")
123 .dataIp(IpAddress.valueOf("20.20.20.2"))
Jian Lie6312162018-03-21 21:41:00 +0900124 .phyIntfs(ImmutableList.of(phyIntf1, phyIntf2))
Jian Li789fadb2018-07-10 13:59:47 +0900125 .controllers(ImmutableList.of(controller1, controller2))
Daniel Parkdeefa702018-07-17 17:55:51 +0900126 .sshAuthInfo(sshAuth)
Jian Li5b402c72018-02-27 14:27:34 +0900127 .build();
128
129 ObjectNode nodeJson = openstackNodeCodec.encode(node, context);
130 assertThat(nodeJson, matchesOpenstackNode(node));
131 }
132
Jian Li27841662018-04-14 01:59:47 +0900133 /**
134 * Tests the openstack compute node decoding.
135 *
136 * @throws IOException
137 */
Jian Li5b402c72018-02-27 14:27:34 +0900138 @Test
Jian Li27841662018-04-14 01:59:47 +0900139 public void testOpenstackComputeNodeDecode() throws IOException {
140 OpenstackNode node = getOpenstackNode("OpenstackComputeNode.json");
Jian Li5b402c72018-02-27 14:27:34 +0900141
142 assertThat(node.hostname(), is("compute-01"));
143 assertThat(node.type().name(), is("COMPUTE"));
144 assertThat(node.managementIp().toString(), is("172.16.130.4"));
145 assertThat(node.dataIp().toString(), is("172.16.130.4"));
146 assertThat(node.intgBridge().toString(), is("of:00000000000000a1"));
147 assertThat(node.vlanIntf(), is("eth2"));
Jian Lie6312162018-03-21 21:41:00 +0900148 assertThat(node.phyIntfs().size(), is(2));
Jian Li789fadb2018-07-10 13:59:47 +0900149 assertThat(node.controllers().size(), is(2));
Daniel Parkdeefa702018-07-17 17:55:51 +0900150 assertThat(node.sshAuthInfo().id(), is("sdn"));
151 assertThat(node.sshAuthInfo().password(), is("sdn"));
Daniel Park92abf312018-08-08 17:01:35 +0900152 assertThat(node.datapathType(), is(OpenstackNode.DatapathType.NORMAL));
Jian Lie6312162018-03-21 21:41:00 +0900153
154 node.phyIntfs().forEach(intf -> {
155 if (intf.network().equals("mgmtnetwork")) {
156 assertThat(intf.intf(), is("eth3"));
157 }
158 if (intf.network().equals("oamnetwork")) {
159 assertThat(intf.intf(), is("eth4"));
160 }
161 });
Jian Li789fadb2018-07-10 13:59:47 +0900162
163 node.controllers().forEach(ctrl -> {
164 if (ctrl.ip().toString().equals("10.10.10.2")) {
165 assertThat(ctrl.port(), is(6653));
166 }
167 if (ctrl.ip().toString().equals("10.10.10.3")) {
168 assertThat(ctrl.port(), is(6663));
169 }
170 });
Daniel Park92abf312018-08-08 17:01:35 +0900171
172 OpenstackNode dpdkNode = getOpenstackNode("OpenstackDpdkComputeNode.json");
173
174 assertThat(dpdkNode.datapathType(), is(OpenstackNode.DatapathType.NETDEV));
Jian Li5b402c72018-02-27 14:27:34 +0900175 }
176
177 /**
Jian Li27841662018-04-14 01:59:47 +0900178 * Tests the openstack controller node encoding.
179 */
180 @Test
181 public void testOpenstackControllerNodeEncode() {
182 OpenstackAuth auth = DefaultOpenstackAuth.builder()
183 .version("v2.0")
Jian Li27841662018-04-14 01:59:47 +0900184 .protocol(OpenstackAuth.Protocol.HTTP)
185 .project("admin")
186 .username("admin")
187 .password("nova")
188 .perspective(OpenstackAuth.Perspective.PUBLIC)
189 .build();
190
191 OpenstackNode node = DefaultOpenstackNode.builder()
192 .hostname("controller")
193 .type(OpenstackNode.NodeType.CONTROLLER)
194 .state(NodeState.INIT)
195 .managementIp(IpAddress.valueOf("172.16.130.10"))
Jian Li6d410362018-08-17 09:41:08 +0900196 .endpoint("keystone-end-point-url")
Jian Li27841662018-04-14 01:59:47 +0900197 .authentication(auth)
198 .build();
199
200 ObjectNode nodeJson = openstackNodeCodec.encode(node, context);
201 assertThat(nodeJson, matchesOpenstackNode(node));
202 }
203
204 /**
205 * Tests the openstack controller node decoding.
206 */
207 @Test
208 public void testOpenstackControllerNodeDecode() throws IOException {
209 OpenstackNode node = getOpenstackNode("OpenstackControllerNode.json");
210
211 assertThat(node.hostname(), is("controller"));
212 assertThat(node.type().name(), is("CONTROLLER"));
213 assertThat(node.managementIp().toString(), is("172.16.130.10"));
Jian Li6d410362018-08-17 09:41:08 +0900214 assertThat(node.endpoint(), is("keystone-end-point-url"));
Jian Li27841662018-04-14 01:59:47 +0900215
216 OpenstackAuth auth = node.authentication();
217
218 assertThat(auth.version(), is("v2.0"));
Jian Li27841662018-04-14 01:59:47 +0900219 assertThat(auth.protocol(), is(OpenstackAuth.Protocol.HTTP));
220 assertThat(auth.username(), is("admin"));
221 assertThat(auth.password(), is("nova"));
222 assertThat(auth.project(), is("admin"));
223 assertThat(auth.perspective(), is(OpenstackAuth.Perspective.PUBLIC));
224 }
225
226 /**
Jian Li5b402c72018-02-27 14:27:34 +0900227 * Reads in an openstack node from the given resource and decodes it.
228 *
229 * @param resourceName resource to use to read the JSON for the rule
230 * @return decoded openstack node
231 * @throws IOException if processing the resource fails
232 */
233 private OpenstackNode getOpenstackNode(String resourceName) throws IOException {
234 InputStream jsonStream = OpenstackNodeCodecTest.class.getResourceAsStream(resourceName);
235 JsonNode json = context.mapper().readTree(jsonStream);
236 MatcherAssert.assertThat(json, notNullValue());
237 OpenstackNode node = openstackNodeCodec.decode((ObjectNode) json, context);
238 assertThat(node, notNullValue());
239 return node;
240 }
241
242 /**
243 * Mock codec context for use in codec unit tests.
244 */
245 private class MockCodecContext implements CodecContext {
246 private final ObjectMapper mapper = new ObjectMapper();
247 private final CodecManager manager = new CodecManager();
248 private final Map<Class<?>, Object> services = new HashMap<>();
249
250 /**
251 * Constructs a new mock codec context.
252 */
253 public MockCodecContext() {
254 manager.activate();
255 }
256
257 @Override
258 public ObjectMapper mapper() {
259 return mapper;
260 }
261
262 @Override
263 @SuppressWarnings("unchecked")
264 public <T> JsonCodec<T> codec(Class<T> entityClass) {
Jian Lie6312162018-03-21 21:41:00 +0900265 if (entityClass == OpenstackPhyInterface.class) {
266 return (JsonCodec<T>) openstackPhyIntfJsonCodec;
267 }
Jian Li789fadb2018-07-10 13:59:47 +0900268 if (entityClass == ControllerInfo.class) {
269 return (JsonCodec<T>) openstackControllerJsonCodec;
270 }
Jian Li27841662018-04-14 01:59:47 +0900271 if (entityClass == OpenstackAuth.class) {
272 return (JsonCodec<T>) openstackAuthJsonCodec;
273 }
Daniel Parkdeefa702018-07-17 17:55:51 +0900274 if (entityClass == OpenstackSshAuth.class) {
275 return (JsonCodec<T>) openstackSshAuthJsonCodec;
276 }
Jian Li5b402c72018-02-27 14:27:34 +0900277 return manager.getCodec(entityClass);
278 }
279
280 @SuppressWarnings("unchecked")
281 @Override
282 public <T> T getService(Class<T> serviceClass) {
283 return (T) services.get(serviceClass);
284 }
285
286 // for registering mock services
287 public <T> void registerService(Class<T> serviceClass, T impl) {
288 services.put(serviceClass, impl);
289 }
290 }
291}