2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.so.openstack.utils;
25 import static org.junit.Assert.assertEquals;
26 import static org.mockito.ArgumentMatchers.eq;
27 import static org.mockito.ArgumentMatchers.isA;
28 import static org.mockito.ArgumentMatchers.isNull;
29 import static org.mockito.Mockito.doNothing;
30 import static org.mockito.Mockito.doReturn;
31 import static org.mockito.Mockito.doThrow;
32 import static org.mockito.Mockito.times;
33 import java.io.IOException;
34 import java.util.ArrayList;
35 import java.util.List;
36 import org.junit.Before;
37 import org.junit.Rule;
38 import org.junit.Test;
39 import org.junit.rules.ExpectedException;
40 import org.junit.runner.RunWith;
41 import org.mockito.InjectMocks;
42 import org.mockito.Mock;
43 import org.mockito.Mockito;
44 import org.mockito.Spy;
45 import org.mockito.junit.MockitoJUnitRunner;
46 import org.onap.so.openstack.exceptions.MsoException;
47 import org.onap.so.openstack.exceptions.MsoOpenstackException;
48 import org.onap.so.openstack.exceptions.MsoStackAlreadyExists;
49 import org.springframework.core.env.Environment;
50 import com.woorea.openstack.base.client.OpenStackResponseException;
51 import com.woorea.openstack.heat.Heat;
52 import com.woorea.openstack.heat.StackResource;
53 import com.woorea.openstack.heat.StackResource.CreateStack;
54 import com.woorea.openstack.heat.StackResource.DeleteStack;
55 import com.woorea.openstack.heat.model.CreateStackParam;
56 import com.woorea.openstack.heat.model.Resource;
57 import com.woorea.openstack.heat.model.Resources;
58 import com.woorea.openstack.heat.model.Stack;
60 @RunWith(MockitoJUnitRunner.class)
61 public class MsoHeatUtilsTest extends MsoHeatUtils {
64 public ExpectedException exceptionRule = ExpectedException.none();
68 private MsoHeatUtils heatUtils;
71 private Heat heatClient;
74 private StackStatusHandler stackStatusHandler;
77 private Environment env;
80 private StackResource stackResource;
83 private NovaClientImpl novaClient;
86 private DeleteStack mockDeleteStack;
89 private Resources mockResources;
92 private CreateStack mockCreateStack;
94 private String cloudSiteId = "cloudSiteId";
95 private String tenantId = "tenantId";
99 doReturn("15").when(env).getProperty("org.onap.so.adapters.po.pollInterval", "15");
100 doReturn("1").when(env).getProperty("org.onap.so.adapters.po.pollMultiplier", "60");
104 public final void pollStackForStatus_Create_Complete_Test() throws MsoException, IOException {
105 Stack stack = new Stack();
107 stack.setStackName("stackName");
108 stack.setStackStatus("CREATE_IN_PROGRESS");
109 stack.setStackStatusReason("Stack Finished");
111 Stack latestStack = new Stack();
112 latestStack.setId("id");
113 latestStack.setStackName("stackName");
114 latestStack.setStackStatus("CREATE_COMPLETE");
115 latestStack.setStackStatusReason("Stack Finished");
116 doNothing().when(stackStatusHandler).updateStackStatus(stack);
117 doReturn(latestStack).when(heatUtils).queryHeatStack(isA(Heat.class), eq("stackName/id"));
118 doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
119 Stack actual = heatUtils.pollStackForStatus(1, stack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
120 Mockito.verify(stackStatusHandler, times(1)).updateStackStatus(stack);
121 Mockito.verify(heatUtils, times(1)).queryHeatStack(isA(Heat.class), eq("stackName/id"));
122 assertEquals(true, actual != null);
127 public final void pollStackForStatus_Polling_Exhausted_Test() throws MsoException, IOException {
128 Stack stack = new Stack();
130 stack.setStackName("stackName");
131 stack.setStackStatus("CREATE_IN_PROGRESS");
132 stack.setStackStatusReason("Stack Finished");
133 doNothing().when(stackStatusHandler).updateStackStatus(stack);
134 doReturn(stack).when(heatUtils).queryHeatStack(isA(Heat.class), eq("stackName/id"));
135 doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
136 Stack actual = heatUtils.pollStackForStatus(1, stack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
137 Mockito.verify(stackStatusHandler, times(1)).updateStackStatus(stack);
138 Mockito.verify(heatUtils, times(1)).queryHeatStack(isA(Heat.class), eq("stackName/id"));
139 assertEquals(true, actual != null);
143 public final void postProcessStackCreate_CREATE_IN_PROGRESS_Test() throws MsoException, IOException {
144 Stack stack = new Stack();
146 stack.setStackName("stackName");
147 stack.setStackStatus("CREATE_IN_PROGRESS");
148 stack.setStackStatusReason("Stack Finished");
149 CreateStackParam createStackParam = new CreateStackParam();
150 createStackParam.setStackName("stackName");
152 exceptionRule.expect(StackCreationException.class);
153 exceptionRule.expectMessage("Stack rollback suppressed, stack not deleted");
154 heatUtils.postProcessStackCreate(stack, false, 120, false, cloudSiteId, tenantId, createStackParam);
158 public final void postProcessStackCreate_Backout_True_Test() throws MsoException, IOException {
159 Stack stack = new Stack();
161 stack.setStackName("stackName");
162 stack.setStackStatus("CREATE_IN_PROGRESS");
163 stack.setStackStatusReason("Stack Finished");
165 Stack deletedStack = new Stack();
166 deletedStack.setId("id");
167 deletedStack.setStackName("stackName");
168 deletedStack.setStackStatus("DELETE_COMPLETE");
169 deletedStack.setStackStatusReason("Stack Deleted");
171 CreateStackParam createStackParam = new CreateStackParam();
172 createStackParam.setStackName("stackName");
173 doReturn(deletedStack).when(heatUtils).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
174 exceptionRule.expect(StackCreationException.class);
175 exceptionRule.expectMessage(
176 "Stack Creation Failed Openstack Status: CREATE_IN_PROGRESS Status Reason: Stack Finished , Rollback of Stack Creation completed with status: DELETE_COMPLETE Status Reason: Stack Deleted");
177 heatUtils.postProcessStackCreate(stack, true, 120, false, cloudSiteId, tenantId, createStackParam);
178 Mockito.verify(heatUtils, times(1)).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
182 public final void postProcessStackCreate_Keypair_True_Test() throws MsoException, IOException {
183 Stack stack = new Stack();
185 stack.setStackName("stackName");
186 stack.setStackStatus("CREATE_IN_PROGRESS");
187 stack.setStackStatusReason(
188 "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
190 Stack createdStack = new Stack();
191 createdStack.setId("id");
192 createdStack.setStackName("stackName");
193 createdStack.setStackStatus("CREATE_COMPLETE");
194 createdStack.setStackStatusReason("Stack Created");
196 CreateStackParam createStackParam = new CreateStackParam();
197 createStackParam.setStackName("stackName");
198 doReturn(createdStack).when(heatUtils).handleKeyPairConflict(cloudSiteId, tenantId, createStackParam, 120, true,
200 heatUtils.postProcessStackCreate(stack, true, 120, true, cloudSiteId, tenantId, createStackParam);
201 Mockito.verify(heatUtils, times(1)).handleKeyPairConflict(cloudSiteId, tenantId, createStackParam, 120, true,
206 public final void handleUnknownCreateStackFailure_Test() throws MsoException, IOException {
208 Stack stack = new Stack();
210 stack.setStackName("stackName");
211 stack.setStackStatus("CREATE_FAILED");
212 stack.setStackStatusReason(
213 "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
215 Stack deletedStack = new Stack();
216 deletedStack.setId("id");
217 deletedStack.setStackName("stackName");
218 deletedStack.setStackStatus("DELETE_COMPLETE");
219 deletedStack.setStackStatusReason("Stack Deleted");
221 CreateStackParam createStackParam = new CreateStackParam();
222 createStackParam.setStackName("stackName");
223 doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
224 doNothing().when(heatUtils).postProcessStackDelete(deletedStack);
225 doReturn(null).when(heatUtils).executeAndRecordOpenstackRequest(mockDeleteStack);
226 doReturn(stackResource).when(heatClient).getStacks();
227 doReturn(mockDeleteStack).when(stackResource).deleteByName("stackName/id");
228 doReturn(deletedStack).when(heatUtils).pollStackForStatus(120, stack, "DELETE_IN_PROGRESS", cloudSiteId,
231 heatUtils.handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
232 Mockito.verify(heatUtils, times(1)).executeAndRecordOpenstackRequest(mockDeleteStack);
233 Mockito.verify(heatUtils, times(1)).pollStackForStatus(120, stack, "DELETE_IN_PROGRESS", cloudSiteId, tenantId);
234 Mockito.verify(heatUtils, times(1)).postProcessStackDelete(deletedStack);
239 public final void handleUnknownCreateStackFailure_Null_Stack_Test() throws MsoException, IOException {
241 exceptionRule.expect(StackCreationException.class);
242 exceptionRule.expectMessage("Cannot Find Stack Name or Id");
243 heatUtils.handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
247 public final void postProcessStackDelete_Stack_Test() throws MsoException, IOException {
248 Stack deletedStack = new Stack();
249 deletedStack.setId("id");
250 deletedStack.setStackName("stackName");
251 deletedStack.setStackStatus("DELETE_FAILED");
252 deletedStack.setStackStatusReason("Stack DID NOT DELETE");
253 exceptionRule.expect(StackRollbackException.class);
254 exceptionRule.expectMessage(
255 "Stack Deletion completed with status: DELETE_FAILED Status Reason: Stack DID NOT DELETE");
256 heatUtils.postProcessStackDelete(deletedStack);
260 public final void postProcessStackDelete__Null_Stack_Test() throws MsoException, IOException {
262 exceptionRule.expect(StackRollbackException.class);
263 exceptionRule.expectMessage("Cannot Find Stack Name or Id");
264 heatUtils.postProcessStackDelete(stack);
268 public final void isKeyPairFailure_Test() throws MsoException, IOException {
269 boolean actual = heatUtils.isKeyPairFailure(
270 "Exception during create VF 0 : Stack error (CREATE_FAILED): Resource CREATE failed: Conflict: resources.bfnm_my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID:req-941b0af6-63ae-4d6a-afbc-90b728bacf82) - stack successfully deleted'rolledBack='true'");
271 assertEquals(true, actual);
275 public final void handleKeyPairConflict_Test() throws MsoException, IOException, NovaClientException {
276 Stack stack = new Stack();
278 stack.setStackName("stackName");
279 stack.setStackStatus("CREATE_FAILED");
280 stack.setStackStatusReason(
281 "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
283 Stack createdStack = new Stack();
284 createdStack.setId("id");
285 createdStack.setStackName("stackName");
286 createdStack.setStackStatus("CREATE_COMPLETE");
287 createdStack.setStackStatusReason("Stack Created");
291 List<Resource> resources = new ArrayList<>();
292 Resource resource = new Resource();
293 resource.setName("KeypairName");
294 resource.setPhysicalResourceId("KeypairName");
295 resource.setType("OS::Nova::KeyPair");
296 resources.add(resource);
298 CreateStackParam createStackParam = new CreateStackParam();
299 createStackParam.setStackName("stackName");
301 doReturn(resources).when(mockResources).getList();
302 doReturn(mockResources).when(heatUtils).queryStackResources(cloudSiteId, tenantId, "stackName", 2);
303 doNothing().when(novaClient).deleteKeyPair(cloudSiteId, tenantId, "KeypairName");
304 doReturn(null).when(heatUtils).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
305 doReturn(createdStack).when(heatUtils).createStack(createStackParam, cloudSiteId, tenantId);
306 doReturn(createdStack).when(heatUtils).processCreateStack(cloudSiteId, tenantId, 120, true, createdStack,
307 createStackParam, false);
309 heatUtils.handleKeyPairConflict(cloudSiteId, tenantId, createStackParam, 120, true, stack);
310 Mockito.verify(heatUtils, times(1)).queryStackResources(cloudSiteId, tenantId, "stackName", 2);
311 Mockito.verify(novaClient, times(1)).deleteKeyPair(cloudSiteId, tenantId, "KeypairName");
312 Mockito.verify(heatUtils, times(1)).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
313 Mockito.verify(heatUtils, times(1)).createStack(createStackParam, cloudSiteId, tenantId);
314 Mockito.verify(heatUtils, times(1)).processCreateStack(cloudSiteId, tenantId, 120, true, createdStack,
315 createStackParam, false);
319 public final void processCreateStack_Test() throws MsoException, IOException, NovaClientException {
320 Stack stack = new Stack();
322 stack.setStackName("stackName");
323 stack.setStackStatus("CREATE_FAILED");
324 stack.setStackStatusReason(
325 "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
327 Stack createdStack = new Stack();
328 createdStack.setId("id");
329 createdStack.setStackName("stackName");
330 createdStack.setStackStatus("CREATE_COMPLETE");
331 createdStack.setStackStatusReason("Stack Created");
334 CreateStackParam createStackParam = new CreateStackParam();
335 createStackParam.setStackName("stackName");
337 doReturn(createdStack).when(heatUtils).pollStackForStatus(120, stack, "CREATE_IN_PROGRESS", cloudSiteId,
339 doReturn(createdStack).when(heatUtils).postProcessStackCreate(createdStack, true, 120, true, cloudSiteId,
340 tenantId, createStackParam);
342 heatUtils.processCreateStack(cloudSiteId, tenantId, 120, true, stack, createStackParam, true);
343 Mockito.verify(heatUtils, times(1)).pollStackForStatus(120, stack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
344 Mockito.verify(heatUtils, times(1)).postProcessStackCreate(createdStack, true, 120, true, cloudSiteId, tenantId,
349 public final void processCreateStack_Exception_Backout_Test()
350 throws MsoException, IOException, NovaClientException {
351 Stack stack = new Stack();
353 stack.setStackName("stackName");
354 stack.setStackStatus("CREATE_FAILED");
355 stack.setStackStatusReason(
356 "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
358 Stack deletedStack = new Stack();
359 deletedStack.setId("id");
360 deletedStack.setStackName("stackName");
361 deletedStack.setStackStatus("DELETE_COMPLETE");
362 deletedStack.setStackStatusReason("Stack Deleted");
364 CreateStackParam createStackParam = new CreateStackParam();
365 createStackParam.setStackName("stackName");
367 doThrow(new StackCreationException("Error")).when(heatUtils).pollStackForStatus(120, stack,
368 "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
369 doReturn(deletedStack).when(heatUtils).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
370 exceptionRule.expect(MsoException.class);
371 exceptionRule.expectMessage("Error");
372 heatUtils.processCreateStack(cloudSiteId, tenantId, 120, true, stack, createStackParam, true);
373 Mockito.verify(heatUtils, times(1)).pollStackForStatus(120, stack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
374 Mockito.verify(heatUtils, times(1)).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
379 public final void createStack_Test() throws MsoException, IOException, NovaClientException {
380 CreateStackParam createStackParam = new CreateStackParam();
381 createStackParam.setStackName("stackName");
383 doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
384 doReturn(stackResource).when(heatClient).getStacks();
385 doReturn(mockCreateStack).when(stackResource).create(createStackParam);
387 doReturn(null).when(heatUtils).executeAndRecordOpenstackRequest(mockCreateStack);
389 heatUtils.createStack(createStackParam, cloudSiteId, tenantId);
390 Mockito.verify(stackResource, times(1)).create(createStackParam);
391 Mockito.verify(heatUtils, times(1)).saveStackRequest(eq(mockCreateStack), isNull(), eq("stackName"));
392 Mockito.verify(heatClient, times(1)).getStacks();
393 Mockito.verify(stackResource, times(1)).create(createStackParam);
397 public final void createStack_Error_Test() throws MsoException, IOException, NovaClientException {
398 CreateStackParam createStackParam = new CreateStackParam();
399 createStackParam.setStackName("stackName");
401 doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
402 doReturn(stackResource).when(heatClient).getStacks();
403 doReturn(mockCreateStack).when(stackResource).create(createStackParam);
405 doThrow(new OpenStackResponseException("Unknown Error", 500)).when(heatUtils)
406 .executeAndRecordOpenstackRequest(mockCreateStack);
407 exceptionRule.expect(MsoOpenstackException.class);
408 exceptionRule.expectMessage("Unknown Error");
409 heatUtils.createStack(createStackParam, cloudSiteId, tenantId);
410 Mockito.verify(stackResource, times(1)).create(createStackParam);
411 Mockito.verify(heatUtils, times(1)).saveStackRequest(eq(mockCreateStack), isNull(), eq("stackName"));
412 Mockito.verify(heatClient, times(1)).getStacks();
413 Mockito.verify(stackResource, times(1)).create(createStackParam);
417 public final void createStack_Error_404_Test() throws MsoException, IOException, NovaClientException {
418 CreateStackParam createStackParam = new CreateStackParam();
419 createStackParam.setStackName("stackName");
421 doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
422 doReturn(stackResource).when(heatClient).getStacks();
423 doReturn(mockCreateStack).when(stackResource).create(createStackParam);
425 doThrow(new OpenStackResponseException("Not Found", 409)).when(heatUtils)
426 .executeAndRecordOpenstackRequest(mockCreateStack);
427 exceptionRule.expect(MsoStackAlreadyExists.class);
428 exceptionRule.expectMessage("Stack stackName already exists in Tenant tenantId in Cloud cloudSiteId");
429 heatUtils.createStack(createStackParam, cloudSiteId, tenantId);
430 Mockito.verify(stackResource, times(1)).create(createStackParam);
431 Mockito.verify(heatUtils, times(1)).saveStackRequest(eq(mockCreateStack), isNull(), eq("stackName"));
432 Mockito.verify(heatClient, times(1)).getStacks();
433 Mockito.verify(stackResource, times(1)).create(createStackParam);
437 public final void processCreateStack_Exception_No_Backout_Test()
438 throws MsoException, IOException, NovaClientException {
439 Stack stack = new Stack();
441 stack.setStackName("stackName");
442 stack.setStackStatus("CREATE_FAILED");
443 stack.setStackStatusReason(
444 "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
446 Stack deletedStack = new Stack();
447 deletedStack.setId("id");
448 deletedStack.setStackName("stackName");
449 deletedStack.setStackStatus("DELETE_COMPLETE");
450 deletedStack.setStackStatusReason("Stack Deleted");
452 CreateStackParam createStackParam = new CreateStackParam();
453 createStackParam.setStackName("stackName");
455 doThrow(new StackCreationException("Error")).when(heatUtils).pollStackForStatus(120, stack,
456 "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
458 exceptionRule.expect(MsoException.class);
459 exceptionRule.expectMessage("Error");
460 heatUtils.processCreateStack(cloudSiteId, tenantId, 120, false, stack, createStackParam, true);
461 Mockito.verify(heatUtils, times(1)).pollStackForStatus(120, stack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
462 Mockito.verify(heatUtils, times(0)).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);