2 * Copyright © 2019 iconectiv
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.
17 package org.openecomp.core.externaltesting.impl;
19 import com.fasterxml.jackson.core.type.TypeReference;
20 import com.fasterxml.jackson.databind.ObjectMapper;
22 import java.io.FileInputStream;
23 import java.io.IOException;
24 import java.nio.charset.Charset;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Optional;
30 import java.util.UUID;
31 import org.apache.commons.io.FileUtils;
32 import org.apache.commons.io.IOUtils;
33 import org.apache.commons.lang3.tuple.Pair;
34 import org.junit.Assert;
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.mockito.ArgumentMatchers;
39 import org.mockito.InjectMocks;
40 import org.mockito.Mock;
41 import org.mockito.Mockito;
42 import org.mockito.MockitoAnnotations;
43 import org.mockito.junit.MockitoJUnitRunner;
44 import org.openecomp.core.externaltesting.api.ClientConfiguration;
45 import org.openecomp.core.externaltesting.api.ExternalTestingManager;
46 import org.openecomp.core.externaltesting.api.RemoteTestingEndpointDefinition;
47 import org.openecomp.core.externaltesting.api.TestTreeNode;
48 import org.openecomp.core.externaltesting.api.VtpNameDescriptionPair;
49 import org.openecomp.core.externaltesting.api.VtpTestCase;
50 import org.openecomp.core.externaltesting.api.VtpTestExecutionRequest;
51 import org.openecomp.core.externaltesting.api.VtpTestExecutionResponse;
52 import org.openecomp.core.externaltesting.errors.ExternalTestingException;
53 import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManager;
54 import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager;
55 import org.openecomp.sdc.versioning.VersioningManager;
56 import org.openecomp.sdc.versioning.dao.types.Version;
57 import org.springframework.core.ParameterizedTypeReference;
58 import org.springframework.http.HttpHeaders;
59 import org.springframework.http.HttpMethod;
60 import org.springframework.http.HttpStatus;
61 import org.springframework.http.MediaType;
62 import org.springframework.http.ResponseEntity;
63 import org.springframework.util.LinkedMultiValueMap;
64 import org.springframework.web.client.HttpServerErrorException;
65 import org.springframework.web.client.HttpStatusCodeException;
66 import org.springframework.web.client.ResourceAccessException;
67 import org.springframework.web.client.RestTemplate;
69 @RunWith(MockitoJUnitRunner.class)
70 public class ExternalTestingManagerImplTest {
73 private RestTemplate restTemplate;
76 private VersioningManager versioningManager;
79 private VendorSoftwareProductManager vendorSoftwareProductManager;
82 private OrchestrationTemplateCandidateManager candidateManager;
85 private ExternalTestingManagerImpl mgr = new ExternalTestingManagerImpl();
87 @SuppressWarnings("unchecked")
88 private ExternalTestingManagerImpl configTestManager(boolean loadConfig) throws IOException {
90 MockitoAnnotations.initMocks(this);
96 ObjectMapper mapper = new ObjectMapper();
98 // read mock data for API calls.
100 File scenarioFile = new File("src/test/data/scenarios.json");
101 TypeReference<List<VtpNameDescriptionPair>> typ = new TypeReference<List<VtpNameDescriptionPair>>() { };
102 List<VtpNameDescriptionPair> scenarios = mapper.readValue(scenarioFile, typ);
104 File testSuitesFile = new File("src/test/data/testsuites.json");
105 List<VtpNameDescriptionPair> testSuites =
106 mapper.readValue(testSuitesFile, new TypeReference<List<VtpNameDescriptionPair>>() { });
108 File testCasesFile = new File("src/test/data/testcases.json");
109 List<VtpTestCase> testCases = mapper.readValue(testCasesFile, new TypeReference<List<VtpTestCase>>() { });
111 File testCaseFile = new File("src/test/data/testcase-sriov.json");
112 VtpTestCase testCase = mapper.readValue(testCaseFile, VtpTestCase.class);
114 File runResultFile = new File("src/test/data/runresult.json");
115 List<VtpTestExecutionResponse> runResults =
116 mapper.readValue(runResultFile, new TypeReference<List<VtpTestExecutionResponse>>() { });
118 File priorExecutionFile = new File("src/test/data/priorexecution.json");
119 VtpTestExecutionResponse priorExecution = mapper.readValue(priorExecutionFile, VtpTestExecutionResponse.class);
121 // create an error response as well
122 String notFound = FileUtils.readFileToString(new File("src/test/data/notfound.json"), "UTF-8");
124 ParameterizedTypeReference<List<VtpNameDescriptionPair>> listOfPairType =
125 new ParameterizedTypeReference<List<VtpNameDescriptionPair>>() { };
126 ParameterizedTypeReference<List<VtpTestCase>> listOfCasesType =
127 new ParameterizedTypeReference<List<VtpTestCase>>() { };
128 ParameterizedTypeReference<VtpTestCase> caseType = new ParameterizedTypeReference<VtpTestCase>() { };
130 HttpHeaders headers = new HttpHeaders();
131 headers.setContentType(MediaType.parseMediaType("application/problem+json"));
133 byte[] csar = IOUtils.toByteArray(new FileInputStream("src/test/data/csar.zip"));
134 byte[] heat = IOUtils.toByteArray(new FileInputStream("src/test/data/heat.zip"));
136 List<Version> versionList = new ArrayList<>();
137 versionList.add(new Version(UUID.randomUUID().toString()));
139 Mockito.when(candidateManager.get(ArgumentMatchers.contains("csar"), ArgumentMatchers.any()))
140 .thenReturn(Optional.of(Pair.of("Processed.zip", csar)));
142 Mockito.when(candidateManager.get(ArgumentMatchers.contains("heat"), ArgumentMatchers.any()))
143 .thenReturn(Optional.empty());
145 Mockito.when(vendorSoftwareProductManager.get(ArgumentMatchers.contains("heat"), ArgumentMatchers.any()))
146 .thenReturn(Optional.of(Pair.of("Processed.zip", heat)));
149 Mockito.when(vendorSoftwareProductManager.get(ArgumentMatchers.contains("missing"), ArgumentMatchers.any()))
150 .thenReturn(Optional.empty());
152 Mockito.when(candidateManager.get(ArgumentMatchers.contains("missing"), ArgumentMatchers.any()))
153 .thenReturn(Optional.empty());
156 Mockito.when(versioningManager.list(ArgumentMatchers.contains("missing"))).thenReturn(versionList);
159 Mockito.when(restTemplate.exchange(ArgumentMatchers.endsWith("/scenarios"), ArgumentMatchers.eq(HttpMethod.GET),
160 ArgumentMatchers.any(), ArgumentMatchers.eq(listOfPairType)))
161 .thenReturn(new ResponseEntity(scenarios, HttpStatus.OK));
163 Mockito.when(restTemplate
164 .exchange(ArgumentMatchers.endsWith("/testsuites"), ArgumentMatchers.eq(HttpMethod.GET),
165 ArgumentMatchers.any(), ArgumentMatchers.eq(listOfPairType)))
166 .thenReturn(new ResponseEntity(testSuites, HttpStatus.OK));
168 Mockito.when(restTemplate.exchange(ArgumentMatchers.endsWith("/testcases"), ArgumentMatchers.eq(HttpMethod.GET),
169 ArgumentMatchers.any(), ArgumentMatchers.eq(listOfCasesType)))
170 .thenReturn(new ResponseEntity(testCases, HttpStatus.OK));
172 Mockito.when(restTemplate.exchange(ArgumentMatchers.endsWith("/sriov"), ArgumentMatchers.eq(HttpMethod.GET),
173 ArgumentMatchers.any(), ArgumentMatchers.eq(caseType)))
174 .thenReturn(new ResponseEntity(testCase, HttpStatus.OK));
177 // POST for execution
179 Mockito.when(restTemplate
180 .exchange(ArgumentMatchers.contains("executions"), ArgumentMatchers.eq(HttpMethod.POST),
181 ArgumentMatchers.any(), ArgumentMatchers
182 .eq(new ParameterizedTypeReference<List<VtpTestExecutionResponse>>() { })))
183 .thenReturn(new ResponseEntity(runResults, HttpStatus.OK));
186 Mockito.when(restTemplate
187 .exchange(ArgumentMatchers.contains("/executions/"), ArgumentMatchers.eq(HttpMethod.GET),
188 ArgumentMatchers.any(), ArgumentMatchers
189 .eq(new ParameterizedTypeReference<VtpTestExecutionResponse>() { })))
190 .thenReturn(new ResponseEntity(priorExecution, HttpStatus.OK));
193 HttpStatusCodeException missingException =
194 new HttpServerErrorException(HttpStatus.NOT_FOUND, "Not Found", headers, notFound.getBytes(),
195 Charset.defaultCharset());
196 Mockito.when(restTemplate.exchange(ArgumentMatchers.endsWith("/missing"), ArgumentMatchers.eq(HttpMethod.GET),
197 ArgumentMatchers.any(), ArgumentMatchers.eq(caseType))).thenThrow(missingException);
200 Mockito.when(restTemplate.exchange(ArgumentMatchers.endsWith("/sitedown"), ArgumentMatchers.eq(HttpMethod.GET),
201 ArgumentMatchers.any(), ArgumentMatchers.eq(caseType)))
202 .thenThrow(new ResourceAccessException("Remote site is down"));
204 Mockito.when(restTemplate.exchange(ArgumentMatchers.endsWith("throwexception"),
205 ArgumentMatchers.eq(HttpMethod.POST), ArgumentMatchers.any(),
206 ArgumentMatchers.eq(new ParameterizedTypeReference<List<VtpTestExecutionResponse>>() { })))
207 .thenThrow(missingException);
214 public void setConfigLocation() {
215 System.setProperty("config.location", "src/test/data");
219 public void testManager() throws IOException {
220 ExternalTestingManager m = configTestManager(true);
222 ClientConfiguration config = m.getConfig();
223 Assert.assertNotNull(config);
225 List<RemoteTestingEndpointDefinition> endpoints = m.getEndpoints();
226 Assert.assertEquals("two endpoints", 2, endpoints.size());
229 // this will exercise the internal APIs as well.
230 TestTreeNode root = m.getTestCasesAsTree();
231 Assert.assertEquals("two scenarios", 2, root.getChildren().size());
234 // handle case where remote endpoint is down.
236 m.getTestCase("repository", "scen", "suite", "sitedown");
237 Assert.fail("not expected to retrieve sitedown test case");
238 } catch (ExternalTestingException e) {
239 // expecting this exception.
240 Assert.assertNotNull(e.getDetail());
241 Assert.assertNotEquals(0, e.getHttpStatus());
242 Assert.assertNotNull(e.getMessageCode());
245 // get a particular test case
247 m.getTestCase("repository", "scen", "suite", "missing");
248 Assert.fail("not expected to retrieve missing test case");
249 } catch (ExternalTestingException e) {
250 // expecting this exception.
251 Assert.assertNotNull(e.getDetail());
252 Assert.assertNotEquals(0, e.getHttpStatus());
253 Assert.assertNotNull(e.getMessageCode());
258 public void testManagerExecution() throws IOException {
259 ExternalTestingManager m = configTestManager(true);
262 List<VtpTestExecutionRequest> requests = new ArrayList<>();
263 VtpTestExecutionRequest req = new VtpTestExecutionRequest();
264 req.setEndpoint("repository");
267 // send a request with the endpoint defined.
268 List<VtpTestExecutionResponse> responses = m.execute(requests, "vspId", "vspVersionId", "rid", null);
269 Assert.assertEquals(1, responses.size());
271 // send a request for a prior execution.
272 VtpTestExecutionResponse execRsp = m.getExecution("repository", "execId");
273 Assert.assertEquals("COMPLETE", execRsp.getStatus());
277 public void testMissingConfig() throws IOException {
278 // directory exists but no config file should be found here.
279 System.setProperty("config.location", "src/test");
280 ExternalTestingManager m = configTestManager(true);
281 Assert.assertFalse("missing config client enabled false", m.getConfig().isEnabled());
282 Assert.assertEquals("missing config no endpoints", 0, m.getEndpoints().size());
286 public void testMissingEndpoint() throws IOException {
287 ExternalTestingManager m = configTestManager(true);
290 List<VtpTestExecutionRequest> requests = new ArrayList<>();
291 VtpTestExecutionRequest req = new VtpTestExecutionRequest();
292 req.setEndpoint("repository");
295 // send a request with the endpoint defined.
297 m.execute(requests, "vspId", "vspVersionId", "throwexception", null);
298 } catch (ExternalTestingException e) {
305 public void testManagerConfigOverrides() throws IOException {
306 ExternalTestingManager m = configTestManager(false);
308 ClientConfiguration cc = new ClientConfiguration();
311 Assert.assertTrue(m.getConfig().isEnabled());
313 List<RemoteTestingEndpointDefinition> lst = new ArrayList<>();
314 lst.add(new RemoteTestingEndpointDefinition());
315 lst.get(0).setEnabled(true);
317 Assert.assertEquals(1, m.getEndpoints().size());
321 public void testManagerErrorCases() throws IOException {
322 ExternalTestingManager m = configTestManager(false);
323 ClientConfiguration emptyConfig = m.getConfig();
324 Assert.assertFalse("empty configuration should have client enabled of false", emptyConfig.isEnabled());
328 Assert.assertTrue("should have exception here", true);
329 } catch (ExternalTestingException e) {
330 // eat the exception cause this is what should happen.
335 public void testExecutionDistribution() throws IOException {
336 ExternalTestingManager m = configTestManager(true);
338 VtpTestExecutionRequest r1 = new VtpTestExecutionRequest();
339 r1.setScenario("scenario1");
340 r1.setEndpoint("vtp");
342 VtpTestExecutionRequest r2 = new VtpTestExecutionRequest();
343 r2.setScenario("scenario2");
344 r2.setEndpoint("vtp");
346 VtpTestExecutionRequest r3 = new VtpTestExecutionRequest();
347 r3.setScenario("scenario3");
348 r3.setEndpoint("repository");
350 List<VtpTestExecutionResponse> results =
351 m.execute(Arrays.asList(r1, r2, r3), "vspId", "vspVersionId", "rid", null);
352 Assert.assertEquals("three in two out merged", 2, results.size());
356 public void testArchiveProcessing() throws IOException {
357 ExternalTestingManagerImpl m = configTestManager(true);
358 VtpTestExecutionRequest r1 = new VtpTestExecutionRequest();
359 r1.setScenario("scenario1");
360 r1.setEndpoint("vtp");
361 r1.setParameters(new HashMap<>());
363 LinkedMultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
364 m.attachArchiveContent(r1, body, "something.with.csar.content", UUID.randomUUID().toString());
365 r1.setParameters(new HashMap<>());
366 LinkedMultiValueMap<String, Object> body2 = new LinkedMultiValueMap<>();
367 m.attachArchiveContent(r1, body2, "something.with.heat.content", UUID.randomUUID().toString());
369 // now, let's handle a missing archive.
370 r1.setParameters(new HashMap<>());
371 LinkedMultiValueMap<String, Object> body3 = new LinkedMultiValueMap<>();
373 m.attachArchiveContent(r1, body3, "something.with.missing.content", UUID.randomUUID().toString());
374 Assert.fail("expected to receive an exception here");
375 } catch (ExternalTestingException ex) {
376 Assert.assertEquals(500, ex.getHttpStatus());