2 * Copyright (C) 2018 Bell Canada. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.onap.so.heatbridge;
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assert.assertNotNull;
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyString;
23 import static org.mockito.ArgumentMatchers.eq;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.times;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
30 import java.io.IOException;
31 import java.nio.charset.Charset;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collections;
35 import java.util.List;
36 import java.util.Objects;
37 import java.util.Optional;
39 import org.apache.commons.io.FileUtils;
40 import org.junit.Assert;
41 import org.junit.Before;
42 import org.junit.Ignore;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.mockito.ArgumentCaptor;
46 import org.mockito.Mock;
47 import org.mockito.junit.MockitoJUnitRunner;
48 import org.onap.aai.domain.yang.LInterface;
49 import org.onap.aai.domain.yang.PInterface;
50 import org.onap.aai.domain.yang.SriovPf;
51 import org.onap.aai.domain.yang.Vserver;
52 import org.onap.so.client.aai.AAIObjectType;
53 import org.onap.so.client.aai.AAIResourcesClient;
54 import org.onap.so.client.aai.AAISingleTransactionClient;
55 import org.onap.so.client.aai.entities.uri.AAIResourceUri;
56 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
57 import org.onap.so.client.graphinventory.exceptions.BulkProcessFailed;
58 import org.onap.so.db.catalog.beans.CloudIdentity;
59 import org.onap.so.heatbridge.constants.HeatBridgeConstants;
60 import org.onap.so.heatbridge.openstack.api.OpenstackClient;
61 import org.onap.so.heatbridge.openstack.api.OpenstackClientException;
62 import org.openstack4j.model.compute.Flavor;
63 import org.openstack4j.model.compute.Image;
64 import org.openstack4j.model.compute.Server;
65 import org.openstack4j.model.compute.Server.Status;
66 import org.openstack4j.model.heat.Resource;
67 import org.openstack4j.model.network.Network;
68 import org.openstack4j.model.network.NetworkType;
69 import org.openstack4j.model.network.Port;
70 import org.openstack4j.openstack.heat.domain.HeatResource;
71 import org.openstack4j.openstack.heat.domain.HeatResource.Resources;
73 import com.fasterxml.jackson.databind.ObjectMapper;
74 import com.google.common.collect.ImmutableMap;
77 @RunWith(MockitoJUnitRunner.class)
78 public class HeatBridgeImplTest {
80 private static final String CLOUD_OWNER = "CloudOwner";
81 private static final String REGION_ID = "RegionOne";
82 private static final String TENANT_ID = "7320ec4a5b9d4589ba7c4412ccfd290f";
83 private static final ObjectMapper MAPPER = new ObjectMapper();
86 private OpenstackClient osClient;
88 private CloudIdentity cloudIdentity = new CloudIdentity();
91 private AAIResourcesClient resourcesClient;
93 private AAISingleTransactionClient transaction;
95 private HeatBridgeImpl heatbridge;
98 public void setUp() throws HeatBridgeException, OpenstackClientException, BulkProcessFailed {
100 when(resourcesClient.beginSingleTransaction()).thenReturn(transaction);
101 heatbridge = new HeatBridgeImpl(resourcesClient, cloudIdentity, CLOUD_OWNER, REGION_ID, TENANT_ID);
106 public void testQueryNestedHeatStackResources() throws HeatBridgeException {
108 String heatStackId = "1234567";
109 List<Resource> expectedResourceList = (List<Resource>) extractTestStackResources();
110 when(osClient.getStackBasedResources(heatStackId, HeatBridgeConstants.OS_DEFAULT_HEAT_NESTING))
111 .thenReturn(expectedResourceList);
114 List<Resource> resourceList = heatbridge.queryNestedHeatStackResources(heatStackId);
117 verify(osClient).getStackBasedResources(heatStackId, HeatBridgeConstants.OS_DEFAULT_HEAT_NESTING);
118 assertEquals(resourceList, expectedResourceList);
122 public void testExtractStackResourceIdsByResourceType() throws HeatBridgeException {
124 List<Resource> expectedResourceList = (List<Resource>) extractTestStackResources();
125 List<String> expectedServerIds = Arrays.asList("43c2159b-2c04-46ac-bda5-594110cae2d3",
126 "7cff109a-b2b7-4933-97b4-ec44a8365568");
129 List<String> serverIds = heatbridge
130 .extractStackResourceIdsByResourceType(expectedResourceList, HeatBridgeConstants.OS_SERVER_RESOURCE_TYPE);
133 assertEquals(expectedServerIds, serverIds);
138 public void testGetAllOpenstackServers() {
140 List<Resource> stackResources = (List<Resource>) extractTestStackResources();
142 Server server1 = mock(Server.class);
143 Server server2 = mock(Server.class);
144 List<Server> expectedServers = Arrays.asList(server1, server2);
146 when(osClient.getServerById("43c2159b-2c04-46ac-bda5-594110cae2d3")).thenReturn(server1);
147 when(osClient.getServerById("7cff109a-b2b7-4933-97b4-ec44a8365568")).thenReturn(server2);
150 List<Server> servers = heatbridge.getAllOpenstackServers(stackResources);
153 assertEquals(expectedServers, servers);
158 public void testExtractOpenstackImagesFromServers() {
160 Server server1 = mock(Server.class);
161 Server server2 = mock(Server.class);
162 List<Server> servers = Arrays.asList(server1, server2);
164 Image image1 = mock(Image.class);
165 Image image2 = mock(Image.class);
166 when(image1.getId()).thenReturn("1");
167 when(image2.getId()).thenReturn("1");
168 List<Image> expectedDistinctImages = Collections.singletonList(image1);
170 when(server1.getImage()).thenReturn(image1);
171 when(server2.getImage()).thenReturn(image2);
174 List<Image> images = heatbridge.extractOpenstackImagesFromServers(servers);
177 assertEquals(expectedDistinctImages, images);
182 public void testExtractOpenstackFlavorsFromServers() {
184 Server server1 = mock(Server.class);
185 Server server2 = mock(Server.class);
186 List<Server> servers = Arrays.asList(server1, server2);
188 Flavor flavor1 = mock(Flavor.class);
189 Flavor flavor2 = mock(Flavor.class);
190 when(flavor1.getId()).thenReturn("1");
191 when(flavor2.getId()).thenReturn("2");
192 List<Flavor> expectedFlavors = Arrays.asList(flavor1, flavor2);
194 when(server1.getFlavor()).thenReturn(flavor1);
195 when(server2.getFlavor()).thenReturn(flavor2);
198 List<Flavor> flavors = heatbridge.extractOpenstackFlavorsFromServers(servers);
201 assertEquals(expectedFlavors, flavors);
205 public void testUpdateVserversToAai() throws HeatBridgeException {
207 Server server1 = mock(Server.class);
209 when(server1.getId()).thenReturn("test-server1-id");
210 when(server1.getHypervisorHostname()).thenReturn("test-hypervisor");
211 when(server1.getName()).thenReturn("test-server1-name");
212 when(server1.getStatus()).thenReturn(Status.ACTIVE);
213 when(server1.getLinks()).thenReturn(new ArrayList<>());
215 Server server2 = mock(Server.class);
216 when(server2.getId()).thenReturn("test-server2-id");
217 when(server2.getHypervisorHostname()).thenReturn("test-hypervisor");
218 when(server2.getName()).thenReturn("test-server2-name");
219 when(server2.getStatus()).thenReturn(Status.ACTIVE);
220 when(server2.getLinks()).thenReturn(new ArrayList<>());
222 List<Server> servers = Arrays.asList(server1, server2);
224 Image image = mock(Image.class);
225 when(server1.getImage()).thenReturn(image);
226 when(server2.getImage()).thenReturn(image);
227 when(image.getId()).thenReturn("test-image-id");
229 Flavor flavor = mock(Flavor.class);
230 when(server1.getFlavor()).thenReturn(flavor);
231 when(server2.getFlavor()).thenReturn(flavor);
232 when(flavor.getId()).thenReturn("test-flavor-id");
236 heatbridge.buildAddVserversToAaiAction("test-genericVnf-id", "test-vfModule-id", servers);
239 ArgumentCaptor<AAIResourceUri> captor = ArgumentCaptor.forClass(AAIResourceUri.class);
240 verify(transaction, times(2)).create(captor.capture(), any(Vserver.class));
242 List<AAIResourceUri> uris = captor.getAllValues();
243 assertEquals(AAIUriFactory.createResourceUri(
244 AAIObjectType.VSERVER, CLOUD_OWNER, REGION_ID, TENANT_ID, server1.getId()), uris.get(0));
245 assertEquals(AAIUriFactory.createResourceUri(
246 AAIObjectType.VSERVER, CLOUD_OWNER, REGION_ID, TENANT_ID, server2.getId()), uris.get(1));
251 public void testUpdateImagesToAai() throws HeatBridgeException {
253 Image image1 = mock(Image.class);
254 when(image1.getId()).thenReturn("test-image1-id");
255 when(image1.getName()).thenReturn("test-image1-name");
256 when(image1.getLinks()).thenReturn(new ArrayList<>());
258 Image image2 = mock(Image.class);
259 when(image2.getId()).thenReturn("test-image2-id");
260 when(image2.getName()).thenReturn("test-image2-name");
261 when(image2.getLinks()).thenReturn(new ArrayList<>());
263 List<Image> images = Arrays.asList(image1, image2);
266 heatbridge.buildAddImagesToAaiAction(images);
269 verify(transaction, times(2)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Image.class));
272 heatbridge.buildAddImagesToAaiAction(images);
275 verify(transaction, times(4)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Image.class));
279 public void testUpdateFlavorsToAai() throws HeatBridgeException {
281 Flavor flavor1 = mock(Flavor.class);
282 when(flavor1.getId()).thenReturn("test-flavor1-id");
283 when(flavor1.getName()).thenReturn("test-flavor1-name");
284 when(flavor1.getLinks()).thenReturn(new ArrayList<>());
286 Flavor flavor2 = mock(Flavor.class);
287 when(flavor2.getId()).thenReturn("test-flavor2-id");
288 when(flavor2.getName()).thenReturn("test-flavor2-name");
289 when(flavor2.getLinks()).thenReturn(new ArrayList<>());
291 List<Flavor> flavors = Arrays.asList(flavor1, flavor2);
294 heatbridge.buildAddFlavorsToAaiAction(flavors);
297 verify(transaction, times(2)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Flavor.class));
300 heatbridge.buildAddFlavorsToAaiAction(flavors);
303 verify(transaction, times(4)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Flavor.class));
308 public void testUpdateVserverLInterfacesToAai() throws HeatBridgeException {
310 List<Resource> stackResources = (List<Resource>) extractTestStackResources();
311 Port port = mock(Port.class);
312 when(port.getId()).thenReturn("test-port-id");
313 when(port.getName()).thenReturn("test-port-name");
314 when(port.getvNicType()).thenReturn(HeatBridgeConstants.OS_SRIOV_PORT_TYPE);
315 when(port.getMacAddress()).thenReturn("78:4f:43:68:e2:78");
316 when(port.getNetworkId()).thenReturn("890a203a-23gg-56jh-df67-731656a8f13a");
317 when(port.getDeviceId()).thenReturn("test-device-id");
318 when(port.getVifDetails())
319 .thenReturn(ImmutableMap.of(HeatBridgeConstants.OS_VLAN_NETWORK_KEY, "2345"));
320 String pfPciId = "0000:08:00.0";
321 when(port.getProfile()).thenReturn(ImmutableMap.of(HeatBridgeConstants.OS_PCI_SLOT_KEY, pfPciId,
322 HeatBridgeConstants.OS_PHYSICAL_NETWORK_KEY, "physical_network_id"));
324 Network network = mock(Network.class);
325 when(network.getId()).thenReturn("test-network-id");
326 when(network.getNetworkType()).thenReturn(NetworkType.VLAN);
327 when(network.getProviderSegID()).thenReturn("2345");
329 when(osClient.getPortById("212a203a-9764-4f42-84ea-731536a8f13a")).thenReturn(port);
330 when(osClient.getPortById("387e3904-8948-43d1-8635-b6c2042b54da")).thenReturn(port);
331 when(osClient.getPortById("70a09dfd-f1c5-4bc8-bd8f-dc539b8d662a")).thenReturn(port);
332 when(osClient.getPortById("12f88b4d-c8a4-4fbd-bcb4-7e36af02430b")).thenReturn(port);
333 when(osClient.getPortById("c54b9f45-b413-4937-bbe4-3c8a5689cfc9")).thenReturn(port);
334 when(osClient.getNetworkById(anyString())).thenReturn(network);
336 SriovPf sriovPf = new SriovPf();
337 sriovPf.setPfPciId(pfPciId);
338 PInterface pIf = mock(PInterface.class);
339 when(pIf.getInterfaceName()).thenReturn("test-port-id");
340 when(resourcesClient.get(eq(PInterface.class), any(AAIResourceUri.class))).thenReturn(Optional.of(pIf));
343 heatbridge.buildAddVserverLInterfacesToAaiAction(stackResources, Arrays.asList("1", "2"));
346 verify(transaction, times(5)).create(any(AAIResourceUri.class), any(LInterface.class));
347 verify(osClient, times(5)).getPortById(anyString());
348 verify(osClient, times(5)).getNetworkById(anyString());
351 private List<? extends Resource> extractTestStackResources() {
352 List<HeatResource> stackResources = null;
354 stackResources = MAPPER.readValue(readTestResourceFile("stack-resources.json"), Resources.class)
356 assertNotNull(stackResources);
357 assertFalse(stackResources.isEmpty());
358 } catch (IOException e) {
359 Assert.fail("Failed to extract test stack resources.");
361 return stackResources;
364 private String readTestResourceFile(String filePath) {
365 String content = null;
366 String pathname = Objects.requireNonNull(getClass().getClassLoader().getResource(filePath)).getFile();
367 File file = new File(pathname);
369 content = Objects.requireNonNull(FileUtils.readFileToString(file, Charset.defaultCharset()));
370 } catch (IOException e) {
371 Assert.fail(String.format("Failed to read test resource file (%s)", filePath));