diff options
Diffstat (limited to 'appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java')
4 files changed, 338 insertions, 119 deletions
diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/ChefApiClientTest.java b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/ChefApiClientTest.java new file mode 100644 index 000000000..58b55854a --- /dev/null +++ b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/ChefApiClientTest.java @@ -0,0 +1,215 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. All rights reserved. + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.appc.adapter.chef.chefclient; + +import static junit.framework.TestCase.assertEquals; +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.mock; + +import com.google.common.collect.ImmutableMap; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.function.Supplier; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.StatusLine; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.StringEntity; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatcher; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ChefApiClientTest { + + private static final String END_POINT = "https://chefServer"; + private static final String ORGANIZATIONS_PATH = "onap"; + private static final String USER_ID = "testUser"; + private static final String REQUEST_PATH = "/test/path"; + private static final String BODY = "SOME BODY STRING"; + private static final ImmutableMap<String, String> HEADERS = ImmutableMap.<String, String>builder() + .put("Content-type", "application/json") + .put("Accept", "application/json") + .put("X-Ops-Timestamp", "1970-01-15T06:56:07Z") + .put("X-Ops-UserId", USER_ID) + .put("X-Chef-Version", "12.4.1") + .put("X-Ops-Content-Hash", BODY) + .put("X-Ops-Sign", "version=1.0").build(); + + @Mock + private HttpClient httpClient; + @Mock + private ChefApiHeaderFactory chefHttpHeaderFactory; + + @InjectMocks + private ChefApiClientFactory chefApiClientFactory; + private static final String PEM_FILEPATH = "path/to/pemFile"; + private ChefApiClient chefApiClient; + + @Before + public void setUp() { + chefApiClient = chefApiClientFactory.create( + END_POINT, + ORGANIZATIONS_PATH, + USER_ID, + PEM_FILEPATH); + } + + @Test + public void execute_HttpGet_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException { + // GIVEN + String methodName = "GET"; + String body = ""; + Supplier<ChefResponse> chefClientApiCall = () -> chefApiClient.get(REQUEST_PATH); + + // WHEN //THEN + assertChefApiClientCall(methodName, body, chefClientApiCall); + } + + @Test + public void execute_HttpDelete_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException { + // GIVEN + String methodName = "DELETE"; + String body = ""; + Supplier<ChefResponse> chefClientApiCall = () -> chefApiClient.delete(REQUEST_PATH); + + // WHEN //THEN + assertChefApiClientCall(methodName, body, chefClientApiCall); + } + + @Test + public void execute_HttpPost_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException { + // GIVEN + String methodName = "POST"; + Supplier<ChefResponse> chefClientApiCall = () -> chefApiClient.post(REQUEST_PATH, BODY); + + // WHEN //THEN + assertChefApiClientCall(methodName, BODY, chefClientApiCall); + } + + @Test + public void execute_HttpPut_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException { + // GIVEN + String methodName = "PUT"; + Supplier<ChefResponse> chefClientApiCall = () -> chefApiClient.put(REQUEST_PATH, BODY); + + // WHEN //THEN + assertChefApiClientCall(methodName, BODY, chefClientApiCall); + } + + private void assertChefApiClientCall(String methodName, String body, Supplier<ChefResponse> httpMethod) + throws IOException { + // GIVEN + given(chefHttpHeaderFactory.create(methodName, REQUEST_PATH, body, USER_ID, ORGANIZATIONS_PATH, PEM_FILEPATH)) + .willReturn(HEADERS); + + StatusLine statusLine = mock(StatusLine.class); + given(statusLine.getStatusCode()).willReturn(HttpStatus.SC_OK); + HttpResponse httpResponse = mock(HttpResponse.class); + given(httpResponse.getStatusLine()).willReturn(statusLine); + given(httpResponse.getEntity()).willReturn(new StringEntity("Successful Response String")); + given(httpClient.execute(argThat(new HttpRequestBaseMatcher(methodName)))) + .willReturn(httpResponse); + + // WHEN + ChefResponse chefResponse = httpMethod.get(); + + // THEN + assertEquals("Successful Response String", chefResponse.getBody()); + assertEquals(HttpStatus.SC_OK, chefResponse.getStatusCode()); + } + + @Test + public void execute_shouldHandleException_whenHttpClientExecutionFails() throws IOException { + + // GIVEN + given(chefHttpHeaderFactory.create("GET", REQUEST_PATH, "", USER_ID, ORGANIZATIONS_PATH, PEM_FILEPATH)) + .willReturn(HEADERS); + + String expectedErrorMsg = "HttpClient call failed"; + given(httpClient.execute(argThat(new HttpRequestBaseMatcher("GET")))) + .willThrow(new IOException(expectedErrorMsg)); + + // WHEN + ChefResponse chefResponse = chefApiClient.get(REQUEST_PATH); + + // THEN + assertEquals(expectedErrorMsg, chefResponse.getBody()); + assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, chefResponse.getStatusCode()); + } + + @Test + public void execute_shouldHandleException_whenEndpointURIisMalformed() { + // GIVEN + String expectedErrorMsg = "Malformed escape pair at index 1: /%#@/"; + + // WHEN + ChefApiClient chefApiClient = chefApiClientFactory.create( + "/%#@/", + ORGANIZATIONS_PATH, + USER_ID, + PEM_FILEPATH); + ChefResponse chefResponse = chefApiClient.get(REQUEST_PATH); + + // THEN + assertEquals(expectedErrorMsg, chefResponse.getBody()); + assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, chefResponse.getStatusCode()); + } + + private class HttpRequestBaseMatcher extends ArgumentMatcher<HttpRequestBase> { + + private final String methodName; + + public HttpRequestBaseMatcher(String methodName) { + this.methodName = methodName; + } + + @Override + public boolean matches(Object argument) { + HttpRequestBase httpRequestBase = (HttpRequestBase) argument; + + boolean headersMatch = checkIfHeadersMatch(httpRequestBase); + try { + return methodName.equals(httpRequestBase.getMethod()) + && new URI(END_POINT + REQUEST_PATH).equals(httpRequestBase.getURI()) + && headersMatch; + } catch (URISyntaxException e) { + e.printStackTrace(); + return false; + } + } + + private boolean checkIfHeadersMatch(HttpRequestBase httpRequestBase) { + Header[] generatedHeaders = httpRequestBase.getAllHeaders(); + return generatedHeaders.length > 0 + && generatedHeaders.length == HEADERS.size() + && HEADERS.entrySet().stream() + .allMatch(p -> httpRequestBase.getFirstHeader(p.getKey()).getValue().equals(p.getValue())); + } + } +}
\ No newline at end of file diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/ChefApiHeaderFactoryTest.java b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/ChefApiHeaderFactoryTest.java new file mode 100644 index 000000000..cc309811d --- /dev/null +++ b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/ChefApiHeaderFactoryTest.java @@ -0,0 +1,83 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. All rights reserved. + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.appc.adapter.chef.chefclient; + +import static junit.framework.TestCase.assertEquals; +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.any; + +import com.google.common.collect.ImmutableMap; +import java.util.Date; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ChefApiHeaderFactoryTest { + + private static final String ORGANIZATIONS_PATH = "onap"; + private static final String USER_ID = "testUser"; + private static final String REQUEST_PATH = "/test/path"; + private static final String EXPECTED_TIMESTAMP = "1970-01-15T06:56:07Z"; + private static final String EMPTY_BODY = ""; + + @Mock + private FormattedTimestamp formattedTimestamp; + + @InjectMocks + private ChefApiHeaderFactory chefApiHeaderFactory; + + @Test + public void create_shouldCreateProperChefHeaders_withHashedAuthorizationString() { + // GIVEN + given(formattedTimestamp.format(any(Date.class))).willReturn(EXPECTED_TIMESTAMP); + String pemFilePath = getClass().getResource("/testclient.pem").getPath(); + + // WHEN + ImmutableMap<String, String> headers = chefApiHeaderFactory + .create("GET", REQUEST_PATH, "", USER_ID, ORGANIZATIONS_PATH, pemFilePath); + + // THEN + assertEquals(headers, createExpectedHeaders()); + } + + private ImmutableMap<String, String> createExpectedHeaders() { + String hashedBody = Utils.sha1AndBase64(EMPTY_BODY); + ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); + builder + .put("Content-type", "application/json") + .put("Accept", "application/json") + .put("X-Ops-Timestamp", EXPECTED_TIMESTAMP) + .put("X-Ops-UserId", USER_ID) + .put("X-Chef-Version", "12.4.1") + .put("X-Ops-Content-Hash", hashedBody) + .put("X-Ops-Sign", "version=1.0") + .put("X-Ops-Authorization-1", "i+HGCso703727yd2ZQWMZIIpGKgTzm41fA31LIExNxEf9mOUMcpesIHjH/Wr") + .put("X-Ops-Authorization-2", "QEvsX/Gy1ay9KsUtqhy9GA6PB8UfDeMNoVUisqR4HQW+S6IOfvqBjW+2afzE") + .put("X-Ops-Authorization-3", "RdRReB/TJIF3s6ZC8vNpbEdY9kHmwiDglhxmS8X2FS+ArSh/DK/i7MqBbjux") + .put("X-Ops-Authorization-4", "49iiOlRVG7aTr/FA115hlBYP9CYCIQWKIBUOK3JyV9fXNdVqc9R0r1XdjxUl") + .put("X-Ops-Authorization-5", "EDGw6tuE8YW8mH5wkgHCjKpXG3WjmWt2X6kUrdIu44qCBK2N3sZziSub2fJA") + .put("X-Ops-Authorization-6", "hPBuOhjiYDZuFUqC99lCryM0Hf5RMw1uTlkYsBEZmA=="); + + return builder.build(); + } +}
\ No newline at end of file diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/FormattedTimestampTest.java b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/FormattedTimestampTest.java new file mode 100644 index 000000000..47d2f6c2c --- /dev/null +++ b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/FormattedTimestampTest.java @@ -0,0 +1,40 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. All rights reserved. + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.appc.adapter.chef.chefclient; + +import static org.junit.Assert.assertEquals; + +import java.util.Date; +import org.junit.Test; + +public class FormattedTimestampTest { + + @Test + public void format_shouldFormatGivenDate_withCorrectTimezoneSet() { + // GIVEN + String expectedFormattedDate = "1970-01-15T06:56:07Z"; + + // WHEN + String formattedDateWithTimezone = new FormattedTimestamp().format(new Date(1234567890)); + + // THEN + assertEquals(expectedFormattedDate, formattedDateWithTimezone); + } +}
\ No newline at end of file diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/TestChefApiClient.java b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/TestChefApiClient.java deleted file mode 100644 index 9e787b64d..000000000 --- a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/onap/appc/adapter/chef/chefclient/TestChefApiClient.java +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP : APPC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Copyright (C) 2017 Amdocs - * ============================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * ============LICENSE_END========================================================= - */ - -package org.onap.appc.adapter.chef.chefclient; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import java.io.InputStream; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; -import java.util.Properties; -import org.junit.Before; -import org.junit.Test; -import org.onap.appc.adapter.chef.chefapi.ApiMethod; -import org.onap.appc.adapter.chef.chefapi.Delete; -import org.onap.appc.adapter.chef.chefapi.Get; -import org.onap.appc.adapter.chef.chefapi.Post; -import org.onap.appc.adapter.chef.chefapi.Put; - -public class TestChefApiClient { - - private ChefApiClient client; - private Properties props; - private static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"); - - @Before - public void setup() throws IllegalArgumentException, IllegalAccessException { - props = new Properties(); - InputStream propStr = getClass().getResourceAsStream("/test.properties"); - if (propStr == null) { - fail("src/test/resources/test.properties missing"); - } - - try { - props.load(propStr); - propStr.close(); - } catch (Exception e) { - e.printStackTrace(); - fail("Could not initialize properties"); - } - client = new ChefApiClient(props.getProperty("org.onap.appc.adapter.chef.chefclient.userId"), - System.getProperty("user.dir") + props.getProperty("org.onap.appc.adapter.chef.chefclient.pemPath"), - props.getProperty("org.onap.appc.adapter.chef.chefclient.endPoint"), - props.getProperty("org.onap.appc.adapter.chef.chefclient.organizations")); - } - - @Test - public void testGet() { - Get get = client.get(props.getProperty("org.onap.appc.adapter.chef.chefclient.path")); - ApiMethod method = get.execute(); - String[] response = method.test.split("\n"); - thenStringShouldMatch("GET", response); - } - - @Test - public void testPut() { - Put put = client.put(props.getProperty("org.onap.appc.adapter.chef.chefclient.path")); - ApiMethod method = put.execute(); - String[] response = method.test.split("\n"); - - thenStringShouldMatch("PUT", response); - } - - @Test - public void testPost() { - Post post = client.post(props.getProperty("org.onap.appc.adapter.chef.chefclient.path")); - ApiMethod method = post.execute(); - String[] response = method.test.split("\n"); - - thenStringShouldMatch("POST", response); - } - - @Test - public void testDelete() { - Delete delete = client.delete(props.getProperty("org.onap.appc.adapter.chef.chefclient.path")); - ApiMethod method = delete.execute(); - String[] response = method.test.split("\n"); - - thenStringShouldMatch("DELETE", response); - } - - private void thenStringShouldMatch(String method, String[] response) { - assertEquals("sb Method:" + method, response[0]); - assertEquals("Hashed Path:+JEk1y2gXwqZRweNjXYtx4ojxW8=", response[1]); - assertEquals("X-Ops-Content-Hash:2jmj7l5rSw0yVb/vlWAYkK/YBwk=", response[2]); - checkTimestamp(response[3], 30000); - assertEquals("X-Ops-UserId:test", response[4]); - } - - private void checkTimestamp(String timeStampHeader, long maxDeltaMs) { - assertTrue(timeStampHeader.startsWith("X-Ops-Timestamp:")); - LocalDateTime ld1 = LocalDateTime.parse(timeStampHeader.replace("X-Ops-Timestamp:", ""), dtf); - assertTrue(ChronoUnit.MILLIS.between(ld1, LocalDateTime.now(ZoneId.of("UTC"))) <= maxDeltaMs); - } -} |