From: FrancescoFioraEst Date: Mon, 19 Jan 2026 11:49:12 +0000 (+0000) Subject: Refactor participant-Kubernetes X-Git-Tag: 9.0.1~16 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=b46a63c076a7cdd431d401ad6e0a5d551c4f96e4;p=policy%2Fclamp.git Refactor participant-Kubernetes Refactor participant-Kubernetes and remove duplication of Spring config file. Issue-ID: POLICY-5533 Change-Id: I3cfe04d4eadde82b476f6131eecb7958c311b5fa Signed-off-by: FrancescoFioraEst --- diff --git a/examples/src/main/resources/clamp/acm/acelement-helm/acelement/values.yaml b/examples/src/main/resources/clamp/acm/acelement-helm/acelement/values.yaml index 2d1fd1df1..e78fac1a3 100644 --- a/examples/src/main/resources/clamp/acm/acelement-helm/acelement/values.yaml +++ b/examples/src/main/resources/clamp/acm/acelement-helm/acelement/values.yaml @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (C) 2022-2024 Nordix Foundation. +# Copyright (C) 2022-2024,2026 OpenInfra Foundation Europe. 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. @@ -26,7 +26,7 @@ image: repository: nexus3.onap.org:10001 name: onap/policy-clamp-acm-element-impl pullPolicy: IfNotPresent - tag: "8.0.1" + tag: "8.2.2" nameOverride: "ac-element-impl" diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java index 451ed22de..79cac5596 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2024 Nordix Foundation. + * Copyright (C) 2021-2024,2026 OpenInfra Foundation Europe. 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. @@ -42,7 +42,6 @@ import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.models.base.PfModelException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** @@ -55,10 +54,20 @@ public class AutomationCompositionElementHandler extends AcElementListenerV3 { private static final Coder CODER = new StandardCoder(); private final ChartService chartService; + private final PodStatusValidator podStatusValidator; - public AutomationCompositionElementHandler(ParticipantIntermediaryApi intermediaryApi, ChartService chartService) { + /** + * Constructor. + * + * @param intermediaryApi the ParticipantIntermediaryApi + * @param chartService the ChartService + * @param podStatusValidator the PodStatusValidator + */ + public AutomationCompositionElementHandler(ParticipantIntermediaryApi intermediaryApi, ChartService chartService, + PodStatusValidator podStatusValidator) { super(intermediaryApi); this.chartService = chartService; + this.podStatusValidator = podStatusValidator; } @@ -153,8 +162,7 @@ public class AutomationCompositionElementHandler extends AcElementListenerV3 { int podStatusCheckInterval, InstanceElementDto instanceElement) throws InterruptedException, PfModelException { - var result = new PodStatusValidator(chart, timeout, podStatusCheckInterval); - result.run(); + podStatusValidator.run(timeout, podStatusCheckInterval, chart); LOGGER.info("Pod Status Validator Completed"); intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, elementId, DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed"); diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClient.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClient.java index da8d455b8..043bb2b1d 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClient.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClient.java @@ -1,6 +1,6 @@ /*- * ========================LICENSE_START================================= - * Copyright (C) 2021-2025 OpenInfra Foundation Europe. All rights reserved. + * Copyright (C) 2021-2026 OpenInfra Foundation Europe. All rights reserved. * ====================================================================== * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ====================================================================== @@ -26,7 +26,7 @@ import java.lang.invoke.MethodHandles; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; @@ -35,17 +35,16 @@ import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository; import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartStore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * Client to talk with Helm cli. Supports helm3 + version */ @Component -@NoArgsConstructor +@RequiredArgsConstructor public class HelmClient { - private ChartStore chartStore; + private final ChartStore chartStore; private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private static final String PATH_DELIMITER = "/"; @@ -53,11 +52,6 @@ public class HelmClient { private static final String COMMAND_HELM = "/usr/local/bin/helm"; public static final String COMMAND_KUBECTL = "/usr/local/bin/kubectl"; - @Autowired - public HelmClient(ChartStore chartStore) { - this.chartStore = chartStore; - } - /** * Install a chart. * @@ -95,7 +89,6 @@ public class HelmClient { return false; } - /** * Finds helm chart repository for the chart. * @@ -129,11 +122,9 @@ public class HelmClient { */ public String verifyConfiguredRepo(ChartInfo chart) throws ServiceException { logger.info("Looking for helm chart {} in all the configured helm repositories", chart.getChartId().getName()); - String repository; var builder = helmRepoVerifyCommand(chart.getChartId().getName()); - String output = executeCommand(builder); - repository = verifyOutput(output, chart.getChartId().getName()); - return repository; + var output = executeCommand(builder); + return verifyOutput(output, chart.getChartId().getName()); } /** @@ -146,7 +137,6 @@ public class HelmClient { executeCommand(prepareUnInstallCommand(chart)); } - /** * Execute helm cli bash commands. * @@ -184,7 +174,7 @@ public class HelmClient { private boolean checkNamespaceExists(String namespace) throws ServiceException { logger.info("Check if namespace {} exists on the cluster", namespace); - String output = executeCommand(prepareVerifyNamespaceCommand(namespace)); + var output = executeCommand(prepareVerifyNamespaceCommand(namespace)); return !output.isEmpty(); } @@ -218,7 +208,7 @@ public class HelmClient { try { logger.debug("Verify the repo already exist in helm repositories"); var helmArguments = List.of(COMMAND_SH, "-c", COMMAND_HELM + " repo list | grep " + repo.getRepoName()); - String response = executeCommand(new ProcessBuilder().command(helmArguments)); + var response = executeCommand(new ProcessBuilder().command(helmArguments)); if (StringUtils.isEmpty(response)) { return false; } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java index 3eba9427d..5e3f465b4 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java @@ -1,6 +1,6 @@ /*- * ========================LICENSE_START================================= - * Copyright (C) 2021-2024 Nordix Foundation. All rights reserved. + * Copyright (C) 2021-2024,2026 OpenInfra Foundation Europe. 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. @@ -26,6 +26,7 @@ import java.lang.invoke.MethodHandles; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; +import lombok.RequiredArgsConstructor; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; @@ -33,57 +34,41 @@ import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; import org.onap.policy.models.base.PfModelException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; - +@Component +@RequiredArgsConstructor public class PodStatusValidator { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - private final int statusCheckInterval; - - //Timeout for the thread to exit. - private final int timeout; - - private ChartInfo chart; - - private HelmClient client = new HelmClient(); - - /** - * Constructor for PodStatusValidator. - * - * @param chart chartInfo - * @param timeout timeout for the thread to exit - * @param statusCheckInterval Interval to check pod status - */ - public PodStatusValidator(ChartInfo chart, int timeout, int statusCheckInterval) { - this.chart = chart; - this.timeout = timeout; - this.statusCheckInterval = statusCheckInterval; - } + private final HelmClient client; /** * Run the execution. * * @throws InterruptedException in case of an exception - * @throws ServiceException in case of an exception + * @throws PfModelException in case of an exception */ - public void run() throws InterruptedException, PfModelException { + public void run(int timeout, int statusCheckInterval, ChartInfo chart) + throws InterruptedException, PfModelException { logger.info("Polling the status of deployed pods for the chart {}", chart.getChartId().getName()); try { - verifyPodStatus(); + verifyPodStatus(timeout, statusCheckInterval, chart); } catch (IOException | ServiceException e) { throw new PfModelException(Response.Status.BAD_REQUEST, "Error verifying the status of the pod. Exiting"); } } - private void verifyPodStatus() throws ServiceException, IOException, InterruptedException, PfModelException { + private void verifyPodStatus(int timeout, int statusCheckInterval, ChartInfo chart) + throws ServiceException, IOException, InterruptedException, PfModelException { var isVerified = false; long endTime = System.currentTimeMillis() + (timeout * 1000L); while (!isVerified && System.currentTimeMillis() < endTime) { var output = client.executeCommand(verifyPodStatusCommand(chart)); - var podStatusMap = mapPodStatus(output); + var podStatusMap = mapPodStatus(chart, output); isVerified = !podStatusMap.isEmpty() && podStatusMap.values().stream().allMatch("Running"::equals); if (!isVerified) { @@ -103,17 +88,17 @@ public class PodStatusValidator { private ProcessBuilder verifyPodStatusCommand(ChartInfo chart) { String cmd = HelmClient.COMMAND_KUBECTL - + " get pods --namespace " + chart.getNamespace() + " | grep " + getPodName(); + + " get pods --namespace " + chart.getNamespace() + " | grep " + getPodName(chart); return new ProcessBuilder(HelmClient.COMMAND_SH, "-c", cmd); } - private String getPodName() { + private String getPodName(ChartInfo chart) { return StringUtils.isNotEmpty(chart.getPodName()) ? chart.getPodName() : chart.getChartId().getName(); } - private Map mapPodStatus(String output) throws IOException { + private Map mapPodStatus(ChartInfo chart, String output) throws IOException { Map podStatusMap = new HashMap<>(); - var podName = getPodName(); + var podName = getPodName(chart); try (var reader = new BufferedReader(new InputStreamReader(IOUtils.toInputStream(output, StandardCharsets.UTF_8)))) { var line = reader.readLine(); diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/HelmRepositoryConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/HelmRepositoryConfig.java similarity index 62% rename from participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/HelmRepositoryConfig.java rename to participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/HelmRepositoryConfig.java index 61a813e8a..9ad64a1f2 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/HelmRepositoryConfig.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/HelmRepositoryConfig.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 2022, 2026 OpenInfra Foundation Europe. 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. @@ -18,26 +18,16 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.acm.participant.kubernetes.configurations; +package org.onap.policy.clamp.acm.participant.kubernetes.parameters; -import java.lang.invoke.MethodHandles; -import java.util.ArrayList; -import java.util.List; import lombok.Data; -import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; -@Component @ConfigurationProperties(prefix = "helm") @Data public class HelmRepositoryConfig { - private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private String repos = "[]"; - private List repos = new ArrayList<>(); - - private List protocols = new ArrayList<>(); + private String protocols = ""; } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartService.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartService.java index 2274dd73c..8d7ad04f5 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartService.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartService.java @@ -1,6 +1,6 @@ /*- * ========================LICENSE_START================================= - * Copyright (C) 2021-2022, 2025 OpenInfra Foundation Europe. All rights reserved. + * Copyright (C) 2021-2022, 2025-2026 OpenInfra Foundation Europe. 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. @@ -20,43 +20,35 @@ package org.onap.policy.clamp.acm.participant.kubernetes.service; import java.io.IOException; import java.lang.invoke.MethodHandles; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; -import lombok.NoArgsConstructor; -import org.onap.policy.clamp.acm.participant.kubernetes.configurations.HelmRepositoryConfig; +import lombok.RequiredArgsConstructor; import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; import org.onap.policy.clamp.acm.participant.kubernetes.helm.HelmClient; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository; +import org.onap.policy.clamp.acm.participant.kubernetes.parameters.HelmRepositoryConfig; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @Service -@NoArgsConstructor +@RequiredArgsConstructor public class ChartService { private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - private ChartStore chartStore; + private final ChartStore chartStore; - private HelmClient helmClient; + private final HelmClient helmClient; - private HelmRepositoryConfig helmRepositoryConfig; + private final HelmRepositoryConfig helmRepositoryConfig; - /** - * Instantiates the ChartService with the specified dependencies. - * - * @param chartStore the store for managing Helm chart information - * @param helmClient the client for interacting with Helm - * @param helmRepositoryConfig the configuration for Helm repositories - */ - @Autowired - public ChartService(ChartStore chartStore, HelmClient helmClient, HelmRepositoryConfig helmRepositoryConfig) { - this.chartStore = chartStore; - this.helmClient = helmClient; - this.helmRepositoryConfig = helmRepositoryConfig; - } + private static final Coder coder = new StandardCoder(); /** * Get all the installed charts. @@ -98,6 +90,8 @@ public class ChartService { chartStore.deleteChart(chart); } + private static class Repositories extends ArrayList {} + /** * Install a helm chart. * @param chart name and version. @@ -108,22 +102,28 @@ public class ChartService { public boolean installChart(ChartInfo chart) throws ServiceException, IOException { boolean permittedRepo = false; if (chart.getRepository() == null) { - String repoName = findChartRepo(chart); + var repoName = findChartRepo(chart); if (repoName == null) { logger.error("Chart repository could not be found. Skipping chart Installation " + "for the chart {} ", chart.getChartId().getName()); return false; } else { - HelmRepository repo = HelmRepository.builder().repoName(repoName).build(); + var repo = HelmRepository.builder().repoName(repoName).build(); chart.setRepository(repo); } } else { // Add a remote repository if passed via TOSCA // and check whether the repo is permitted - for (HelmRepository repo : helmRepositoryConfig.getRepos()) { + Repositories repos = null; + try { + repos = coder.decode(helmRepositoryConfig.getRepos(), Repositories.class); + } catch (CoderException e) { + throw new ServiceException(e.getMessage()); + } + for (var repo : repos) { + var protocols = Arrays.stream(helmRepositoryConfig.getProtocols().split(",")).toList(); if (repo.getAddress().equals(chart.getRepository().getAddress()) - && helmRepositoryConfig.getProtocols() - .contains(chart.getRepository().getAddress().split(":")[0])) { + && protocols.contains(chart.getRepository().getAddress().split(":")[0])) { configureRepository(chart.getRepository()); permittedRepo = true; break; diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml b/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml index 60d4796d2..a03a6265d 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml @@ -130,17 +130,8 @@ chart: enabled: false # Update the config here for permitting repositories and protocols helm: - repos: - - - repoName: kong - address: https://charts.konghq.com - - - repoName: bitnami - address: https://charts.bitnami.com/bitnami - - protocols: - - http - - https + repos: [{"repoName": "kong", "address": "https://charts.konghq.com"},{"repoName": "bitnami", "address": "https://charts.bitnami.com/bitnami"}] + protocols: http,https tracing: enabled: ${allowTracing:false} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java index d6f514293..a6394d4e8 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2024 Nordix Foundation. + * Copyright (C) 2021-2024,2026 OpenInfra Foundation Europe. All rights reserved. * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,12 +24,9 @@ package org.onap.policy.clamp.acm.participant.kubernetes.handler; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -40,10 +37,10 @@ import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.helm.PodStatusValidator; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; import org.onap.policy.clamp.acm.participant.kubernetes.parameters.CommonTestData; @@ -65,8 +62,6 @@ class AutomationCompositionElementHandlerTest { "org.onap.domain.database.PMSH_K8SMicroserviceAutomationCompositionElement"; private final CommonTestData commonTestData = new CommonTestData(); - - @BeforeAll static void init() throws CoderException { charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); @@ -75,137 +70,111 @@ class AutomationCompositionElementHandlerTest { @Test void test_AutomationCompositionElementStateChange() throws ServiceException, PfModelException { - var chartService = Mockito.mock(ChartService.class); - var automationCompositionElementHandler = - new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + var chartService = mock(ChartService.class); + var acElementHandler = new AutomationCompositionElementHandler( + mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class)); - doNothing().when(chartService).uninstallChart(charts.get(0)); - - ObjectMapper objectMapper = new ObjectMapper(); + var objectMapper = new ObjectMapper(); Map inPropertiesMap = objectMapper.convertValue(charts.get(0), new TypeReference<>() {}); - automationCompositionElementHandler.undeploy(commonTestData.createCompositionElementDto(), + acElementHandler.undeploy(commonTestData.createCompositionElementDto(), commonTestData.createInstanceElementDto(Map.of("chart", inPropertiesMap))); doThrow(new ServiceException("Error uninstalling the chart")).when(chartService).uninstallChart(charts.get(0)); - assertDoesNotThrow(() -> automationCompositionElementHandler - .undeploy(commonTestData.createCompositionElementDto(), + assertDoesNotThrow(() -> acElementHandler.undeploy(commonTestData.createCompositionElementDto(), commonTestData.createInstanceElementDto(inPropertiesMap))); } @Test void test_AutomationCompositionElementUpdate() - throws PfModelException, IOException, ServiceException, InterruptedException { - var chartService = Mockito.mock(ChartService.class); - var automationCompositionElementHandler = - spy(new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService)); + throws PfModelException, IOException, ServiceException { + var chartService = mock(ChartService.class); + var acElementHandler = new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), + chartService, mock(PodStatusValidator.class)); - doNothing().when(automationCompositionElementHandler).checkPodStatus(any(), any(), any(), anyInt(), anyInt(), - any()); var nodeTemplatesMap = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); var instanceElementDto = commonTestData.createInstanceElementDto(nodeTemplatesMap .get(K8S_AUTOMATION_COMPOSITION_ELEMENT).getProperties()); var compositionElementDto = commonTestData.createCompositionElementDto(); doReturn(false).when(chartService).installChart(any()); - assertThrows(PfModelException.class, () -> automationCompositionElementHandler.deploy(compositionElementDto, - instanceElementDto)); + assertThrows(PfModelException.class, () -> acElementHandler.deploy(compositionElementDto, instanceElementDto)); doReturn(true).when(chartService).installChart(any()); - automationCompositionElementHandler.deploy(compositionElementDto, instanceElementDto); - - doThrow(new ServiceException("Error installing the chart")).when(chartService).installChart(Mockito.any()); + acElementHandler.deploy(compositionElementDto, instanceElementDto); - assertThrows(PfModelException.class, - () -> automationCompositionElementHandler.deploy(compositionElementDto, instanceElementDto)); + doThrow(new ServiceException("Error installing the chart")).when(chartService).installChart(any()); - } - - @Test - void test_checkPodStatus() { - var chartService = Mockito.mock(ChartService.class); - var automationCompositionElementHandler = - new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); - - var chartInfo = charts.get(0); - var automationCompositionId = UUID.randomUUID(); - assertThrows(PfModelException.class, () -> automationCompositionElementHandler - .checkPodStatus(automationCompositionId, UUID.randomUUID(), chartInfo, 1, 1, - commonTestData.createInstanceElementDto(Map.of()))); + assertThrows(PfModelException.class, () -> acElementHandler.deploy(compositionElementDto, instanceElementDto)); } @Test void testUpdate() { - var chartService = Mockito.mock(ChartService.class); - var automationCompositionElementHandler = - new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + var chartService = mock(ChartService.class); + var acElementHandler = new AutomationCompositionElementHandler( + mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class)); assertDoesNotThrow( - () -> automationCompositionElementHandler.update(commonTestData.createCompositionElementDto(), + () -> acElementHandler.update(commonTestData.createCompositionElementDto(), commonTestData.createInstanceElementDto(Map.of()), commonTestData.createInstanceElementDto(Map.of()))); } @Test void testLock() { - var chartService = Mockito.mock(ChartService.class); - var automationCompositionElementHandler = - new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + var chartService = mock(ChartService.class); + var acElementHandler = new AutomationCompositionElementHandler( + mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class)); - assertDoesNotThrow(() -> automationCompositionElementHandler.lock(commonTestData.createCompositionElementDto(), + assertDoesNotThrow(() -> acElementHandler.lock(commonTestData.createCompositionElementDto(), commonTestData.createInstanceElementDto(Map.of()))); } @Test void testUnlock() { - var chartService = Mockito.mock(ChartService.class); - var automationCompositionElementHandler = - new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + var chartService = mock(ChartService.class); + var acElementHandler = new AutomationCompositionElementHandler( + mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class)); - assertDoesNotThrow(() -> automationCompositionElementHandler - .unlock(commonTestData.createCompositionElementDto(), + assertDoesNotThrow(() -> acElementHandler.unlock(commonTestData.createCompositionElementDto(), commonTestData.createInstanceElementDto(Map.of()))); } @Test void testDelete() { - var chartService = Mockito.mock(ChartService.class); - var automationCompositionElementHandler = - new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + var chartService = mock(ChartService.class); + var acElementHandler = new AutomationCompositionElementHandler( + mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class)); - assertDoesNotThrow(() -> automationCompositionElementHandler - .delete(commonTestData.createCompositionElementDto(), + assertDoesNotThrow(() -> acElementHandler.delete(commonTestData.createCompositionElementDto(), commonTestData.createInstanceElementDto(Map.of()))); } @Test void testPrime() { - var chartService = Mockito.mock(ChartService.class); - var automationCompositionElementHandler = - new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + var chartService = mock(ChartService.class); + var acElementHandler = new AutomationCompositionElementHandler( + mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class)); - assertDoesNotThrow(() -> automationCompositionElementHandler.prime(new CompositionDto(UUID.randomUUID(), - Map.of(), Map.of()))); + assertDoesNotThrow(() -> acElementHandler.prime(new CompositionDto(UUID.randomUUID(), Map.of(), Map.of()))); } @Test void testDeprime() { - var chartService = Mockito.mock(ChartService.class); - var automationCompositionElementHandler = - new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + var chartService = mock(ChartService.class); + var acElementHandler = new AutomationCompositionElementHandler( + mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class)); - assertDoesNotThrow(() -> automationCompositionElementHandler.deprime(new CompositionDto(UUID.randomUUID(), - Map.of(), Map.of()))); + assertDoesNotThrow(() -> acElementHandler.deprime(new CompositionDto(UUID.randomUUID(), Map.of(), Map.of()))); } @Test void testMigrate() { - var chartService = Mockito.mock(ChartService.class); - var automationCompositionElementHandler = - new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + var chartService = mock(ChartService.class); + var acElementHandler = new AutomationCompositionElementHandler( + mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class)); - assertDoesNotThrow(() -> automationCompositionElementHandler - .migrate(commonTestData.createCompositionElementDto(), + assertDoesNotThrow(() -> acElementHandler.migrate(commonTestData.createCompositionElementDto(), commonTestData.createCompositionElementDto(), commonTestData.createInstanceElementDto(Map.of()), commonTestData.createInstanceElementDto(Map.of()), 0)); } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClientTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClientTest.java index 77b3ec588..176b65a95 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClientTest.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClientTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021,2025 OpenInfra Foundation Europe. All rights reserved. + * Copyright (C) 2021,2025-2026 OpenInfra Foundation Europe. All rights reserved. * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,7 +30,8 @@ import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import java.io.File; import java.io.IOException; @@ -39,10 +40,6 @@ import java.util.List; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; @@ -51,28 +48,15 @@ import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartStore; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; -import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.util.FileSystemUtils; -@ExtendWith(SpringExtension.class) class HelmClientTest { private static final Coder CODER = new StandardCoder(); private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; private static List charts; - @InjectMocks - @Spy - private HelmClient helmClient = new HelmClient(); - - @Mock - ChartStore chartStore; - - @Mock - HelmRepository repo; - - @BeforeAll static void init() throws CoderException { charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); @@ -85,6 +69,8 @@ class HelmClientTest { @Test void test_installChart() throws ServiceException { + var chartStore = mock(ChartStore.class); + var helmClient = spy(new HelmClient(chartStore)); doReturn("success").when(helmClient).executeCommand(any()); doReturn(new File("/target/tmp/override.yaml")).when(chartStore) .getOverrideFile(any()); @@ -96,14 +82,17 @@ class HelmClientTest { doReturn("").when(helmClient).executeCommand(any()); assertDoesNotThrow(() -> helmClient.installChart(chartinfo)); - } @Test void test_addRepository() throws ServiceException { + var chartStore = mock(ChartStore.class); + var helmClient = spy(new HelmClient(chartStore)); doReturn("").when(helmClient).executeCommand(any()); - when(repo.getRepoName()).thenReturn("RepoName"); - when(repo.getAddress()).thenReturn("http://localhost:8080"); + + var repo = new HelmRepository(); + repo.setRepoName("RepoName"); + repo.setAddress("http://localhost:8080"); assertDoesNotThrow(() -> helmClient.addRepository(repo)); doReturn("failed").when(helmClient).executeCommand(any()); @@ -112,6 +101,8 @@ class HelmClientTest { @Test void test_findChartRepository() throws IOException, ServiceException { + var chartStore = mock(ChartStore.class); + var helmClient = spy(new HelmClient(chartStore)); String tmpPath = "target/tmp/dummyChart/1.0/"; doReturn("nginx-stable/nginx-ingress\t0.9.3\t1.11.3" + " \tNGINX Ingress Controller").when(helmClient).executeCommand(any()); @@ -135,6 +126,8 @@ class HelmClientTest { @Test void test_uninstallChart() throws ServiceException { + var chartStore = mock(ChartStore.class); + var helmClient = spy(new HelmClient(chartStore)); doReturn("success").when(helmClient).executeCommand(any()); helmClient.uninstallChart(charts.get(0)); doThrow(ServiceException.class).when(helmClient).executeCommand(any()); @@ -145,9 +138,10 @@ class HelmClientTest { @Test void test_verifyConfiguredRepoForInvalidChart() throws ServiceException { + var chartStore = mock(ChartStore.class); + var helmClient = spy(new HelmClient(chartStore)); doReturn("").when(helmClient).executeCommand(any()); String configuredRepo = helmClient.verifyConfiguredRepo(charts.get(1)); assertNull(configuredRepo); } - } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java index c9253856b..7d04d0fc8 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022,2024 Nordix Foundation. + * Copyright (C) 2021-2022,2024,2026 OpenInfra Foundation Europe. All rights reserved. * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,14 +25,11 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import java.io.File; -import java.util.List; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; @@ -40,54 +37,49 @@ import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.models.base.PfModelException; -import org.springframework.test.context.junit.jupiter.SpringExtension; -@ExtendWith(SpringExtension.class) class PodStatusValidatorTest { private static final Coder CODER = new StandardCoder(); private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; private static final int TIMEOUT = 2; private static final int STATUS_CHECK_INTERVAL = 1; - private static List charts; - - @InjectMocks - private PodStatusValidator podStatusValidator = new PodStatusValidator(charts.get(0), TIMEOUT, - STATUS_CHECK_INTERVAL); - - @InjectMocks - private PodStatusValidator podValidatorWithPodName = new PodStatusValidator(charts.get(2), TIMEOUT, - STATUS_CHECK_INTERVAL); - - - @Mock - private HelmClient client; + private static ChartInfo chart0; + private static ChartInfo chart2; @BeforeAll static void init() throws CoderException { - charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + var charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + chart0 = charts.get(0); + chart2 = charts.get(2); } - @Test void test_RunningPodState() throws ServiceException { + var client = mock(HelmClient.class); + var podStatusValidator = new PodStatusValidator(client); String runningPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\r\nHelloWorld-54777df9f8-qpzqr\t1/1\tRunning\t0\t9h"; doReturn(runningPod).when(client).executeCommand(any()); - assertDoesNotThrow(() -> podStatusValidator.run()); + assertDoesNotThrow(() -> podStatusValidator.run(TIMEOUT, STATUS_CHECK_INTERVAL, chart0)); } @Test void test_InvalidPodState() throws ServiceException { + var client = mock(HelmClient.class); + var podStatusValidator = new PodStatusValidator(client); String invalidPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\nhellofromdocker-54777df9f8-qpzqr\t1/1\tInit\t0\t9h"; doReturn(invalidPod).when(client).executeCommand(any()); - assertThrows(PfModelException.class, () -> podStatusValidator.run()); + assertThrows(PfModelException.class, + () -> podStatusValidator.run(TIMEOUT, STATUS_CHECK_INTERVAL, chart0)); } // Use case scenario: Hard coded pod name @Test void test_RunningPodStateWithPodName() throws ServiceException { + var client = mock(HelmClient.class); + var podStatusValidator = new PodStatusValidator(client); String runningPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\r\nhelloallworld-54777df9f8-qpzqr\t1/1\tRunning\t0\t9h"; doReturn(runningPod).when(client).executeCommand(any()); - assertDoesNotThrow(() -> podValidatorWithPodName.run()); + assertDoesNotThrow(() -> podStatusValidator.run(TIMEOUT, STATUS_CHECK_INTERVAL, chart2)); } } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartServiceTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartServiceTest.java index 669ca3fe3..7e04653c9 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartServiceTest.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartServiceTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation. + * Copyright (C) 2021-2022,2026 OpenInfra Foundation Europe. All rights reserved. * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,54 +27,35 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; import java.util.List; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; -import org.onap.policy.clamp.acm.participant.kubernetes.configurations.HelmRepositoryConfig; import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; import org.onap.policy.clamp.acm.participant.kubernetes.helm.HelmClient; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository; +import org.onap.policy.clamp.acm.participant.kubernetes.parameters.HelmRepositoryConfig; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; import org.springframework.mock.web.MockMultipartFile; -import org.springframework.test.context.junit.jupiter.SpringExtension; -@ExtendWith(SpringExtension.class) class ChartServiceTest { private static final Coder CODER = new StandardCoder(); private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; private static List charts; - @InjectMocks - @Spy - private ChartService chartService = new ChartService(); - - @Mock - private ChartStore chartStore; - - @Mock - private HelmClient helmClient; - - @Mock - private HelmRepositoryConfig helmRepositoryConfig; - @BeforeAll static void init() throws CoderException { charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); @@ -82,77 +63,127 @@ class ChartServiceTest { @Test void test_getAllCharts() { - assertThat(chartService.getAllCharts()).isEmpty(); + var chartStore = mock(ChartStore.class); + var helmClient = mock(HelmClient.class); + var chartService = new ChartService(chartStore, helmClient, new HelmRepositoryConfig()); + assertThat(chartService.getAllCharts()).isEmpty(); doReturn(charts).when(chartStore).getAllCharts(); - Collection result = chartService.getAllCharts(); + var result = chartService.getAllCharts(); assertNotNull(result); assertThat(result).containsAll(charts); } @Test void test_getChart() { + var chartStore = mock(ChartStore.class); + var helmClient = mock(HelmClient.class); + var chartService = new ChartService(chartStore, helmClient, new HelmRepositoryConfig()); assertNull(chartService.getChart("dummyName", "dummyversion")); - doReturn(charts.get(0)).when(chartStore).getChart(any(), any()); - ChartInfo chart = chartService.getChart(charts.get(0).getChartId().getName(), - charts.get(0).getChartId().getVersion()); + var chart0 = charts.get(0); + doReturn(chart0).when(chartStore).getChart(any(), any()); + var chart = chartService.getChart(chart0.getChartId().getName(), chart0.getChartId().getVersion()); assertNotNull(chart); - assertThat(chart.getNamespace()).isEqualTo(charts.get(0).getNamespace()); + assertThat(chart.getNamespace()).isEqualTo(chart0.getNamespace()); } @Test void test_saveChart() throws IOException, ServiceException { - doThrow(IOException.class).when(chartStore).saveChart(charts.get(0), null, null); - assertThatThrownBy(() -> chartService.saveChart(charts.get(0), null, null)) + var chart0 = charts.get(0); + var chartStore = mock(ChartStore.class); + doThrow(IOException.class).when(chartStore).saveChart(chart0, null, null); + var helmClient = mock(HelmClient.class); + var chartService = new ChartService(chartStore, helmClient, new HelmRepositoryConfig()); + assertThatThrownBy(() -> chartService.saveChart(chart0, null, null)) .isInstanceOf(IOException.class); - MockMultipartFile mockChartFile = new MockMultipartFile("chart", "dummy".getBytes()); - MockMultipartFile mockOverrideFile = new MockMultipartFile("override", "dummy".getBytes()); + var mockChartFile = new MockMultipartFile("chart", "dummy".getBytes()); + var mockOverrideFile = new MockMultipartFile("override", "dummy".getBytes()); - doReturn(charts.get(0)).when(chartStore).saveChart(any(), any(), any()); + doReturn(chart0).when(chartStore).saveChart(any(), any(), any()); - ChartInfo chart = chartService.saveChart(charts.get(0), mockChartFile, mockOverrideFile); + var chart = chartService.saveChart(chart0, mockChartFile, mockOverrideFile); assertNotNull(chart); - assertThat(chart.getChartId().getName()).isEqualTo(charts.get(0).getChartId().getName()); + assertThat(chart.getChartId().getName()).isEqualTo(chart0.getChartId().getName()); + } + @Test + void test_FailInstallChart() throws IOException, ServiceException { + var helmRepositoryConfig = new HelmRepositoryConfig(); + helmRepositoryConfig.setRepos("[]"); + helmRepositoryConfig.setProtocols("http,https"); + var chartStore = mock(ChartStore.class); + var helmClient = mock(HelmClient.class); + var chartService = new ChartService(chartStore, helmClient, helmRepositoryConfig); + doReturn("dummyRepoName").when(helmClient).findChartRepository(any()); + var testChart = charts.get(1); + var result = chartService.installChart(testChart); + assertTrue(result); + } + + @Test + void test_FailEncodeInstallChart() { + var helmRepositoryConfig = new HelmRepositoryConfig(); + helmRepositoryConfig.setRepos("["); + helmRepositoryConfig.setProtocols("http,https"); + var chartStore = mock(ChartStore.class); + var helmClient = mock(HelmClient.class); + var chartService = new ChartService(chartStore, helmClient, helmRepositoryConfig); + var chart0 = charts.get(0); + assertThatThrownBy(() -> chartService.installChart(chart0)).isInstanceOf(ServiceException.class); } @Test - void test_installChart() throws IOException, ServiceException { - List helmRepositoryList = new ArrayList<>(); - helmRepositoryList.add(HelmRepository.builder().address("https://localhost:8080").build()); - doReturn(helmRepositoryList).when(helmRepositoryConfig).getRepos(); - doReturn(List.of("http", "https")).when(helmRepositoryConfig).getProtocols(); - assertDoesNotThrow(() -> chartService.installChart(charts.get(0))); + void test_installChart() throws IOException, ServiceException, CoderException { + var helmRepositoryConfig = new HelmRepositoryConfig(); + var repos = List.of(HelmRepository.builder().address("https://localhost:8080").build()); + helmRepositoryConfig.setRepos(CODER.encode(repos)); + helmRepositoryConfig.setProtocols("http,https"); + var chart0 = charts.get(0); + var chartStore = mock(ChartStore.class); + var helmClient = mock(HelmClient.class); + var chartService = new ChartService(chartStore, helmClient, helmRepositoryConfig); + assertDoesNotThrow(() -> chartService.installChart(chart0)); + doThrow(ServiceException.class).when(helmClient).installChart(any()); - assertThatThrownBy(() -> chartService.installChart(charts.get(0))).isInstanceOf(ServiceException.class); + assertThatThrownBy(() -> chartService.installChart(chart0)).isInstanceOf(ServiceException.class); - doReturn("dummyRepoName").when(chartService).findChartRepo(any()); - doNothing().when(helmClient).installChart(any()); - chartService.installChart(charts.get(1)); - assertEquals("dummyRepoName", charts.get(1).getRepository().getRepoName()); + doReturn("dummyRepoName").when(helmClient).findChartRepository(any()); + var testChart = charts.get(1); + chartService.installChart(testChart); + assertEquals("dummyRepoName", testChart.getRepository().getRepoName()); - ChartInfo testChart = charts.get(1); testChart.setRepository(null); - doReturn(null).when(chartService).findChartRepo(any()); - chartService.installChart(charts.get(1)); + doReturn(null).when(helmClient).findChartRepository(any()); + chartService.installChart(testChart); + + chartService.deleteChart(testChart); + verify(chartStore).deleteChart(testChart); } @Test void test_UninstallChart() throws ServiceException { - assertDoesNotThrow(() -> chartService.uninstallChart(charts.get(0))); + var chart0 = charts.get(0); + var chartStore = mock(ChartStore.class); + var helmClient = mock(HelmClient.class); + var chartService = new ChartService(chartStore, helmClient, new HelmRepositoryConfig()); + assertDoesNotThrow(() -> chartService.uninstallChart(chart0)); doThrow(ServiceException.class).when(helmClient).uninstallChart(any()); - assertThatThrownBy(() -> chartService.uninstallChart(charts.get(0))).isInstanceOf(ServiceException.class); + assertThatThrownBy(() -> chartService.uninstallChart(chart0)).isInstanceOf(ServiceException.class); } @Test void test_findChartRepo() throws IOException, ServiceException { - assertDoesNotThrow(() -> chartService.findChartRepo(charts.get(0))); + var chart0 = charts.get(0); + var chartStore = mock(ChartStore.class); + var helmClient = mock(HelmClient.class); + var chartService = new ChartService(chartStore, helmClient, new HelmRepositoryConfig()); + assertDoesNotThrow(() -> chartService.findChartRepo(chart0)); doReturn("dummyRepoName").when(helmClient).findChartRepository(any()); assertEquals("dummyRepoName", chartService.findChartRepo(charts.get(1))); doThrow(ServiceException.class).when(helmClient).findChartRepository(any()); - assertThatThrownBy(() -> chartService.findChartRepo(charts.get(0))).isInstanceOf(ServiceException.class); + assertThatThrownBy(() -> chartService.findChartRepo(chart0)).isInstanceOf(ServiceException.class); } }