blob: 4268d6c57f1b9c6522bebbaab2517b217dadb074 [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)
Daniel Park7e8c4d82018-08-13 23:47:49 +0900127 .socketDir("/var/lib/libvirt/qemu")
Jian Li5b402c72018-02-27 14:27:34 +0900128 .build();
129
130 ObjectNode nodeJson = openstackNodeCodec.encode(node, context);
131 assertThat(nodeJson, matchesOpenstackNode(node));
132 }
133
Jian Li27841662018-04-14 01:59:47 +0900134 /**
135 * Tests the openstack compute node decoding.
136 *
137 * @throws IOException
138 */
Jian Li5b402c72018-02-27 14:27:34 +0900139 @Test
Jian Li27841662018-04-14 01:59:47 +0900140 public void testOpenstackComputeNodeDecode() throws IOException {
141 OpenstackNode node = getOpenstackNode("OpenstackComputeNode.json");
Jian Li5b402c72018-02-27 14:27:34 +0900142
143 assertThat(node.hostname(), is("compute-01"));
144 assertThat(node.type().name(), is("COMPUTE"));
145 assertThat(node.managementIp().toString(), is("172.16.130.4"));
146 assertThat(node.dataIp().toString(), is("172.16.130.4"));
147 assertThat(node.intgBridge().toString(), is("of:00000000000000a1"));
148 assertThat(node.vlanIntf(), is("eth2"));
Jian Lie6312162018-03-21 21:41:00 +0900149 assertThat(node.phyIntfs().size(), is(2));
Jian Li789fadb2018-07-10 13:59:47 +0900150 assertThat(node.controllers().size(), is(2));
Daniel Parkdeefa702018-07-17 17:55:51 +0900151 assertThat(node.sshAuthInfo().id(), is("sdn"));
152 assertThat(node.sshAuthInfo().password(), is("sdn"));
Daniel Park92abf312018-08-08 17:01:35 +0900153 assertThat(node.datapathType(), is(OpenstackNode.DatapathType.NORMAL));
Daniel Park7e8c4d82018-08-13 23:47:49 +0900154 assertThat(node.socketDir(), is("/var/lib/libvirt/qemu"));
155
Jian Lie6312162018-03-21 21:41:00 +0900156
157 node.phyIntfs().forEach(intf -> {
158 if (intf.network().equals("mgmtnetwork")) {
159 assertThat(intf.intf(), is("eth3"));
160 }
161 if (intf.network().equals("oamnetwork")) {
162 assertThat(intf.intf(), is("eth4"));
163 }
164 });
Jian Li789fadb2018-07-10 13:59:47 +0900165
166 node.controllers().forEach(ctrl -> {
167 if (ctrl.ip().toString().equals("10.10.10.2")) {
168 assertThat(ctrl.port(), is(6653));
169 }
170 if (ctrl.ip().toString().equals("10.10.10.3")) {
171 assertThat(ctrl.port(), is(6663));
172 }
173 });
Daniel Park92abf312018-08-08 17:01:35 +0900174
175 OpenstackNode dpdkNode = getOpenstackNode("OpenstackDpdkComputeNode.json");
176
177 assertThat(dpdkNode.datapathType(), is(OpenstackNode.DatapathType.NETDEV));
Jian Li5b402c72018-02-27 14:27:34 +0900178 }
179
180 /**
Jian Li27841662018-04-14 01:59:47 +0900181 * Tests the openstack controller node encoding.
182 */
183 @Test
184 public void testOpenstackControllerNodeEncode() {
185 OpenstackAuth auth = DefaultOpenstackAuth.builder()
186 .version("v2.0")
Jian Li27841662018-04-14 01:59:47 +0900187 .protocol(OpenstackAuth.Protocol.HTTP)
188 .project("admin")
189 .username("admin")
190 .password("nova")
191 .perspective(OpenstackAuth.Perspective.PUBLIC)
192 .build();
193
194 OpenstackNode node = DefaultOpenstackNode.builder()
195 .hostname("controller")
196 .type(OpenstackNode.NodeType.CONTROLLER)
197 .state(NodeState.INIT)
198 .managementIp(IpAddress.valueOf("172.16.130.10"))
Jian Li6d410362018-08-17 09:41:08 +0900199 .endpoint("keystone-end-point-url")
Jian Li27841662018-04-14 01:59:47 +0900200 .authentication(auth)
201 .build();
202
203 ObjectNode nodeJson = openstackNodeCodec.encode(node, context);
204 assertThat(nodeJson, matchesOpenstackNode(node));
205 }
206
207 /**
208 * Tests the openstack controller node decoding.
209 */
210 @Test
211 public void testOpenstackControllerNodeDecode() throws IOException {
212 OpenstackNode node = getOpenstackNode("OpenstackControllerNode.json");
213
214 assertThat(node.hostname(), is("controller"));
215 assertThat(node.type().name(), is("CONTROLLER"));
216 assertThat(node.managementIp().toString(), is("172.16.130.10"));
Jian Li6d410362018-08-17 09:41:08 +0900217 assertThat(node.endpoint(), is("keystone-end-point-url"));
Jian Li27841662018-04-14 01:59:47 +0900218
219 OpenstackAuth auth = node.authentication();
220
221 assertThat(auth.version(), is("v2.0"));
Jian Li27841662018-04-14 01:59:47 +0900222 assertThat(auth.protocol(), is(OpenstackAuth.Protocol.HTTP));
223 assertThat(auth.username(), is("admin"));
224 assertThat(auth.password(), is("nova"));
225 assertThat(auth.project(), is("admin"));
226 assertThat(auth.perspective(), is(OpenstackAuth.Perspective.PUBLIC));
227 }
228
229 /**
Jian Li5b402c72018-02-27 14:27:34 +0900230 * Reads in an openstack node from the given resource and decodes it.
231 *
232 * @param resourceName resource to use to read the JSON for the rule
233 * @return decoded openstack node
234 * @throws IOException if processing the resource fails
235 */
236 private OpenstackNode getOpenstackNode(String resourceName) throws IOException {
237 InputStream jsonStream = OpenstackNodeCodecTest.class.getResourceAsStream(resourceName);
238 JsonNode json = context.mapper().readTree(jsonStream);
239 MatcherAssert.assertThat(json, notNullValue());
240 OpenstackNode node = openstackNodeCodec.decode((ObjectNode) json, context);
241 assertThat(node, notNullValue());
242 return node;
243 }
244
245 /**
246 * Mock codec context for use in codec unit tests.
247 */
248 private class MockCodecContext implements CodecContext {
249 private final ObjectMapper mapper = new ObjectMapper();
250 private final CodecManager manager = new CodecManager();
251 private final Map<Class<?>, Object> services = new HashMap<>();
252
253 /**
254 * Constructs a new mock codec context.
255 */
256 public MockCodecContext() {
257 manager.activate();
258 }
259
260 @Override
261 public ObjectMapper mapper() {
262 return mapper;
263 }
264
265 @Override
266 @SuppressWarnings("unchecked")
267 public <T> JsonCodec<T> codec(Class<T> entityClass) {
Jian Lie6312162018-03-21 21:41:00 +0900268 if (entityClass == OpenstackPhyInterface.class) {
269 return (JsonCodec<T>) openstackPhyIntfJsonCodec;
270 }
Jian Li789fadb2018-07-10 13:59:47 +0900271 if (entityClass == ControllerInfo.class) {
272 return (JsonCodec<T>) openstackControllerJsonCodec;
273 }
Jian Li27841662018-04-14 01:59:47 +0900274 if (entityClass == OpenstackAuth.class) {
275 return (JsonCodec<T>) openstackAuthJsonCodec;
276 }
Daniel Parkdeefa702018-07-17 17:55:51 +0900277 if (entityClass == OpenstackSshAuth.class) {
278 return (JsonCodec<T>) openstackSshAuthJsonCodec;
279 }
Jian Li5b402c72018-02-27 14:27:34 +0900280 return manager.getCodec(entityClass);
281 }
282
283 @SuppressWarnings("unchecked")
284 @Override
285 public <T> T getService(Class<T> serviceClass) {
286 return (T) services.get(serviceClass);
287 }
288
289 // for registering mock services
290 public <T> void registerService(Class<T> serviceClass, T impl) {
291 services.put(serviceClass, impl);
292 }
293 }
294}