2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021 Nordix Foundation.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.clamp.controlloop.participant.kubernetes.rest;
23 import static org.hamcrest.CoreMatchers.is;
24 import static org.mockito.Mockito.doNothing;
25 import static org.mockito.Mockito.when;
26 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
27 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
28 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
31 import java.util.List;
32 import org.json.JSONObject;
33 import org.junit.jupiter.api.BeforeAll;
34 import org.junit.jupiter.api.BeforeEach;
35 import org.junit.jupiter.api.Test;
36 import org.junit.jupiter.api.extension.ExtendWith;
37 import org.onap.policy.clamp.controlloop.participant.kubernetes.controller.ChartController;
38 import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo;
39 import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList;
40 import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.ParticipantK8sParameters;
41 import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartService;
42 import org.onap.policy.common.utils.coder.Coder;
43 import org.onap.policy.common.utils.coder.CoderException;
44 import org.onap.policy.common.utils.coder.StandardCoder;
45 import org.springframework.beans.factory.annotation.Autowired;
46 import org.springframework.boot.context.properties.EnableConfigurationProperties;
47 import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
48 import org.springframework.boot.test.mock.mockito.MockBean;
49 import org.springframework.http.MediaType;
50 import org.springframework.mock.web.MockMultipartFile;
51 import org.springframework.test.context.junit.jupiter.SpringExtension;
52 import org.springframework.test.web.servlet.MockMvc;
53 import org.springframework.test.web.servlet.RequestBuilder;
54 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
55 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
56 import org.springframework.web.context.WebApplicationContext;
59 @ExtendWith(SpringExtension.class)
60 @WebMvcTest(value = ChartController.class)
61 @EnableConfigurationProperties(value = ParticipantK8sParameters.class)
62 class ChartControllerTest {
64 private static final Coder CODER = new StandardCoder();
65 private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json";
66 private static List<ChartInfo> charts;
67 private static String DEFAULT_CHART_URL = "/helm/charts";
68 private static String INSTALL_CHART_URL = "/helm/install";
69 private static String UNINSTALL_CHART_URL = "/helm/uninstall/";
72 private MockMvc mockMvc;
75 private ChartService chartService;
78 private WebApplicationContext context;
81 * Read input chart info json.
82 * @throws Exception incase of error.
85 static void setupParams() throws CoderException {
86 charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts();
90 * Mock service layer in Controller.
91 * @throws Exception incase of error.
94 void mockServiceClass() {
95 when(chartService.getAllCharts()).thenReturn(charts);
96 when(chartService.getChart(charts.get(0).getChartId().getName(), charts.get(0).getChartId().getVersion()))
97 .thenReturn(charts.get(0));
99 this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
103 * Test endpoint for retrieving all charts.
104 * @throws Exception incase of error.
107 void retrieveAllCharts() throws Exception {
108 RequestBuilder requestBuilder;
109 requestBuilder = MockMvcRequestBuilders.get(DEFAULT_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE);
111 mockMvc.perform(requestBuilder).andExpect(status().isOk())
112 .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
113 .andExpect(jsonPath("$.charts.[0].chartId.name", is("HelloWorld")));
117 * Test endpoint for installing a chart.
118 * @throws Exception incase of error.
121 void installChart() throws Exception {
122 RequestBuilder requestBuilder;
124 //Mocking successful installation for void install method
125 doNothing().when(chartService).installChart(charts.get(0));
127 requestBuilder = MockMvcRequestBuilders.post(INSTALL_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE)
128 .content(getInstallationJson(charts.get(0).getChartId().getName(), charts.get(0).getChartId().getVersion()))
129 .contentType(MediaType.APPLICATION_JSON_VALUE);
131 mockMvc.perform(requestBuilder).andExpect(status().isCreated());
133 //Install Invalid chart, expects HTTP status NOT_FOUND
134 requestBuilder = MockMvcRequestBuilders.post(INSTALL_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE)
135 .content(getInstallationJson("invalidName", "invalidVersion"))
136 .contentType(MediaType.APPLICATION_JSON_VALUE);
138 mockMvc.perform(requestBuilder).andExpect(status().isNotFound());
142 * Test endpoint for uninstalling a chart.
143 * @throws Exception incase of error.
146 void uninstallChart() throws Exception {
147 RequestBuilder requestBuilder;
149 //Mocking successful scenario for void uninstall method
150 doNothing().when(chartService).uninstallChart(charts.get(0));
152 requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + charts.get(0)
153 .getChartId().getName() + "/" + charts.get(0).getChartId().getVersion())
154 .accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE);
156 mockMvc.perform(requestBuilder).andExpect(status().isNoContent());
159 requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + "invalidName"
160 + "/" + "invalidVersion").accept(MediaType.APPLICATION_JSON_VALUE)
161 .contentType(MediaType.APPLICATION_JSON_VALUE);
163 mockMvc.perform(requestBuilder).andExpect(status().isNotFound());
167 * Test endpoint for chart onboarding.
168 * @throws Exception incase of error.
171 void onboardChart() throws Exception {
172 RequestBuilder requestBuilder;
173 MockMultipartFile chartFile = new MockMultipartFile("chart", "hello.tgz",
174 MediaType.TEXT_PLAIN_VALUE, "Dummy data".getBytes());
176 MockMultipartFile overrideFile = new MockMultipartFile("values", "values.yaml",
177 MediaType.TEXT_PLAIN_VALUE, "Dummy data".getBytes());
179 //Mocking successful scenario for void uninstall method
180 when(chartService.saveChart(charts.get(0), chartFile, null)).thenReturn(charts.get(0));
182 requestBuilder = MockMvcRequestBuilders.multipart(DEFAULT_CHART_URL)
183 .file(chartFile).file(overrideFile).param("info", getChartInfoJson());
185 mockMvc.perform(requestBuilder).andExpect(status().isOk());
189 * Test endpoint for deleting a chart.
190 * @throws Exception incase of error.
193 void deleteChart() throws Exception {
194 RequestBuilder requestBuilder;
196 //Mocking successful scenario for void uninstall method
197 doNothing().when(chartService).deleteChart(charts.get(0));
199 requestBuilder = MockMvcRequestBuilders.delete(DEFAULT_CHART_URL + "/" + charts.get(0)
200 .getChartId().getName() + "/" + charts.get(0).getChartId().getVersion())
201 .accept(MediaType.APPLICATION_JSON_VALUE)
202 .contentType(MediaType.APPLICATION_JSON_VALUE);
204 mockMvc.perform(requestBuilder).andExpect(status().isNoContent());
206 requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + "invalidName"
207 + "/" + "invalidVersion").accept(MediaType.APPLICATION_JSON_VALUE)
208 .contentType(MediaType.APPLICATION_JSON_VALUE);
210 mockMvc.perform(requestBuilder).andExpect(status().isNotFound());
214 private String getInstallationJson(String name, String version) {
215 JSONObject jsonObj = new JSONObject();
216 jsonObj.put("name", name);
217 jsonObj.put("version", version);
218 return jsonObj.toString();
221 private String getChartInfoJson() {
222 JSONObject jsonObj = new JSONObject();
223 jsonObj.put("chartName", charts.get(0).getChartId().getName());
224 jsonObj.put("version", charts.get(0).getChartId().getVersion());
225 jsonObj.put("namespace", charts.get(0).getNamespace());
226 jsonObj.put("repository", charts.get(0).getRepository());
227 jsonObj.put("releaseName", charts.get(0).getReleaseName());
228 return jsonObj.toString();