Fixes for Chef Adapter bundle
[appc.git] / appc-adapters / appc-chef-adapter / appc-chef-adapter-bundle / src / test / java / org / onap / appc / adapter / chef / impl / ChefAdapterImplJobPusherTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2018 Nokia. All rights reserved.
6  * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
7  * =============================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21 package org.onap.appc.adapter.chef.impl;
22
23 import static com.google.common.collect.Maps.immutableEntry;
24 import static org.assertj.core.api.Assertions.assertThat;
25 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
26 import static org.mockito.BDDMockito.given;
27
28 import com.google.common.collect.ImmutableMap;
29 import com.google.common.collect.ImmutableMap.Builder;
30 import java.util.Map;
31 import java.util.Map.Entry;
32 import org.apache.http.HttpStatus;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.mockito.InjectMocks;
37 import org.mockito.Mock;
38 import org.mockito.runners.MockitoJUnitRunner;
39 import org.onap.appc.adapter.chef.chefclient.ChefApiClientFactory;
40 import org.onap.appc.adapter.chef.chefclient.api.ChefApiClient;
41 import org.onap.appc.adapter.chef.chefclient.api.ChefResponse;
42 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
43 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
44
45 @RunWith(MockitoJUnitRunner.class)
46 public class ChefAdapterImplJobPusherTest {
47
48     private static final String CLIENT_PRIVATE_KEY_PATH = "/opt/onap/appc/chef/localhost/onap/testclient.pem";
49     private static final String RESULT_CODE_ATTR_KEY = "chefServerResult.code";
50     private static final String RESULT_MESSAGE_ATTR_KEY = "chefServerResult.message";
51     private static final String EXPECTED_RESPONSE_MSG = "jobs/{666}/";
52
53     private static final String USERNAME = "testclient";
54     private static final String SERVER_ADDRESS = "localhost";
55     private static final String ORGANIZATIONS = "onap";
56     private static final String ACTION_PARAM = "/pushy/jobs";
57     private static final String REQUEST_BODY_DATA = "requestBodyData";
58     private static final String JOB_ID = "jobID";
59
60     @Mock
61     private PrivateKeyChecker privateKeyChecker;
62     @Mock
63     private ChefApiClientFactory chefApiClientFactory;
64     @Mock
65     private ChefApiClient chefApiClient;
66
67     @InjectMocks
68     private ChefAdapterFactory chefAdapterFactory;
69     private SvcLogicContext svcLogicContext;
70
71     @Before
72     public void setUp() {
73         svcLogicContext = new SvcLogicContext();
74     }
75
76     @Test
77     public void pushJob_shouldSuccessfullyMakePostCall_andUpdateSvcLogicContext_whenReturnedStatusIsDifferentThan_201()
78         throws SvcLogicException {
79         assertSuccessfulPostCallForStatus(HttpStatus.SC_OK);
80         assertThat(svcLogicContext.getAttribute(JOB_ID)).isBlank();
81     }
82
83     @Test
84     public void pushJob_shouldSuccessfullyMakePostCall_andUpdateSvcLogicContext_withReturnedStatusIs_201()
85         throws SvcLogicException {
86         assertSuccessfulPostCallForStatus(HttpStatus.SC_CREATED);
87         assertThat(svcLogicContext.getAttribute(JOB_ID)).isEqualTo("666");
88     }
89
90     @SuppressWarnings("unchecked")
91     public void assertSuccessfulPostCallForStatus(int expectedHttpStatus) throws SvcLogicException {
92         // GIVEN
93         Map<String, String> params = givenInputParams(
94             immutableEntry("chefAction", ACTION_PARAM),
95             immutableEntry("pushRequest", REQUEST_BODY_DATA));
96         given(chefApiClientFactory.create("https://localhost/organizations/onap", ORGANIZATIONS, USERNAME,
97             CLIENT_PRIVATE_KEY_PATH)).willReturn(chefApiClient);
98         given(chefApiClient.post(ACTION_PARAM, REQUEST_BODY_DATA))
99             .willReturn(ChefResponse.create(expectedHttpStatus, EXPECTED_RESPONSE_MSG));
100
101         // WHEN
102         chefAdapterFactory.create().pushJob(params, svcLogicContext);
103
104         // THEN
105         assertThat(svcLogicContext.getStatus()).isEqualTo("success");
106         assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY))
107             .isEqualTo(Integer.toString(expectedHttpStatus));
108         assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(EXPECTED_RESPONSE_MSG);
109     }
110
111     @SuppressWarnings("unchecked")
112     @Test
113     public void pushJob_shouldHandleAllOccurringExceptions_duringMethodExecution() {
114         // GIVEN
115         Map<String, String> params = givenInputParams();
116         String expectedErrorMessage = "Something went wrong";
117         given(chefApiClientFactory.create("https://localhost/organizations/onap", ORGANIZATIONS, USERNAME,
118             CLIENT_PRIVATE_KEY_PATH)).willThrow(new NullPointerException(expectedErrorMessage));
119
120         // WHEN // THEN
121         assertThatExceptionOfType(SvcLogicException.class)
122             .isThrownBy(() -> chefAdapterFactory.create().pushJob(params, svcLogicContext))
123             .withMessage("Chef Adapter error:" + expectedErrorMessage);
124
125         assertThat(svcLogicContext.getStatus()).isEqualTo("failure");
126         assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY))
127             .isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED));
128         assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(expectedErrorMessage);
129         assertThat(svcLogicContext.getAttribute(JOB_ID)).isBlank();
130     }
131
132     @SuppressWarnings("unchecked")
133     @Test
134     public void checkPushJob_shouldSetFailStatusAndMsgInContext_andThrowException_whenRetryTimesParamIsMissing() {
135         // GIVEN
136         Map<String, String> params = givenInputParams(
137             immutableEntry("retryInterval", "1"),
138             immutableEntry("jobid", "666"));
139
140         // WHEN // THEN
141         assertIfInputParamsAreValidated(params);
142     }
143
144     @SuppressWarnings("unchecked")
145     @Test
146     public void checkPushJob_shouldSetFailStatusAndMsgInContext_andThrowException_whenRetryIntervalParamIsMissing() {
147         // GIVEN
148         Map<String, String> params = givenInputParams(
149             immutableEntry("retryTimes", "4"),
150             immutableEntry("jobid", "666"));
151
152         // WHEN // THEN
153         assertIfInputParamsAreValidated(params);
154     }
155
156     @SuppressWarnings("unchecked")
157     @Test
158     public void checkPushJob_shouldSetFailStatusAndMsgInContext_andThrowException_whenJobIdParamIsMissing() {
159         // GIVEN
160         Map<String, String> params = givenInputParams(
161             immutableEntry("retryTimes", "4"),
162             immutableEntry("retryInterval", "1"));
163         assertIfInputParamsAreValidated(params);
164     }
165
166     public void assertIfInputParamsAreValidated(Map<String, String> params) {
167         // WHEN // THEN
168         assertThatExceptionOfType(SvcLogicException.class)
169             .isThrownBy(() -> chefAdapterFactory.create().checkPushJob(params, svcLogicContext))
170             .withMessage("Chef Adapter error:" + "Missing Mandatory param(s) retryTimes , retryInterval ");
171
172         assertThat(svcLogicContext.getStatus()).isEqualTo("failure");
173         assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY))
174             .isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED));
175         assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY))
176             .isEqualTo("Missing Mandatory param(s) retryTimes , retryInterval ");
177     }
178
179     @Test
180     public void checkPushJob_shouldCheckJobStatusOnlyOnce_withoutAdditionalRetries_whenFirstReturnedJobStatusIs_Complete()
181         throws SvcLogicException {
182         String expectedHttpStatus = Integer.toString(HttpStatus.SC_OK);
183         String expectedMessage = "{status:complete}";
184
185         assertCheckJobStatusFor(
186             expectedHttpStatus,
187             expectedMessage,
188             ChefResponse.create(HttpStatus.SC_OK, "{status:complete}"),
189             ChefResponse.create(HttpStatus.SC_OK, "{status:running}"));
190     }
191
192     @Test
193     public void checkPushJob_shouldCheckJobStatusExpectedNumberOf_ThreeRetryTimes_whenEachReturnedStatusIs_Running()
194         throws SvcLogicException {
195         String expectedHttpStatus = Integer.toString(HttpStatus.SC_ACCEPTED);
196         String expectedMessage = "chef client runtime out";
197
198         assertCheckJobStatusFor(
199             expectedHttpStatus,
200             expectedMessage,
201             ChefResponse.create(HttpStatus.SC_OK, "{status:running}"),
202             ChefResponse.create(HttpStatus.SC_OK, "{status:running}"),
203             ChefResponse.create(HttpStatus.SC_OK, "{status:running}"));
204     }
205
206     @Test
207     public void checkPushJob_shouldCheckJobStatusOnlyOnce_withoutAdditionalRetries_whenFirstReturnedJobStatusIsNot_Running()
208         throws SvcLogicException {
209
210         String expectedHttpStatus = Integer.toString(HttpStatus.SC_INTERNAL_SERVER_ERROR);
211         String expectedMessage = "{status:unexpectedStatus}";
212
213         assertCheckJobStatusFor(
214             expectedHttpStatus,
215             expectedMessage,
216             ChefResponse.create(HttpStatus.SC_OK, "{status:unexpectedStatus}"),
217             ChefResponse.create(HttpStatus.SC_OK, "{status:running}"));
218     }
219
220     @SuppressWarnings("unchecked")
221     public void assertCheckJobStatusFor(String expectedHttpStatus, String expectedMessage, ChefResponse firstResponse,
222         ChefResponse... nextResponses) throws SvcLogicException {
223
224         // GIVEN
225         Map<String, String> params = givenInputParams(
226             immutableEntry("jobid", "666"),
227             immutableEntry("retryTimes", "3"),
228             immutableEntry("retryInterval", "1"));
229         given(chefApiClientFactory.create("https://localhost/organizations/onap", ORGANIZATIONS, USERNAME,
230             CLIENT_PRIVATE_KEY_PATH)).willReturn(chefApiClient);
231         given(chefApiClient.get(ACTION_PARAM + "/" + params.get("jobid")))
232             .willReturn(firstResponse, nextResponses);
233
234         // WHEN
235         chefAdapterFactory.create().checkPushJob(params, svcLogicContext);
236
237         // THEN
238         assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY))
239             .isEqualTo(expectedHttpStatus);
240         assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(expectedMessage);
241     }
242
243     @SuppressWarnings("unchecked")
244     private Map<String, String> givenInputParams(Entry<String, String>... entries) {
245         Builder<String, String> paramsBuilder = ImmutableMap.builder();
246         paramsBuilder.put("username", USERNAME)
247             .put("serverAddress", SERVER_ADDRESS)
248             .put("organizations", ORGANIZATIONS);
249
250         for (Entry<String, String> entry : entries) {
251             paramsBuilder.put(entry);
252         }
253         return paramsBuilder.build();
254     }
255 }