1856dec5e417260208d1d49531bd457147d1ca1e
[so/adapters/so-cnf-adapter.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2023 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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.so.cnfm.lcm.bpmn.flows.extclients.helm;
21
22 import static org.junit.Assert.assertEquals;
23 import static org.mockito.ArgumentMatchers.argThat;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.when;
26 import java.io.ByteArrayInputStream;
27 import java.io.IOException;
28 import java.nio.file.Path;
29 import java.nio.file.Paths;
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.List;
33 import org.junit.Test;
34 import org.mockito.ArgumentMatcher;
35 import org.onap.so.cnfm.lcm.bpmn.flows.Constants;
36 import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.HelmClientExecuteException;
37 import org.onap.so.cnfm.lcm.bpmn.flows.utils.PropertiesToYamlConverter;
38 import org.onap.so.cnfm.lcm.database.beans.utils.Utils;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43 /**
44  *
45  * @author Waqas Ikram (waqas.ikram@est.tech)
46  *
47  */
48 public class HelmClientTest {
49     private static final Logger logger = LoggerFactory.getLogger(HelmClientTest.class);
50
51     private static final int SUCCESSFUL_EXIT_CODE = 0;
52     private static final int FAILED_EXIT_CODE = 1;
53
54     private static final Path DUMMY_HELM_CHART = Paths.get("/some/dir/dummy/dummy-chart.tgz");
55     private static final Path DUMMY_KUBE_CONFIG = Paths.get("/some/dir/dummy/kube-config");
56     private static final String DUMMY_RELEASE_NAME = "RELEASE_NAME";
57     private static final PropertiesToYamlConverter PROPERTIES_TO_YAML_CONVERTER = new PropertiesToYamlConverter();
58     private static final List<String> EXPECTED_COMMANDS = Arrays.asList("helm", "install", DUMMY_RELEASE_NAME, "-n",
59             "default", DUMMY_HELM_CHART.toString(), "--dry-run", "--kubeconfig", DUMMY_KUBE_CONFIG.toString());
60
61     private static final List<String> EXPECTED_GET_KUBE_KINDS_COMMANDS = Arrays.asList("sh", "-c",
62             "helm template " + DUMMY_RELEASE_NAME + " -n default " + DUMMY_HELM_CHART.toString() + " --dry-run"
63                     + " --kubeconfig " + DUMMY_KUBE_CONFIG.toString() + " --skip-tests | grep kind | uniq");
64
65     private static final List<String> EXPECTED_GET_KUBE_KINDS_MANIFEST_COMMANDS =
66             Arrays.asList("sh", "-c", "helm get manifest " + DUMMY_RELEASE_NAME + " -n default --kubeconfig "
67                     + DUMMY_KUBE_CONFIG.toString() + " | grep kind | uniq");
68
69     private static final List<String> EXPECTED_HELM_INSTALL_COMMANDS = Arrays.asList("sh", "-c", "helm install "
70             + DUMMY_RELEASE_NAME + " -n default " + DUMMY_HELM_CHART + " --kubeconfig " + DUMMY_KUBE_CONFIG.toString());
71
72     private static final List<String> EXPECTED_HELM_UNINSTALL_COMMANDS = Arrays.asList("helm", "uninstall",
73             DUMMY_RELEASE_NAME, "-n", "default", "--kubeconfig", DUMMY_KUBE_CONFIG.toString());
74
75     @Test(expected = Test.None.class)
76     public void testRunHelmChartInstallWithDryRunFlag_successfulCase() throws Exception {
77
78         try (final ByteArrayInputStream errorStream = new ByteArrayInputStream("".getBytes());
79                 final ByteArrayInputStream inputStream = new ByteArrayInputStream("Successful".getBytes());) {
80
81             final ProcessBuilder mockedProcessBuilder = mock(ProcessBuilder.class);
82
83             final ListMatcher expectedCommandsMatcher = new ListMatcher(EXPECTED_COMMANDS);
84             mockProcessBuilder(mockedProcessBuilder, expectedCommandsMatcher, errorStream, inputStream,
85                     SUCCESSFUL_EXIT_CODE, EXPECTED_COMMANDS);
86
87             final HelmClient objUnderTest =
88                     new StubbedHelmClientImpl(PROPERTIES_TO_YAML_CONVERTER, mockedProcessBuilder);
89
90             objUnderTest.runHelmChartInstallWithDryRunFlag(DUMMY_RELEASE_NAME, DUMMY_KUBE_CONFIG, DUMMY_HELM_CHART);
91         }
92
93     }
94
95     @Test(expected = HelmClientExecuteException.class)
96     public void testRunHelmChartInstallWithDryRunFlag_processFailed_throwException() throws Exception {
97
98         try (final ByteArrayInputStream errorStream = new ByteArrayInputStream("process failed".getBytes());
99                 final ByteArrayInputStream inputStream = new ByteArrayInputStream("".getBytes());) {
100
101             final ProcessBuilder mockedProcessBuilder = mock(ProcessBuilder.class);
102
103             final ListMatcher expectedCommandsMatcher = new ListMatcher(EXPECTED_COMMANDS);
104             mockProcessBuilder(mockedProcessBuilder, expectedCommandsMatcher, errorStream, inputStream, FAILED_EXIT_CODE,
105                     EXPECTED_COMMANDS);
106
107             final HelmClient objUnderTest =
108                     new StubbedHelmClientImpl(PROPERTIES_TO_YAML_CONVERTER, mockedProcessBuilder);
109
110             objUnderTest.runHelmChartInstallWithDryRunFlag(DUMMY_RELEASE_NAME, DUMMY_KUBE_CONFIG, DUMMY_HELM_CHART);
111         }
112     }
113
114     @Test
115     public void testGetKubeKinds_successfulCase() throws Exception {
116
117         try (final ByteArrayInputStream errorStream = new ByteArrayInputStream("".getBytes());
118                 final ByteArrayInputStream inputStream =
119                         new ByteArrayInputStream(Constants.KIND_REPLICA_SET.getBytes());) {
120
121             final ProcessBuilder mockedProcessBuilder = mock(ProcessBuilder.class);
122
123             final ListMatcher expectedCommandsMatcher = new ListMatcher(EXPECTED_GET_KUBE_KINDS_COMMANDS);
124             mockProcessBuilder(mockedProcessBuilder, expectedCommandsMatcher, errorStream, inputStream, SUCCESSFUL_EXIT_CODE,
125                     EXPECTED_GET_KUBE_KINDS_COMMANDS);
126
127             final HelmClient objUnderTest =
128                     new StubbedHelmClientImpl(PROPERTIES_TO_YAML_CONVERTER, mockedProcessBuilder);
129             final List<String> actualKubeKinds =
130                     objUnderTest.getKubeKinds(DUMMY_RELEASE_NAME, DUMMY_KUBE_CONFIG, DUMMY_HELM_CHART);
131
132             assertEquals(Arrays.asList(Constants.KIND_REPLICA_SET), actualKubeKinds);
133
134         }
135     }
136
137     @Test
138     public void testGetKubeKindsUsingManifestCommand_successfulCase() throws Exception {
139
140         try (final ByteArrayInputStream errorStream = new ByteArrayInputStream("".getBytes());
141                 final ByteArrayInputStream inputStream =
142                         new ByteArrayInputStream(Constants.KIND_DAEMON_SET.getBytes());) {
143
144             final ProcessBuilder mockedProcessBuilder = mock(ProcessBuilder.class);
145
146             final ListMatcher expectedCommandsMatcher = new ListMatcher(EXPECTED_GET_KUBE_KINDS_MANIFEST_COMMANDS);
147             mockProcessBuilder(mockedProcessBuilder, expectedCommandsMatcher, errorStream, inputStream, SUCCESSFUL_EXIT_CODE,
148                     EXPECTED_GET_KUBE_KINDS_COMMANDS);
149
150             final HelmClient objUnderTest =
151                     new StubbedHelmClientImpl(PROPERTIES_TO_YAML_CONVERTER, mockedProcessBuilder);
152
153             final List<String> actualKubeKinds =
154                     objUnderTest.getKubeKindsUsingManifestCommand(DUMMY_RELEASE_NAME, DUMMY_KUBE_CONFIG);
155             assertEquals(Arrays.asList(Constants.KIND_DAEMON_SET), actualKubeKinds);
156         }
157     }
158
159     @Test(expected = Test.None.class)
160     public void testInstallHelmChart_successfulCase() throws Exception {
161
162         try (final ByteArrayInputStream errorStream = new ByteArrayInputStream("".getBytes());
163                 final ByteArrayInputStream inputStream = new ByteArrayInputStream("Successful".getBytes());) {
164
165             final ProcessBuilder mockedProcessBuilder = mock(ProcessBuilder.class);
166
167             final ListMatcher expectedCommandsMatcher = new ListMatcher(EXPECTED_HELM_INSTALL_COMMANDS);
168             mockProcessBuilder(mockedProcessBuilder, expectedCommandsMatcher, errorStream, inputStream, SUCCESSFUL_EXIT_CODE,
169                     EXPECTED_HELM_INSTALL_COMMANDS);
170
171             final HelmClient objUnderTest =
172                     new StubbedHelmClientImpl(PROPERTIES_TO_YAML_CONVERTER, mockedProcessBuilder);
173
174             objUnderTest.installHelmChart(DUMMY_RELEASE_NAME, DUMMY_KUBE_CONFIG, DUMMY_HELM_CHART,
175                     Collections.emptyMap());
176         }
177     }
178
179     @Test(expected = Test.None.class)
180     public void testUnInstallHelmChart_successfulCase() throws Exception {
181
182         try (final ByteArrayInputStream errorStream = new ByteArrayInputStream("".getBytes());
183                 final ByteArrayInputStream inputStream = new ByteArrayInputStream("Successful".getBytes());) {
184
185             final ProcessBuilder mockedProcessBuilder = mock(ProcessBuilder.class);
186
187             final ListMatcher expectedCommandsMatcher = new ListMatcher(EXPECTED_HELM_UNINSTALL_COMMANDS);
188             mockProcessBuilder(mockedProcessBuilder, expectedCommandsMatcher, errorStream, inputStream, SUCCESSFUL_EXIT_CODE,
189                     EXPECTED_HELM_UNINSTALL_COMMANDS);
190
191             final HelmClient objUnderTest =
192                     new StubbedHelmClientImpl(PROPERTIES_TO_YAML_CONVERTER, mockedProcessBuilder);
193
194             objUnderTest.unInstallHelmChart(DUMMY_RELEASE_NAME, DUMMY_KUBE_CONFIG);
195         }
196     }
197
198     private void mockProcessBuilder(final ProcessBuilder mockedProcessBuilder,
199             final ListMatcher expectedCommandsMatcher, final ByteArrayInputStream errorStream,
200             final ByteArrayInputStream inputStream, final int exitCode, final List<String> expectedCommands)
201             throws InterruptedException, IOException {
202
203         final Process mockedProcess = mock(Process.class);
204         when(mockedProcessBuilder.command(argThat(expectedCommandsMatcher))).thenReturn(mockedProcessBuilder);
205         when(mockedProcess.getErrorStream()).thenReturn(errorStream);
206         when(mockedProcess.getInputStream()).thenReturn(inputStream);
207         when(mockedProcess.exitValue()).thenReturn(exitCode);
208         when(mockedProcess.waitFor()).thenReturn(0);
209         when(mockedProcessBuilder.command()).thenReturn(expectedCommands);
210         when(mockedProcessBuilder.start()).thenReturn(mockedProcess);
211     }
212
213     private class ListMatcher implements ArgumentMatcher<List<String>> {
214
215         private final List<String> expectArgumentList;
216
217         public ListMatcher(final List<String> expectArgumentList) {
218             this.expectArgumentList = expectArgumentList;
219         }
220
221         @Override
222         public boolean matches(final List<String> actualArgumentList) {
223             final boolean result = Utils.isEquals(expectArgumentList, actualArgumentList);
224             if (!result) {
225                 logger.error("Mismatch arguments expected: {}, actual: {}", expectArgumentList, actualArgumentList);
226             }
227             return result;
228         }
229     }
230
231     private class StubbedHelmClientImpl extends HelmClientImpl {
232
233         private final ProcessBuilder processBuilder;
234
235         public StubbedHelmClientImpl(final PropertiesToYamlConverter propertiesToYamlConverter,
236                 final ProcessBuilder processBuilder) {
237             super(propertiesToYamlConverter);
238             this.processBuilder = processBuilder;
239         }
240
241         @Override
242         ProcessBuilder getProcessBuilder() {
243             return processBuilder;
244         }
245
246     }
247
248 }