2 * Copyright (C) 2018 Bell Canada. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5 * the License. You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11 * specific language governing permissions and limitations under the License.
13 package org.onap.so.heatbridge;
15 import static org.junit.Assert.assertEquals;
16 import static org.junit.Assert.assertFalse;
17 import static org.junit.Assert.assertNotNull;
18 import static org.mockito.ArgumentMatchers.any;
19 import static org.mockito.ArgumentMatchers.anyString;
20 import static org.mockito.ArgumentMatchers.eq;
21 import static org.mockito.Mockito.mock;
22 import static org.mockito.Mockito.times;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
26 import java.io.IOException;
27 import java.nio.charset.Charset;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collections;
31 import java.util.List;
32 import java.util.Objects;
33 import java.util.Optional;
34 import org.apache.commons.io.FileUtils;
35 import org.junit.Assert;
36 import org.junit.Before;
37 import org.junit.Ignore;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.mockito.ArgumentCaptor;
41 import org.mockito.Mock;
42 import org.mockito.junit.MockitoJUnitRunner;
43 import org.onap.aai.domain.yang.LInterface;
44 import org.onap.aai.domain.yang.PInterface;
45 import org.onap.aai.domain.yang.SriovPf;
46 import org.onap.aai.domain.yang.Vserver;
47 import org.onap.so.client.aai.AAIObjectType;
48 import org.onap.so.client.aai.AAIResourcesClient;
49 import org.onap.so.client.aai.AAISingleTransactionClient;
50 import org.onap.so.client.aai.entities.uri.AAIResourceUri;
51 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
52 import org.onap.so.client.graphinventory.exceptions.BulkProcessFailed;
53 import org.onap.so.db.catalog.beans.CloudIdentity;
54 import org.onap.so.heatbridge.constants.HeatBridgeConstants;
55 import org.onap.so.heatbridge.openstack.api.OpenstackClient;
56 import org.onap.so.heatbridge.openstack.api.OpenstackClientException;
57 import org.openstack4j.model.compute.Flavor;
58 import org.openstack4j.model.compute.Image;
59 import org.openstack4j.model.compute.Server;
60 import org.openstack4j.model.compute.Server.Status;
61 import org.openstack4j.model.heat.Resource;
62 import org.openstack4j.model.network.Network;
63 import org.openstack4j.model.network.NetworkType;
64 import org.openstack4j.model.network.Port;
65 import org.openstack4j.openstack.heat.domain.HeatResource;
66 import org.openstack4j.openstack.heat.domain.HeatResource.Resources;
67 import com.fasterxml.jackson.databind.ObjectMapper;
68 import com.google.common.collect.ImmutableMap;
71 @RunWith(MockitoJUnitRunner.class)
72 public class HeatBridgeImplTest {
74 private static final String CLOUD_OWNER = "CloudOwner";
75 private static final String REGION_ID = "RegionOne";
76 private static final String TENANT_ID = "7320ec4a5b9d4589ba7c4412ccfd290f";
77 private static final ObjectMapper MAPPER = new ObjectMapper();
80 private OpenstackClient osClient;
82 private CloudIdentity cloudIdentity = new CloudIdentity();
85 private AAIResourcesClient resourcesClient;
87 private AAISingleTransactionClient transaction;
89 private HeatBridgeImpl heatbridge;
92 public void setUp() throws HeatBridgeException, OpenstackClientException, BulkProcessFailed {
94 when(resourcesClient.beginSingleTransaction()).thenReturn(transaction);
95 heatbridge = new HeatBridgeImpl(resourcesClient, cloudIdentity, CLOUD_OWNER, REGION_ID, TENANT_ID);
100 public void testQueryNestedHeatStackResources() throws HeatBridgeException {
102 String heatStackId = "1234567";
103 List<Resource> expectedResourceList = (List<Resource>) extractTestStackResources();
104 when(osClient.getStackBasedResources(heatStackId, HeatBridgeConstants.OS_DEFAULT_HEAT_NESTING))
105 .thenReturn(expectedResourceList);
108 List<Resource> resourceList = heatbridge.queryNestedHeatStackResources(heatStackId);
111 verify(osClient).getStackBasedResources(heatStackId, HeatBridgeConstants.OS_DEFAULT_HEAT_NESTING);
112 assertEquals(resourceList, expectedResourceList);
116 public void testExtractStackResourceIdsByResourceType() throws HeatBridgeException {
118 List<Resource> expectedResourceList = (List<Resource>) extractTestStackResources();
119 List<String> expectedServerIds =
120 Arrays.asList("43c2159b-2c04-46ac-bda5-594110cae2d3", "7cff109a-b2b7-4933-97b4-ec44a8365568");
123 List<String> serverIds = heatbridge.extractStackResourceIdsByResourceType(expectedResourceList,
124 HeatBridgeConstants.OS_SERVER_RESOURCE_TYPE);
127 assertEquals(expectedServerIds, serverIds);
132 public void testGetAllOpenstackServers() {
134 List<Resource> stackResources = (List<Resource>) extractTestStackResources();
136 Server server1 = mock(Server.class);
137 Server server2 = mock(Server.class);
138 List<Server> expectedServers = Arrays.asList(server1, server2);
140 when(osClient.getServerById("43c2159b-2c04-46ac-bda5-594110cae2d3")).thenReturn(server1);
141 when(osClient.getServerById("7cff109a-b2b7-4933-97b4-ec44a8365568")).thenReturn(server2);
144 List<Server> servers = heatbridge.getAllOpenstackServers(stackResources);
147 assertEquals(expectedServers, servers);
152 public void testExtractOpenstackImagesFromServers() {
154 Server server1 = mock(Server.class);
155 Server server2 = mock(Server.class);
156 List<Server> servers = Arrays.asList(server1, server2);
158 Image image1 = mock(Image.class);
159 Image image2 = mock(Image.class);
160 when(image1.getId()).thenReturn("1");
161 when(image2.getId()).thenReturn("1");
162 List<Image> expectedDistinctImages = Collections.singletonList(image1);
164 when(server1.getImage()).thenReturn(image1);
165 when(server2.getImage()).thenReturn(image2);
168 List<Image> images = heatbridge.extractOpenstackImagesFromServers(servers);
171 assertEquals(expectedDistinctImages, images);
176 public void testExtractOpenstackFlavorsFromServers() {
178 Server server1 = mock(Server.class);
179 Server server2 = mock(Server.class);
180 List<Server> servers = Arrays.asList(server1, server2);
182 Flavor flavor1 = mock(Flavor.class);
183 Flavor flavor2 = mock(Flavor.class);
184 when(flavor1.getId()).thenReturn("1");
185 when(flavor2.getId()).thenReturn("2");
186 List<Flavor> expectedFlavors = Arrays.asList(flavor1, flavor2);
188 when(server1.getFlavor()).thenReturn(flavor1);
189 when(server2.getFlavor()).thenReturn(flavor2);
192 List<Flavor> flavors = heatbridge.extractOpenstackFlavorsFromServers(servers);
195 assertEquals(expectedFlavors, flavors);
199 public void testUpdateVserversToAai() throws HeatBridgeException {
201 Server server1 = mock(Server.class);
203 when(server1.getId()).thenReturn("test-server1-id");
204 when(server1.getHypervisorHostname()).thenReturn("test-hypervisor");
205 when(server1.getName()).thenReturn("test-server1-name");
206 when(server1.getStatus()).thenReturn(Status.ACTIVE);
207 when(server1.getLinks()).thenReturn(new ArrayList<>());
209 Server server2 = mock(Server.class);
210 when(server2.getId()).thenReturn("test-server2-id");
211 when(server2.getHypervisorHostname()).thenReturn("test-hypervisor");
212 when(server2.getName()).thenReturn("test-server2-name");
213 when(server2.getStatus()).thenReturn(Status.ACTIVE);
214 when(server2.getLinks()).thenReturn(new ArrayList<>());
216 List<Server> servers = Arrays.asList(server1, server2);
218 Image image = mock(Image.class);
219 when(server1.getImage()).thenReturn(image);
220 when(server2.getImage()).thenReturn(image);
221 when(image.getId()).thenReturn("test-image-id");
223 Flavor flavor = mock(Flavor.class);
224 when(server1.getFlavor()).thenReturn(flavor);
225 when(server2.getFlavor()).thenReturn(flavor);
226 when(flavor.getId()).thenReturn("test-flavor-id");
230 heatbridge.buildAddVserversToAaiAction("test-genericVnf-id", "test-vfModule-id", servers);
233 ArgumentCaptor<AAIResourceUri> captor = ArgumentCaptor.forClass(AAIResourceUri.class);
234 verify(transaction, times(2)).create(captor.capture(), any(Vserver.class));
236 List<AAIResourceUri> uris = captor.getAllValues();
237 assertEquals(AAIUriFactory.createResourceUri(AAIObjectType.VSERVER, CLOUD_OWNER, REGION_ID, TENANT_ID,
238 server1.getId()), uris.get(0));
239 assertEquals(AAIUriFactory.createResourceUri(AAIObjectType.VSERVER, CLOUD_OWNER, REGION_ID, TENANT_ID,
240 server2.getId()), uris.get(1));
245 public void testUpdateImagesToAai() throws HeatBridgeException {
247 Image image1 = mock(Image.class);
248 when(image1.getId()).thenReturn("test-image1-id");
249 when(image1.getName()).thenReturn("test-image1-name");
250 when(image1.getLinks()).thenReturn(new ArrayList<>());
252 Image image2 = mock(Image.class);
253 when(image2.getId()).thenReturn("test-image2-id");
254 when(image2.getName()).thenReturn("test-image2-name");
255 when(image2.getLinks()).thenReturn(new ArrayList<>());
257 List<Image> images = Arrays.asList(image1, image2);
260 heatbridge.buildAddImagesToAaiAction(images);
263 verify(transaction, times(2)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Image.class));
266 heatbridge.buildAddImagesToAaiAction(images);
269 verify(transaction, times(4)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Image.class));
273 public void testUpdateFlavorsToAai() throws HeatBridgeException {
275 Flavor flavor1 = mock(Flavor.class);
276 when(flavor1.getId()).thenReturn("test-flavor1-id");
277 when(flavor1.getName()).thenReturn("test-flavor1-name");
278 when(flavor1.getLinks()).thenReturn(new ArrayList<>());
280 Flavor flavor2 = mock(Flavor.class);
281 when(flavor2.getId()).thenReturn("test-flavor2-id");
282 when(flavor2.getName()).thenReturn("test-flavor2-name");
283 when(flavor2.getLinks()).thenReturn(new ArrayList<>());
285 List<Flavor> flavors = Arrays.asList(flavor1, flavor2);
288 heatbridge.buildAddFlavorsToAaiAction(flavors);
291 verify(transaction, times(2)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Flavor.class));
294 heatbridge.buildAddFlavorsToAaiAction(flavors);
297 verify(transaction, times(4)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Flavor.class));
302 public void testUpdateVserverLInterfacesToAai() throws HeatBridgeException {
304 List<Resource> stackResources = (List<Resource>) extractTestStackResources();
305 Port port = mock(Port.class);
306 when(port.getId()).thenReturn("test-port-id");
307 when(port.getName()).thenReturn("test-port-name");
308 when(port.getvNicType()).thenReturn(HeatBridgeConstants.OS_SRIOV_PORT_TYPE);
309 when(port.getMacAddress()).thenReturn("78:4f:43:68:e2:78");
310 when(port.getNetworkId()).thenReturn("890a203a-23gg-56jh-df67-731656a8f13a");
311 when(port.getDeviceId()).thenReturn("test-device-id");
312 when(port.getVifDetails()).thenReturn(ImmutableMap.of(HeatBridgeConstants.OS_VLAN_NETWORK_KEY, "2345"));
313 String pfPciId = "0000:08:00.0";
314 when(port.getProfile()).thenReturn(ImmutableMap.of(HeatBridgeConstants.OS_PCI_SLOT_KEY, pfPciId,
315 HeatBridgeConstants.OS_PHYSICAL_NETWORK_KEY, "physical_network_id"));
317 Network network = mock(Network.class);
318 when(network.getId()).thenReturn("test-network-id");
319 when(network.getNetworkType()).thenReturn(NetworkType.VLAN);
320 when(network.getProviderSegID()).thenReturn("2345");
322 when(osClient.getPortById("212a203a-9764-4f42-84ea-731536a8f13a")).thenReturn(port);
323 when(osClient.getPortById("387e3904-8948-43d1-8635-b6c2042b54da")).thenReturn(port);
324 when(osClient.getPortById("70a09dfd-f1c5-4bc8-bd8f-dc539b8d662a")).thenReturn(port);
325 when(osClient.getPortById("12f88b4d-c8a4-4fbd-bcb4-7e36af02430b")).thenReturn(port);
326 when(osClient.getPortById("c54b9f45-b413-4937-bbe4-3c8a5689cfc9")).thenReturn(port);
327 when(osClient.getNetworkById(anyString())).thenReturn(network);
329 SriovPf sriovPf = new SriovPf();
330 sriovPf.setPfPciId(pfPciId);
331 PInterface pIf = mock(PInterface.class);
332 when(pIf.getInterfaceName()).thenReturn("test-port-id");
333 when(resourcesClient.get(eq(PInterface.class), any(AAIResourceUri.class))).thenReturn(Optional.of(pIf));
336 heatbridge.buildAddVserverLInterfacesToAaiAction(stackResources, Arrays.asList("1", "2"));
339 verify(transaction, times(5)).create(any(AAIResourceUri.class), any(LInterface.class));
340 verify(osClient, times(5)).getPortById(anyString());
341 verify(osClient, times(5)).getNetworkById(anyString());
344 private List<? extends Resource> extractTestStackResources() {
345 List<HeatResource> stackResources = null;
347 stackResources = MAPPER.readValue(readTestResourceFile("stack-resources.json"), Resources.class).getList();
348 assertNotNull(stackResources);
349 assertFalse(stackResources.isEmpty());
350 } catch (IOException e) {
351 Assert.fail("Failed to extract test stack resources.");
353 return stackResources;
356 private String readTestResourceFile(String filePath) {
357 String content = null;
358 String pathname = Objects.requireNonNull(getClass().getClassLoader().getResource(filePath)).getFile();
359 File file = new File(pathname);
361 content = Objects.requireNonNull(FileUtils.readFileToString(file, Charset.defaultCharset()));
362 } catch (IOException e) {
363 Assert.fail(String.format("Failed to read test resource file (%s)", filePath));