From 6ad41e3ccd398a2721f41ad61c80b7bb03f7d127 Mon Sep 17 00:00:00 2001 From: Ittay Stern Date: Mon, 31 Dec 2018 17:21:27 +0200 Subject: Merge from ECOMP's repository Main Features -------------- - Async-Instantiation jobs mechanism major update; still WIP (package `org.onap.vid.job`) - New features in View/Edit: Activate fabric configuration; show related networks; soft delete - Support AAI service-tree traversal (`AAIServiceTree`) - In-memory cache for SDC models and certain A&AI queries (`CacheProviderWithLoadingCache`) - Upgrade TOSCA Parser and add parsing options; fix malformed TOSCA models - Resolve Cloud-Owner values for MSO - Pass X-ONAP headers to MSO Infrastructure -------------- - Remove codehaus' jackson mapper; use soley fasterxml 2.9.7 - Surefire invokes both TestNG and JUnit tests - Support Kotlin source files - AaiController2 which handles errors in a "Spring manner" - Inline generated-sources and remove jsonschema2pojo Quality -------- - Cumulative bug fixes (A&AI API, UI timeouts, and many more) - Many Sonar issues cleaned-up - Some unused classes removed - Minor changes in vid-automation project, allowing some API verification to run Hard Merges ------------ - HTTP Clients (MSO, A&AI, WebConfig, OutgoingRequestHeadersTest) - Moved `package org.onap.vid.controllers` to `controller`, without plural -- just to keep semantic sync with ECOMP. Reference commit in ECOMP: 3d1141625 Issue-ID: VID-378 Change-Id: I9c8d1e74caa41815891d441fc0760bb5f29c5788 Signed-off-by: Ittay Stern --- .../org/onap/vid/job/command/CommandUtilsTest.java | 88 ++++++ .../job/command/InProgressStatusCommandTest.java | 143 ---------- .../job/command/InProgressStatusServiceTest.java | 83 ++++++ .../vid/job/command/InstanceGroupCommandTest.java | 85 ++++++ .../vid/job/command/JobCommandFactoryTest.java | 36 ++- .../onap/vid/job/command/ResourceCommandTest.java | 303 +++++++++++++++++++++ .../ResourceInProgressStatusCommandTest.java | 40 +++ .../ServiceInProgressStatusCommandTest.java | 208 ++++++++++++++ .../command/ServiceInstantiationCommandTest.java | 157 ----------- .../vid/job/command/WatchChildrenJobsBLTest.java | 98 +++++++ .../onap/vid/job/command/WatchingCommandTest.java | 77 ++++++ 11 files changed, 1017 insertions(+), 301 deletions(-) create mode 100644 vid-app-common/src/test/java/org/onap/vid/job/command/CommandUtilsTest.java delete mode 100644 vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusCommandTest.java create mode 100644 vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusServiceTest.java create mode 100644 vid-app-common/src/test/java/org/onap/vid/job/command/InstanceGroupCommandTest.java create mode 100644 vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java create mode 100644 vid-app-common/src/test/java/org/onap/vid/job/command/ResourceInProgressStatusCommandTest.java create mode 100644 vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInProgressStatusCommandTest.java delete mode 100644 vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInstantiationCommandTest.java create mode 100644 vid-app-common/src/test/java/org/onap/vid/job/command/WatchChildrenJobsBLTest.java create mode 100644 vid-app-common/src/test/java/org/onap/vid/job/command/WatchingCommandTest.java (limited to 'vid-app-common/src/test/java/org/onap/vid/job/command') diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/CommandUtilsTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/CommandUtilsTest.java new file mode 100644 index 000000000..61a54f250 --- /dev/null +++ b/vid-app-common/src/test/java/org/onap/vid/job/command/CommandUtilsTest.java @@ -0,0 +1,88 @@ +package org.onap.vid.job.command; + +import com.google.common.collect.ImmutableMap; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.vid.asdc.AsdcCatalogException; +import org.onap.vid.model.GroupProperties; +import org.onap.vid.model.ServiceModel; +import org.onap.vid.model.VfModule; +import org.onap.vid.services.VidService; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.Collections; +import java.util.Map; +import java.util.UUID; + +import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.mockito.Mockito.*; + +public class CommandUtilsTest { + + @InjectMocks + CommandUtils commandUtils; + + @Mock + VidService vidService; + + @BeforeClass + public void initMocks() { + MockitoAnnotations.initMocks(this); + } + + @AfterMethod + public void resetVidService() { + reset(vidService); + } + + @DataProvider + public static Object[][] trueAndFalse() { + return new Object[][]{ {true}, {false} }; + } + + @Test(dataProvider="trueAndFalse") + void testIsVfModelIsBaseModule(boolean isBase) throws AsdcCatalogException { + final String serviceModelUuid = UUID.randomUUID().toString(); + final String vfModuleUuid = UUID.randomUUID().toString(); + + ServiceModel mockedServiceModel = mock(ServiceModel.class); + VfModule mockedVfModule = mock(VfModule.class); + GroupProperties mockedGroupProperties = mock(GroupProperties.class); + Map vfModulesMap = ImmutableMap.of(randomAlphanumeric(10), mockedVfModule); + + when(vidService.getService(serviceModelUuid)).thenReturn(mockedServiceModel); + when(mockedServiceModel.getVfModules()).thenReturn(vfModulesMap); + when(mockedVfModule.getUuid()).thenReturn(vfModuleUuid); + when(mockedVfModule.getProperties()).thenReturn(mockedGroupProperties); + when(mockedGroupProperties.getBaseModule()).thenReturn(isBase); + + assertThat(commandUtils.isVfModuleBaseModule(serviceModelUuid, vfModuleUuid), equalTo(isBase)); + } + + @Test(expectedExceptions = AsdcCatalogException.class) + void whenCantFindModelInSdc_thenExceptionIsThrown() throws AsdcCatalogException { + String serviceModelUuid = UUID.randomUUID().toString(); + when(vidService.getService(serviceModelUuid)).thenReturn(null); + commandUtils.isVfModuleBaseModule(serviceModelUuid, "abc"); + } + + @Test(expectedExceptions = AsdcCatalogException.class) + void whenCantFindVfModuleInModel_thenExceptionIsThrown() throws AsdcCatalogException { + + String serviceModelUuid = UUID.randomUUID().toString(); + + ServiceModel mockedServiceModel = mock(ServiceModel.class); + Map emptyMap = Collections.emptyMap(); + + when(vidService.getService(serviceModelUuid)).thenReturn(mockedServiceModel); + when(mockedServiceModel.getVfModules()).thenReturn(emptyMap); + + commandUtils.isVfModuleBaseModule(serviceModelUuid, "abc"); + } +} diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusCommandTest.java deleted file mode 100644 index bc623928c..000000000 --- a/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusCommandTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * VID - * ================================================================================ - * Copyright (C) 2018 Nokia Intellectual Property. 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.vid.job.command; - - -import io.joshworks.restclient.http.HttpResponse; -import org.mockito.Mock; -import org.onap.vid.job.Job; -import org.onap.vid.job.NextCommand; -import org.onap.vid.mso.MsoInterface; -import org.onap.vid.mso.rest.AsyncRequestStatus; -import org.onap.vid.services.AsyncInstantiationBusinessLogic; -import org.onap.vid.services.AuditService; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import javax.ws.rs.ProcessingException; -import java.util.UUID; - - -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; - -public class InProgressStatusCommandTest { - - @Mock - private AsyncInstantiationBusinessLogic asyncInstantiationBusinessLogic; - - @Mock - private MsoInterface msoInterface; - - @Mock - private AuditService auditService; - - @Mock - private HttpResponse msoResponse; - - @Mock - private AsyncRequestStatus asyncRequestStatus; - - @Mock - private AsyncRequestStatus.Request request; - - private UUID uuid = UUID.randomUUID(); - - private InProgressStatusCommand inProgressStatusCommand; - - @BeforeMethod - public void setUp() { - initMocks(this); - - inProgressStatusCommand = new InProgressStatusCommand(asyncInstantiationBusinessLogic, msoInterface, auditService, uuid, "sampleRequestId"); - - when(asyncInstantiationBusinessLogic.getOrchestrationRequestsPath()).thenReturn("http://localhost:8080/samplePath"); - when(msoInterface.get("http://localhost:8080/samplePath/sampleRequestId", AsyncRequestStatus.class)).thenReturn(msoResponse); - when(msoResponse.getBody()).thenReturn(asyncRequestStatus); - } - - - @Test - public void whenSOReturnsErrorShouldSetProperFailureStateAndReturnRetryCommand() { - when(msoResponse.getStatus()).thenReturn(500); - - NextCommand call = inProgressStatusCommand.call(); - - assertThat(call.getStatus()).isEqualTo(Job.JobStatus.IN_PROGRESS); - assertThat(call.getCommand()).isEqualTo(inProgressStatusCommand); - - verify(auditService).setFailedAuditStatusFromMso(uuid, "sampleRequestId", 500, asyncRequestStatus.toString()); - } - - @Test - public void shouldProperlyHandleFailedInstantiation() { - when(msoResponse.getStatus()).thenReturn(200); - when(asyncInstantiationBusinessLogic.calcStatus(asyncRequestStatus)).thenReturn(Job.JobStatus.FAILED); - asyncRequestStatus.request = request; - - NextCommand call = inProgressStatusCommand.call(); - - assertThat(call.getCommand()).isEqualTo(inProgressStatusCommand); - assertThat(call.getStatus()).isEqualTo(Job.JobStatus.FAILED); - - verify(asyncInstantiationBusinessLogic).handleFailedInstantiation(uuid); - verify(asyncInstantiationBusinessLogic).auditMsoStatus(uuid, request); - } - - @Test - public void shouldRetryCommandWithPausedState() { - when(msoResponse.getStatus()).thenReturn(200); - when(asyncInstantiationBusinessLogic.calcStatus(asyncRequestStatus)).thenReturn(Job.JobStatus.PAUSE); - asyncRequestStatus.request = request; - - NextCommand call = inProgressStatusCommand.call(); - - assertThat(call.getCommand()).isEqualTo(inProgressStatusCommand); - assertThat(call.getStatus()).isEqualTo(Job.JobStatus.IN_PROGRESS); - - verify(asyncInstantiationBusinessLogic).auditMsoStatus(uuid, request); - verify(asyncInstantiationBusinessLogic).updateServiceInfoAndAuditStatus(uuid, Job.JobStatus.PAUSE); - } - - @Test - public void shouldRetryCommandExitedWithProcessingException() { - when(msoResponse.getStatus()).thenReturn(200); - when(asyncInstantiationBusinessLogic.calcStatus(asyncRequestStatus)).thenThrow(new ProcessingException("")); - - NextCommand call = inProgressStatusCommand.call(); - - assertThat(call.getCommand()).isEqualTo(inProgressStatusCommand); - assertThat(call.getStatus()).isEqualTo(Job.JobStatus.IN_PROGRESS); - } - - @Test - public void shouldSetStoppedStatusWhenRuntimeExceptionOccurs() { - when(msoResponse.getStatus()).thenReturn(200); - when(asyncInstantiationBusinessLogic.calcStatus(asyncRequestStatus)).thenThrow(new RuntimeException()); - - NextCommand call = inProgressStatusCommand.call(); - - assertThat(call.getCommand()).isEqualTo(inProgressStatusCommand); - assertThat(call.getStatus()).isEqualTo(Job.JobStatus.STOPPED); - } -} \ No newline at end of file diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusServiceTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusServiceTest.java new file mode 100644 index 000000000..2e8139716 --- /dev/null +++ b/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusServiceTest.java @@ -0,0 +1,83 @@ +package org.onap.vid.job.command; + +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.vid.job.Job; +import org.onap.vid.job.impl.JobSharedData; +import org.onap.vid.model.serviceInstantiation.ServiceInstantiation; +import org.onap.vid.mso.RestMsoImplementation; +import org.onap.vid.mso.RestObject; +import org.onap.vid.mso.rest.AsyncRequestStatus; +import org.onap.vid.services.AsyncInstantiationBaseTest; +import org.onap.vid.services.AsyncInstantiationBusinessLogic; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.UUID; +import java.util.stream.Stream; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; +import static org.testng.AssertJUnit.assertEquals; + +public class InProgressStatusServiceTest { + + @Mock + private RestMsoImplementation restMso; + + @Mock + private AsyncInstantiationBusinessLogic asyncInstantiationBL; + + @InjectMocks + private InProgressStatusService inProgressStatusService; + + @BeforeClass + public void initMocks() { + MockitoAnnotations.initMocks(this); + } + + @DataProvider + public static Object[][] jobStatuses() { + return Stream.of(Job.JobStatus.values()) + .map(student -> new Object[] { student }) + .toArray(Object[][]::new); + } + + @Test(dataProvider = "jobStatuses") + public void whenGetFromMsoRequestStatus_returnItToCaller(Job.JobStatus expectedJobStatus) { + + UUID jobUuid = UUID.randomUUID(); + String userId = "mockedUserID"; + String requestId = UUID.randomUUID().toString(); + ServiceInstantiation serviceInstantiation = mock(ServiceInstantiation.class); + + when(asyncInstantiationBL.getOrchestrationRequestsPath()).thenReturn(""); + + RestObject msoResponse = mock(RestObject.class); + AsyncRequestStatus requestStatus = AsyncInstantiationBaseTest.asyncRequestStatusResponse(""); + + when(msoResponse.getStatusCode()).thenReturn(200); + when(msoResponse.get()).thenReturn(requestStatus); + when(restMso.GetForObject(contains(requestId), eq(AsyncRequestStatus.class))).thenReturn(msoResponse); + + when(asyncInstantiationBL.calcStatus(any())).thenReturn(expectedJobStatus); + + ExpiryChecker expiryChecker = mock(ExpiryChecker.class); + when(expiryChecker.isExpired(any())).thenReturn(false); + + JobSharedData sharedData = new JobSharedData(jobUuid, userId, serviceInstantiation); + Job.JobStatus actualJobStatus = inProgressStatusService.call(expiryChecker, sharedData, requestId); + assertEquals(expectedJobStatus, actualJobStatus); + + verify(asyncInstantiationBL).auditMsoStatus(eq(jobUuid), same(requestStatus.request)); + + //verify we don't update service info during this case, which shall stay in_progress + verify(asyncInstantiationBL, never()).updateServiceInfo(any(), any()); + + + } + +} diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/InstanceGroupCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/InstanceGroupCommandTest.java new file mode 100644 index 000000000..4cd00174a --- /dev/null +++ b/vid-app-common/src/test/java/org/onap/vid/job/command/InstanceGroupCommandTest.java @@ -0,0 +1,85 @@ +package org.onap.vid.job.command; + +import com.google.common.collect.ImmutableMap; +import org.apache.commons.beanutils.BeanUtils; +import org.mockito.Answers; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.vid.job.impl.JobSharedData; +import org.onap.vid.model.RequestReferencesContainer; +import org.onap.vid.model.serviceInstantiation.InstanceGroup; +import org.onap.vid.mso.RestMsoImplementation; +import org.onap.vid.mso.model.ModelInfo; +import org.onap.vid.services.AsyncInstantiationBusinessLogic; +import org.springframework.http.HttpMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.util.Optional; +import java.util.Set; + +import static java.util.function.Function.identity; +import static java.util.stream.Collectors.toMap; +import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +public class InstanceGroupCommandTest { + + @Mock(answer = Answers.RETURNS_MOCKS) + RestMsoImplementation restMso; + + @Mock InstanceGroup instanceGroupRequest; + + @Mock(answer = Answers.RETURNS_MOCKS) + MsoResultHandlerService msoResultHandlerService; + + @Mock WatchChildrenJobsBL watchChildrenJobsBL; + + @Mock(answer = Answers.RETURNS_MOCKS) + AsyncInstantiationBusinessLogic asyncInstantiationBL; + + @Mock InProgressStatusService inProgressStatusService; + + @InjectMocks + private InstanceGroupCommand command; + + @BeforeMethod + public void initMocks() { + command = null; + MockitoAnnotations.initMocks(this); + } + + @Test + public void createMyself_callsMso() { + final ModelInfo serviceModelInfo = setRandomStrings(new ModelInfo()); + final String serviceInstanceId = "service-instance-id"; + final String userId = "ff3223"; + + command.init(new JobSharedData( + null, userId, instanceGroupRequest + ), ImmutableMap.of( + "resourceModelInfos", ImmutableMap.of("SERVICE_MODEL_INFO", serviceModelInfo), + "resourceInstancesIds", ImmutableMap.of("SERVICE_INSTANCE_ID", serviceInstanceId) + )); + + command.createMyself(); + + verify(asyncInstantiationBL).generateInstanceGroupInstantiationRequest( + same(instanceGroupRequest), eq(serviceModelInfo), eq(serviceInstanceId), eq(userId)); + verify(restMso, only()).restCall(eq(HttpMethod.POST), eq(RequestReferencesContainer.class), any(), any(), eq(Optional.empty())); + + } + + private ModelInfo setRandomStrings(ModelInfo object) { + try { + Set fields = BeanUtils.describe(object).keySet(); + BeanUtils.populate(object, + fields.stream().collect(toMap(identity(), s -> randomAlphanumeric(4)))); + return object; + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/JobCommandFactoryTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/JobCommandFactoryTest.java index b51553be7..2138b77cd 100644 --- a/vid-app-common/src/test/java/org/onap/vid/job/command/JobCommandFactoryTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/job/command/JobCommandFactoryTest.java @@ -1,17 +1,22 @@ package org.onap.vid.job.command; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.collect.ImmutableMap; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.onap.vid.job.Job; +import org.onap.vid.job.JobAdapter; import org.onap.vid.job.JobCommand; import org.onap.vid.job.JobType; +import org.onap.vid.job.impl.JobSharedData; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.util.Arrays; import java.util.Map; +import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; @@ -48,19 +53,48 @@ public class JobCommandFactoryTest { } + public static class MockedRequest implements JobAdapter.AsyncJobRequest { + + final public int x; + final public String y; + + @JsonCreator + public MockedRequest(@JsonProperty("x")int x, @JsonProperty("y")String y) { + this.x = x; + this.y = y; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof MockedRequest)) return false; + MockedRequest that = (MockedRequest) o; + return x == that.x && + Objects.equals(y, that.y); + } + + @Override + public int hashCode() { + + return Objects.hash(x, y); + } + } + @Test(dataProvider = "jobTypes") public void givenJob_createCommandCallsTheInitAndReturnsTheInstance(JobType jobType) { final UUID uuid = UUID.randomUUID(); final Map data = ImmutableMap.of("foo", "bar"); + final JobSharedData sharedData = new JobSharedData(uuid, "userid", new MockedRequest(1,"a")); when(job.getType()).thenReturn(jobType); when(job.getUuid()).thenReturn(uuid); when(job.getData()).thenReturn(data); + when(job.getSharedData()).thenReturn(sharedData); final JobCommand command = jobCommandFactory.toCommand(job); - verify(mockCommand).init(uuid, data); + verify(mockCommand).init(sharedData, data); assertThat(command, equalTo(mockCommand)); } diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java new file mode 100644 index 000000000..29be48edc --- /dev/null +++ b/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java @@ -0,0 +1,303 @@ +package org.onap.vid.job.command; + +import com.google.common.collect.ImmutableMap; +import org.jetbrains.annotations.NotNull; +import org.onap.vid.exceptions.GenericUncheckedException; +import org.onap.vid.job.Job; +import org.onap.vid.job.JobAdapter; +import org.onap.vid.job.NextCommand; +import org.onap.vid.job.impl.JobSharedData; +import org.onap.vid.model.Action; +import org.onap.vid.model.serviceInstantiation.BaseResource; +import org.onap.vid.mso.RestMsoImplementation; +import org.springframework.http.HttpMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.ws.rs.ProcessingException; +import java.util.Collections; +import java.util.Optional; +import java.util.stream.Stream; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; +import static org.onap.vid.job.command.ResourceCommandKt.ACTION_PHASE; +import static org.onap.vid.job.command.ResourceCommandKt.INTERNAL_STATE; +import static org.onap.vid.utils.Logging.getMethodCallerName; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; + +public class ResourceCommandTest { + + public static class MockCommand extends ResourceCommand { + + public MockCommand(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus) { + super(mock(RestMsoImplementation.class, RETURNS_MOCKS), mock(InProgressStatusService.class), mock(MsoResultHandlerService.class, RETURNS_MOCKS), mock(WatchChildrenJobsBL.class)); + + this.mockedJobStatus = mockedJobStatus; + this.mockState = mockState; + this.mockPhase = mockPhase; + if (mockState==InternalState.INITIAL) { + init(mock(JobSharedData.class), Collections.emptyMap()); + } + else { + init(mock(JobSharedData.class), ImmutableMap.of(INTERNAL_STATE, mockState.name(), ACTION_PHASE, mockPhase.name())); + } + when(this.getWatchChildrenJobsBL().cumulateJobStatus(any(), any())).thenReturn(mockedJobStatus); + } + + private final Job.JobStatus mockedJobStatus; + private final InternalState mockState; + private final Action mockPhase; + + + @NotNull + @Override + public Job.JobStatus createChildren() { + if (mockState == InternalState.CREATING_CHILDREN || (mockState == InternalState.INITIAL && mockPhase== Action.Delete)) + return mockedJobStatus; + throw (new RuntimeException("Not expected to call "+getMethodCallerName())); + } + + protected Job.JobStatus mockedStatusOrThrow(InternalState expectedState) { + if (mockState == expectedState) + return mockedJobStatus; + throw (new RuntimeException("Not expected to call "+getMethodCallerName())); + } + + protected MsoRestCallPlan mockedPlanOrThrow(InternalState expectedState) { + if (mockState == expectedState) + return new MsoRestCallPlan(HttpMethod.POST, "path", Optional.empty(), Optional.empty(), "nothing"); + throw (new RuntimeException("Not expected to call "+getMethodCallerName())); + } + + @NotNull + @Override + public MsoRestCallPlan planCreateMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId) { + return mockedPlanOrThrow(InternalState.CREATE_MYSELF); + } + + @NotNull + @Override + public MsoRestCallPlan planDeleteMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId) { + return mockedPlanOrThrow(InternalState.DELETE_MYSELF); + } + } + + public static class MockCommandTestingStateMachine extends MockCommand { + + private final JobSharedData sharedData; + + public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf) { + this(mockState, mockPhase, mockedJobStatus, mockedNeedToDeleteMySelf, false); + } + + public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf, boolean isService) { + super(mockState, mockPhase, mockedJobStatus); + this.mockedNeedToDeleteMySelf = mockedNeedToDeleteMySelf; + this.isService = isService; + this.sharedData = mock(JobSharedData.class, RETURNS_MOCKS); + } + + protected final boolean mockedNeedToDeleteMySelf; + private final boolean isService; + + @NotNull + @Override + public Job.JobStatus inProgress() { + return mockedStatusOrThrow(InternalState.IN_PROGRESS); + } + + @NotNull + @Override + public Job.JobStatus watchChildren() { + return mockedStatusOrThrow(InternalState.WATCHING); + } + + @Override + public boolean isNeedToDeleteMyself() { + return mockedNeedToDeleteMySelf; + } + + @Override + protected boolean isServiceCommand() { + return isService; + } + + @Override + public JobSharedData getSharedData() { + return sharedData; + } + } + + @DataProvider + public static Object[][] nextStateDeletePhaseProvider() { + return new Object[][]{ + {InternalState.CREATING_CHILDREN, Job.JobStatus.COMPLETED, InternalState.WATCHING}, + {InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF}, + {InternalState.WATCHING, Job.JobStatus.IN_PROGRESS, InternalState.WATCHING}, + {InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING}, + {InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS}, + {InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, InternalState.TERMINAL}, + {InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS}, + {InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.IN_PROGRESS}, + }; + } + + @Test(dataProvider = "nextStateDeletePhaseProvider") + public void whenCalcNextStateDeletePhase_expectedStateIsReturned( + InternalState internalState, Job.JobStatus jobStatus, InternalState expectedState) { + + //there is no meaning to the constructor inputs here + MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.TERMINAL, Action.Delete, Job.JobStatus.FAILED, true); + assertEquals(expectedState, underTest.calcNextStateDeletePhase(jobStatus, internalState)); + } + + @Test + public void whenNoNeedToDeleteMyself_internalStateMovesFromWatchingToTerminal() { + MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Action.Delete, Job.JobStatus.COMPLETED, false); + assertEquals(InternalState.TERMINAL, underTest.calcNextStateDeletePhase(Job.JobStatus.COMPLETED, InternalState.WATCHING)); + } + + @DataProvider + public static Object[][] testShallStopJobDataProvider() { + return new Object[][]{ + {Job.JobStatus.IN_PROGRESS, Action.None, false, false}, + {Job.JobStatus.COMPLETED_WITH_NO_ACTION, Action.None, false, false}, + {Job.JobStatus.COMPLETED, Action.None, false, false}, + {Job.JobStatus.FAILED, Action.None, false, true}, + {Job.JobStatus.COMPLETED_WITH_ERRORS, Action.None, false, true}, + {Job.JobStatus.COMPLETED_WITH_ERRORS, Action.None, true, false}, + {Job.JobStatus.FAILED, Action.None, true, false}, + {Job.JobStatus.FAILED, Action.Delete, true, true}, + {Job.JobStatus.FAILED, Action.Create, true, true}, + }; + } + + + @Test(dataProvider = "testShallStopJobDataProvider") + public void testShallStopJob(Job.JobStatus jobStatus, Action action, boolean isService, boolean expectedResult) { + //in this test, there is no meaning to constructor parameters besides isService + MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Action.Delete, Job.JobStatus.COMPLETED, false, isService); + + BaseResource mockedRequest = mock(BaseResource.class); + when(underTest.getSharedData().getRequest()).thenReturn(mockedRequest); + when(mockedRequest.getAction()).thenReturn(action); + + assertEquals(expectedResult, underTest.shallStopJob(jobStatus)); + } + + @DataProvider + public static Object[][] testCallDataProvider() { + return new Object[][]{ + {"initial state with successful creating children" ,InternalState.INITIAL, Job.JobStatus.COMPLETED, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS}, + {"initial state with failed creating children", InternalState.INITIAL, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED}, + {"watching state with children still in progress" ,InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS}, + {"watching state with children that completed with errors" ,InternalState.WATCHING, Job.JobStatus.COMPLETED_WITH_ERRORS, null, Job.JobStatus.COMPLETED_WITH_ERRORS}, + {"watching state with children that completed with no action" ,InternalState.WATCHING, Job.JobStatus.COMPLETED_WITH_NO_ACTION, InternalState.DELETE_MYSELF, Job.JobStatus.RESOURCE_IN_PROGRESS}, + {"watching state with children that has completed" ,InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF, Job.JobStatus.RESOURCE_IN_PROGRESS}, + {"mso call state that failed" ,InternalState.DELETE_MYSELF, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED}, + //TODO handle AAI get unique name state {"mso call state that still in progress" ,InternalState.DELETE_MYSELF, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED, false}, + {"mso call state that success" ,InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS}, + {"in progress return in progress" ,InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS}, + {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.PAUSE, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS}, + {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.STOPPED, null, Job.JobStatus.STOPPED}, + {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED}, + {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, null, Job.JobStatus.COMPLETED}, + + }; + } + + @Test(dataProvider = "testCallDataProvider") + public void whenCallCommandWithDeletePhase_nextJobStatusAndInternalStateAreAsExpected( + String description, InternalState internalState, Job.JobStatus currentStateResult, + InternalState expectedNextState, Job.JobStatus expectedNextStatus) { + + MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(internalState, Action.Delete, currentStateResult, true); + NextCommand nextCommand = underTest.call(); + assertEquals(expectedNextStatus, nextCommand.getStatus()); + + //expectedNextState == null means nextCommand has no real command + if (expectedNextState!=null) { + assertEquals(expectedNextState, (nextCommand.getCommand().getData().get(INTERNAL_STATE))); + assertFalse(nextCommand.getStatus().isFinal()); + } + else { + assertNull(nextCommand.getCommand()); + assertTrue(nextCommand.getStatus().isFinal()); + } + } + + @Test(expectedExceptions = IllegalStateException.class) + public void whenCommandInUnMappedState_exceptionIsThrown() { + MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.TERMINAL, Action.Delete, Job.JobStatus.COMPLETED, true); + underTest.call(); + } + + @DataProvider + public static Object[][] InProgressDataProvider() { + return Stream.of(Job.JobStatus.values()) + .map(status -> new Object[] { status }) + .toArray(Object[][]::new); + } + + @Test(dataProvider = "InProgressDataProvider") + public void whenGetResultFromMso_InProgressReturnThem(Job.JobStatus mockedJobStatus) { + Job.JobStatus expectedJobStatus = (mockedJobStatus== Job.JobStatus.PAUSE) ? Job.JobStatus.IN_PROGRESS : mockedJobStatus; + MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Action.Delete, mockedJobStatus); + when(underTest.getInProgressStatusService().call(any(), any(), any())).thenReturn(mockedJobStatus); + assertEquals(expectedJobStatus, underTest.inProgress()); + } + + @DataProvider + public static Object[][] InProgressExceptionsDataProvider() { + return new Object[][]{ + {new ProcessingException(""), Job.JobStatus.IN_PROGRESS}, + {new InProgressStatusService.BadResponseFromMso(null), Job.JobStatus.IN_PROGRESS}, + {new GenericUncheckedException(""),Job.JobStatus.STOPPED } + }; + } + + @Test(dataProvider = "InProgressExceptionsDataProvider") + public void whenInProgressStatusServiceThrowException_InProgressReturnStatus(Exception exception, Job.JobStatus expectedJobStatus) { + MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Action.Delete, expectedJobStatus); + when(underTest.getInProgressStatusService().call(any(), any(), any())).thenThrow(exception); + assertEquals(expectedJobStatus, underTest.inProgress()); + } + + @DataProvider + public static Object[][] testIsNeedToDeleteMySelfDataProvider() { + return Stream.of(Action.values()) + .map(status -> new Object[] { status }) + .toArray(Object[][]::new); + } + + @Test(dataProvider = "testIsNeedToDeleteMySelfDataProvider") + public void testIsNeedToDeleteMySelf(Action action) { + boolean expectedResult = (action== Action.Delete); + MockCommand underTest = new MockCommand(InternalState.DELETE_MYSELF, Action.Delete, Job.JobStatus.IN_PROGRESS); + BaseResource mockedBaseResource = mock(BaseResource.class); + when(underTest.getSharedData().getRequest()).thenReturn(mockedBaseResource); + when(mockedBaseResource.getAction()).thenReturn(action); + assertEquals(expectedResult, underTest.isNeedToDeleteMyself()); + } + + @DataProvider + public static Object[][] testWatchingDataProvider() { + return new Object[][]{ + {"all children final, no failed child ", Job.JobStatus.COMPLETED, Job.JobStatus.COMPLETED}, + {"all children final, there is failed child ", Job.JobStatus.COMPLETED_WITH_ERRORS, Job.JobStatus.COMPLETED_WITH_ERRORS}, + {"not all children final", Job.JobStatus.IN_PROGRESS, Job.JobStatus.IN_PROGRESS}, + }; + } + + @Test(dataProvider = "testWatchingDataProvider") + public void testWatching(String desc, Job.JobStatus childrenJobsStatus, Job.JobStatus expectedJobStatus) { + MockCommand underTest = new MockCommand(InternalState.WATCHING, Action.Delete, Job.JobStatus.IN_PROGRESS); + when(underTest.getWatchChildrenJobsBL().retrieveChildrenJobsStatus(any())).thenReturn(childrenJobsStatus); + assertEquals(expectedJobStatus, underTest.watchChildren()); + } + +} diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceInProgressStatusCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceInProgressStatusCommandTest.java new file mode 100644 index 000000000..9ec49a2e5 --- /dev/null +++ b/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceInProgressStatusCommandTest.java @@ -0,0 +1,40 @@ +package org.onap.vid.job.command; + +import org.mockito.InjectMocks; +import org.mockito.MockitoAnnotations; +import org.onap.vid.job.Job; +import org.onap.vid.job.NextCommand; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + + +public class ResourceInProgressStatusCommandTest { + + @InjectMocks + private ResourceInProgressStatusCommand commandUnderTest = new ResourceInProgressStatusCommand(); + + @BeforeMethod + public void initMocks() { + MockitoAnnotations.initMocks(this); + } + + @DataProvider + public static Object[][] givenStatusToExpectedStatus() { + return new Object[][]{ + {Job.JobStatus.IN_PROGRESS, Job.JobStatus.IN_PROGRESS}, + {Job.JobStatus.FAILED, Job.JobStatus.FAILED}, + {Job.JobStatus.COMPLETED, Job.JobStatus.COMPLETED} + }; + } + + @Test(dataProvider = "givenStatusToExpectedStatus") + public void whenGetStatusFromMso_returnExpectedNextCommand(Job.JobStatus jobStatus, Job.JobStatus expectedNextStatus) { + NextCommand nextCommand = commandUnderTest.processJobStatus(jobStatus); + assertThat(nextCommand.getStatus(), is(expectedNextStatus)); + assertThat(nextCommand.getCommand(), is(commandUnderTest)); + } +} diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInProgressStatusCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInProgressStatusCommandTest.java new file mode 100644 index 000000000..bfda6cf34 --- /dev/null +++ b/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInProgressStatusCommandTest.java @@ -0,0 +1,208 @@ +package org.onap.vid.job.command; + +import com.google.common.collect.ImmutableMap; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.portalsdk.core.util.SystemProperties; +import org.onap.vid.job.*; +import org.onap.vid.job.impl.JobSharedData; +import org.onap.vid.model.serviceInstantiation.Network; +import org.onap.vid.model.serviceInstantiation.ServiceInstantiation; +import org.onap.vid.model.serviceInstantiation.Vnf; +import org.onap.vid.mso.model.ModelInfo; +import org.onap.vid.properties.Features; +import org.onap.vid.properties.VidProperties; +import org.onap.vid.services.AsyncInstantiationBusinessLogic; +import org.springframework.core.env.Environment; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.togglz.core.manager.FeatureManager; + +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.Map; +import java.util.TreeMap; +import java.util.UUID; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.core.Is.is; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; +import static org.onap.vid.job.Job.JobStatus.*; + +public class ServiceInProgressStatusCommandTest { + + + @Mock + private AsyncInstantiationBusinessLogic asyncInstantiationBL; + + @Mock + private JobsBrokerService jobsBrokerService; + + @Mock + private JobAdapter jobAdapter; + + @Mock + private FeatureManager featureManager; + + @Mock + private JobSharedData sharedData; + + @Mock + private Environment environment; + + @Mock + private ServiceInstantiation request; + + @Mock + private InProgressStatusService inProgressStatusService; + + @InjectMocks + private ServiceInProgressStatusCommand command = new ServiceInProgressStatusCommand(); + + @DataProvider + public static Object[][] isNeedToCreateChildJobsDataProvider() { + return new Object[][]{ + {new TreeMap() , true, true, false}, + {null , true, true, false}, + {ImmutableMap.of("a",mock(Vnf.class)), false, true, false}, + {ImmutableMap.of("a",mock(Vnf.class)), true, false, false}, + {ImmutableMap.of("a",mock(Vnf.class)), true, true, true}, + }; + } + + @DataProvider + public static Object[][] processJobStatusData() { + return new Object[][]{ + /* {MSO jobStatus, jobStartTime, isNeedToCreateChildJobs(), property vid.job.max.hoursInProgress, expected nextCommand.getStatus() } */ + {IN_PROGRESS, false, IN_PROGRESS}, + {FAILED, false, FAILED}, + {PAUSE, false, IN_PROGRESS}, + {COMPLETED, false, COMPLETED}, + {COMPLETED, true, IN_PROGRESS}, + {RESOURCE_IN_PROGRESS, false, RESOURCE_IN_PROGRESS}, + {PENDING, false, PENDING}, + {STOPPED, false, STOPPED}, + {COMPLETED_WITH_ERRORS, false, COMPLETED_WITH_ERRORS}, + {CREATING, false, CREATING} + }; + } + + @DataProvider + public static Object[][] isExpiredJobStatusData() { + return new Object[][]{ + {ZonedDateTime.now(), "24", false}, + {getTimeNowMinus(2), "1", true}, + {getTimeNowMinus(24), "24", true}, + {getTimeNowMinus(2), "0", false}, + {getTimeNowMinus(2), "-1", false}, + {getTimeNowMinus(2), "", false}, + {getTimeNowMinus(2), "a", false} + }; + } + + private static ZonedDateTime getTimeNowMinus(int hoursAgo) { + return ZonedDateTime.ofInstant(Instant.now().minus(hoursAgo, ChronoUnit.HOURS), ZoneOffset.UTC); + } + + @BeforeMethod + public void initMocks() { + MockitoAnnotations.initMocks(this); + } + + @Test(dataProvider = "isNeedToCreateChildJobsDataProvider" ) + public void testIsNeedToCreateChildJobs(Map serviceVnfs, boolean isALaCarte, + boolean isFeatureEnabled, boolean expected) { + MockitoAnnotations.initMocks(this); + ServiceInstantiation serviceInstantiation = mock(ServiceInstantiation.class); + when(serviceInstantiation.getVnfs()).thenReturn(serviceVnfs); + when(serviceInstantiation.isALaCarte()).thenReturn(isALaCarte); + when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(isFeatureEnabled); + assertThat(command.isNeedToCreateChildJobs(serviceInstantiation), is(expected)); + } + + @Test + public void whenGetFromMsoCompletedAndALaCarte_generateNewJobsForVnfs() { + UUID uuid = UUID.randomUUID(); + String userId = "mockedUserID"; + Vnf vnf1 = mock(Vnf.class); + Vnf vnf2 = mock(Vnf.class); + Network network1 = mock(Network.class); + ServiceInstantiation serviceInstantiation = mock(ServiceInstantiation.class); + when(serviceInstantiation.getVnfs()).thenReturn(ImmutableMap.of("a", vnf1, "b", vnf2)); + when(serviceInstantiation.getNetworks()).thenReturn(ImmutableMap.of("c", network1)); + when(serviceInstantiation.isALaCarte()).thenReturn(true); + when(serviceInstantiation.getModelInfo()).thenReturn(new ModelInfo()); + + when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true); + + UUID uuid1 = UUID.fromString("12345678-1234-1234-1234-123456789012"); + UUID uuid2 = UUID.fromString("12345678-1234-1234-1234-123456789013"); + UUID uuid3 = UUID.fromString("12345678-1234-1234-1234-123456789014"); + when(jobsBrokerService.add(any())).thenReturn(uuid1).thenReturn(uuid2).thenReturn(uuid3); + + JobSharedData sharedData = new JobSharedData(uuid, userId, serviceInstantiation); + command.init(sharedData, "", ""); + when(inProgressStatusService.call(any(), eq(sharedData), any())).thenReturn(Job.JobStatus.COMPLETED); + NextCommand nextCommand = command.call(); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(JobAdapter.AsyncJobRequest.class); + verify(jobAdapter, times(2)).createChildJob(eq(JobType.VnfInstantiation), eq(Job.JobStatus.CREATING), argumentCaptor.capture(), eq(sharedData), any()); + verify(jobAdapter, times(1)).createChildJob(eq(JobType.NetworkInstantiation), eq(Job.JobStatus.CREATING), argumentCaptor.capture(), eq(sharedData), any()); + assertThat(argumentCaptor.getAllValues(), containsInAnyOrder(vnf1, vnf2, network1)); + + verify(jobsBrokerService, times(3)).add(any()); + + //verify we don't update service info during this case, which shall stay in_progress + verify(asyncInstantiationBL, never()).updateServiceInfo(any(), any()); + + assertThat(nextCommand.getStatus(), is(Job.JobStatus.IN_PROGRESS)); + assertThat(nextCommand.getCommand().getType(), is(new WatchingCommand().getType())); + assertThat(nextCommand.getCommand().getData().get("childrenJobs"), is(Arrays.asList(uuid1.toString(), uuid2.toString(), uuid3.toString()))); + assertThat(nextCommand.getCommand().getData().get("isService"), is(true)); + } + + @Test(dataProvider = "processJobStatusData") + public void processJobStatusTest(Job.JobStatus jobStatus, boolean isNeedToCreateChildJobs, Job.JobStatus expectedStatus) { + + when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true); + // All mocks under are used for isNeedToCreateChildJobs=true case + when(sharedData.getRequest()).thenReturn(request); + when(request.isALaCarte()).thenReturn(true); + Map vnfs = mock(Map.class); + ModelInfo modelInfo = mock(ModelInfo.class); + + // if vnfs.isEmpty -> isNeedToCreateChildJobs will return false + when(vnfs.isEmpty()).thenReturn(!isNeedToCreateChildJobs); + + when(request.getVnfs()).thenReturn(vnfs); + when(request.getModelInfo()).thenReturn(modelInfo); + command.instanceId = "MockInstId"; + + NextCommand nextCommand = command.processJobStatus(jobStatus); + Assert.assertEquals(nextCommand.getStatus(), expectedStatus); + if (isNeedToCreateChildJobs) { + Assert.assertEquals(nextCommand.getCommand().getClass(), WatchingCommand.class); + } else { + Assert.assertEquals(nextCommand.getCommand(), command); + } + } + + @Test(dataProvider = "isExpiredJobStatusData") + public void isExpiredJobStatusTest(ZonedDateTime jobStartTime, String configValue, boolean expectedResult) { + SystemProperties systemProperties = new SystemProperties(); + systemProperties.setEnvironment(environment); + when(environment.getRequiredProperty(VidProperties.VID_JOB_MAX_HOURS_IN_PROGRESS)).thenReturn(configValue); + when(environment.containsProperty(VidProperties.VID_JOB_MAX_HOURS_IN_PROGRESS)).thenReturn(true); + Assert.assertEquals(command.getExpiryChecker().isExpired(jobStartTime), expectedResult); + } +} diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInstantiationCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInstantiationCommandTest.java deleted file mode 100644 index e7ab4f098..000000000 --- a/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInstantiationCommandTest.java +++ /dev/null @@ -1,157 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * VID - * ================================================================================ - * Copyright (C) 2018 Nokia Intellectual Property. 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.vid.job.command; - - -import io.joshworks.restclient.http.HttpResponse; -import org.mockito.Mock; -import org.onap.vid.aai.AaiResponse; -import org.onap.vid.aai.exceptions.InvalidAAIResponseException; -import org.onap.vid.changeManagement.RequestDetailsWrapper; -import org.onap.vid.domain.mso.RequestReferences; -import org.onap.vid.exceptions.MaxRetriesException; -import org.onap.vid.job.Job; -import org.onap.vid.job.NextCommand; -import org.onap.vid.model.RequestReferencesContainer; -import org.onap.vid.model.serviceInstantiation.ServiceInstantiation; -import org.onap.vid.mso.MsoInterface; -import org.onap.vid.mso.model.ServiceInstantiationRequestDetails; -import org.onap.vid.services.AsyncInstantiationBusinessLogic; -import org.onap.vid.services.AuditService; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import java.util.UUID; - -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.IsEqual.equalTo; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; - -public class ServiceInstantiationCommandTest { - @Mock - private AsyncInstantiationBusinessLogic asyncInstantiationBusinessLogic; - - @Mock - private MsoInterface msoInterface; - - @Mock - private AuditService auditService; - - @Mock - private ServiceInstantiation serviceInstantiation; - - @Mock - private HttpResponse msoResponse; - - @Mock - private RequestDetailsWrapper requestDetailsWrapper; - - @Mock - private AaiResponse aaiResponse; - - @Mock - private RequestReferencesContainer requestReferencesContainer; - - - private UUID uuid = UUID.randomUUID(); - - - private ServiceInstantiationCommand serviceInstantiationCommand; - - @BeforeMethod - public void setUp() { - initMocks(this); - serviceInstantiationCommand = new ServiceInstantiationCommand(asyncInstantiationBusinessLogic, auditService, msoInterface, uuid, serviceInstantiation, "sampleUserId"); - } - - - @Test - public void shouldProperlyHandleMaxRetriesException() { - when(asyncInstantiationBusinessLogic.generateServiceInstantiationRequest(uuid, serviceInstantiation, "sampleUserId")).thenThrow(new MaxRetriesException("", 2)); - - NextCommand call = serviceInstantiationCommand.call(); - - assertThat(call.getCommand(), is(nullValue())); - assertThat(call.getStatus(), is(equalTo(Job.JobStatus.FAILED))); - - verify(asyncInstantiationBusinessLogic).handleFailedInstantiation(uuid); - } - - @Test - public void shouldProperlyHandleInvalidAAIResponseException() { - doThrow(new InvalidAAIResponseException(aaiResponse)).when(asyncInstantiationBusinessLogic).generateServiceInstantiationRequest(uuid, serviceInstantiation, "sampleUserId"); - - NextCommand call = serviceInstantiationCommand.call(); - - assertThat(call.getCommand(), is(serviceInstantiationCommand)); - assertThat(call.getStatus(), is(equalTo(Job.JobStatus.IN_PROGRESS))); - } - - - @Test - public void shouldProperlyHandleInvalidSOResponse() { - when(asyncInstantiationBusinessLogic.generateServiceInstantiationRequest(uuid, serviceInstantiation, "sampleUserId")).thenReturn(requestDetailsWrapper); - when(asyncInstantiationBusinessLogic.getServiceInstantiationPath(serviceInstantiation)).thenReturn("samplePath"); - when(msoInterface.post("samplePath", requestDetailsWrapper, RequestReferencesContainer.class)).thenReturn(msoResponse); - when(msoResponse.getStatus()).thenReturn(500); - when(msoResponse.getBody()).thenReturn(requestReferencesContainer); - - NextCommand call = serviceInstantiationCommand.call(); - - assertThat(call.getCommand(), is(nullValue())); - assertThat(call.getStatus(), is(equalTo(Job.JobStatus.FAILED))); - - verify(auditService).setFailedAuditStatusFromMso(uuid, null, 500, requestReferencesContainer.toString()); - } - - - @Test - public void shouldProperlyUpdateServiceStatusAndReturnInProgressCommand() { - RequestReferences requestReferences = createRequestReferences(); - - when(asyncInstantiationBusinessLogic.generateServiceInstantiationRequest(uuid, serviceInstantiation, "sampleUserId")).thenReturn(requestDetailsWrapper); - when(asyncInstantiationBusinessLogic.getServiceInstantiationPath(serviceInstantiation)).thenReturn("samplePath"); - when(msoInterface.post("samplePath", requestDetailsWrapper, RequestReferencesContainer.class)).thenReturn(msoResponse); - when(msoResponse.getStatus()).thenReturn(200); - when(msoResponse.getBody()).thenReturn(requestReferencesContainer); - when(requestReferencesContainer.getRequestReferences()).thenReturn(requestReferences); - - - NextCommand call = serviceInstantiationCommand.call(); - - assertThat(call.getCommand(), instanceOf(InProgressStatusCommand.class)); - assertThat(call.getStatus(), is(equalTo(Job.JobStatus.IN_PROGRESS))); - - } - - private RequestReferences createRequestReferences() { - RequestReferences requestReferences = new RequestReferences(); - requestReferences.setInstanceId("sampleInstanceId"); - requestReferences.setRequestId("sampleRequestId"); - return requestReferences; - } -} \ No newline at end of file diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/WatchChildrenJobsBLTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/WatchChildrenJobsBLTest.java new file mode 100644 index 000000000..98524c7db --- /dev/null +++ b/vid-app-common/src/test/java/org/onap/vid/job/command/WatchChildrenJobsBLTest.java @@ -0,0 +1,98 @@ +package org.onap.vid.job.command; + +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.portalsdk.core.service.DataAccessService; +import org.onap.vid.job.Job.JobStatus; +import org.onap.vid.job.impl.JobDaoImpl; +import org.onap.vid.utils.DaoUtils; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.when; +import static org.testng.AssertJUnit.assertEquals; + +public class WatchChildrenJobsBLTest { + @Mock + private DataAccessService dataAccessService; + + @InjectMocks + private WatchChildrenJobsBL watchChildrenJobsBL; + + @BeforeClass + public void initMocks() { + MockitoAnnotations.initMocks(this); + } + + public static Object[][] dataProviderForChildrenStatusOnly() { + return new Object[][]{ + {Arrays.asList(JobStatus.STOPPED, JobStatus.COMPLETED_WITH_NO_ACTION, JobStatus.COMPLETED), JobStatus.COMPLETED_WITH_ERRORS}, + {Arrays.asList(JobStatus.COMPLETED, JobStatus.FAILED, JobStatus.COMPLETED_WITH_NO_ACTION), JobStatus.COMPLETED_WITH_ERRORS}, + {Arrays.asList(null, JobStatus.COMPLETED), JobStatus.COMPLETED_WITH_ERRORS}, + {Arrays.asList(null, JobStatus.IN_PROGRESS), JobStatus.IN_PROGRESS}, + {Arrays.asList(null, JobStatus.FAILED), JobStatus.FAILED}, + {new ArrayList<>(), JobStatus.COMPLETED_WITH_NO_ACTION} + }; + } + + @DataProvider + public static Object[][] childrenStatusDataProvider() { + + List result = new ArrayList<>(); + result.addAll(Arrays.asList(dataProviderForChildrenStatusOnly())); + result.addAll(Arrays.asList(inputsStatusAndExpectedOutputDataProvider())); + return result.toArray(new Object[result.size()][]); + } + + @DataProvider + public static Object[][] inputsStatusAndExpectedOutputDataProvider() { + return new Object[][]{ + {Arrays.asList(JobStatus.COMPLETED, JobStatus.COMPLETED), JobStatus.COMPLETED}, + {Arrays.asList(JobStatus.COMPLETED, JobStatus.COMPLETED_WITH_NO_ACTION), JobStatus.COMPLETED}, + {Arrays.asList(JobStatus.FAILED, JobStatus.COMPLETED_WITH_NO_ACTION), JobStatus.FAILED}, + {Arrays.asList(JobStatus.FAILED, JobStatus.COMPLETED), JobStatus.COMPLETED_WITH_ERRORS}, + {Arrays.asList(JobStatus.RESOURCE_IN_PROGRESS, JobStatus.FAILED), JobStatus.IN_PROGRESS}, + {Arrays.asList(JobStatus.PAUSE, JobStatus.FAILED), JobStatus.IN_PROGRESS}, + {Arrays.asList(JobStatus.PENDING, JobStatus.FAILED), JobStatus.IN_PROGRESS}, + {Arrays.asList(JobStatus.IN_PROGRESS, JobStatus.COMPLETED), JobStatus.IN_PROGRESS}, + {Arrays.asList(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS), JobStatus.IN_PROGRESS}, + {Arrays.asList(JobStatus.COMPLETED, JobStatus.COMPLETED_WITH_ERRORS), JobStatus.COMPLETED_WITH_ERRORS}, + {Arrays.asList(JobStatus.COMPLETED_WITH_ERRORS, JobStatus.FAILED), JobStatus.COMPLETED_WITH_ERRORS}, + {Arrays.asList(JobStatus.COMPLETED_WITH_ERRORS, JobStatus.COMPLETED_WITH_ERRORS), JobStatus.COMPLETED_WITH_ERRORS}, + {Arrays.asList(JobStatus.COMPLETED_WITH_ERRORS, JobStatus.COMPLETED_WITH_NO_ACTION), JobStatus.COMPLETED_WITH_ERRORS}, + {Arrays.asList(JobStatus.COMPLETED_WITH_NO_ACTION, JobStatus.COMPLETED_WITH_NO_ACTION), JobStatus.COMPLETED_WITH_NO_ACTION}, + + + }; + } + + @Test(dataProvider = "childrenStatusDataProvider") + public void whenRetrieveListOfChildrenWithStatues_thenAccumulatedChildrenStatusAsExpected(List childJobs, JobStatus expectedChildrenJobsStatus) { + //init sql result mock + List mockChildren = childJobs.stream().map(st -> { + JobDaoImpl job = new JobDaoImpl(); + job.setUuid(UUID.randomUUID()); + job.setStatus(st); + return job; + }).collect(Collectors.toList()); + when(dataAccessService.getList(eq(JobDaoImpl.class), anyString(), any(), eq(DaoUtils.getPropsMap()))) + .thenReturn(mockChildren); + + List uuids = mockChildren.stream().map(job -> job.getUuid().toString()).collect(Collectors.toList()); + assertEquals(expectedChildrenJobsStatus, watchChildrenJobsBL.retrieveChildrenJobsStatus(uuids)); + } + + @Test(dataProvider = "inputsStatusAndExpectedOutputDataProvider") + public void whenCumulate2JobStatus_thenResultAsExpected(List jobs, JobStatus expectedChildrenJobsStatus) { + assertEquals(expectedChildrenJobsStatus, watchChildrenJobsBL.cumulateJobStatus(jobs.get(0), jobs.get(1))); + } +} diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/WatchingCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/WatchingCommandTest.java new file mode 100644 index 000000000..f47a18d5f --- /dev/null +++ b/vid-app-common/src/test/java/org/onap/vid/job/command/WatchingCommandTest.java @@ -0,0 +1,77 @@ +package org.onap.vid.job.command; + +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.portalsdk.core.service.DataAccessService; +import org.onap.vid.job.Job; +import org.onap.vid.job.NextCommand; +import org.onap.vid.job.impl.JobSharedData; +import org.onap.vid.model.serviceInstantiation.ServiceInstantiation; +import org.onap.vid.services.AsyncInstantiationBusinessLogic; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.List; +import java.util.UUID; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; + +public class WatchingCommandTest { + + @Mock + private AsyncInstantiationBusinessLogic asyncInstantiationBL; + + @Mock + private DataAccessService dataAccessService; + + @Mock + private WatchChildrenJobsBL watchChildrenJobsBL; + + @InjectMocks + private WatchingCommand watchingCommand = new WatchingCommand(); + + + + @BeforeClass + public void initMocks() { + MockitoAnnotations.initMocks(this); + } + + @DataProvider + public static Object[][] testWatchingDataProvider() { + return new Object[][]{ + {"all children final, no failed child, is service", Job.JobStatus.COMPLETED, true, Job.JobStatus.COMPLETED}, + {"all children final, there is failed child, is service", Job.JobStatus.COMPLETED_WITH_ERRORS, true, Job.JobStatus.COMPLETED_WITH_ERRORS}, + {"not all children final, is service", Job.JobStatus.IN_PROGRESS, true, Job.JobStatus.IN_PROGRESS}, + {"all children final, no failed child, not service", Job.JobStatus.COMPLETED, false, Job.JobStatus.COMPLETED}, + {"all children final, there is failed child, not service", Job.JobStatus.COMPLETED_WITH_ERRORS, false, Job.JobStatus.COMPLETED_WITH_ERRORS}, + {"not all children final, not service", Job.JobStatus.IN_PROGRESS, false, Job.JobStatus.RESOURCE_IN_PROGRESS}, + }; + } + + + + @Test(dataProvider = "testWatchingDataProvider") + public void whenGetChildrenStatus_thenJobStatusAsExpected(String desc, Job.JobStatus childrenComulativeStatus, boolean isService, Job.JobStatus expectedCommandStatus) { + UUID jobUUID = UUID.randomUUID(); + JobSharedData sharedData = new JobSharedData(jobUUID, "mockedUserID", mock(ServiceInstantiation.class)); + List uuids = mock(List.class); + watchingCommand.init(sharedData, uuids, isService); + when(watchChildrenJobsBL.retrieveChildrenJobsStatus(eq(uuids))).thenReturn(childrenComulativeStatus); + when(watchChildrenJobsBL.cumulateJobStatus(eq(childrenComulativeStatus),eq(Job.JobStatus.COMPLETED))).thenReturn(childrenComulativeStatus); + + //execute command and verify + NextCommand nextCommand = watchingCommand.call(); + assertThat(nextCommand.getStatus(), is(expectedCommandStatus)); + if (!expectedCommandStatus.equals(Job.JobStatus.IN_PROGRESS) && isService) { + verify(asyncInstantiationBL).updateServiceInfoAndAuditStatus(jobUUID, expectedCommandStatus); + } else { + verify(asyncInstantiationBL, never()).updateServiceInfoAndAuditStatus(jobUUID, expectedCommandStatus); + } + } +} -- cgit 1.2.3-korg