blob: 7d504d31a7151e1d39c9275a24cfdee627841234 [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;
Jian Li27841662018-04-14 01:59:47 +090036import org.onosproject.openstacknode.impl.DefaultOpenstackAuth;
Jian Li5a38ab62018-07-02 22:34:11 +090037import org.onosproject.openstacknode.api.DefaultOpenstackNode;
Jian Lie6312162018-03-21 21:41:00 +090038import org.onosproject.openstacknode.impl.DefaultOpenstackPhyInterface;
Jian Li5b402c72018-02-27 14:27:34 +090039
40import java.io.IOException;
41import java.io.InputStream;
42import java.util.HashMap;
43import java.util.Map;
44
45import static org.easymock.EasyMock.createMock;
46import static org.easymock.EasyMock.expect;
47import static org.easymock.EasyMock.replay;
48import static org.hamcrest.MatcherAssert.assertThat;
49import static org.hamcrest.Matchers.is;
50import static org.hamcrest.Matchers.notNullValue;
51import static org.onosproject.net.NetTestTools.APP_ID;
52import static org.onosproject.openstacknode.codec.OpenstackNodeJsonMatcher.matchesOpenstackNode;
53
54/**
55 * Unit tests for OpenstackNode codec.
56 */
57public class OpenstackNodeCodecTest {
58 MockCodecContext context;
59 JsonCodec<OpenstackNode> openstackNodeCodec;
Jian Lie6312162018-03-21 21:41:00 +090060 JsonCodec<OpenstackPhyInterface> openstackPhyIntfJsonCodec;
Jian Li789fadb2018-07-10 13:59:47 +090061 JsonCodec<ControllerInfo> openstackControllerJsonCodec;
Jian Li27841662018-04-14 01:59:47 +090062 JsonCodec<OpenstackAuth> openstackAuthJsonCodec;
Jian Li5b402c72018-02-27 14:27:34 +090063 final CoreService mockCoreService = createMock(CoreService.class);
64 private static final String REST_APP_ID = "org.onosproject.rest";
65
66 @Before
67 public void setUp() {
68 context = new MockCodecContext();
69 openstackNodeCodec = new OpenstackNodeCodec();
Jian Lie6312162018-03-21 21:41:00 +090070 openstackPhyIntfJsonCodec = new OpenstackPhyInterfaceCodec();
Jian Li789fadb2018-07-10 13:59:47 +090071 openstackControllerJsonCodec = new OpenstackControllerCodec();
Jian Li27841662018-04-14 01:59:47 +090072 openstackAuthJsonCodec = new OpenstackAuthCodec();
Jian Lie6312162018-03-21 21:41:00 +090073
Jian Li5b402c72018-02-27 14:27:34 +090074 assertThat(openstackNodeCodec, notNullValue());
Jian Lie6312162018-03-21 21:41:00 +090075 assertThat(openstackPhyIntfJsonCodec, notNullValue());
Jian Li789fadb2018-07-10 13:59:47 +090076 assertThat(openstackControllerJsonCodec, notNullValue());
Jian Li27841662018-04-14 01:59:47 +090077 assertThat(openstackAuthJsonCodec, notNullValue());
Jian Li5b402c72018-02-27 14:27:34 +090078
79 expect(mockCoreService.registerApplication(REST_APP_ID))
80 .andReturn(APP_ID).anyTimes();
81 replay(mockCoreService);
82 context.registerService(CoreService.class, mockCoreService);
83 }
84
Jian Li27841662018-04-14 01:59:47 +090085 /**
86 * Tests the openstack compute node encoding.
87 */
Jian Li5b402c72018-02-27 14:27:34 +090088 @Test
Jian Li27841662018-04-14 01:59:47 +090089 public void testOpenstackComputeNodeEncode() {
Jian Lie6312162018-03-21 21:41:00 +090090
91 OpenstackPhyInterface phyIntf1 = DefaultOpenstackPhyInterface.builder()
92 .network("mgmtnetwork")
93 .intf("eth3")
94 .build();
95 OpenstackPhyInterface phyIntf2 = DefaultOpenstackPhyInterface.builder()
96 .network("oamnetwork")
97 .intf("eth4")
98 .build();
99
Jian Li789fadb2018-07-10 13:59:47 +0900100 ControllerInfo controller1 =
101 new ControllerInfo(IpAddress.valueOf("10.10.10.2"), 6653, "tcp");
102 ControllerInfo controller2 =
103 new ControllerInfo(IpAddress.valueOf("10.10.10.3"), 6663, "tcp");
104
Jian Li5b402c72018-02-27 14:27:34 +0900105 OpenstackNode node = DefaultOpenstackNode.builder()
106 .hostname("compute")
107 .type(OpenstackNode.NodeType.COMPUTE)
108 .state(NodeState.INIT)
109 .managementIp(IpAddress.valueOf("10.10.10.1"))
110 .intgBridge(DeviceId.deviceId("br-int"))
111 .vlanIntf("vxlan")
112 .dataIp(IpAddress.valueOf("20.20.20.2"))
Jian Lie6312162018-03-21 21:41:00 +0900113 .phyIntfs(ImmutableList.of(phyIntf1, phyIntf2))
Jian Li789fadb2018-07-10 13:59:47 +0900114 .controllers(ImmutableList.of(controller1, controller2))
Jian Li5b402c72018-02-27 14:27:34 +0900115 .build();
116
117 ObjectNode nodeJson = openstackNodeCodec.encode(node, context);
118 assertThat(nodeJson, matchesOpenstackNode(node));
119 }
120
Jian Li27841662018-04-14 01:59:47 +0900121 /**
122 * Tests the openstack compute node decoding.
123 *
124 * @throws IOException
125 */
Jian Li5b402c72018-02-27 14:27:34 +0900126 @Test
Jian Li27841662018-04-14 01:59:47 +0900127 public void testOpenstackComputeNodeDecode() throws IOException {
128 OpenstackNode node = getOpenstackNode("OpenstackComputeNode.json");
Jian Li5b402c72018-02-27 14:27:34 +0900129
130 assertThat(node.hostname(), is("compute-01"));
131 assertThat(node.type().name(), is("COMPUTE"));
132 assertThat(node.managementIp().toString(), is("172.16.130.4"));
133 assertThat(node.dataIp().toString(), is("172.16.130.4"));
134 assertThat(node.intgBridge().toString(), is("of:00000000000000a1"));
135 assertThat(node.vlanIntf(), is("eth2"));
Jian Lie6312162018-03-21 21:41:00 +0900136 assertThat(node.phyIntfs().size(), is(2));
Jian Li789fadb2018-07-10 13:59:47 +0900137 assertThat(node.controllers().size(), is(2));
Jian Lie6312162018-03-21 21:41:00 +0900138
139 node.phyIntfs().forEach(intf -> {
140 if (intf.network().equals("mgmtnetwork")) {
141 assertThat(intf.intf(), is("eth3"));
142 }
143 if (intf.network().equals("oamnetwork")) {
144 assertThat(intf.intf(), is("eth4"));
145 }
146 });
Jian Li789fadb2018-07-10 13:59:47 +0900147
148 node.controllers().forEach(ctrl -> {
149 if (ctrl.ip().toString().equals("10.10.10.2")) {
150 assertThat(ctrl.port(), is(6653));
151 }
152 if (ctrl.ip().toString().equals("10.10.10.3")) {
153 assertThat(ctrl.port(), is(6663));
154 }
155 });
Jian Li5b402c72018-02-27 14:27:34 +0900156 }
157
158 /**
Jian Li27841662018-04-14 01:59:47 +0900159 * Tests the openstack controller node encoding.
160 */
161 @Test
162 public void testOpenstackControllerNodeEncode() {
163 OpenstackAuth auth = DefaultOpenstackAuth.builder()
164 .version("v2.0")
165 .port(35357)
166 .protocol(OpenstackAuth.Protocol.HTTP)
167 .project("admin")
168 .username("admin")
169 .password("nova")
170 .perspective(OpenstackAuth.Perspective.PUBLIC)
171 .build();
172
173 OpenstackNode node = DefaultOpenstackNode.builder()
174 .hostname("controller")
175 .type(OpenstackNode.NodeType.CONTROLLER)
176 .state(NodeState.INIT)
177 .managementIp(IpAddress.valueOf("172.16.130.10"))
Jian Li92d42fc2018-05-25 16:23:49 +0900178 .endPoint("keystone-end-point-url")
Jian Li27841662018-04-14 01:59:47 +0900179 .authentication(auth)
180 .build();
181
182 ObjectNode nodeJson = openstackNodeCodec.encode(node, context);
183 assertThat(nodeJson, matchesOpenstackNode(node));
184 }
185
186 /**
187 * Tests the openstack controller node decoding.
188 */
189 @Test
190 public void testOpenstackControllerNodeDecode() throws IOException {
191 OpenstackNode node = getOpenstackNode("OpenstackControllerNode.json");
192
193 assertThat(node.hostname(), is("controller"));
194 assertThat(node.type().name(), is("CONTROLLER"));
195 assertThat(node.managementIp().toString(), is("172.16.130.10"));
Jian Li92d42fc2018-05-25 16:23:49 +0900196 assertThat(node.endPoint(), is("keystone-end-point-url"));
Jian Li27841662018-04-14 01:59:47 +0900197
198 OpenstackAuth auth = node.authentication();
199
200 assertThat(auth.version(), is("v2.0"));
201 assertThat(auth.port(), is(35357));
202 assertThat(auth.protocol(), is(OpenstackAuth.Protocol.HTTP));
203 assertThat(auth.username(), is("admin"));
204 assertThat(auth.password(), is("nova"));
205 assertThat(auth.project(), is("admin"));
206 assertThat(auth.perspective(), is(OpenstackAuth.Perspective.PUBLIC));
207 }
208
209 /**
Jian Li5b402c72018-02-27 14:27:34 +0900210 * Reads in an openstack node from the given resource and decodes it.
211 *
212 * @param resourceName resource to use to read the JSON for the rule
213 * @return decoded openstack node
214 * @throws IOException if processing the resource fails
215 */
216 private OpenstackNode getOpenstackNode(String resourceName) throws IOException {
217 InputStream jsonStream = OpenstackNodeCodecTest.class.getResourceAsStream(resourceName);
218 JsonNode json = context.mapper().readTree(jsonStream);
219 MatcherAssert.assertThat(json, notNullValue());
220 OpenstackNode node = openstackNodeCodec.decode((ObjectNode) json, context);
221 assertThat(node, notNullValue());
222 return node;
223 }
224
225 /**
226 * Mock codec context for use in codec unit tests.
227 */
228 private class MockCodecContext implements CodecContext {
229 private final ObjectMapper mapper = new ObjectMapper();
230 private final CodecManager manager = new CodecManager();
231 private final Map<Class<?>, Object> services = new HashMap<>();
232
233 /**
234 * Constructs a new mock codec context.
235 */
236 public MockCodecContext() {
237 manager.activate();
238 }
239
240 @Override
241 public ObjectMapper mapper() {
242 return mapper;
243 }
244
245 @Override
246 @SuppressWarnings("unchecked")
247 public <T> JsonCodec<T> codec(Class<T> entityClass) {
Jian Lie6312162018-03-21 21:41:00 +0900248 if (entityClass == OpenstackPhyInterface.class) {
249 return (JsonCodec<T>) openstackPhyIntfJsonCodec;
250 }
Jian Li789fadb2018-07-10 13:59:47 +0900251 if (entityClass == ControllerInfo.class) {
252 return (JsonCodec<T>) openstackControllerJsonCodec;
253 }
Jian Li27841662018-04-14 01:59:47 +0900254 if (entityClass == OpenstackAuth.class) {
255 return (JsonCodec<T>) openstackAuthJsonCodec;
256 }
Jian Li5b402c72018-02-27 14:27:34 +0900257 return manager.getCodec(entityClass);
258 }
259
260 @SuppressWarnings("unchecked")
261 @Override
262 public <T> T getService(Class<T> serviceClass) {
263 return (T) services.get(serviceClass);
264 }
265
266 // for registering mock services
267 public <T> void registerService(Class<T> serviceClass, T impl) {
268 services.put(serviceClass, impl);
269 }
270 }
271}