From 84decdf394b0d0c0e84c5d6144abc12b8230619c Mon Sep 17 00:00:00 2001 From: Mark Lawrence <15652599+Mark-J-Lawrence@users.noreply.github.com> Date: Wed, 22 May 2024 16:02:04 +0100 Subject: [PATCH] sdv manager delivery Signed-off-by: Mark Lawrence <15652599+Mark-J-Lawrence@users.noreply.github.com> --- .../dev.galasa.sdv.manager.ivt/build.gradle | 30 + .../settings.gradle | 1 + .../galasa/sdv/manager/ivt/SdvManagerIVT.java | 56 + .../dev.galasa.sdv.manager/bnd.bnd | 7 + .../dev.galasa.sdv.manager/build.gradle | 97 + .../config/checkstyle/checkstyle.xml | 377 ++ .../config/pmd/sdvrules.xml | 317 ++ .../config/spotbugs/excludes.xml | 50 + .../dev.galasa.sdv.manager/settings.gradle | 1 + .../main/java/dev/galasa/sdv/ISdvUser.java | 38 + .../dev/galasa/sdv/SdvManagerException.java | 32 + .../java/dev/galasa/sdv/SdvManagerField.java | 23 + .../src/main/java/dev/galasa/sdv/SdvUser.java | 41 + .../galasa/sdv/internal/RecordingRegion.java | 59 + .../sdv/internal/SdvHttpRecorderImpl.java | 415 ++ .../galasa/sdv/internal/SdvManagerImpl.java | 448 ++ .../internal/SdvManagersResourceMonitor.java | 151 + .../galasa/sdv/internal/SdvRecorderImpl.java | 554 +++ .../sdv/internal/SdvResourceManagement.java | 83 + .../dev/galasa/sdv/internal/SdvUserImpl.java | 154 + .../dev/galasa/sdv/internal/SdvUserPool.java | 140 + .../sdv/internal/SdvUserResourceMonitor.java | 122 + .../sdv/internal/properties/SdvHlq.java | 45 + .../sdv/internal/properties/SdvPoolUsers.java | 48 + .../sdv/internal/properties/SdvPort.java | 45 + .../properties/SdvPropertiesSingleton.java | 58 + .../sdv/internal/properties/SdvRole.java | 45 + .../internal/properties/SdvSdcActivation.java | 55 + .../properties/SdvSrrLogstreamRemoval.java | 57 + .../main/resources/jcl/definelogstream.jcl | 12 + .../main/resources/jcl/deletelogstreams.jcl | 19 + .../src/main/resources/jcl/getYaml.jcl | 7 + .../sdv/internal/TestRecordingRegion.java | 71 + .../sdv/internal/TestSdvHttpRecorderImpl.java | 4157 +++++++++++++++++ .../sdv/internal/TestSdvManagerImpl.java | 1928 ++++++++ .../TestSdvManagersResourceMonitor.java | 460 ++ .../internal/TestSdvResourceManagement.java | 135 + .../galasa/sdv/internal/TestSdvUserImpl.java | 71 + .../galasa/sdv/internal/TestSdvUserPool.java | 328 ++ .../internal/TestSdvUserResourceMonitor.java | 440 ++ .../src/test/resources/getYaml.jcl | 7 + .../src/test/resources/getYamlRegionA.jcl | 13 + .../src/test/resources/getYamlRegionB.jcl | 11 + .../src/test/resources/yamlRegionA.yaml | 1 + .../src/test/resources/yamlRegionB.yaml | 1 + galasa-managers-parent/gradle.properties | 2 +- galasa-managers-parent/settings.gradle | 2 + release.yaml | 15 + 48 files changed, 11228 insertions(+), 1 deletion(-) create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/build.gradle create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/settings.gradle create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/src/main/java/dev/galasa/sdv/manager/ivt/SdvManagerIVT.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/bnd.bnd create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/build.gradle create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/checkstyle/checkstyle.xml create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/pmd/sdvrules.xml create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/spotbugs/excludes.xml create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/settings.gradle create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/ISdvUser.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvManagerException.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvManagerField.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvUser.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/RecordingRegion.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvHttpRecorderImpl.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvManagerImpl.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvManagersResourceMonitor.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvRecorderImpl.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvResourceManagement.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserImpl.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserPool.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserResourceMonitor.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvHlq.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPoolUsers.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPort.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPropertiesSingleton.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvRole.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvSdcActivation.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvSrrLogstreamRemoval.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/definelogstream.jcl create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/deletelogstreams.jcl create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/getYaml.jcl create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestRecordingRegion.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvHttpRecorderImpl.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvManagerImpl.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvManagersResourceMonitor.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvResourceManagement.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserImpl.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserPool.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserResourceMonitor.java create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYaml.jcl create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYamlRegionA.jcl create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYamlRegionB.jcl create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/yamlRegionA.yaml create mode 100644 galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/yamlRegionB.yaml diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/build.gradle b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/build.gradle new file mode 100644 index 000000000..431a18aca --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/build.gradle @@ -0,0 +1,30 @@ +plugins { + id 'galasa.manager.ivt' +} + +description = 'Galasa SDV Manager IVT' + +version = '0.34.0' + +dependencies { + implementation project (':galasa-managers-cicsts-parent:dev.galasa.cicsts.ceci.manager') + implementation project (':galasa-managers-core-parent:dev.galasa.core.manager') + implementation project (':galasa-managers-cicsts-parent:dev.galasa.cicsts.manager') + implementation project (':galasa-managers-zos-parent:dev.galasa.zos3270.manager') + implementation project (':galasa-managers-zos-parent:dev.galasa.zos.manager') + implementation project (':galasa-managers-core-parent:dev.galasa.artifact.manager') + implementation project (':galasa-managers-testingtools-parent:dev.galasa.sdv.manager') +} + +// Note: These values are consumed by the parent build process +// They indicate which packages of functionality this OSGi bundle should be delivered inside, +// or referenced from. +// The settings here are gathered together by the build process to create a release.yaml file +// which gathers-up all the packaging metadata about all the OSGi bundles in this component. +ext.projectName=project.name +ext.includeInOBR = false +ext.includeInMVP = false +ext.includeInBOM = false +ext.includeInIsolated = false +ext.includeInCodeCoverage = false +ext.includeInJavadoc = false diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/settings.gradle b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/settings.gradle new file mode 100644 index 000000000..96a5356df --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'dev.galasa.sdv.manager.ivt' \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/src/main/java/dev/galasa/sdv/manager/ivt/SdvManagerIVT.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/src/main/java/dev/galasa/sdv/manager/ivt/SdvManagerIVT.java new file mode 100644 index 000000000..0e285ecb9 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager.ivt/src/main/java/dev/galasa/sdv/manager/ivt/SdvManagerIVT.java @@ -0,0 +1,56 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.sdv.manager.ivt; + +import org.apache.commons.logging.Log; + +import static org.assertj.core.api.Assertions.assertThat; + +import dev.galasa.BeforeClass; +import dev.galasa.Test; +import dev.galasa.cicsts.CicsRegion; +import dev.galasa.cicsts.CicsTerminal; +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.core.manager.Logger; +import dev.galasa.sdv.ISdvUser; +import dev.galasa.sdv.SdvManagerException; +import dev.galasa.sdv.SdvUser; + + @Test + public class SdvManagerIVT { + + @Logger + public Log logger; + + @CicsRegion + public ICicsRegion cics; + + @CicsTerminal + public ICicsTerminal terminal; + + @SdvUser(roleTag = "role1") + public ISdvUser user1; + + private static final String SDV_TCPIPSERVICE_NAME = "SDVXSDT"; + + @BeforeClass + public void logIntoTerminals() throws SdvManagerException { + user1.logIntoTerminal(terminal); + } + + @Test + public void userUsesCeda() throws Exception { + + terminal.type("CEDA DI G(SDVGRP)").enter().waitForTextInField(SDV_TCPIPSERVICE_NAME); + + assertThat(terminal.searchText(SDV_TCPIPSERVICE_NAME)) + .as("Expectation to see " + SDV_TCPIPSERVICE_NAME + " in terminal").isTrue(); + terminal.pf3(); + } + + } + \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/bnd.bnd b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/bnd.bnd new file mode 100644 index 000000000..2c28add93 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/bnd.bnd @@ -0,0 +1,7 @@ +-snapshot: ${tstamp} +Bundle-Name: Galasa SDV Manager +Export-Package: dev.galasa.sdv +Import-Package: !javax.validation.constraints,\ + * + + diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/build.gradle b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/build.gradle new file mode 100644 index 000000000..11be80ff0 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/build.gradle @@ -0,0 +1,97 @@ +plugins { + id 'galasa.manager' + id 'checkstyle' + id 'pmd' + id("com.github.spotbugs") version "4.7.0" +} + +description = 'Galasa SDV Manager' + +version = '0.34.0' + +checkstyle { + configFile = file("config/checkstyle/checkstyle.xml") + toolVersion = "10.14.2" +} +configurations.all { + attributes { + attribute(Attribute.of('org.gradle.jvm.environment', String), 'standard-jvm') + } +} + +jacoco { + toolVersion = "0.8.7" +} + +pmd { + consoleOutput = true + toolVersion = "6.50.0" + ruleSetFiles = files("config/pmd/sdvrules.xml") + ruleSets = [] +} + +dependencies { + + implementation project(':galasa-managers-core-parent:dev.galasa.artifact.manager') + implementation project(':galasa-managers-zos-parent:dev.galasa.zos3270.manager') + implementation project(':galasa-managers-cicsts-parent:dev.galasa.cicsts.manager') + implementation project(':galasa-managers-comms-parent:dev.galasa.http.manager') + implementation 'com.google.code.gson:gson:2.10.1' + + // Unit testing + testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2' + testImplementation 'org.mockito:mockito-core:5.3.1' + testImplementation 'org.mockito:mockito-junit-jupiter:5.3.1' + testImplementation 'commons-io:commons-io:2.16.1' +} + +test { + useJUnitPlatform() + maxHeapSize = '1G' + finalizedBy jacocoTestReport // report is always generated after tests run + enabled true +} + +tasks.withType(com.github.spotbugs.snom.SpotBugsTask) { + excludeFilter = file("config/spotbugs/excludes.xml") + reports { + xml { + enabled = true + } + html { + enabled = true + } + } +} + +jacocoTestReport { + enabled true + dependsOn test // tests are required to run before generating the report +} + +jacocoTestCoverageVerification { + violationRules { + rule { + limit { + counter = 'LINE' + value = 'COVEREDRATIO' + minimum = 0.84 + } + } + } +} + +check.dependsOn jacocoTestCoverageVerification + +// Note: These values are consumed by the parent build process +// They indicate which packages of functionality this OSGi bundle should be delivered inside, +// or referenced from. +// The settings here are gathered together by the build process to create a release.yaml file +// which gathers-up all the packaging metadata about all the OSGi bundles in this component. +ext.projectName=project.name +ext.includeInOBR = true +ext.includeInMVP = true +ext.includeInBOM = true +ext.includeInIsolated = true +ext.includeInCodeCoverage = true +ext.includeInJavadoc = true \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/checkstyle/checkstyle.xml b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/checkstyle/checkstyle.xml new file mode 100644 index 000000000..f795191a7 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/checkstyle/checkstyle.xml @@ -0,0 +1,377 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/pmd/sdvrules.xml b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/pmd/sdvrules.xml new file mode 100644 index 000000000..dcc694c47 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/pmd/sdvrules.xml @@ -0,0 +1,317 @@ + + + SDV configuration of PMD. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/spotbugs/excludes.xml b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/spotbugs/excludes.xml new file mode 100644 index 000000000..423a426f9 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/config/spotbugs/excludes.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/settings.gradle b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/settings.gradle new file mode 100644 index 000000000..fa2508d23 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'dev.galasa.sdv.manager' diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/ISdvUser.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/ISdvUser.java new file mode 100644 index 000000000..e94d9c3ca --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/ISdvUser.java @@ -0,0 +1,38 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv; + +import dev.galasa.cicsts.ICicsTerminal; + +/** + * This class provides the interface for + * SDVUserImpl. + * + */ +public interface ISdvUser { + + String getCredentialsTag(); + + String getUsername(); + + String getPassword(); + + String getRole(); + + String getCicsTag(); + + String getSrrId(); + + Boolean isRecording(); + + void setSrrId(String srrId); + + void setNotRecording(); + + void logIntoTerminal(ICicsTerminal terminal) throws SdvManagerException; + +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvManagerException.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvManagerException.java new file mode 100644 index 000000000..9d8d0fd06 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvManagerException.java @@ -0,0 +1,32 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv; + +import dev.galasa.ManagerException; + +/** + * This class provides a generic Exception which can be thrown + * throughout the SDV Manager. + * + */ +public class SdvManagerException extends ManagerException { + + private static final long serialVersionUID = 1L; + + public SdvManagerException() { + // This constructor is intentionally empty. Nothing special is needed here. + } + + public SdvManagerException(String message) { + super(message); + } + + public SdvManagerException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvManagerField.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvManagerField.java new file mode 100644 index 000000000..165fadb03 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvManagerField.java @@ -0,0 +1,23 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Used to annotate annotations that are to be used for Test Class fields. To be populated by the + * Manager. + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface SdvManagerField { + +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvUser.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvUser.java new file mode 100644 index 000000000..a7f8fdd72 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/SdvUser.java @@ -0,0 +1,41 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv; + +import dev.galasa.framework.spi.ValidAnnotatedFields; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * A zOS User that will have SDV recording switched on, on a specified CICS TS Region. + * + *

+ * Used to populate a {@link ISdvUser} field + *

+ * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +@SdvManagerField +@ValidAnnotatedFields({ISdvUser.class}) +public @interface SdvUser { + + /** + * The tag of the CICS region the User is to be associated with. SDV Recording will take place + * for this user on this CICS Region. + */ + String cicsTag() default "PRIMARY"; + + /** + * The SDV manager will select a user from the zOS image pool user matching this roleTag. + */ + String roleTag(); + +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/RecordingRegion.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/RecordingRegion.java new file mode 100644 index 000000000..3f95e389d --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/RecordingRegion.java @@ -0,0 +1,59 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.sdv.ISdvUser; +import dev.galasa.sdv.SdvManagerException; +import java.util.ArrayList; +import java.util.List; + +/** + * This class contains all required information to run SDV + * for a single CICS Region under test. + * + *

Each region has it own maintenance terminal to allow the + * creation, and tear down of required resources, and contains a + * list of all SDV Users being recorded on that region. + * + */ +class RecordingRegion { + + private ICicsTerminal maintenanceTerminal; + private List recordingUsers = new ArrayList<>(); + + public RecordingRegion(ICicsTerminal maintenanceTerminal) { + this.maintenanceTerminal = maintenanceTerminal; + } + + public ICicsTerminal getMaintenanceTerminal() { + return this.maintenanceTerminal; + } + + public Boolean addUserToRecord(ISdvUser user) throws SdvManagerException { + + // Check if user already exists in the list. This would mean + // the user had incorrectly been provisioned to a CICS region + // more than one by the pool code. In which case, this would + // be a bug + for (ISdvUser ru : recordingUsers) { + if (user.getUsername().equals(ru.getUsername())) { + throw new SdvManagerException("User '" + user.getUsername() + + "' has been allocated to more than one region in the test." + + " Please report this to the Galasa project."); + } + } + + recordingUsers.add(user); + return true; + } + + public List getRecordingUsers() { + return this.recordingUsers; + } + +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvHttpRecorderImpl.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvHttpRecorderImpl.java new file mode 100644 index 000000000..7e95e2246 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvHttpRecorderImpl.java @@ -0,0 +1,415 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import com.google.gson.JsonObject; +import dev.galasa.artifact.IArtifactManager; +import dev.galasa.cicsts.CicstsManagerException; +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.http.HttpClientException; +import dev.galasa.http.HttpClientResponse; +import dev.galasa.http.IHttpClient; +import dev.galasa.http.spi.IHttpManagerSpi; +import dev.galasa.sdv.ISdvUser; +import dev.galasa.sdv.SdvManagerException; +import dev.galasa.sdv.internal.properties.SdvPort; +import dev.galasa.zosbatch.spi.IZosBatchSpi; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This class contains HTTP specific implementations of the SdvRecorderImpl abstract class. + * + *

A number of functions from SdvRecorderImpl are overridden to provide HTTP recorder-only + * functionality. In particular, the creation and teardown of HTTP specific resources, and the + * start/end of SDC recording via HTTP endpoints. + * + */ +public class SdvHttpRecorderImpl extends SdvRecorderImpl { + + private static final String TCPIPSERVICE_TEXT = "TCPIPSERVICE"; + private static final String SDV_TCPIPSERVICE_RESOURCE_NAME = "SDVXSDT"; + private static final String URIMAP_TEXT = "URIMAP"; + private static final String SDV_URIMAP_RESOURCE_NAME = "SDVXSDU"; + private static final String SDV_HTTP_ENDPOINT_PATH = "/DFHSDC"; + private static final String ON_CICS_REGION_MSG = "', on CICS Region "; + private static final String STATUS_CODE_MSG = ". Status code: "; + + private static final Log LOG = LogFactory.getLog(SdvHttpRecorderImpl.class); + + private IHttpManagerSpi httpManager; + + /** + * The HTTP recorder constructor, which instantiates super class SdvRecorderImpl, then + * additionally takes an http manager. + * + * @param framework - Galasa framework + * @param recordingRegions - A unique Map of CICS regions under test. + * @param artifactManager - Galasa Artifact Manager. + * @param batchManager - Galasa Batch Manager. + * @param storedArtifactRoot - The path where files should be stored to be included as test + * artifacts. + * @param dss - Galasa DSS. + * @param httpManager - Galasa HTTP Manager. + */ + public SdvHttpRecorderImpl(IFramework framework, Map recordingRegions, IArtifactManager artifactManager, + IZosBatchSpi batchManager, Path storedArtifactRoot, + IDynamicStatusStoreService dss, IHttpManagerSpi httpManager) { + super(framework, recordingRegions, artifactManager, batchManager, storedArtifactRoot, dss); + + this.httpManager = httpManager; + } + + @Override + protected void createCicsResources(ICicsRegion region, ICicsTerminal terminal) + throws SdvManagerException { + + // Deleting possible remains of a previous run + if (LOG.isInfoEnabled()) { + LOG.info("Deleting any existing resources on " + region.getApplid()); + } + try { + if (region.ceda().resourceExists(terminal, TCPIPSERVICE_TEXT, + SDV_TCPIPSERVICE_RESOURCE_NAME, CICS_RESOURCES_GROUP_NAME)) { + region.cemt().setResource(terminal, TCPIPSERVICE_TEXT, + SDV_TCPIPSERVICE_RESOURCE_NAME, "CLOSED"); + } + if (region.ceda().resourceExists(terminal, URIMAP_TEXT, SDV_URIMAP_RESOURCE_NAME, + CICS_RESOURCES_GROUP_NAME)) { + region.cemt().setResource(terminal, URIMAP_TEXT, SDV_URIMAP_RESOURCE_NAME, + "DISABLED"); + } + region.ceda().deleteGroup(terminal, CICS_RESOURCES_GROUP_NAME); + } catch (CicstsManagerException e) { + if (LOG.isDebugEnabled()) { + LOG.debug("CICS resource disabling expectedly failed on " + region.getApplid()); + } + } + + // Run common SDC pre-reqs + super.createCicsResources(region, terminal); + + // Run HTTP specific pre-reqs + // TCPIPSERVICE + if (LOG.isInfoEnabled()) { + LOG.info("Creating TCPIPSERVICE on " + region.getApplid()); + } + + String port = SdvPort.get(region.getTag()); + if (port == null) { + throw new SdvManagerException( + "Could not find SDC port in CPS properties for CICS tag: " + region.getTag() + ); + } + + try { + region.ceda().createResource(terminal, TCPIPSERVICE_TEXT, + SDV_TCPIPSERVICE_RESOURCE_NAME, CICS_RESOURCES_GROUP_NAME, + "TRANSACTION(CWXN) PORTNUMBER(" + port + ") AUTHENTICATE(BASIC)" + + "PROTOCOL(HTTP)"); + } catch (CicstsManagerException e) { + throw new SdvManagerException( + "Could not create TCPIPSERVICE on CICS Region " + region.getApplid(), e + ); + } + + // URIMAP + if (LOG.isInfoEnabled()) { + LOG.info("Creating URIMAP on " + region.getApplid()); + } + try { + region.ceda().createResource(terminal, URIMAP_TEXT, SDV_URIMAP_RESOURCE_NAME, + CICS_RESOURCES_GROUP_NAME, + "USAGE(SERVER) SCHEME(HTTP) PATH(" + SDV_HTTP_ENDPOINT_PATH + "*) TCPIPSERVICE(" + + SDV_TCPIPSERVICE_RESOURCE_NAME + ") " + + "PROGRAM(DFHXSJH) HOST(*) TRANSACTION(CXSD)"); + } catch (CicstsManagerException e) { + throw new SdvManagerException( + "Could not create URIMAP on CICS region " + region.getApplid(), e + ); + } + + try { + region.ceda().installGroup(terminal, CICS_RESOURCES_GROUP_NAME); + } catch (CicstsManagerException e) { + throw new SdvManagerException( + "Could not install SDV resource group on CICS region " + region.getApplid(), e + ); + } + } + + @Override + protected void deleteCicsResources(ICicsRegion region, ICicsTerminal terminal) { + + // URIMAP + if (LOG.isInfoEnabled()) { + LOG.info("Disabling URIMAP on " + region.getApplid()); + } + try { + region.cemt().setResource(terminal, URIMAP_TEXT, SDV_URIMAP_RESOURCE_NAME, "DISABLED"); + } catch (CicstsManagerException e) { + if (LOG.isErrorEnabled()) { + LOG.error("Could not create URIMAP on CICS Region " + region.getApplid()); + } + } + + // TCPIPSERVICE + if (LOG.isInfoEnabled()) { + LOG.info("Disabling TCPIPSERVICE on " + region.getApplid()); + } + try { + region.cemt().setResource(terminal, TCPIPSERVICE_TEXT, SDV_TCPIPSERVICE_RESOURCE_NAME, + "CLOSED"); + } catch (CicstsManagerException e) { + if (LOG.isErrorEnabled()) { + LOG.error("Could not create TCPIPSERVICE on CICS Region " + region.getApplid()); + } + } + + // Delete common SDC resources + super.deleteCicsResources(region, terminal); + } + + @Override + void startRecording() throws SdvManagerException { + for (Map.Entry entry : recordingRegions.entrySet()) { + for (ISdvUser recordingUser : entry.getValue().getRecordingUsers()) { + + if (LOG.isInfoEnabled()) { + LOG.info("Starting SDV Recording for CICS region: " + entry.getKey().getApplid() + + ", User: " + recordingUser.getUsername()); + } + try { + startRecordingUsingHttp(entry.getKey(), recordingUser); + + if (LOG.isInfoEnabled()) { + LOG.info("Recording CICS region: " + entry.getKey().getApplid() + ", User: " + + recordingUser.getUsername() + ", SRR ID: " + + recordingUser.getSrrId()); + } + } catch (SdvManagerException e) { + throw new SdvManagerException( + "Was unable to start recording for user '" + + recordingUser.getUsername() + + ON_CICS_REGION_MSG + + entry.getKey().getApplid(), e); + } + } + } + } + + private void startRecordingUsingHttp(ICicsRegion cicsRegion, ISdvUser recordingUser) + throws SdvManagerException { + + IHttpClient httpClient = this.httpManager.newHttpClient(); + + try { + httpClient.setURI(new URI("http://" + cicsRegion.getZosImage().getIpHost().getHostname() + + ":" + SdvPort.get(cicsRegion.getTag()))); + } catch (URISyntaxException e) { + throw new SdvManagerException( + "Badly formed URI for SDC service for CICS Region " + cicsRegion.getApplid(), e + ); + } + + HttpClientResponse response; + httpClient.setAuthorisation(recordingUser.getUsername(), recordingUser.getPassword()); + + // Check that an SDC isn't already running + Boolean sdcAlreadyRunning = false; + try { + response = httpClient.getJson(SDV_HTTP_ENDPOINT_PATH); + + if (response.getStatusCode() == 200) { + sdcAlreadyRunning = true; + } else if (response.getStatusCode() == 404) { + sdcAlreadyRunning = false; + } else { + JsonObject payload = response.getContent(); + String payloadStr = ""; + if (payload != null) { + payloadStr = payload.toString(); + } + + throw new SdvManagerException( + "Error whilst obtaining current SDC status for user '" + + recordingUser.getUsername() + + ON_CICS_REGION_MSG + + cicsRegion.getApplid() + + STATUS_CODE_MSG + + response.getStatusCode() + "\n" + response.getStatusMessage() + + "\n" + payloadStr); + } + } catch (HttpClientException e) { + throw new SdvManagerException( + "Could not check status SDC recording status for user '" + + recordingUser.getUsername() + + ON_CICS_REGION_MSG + + cicsRegion.getApplid() + + ". Is SDC activated?", e); + } + + // If an SDC is already running, stop it + if (sdcAlreadyRunning) { + try { + JsonObject body = new JsonObject(); + body.addProperty("submit", false); + response = httpClient.deleteJson(SDV_HTTP_ENDPOINT_PATH, body); + + if (response.getStatusCode() != 200) { + JsonObject payload = response.getContent(); + String payloadStr = ""; + if (payload != null) { + payloadStr = payload.toString(); + } + throw new SdvManagerException( + "Could not stop SDC recording for user '" + + recordingUser.getUsername() + + ON_CICS_REGION_MSG + + cicsRegion.getApplid() + + STATUS_CODE_MSG + + response.getStatusCode() + + "\n" + response.getStatusMessage() + + "\n" + payloadStr); + } + } catch (HttpClientException e) { + throw new SdvManagerException("Could not stop existing SDC recording for user '" + + recordingUser.getUsername() + + ON_CICS_REGION_MSG + + cicsRegion.getApplid() + ".", e); + } + } + + try { + JsonObject body = new JsonObject(); + response = httpClient.postJson(SDV_HTTP_ENDPOINT_PATH, body); + + if (response.getStatusCode() == 201) { + if (response.getContent().has("srr_id") + && !response.getContent().get("srr_id").getAsString().isBlank()) { + recordingUser.setSrrId(response.getContent().get("srr_id").getAsString()); + } else { + throw new SdvManagerException( + "SDC recording did not return an SRR ID for user '" + + recordingUser.getUsername() + + ON_CICS_REGION_MSG + + cicsRegion.getApplid() + ); + } + } else { + JsonObject payload = response.getContent(); + String payloadStr = ""; + if (payload != null) { + payloadStr = payload.toString(); + } + throw new SdvManagerException( + "Could not start SDC recording for user '" + + recordingUser.getUsername() + + ON_CICS_REGION_MSG + + cicsRegion.getApplid() + + STATUS_CODE_MSG + + response.getStatusCode() + + "\n" + response.getStatusMessage() + "\n" + payloadStr + ); + } + } catch (HttpClientException e) { + throw new SdvManagerException( + "Could not start SDC recording for user '" + + recordingUser.getUsername() + + ON_CICS_REGION_MSG + + cicsRegion.getApplid(), e + ); + } + } + + @Override + void endRecording() throws SdvManagerException { + for (Map.Entry entry : recordingRegions.entrySet()) { + for (ISdvUser recordingUser : entry.getValue().getRecordingUsers()) { + if (recordingUser.isRecording()) { + if (LOG.isInfoEnabled()) { + LOG.info("Ending SDV Recording for region: " + entry.getKey().getApplid() + + ", User: " + recordingUser.getUsername() + ", SRR ID: " + + recordingUser.getSrrId()); + } + try { + stopRecordingUsingHttp(entry.getKey(), recordingUser); + } catch (SdvManagerException e) { + throw new SdvManagerException( + "Unable to stop SRR recording " + + recordingUser.getSrrId() + + ", for user '" + + recordingUser.getUsername() + + ON_CICS_REGION_MSG + + entry.getKey().getApplid(), e + ); + } + } + } + } + } + + private void stopRecordingUsingHttp(ICicsRegion cicsRegion, ISdvUser recordingUser) + throws SdvManagerException { + + IHttpClient httpClient = this.httpManager.newHttpClient(); + + try { + httpClient.setURI(new URI("http://" + cicsRegion.getZosImage().getIpHost().getHostname() + + ":" + SdvPort.get(cicsRegion.getTag()))); + } catch (URISyntaxException e) { + throw new SdvManagerException( + "Badly formed URI for SDC service for CICS Region " + cicsRegion.getApplid(), e + ); + } + + HttpClientResponse response; + httpClient.setAuthorisation(recordingUser.getUsername(), recordingUser.getPassword()); + + try { + JsonObject body = new JsonObject(); + body.addProperty("submit", false); + response = httpClient.deleteJson(SDV_HTTP_ENDPOINT_PATH, body); + + if (response.getStatusCode() != 200) { + JsonObject payload = response.getContent(); + String payloadStr = ""; + if (payload != null) { + payloadStr = payload.toString(); + } + throw new SdvManagerException( + "Could not stop SDC recording for user '" + + recordingUser.getUsername() + + ON_CICS_REGION_MSG + + cicsRegion.getApplid() + + STATUS_CODE_MSG + + response.getStatusCode() + + "\n" + response.getStatusMessage() + + "\n" + payloadStr + ); + } + + recordingUser.setNotRecording(); + } catch (HttpClientException e) { + throw new SdvManagerException( + "Could not stop existing SDC recording for user '" + + recordingUser.getUsername() + + ON_CICS_REGION_MSG + + cicsRegion.getApplid(), e + ); + } + } + +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvManagerImpl.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvManagerImpl.java new file mode 100644 index 000000000..361173f9b --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvManagerImpl.java @@ -0,0 +1,448 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.ICredentialsUsernamePassword; +import dev.galasa.ManagerException; +import dev.galasa.ProductVersion; +import dev.galasa.artifact.IArtifactManager; +import dev.galasa.cicsts.CicstsManagerException; +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.cicsts.spi.ICicsRegionProvisioned; +import dev.galasa.cicsts.spi.ICicstsManagerSpi; +import dev.galasa.framework.spi.AbstractManager; +import dev.galasa.framework.spi.AnnotatedField; +import dev.galasa.framework.spi.ConfigurationPropertyStoreException; +import dev.galasa.framework.spi.DynamicStatusStoreException; +import dev.galasa.framework.spi.GenerateAnnotatedField; +import dev.galasa.framework.spi.IConfidentialTextService; +import dev.galasa.framework.spi.IConfigurationPropertyStoreService; +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.IManager; +import dev.galasa.framework.spi.ResourceUnavailableException; +import dev.galasa.framework.spi.Result; +import dev.galasa.framework.spi.creds.CredentialsException; +import dev.galasa.framework.spi.language.GalasaTest; +import dev.galasa.http.spi.IHttpManagerSpi; +import dev.galasa.sdv.ISdvUser; +import dev.galasa.sdv.SdvManagerException; +import dev.galasa.sdv.SdvManagerField; +import dev.galasa.sdv.SdvUser; +import dev.galasa.sdv.internal.properties.SdvHlq; +import dev.galasa.sdv.internal.properties.SdvPort; +import dev.galasa.sdv.internal.properties.SdvPropertiesSingleton; +import dev.galasa.sdv.internal.properties.SdvRole; +import dev.galasa.zosbatch.spi.IZosBatchSpi; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; +import javax.validation.constraints.NotNull; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.component.annotations.Component; + +/** + * This class acts as the entry points to the SDV manager + * by the Galasa framework, and implements various functions + * at various points throughout the test framework lifecycle. + * + *

It initialises the SDV manager, gathers all required + * config, assess which regions to record and what users, and + * intercepts and implements behaviour for test creation & + * teardown. + * + */ +@Component(service = {IManager.class}) +public class SdvManagerImpl extends AbstractManager { + + public static final String NAMESPACE = "sdv"; + + private static final Log LOG = LogFactory.getLog(SdvManagerImpl.class); + + // Dependencies on other managers + private ICicstsManagerSpi cicsManager; + private IZosBatchSpi batchManager; + private IHttpManagerSpi httpManager; + private IArtifactManager artifactManager; + private IDynamicStatusStoreService dss; + + private IConfidentialTextService cts; + + // User Pool management + private SdvUserPool sdvUserPool; + + // Local store of tested CICS regions, linked to their users and associated roles, each + // of which being recorded independently + private Map recordingRegions = new HashMap<>(); + + private Path storedArtifactRoot; + private SdvRecorderImpl sdvRecorder; + private List sdvUsersToRecordList = new ArrayList<>(); + + /** Define CF structure to be used when creating logstreams. */ + private static final String CFstructure = "LOG_GENERAL_001"; + + @Override + public void initialise(@NotNull IFramework framework, @NotNull List allManagers, + @NotNull List activeManagers, @NotNull GalasaTest galasaTest) + throws ManagerException { + super.initialise(framework, allManagers, activeManagers, galasaTest); + + // If this is not a java galasa test then exit + if (!galasaTest.isJava()) { + LOG.info("SDV recording is requested but is not eligible as this is not a Java test"); + return; + } + + // Check if SDV specific annotations exist. + // If not, don't use this manager. + List ourFields = findAnnotatedFields(SdvManagerField.class); + if (ourFields.isEmpty()) { + return; + } + + // Get access to the CPS so we can configure ourself + IConfigurationPropertyStoreService cps; + try { + cps = getFramework().getConfigurationPropertyService(NAMESPACE); + SdvPropertiesSingleton.setCps(cps); + } catch (ConfigurationPropertyStoreException e1) { + throw new SdvManagerException( + "Unable to access 'sdv' CPS namespace from framework services", + e1 + ); + } + + try { + this.dss = this.getFramework().getDynamicStatusStoreService(NAMESPACE); + } catch (DynamicStatusStoreException e) { + throw new SdvManagerException( + "Unable to access 'sdv' DSS namespace from framework services", + e + ); + } + + this.cts = framework.getConfidentialTextService(); + + // Initialise the SDV User pool manager + this.sdvUserPool = new SdvUserPool(this.getFramework(), dss, + this.getFramework().getResourcePoolingService()); + + this.storedArtifactRoot = getFramework().getResultArchiveStore().getStoredArtifactsRoot() + .resolve(NAMESPACE); + + // if we get here then we are required so add ourself to the list of active + // managers + youAreRequired(allManagers, activeManagers, galasaTest); + } + + @Override + public void youAreRequired(@NotNull List allManagers, + @NotNull List activeManagers, @NotNull GalasaTest galasaTest) + throws ManagerException { + + if (activeManagers.contains(this)) { + return; + } + + activeManagers.add(this); + + cicsManager = addDependentManager(allManagers, activeManagers, galasaTest, + ICicstsManagerSpi.class); + + if (cicsManager == null) { + throw new SdvManagerException("The CICS Manager is not available"); + } + + batchManager = + addDependentManager(allManagers, activeManagers, galasaTest, IZosBatchSpi.class); + if (batchManager == null) { + throw new SdvManagerException("The z/OS Batch Manager is not available"); + } + + artifactManager = addDependentManager(allManagers, activeManagers, galasaTest, + IArtifactManager.class); + if (artifactManager == null) { + throw new SdvManagerException("The Artifact Manager is not available"); + } + + httpManager = + addDependentManager(allManagers, activeManagers, galasaTest, IHttpManagerSpi.class); + if (httpManager == null) { + throw new SdvManagerException("The HTTP Manager is not available"); + } + } + + @Override + public boolean areYouProvisionalDependentOn(@NotNull IManager otherManager) { + if (otherManager instanceof ICicstsManagerSpi || otherManager instanceof IArtifactManager + || otherManager instanceof IHttpManagerSpi) { + return true; + } + + return super.areYouProvisionalDependentOn(otherManager); + } + + /** + * Provides what is returned by the SdvUser annotation. + * + *

It will obtain an available zOS user from a pool users, which + * matches the specified role. If no users are availble, this + * function will throw an ResourceUnavailableException exception + * which will result in the Galasa framework cancelling the test run, and + * requeuing it to reattempt the test again after a period of time. + * + *

The user will be added to the list of SDV Users within the + * RecordingRegion object. + * + * @param field - + * @param annotations - + * @return - ISdvUser + * @throws SdvManagerException generic errors encountered. + * @throws ResourceUnavailableException no available users in the pool. Galasa framework + * will handle. + */ + @GenerateAnnotatedField(annotation = SdvUser.class) + public ISdvUser getSdvUser(Field field, List annotations) + throws SdvManagerException, ResourceUnavailableException { + SdvUser annotation = field.getAnnotation(SdvUser.class); + + String cicsTag = defaultString(annotation.cicsTag(), "PRIMARY").toUpperCase(Locale.ROOT); + String roleTag = annotation.roleTag().toUpperCase(Locale.ROOT); + + if (roleTag.isBlank()) { + throw new SdvManagerException( + "SdvUser " + field.getName() + " cannot have a blank RoleTag."); + } + + String role = SdvRole.get(roleTag); + if (role == null) { + throw new SdvManagerException( + "Cannot find role. Please create or update CPS Property 'sdv.roleTag." + + roleTag + ".role'."); + } + + ICicsRegionProvisioned region = this.cicsManager.getTaggedCicsRegions().get(cicsTag); + if (region == null) { + throw new SdvManagerException( + "Unable to setup SDV User '" + field.getName() + "', for region with tag '" + + cicsTag + "' as a region with a matching 'cicsTag' tag was not found" + + ", or the region was not provisioned."); + } + + // Check a port has been given for the CICS region under test. + String port = SdvPort.get(region.getTag()); + if (port == null) { + throw new SdvManagerException( + "Could not find port. Please create or update CPS property 'sdv.cicsTag." + + region.getTag() + ".port'."); + } + + // Check an HLQ has been given for the CICS region under test. + String hlq = SdvHlq.get(region.getTag()); + if (hlq == null) { + throw new SdvManagerException( + "Could not find HLQ. Please create or update CPS property 'sdv.cicsTag." + + region.getTag() + ".hlq'."); + } + + // This can throw a ResourceUnavailableException, do not capture this + // let the framework handle it as it will re-queue the test for re-run + // later + String credentialTag = ""; + credentialTag = this.sdvUserPool.allocateUser(role, region); + + ICredentialsUsernamePassword credsObj = null; + try { + credsObj = (ICredentialsUsernamePassword) getFramework().getCredentialsService() + .getCredentials(credentialTag); + + cts.registerText(credsObj.getPassword(), + "Password for credential tag: " + credentialTag); + + } catch (CredentialsException e) { + throw new SdvManagerException( + "No credentials were found with the tag: " + credentialTag, e); + } + + SdvUserImpl newSdvUser = new SdvUserImpl(credentialTag, credsObj, cicsTag, role); + sdvUsersToRecordList.add(newSdvUser); + + return newSdvUser; + + } + + private void releaseUsers() throws CicstsManagerException { + // Release the users back to the pool + for (ISdvUser sdvUser : sdvUsersToRecordList) { + try { + SdvUserPool.deleteDss( + sdvUser.getCredentialsTag(), + cicsManager.locateCicsRegion(sdvUser.getCicsTag()).getApplid(), + getFramework().getTestRunName(), + this.dss + ); + } catch (DynamicStatusStoreException | CicstsManagerException e) { + if (LOG.isErrorEnabled()) { + LOG.error("Could not release SDV User: " + sdvUser.getCredentialsTag() + + ", on CICS region " + + cicsManager.locateCicsRegion(sdvUser.getCicsTag()).getApplid() + + ", for test run " + getFramework().getTestRunName(), e); + } + } + } + } + + @Override + public void provisionGenerate() throws ManagerException, ResourceUnavailableException { + + // *** Auto generate the fields + generateAnnotatedFields(SdvManagerField.class); + + // Create a list of regions, and their associated recordings + // per user + LOG.info("Populating list of CICS regions under test and recordings " + + "required for each user."); + + try { + for (Map.Entry entry : + cicsManager.getTaggedCicsRegions() + .entrySet()) { + + // Check CICS region is running version 750 or greater + if (entry.getValue().getVersion().isEarlierThan(ProductVersion.v(750))) { + if (LOG.isWarnEnabled()) { + LOG.warn("SDV recording will not take place on CICS region '" + + entry.getValue().getApplid() + + "'. Running version earlier than 750."); + } + continue; + } + + // Check CICS region has SEC=YES set + if (entry.getValue().getRegionJob().retrieveOutputAsString() + .contains("DFHXS1102I")) { + if (LOG.isWarnEnabled()) { + LOG.warn("SDV recording will not take place on CICS region '" + + entry.getValue().getApplid() + "'. Security is not active."); + } + continue; + } + + // Get list of users for this CICS region + List listOfUsersForRegion = + sdvUsersToRecordList.stream() + .filter(u -> entry.getKey().equals(u.getCicsTag())) + .collect(Collectors.toList()); + + if (!listOfUsersForRegion.isEmpty()) { + // Create maintenance terminal for CICS region as + // we know we definitely plan to record something there + // and will need this to create resources + ICicsTerminal terminal; + terminal = cicsManager.generateCicsTerminal(entry.getKey()); + RecordingRegion rr = new RecordingRegion(terminal); + recordingRegions.put(entry.getValue(), rr); + + // Add each SdvUser associated to the region to the + // list of recording Users on that region + for (ISdvUser sdvUser : listOfUsersForRegion) { + if (recordingRegions.get(entry.getValue()).addUserToRecord(sdvUser)) { + if (LOG.isInfoEnabled()) { + LOG.info("Will record - CICS Region: " + + entry.getValue().getApplid() + + ", User: " + sdvUser.getUsername() + ", Role: " + + sdvUser.getRole()); + } + } + } + } else { + if (LOG.isWarnEnabled()) { + LOG.warn( + "No users have been listed for recording via the " + + "SdvUser annotation for cicsTag '" + + entry.getValue().getTag() + + "'."); + } + } + } + LOG.info("Finished populating list of tested CICS regions and recordings " + + "required for each user/role."); + + // Create instance of the HTTP SDV recording tool + this.sdvRecorder = new SdvHttpRecorderImpl(getFramework(), recordingRegions, + artifactManager, batchManager, storedArtifactRoot, dss, httpManager); + } catch (ManagerException e) { + // If anything fails in here, we've already allocated the users, in + // which case, release them. + releaseUsers(); + throw e; + } + + } + + @Override + public void provisionStart() throws SdvManagerException { + // Create necessary resources to run SDV + sdvRecorder.prepareEnvironments(CFstructure); + } + + @Override + public void provisionStop() { + // SDV is ending, possibly via an exception + // so stop any known recordings & remove + // all resources + try { + sdvRecorder.endRecording(); + } catch (SdvManagerException e) { + LOG.error("Could not stop known SDC recordings in provisionStop.", e); + } + + try { + releaseUsers(); + } catch (CicstsManagerException e) { + LOG.error("Could not release SDV SdvUsers in provisionStop.", e); + } + + try { + sdvRecorder.cleanUpEnvironments(); + } catch (SdvManagerException e) { + LOG.error("Could not cleanup SDV environments in provisionStop.", e); + } + + } + + @Override + public void startOfTestClass() throws SdvManagerException { + // Start recording before test run + sdvRecorder.startRecording(); + } + + @Override + public Result endOfTestClass(@NotNull Result currentResult, Throwable currentException) + throws ManagerException { + + // Stop recording after test run + sdvRecorder.endRecording(); + + if (currentResult.isPassed()) { + sdvRecorder.exportRecordings(getFramework().getTestRun().getTestBundleName(), + getFramework().getTestRun().getTestClassName()); + } + + // We are not going to change the result + return super.endOfTestClass(currentResult, currentException); + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvManagersResourceMonitor.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvManagersResourceMonitor.java new file mode 100644 index 000000000..1e70189af --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvManagersResourceMonitor.java @@ -0,0 +1,151 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.framework.spi.DssDelete; +import dev.galasa.framework.spi.DynamicStatusStoreException; +import dev.galasa.framework.spi.DynamicStatusStoreMatchException; +import dev.galasa.framework.spi.FrameworkException; +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.IResourceManagement; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This class provides specific implementation to monitor the number of running SDV managers. + * + */ +public class SdvManagersResourceMonitor implements Runnable { + + private static final Log LOG = LogFactory.getLog(SdvManagersResourceMonitor.class); + + private final IFramework framework; + private final IResourceManagement resourceManagement; + private final IDynamicStatusStoreService dss; + + private static final String PERIOD_REGEX = "\\."; + + /** + * SdvManagersResourceMonitor constructor. + * + * @param framework - Galasa framework. + * @param resourceManagement - Galasa Resource Management. + * @param dss - Galasa DSS. + */ + public SdvManagersResourceMonitor(IFramework framework, IResourceManagement resourceManagement, + IDynamicStatusStoreService dss) { + this.framework = framework; + this.resourceManagement = resourceManagement; + this.dss = dss; + LOG.info("SDV Managers resource monitor initialised"); + } + + @Override + public void run() { + LOG.info("Monitoring for SDV managers held up in active status"); + + try { + // Get the list of SDV manager props in the DSS + Map sdvManagersInDss = dss.getPrefix("manager.runningManagers"); + + Set allActiveRuns = this.framework.getFrameworkRuns().getActiveRunNames(); + + // Iterate through all SDV managers stored in the DSS + for (Map.Entry entry : sdvManagersInDss.entrySet()) { + // Split list of managers into array + Set initialRunList = + new HashSet(Arrays.asList(entry.getValue().split(","))); + + for (String runName : initialRunList) { + if (!allActiveRuns.contains(runName)) { + String removeRun = runName; + String removeCicsApplId = entry.getKey().split(PERIOD_REGEX)[2]; + + deleteDss(removeCicsApplId, removeRun); + } + } + } + } catch (FrameworkException e) { + LOG.error("Failure during scanning DSS for SDV Managers"); + } + + this.resourceManagement.resourceManagementRunSuccessful(); + LOG.info("Finished cleaning up SDV Manager activity"); + } + + /** + * Called when a Galasa test run ends or is removed. + * + * @param runName - Galasa test run name. + */ + public void runFinishedOrDeleted(String runName) { + + try { + // Get list of SDV Managers listed as active in the DSS + Map sdvManagersInDss = dss.getPrefix("manager.runningManagers"); + + for (Map.Entry entry : sdvManagersInDss.entrySet()) { + // Split list of managers into array + Set initialRunList = + new HashSet(Arrays.asList(entry.getValue().split(","))); + + // This SDV Manager belongs to the run + if (initialRunList.contains(runName)) { + String removeCicsApplId = entry.getKey().split(PERIOD_REGEX)[2]; + deleteDss(removeCicsApplId, runName); + } + } + } catch (FrameworkException e) { + if (LOG.isErrorEnabled()) { + LOG.error("Failure cleaning up SDV Managers for finished run " + runName); + } + } + } + + private void deleteDss(String cicsApplid, String run) + throws DynamicStatusStoreMatchException, DynamicStatusStoreException { + + Set currentRunList = + new HashSet(Arrays.asList( + dss.get("manager.runningManagers." + cicsApplid).split(",") + )); + + if (currentRunList.size() == 1) { + // This is the last manager against the region + // and is stale, so delete all manager entries for + // this region + if (LOG.isInfoEnabled()) { + LOG.info("Removing SDV Manager props for CICS region " + cicsApplid + + ", assigned to inactive run " + run); + } + + dss.performActions( + new DssDelete("manager.runningManagers." + cicsApplid, null), + new DssDelete("manager." + cicsApplid + ".sdcLive", null) + ); + + } else { + // There are other managers, which may be live, or not. + // leave it to the last manager standing to tidy up. + // Just remove this run from the list + if (LOG.isInfoEnabled()) { + LOG.info("Removing SDV Manager from list on CICS region " + cicsApplid + + ", assigned to inactive run " + run); + } + + currentRunList.remove(run); + + dss.put("manager.runningManagers." + cicsApplid, String.join(",", currentRunList)); + } + + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvRecorderImpl.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvRecorderImpl.java new file mode 100644 index 000000000..1c17c07fb --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvRecorderImpl.java @@ -0,0 +1,554 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.artifact.IArtifactManager; +import dev.galasa.artifact.TestBundleResourceException; +import dev.galasa.cicsts.CicstsManagerException; +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.framework.spi.DynamicStatusStoreException; +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.sdv.ISdvUser; +import dev.galasa.sdv.SdvManagerException; +import dev.galasa.sdv.internal.properties.SdvHlq; +import dev.galasa.sdv.internal.properties.SdvSdcActivation; +import dev.galasa.sdv.internal.properties.SdvSrrLogstreamRemoval; +import dev.galasa.zosbatch.IZosBatchJob; +import dev.galasa.zosbatch.IZosBatchJobOutputSpoolFile; +import dev.galasa.zosbatch.ZosBatchException; +import dev.galasa.zosbatch.spi.IZosBatchSpi; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + + +/** + * This is the abstract base class for all SDV recorders. + * + *

It contains all common implementations for any SDV records. + * + *

It expects start/end recording functions to be overridden and implemented by specific child + * classes, but provides common resource creation/teardown, and YAML job generation. + * + */ +public abstract class SdvRecorderImpl { + + private static final Log LOG = LogFactory.getLog(SdvRecorderImpl.class); + + protected Map recordingRegions; + + private Path storedArtifactRoot; + private IArtifactManager artifactManager; + private IZosBatchSpi batchManager; + private IDynamicStatusStoreService dss; + private IFramework framework; + + protected static final String CICS_RESOURCES_GROUP_NAME = "SDVGRP"; + + private static final String DSS_MANAGER_PREFIX = "manager."; + private static final String DSS_RUNNING_MANAGERS_TAG = "runningManagers."; + private static final String DSS_SDC_LIVE_TAG = ".sdcLive"; + + /** + * SdvRecorderImpl constructor. + * + * @param framework - Galasa framework + * @param recordingRegions - A unique Map of CICS regions under test. + * @param artifactManager - Galasa Artifact Manager. + * @param batchManager - Galasa Batch Manager. + * @param storedArtifactRoot - The path where files should be stored to be included as test + * artifacts. + * @param dss - Galasa DSS. + */ + public SdvRecorderImpl(IFramework framework, Map recordingRegions, + IArtifactManager artifactManager, IZosBatchSpi batchManager, Path storedArtifactRoot, + IDynamicStatusStoreService dss) { + this.framework = framework; + this.recordingRegions = recordingRegions; + this.artifactManager = artifactManager; + this.batchManager = batchManager; + this.storedArtifactRoot = storedArtifactRoot; + this.dss = dss; + } + + abstract void startRecording() throws SdvManagerException; + + abstract void endRecording() throws SdvManagerException; + + /** + * Implements the full configuration of SDC on CICS regions under test. + * + *

It firstly consults the DSS to see if any other managers are running on a + * given CICS region, which will have already configured SDC. If no regions are found, and + * the SDV config states SDC should be configured, this manager adds an entry to the DSS to + * claim it will configure SDC. A list of running managers in the DSS is then created and + * updated. If another manager is found, this manager will only add to the list of running + * managers on the region and will skip SDC configuration. + * + *

See cleanUpEnvironments to see how the running manager list is used. + * + * @param cfStructure - Coupling Facility structure name to use when creating logstream. + * @throws SdvManagerException general error encountered. + */ + public void prepareEnvironments(String cfStructure) throws SdvManagerException { + for (Map.Entry entry : recordingRegions.entrySet()) { + try { + // Attempt to see if we are the first SDV manager working on the region, then + // create the runningManagers prop. Then configure SDC, if necessary. + if (LOG.isInfoEnabled()) { + LOG.info("Attempting to find other SDV managers running on " + + entry.getKey().getApplid()); + } + + if (dss.putSwap( + DSS_MANAGER_PREFIX + DSS_RUNNING_MANAGERS_TAG + entry.getKey().getApplid(), + null, framework.getTestRunName())) { + dss.put(DSS_MANAGER_PREFIX + entry.getKey().getApplid() + DSS_SDC_LIVE_TAG, + "false"); + + if (LOG.isInfoEnabled()) { + LOG.info("No other SDV managers found running on " + + entry.getKey().getApplid() + ". Created runningManagers list."); + } + + if (SdvSdcActivation.get(entry.getKey().getTag())) { + if (LOG.isInfoEnabled()) { + LOG.info( + "Activating SDC on CICS region: " + entry.getKey().getApplid()); + } + + createSrrLogstream(entry.getKey(), cfStructure); + createCicsResources(entry.getKey(), + entry.getValue().getMaintenanceTerminal()); + } + + dss.put(DSS_MANAGER_PREFIX + entry.getKey().getApplid() + DSS_SDC_LIVE_TAG, + "true"); + } else { + // We are not the first SDV manager running on the region, therefore + // SDC will already be set up (or is currently in the process of being set up), + // if necessary. + // Add to the running manager list only, and wait for SDC to be reported as live + // before continuing. + Set runningManagers = new HashSet( + Arrays.asList(dss.get(DSS_MANAGER_PREFIX + + DSS_RUNNING_MANAGERS_TAG + entry.getKey().getApplid()).split(","))); + + if (LOG.isInfoEnabled()) { + LOG.info(runningManagers.size() + " other SDV managers found running on " + + entry.getKey().getApplid() + ". Adding new manager to list."); + } + + runningManagers.add(framework.getTestRunName()); + dss.put( + DSS_MANAGER_PREFIX + DSS_RUNNING_MANAGERS_TAG + entry.getKey().getApplid(), + String.join(",", runningManagers)); + + // Wait for sdcLive to become True before continuing + if (LOG.isInfoEnabled()) { + LOG.info("Will wait for SDC to become live on " + + entry.getKey().getApplid()); + } + + int i = 0; + while (!"true".equals(dss.get( + DSS_MANAGER_PREFIX + entry.getKey().getApplid() + DSS_SDC_LIVE_TAG)) + && i++ < 20) { + if (LOG.isInfoEnabled()) { + LOG.info("SDC not live, reattempting on " + entry.getKey().getApplid() + + "..."); + } + Thread.sleep(1000); + } + + if (LOG.isInfoEnabled()) { + LOG.info( + "SDC made live by another SDV manager, continuing on " + + entry.getKey().getApplid() + ); + } + } + } catch (DynamicStatusStoreException | InterruptedException e) { + throw new SdvManagerException("Unable interact with DSS for SDV.", e); + } + } + } + + /** + * Implements the teardown of SDC on CICS regions under test. + * + *

It firstly consults the DSS to see if it is the last manager running on the given CICS + * region. If it is, and the SDV config states SDC should be configured, this manager will + * deconfigure SDC on the region and remove all resources. It will then remove entries from the + * DSS related to this. If more than one manager is found, this manager will only decrement the + * count of running managers on the region. + * + *

SRR Logstream removal is not done by default but can be configured to do so via the CPS + * properties. It would be essential to do this if provisioning a CICS region for the lifespan + * of the test run, to ensure no artifacts are left behind. + * + * @throws SdvManagerException general error encountered. + */ + public void cleanUpEnvironments() throws SdvManagerException { + for (Map.Entry entry : recordingRegions.entrySet()) { + + try { + if (LOG.isInfoEnabled()) { + LOG.info("Attempting to find other SDV managers running on " + + entry.getKey().getApplid()); + } + + // Get number of running SDV managers. + Set runningManagers = new HashSet( + Arrays.asList(dss.get(DSS_MANAGER_PREFIX + + DSS_RUNNING_MANAGERS_TAG + entry.getKey().getApplid()).split(","))); + + if (LOG.isInfoEnabled()) { + LOG.info(runningManagers + " SDV managers found running on " + + entry.getKey().getApplid() + "."); + } + + // If we are the last running for a + // region, clean up the resources on your way out, if necessary. + if (runningManagers.size() == 1) { + // Remove entry from DSS + if (LOG.isInfoEnabled()) { + LOG.info("Removing DSS entry, as this is the final SDV manager on " + + entry.getKey().getApplid() + "."); + } + + dss.delete( + DSS_MANAGER_PREFIX + DSS_RUNNING_MANAGERS_TAG + entry.getKey().getApplid() + ); + + if (SdvSdcActivation.get(entry.getKey().getTag())) { + if (LOG.isInfoEnabled()) { + LOG.info("Cleaning up CICS region after SDV recording: " + + entry.getKey().getApplid()); + } + + deleteCicsResources(entry.getKey(), + entry.getValue().getMaintenanceTerminal()); + } + + if (SdvSrrLogstreamRemoval.get(entry.getKey().getTag())) { + deleteSrrLogstream(entry.getKey()); + } + + dss.delete(DSS_MANAGER_PREFIX + entry.getKey().getApplid() + DSS_SDC_LIVE_TAG); + } else { + // We are not the SDV manager running, so just remove yourself + // from the equation & leave the last manager to do the tidying up + if (runningManagers != null) { + if (LOG.isInfoEnabled()) { + LOG.info( + "Removing " + framework.getTestRunName() + + " from running SDV manager list on " + entry.getKey().getApplid() + ); + } + + runningManagers.remove(framework.getTestRunName()); + + dss.put( + DSS_MANAGER_PREFIX + + DSS_RUNNING_MANAGERS_TAG + entry.getKey().getApplid(), + String.join(",", runningManagers) + ); + } + } + } catch (DynamicStatusStoreException e) { + throw new SdvManagerException("Unable interact with DSS for SDV.", e); + } + } + } + + /** + * Orchestrates the generation and storage of the Security YAML for each CICS region under test. + * + *

It loops through each CICS region under test, obtains the combined YAML + * for all users under test, then stores it as part of the test runs stored artifacts. + * + */ + public void exportRecordings(String testBundleName, String testClassName) + throws SdvManagerException { + for (Map.Entry entry : recordingRegions.entrySet()) { + if (LOG.isInfoEnabled()) { + LOG.info("Exporting SDV Security YAML for CICS region: " + + entry.getKey().getApplid()); + } + + String regionYaml = getRegionSecurityYaml(entry.getKey(), entry.getValue()); + storeYaml(entry.getKey(), regionYaml, testBundleName, testClassName); + } + } + + private void createSrrLogstream(ICicsRegion region, String cfStructure) + throws SdvManagerException { + + if (LOG.isInfoEnabled()) { + LOG.info("Attepmting to create LOGSTREAM on " + region.getApplid()); + } + + try { + Map attrs = new HashMap(); + attrs.put("OWNER", region.getRegionJob().getOwner()); + attrs.put("APPLID", region.getApplid()); + attrs.put("CFSTRUCT", cfStructure); + + String jcl = artifactManager.getBundleResources(this.getClass()) + .retrieveSkeletonFileAsString("/jcl/definelogstream.jcl", attrs).trim(); + + IZosBatchJob job = batchManager.getZosBatch(region.getZosImage()).submitJob(jcl, null); + int rc = job.waitForJob(); + if (rc == 12) { + if (LOG.isInfoEnabled()) { + LOG.info( + "Logstream not created, using existing, on CICS Region " + + region.getApplid() + + "." + ); + } + } else if (rc > 4) { + if (LOG.isWarnEnabled()) { + LOG.warn( + "JCL to define logstreams fail for CICS Region " + + region.getApplid() + + ", check artifacts for more details" + ); + } + } + } catch (ZosBatchException | TestBundleResourceException | IOException + | CicstsManagerException e) { + throw new SdvManagerException( + "Unable to run JCL to define logstreams for CICS Region " + + region.getApplid(), + e + ); + } + } + + private void deleteSrrLogstream(ICicsRegion region) throws SdvManagerException { + + if (LOG.isInfoEnabled()) { + LOG.info("Deleting LOGSTREAM on " + region.getApplid()); + } + + try { + Map attrs = new HashMap(); + attrs.put("OWNER", region.getRegionJob().getOwner()); + attrs.put("APPLID", region.getApplid()); + + String jcl = artifactManager.getBundleResources(this.getClass()) + .retrieveSkeletonFileAsString("/jcl/deletelogstreams.jcl", attrs).trim(); + + IZosBatchJob job = batchManager.getZosBatch(region.getZosImage()).submitJob(jcl, null); + int rc = job.waitForJob(); + if (rc > 4) { + throw new SdvManagerException( + "JCL to delete logstreams fail on CICS Region " + + region.getApplid() + + ", check artifacts for more details." + ); + } + } catch (ZosBatchException | TestBundleResourceException | IOException + | CicstsManagerException e) { + throw new SdvManagerException( + "Unable to run JCL to delete logstreams for CICS Region " + + region.getApplid(), + e + ); + } + + } + + protected void createCicsResources(ICicsRegion region, ICicsTerminal terminal) + throws SdvManagerException { + + // JOURNALMODEL + if (LOG.isInfoEnabled()) { + LOG.info("Creating JOURNALMODEL on " + region.getApplid()); + } + try { + region.ceda().createResource(terminal, "JOURNALMODEL", "SRR", CICS_RESOURCES_GROUP_NAME, + "JOURNALNAME(DFHSECR) DESCRIPTION(SRR JOURNAL) TYPE(MVS) STREAMNAME(" + + region.getRegionJob().getOwner() + "." + region.getApplid() + + ".DFHSECR)"); + } catch (CicstsManagerException e) { + throw new SdvManagerException( + "Could not create SRR JOURNALMODEL definition on CICS Region " + + region.getApplid() + + ".", + e + ); + } + + try { + region.ceda().installGroup(terminal, "DFHXSD"); + } catch (CicstsManagerException e) { + if (LOG.isInfoEnabled()) { + LOG.info( + "Couldn't install DFHXSD, already installed on CICS Region " + + region.getApplid() + ); + } + } + } + + protected void deleteCicsResources(ICicsRegion region, ICicsTerminal terminal) { + + if (LOG.isInfoEnabled()) { + LOG.info("Deleting the " + CICS_RESOURCES_GROUP_NAME + " group on " + + region.getApplid()); + } + try { + region.ceda().deleteGroup(terminal, CICS_RESOURCES_GROUP_NAME); + } catch (CicstsManagerException e) { + if (LOG.isErrorEnabled()) { + LOG.error( + "Could not delete the " + + CICS_RESOURCES_GROUP_NAME + + " on CICS Region " + + region.getApplid(), + e + ); + } + } + } + + private String getRegionSecurityYaml(ICicsRegion region, RecordingRegion recordingRegionData) + throws SdvManagerException { + + String yaml = ""; + try { + if (LOG.isInfoEnabled()) { + LOG.info("Building Security metadata job JCL for " + region.getApplid()); + } + Map attrs = new HashMap(); + attrs.put("OWNER", region.getRegionJob().getOwner()); + attrs.put("APPLID", region.getApplid()); + attrs.put("CICSHLQ", SdvHlq.get(region.getTag())); + + String jcl = artifactManager.getBundleResources(this.getClass()) + .retrieveSkeletonFileAsString("/jcl/getYaml.jcl", attrs).trim(); + + // Append to the JCL user and their role recorded on the region + // for the test + Boolean srrFound = false; + List srrIds = new ArrayList<>(); + for (ISdvUser recordingUser : recordingRegionData.getRecordingUsers()) { + if (recordingUser.getSrrId() != null) { + srrFound = true; + srrIds.add(recordingUser.getSrrId()); + jcl = jcl + "\nMATCHID=" + recordingUser.getSrrId() + "\nUSERID=" + + recordingUser.getUsername() + ",ROLE=" + recordingUser.getRole(); + } else { + if (LOG.isWarnEnabled()) { + LOG.warn("No SDC registered for user " + recordingUser.getUsername() + + " on region " + region.getApplid() + + ", skipping YAML generation."); + } + } + } + + if (!srrFound) { + return null; + } + + // Add final line indicating the end of the DDIN + jcl = jcl + "\n/*\n//"; + + if (LOG.isInfoEnabled()) { + LOG.info("Submitting Security metadata job JCL for " + region.getApplid()); + } + IZosBatchJob job = batchManager.getZosBatch(region.getZosImage()).submitJob(jcl, null); + int rc = job.waitForJob(); + + if (rc > 4) { + if (LOG.isErrorEnabled()) { + LOG.error( + "JCL to get Security metadata fail on CICS Region " + + region.getApplid() + + ", check artifacts for more details" + ); + } + } + + if (LOG.isInfoEnabled()) { + LOG.info( + "Grabbing Security metadata job output on CICS Region " + + region.getApplid() + ); + } + List spoolFiles; + spoolFiles = job.retrieveOutput().getSpoolFiles(); + + IZosBatchJobOutputSpoolFile yamlFile = spoolFiles.stream() + .filter(file -> "YAML".equals(file.getDdname())).findAny().orElse(null); + + if (yamlFile != null) { + if (LOG.isInfoEnabled()) { + LOG.info("YAML output obtained on " + region.getApplid()); + } + yaml = yamlFile.getRecords(); + } else { + throw new SdvManagerException( + "Security metadata job did not return any YAML for CICS Region " + + region.getApplid() + + ", containing SRR IDs: " + + String.join(",", srrIds) + ); + } + + } catch (ZosBatchException | TestBundleResourceException | IOException + | CicstsManagerException e) { + throw new SdvManagerException( + "Unable to run JCL to get Security metadata on CICS Region " + + region.getApplid(), + e + ); + } + + return yaml; + + } + + private void storeYaml(ICicsRegion region, String regionYaml, String testBundleName, + String testClassName) throws SdvManagerException { + + if (regionYaml != null) { + if (LOG.isInfoEnabled()) { + LOG.info("Storing YAML as test artifact for " + region.getApplid()); + } + + // Add to Galasa run + Path f = storedArtifactRoot.resolve(testBundleName + "/" + testClassName + "." + + region.getTag() + ".cics-security.yaml"); + try { + Files.write(f, regionYaml.getBytes("utf8"), StandardOpenOption.CREATE); + } catch (Exception e) { + throw new SdvManagerException( + "Unable to add YAML to Galasa run for CICS Region " + + region.getApplid() + + ". Attempting to save to path: " + f.toString(), + e + ); + } + } + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvResourceManagement.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvResourceManagement.java new file mode 100644 index 000000000..0b79f970b --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvResourceManagement.java @@ -0,0 +1,83 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.IResourceManagement; +import dev.galasa.framework.spi.IResourceManagementProvider; +import dev.galasa.framework.spi.ResourceManagerException; +import java.util.concurrent.TimeUnit; +import org.osgi.service.component.annotations.Component; + +/** + * This class acts as the high-level resource management deamon for + * SDV manager. + * + *

It will ensure sdv entries in the DSS are kept in-sync, + * up-to-date, and will tidy up any stale information. + * + */ +@Component(service = {IResourceManagementProvider.class}) +public class SdvResourceManagement implements IResourceManagementProvider { + + private IFramework framework; + private IResourceManagement resourceManagement; + + private SdvUserResourceMonitor sdvUserResourceMonitor; + private SdvManagersResourceMonitor sdvManagersResourceMonitor; + + @Override + public boolean initialise(IFramework framework, IResourceManagement resourceManagement) + throws ResourceManagerException { + this.framework = framework; + this.resourceManagement = resourceManagement; + + IDynamicStatusStoreService dss; + try { + dss = this.framework.getDynamicStatusStoreService("sdv"); + } catch (Exception e) { + throw new ResourceManagerException("Unable to initialise 'sdv' namespace from DSS.", e); + } + + sdvUserResourceMonitor = new SdvUserResourceMonitor( + framework, + resourceManagement, + dss + ); + sdvManagersResourceMonitor = new SdvManagersResourceMonitor( + framework, + resourceManagement, + dss + ); + + return true; + } + + @Override + public void start() { + + this.resourceManagement.getScheduledExecutorService().scheduleWithFixedDelay( + sdvUserResourceMonitor, this.framework.getRandom().nextInt(20), 20, + TimeUnit.SECONDS); + + this.resourceManagement.getScheduledExecutorService().scheduleWithFixedDelay( + sdvManagersResourceMonitor, this.framework.getRandom().nextInt(20), 20, + TimeUnit.SECONDS); + } + + @Override + public void shutdown() { + // Not required + } + + @Override + public void runFinishedOrDeleted(String runName) { + this.sdvUserResourceMonitor.runFinishedOrDeleted(runName); + this.sdvManagersResourceMonitor.runFinishedOrDeleted(runName); + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserImpl.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserImpl.java new file mode 100644 index 000000000..be5e6435f --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserImpl.java @@ -0,0 +1,154 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.ICredentialsUsernamePassword; +import dev.galasa.cicsts.CicstsManagerException; +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.sdv.ISdvUser; +import dev.galasa.sdv.SdvManagerException; +import dev.galasa.zos3270.Zos3270Exception; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This class implements the ISdvUser interface. + * + *

It provides all implementation for methods called on the + * ISdvUser interface. + * + */ +public class SdvUserImpl implements ISdvUser { + + private static final Log LOG = LogFactory.getLog(SdvUserImpl.class); + + private String credentialsTag; + private String role; + private String cicsTag; + private ICredentialsUsernamePassword credentials; + private String srrId; // When null, no recording is taking place + private Boolean recording; + + /** + * The SdvUserImpl constructor. + * + * @param credentialsTag - The string tag for the credential in the secure Galasa properties. + * @param credentials - ICredentialsUsernamePassword object containing the actual credentials. + * @param cicsTag - The string tag for the CICS region the user will run on. + * @param role - The role name the user belongs to. + */ + public SdvUserImpl(String credentialsTag, ICredentialsUsernamePassword credentials, + String cicsTag, String role) { + + this.credentialsTag = credentialsTag; + this.credentials = credentials; + this.cicsTag = cicsTag; + this.srrId = null; + this.recording = false; + this.role = role; + } + + @Override + public String getCredentialsTag() { + return this.credentialsTag; + } + + @Override + public String getUsername() { + return this.credentials.getUsername(); + } + + @Override + public String getPassword() { + return this.credentials.getPassword(); + } + + @Override + public String getRole() { + return this.role; + } + + @Override + public String getCicsTag() { + return this.cicsTag; + } + + @Override + public void logIntoTerminal(ICicsTerminal terminal) throws SdvManagerException { + try { + // Are we already on CESL/N? If not go to it + long timeout = 0; + if (!terminal.searchText("Signon to CICS", timeout)) { + terminal.clear().wfk(); + + terminal.type("CESL").enter().wfk(); + } + + terminal.waitForTextInField(new String[] {"Userid"}, + new String[] {"Security is not active"}); + terminal.type(this.credentials.getUsername()); + terminal.positionCursorToFieldContaining("Password"); + terminal.tab(); + terminal.type(this.credentials.getPassword()); + terminal.enter().wfk(); + + waitForLoggedOnText(terminal); + if (LOG.isDebugEnabled()) { + LOG.debug("Logged into CICS TS as user: " + this.credentials.getUsername()); + } + + terminal.clear().wfk(); + } catch (CicstsManagerException | Zos3270Exception e) { + throw new SdvManagerException( + "Could not log in via CESL on CICS region " + + terminal.getCicsRegion().getApplid(), + e + ); + } + + } + + @Override + public String getSrrId() { + return this.srrId; + } + + @Override + public Boolean isRecording() { + return this.recording; + } + + @Override + public void setSrrId(String srrId) { + this.srrId = srrId; + this.recording = true; + } + + @Override + public void setNotRecording() { + this.recording = false; + } + + private void waitForLoggedOnText(ICicsTerminal cicsTerminal) throws CicstsManagerException { + + String[] pass = {"Sign-on is complete"}; + String[] fail = {"Your password has expired. Please type your new password.", + "Invalid credentials entered", "userid has been revoked"}; + + try { + cicsTerminal.waitForTextInField(pass, fail); + } catch (Exception e) { + throw new CicstsManagerException( + "Unable to wait for the initial CICS screen, looking for '" + + String.join("', '", pass) + + "' on CICS Region " + + cicsTerminal.getCicsRegion().getApplid(), + e); + } + } + +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserPool.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserPool.java new file mode 100644 index 000000000..66bcaa593 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserPool.java @@ -0,0 +1,140 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.framework.spi.DssDelete; +import dev.galasa.framework.spi.DssUpdate; +import dev.galasa.framework.spi.DynamicStatusStoreException; +import dev.galasa.framework.spi.DynamicStatusStoreMatchException; +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.IResourcePoolingService; +import dev.galasa.framework.spi.InsufficientResourcesAvailableException; +import dev.galasa.framework.spi.ResourceUnavailableException; +import dev.galasa.sdv.SdvManagerException; +import dev.galasa.sdv.internal.properties.SdvPoolUsers; +import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This class provides the implementation for querying available + * users in a pool matching a role, and then picks one, and marks + * it as being in use. + * + *

It additonally implements the ability to release users back to + * the pool. + */ +public class SdvUserPool { + + private static final Log LOG = LogFactory.getLog(SdvUserPool.class); + + private final IDynamicStatusStoreService dss; + private final IResourcePoolingService rps; + private final IFramework framework; + + /** + * SdvUserPool contructor. + * + * @param framework - Galasa framework object. + * @param dss - Galasa DSS. + * @param rps - Galasa Resource Pooling Service. + * @throws SdvManagerException general error encountered. + */ + public SdvUserPool(IFramework framework, IDynamicStatusStoreService dss, + IResourcePoolingService rps) throws SdvManagerException { + + this.framework = framework; + this.dss = dss; + this.rps = rps; + } + + /** + * Will return an available user for a given role, if one is + * available. The user will then be marked as unavailable. + * + *

If a user is not available, an exception will be thrown. + * + * @param role - The role name the returned user must belong to. + * @param cicsRegion - The CICS Region which the user will interact with. + * @return - The Galasa credentials tag string for the allocated user. + * @throws SdvManagerException general error encountered. + * @throws ResourceUnavailableException no available users for that role currently. + */ + public String allocateUser(String role, ICicsRegion cicsRegion) + throws SdvManagerException, ResourceUnavailableException { + + List availableSdvUsers = null; + String theSdvUser = null; + + // Get the full pool of user credential tags for the + // specified zOS image and role + List fullZosImageUserListForRole = + SdvPoolUsers.get(cicsRegion.getZosImage().getImageID(), role); + + if (fullZosImageUserListForRole.isEmpty()) { + throw new SdvManagerException( + "No user credential tags provided for role '" + role + + "' on z/OS image '" + + cicsRegion.getZosImage().getImageID() + + "'. Please create or update CPS property 'sdv.zosImage." + + cicsRegion.getZosImage().getImageID() + + ".role." + + role + + ".credTags'." + ); + } + + // Retrieve available users from the pool, not being used by the region + try { + availableSdvUsers = this.rps.obtainResources(fullZosImageUserListForRole, null, 1, 1, + dss, "sdvuser." + cicsRegion.getApplid() + "."); + } catch (InsufficientResourcesAvailableException e) { + // There are no users available, inform the framework that we should go into wait state + // and try again later + // All resources (from other managers) will be discarded by using this + throw new ResourceUnavailableException( + "Could not obtain a user from the SDV user pool for image " + + cicsRegion.getZosImage().getImageID() + ", and role " + role, + e); + } + + // Allocate the user retrieved from the pool + try { + // There should only be a single user in the list allocated + theSdvUser = availableSdvUsers.get(0); + + // Allocate the user in the DSS + this.dss.performActions( + new DssUpdate("sdvuser." + cicsRegion.getApplid() + "." + theSdvUser, + this.framework.getTestRunName()), + new DssUpdate("run." + this.framework.getTestRunName() + ".sdvuser." + + cicsRegion.getApplid() + "." + theSdvUser, "active")); + + if (LOG.isTraceEnabled()) { + LOG.trace("Allocated SDV User " + theSdvUser + " on image " + + cicsRegion.getZosImage().getImageID() + " for CICS Applid " + + cicsRegion.getApplid() + " from SDV User pool allocation"); + } + + } catch (DynamicStatusStoreException e) { + throw new SdvManagerException( + "Could not update the DSS for user allocation of SDV User " + theSdvUser + + " on image " + cicsRegion.getZosImage().getImageID(), + e); + } + return theSdvUser; + } + + public static void deleteDss(String user, String cicsApplid, String run, + IDynamicStatusStoreService dss) + throws DynamicStatusStoreMatchException, DynamicStatusStoreException { + dss.performActions(new DssDelete("sdvuser." + cicsApplid + "." + user, run), + new DssDelete("run." + run + ".sdvuser." + cicsApplid + "." + user, "active")); + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserResourceMonitor.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserResourceMonitor.java new file mode 100644 index 000000000..c06820f6b --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/SdvUserResourceMonitor.java @@ -0,0 +1,122 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.IResourceManagement; +import java.util.Map; +import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This class provides specific implementation to monitor SdvUser usage. + * + */ +public class SdvUserResourceMonitor implements Runnable { + + private static final Log LOG = LogFactory.getLog(SdvUserResourceMonitor.class); + + private final IFramework framework; + private final IResourceManagement resourceManagement; + private final IDynamicStatusStoreService dss; + + private static final String PERIOD_REGEX = "\\."; + + /** + * SdvUserResourceMonitor constructor. + * + * @param framework - Galasa framework. + * @param resourceManagement - Galasa Resource Management. + * @param dss - Galasa DSS. + */ + public SdvUserResourceMonitor(IFramework framework, IResourceManagement resourceManagement, + IDynamicStatusStoreService dss) { + this.framework = framework; + this.resourceManagement = resourceManagement; + this.dss = dss; + LOG.info("SDV User provisioning resource monitor initialised"); + } + + @Override + public void run() { + LOG.info("Monitoring for SDV Users held up in allocated status"); + + try { + + // Get the list of SDV Users allocated in the DSS + Map sdvUsersInDss = dss.getPrefix("sdvuser"); + + Set allActiveRuns = this.framework.getFrameworkRuns().getActiveRunNames(); + + // Iterate through all SDV Users stored in the DSS + for (Map.Entry entry : sdvUsersInDss.entrySet()) { + // Delete DSS SDV User allocation to run not active + if (!allActiveRuns.contains(entry.getValue())) { + String removeRun = entry.getValue(); + String removeCicsApplId = entry.getKey().split(PERIOD_REGEX)[1]; + String removeUser = entry.getKey().split(PERIOD_REGEX)[2]; + + if (LOG.isInfoEnabled()) { + LOG.info("Freeing allocated user " + removeUser + + " assigned to inactive run " + removeRun); + } + + deleteDss(removeUser, removeCicsApplId, removeRun); + } + } + } catch (Exception e) { + LOG.error("Failure during scanning DSS for SDV Users"); + } + + this.resourceManagement.resourceManagementRunSuccessful(); + LOG.info("Finished cleaning up SDV User allocation"); + } + + /** + * Called when a Galasa test run ends or is removed. + * + * @param runName - Galasa test run name. + */ + public void runFinishedOrDeleted(String runName) { + + try { + // Get list of SDV Users allocated in the DSS + Map sdvUsersInDss = dss.getPrefix("sdvuser"); + + for (Map.Entry entry : sdvUsersInDss.entrySet()) { + + // This SDV User allocation belongs to the run + if (entry.getValue().equals(runName)) { + deleteDss(entry.getKey().split(PERIOD_REGEX)[2], + entry.getKey().split(PERIOD_REGEX)[1], entry.getValue()); + } + } + } catch (Exception e) { + if (LOG.isErrorEnabled()) { + LOG.error("Failure cleaning up SDV Users for finished run " + runName); + } + } + } + + private void deleteDss(String user, String cicsApplid, String run) { + if (LOG.isInfoEnabled()) { + LOG.info("Freeing user " + user + " on CICS Applid " + cicsApplid + " allocated to run " + + run + " which has finished"); + } + + try { + SdvUserPool.deleteDss(user, cicsApplid, run, dss); + } catch (Exception e) { + if (LOG.isErrorEnabled()) { + LOG.error("Failure in discarding SDV User " + user + " on CICS Applid " + cicsApplid + + " allocated to run " + run); + } + } + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvHlq.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvHlq.java new file mode 100644 index 000000000..4d1e6c8e0 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvHlq.java @@ -0,0 +1,45 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal.properties; + +import dev.galasa.framework.spi.ConfigurationPropertyStoreException; +import dev.galasa.framework.spi.cps.CpsProperties; +import dev.galasa.sdv.SdvManagerException; +import javax.validation.constraints.NotNull; + +/** + * The HLQ of the CICS region install. + * + * @galasa.cps.property + * + * @galasa.name sdv.cicsTag.[cicsTag].hlq + * + * @galasa.description The HLQ of the CICS region install + * + * @galasa.required Yes + * + * @galasa.default None + * + * @galasa.valid_values String + * + * @galasa.examples sdv.cicsTag.A.hlq=CICS.INSTALL
+ * + */ +public class SdvHlq extends CpsProperties { + + /** + * Returns the HLQ for a given cicsTag. + */ + public static String get(@NotNull String cicsTag) throws SdvManagerException { + try { + return getStringNulled(SdvPropertiesSingleton.cps(), "cicsTag", "hlq", cicsTag); + } catch (ConfigurationPropertyStoreException e) { + throw new SdvManagerException("Problem asking CPS for the HLQ for CICS tag: " + cicsTag, + e); + } + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPoolUsers.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPoolUsers.java new file mode 100644 index 000000000..224188dc5 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPoolUsers.java @@ -0,0 +1,48 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal.properties; + +import dev.galasa.framework.spi.ConfigurationPropertyStoreException; +import dev.galasa.framework.spi.cps.CpsProperties; +import dev.galasa.sdv.SdvManagerException; +import java.util.List; +import javax.validation.constraints.NotNull; + +/** + * The list of credentials that belong to a given role on a zOS image. + * + * @galasa.cps.property + * + * @galasa.name sdv.zosImage.[imageID].role.[Role].credTags + * + * @galasa.description The list of credentials that belong to a given role on a zOS image + * + * @galasa.required Yes + * + * @galasa.default [] + * + * @galasa.valid_values String[] + * + * @galasa.examples sdv.zosImage.ABC.role.TELLER.credTags=USER1,USER2
+ * + */ +public class SdvPoolUsers extends CpsProperties { + + /** + * Returns a List of users from the pool that belong to the provided role. + */ + public static @NotNull @NotNull List get(String image, String role) + throws SdvManagerException { + try { + return getStringList(SdvPropertiesSingleton.cps(), "zosImage", "credTags", image, + "role", role); + } catch (ConfigurationPropertyStoreException e) { + throw new SdvManagerException("Problem asking CPS for the User pool for zOS image: " + + image + ", and role: " + role, e); + } + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPort.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPort.java new file mode 100644 index 000000000..90cf9802a --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPort.java @@ -0,0 +1,45 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal.properties; + +import dev.galasa.framework.spi.ConfigurationPropertyStoreException; +import dev.galasa.framework.spi.cps.CpsProperties; +import dev.galasa.sdv.SdvManagerException; +import javax.validation.constraints.NotNull; + +/** + * The port the SDC TCPIPSERVICE should serve from on a CICS region. + * + * @galasa.cps.property + * + * @galasa.name sdv.cicsTag.[cicsTag].port + * + * @galasa.description The port the SDC TCPIPSERVICE should serve from on a CICS region + * + * @galasa.required Yes + * + * @galasa.default None + * + * @galasa.valid_values String + * + * @galasa.examples sdv.cicsTag.A.port=32000
+ * + */ +public class SdvPort extends CpsProperties { + + /** + * Returns the port number for a given cicsTag a TCPIPSERVICE should serve from. + */ + public static String get(@NotNull String cicsTag) throws SdvManagerException { + try { + return getStringNulled(SdvPropertiesSingleton.cps(), "cicsTag", "port", cicsTag); + } catch (ConfigurationPropertyStoreException e) { + throw new SdvManagerException( + "Problem asking CPS for the SDV port for CICS tag: " + cicsTag, e); + } + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPropertiesSingleton.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPropertiesSingleton.java new file mode 100644 index 000000000..27575a9d0 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvPropertiesSingleton.java @@ -0,0 +1,58 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal.properties; + +import dev.galasa.framework.spi.IConfigurationPropertyStoreService; +import dev.galasa.sdv.SdvManagerException; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; + +/** + * CPS Properties singleton class. + */ +@Component(service = SdvPropertiesSingleton.class, immediate = true) +public class SdvPropertiesSingleton { + + private static SdvPropertiesSingleton instance; + + private IConfigurationPropertyStoreService cps; + + @Activate + public void activate() { + instance = this; // NOSONAR + } + + @Deactivate + public void deactivate() { + instance = null; // NOSONAR + } + + /** + * Returns instance of CPS Properties class. + */ + public static IConfigurationPropertyStoreService cps() throws SdvManagerException { + if (instance != null) { + return instance.cps; + } + + throw new SdvManagerException( + "Attempt to access manager CPS before it has been initialised"); + } + + /** + * Sets instance of CPS Properties class. + */ + public static void setCps(IConfigurationPropertyStoreService cps) throws SdvManagerException { + if (instance != null) { + instance.cps = cps; + return; + } + + throw new SdvManagerException("Attempt to set manager CPS before instance created"); + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvRole.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvRole.java new file mode 100644 index 000000000..0dfe3d7be --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvRole.java @@ -0,0 +1,45 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal.properties; + +import dev.galasa.framework.spi.ConfigurationPropertyStoreException; +import dev.galasa.framework.spi.cps.CpsProperties; +import dev.galasa.sdv.SdvManagerException; +import javax.validation.constraints.NotNull; + +/** + * The role associated with a role tag. + * + * @galasa.cps.property + * + * @galasa.name sdv.roleTag.[roleTag].role + * + * @galasa.description The role associated with a role tag. + * + * @galasa.required Yes + * + * @galasa.default None + * + * @galasa.valid_values String + * + * @galasa.examples sdv.roleTag.A.role=TELLER
+ * + */ +public class SdvRole extends CpsProperties { + + /** + * Returns the Role name associated with a provided RoleTag. + */ + public static String get(@NotNull String roleTag) throws SdvManagerException { + try { + return getStringNulled(SdvPropertiesSingleton.cps(), "roleTag", "role", roleTag); + } catch (ConfigurationPropertyStoreException e) { + throw new SdvManagerException( + "Problem asking CPS for the Role for Role tag: " + roleTag, e); + } + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvSdcActivation.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvSdcActivation.java new file mode 100644 index 000000000..c4486f2ac --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvSdcActivation.java @@ -0,0 +1,55 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal.properties; + +import dev.galasa.framework.spi.ConfigurationPropertyStoreException; +import dev.galasa.framework.spi.cps.CpsProperties; +import dev.galasa.sdv.SdvManagerException; +import javax.validation.constraints.NotNull; + +/** + * Should the SDV manager configure and make SDC active on the CICS region?. + * + * @galasa.cps.property + * + * @galasa.name sdv.cicsTag.[cicsTag].SdcActivation + * + * @galasa.description Should the SDV manager configure all pre-reqs and make SDC active on the CICS + * region? + * + * Typically should be enabled for CICS regions that will be created as part of + * test, and then discarded. + * + * @galasa.required No + * + * @galasa.default false + * + * @galasa.valid_values true, false + * + * @galasa.examples sdv.cicsTag.A.SdcActivation=true
+ * + */ +public class SdvSdcActivation extends CpsProperties { + + /** + * Returns a boolean indicating if the manager should activate SDC as part of its set up. + */ + public static boolean get(@NotNull String cicsTag) throws SdvManagerException { + try { + String sdvSdcActivation = getStringNulled(SdvPropertiesSingleton.cps(), "cicsTag", + "SdcActivation", cicsTag); + + if (sdvSdcActivation == null) { + return false; + } + return Boolean.parseBoolean(sdvSdcActivation); + } catch (ConfigurationPropertyStoreException e) { + throw new SdvManagerException( + "Problem asking CPS for SDC activation config for CICS tag: " + cicsTag, e); + } + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvSrrLogstreamRemoval.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvSrrLogstreamRemoval.java new file mode 100644 index 000000000..13d12a234 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/java/dev/galasa/sdv/internal/properties/SdvSrrLogstreamRemoval.java @@ -0,0 +1,57 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal.properties; + +import dev.galasa.framework.spi.ConfigurationPropertyStoreException; +import dev.galasa.framework.spi.cps.CpsProperties; +import dev.galasa.sdv.SdvManagerException; +import javax.validation.constraints.NotNull; + +/** + * Should the SDV manager remove the SRR Journal and logstream on the CICS region?. + * + * @galasa.cps.property + * + * @galasa.name sdv.cicsTag.[cicsTag].SrrLogstreamRemoval + * + * @galasa.description Should the SDV manager remove the SRR Journal and logstream on the CICS + * region? + * + * Typically should be enabled for CICS regions that will be shutdown as part of + * test, and then discarded. + * + * @galasa.required No + * + * @galasa.default false + * + * @galasa.valid_values true, false + * + * @galasa.examples sdv.cicsTag.A.SrrLogstreamRemoval=true
+ * + */ +public class SdvSrrLogstreamRemoval extends CpsProperties { + + /** + * Returns a boolean indicating if the manager should delete the SRR logstream as part + * of its cleanup. + */ + public static boolean get(@NotNull String cicsTag) throws SdvManagerException { + try { + String sdvSrrLogstreamRemoval = getStringNulled(SdvPropertiesSingleton.cps(), "cicsTag", + "SrrLogstreamRemoval", cicsTag); + + if (sdvSrrLogstreamRemoval == null) { + return false; + } + return Boolean.parseBoolean(sdvSrrLogstreamRemoval); + } catch (ConfigurationPropertyStoreException e) { + throw new SdvManagerException( + "Problem asking CPS for SRR Logstream removal config for CICS tag: " + cicsTag, + e); + } + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/definelogstream.jcl b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/definelogstream.jcl new file mode 100644 index 000000000..4efa39e0f --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/definelogstream.jcl @@ -0,0 +1,12 @@ +//****************************************************** +//* DEFINE a new logstream model for DFHSECR journal +//* Note: Log data will be autodeleted after 1 day +//****************************************************** +//DEFMODEL EXEC PGM=IXCMIAPU +//SYSPRINT DD SYSOUT=A,DCB=RECFM=FBA +//SYSIN DD * + DATA TYPE(LOGR) REPORT(NO) + DEFINE LOGSTREAM NAME(++OWNER++.++APPLID++.MODEL) + STRUCTNAME(++CFSTRUCT++) MODEL(YES) + AUTODELETE(YES) RETPD(0001) +/* \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/deletelogstreams.jcl b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/deletelogstreams.jcl new file mode 100644 index 000000000..805cf71b9 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/deletelogstreams.jcl @@ -0,0 +1,19 @@ +//****************************************************** +//* DELETE logstreams used by any previous instances +//* of this CICS +//****************************************************** +//DELSTR EXEC PGM=IXCMIAPU +//SYSPRINT DD SYSOUT=A,DCB=RECFM=FBA +//SYSIN DD * + DATA TYPE(LOGR) REPORT(NO) + DELETE LOGSTREAM NAME(++OWNER++.++APPLID++.DFHSECR) +/* +//* +//DELMOD EXEC PGM=IXCMIAPU +//SYSPRINT DD SYSOUT=A,DCB=RECFM=FBA +//SYSIN DD * + DATA TYPE(LOGR) REPORT(NO) + DELETE LOGSTREAM NAME(++OWNER++.++APPLID++.MODEL) +/* + SET MAXCC=0 +// \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/getYaml.jcl b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/getYaml.jcl new file mode 100644 index 000000000..908cfd8bf --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/main/resources/jcl/getYaml.jcl @@ -0,0 +1,7 @@ +//MYLIB JCLLIB ORDER=(++CICSHLQ++.SDFHPROC) +//SDVCAPTR EXEC DFHXSDSO, +// HLQ=++CICSHLQ++, +// LOGSTRM=++OWNER++.++APPLID++.DFHSECR, +// CYL=100 +//EXTRACT.SYSIN DD * +HEADER=NO \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestRecordingRegion.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestRecordingRegion.java new file mode 100644 index 000000000..ed6391249 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestRecordingRegion.java @@ -0,0 +1,71 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.ICredentialsUsernamePassword; +import dev.galasa.framework.spi.creds.CredentialsException; +import dev.galasa.framework.spi.creds.CredentialsUsernamePassword; +import dev.galasa.sdv.ISdvUser; +import dev.galasa.sdv.SdvManagerException; +import java.util.List; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + + +class TestRecordingRegion { + + RecordingRegion rr; + ICredentialsUsernamePassword credentials; + + @BeforeEach + void beforeEach() throws CredentialsException { + rr = new RecordingRegion(null); + + credentials = + new CredentialsUsernamePassword(null, "user1", "password1"); + } + + @Test + void testAddingNewUserToRegion() throws SdvManagerException, CredentialsException { + // No users to start + List beforeList = rr.getRecordingUsers(); + Assertions.assertEquals(0, beforeList.size()); + + // Add new user + ISdvUser newUser = new SdvUserImpl("creds1", credentials, "cics1", "TELLER"); + rr.addUserToRecord(newUser); + + // Number of users increment, and user is the one created + List afterList = rr.getRecordingUsers(); + Assertions.assertEquals(1, afterList.size()); + Assertions.assertEquals(newUser, afterList.get(0)); + } + + @Test + void testAddingExistingUserToRegion() throws SdvManagerException, CredentialsException { + // Add existing user + ISdvUser existingUser = new SdvUserImpl("creds1", credentials, "cics1", "TELLER"); + rr.addUserToRecord(existingUser); + List beforeList = rr.getRecordingUsers(); + Assertions.assertEquals(1, beforeList.size()); + Assertions.assertEquals(existingUser, beforeList.get(0)); + + // Create new user with same user name + ISdvUser newUser = new SdvUserImpl("creds2", credentials, "cics1", "ADMIN"); + Throwable exception = Assertions.assertThrows( + SdvManagerException.class, + () -> rr.addUserToRecord(newUser) + ); + + Assertions.assertEquals( + "User 'user1' has been allocated to more than one region in the test." + + " Please report this to the Galasa project.", + exception.getMessage() + ); + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvHttpRecorderImpl.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvHttpRecorderImpl.java new file mode 100644 index 000000000..3afa33691 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvHttpRecorderImpl.java @@ -0,0 +1,4157 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import com.google.gson.JsonObject; +import dev.galasa.ICredentialsUsernamePassword; +import dev.galasa.artifact.IArtifactManager; +import dev.galasa.artifact.IBundleResources; +import dev.galasa.artifact.TestBundleResourceException; +import dev.galasa.cicsts.CedaException; +import dev.galasa.cicsts.CemtException; +import dev.galasa.cicsts.CicstsManagerException; +import dev.galasa.cicsts.ICeda; +import dev.galasa.cicsts.ICemt; +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.cicsts.spi.ICicsRegionProvisioned; +import dev.galasa.framework.spi.DynamicStatusStoreException; +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.ResourceUnavailableException; +import dev.galasa.framework.spi.creds.CredentialsException; +import dev.galasa.framework.spi.creds.CredentialsUsernamePassword; +import dev.galasa.http.HttpClientException; +import dev.galasa.http.HttpClientResponse; +import dev.galasa.http.IHttpClient; +import dev.galasa.http.spi.IHttpManagerSpi; +import dev.galasa.ipnetwork.IIpHost; +import dev.galasa.sdv.ISdvUser; +import dev.galasa.sdv.SdvManagerException; +import dev.galasa.sdv.internal.properties.SdvHlq; +import dev.galasa.sdv.internal.properties.SdvPort; +import dev.galasa.sdv.internal.properties.SdvSdcActivation; +import dev.galasa.sdv.internal.properties.SdvSrrLogstreamRemoval; +import dev.galasa.zos.IZosImage; +import dev.galasa.zosbatch.IZosBatch; +import dev.galasa.zosbatch.IZosBatchJob; +import dev.galasa.zosbatch.IZosBatchJobOutput; +import dev.galasa.zosbatch.IZosBatchJobOutputSpoolFile; +import dev.galasa.zosbatch.ZosBatchException; +import dev.galasa.zosbatch.internal.ZosBatchJobOutputSpoolFileImpl; +import dev.galasa.zosbatch.spi.IZosBatchSpi; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + + +class TestSdvHttpRecorderImpl { + + private MockedStatic sdvSdcActivation; + private MockedStatic sdvPort; + private MockedStatic sdvSrrLogstreamRemoval; + private MockedStatic sdvHlq; + private MockedStatic files; + + private ICicsRegionProvisioned mockCicsaRegion; + private IZosImage regionaImage; + private ICicsRegionProvisioned mockCicsbRegion; + private IZosImage regionbImage; + + private String regionaTag = "CICSA"; + private String regionaApplid = "APPL1"; + private String passwordString = "password123"; + private String regionbTag = "CICSB"; + private String regionbApplid = "APPL2"; + private String tellerRoleString = "TELLER"; + private String testRunName = "RUN123"; + private String createLogstreamJcl = "jcl_for_defining_logstreams"; + private String deleteLogstreamJcl = "jcl_for_defining_logstreams"; + private String logVariableString = "LOG"; + private String regionAportString = "32000"; + private String regionBportString = "32001"; + private String owner1String = "owner1"; + private String owner2String = "owner2"; + private String user1String = "user1"; + private String user2String = "user2"; + private String user3String = "user3"; + private String creds1String = "CREDS1"; + private String creds2String = "CREDS2"; + private String creds3String = "CREDS3"; + private String adminRoleString = "ADMIN"; + private String sdvHttpRecorderImplClassString = + "dev.galasa.sdv.internal.SdvHttpRecorderImpl"; + private String jclCreateLogstreamPathString = "/jcl/definelogstream.jcl"; + private String jclDeleteLogstreamPathString = "/jcl/deletelogstreams.jcl"; + private String jclGetYamlPathString = "/jcl/getYaml.jcl"; + private String structureString = "A_STRUCTURE"; + private String modifiersString = "modifiers"; + private String managerPrefixString = "manager."; + private String runningManagersString = "runningManagers."; + private String falseString = "false"; + private String sdcLiveString = ".sdcLive"; + private String cicsServerStringA = "cicsServerA"; + private String sdcUrl = "/DFHSDC"; + private String httpString = "http://"; + private String srrIdString = "srr_id"; + private String srrId1 = "_654654"; + private String srrId2 = "_7676575"; + private String srrId3 = "_4543634"; + private static final String uncheckedString = "unchecked"; + private String user1UnableToStartErrorString + = "Was unable to start recording for user 'user1', on CICS Region APPL1"; + private String messagePropString = "message"; + private String errorMessageString = "bad stuff happening"; + private String submitString = "submit"; + private String nullString = "null"; + private String errorOutputBadStuffString = "\nbad stuff happening"; + private String errorOutputPayloadStrng = + "\n{\"srr_id\":\"null\",\"message\":\"somethings gone badly wrong\"}"; + private String serverErrorMessage = "somethings gone badly wrong"; + private String utfString = "utf8"; + private String getYamlString = "/getYaml.jcl"; + private String onCicsRegionMsg = "', on CICS Region "; + + + @SuppressWarnings("PMD") + private static final Log mockLog = Mockito.mock(Log.class); + + @BeforeEach + public void setUp() throws CicstsManagerException { + // Registering static mocks before each test + sdvSdcActivation = Mockito.mockStatic(SdvSdcActivation.class); + sdvPort = Mockito.mockStatic(SdvPort.class); + sdvSrrLogstreamRemoval = Mockito.mockStatic(SdvSrrLogstreamRemoval.class); + sdvHlq = Mockito.mockStatic(SdvHlq.class); + files = Mockito.mockStatic(Files.class); + + sdvHlq.when(() -> SdvHlq.get(regionaTag)).thenReturn("CICS.INSTALL"); + sdvHlq.when(() -> SdvHlq.get(regionbTag)).thenReturn("CICS.INSTALL"); + + // LOG + Mockito.reset(mockLog); + Mockito.when(mockLog.isInfoEnabled()).thenReturn(true); + Mockito.when(mockLog.isWarnEnabled()).thenReturn(true); + Mockito.when(mockLog.isErrorEnabled()).thenReturn(true); + Mockito.when(mockLog.isTraceEnabled()).thenReturn(true); + Mockito.when(mockLog.isDebugEnabled()).thenReturn(true); + + // Region A SdvPort + sdvPort.when(() -> SdvPort.get(regionaTag)).thenReturn(regionAportString); + + sdvSrrLogstreamRemoval.when(() -> SdvSrrLogstreamRemoval.get(regionaTag)).thenReturn(true); + + // Mock RegionA + IIpHost ipHostA = Mockito.mock(IIpHost.class); + Mockito.when(ipHostA.getHostname()).thenReturn(cicsServerStringA); + regionaImage = Mockito.mock(IZosImage.class); + Mockito.when(regionaImage.getIpHost()).thenReturn(ipHostA); + IZosBatchJob mockIzOsBatchJoba = Mockito.mock(IZosBatchJob.class); + Mockito.when(mockIzOsBatchJoba.getOwner()).thenReturn(owner1String); + mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getTag()).thenReturn(regionaTag); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn(regionaApplid); + Mockito.when(mockCicsaRegion.getRegionJob()).thenReturn(mockIzOsBatchJoba); + Mockito.when(mockCicsaRegion.getZosImage()).thenReturn(regionaImage); + + // Region B SdvPort + sdvPort.when(() -> SdvPort.get(regionbTag)).thenReturn(regionBportString); + + sdvSrrLogstreamRemoval.when(() -> SdvSrrLogstreamRemoval.get(regionbTag)).thenReturn(true); + + // Mock RegionB + IIpHost ipHostB = Mockito.mock(IIpHost.class); + Mockito.when(ipHostB.getHostname()).thenReturn("cicsServerB"); + regionbImage = Mockito.mock(IZosImage.class); + Mockito.when(regionbImage.getIpHost()).thenReturn(ipHostB); + IZosBatchJob mockIzOsBatchJobb = Mockito.mock(IZosBatchJob.class); + Mockito.when(mockIzOsBatchJobb.getOwner()).thenReturn(owner2String); + mockCicsbRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsbRegion.getTag()).thenReturn(regionbTag); + Mockito.when(mockCicsbRegion.getApplid()).thenReturn(regionbApplid); + Mockito.when(mockCicsbRegion.getRegionJob()).thenReturn(mockIzOsBatchJobb); + Mockito.when(mockCicsbRegion.getZosImage()).thenReturn(regionbImage); + } + + @AfterEach + public void tearDown() { + // Closing static mocks after each test + sdvSdcActivation.close(); + sdvPort.close(); + sdvSrrLogstreamRemoval.close(); + sdvHlq.close(); + files.close(); + } + + @Test + void testPrepareEnvironmentsAsFirstManagerOnRegionWithSdcActivation() + throws CredentialsException, SdvManagerException, ClassNotFoundException, + NoSuchFieldException, SecurityException, IllegalArgumentException, + IllegalAccessException, InstantiationException, InvocationTargetException, + NoSuchMethodException, ResourceUnavailableException, DynamicStatusStoreException, + CicstsManagerException, TestBundleResourceException, IOException, ZosBatchException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).createResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).installGroup(Mockito.any(), Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + Mockito.when( + ceda.resourceExists(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(true); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + Mockito.when(mockCicsbRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsbRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrB = new RecordingRegion(regionbTerminal); + // Mock user 1 + ICredentialsUsernamePassword user3Creds = + new CredentialsUsernamePassword(null, user3String, passwordString); + ISdvUser user3 = new SdvUserImpl(creds3String, user3Creds, regionbTag, tellerRoleString); + rrB.addUserToRecord(user3); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + recordingRegions.put(mockCicsbRegion, rrB); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenReturn(true); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + regionaApplid + sdcLiveString, falseString); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionbApplid, + null, testRunName)).thenReturn(true); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + regionbApplid + sdcLiveString, falseString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclCreateLogstreamPathString), Mockito.any())) + .thenReturn(createLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(0); + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(createLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + Mockito.when(batchManager.getZosBatch(regionbImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionbTag)).thenReturn(true); + + // Make call to funtion under test + sdvHttpRecorder.prepareEnvironments(structureString); + + // Ensure that we call ceda & cemt to create resources + Mockito.verify(cemt, Mockito.times(4)).setResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(6)).createResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(4)).installGroup(Mockito.any(), Mockito.any()); + } + + @Test + void testPrepareEnvironmentsAsSecondManagerOnRegion() + throws CicstsManagerException, CredentialsException, SdvManagerException, + DynamicStatusStoreException, TestBundleResourceException, IOException, + ZosBatchException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).createResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).installGroup(Mockito.any(), Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + Mockito.when( + ceda.resourceExists(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(true); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + Mockito.when(mockCicsbRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsbRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrB = new RecordingRegion(regionbTerminal); + // Mock user 1 + ICredentialsUsernamePassword user3Creds = + new CredentialsUsernamePassword(null, user3String, passwordString); + ISdvUser user3 = new SdvUserImpl(creds3String, user3Creds, regionbTag, tellerRoleString); + rrB.addUserToRecord(user3); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + recordingRegions.put(mockCicsbRegion, rrB); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenReturn(false); + Mockito.when(dssService.get(managerPrefixString + runningManagersString + regionaApplid)) + .thenReturn("L1,L2"); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + runningManagersString + regionaApplid, + "L1,L2,RUN123"); + Mockito.when(dssService.get(managerPrefixString + regionaApplid + sdcLiveString)) + .thenReturn(falseString, "true"); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionbApplid, + null, testRunName)).thenReturn(false); + Mockito.when(dssService.get(managerPrefixString + runningManagersString + regionbApplid)) + .thenReturn("L1,L2"); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + runningManagersString + regionbApplid, + "L5,L6,RUN123"); + Mockito.when(dssService.get(managerPrefixString + regionbApplid + sdcLiveString)) + .thenReturn(falseString, "true"); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclCreateLogstreamPathString), Mockito.any())) + .thenReturn(createLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(0); + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(createLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + sdvHttpRecorder.prepareEnvironments(structureString); + + // Ensure that we DO NOT call ceda & cemt to create resources. + // Another manager will had created the resource, so this manager didn't have to. + Mockito.verify(cemt, Mockito.times(0)).setResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(0)).createResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(0)).installGroup(Mockito.any(), Mockito.any()); + } + + @Test + void testPrepareEnvironmentsLogstreamJobFailsDueToExisting() + throws CicstsManagerException, CredentialsException, SdvManagerException, + DynamicStatusStoreException, TestBundleResourceException, IOException, + ZosBatchException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).createResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).installGroup(Mockito.any(), Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + Mockito.when( + ceda.resourceExists(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(true); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenReturn(true); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + regionaApplid + sdcLiveString, falseString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclCreateLogstreamPathString), Mockito.any())) + .thenReturn(createLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(12); // EXISTING RETURN CODE + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(createLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + sdvHttpRecorder.prepareEnvironments(structureString); + + // Ensure that we call ceda & cemt to create resources + Mockito.verify(cemt, Mockito.times(2)).setResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(3)).createResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(2)).installGroup(Mockito.any(), Mockito.any()); + + // Check there is a warning in the log indicating Region A won't record + Mockito.verify(mockLog).info( + "Logstream not created, using existing, on CICS Region " + + regionaApplid + + "." + ); + } + + @Test + void testPrepareEnvironmentsLogstreamJobFailsDueToError() + throws CicstsManagerException, CredentialsException, SdvManagerException, + DynamicStatusStoreException, TestBundleResourceException, IOException, + ZosBatchException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).createResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).installGroup(Mockito.any(), Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + Mockito.when( + ceda.resourceExists(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(true); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenReturn(true); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + regionaApplid + sdcLiveString, falseString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclCreateLogstreamPathString), Mockito.any())) + .thenReturn(createLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(16); // EXISTING RETURN CODE + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(createLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + sdvHttpRecorder.prepareEnvironments(structureString); + + // Ensure that we call ceda & cemt to create resources + Mockito.verify(cemt, Mockito.times(2)).setResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(3)).createResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(2)).installGroup(Mockito.any(), Mockito.any()); + + // Check there is a warning in the log indicating Region A won't record + Mockito.verify(mockLog).warn( + "JCL to define logstreams fail for CICS Region " + + regionaApplid + + ", check artifacts for more details" + ); + } + + @Test + void testPrepareEnvironmentsCedaCreateException() + throws CicstsManagerException, CredentialsException, SdvManagerException, + DynamicStatusStoreException, TestBundleResourceException, IOException, + ZosBatchException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doThrow(new CedaException("Could not create resource")).when(ceda).createResource( + Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenReturn(true); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + regionaApplid + sdcLiveString, falseString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclCreateLogstreamPathString), Mockito.any())) + .thenReturn(createLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(0); + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(createLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.prepareEnvironments(structureString); + }); + + Assertions.assertEquals( + "Could not create SRR JOURNALMODEL definition on CICS Region " + + regionaApplid + + ".", + exception.getMessage() + ); + + } + + @Test + void testPrepareEnvironmentsCedaInstallSdvGrpException() + throws IllegalArgumentException, IllegalAccessException, InstantiationException, + InvocationTargetException, NoSuchMethodException, SecurityException, + NoSuchFieldException, ClassNotFoundException, ZosBatchException, + TestBundleResourceException, IOException, DynamicStatusStoreException, + CicstsManagerException, CredentialsException, SdvManagerException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).createResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any()); + Mockito.doThrow(new CedaException("could not install")).when(ceda) + .installGroup(Mockito.any(), Mockito.any()); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenReturn(true); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + regionaApplid + sdcLiveString, falseString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclCreateLogstreamPathString), Mockito.any())) + .thenReturn(createLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(0); + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(createLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.prepareEnvironments(structureString); + }); + + Assertions.assertEquals( + "Could not install SDV resource group on CICS region " + + regionaApplid, + exception.getMessage() + ); + + } + + @Test + void testPrepareEnvironmentsCedaInstallDfhxsdException() + throws IllegalArgumentException, IllegalAccessException, InstantiationException, + InvocationTargetException, NoSuchMethodException, SecurityException, + NoSuchFieldException, ClassNotFoundException, ZosBatchException, + TestBundleResourceException, IOException, DynamicStatusStoreException, + CicstsManagerException, CredentialsException, SdvManagerException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).createResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).installGroup(Mockito.any(), Mockito.eq("SDVGRP")); + Mockito.doThrow(new CedaException("could not install")).when(ceda) + .installGroup(Mockito.any(), Mockito.eq("DFHXSD")); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenReturn(true); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + regionaApplid + sdcLiveString, falseString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclCreateLogstreamPathString), Mockito.any())) + .thenReturn(createLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(0); + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(createLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + sdvHttpRecorder.prepareEnvironments(structureString); + + // Ensure that we call ceda & cemt to create resources + Mockito.verify(cemt, Mockito.times(0)).setResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(3)).createResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(2)).installGroup(Mockito.any(), Mockito.any()); + + // Check there is a warning in the log indicating Region A won't record + Mockito.verify(mockLog, Mockito.times(1)).info( + "Couldn't install DFHXSD, already installed on CICS Region " + + regionaApplid + ); + + } + + @Test + void testPrepareEnvironmentsBatchJobThrowsException() throws CredentialsException, + SdvManagerException, DynamicStatusStoreException, TestBundleResourceException, + IOException, ZosBatchException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException, CicstsManagerException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenReturn(true); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + regionaApplid + sdcLiveString, falseString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclCreateLogstreamPathString), Mockito.any())) + .thenReturn(createLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenThrow(new ZosBatchException("bad job run")); + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(createLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.prepareEnvironments(structureString); + }); + + Assertions.assertEquals( + "Unable to run JCL to define logstreams for CICS Region " + + regionaApplid, + exception.getMessage() + ); + } + + @Test + void testPrepareEnvironmentsDssThrowsException() + throws DynamicStatusStoreException, NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException, InstantiationException, + InvocationTargetException, NoSuchMethodException, CicstsManagerException, + CredentialsException, SdvManagerException, ClassNotFoundException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenThrow(new DynamicStatusStoreException("dss issues")); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, null, null, null, dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.prepareEnvironments(structureString); + }); + + Assertions.assertEquals("Unable interact with DSS for SDV.", exception.getMessage()); + } + + @Test + void testPrepareEnvironmentsCemtThrowsException() throws DynamicStatusStoreException, + TestBundleResourceException, IOException, CicstsManagerException, CredentialsException, + SdvManagerException, ZosBatchException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doThrow(new CemtException("bad news")).when(cemt).setResource(Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).createResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).installGroup(Mockito.any(), Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + Mockito.when( + ceda.resourceExists(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(true); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenReturn(true); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + regionaApplid + sdcLiveString, falseString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclCreateLogstreamPathString), Mockito.any())) + .thenReturn(createLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(0); + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(createLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + sdvHttpRecorder.prepareEnvironments(structureString); + + // Ensure that we call ceda & cemt to create resources + Mockito.verify(cemt, Mockito.times(1)).setResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(3)).createResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(2)).installGroup(Mockito.any(), Mockito.any()); + + // Check there is a warning in the log indicating Region A won't record + Mockito.verify(mockLog).debug( + "CICS resource disabling expectedly failed on " + + regionaApplid + ); + } + + @Test + void testPrepareEnvironmentsPortNotFound() throws SdvManagerException, IllegalArgumentException, + IllegalAccessException, NoSuchFieldException, SecurityException, InstantiationException, + InvocationTargetException, NoSuchMethodException, ZosBatchException, + TestBundleResourceException, IOException, DynamicStatusStoreException, + CredentialsException, CicstsManagerException, ClassNotFoundException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).createResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).installGroup(Mockito.any(), Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + Mockito.when( + ceda.resourceExists(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(true); + + // Mock SDVPort + sdvPort.when(() -> SdvPort.get(regionaTag)).thenReturn(null); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenReturn(true); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + regionaApplid + sdcLiveString, falseString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclCreateLogstreamPathString), Mockito.any())) + .thenReturn(createLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(16); // EXISTING RETURN CODE + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(createLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.prepareEnvironments(structureString); + }); + + Assertions.assertEquals( + "Could not find SDC port in CPS properties for CICS tag: " + + regionaTag, + exception.getMessage() + ); + + } + + @Test + void testPrepareEnvironmentsHttpResourcesDoNotAlreadyExist() + throws CicstsManagerException, CredentialsException, SdvManagerException, + DynamicStatusStoreException, TestBundleResourceException, IOException, + ZosBatchException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).createResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).installGroup(Mockito.any(), Mockito.any()); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + Mockito.when( + ceda.resourceExists(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(false); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.putSwap(managerPrefixString + runningManagersString + regionaApplid, + null, testRunName)).thenReturn(true); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + regionaApplid + sdcLiveString, falseString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclCreateLogstreamPathString), Mockito.any())) + .thenReturn(createLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(16); // EXISTING RETURN CODE + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(createLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + sdvHttpRecorder.prepareEnvironments(structureString); + + // Ensure that we call ceda & cemt was not used to disable resources + Mockito.verify(cemt, Mockito.times(0)).setResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(3)).createResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(2)).installGroup(Mockito.any(), Mockito.any()); + } + + @Test + void testCleanUpEnvironmentsAsLastManagerOnRegionWithSdcActivation() + throws CredentialsException, SdvManagerException, ClassNotFoundException, + NoSuchFieldException, SecurityException, IllegalArgumentException, + IllegalAccessException, InstantiationException, InvocationTargetException, + NoSuchMethodException, ResourceUnavailableException, DynamicStatusStoreException, + CicstsManagerException, TestBundleResourceException, IOException, ZosBatchException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + Mockito.when(mockCicsbRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsbRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrB = new RecordingRegion(regionbTerminal); + // Mock user 1 + ICredentialsUsernamePassword user3Creds = + new CredentialsUsernamePassword(null, user3String, passwordString); + ISdvUser user3 = new SdvUserImpl(creds3String, user3Creds, regionbTag, tellerRoleString); + rrB.addUserToRecord(user3); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + recordingRegions.put(mockCicsbRegion, rrB); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.get(managerPrefixString + runningManagersString + regionaApplid)) + .thenReturn(testRunName); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).delete(managerPrefixString + runningManagersString + regionaApplid); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).delete(managerPrefixString + regionaApplid + sdcLiveString); + + Mockito.when(dssService.get(managerPrefixString + runningManagersString + regionbApplid)) + .thenReturn(testRunName); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).delete(managerPrefixString + runningManagersString + regionbApplid); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).delete(managerPrefixString + regionbApplid + sdcLiveString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclDeleteLogstreamPathString), Mockito.any())) + .thenReturn(deleteLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(0); + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(deleteLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + Mockito.when(batchManager.getZosBatch(regionbImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionbTag)).thenReturn(true); + + // Make call to funtion under test + sdvHttpRecorder.cleanUpEnvironments(); + + // Ensure that we call ceda & cemt to delete resources + Mockito.verify(cemt, Mockito.times(4)).setResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(2)).deleteGroup(Mockito.any(), Mockito.any()); + } + + @Test + void testCleanUpEnvironmentsNotAsLastManagerOnRegionWithSdcActivation() + throws CredentialsException, SdvManagerException, ClassNotFoundException, + NoSuchFieldException, SecurityException, IllegalArgumentException, + IllegalAccessException, InstantiationException, InvocationTargetException, + NoSuchMethodException, ResourceUnavailableException, DynamicStatusStoreException, + CicstsManagerException, TestBundleResourceException, IOException, ZosBatchException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + Mockito.when(mockCicsbRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsbRegion.cemt()).thenReturn(cemt); + // Mock RegionA Terminal + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrB = new RecordingRegion(regionbTerminal); + // Mock user 1 + ICredentialsUsernamePassword user3Creds = + new CredentialsUsernamePassword(null, user3String, passwordString); + ISdvUser user3 = new SdvUserImpl(creds3String, user3Creds, regionbTag, tellerRoleString); + rrB.addUserToRecord(user3); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + recordingRegions.put(mockCicsbRegion, rrB); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.get(managerPrefixString + runningManagersString + regionaApplid)) + .thenReturn(testRunName + ",L564,L234"); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + runningManagersString + regionaApplid, + "L564,L234"); + + Mockito.when(dssService.get(managerPrefixString + runningManagersString + regionbApplid)) + .thenReturn(testRunName + ",L789,L101"); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).put(managerPrefixString + runningManagersString + regionbApplid, + "L789,L101"); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, null, null, null, dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionbTag)).thenReturn(true); + + // Make call to funtion under test + sdvHttpRecorder.cleanUpEnvironments(); + + // Ensure that we do not call ceda & cemt to delete resources + Mockito.verify(cemt, Mockito.times(0)).setResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(0)).deleteGroup(Mockito.any(), Mockito.any()); + } + + @Test + void testCleanUpEnvironmentsDssException() throws CredentialsException, SdvManagerException, + DynamicStatusStoreException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.get(managerPrefixString + runningManagersString + regionaApplid)) + .thenThrow(new DynamicStatusStoreException("Unable interact with DSS for SDV.")); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, null, null, null, dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.cleanUpEnvironments(); + }); + + Assertions.assertEquals("Unable interact with DSS for SDV.", exception.getMessage()); + } + + @Test + void testCleanUpEnvironmentsCedaDeleteGroupThrowsException() + throws CicstsManagerException, CredentialsException, SdvManagerException, + DynamicStatusStoreException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException, + TestBundleResourceException, IOException, ZosBatchException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doThrow(new CedaException("cannot delete group")).when(ceda) + .deleteGroup(Mockito.any(), Mockito.any()); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.get(managerPrefixString + runningManagersString + regionaApplid)) + .thenReturn(testRunName); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclDeleteLogstreamPathString), Mockito.any())) + .thenReturn(deleteLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(0); + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(deleteLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + Mockito.when(batchManager.getZosBatch(regionbImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + sdvHttpRecorder.cleanUpEnvironments(); + + Mockito.verify(cemt, Mockito.times(2)).setResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()); + + Mockito.verify(ceda, Mockito.times(1)).deleteGroup(Mockito.any(), Mockito.any()); + + // Check there is a warning in the log indicating Region A won't record + Mockito.verify(mockLog).error(Mockito.eq( + "Could not delete the SDVGRP on CICS Region " + + regionaApplid + ), Mockito.any()); + } + + @Test + void testCleanUpEnvironmentsDeleteSrrLogstreamJobError() + throws CicstsManagerException, CredentialsException, SdvManagerException, + DynamicStatusStoreException, TestBundleResourceException, IOException, + ZosBatchException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.get(managerPrefixString + runningManagersString + regionaApplid)) + .thenReturn(testRunName); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclDeleteLogstreamPathString), Mockito.any())) + .thenReturn(deleteLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(8); + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(deleteLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + Mockito.when(batchManager.getZosBatch(regionbImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.cleanUpEnvironments(); + }); + + Assertions.assertEquals( + "JCL to delete logstreams fail on CICS Region " + + regionaApplid + + ", check artifacts for more details.", + exception.getMessage() + ); + } + + @Test + void testCleanUpEnvironmentsArtifactManagerException() throws CicstsManagerException, + CredentialsException, SdvManagerException, DynamicStatusStoreException, + ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, TestBundleResourceException, IOException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cemt).setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.get(managerPrefixString + runningManagersString + regionaApplid)) + .thenReturn(testRunName); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclDeleteLogstreamPathString), Mockito.any())) + .thenThrow(new TestBundleResourceException("not found")); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, null, null, dssService, + null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.cleanUpEnvironments(); + }); + + Assertions.assertEquals( + "Unable to run JCL to delete logstreams for CICS Region " + + regionaApplid, + exception.getMessage() + ); + } + + @Test + void testCleanUpEnvironmentsCemtSetResourceException() + throws CicstsManagerException, CredentialsException, SdvManagerException, + DynamicStatusStoreException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, ClassNotFoundException, + TestBundleResourceException, IOException, ZosBatchException { + // Mock Cemt + ICemt cemt = Mockito.mock(ICemt.class); + Mockito.doThrow(new CemtException("couldn't set resource")).when(cemt) + .setResource(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + + // Mock Ceda + ICeda ceda = Mockito.mock(ICeda.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(ceda).deleteGroup(Mockito.any(), Mockito.any()); + + Mockito.when(mockCicsaRegion.ceda()).thenReturn(ceda); + Mockito.when(mockCicsaRegion.cemt()).thenReturn(cemt); + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(testRunName); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.get(managerPrefixString + runningManagersString + regionaApplid)) + .thenReturn(testRunName); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString( + Mockito.eq(jclDeleteLogstreamPathString), Mockito.any())) + .thenReturn(deleteLogstreamJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJob.waitForJob()).thenReturn(0); + IZosBatch zosBatch = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatch.submitJob(deleteLogstreamJcl, null)).thenReturn(zosJob); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatch); + Mockito.when(batchManager.getZosBatch(regionbImage)).thenReturn(zosBatch); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(framework, recordingRegions, artifactManager, batchManager, null, + dssService, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionaTag)).thenReturn(true); + sdvSdcActivation.when(() -> SdvSdcActivation.get(regionbTag)).thenReturn(true); + + // Make call to funtion under test + sdvHttpRecorder.cleanUpEnvironments(); + + // Ensure that we call ceda & cemt to create resources + Mockito.verify(ceda, Mockito.times(1)).deleteGroup(Mockito.any(), Mockito.any()); + Mockito.verify(cemt, Mockito.times(2)).setResource(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()); + + // Check there is a warning in the log indicating Region A won't record + Mockito.verify(mockLog, Mockito.times(1)) + .error("Could not create URIMAP on CICS Region " + regionaApplid); + Mockito.verify(mockLog, Mockito.times(1)) + .error("Could not create TCPIPSERVICE on CICS Region " + regionaApplid); + } + + @SuppressWarnings(uncheckedString) + @Test + void testStartRecordingNoExistingSdcForMultipleRegionsAndUsers() + throws SdvManagerException, CicstsManagerException, CredentialsException, + ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, URISyntaxException, HttpClientException { + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock RegionB Terminal + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionB + RecordingRegion rrB = new RecordingRegion(regionbTerminal); + // Mock user 3 + ICredentialsUsernamePassword user3Creds = + new CredentialsUsernamePassword(null, user3String, passwordString); + ISdvUser user3 = new SdvUserImpl(creds3String, user3Creds, regionbTag, tellerRoleString); + rrB.addUserToRecord(user3); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + recordingRegions.put(mockCicsbRegion, rrB); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse1.getStatusCode()).thenReturn(404); + Mockito.when(httpClient1.getJson(sdcUrl)).thenReturn(mockGetResponse1); + // Mock POST JSON return from SDC - to start recording + HttpClientResponse mockPostResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockPostResponse1.getStatusCode()).thenReturn(201); + JsonObject postResponseContent1 = new JsonObject(); + postResponseContent1.addProperty(srrIdString, srrId1); + Mockito.when(mockPostResponse1.getContent()).thenReturn(postResponseContent1); + JsonObject postBody = new JsonObject(); + Mockito.when(httpClient1.postJson(sdcUrl, postBody)).thenReturn(mockPostResponse1); + + // Mock HTTP Client - 2nd time + IHttpClient httpClient2 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient2) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient2).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse2 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse2.getStatusCode()).thenReturn(404); + Mockito.when(httpClient2.getJson(sdcUrl)).thenReturn(mockGetResponse2); + // Mock POST JSON return from SDC - to start recording + HttpClientResponse mockPostResponse2 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockPostResponse2.getStatusCode()).thenReturn(201); + JsonObject postResponseContent2 = new JsonObject(); + postResponseContent2.addProperty(srrIdString, srrId2); + Mockito.when(mockPostResponse2.getContent()).thenReturn(postResponseContent2); + Mockito.when(httpClient2.postJson(sdcUrl, postBody)).thenReturn(mockPostResponse2); + + // Mock HTTP Client - 3rd time + IHttpClient httpClient3 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient3) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient3).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse3 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse3.getStatusCode()).thenReturn(404); + Mockito.when(httpClient3.getJson(sdcUrl)).thenReturn(mockGetResponse3); + // Mock POST JSON return from SDC - to start recording + HttpClientResponse mockPostResponse3 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockPostResponse3.getStatusCode()).thenReturn(201); + JsonObject postResponseContent3 = new JsonObject(); + postResponseContent3.addProperty(srrIdString, srrId3); + Mockito.when(mockPostResponse3.getContent()).thenReturn(postResponseContent3); + Mockito.when(httpClient3.postJson(sdcUrl, postBody)).thenReturn(mockPostResponse3); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1, httpClient2, httpClient3); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + sdvHttpRecorder.startRecording(); + + // Assert HTTP endpoints called + Mockito.verify(httpClient1, Mockito.times(1)).getJson(Mockito.any()); + Mockito.verify(httpClient1, Mockito.times(1)).postJson(Mockito.any(), Mockito.any()); + Mockito.verify(httpClient2, Mockito.times(1)).getJson(Mockito.any()); + Mockito.verify(httpClient2, Mockito.times(1)).postJson(Mockito.any(), Mockito.any()); + Mockito.verify(httpClient3, Mockito.times(1)).getJson(Mockito.any()); + Mockito.verify(httpClient3, Mockito.times(1)).postJson(Mockito.any(), Mockito.any()); + + // Assert that all users are set to recording with SRR IDs + List expectedSrrIdsList = new ArrayList<>(); + expectedSrrIdsList.add(srrId1); + expectedSrrIdsList.add(srrId2); + expectedSrrIdsList.add(srrId3); + + Assertions.assertEquals(true, user1.isRecording()); + Assertions.assertTrue(expectedSrrIdsList.contains(user1.getSrrId())); + Assertions.assertEquals(true, user1.isRecording()); + expectedSrrIdsList.remove(user1.getSrrId()); + + Assertions.assertEquals(true, user2.isRecording()); + Assertions.assertTrue(expectedSrrIdsList.contains(user2.getSrrId())); + Assertions.assertEquals(true, user2.isRecording()); + expectedSrrIdsList.remove(user2.getSrrId()); + + Assertions.assertEquals(true, user3.isRecording()); + Assertions.assertTrue(expectedSrrIdsList.contains(user3.getSrrId())); + Assertions.assertEquals(true, user3.isRecording()); + expectedSrrIdsList.remove(user3.getSrrId()); + } + + @SuppressWarnings(uncheckedString) + @Test + void testStartRecordingExistingSdcForMultipleRegionsAndUsers() + throws CicstsManagerException, CredentialsException, SdvManagerException, + URISyntaxException, HttpClientException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + rrA.addUserToRecord(user2); + + // Mock RegionB Terminal + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionB + RecordingRegion rrB = new RecordingRegion(regionbTerminal); + // Mock user 3 + ICredentialsUsernamePassword user3Creds = + new CredentialsUsernamePassword(null, user3String, passwordString); + ISdvUser user3 = new SdvUserImpl(creds3String, user3Creds, regionbTag, tellerRoleString); + rrB.addUserToRecord(user3); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + recordingRegions.put(mockCicsbRegion, rrB); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse1.getStatusCode()).thenReturn(200); + Mockito.when(httpClient1.getJson(sdcUrl)).thenReturn(mockGetResponse1); + // Mock DELETE JSON return from SDC - to stop existing SDC + HttpClientResponse mockDeleteResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockDeleteResponse1.getStatusCode()).thenReturn(200); + JsonObject deleteBody = new JsonObject(); + deleteBody.addProperty(submitString, false); + Mockito.when(httpClient1.deleteJson(sdcUrl, deleteBody)).thenReturn(mockDeleteResponse1); + // Mock POST JSON return from SDC - to start recording + HttpClientResponse mockPostResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockPostResponse1.getStatusCode()).thenReturn(201); + JsonObject postResponseContent1 = new JsonObject(); + postResponseContent1.addProperty(srrIdString, srrId1); + Mockito.when(mockPostResponse1.getContent()).thenReturn(postResponseContent1); + JsonObject postBody = new JsonObject(); + Mockito.when(httpClient1.postJson(sdcUrl, postBody)).thenReturn(mockPostResponse1); + + // Mock HTTP Client - 2nd time + IHttpClient httpClient2 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient2) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient2).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse2 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse2.getStatusCode()).thenReturn(200); + Mockito.when(httpClient2.getJson(sdcUrl)).thenReturn(mockGetResponse2); + // Mock DELETE JSON return from SDC - to stop existing SDC + HttpClientResponse mockDeleteResponse2 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockDeleteResponse2.getStatusCode()).thenReturn(200); + Mockito.when(httpClient2.deleteJson(sdcUrl, deleteBody)).thenReturn(mockDeleteResponse2); + // Mock POST JSON return from SDC - to start recording + HttpClientResponse mockPostResponse2 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockPostResponse2.getStatusCode()).thenReturn(201); + JsonObject postResponseContent2 = new JsonObject(); + postResponseContent2.addProperty(srrIdString, srrId2); + Mockito.when(mockPostResponse2.getContent()).thenReturn(postResponseContent2); + Mockito.when(httpClient2.postJson(sdcUrl, postBody)).thenReturn(mockPostResponse2); + + // Mock HTTP Client - 3rd time + IHttpClient httpClient3 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient3) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient3).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse3 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse3.getStatusCode()).thenReturn(200); + Mockito.when(httpClient3.getJson(sdcUrl)).thenReturn(mockGetResponse3); + // Mock DELETE JSON return from SDC - to stop existing SDC + HttpClientResponse mockDeleteResponse3 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockDeleteResponse3.getStatusCode()).thenReturn(200); + Mockito.when(httpClient3.deleteJson(sdcUrl, deleteBody)).thenReturn(mockDeleteResponse3); + // Mock POST JSON return from SDC - to start recording + HttpClientResponse mockPostResponse3 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockPostResponse3.getStatusCode()).thenReturn(201); + JsonObject postResponseContent3 = new JsonObject(); + postResponseContent3.addProperty(srrIdString, srrId3); + Mockito.when(mockPostResponse3.getContent()).thenReturn(postResponseContent3); + Mockito.when(httpClient3.postJson(sdcUrl, postBody)).thenReturn(mockPostResponse3); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1, httpClient2, httpClient3); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + sdvHttpRecorder.startRecording(); + + // Assert HTTP endpoints called + Mockito.verify(httpClient1, Mockito.times(1)).getJson(Mockito.any()); + Mockito.verify(httpClient1, Mockito.times(1)).deleteJson(Mockito.any(), Mockito.any()); + Mockito.verify(httpClient1, Mockito.times(1)).postJson(Mockito.any(), Mockito.any()); + Mockito.verify(httpClient2, Mockito.times(1)).getJson(Mockito.any()); + Mockito.verify(httpClient2, Mockito.times(1)).deleteJson(Mockito.any(), Mockito.any()); + Mockito.verify(httpClient2, Mockito.times(1)).postJson(Mockito.any(), Mockito.any()); + Mockito.verify(httpClient3, Mockito.times(1)).getJson(Mockito.any()); + Mockito.verify(httpClient3, Mockito.times(1)).deleteJson(Mockito.any(), Mockito.any()); + Mockito.verify(httpClient3, Mockito.times(1)).postJson(Mockito.any(), Mockito.any()); + + // Assert that all users are set to recording with SRR IDs + List expectedSrrIdsList = new ArrayList<>(); + expectedSrrIdsList.add(srrId1); + expectedSrrIdsList.add(srrId2); + expectedSrrIdsList.add(srrId3); + + Assertions.assertEquals(true, user1.isRecording()); + Assertions.assertTrue(expectedSrrIdsList.contains(user1.getSrrId())); + Assertions.assertEquals(true, user1.isRecording()); + expectedSrrIdsList.remove(user1.getSrrId()); + + Assertions.assertEquals(true, user2.isRecording()); + Assertions.assertTrue(expectedSrrIdsList.contains(user2.getSrrId())); + Assertions.assertEquals(true, user2.isRecording()); + expectedSrrIdsList.remove(user2.getSrrId()); + + Assertions.assertEquals(true, user3.isRecording()); + Assertions.assertTrue(expectedSrrIdsList.contains(user3.getSrrId())); + Assertions.assertEquals(true, user3.isRecording()); + expectedSrrIdsList.remove(user3.getSrrId()); + + } + + @SuppressWarnings(uncheckedString) + @Test + void testStartRecordingHttpGetSdcServerError() throws CredentialsException, SdvManagerException, + URISyntaxException, HttpClientException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException, CicstsManagerException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse1.getStatusCode()).thenReturn(500); + Mockito.when(mockGetResponse1.getStatusMessage()).thenReturn(errorMessageString); + JsonObject getResponseContent1 = new JsonObject(); + getResponseContent1.addProperty(srrIdString, nullString); + getResponseContent1.addProperty(messagePropString, serverErrorMessage); + Mockito.when(mockGetResponse1.getContent()).thenReturn(getResponseContent1); + Mockito.when(httpClient1.getJson(sdcUrl)).thenReturn(mockGetResponse1); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.startRecording(); + }); + + Assertions.assertEquals(user1UnableToStartErrorString, exception.getMessage()); + Assertions.assertEquals( + "Error whilst obtaining current SDC status for user 'user1', " + + "on CICS Region APPL1. Status code: 500" + + errorOutputBadStuffString + errorOutputPayloadStrng, + exception.getCause().getMessage() + ); + } + + @Test + void testStartRecordingGetHttpClientException() + throws CicstsManagerException, CredentialsException, SdvManagerException, + URISyntaxException, HttpClientException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + Mockito.when(httpClient1.getJson(sdcUrl)) + .thenThrow(new HttpClientException("Could not get response from SDC")); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.startRecording(); + }); + + Assertions.assertEquals(user1UnableToStartErrorString, exception.getMessage()); + Assertions.assertEquals( + "Could not check status SDC recording status for user '" + + user1String + + onCicsRegionMsg + + regionaApplid + + ". Is SDC activated?", + exception.getCause().getMessage() + ); + } + + @SuppressWarnings(uncheckedString) + @Test + void testStartRecordingHttpDeleteSdcServerError() + throws CicstsManagerException, CredentialsException, SdvManagerException, + URISyntaxException, HttpClientException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, ClassNotFoundException, NoSuchFieldException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse1.getStatusCode()).thenReturn(200); + Mockito.when(httpClient1.getJson(sdcUrl)).thenReturn(mockGetResponse1); + // Mock DELETE JSON return from SDC - to stop existing SDC + HttpClientResponse mockDeleteResponse1 = Mockito.mock(HttpClientResponse.class); + JsonObject deleteResponseContent1 = new JsonObject(); + deleteResponseContent1.addProperty(srrIdString, nullString); + deleteResponseContent1.addProperty(messagePropString, serverErrorMessage); + Mockito.when(mockDeleteResponse1.getStatusCode()).thenReturn(500); + Mockito.when(mockDeleteResponse1.getStatusMessage()).thenReturn(errorMessageString); + Mockito.when(mockDeleteResponse1.getContent()).thenReturn(deleteResponseContent1); + JsonObject deleteBody = new JsonObject(); + deleteBody.addProperty(submitString, false); + Mockito.when(httpClient1.deleteJson(sdcUrl, deleteBody)).thenReturn(mockDeleteResponse1); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.startRecording(); + }); + + Assertions.assertEquals(user1UnableToStartErrorString, exception.getMessage()); + Assertions.assertEquals( + "Could not stop SDC recording for user '" + + user1String + + onCicsRegionMsg + + regionaApplid + + ". Status code: 500" + + errorOutputBadStuffString + + errorOutputPayloadStrng, + exception.getCause().getMessage() + ); + } + + @SuppressWarnings(uncheckedString) + @Test + void testStartRecordingDeleteHttpClientException() + throws HttpClientException, CicstsManagerException, CredentialsException, + SdvManagerException, URISyntaxException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse1.getStatusCode()).thenReturn(200); + Mockito.when(httpClient1.getJson(sdcUrl)).thenReturn(mockGetResponse1); + // Mock DELETE JSON return from SDC - to stop existing SDC + JsonObject deleteBody = new JsonObject(); + deleteBody.addProperty(submitString, false); + Mockito.when(httpClient1.deleteJson(sdcUrl, deleteBody)) + .thenThrow(new HttpClientException("No response")); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.startRecording(); + }); + + Assertions.assertEquals(user1UnableToStartErrorString, exception.getMessage()); + Assertions.assertEquals( + "Could not stop existing SDC recording for user '" + + user1String + + onCicsRegionMsg + + regionaApplid + + ".", + exception.getCause().getMessage() + ); + } + + @SuppressWarnings(uncheckedString) + @Test + void testStartRecordingHttpPostSdcServerError() + throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, + SecurityException, InstantiationException, InvocationTargetException, + NoSuchMethodException, HttpClientException, URISyntaxException, ClassNotFoundException, + SdvManagerException, CredentialsException, CicstsManagerException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse1.getStatusCode()).thenReturn(404); + Mockito.when(httpClient1.getJson(sdcUrl)).thenReturn(mockGetResponse1); + // Mock POST return from SDC + HttpClientResponse mockPostResponse1 = Mockito.mock(HttpClientResponse.class); + JsonObject postResponseContent1 = new JsonObject(); + postResponseContent1.addProperty(srrIdString, nullString); + postResponseContent1.addProperty(messagePropString, serverErrorMessage); + Mockito.when(mockPostResponse1.getStatusCode()).thenReturn(500); + Mockito.when(mockPostResponse1.getStatusMessage()).thenReturn(errorMessageString); + Mockito.when(mockPostResponse1.getContent()).thenReturn(postResponseContent1); + JsonObject postBody = new JsonObject(); + Mockito.when(httpClient1.postJson(sdcUrl, postBody)).thenReturn(mockPostResponse1); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.startRecording(); + }); + + Assertions.assertEquals(user1UnableToStartErrorString, exception.getMessage()); + Assertions.assertEquals( + "Could not start SDC recording for user '" + + user1String + + onCicsRegionMsg + + regionaApplid + + ". Status code: 500" + + errorOutputBadStuffString + + errorOutputPayloadStrng, + exception.getCause().getMessage() + ); + } + + @SuppressWarnings(uncheckedString) + @Test + void testStartRecordingPostHttpClientException() + throws CicstsManagerException, CredentialsException, SdvManagerException, + URISyntaxException, HttpClientException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse1.getStatusCode()).thenReturn(404); + Mockito.when(httpClient1.getJson(sdcUrl)).thenReturn(mockGetResponse1); + // Mock POST return from SDC + JsonObject postBody = new JsonObject(); + Mockito.when(httpClient1.postJson(sdcUrl, postBody)) + .thenThrow(new HttpClientException("no response")); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.startRecording(); + }); + + Assertions.assertEquals(user1UnableToStartErrorString, exception.getMessage()); + Assertions.assertEquals( + "Could not start SDC recording for user '" + + user1String + + onCicsRegionMsg + + regionaApplid, + exception.getCause().getMessage() + ); + } + + @SuppressWarnings(uncheckedString) + @Test + void testStartRecordingNoSrrIdInResponse() + throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, + SecurityException, InstantiationException, InvocationTargetException, + NoSuchMethodException, ClassNotFoundException, HttpClientException, + CicstsManagerException, CredentialsException, SdvManagerException, URISyntaxException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock GET JSON return from SDC - to find current status + HttpClientResponse mockGetResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockGetResponse1.getStatusCode()).thenReturn(404); + Mockito.when(httpClient1.getJson(sdcUrl)).thenReturn(mockGetResponse1); + // Mock POST return from SDC + HttpClientResponse mockPostResponse1 = Mockito.mock(HttpClientResponse.class); + JsonObject postResponseContent1 = new JsonObject(); + postResponseContent1.addProperty(srrIdString, ""); + postResponseContent1.addProperty(messagePropString, "edge case"); + Mockito.when(mockPostResponse1.getStatusCode()).thenReturn(201); + Mockito.when(mockPostResponse1.getStatusMessage()).thenReturn(errorMessageString); + Mockito.when(mockPostResponse1.getContent()).thenReturn(postResponseContent1); + JsonObject postBody = new JsonObject(); + Mockito.when(httpClient1.postJson(sdcUrl, postBody)).thenReturn(mockPostResponse1); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.startRecording(); + }); + + Assertions.assertEquals(user1UnableToStartErrorString, exception.getMessage()); + Assertions.assertEquals( + "SDC recording did not return an SRR ID for user '" + + user1String + + onCicsRegionMsg + + regionaApplid, + exception.getCause().getMessage() + ); + } + + @Test + void testStartRecordingBadUri() throws IllegalArgumentException, IllegalAccessException, + NoSuchFieldException, SecurityException, InstantiationException, + InvocationTargetException, NoSuchMethodException, ClassNotFoundException, + SdvManagerException, CredentialsException, CicstsManagerException { + // Mock SDVPort + sdvPort.when(() -> SdvPort.get(regionaTag)).thenReturn("////gfg\\"); + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setURI(Mockito.any()); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.startRecording(); + }); + + Assertions.assertEquals(user1UnableToStartErrorString, exception.getMessage()); + Assertions.assertEquals( + "Badly formed URI for SDC service for CICS Region " + + regionaApplid, + exception.getCause().getMessage() + ); + } + + @SuppressWarnings(uncheckedString) + @Test + void testEndRecordingForMultipleRegionsAndUsers() + throws SdvManagerException, CicstsManagerException, CredentialsException, + ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, URISyntaxException, HttpClientException { + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + user1.setSrrId(srrId1); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + user2.setSrrId(srrId2); + rrA.addUserToRecord(user2); + + // Mock RegionB Terminal + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionB + RecordingRegion rrB = new RecordingRegion(regionbTerminal); + // Mock user 3 + ICredentialsUsernamePassword user3Creds = + new CredentialsUsernamePassword(null, user3String, passwordString); + ISdvUser user3 = new SdvUserImpl(creds3String, user3Creds, regionbTag, tellerRoleString); + user3.setSrrId(srrId3); + rrB.addUserToRecord(user3); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + recordingRegions.put(mockCicsbRegion, rrB); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock DELETE JSON return from SDC + HttpClientResponse mockDeleteResponse1 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockDeleteResponse1.getStatusCode()).thenReturn(200); + JsonObject deleteBody = new JsonObject(); + deleteBody.addProperty(submitString, false); + Mockito.when(httpClient1.deleteJson(sdcUrl, deleteBody)).thenReturn(mockDeleteResponse1); + + // Mock HTTP Client - 2nd time + IHttpClient httpClient2 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient2) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient2).setAuthorisation(user1String, passwordString); + // Mock DELETE JSON return from SDC + HttpClientResponse mockDeleteResponse2 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockDeleteResponse2.getStatusCode()).thenReturn(200); + Mockito.when(httpClient2.deleteJson(sdcUrl, deleteBody)).thenReturn(mockDeleteResponse2); + + // Mock HTTP Client - 3rd time + IHttpClient httpClient3 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient3) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient3).setAuthorisation(user1String, passwordString); + // Mock DELETE JSON return from SDC + HttpClientResponse mockDeleteResponse3 = Mockito.mock(HttpClientResponse.class); + Mockito.when(mockDeleteResponse3.getStatusCode()).thenReturn(200); + Mockito.when(httpClient3.deleteJson(sdcUrl, deleteBody)).thenReturn(mockDeleteResponse3); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1, httpClient2, httpClient3); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + sdvHttpRecorder.endRecording(); + + // Assert HTTP endpoints called + Mockito.verify(httpClient1, Mockito.times(1)).deleteJson(Mockito.any(), Mockito.any()); + Mockito.verify(httpClient2, Mockito.times(1)).deleteJson(Mockito.any(), Mockito.any()); + Mockito.verify(httpClient3, Mockito.times(1)).deleteJson(Mockito.any(), Mockito.any()); + + // Assert that all users are no longer recording + Assertions.assertEquals(false, user1.isRecording()); + Assertions.assertEquals(false, user2.isRecording()); + Assertions.assertEquals(false, user3.isRecording()); + + } + + @SuppressWarnings(uncheckedString) + @Test + void testEndRecordingDeleteServerError() + throws SdvManagerException, CicstsManagerException, CredentialsException, + ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, URISyntaxException, HttpClientException { + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + user1.setSrrId(srrId1); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock DELETE JSON return from SDC + HttpClientResponse mockDeleteResponse1 = Mockito.mock(HttpClientResponse.class); + JsonObject deleteResponseContent1 = new JsonObject(); + deleteResponseContent1.addProperty(srrIdString, nullString); + deleteResponseContent1.addProperty(messagePropString, serverErrorMessage); + Mockito.when(mockDeleteResponse1.getStatusCode()).thenReturn(500); + Mockito.when(mockDeleteResponse1.getStatusMessage()).thenReturn(errorMessageString); + Mockito.when(mockDeleteResponse1.getContent()).thenReturn(deleteResponseContent1); + JsonObject deleteBody = new JsonObject(); + deleteBody.addProperty(submitString, false); + Mockito.when(httpClient1.deleteJson(sdcUrl, deleteBody)).thenReturn(mockDeleteResponse1); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.endRecording(); + }); + + Assertions.assertEquals( + "Unable to stop SRR recording " + + srrId1 + + ", for user '" + + user1String + + onCicsRegionMsg + + regionaApplid, + exception.getMessage() + ); + Assertions.assertEquals( + "Could not stop SDC recording for user '" + + user1String + + onCicsRegionMsg + + regionaApplid + + ". Status code: 500" + + errorOutputBadStuffString + + errorOutputPayloadStrng, + exception.getCause().getMessage() + ); + } + + @SuppressWarnings(uncheckedString) + @Test + void testEndRecordingDeleteHttpClientException() + throws SdvManagerException, CicstsManagerException, CredentialsException, + ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, URISyntaxException, HttpClientException { + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + user1.setSrrId(srrId1); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1) + .setURI(new URI(httpString + cicsServerStringA + ":" + regionAportString)); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setAuthorisation(user1String, passwordString); + // Mock DELETE JSON return from SDC + JsonObject deleteBody = new JsonObject(); + deleteBody.addProperty(submitString, false); + Mockito.when(httpClient1.deleteJson(sdcUrl, deleteBody)) + .thenThrow(new HttpClientException("Nothing back")); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.endRecording(); + }); + + Assertions.assertEquals( + "Unable to stop SRR recording " + + srrId1 + + ", for user '" + + user1String + + onCicsRegionMsg + + regionaApplid, + exception.getMessage() + ); + Assertions.assertEquals( + "Could not stop existing SDC recording for user '" + + user1String + + onCicsRegionMsg + + regionaApplid, + exception.getCause().getMessage() + ); + } + + @Test + void testEndRecordingBadUri() throws CredentialsException, SdvManagerException, + ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException { + // Mock SDVPort + sdvPort.when(() -> SdvPort.get(regionaTag)).thenReturn("////gfg\\"); + + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + user1.setSrrId(srrId1); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock HTTP Client - 1st time + IHttpClient httpClient1 = Mockito.mock(IHttpClient.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(httpClient1).setURI(Mockito.any()); + + // Mock HTTP Manager + IHttpManagerSpi httpManager = Mockito.mock(IHttpManagerSpi.class); + Mockito.when(httpManager.newHttpClient()).thenReturn(httpClient1); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, null, null, null, null, httpManager); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.endRecording(); + }); + + Assertions.assertEquals( + "Unable to stop SRR recording " + + srrId1 + + ", for user '" + + user1String + + onCicsRegionMsg + + regionaApplid, + exception.getMessage() + ); + Assertions.assertEquals( + "Badly formed URI for SDC service for CICS Region " + + regionaApplid, + exception.getCause().getMessage() + ); + } + + @Test + void testExportRecordingsForMulitpleRegions() + throws CredentialsException, SdvManagerException, ClassNotFoundException, + InstantiationException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException, NoSuchMethodException, SecurityException, + NoSuchFieldException, TestBundleResourceException, IOException, ZosBatchException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + user1.setSrrId(srrId1); + user1.setNotRecording(); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + user2.setSrrId(srrId2); + user2.setNotRecording(); + rrA.addUserToRecord(user2); + + // Mock RegionA Terminal + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrB = new RecordingRegion(regionbTerminal); + // Mock user 1 + ICredentialsUsernamePassword user3Creds = + new CredentialsUsernamePassword(null, user3String, passwordString); + ISdvUser user3 = new SdvUserImpl(creds3String, user3Creds, regionbTag, tellerRoleString); + user3.setSrrId(srrId3); + user3.setNotRecording(); + rrB.addUserToRecord(user3); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + recordingRegions.put(mockCicsbRegion, rrB); + + String getYamlJcl = + IOUtils.toString(this.getClass().getResourceAsStream(getYamlString), utfString); + + String getYamlAppendedRegionaJcl = IOUtils + .toString(this.getClass().getResourceAsStream("/getYamlRegionA.jcl"), utfString); + + String getYamlAppendedRegionbJcl = IOUtils + .toString(this.getClass().getResourceAsStream("/getYamlRegionB.jcl"), utfString); + + String regionAyaml = IOUtils + .toString(this.getClass().getResourceAsStream("/yamlRegionA.yaml"), utfString); + + String regionByaml = IOUtils + .toString(this.getClass().getResourceAsStream("/yamlRegionB.yaml"), utfString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString(Mockito.eq(jclGetYamlPathString), + Mockito.any())).thenReturn(getYamlJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJobA = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJobA.waitForJob()).thenReturn(0); + IZosBatchJob zosJobB = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJobB.waitForJob()).thenReturn(0); + IZosBatchJobOutput batchJobOutputRegionA = Mockito.mock(IZosBatchJobOutput.class); + IZosBatchJobOutput batchJobOutputRegionB = Mockito.mock(IZosBatchJobOutput.class); + List spoolFilesRegionA = new ArrayList<>(); + IZosBatchJobOutputSpoolFile spoolYamlFileRegionA = new ZosBatchJobOutputSpoolFileImpl( + zosJobA, "JobA", "ID123", "STEPA", "PROCA", "YAML", "SECA", regionAyaml); + spoolFilesRegionA.add(spoolYamlFileRegionA); + List spoolFilesRegionB = new ArrayList<>(); + IZosBatchJobOutputSpoolFile spoolYamlFileRegionB = new ZosBatchJobOutputSpoolFileImpl( + zosJobB, "JobB", "ID234", "STEPB", "PROCB", "YAML", "SECB", regionByaml); + spoolFilesRegionB.add(spoolYamlFileRegionB); + Mockito.when(batchJobOutputRegionA.getSpoolFiles()).thenReturn(spoolFilesRegionA); + Mockito.when(batchJobOutputRegionB.getSpoolFiles()).thenReturn(spoolFilesRegionB); + Mockito.when(zosJobA.retrieveOutput()).thenReturn(batchJobOutputRegionA); + Mockito.when(zosJobB.retrieveOutput()).thenReturn(batchJobOutputRegionB); + IZosBatch zosBatchRegionA = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatchRegionA.submitJob(getYamlAppendedRegionaJcl, null)) + .thenReturn(zosJobA); + IZosBatch zosBatchRegionB = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatchRegionB.submitJob(getYamlAppendedRegionbJcl, null)) + .thenReturn(zosJobB); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatchRegionA); + Mockito.when(batchManager.getZosBatch(regionbImage)).thenReturn(zosBatchRegionB); + + Path storedArtifactRoot = Mockito.mock(Path.class); + Path finalYamlPath = Mockito.mock(Path.class); + Mockito.when(storedArtifactRoot.resolve("bundleB/TestClassB.CICSA.cics-security.yaml")) + .thenReturn(finalYamlPath); + Mockito.when(storedArtifactRoot.resolve("bundleB/TestClassB.CICSB.cics-security.yaml")) + .thenReturn(finalYamlPath); + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, artifactManager, batchManager, + storedArtifactRoot, null, null); + + files.when(() -> Files.write(Mockito.eq(finalYamlPath), + Mockito.eq(regionAyaml.getBytes(utfString)), Mockito.any())).thenReturn(null); + + files.when(() -> Files.write(Mockito.eq(finalYamlPath), + Mockito.eq(regionByaml.getBytes(utfString)), Mockito.any())).thenReturn(null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + sdvHttpRecorder.exportRecordings("bundleB", "TestClassB"); + + // If these write calls are made, we can say all mocks were used with + // their expected attributes and all works + files.verify(() -> Files.write(finalYamlPath, regionAyaml.getBytes(utfString), + StandardOpenOption.CREATE), Mockito.times(1)); + + files.verify(() -> Files.write(finalYamlPath, regionByaml.getBytes(utfString), + StandardOpenOption.CREATE), Mockito.times(1)); + + Mockito.verify(mockLog, Mockito.times(1)) + .info("Storing YAML as test artifact for " + regionaApplid); + + Mockito.verify(mockLog, Mockito.times(1)) + .info("Storing YAML as test artifact for " + regionbApplid); + } + + @Test + void testExportRecordingsWithBadSrrIdForRecording() + throws CredentialsException, SdvManagerException, IOException, + TestBundleResourceException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + user1.setSrrId(null); + user1.setNotRecording(); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + String getYamlJcl = + IOUtils.toString(this.getClass().getResourceAsStream(getYamlString), utfString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString(Mockito.eq(jclGetYamlPathString), + Mockito.any())).thenReturn(getYamlJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, artifactManager, null, null, null, null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + files.when(() -> Files.write(Mockito.any(Path.class), Mockito.any(byte[].class), + Mockito.any(OpenOption.class))).thenReturn(null); + + sdvHttpRecorder.exportRecordings("bundleC", "TestClassC"); + + files.verify(() -> Files.write(Mockito.any(Path.class), Mockito.any(byte[].class), + Mockito.any(OpenOption.class)), Mockito.times(0)); + + // Check there is a warning in the log indicating Region A won't record + Mockito.verify(mockLog).warn("No SDC registered for user " + user1String + " on region " + + regionaApplid + ", skipping YAML generation."); + + } + + @Test + void testExportRecordingsYamlJobErrorCode() + throws CredentialsException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException, SdvManagerException, + ZosBatchException, IOException, TestBundleResourceException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + user1.setSrrId(srrId1); + user1.setNotRecording(); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + String getYamlJcl = + IOUtils.toString(this.getClass().getResourceAsStream(getYamlString), utfString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString(Mockito.eq(jclGetYamlPathString), + Mockito.any())).thenReturn(getYamlJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJobA = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJobA.waitForJob()).thenReturn(12); + IZosBatchJobOutput batchJobOutputRegionA = Mockito.mock(IZosBatchJobOutput.class); + List spoolFilesRegionA = new ArrayList<>(); + Mockito.when(batchJobOutputRegionA.getSpoolFiles()).thenReturn(spoolFilesRegionA); + Mockito.when(zosJobA.retrieveOutput()).thenReturn(batchJobOutputRegionA); + IZosBatch zosBatchRegionA = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatchRegionA.submitJob(Mockito.any(), Mockito.eq(null))) + .thenReturn(zosJobA); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatchRegionA); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, artifactManager, batchManager, null, null, + null); + + files.when(() -> Files.write(Mockito.any(Path.class), Mockito.any(byte[].class), + Mockito.any(OpenOption.class))).thenReturn(null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.exportRecordings("bundleD", "TestClassD"); + }); + + Assertions.assertEquals( + "Security metadata job did not return any YAML for CICS Region " + + regionaApplid + + ", containing SRR IDs: " + + srrId1, + exception.getMessage() + ); + + files.verify(() -> Files.write(Mockito.any(Path.class), Mockito.any(byte[].class), + Mockito.any(OpenOption.class)), Mockito.times(0)); + + Mockito.verify(mockLog, Mockito.times(1)).error( + "JCL to get Security metadata fail on CICS Region " + + regionaApplid + + ", check artifacts for more details" + ); + } + + @Test + void testExportRecordingsArtifactFindException() throws CredentialsException, + SdvManagerException, IOException, TestBundleResourceException, ZosBatchException, + ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + user1.setSrrId(srrId1); + user1.setNotRecording(); + rrA.addUserToRecord(user1); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString(Mockito.eq(jclGetYamlPathString), + Mockito.any())).thenThrow(new TestBundleResourceException("cant find files")); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, artifactManager, null, null, null, null); + + files.when(() -> Files.write(Mockito.any(Path.class), Mockito.any(byte[].class), + Mockito.any(OpenOption.class))).thenReturn(null); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.exportRecordings("bundleE", "TestClassE"); + }); + + Assertions.assertEquals( + "Unable to run JCL to get Security metadata on CICS Region " + + regionaApplid, + exception.getMessage() + ); + + files.verify(() -> Files.write(Mockito.any(Path.class), Mockito.any(byte[].class), + Mockito.any(OpenOption.class)), Mockito.times(0)); + } + + @Test + void testExportRecordingsUnableToSaveYamlFile() throws CredentialsException, + SdvManagerException, IOException, TestBundleResourceException, ZosBatchException, + ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException { + // Mock RegionA Terminal + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + // Mock RecordingRegionA + RecordingRegion rrA = new RecordingRegion(regionaTerminal); + // Mock user 1 + ICredentialsUsernamePassword user1Creds = + new CredentialsUsernamePassword(null, user1String, passwordString); + ISdvUser user1 = new SdvUserImpl(creds1String, user1Creds, regionaTag, tellerRoleString); + user1.setSrrId(srrId1); + user1.setNotRecording(); + rrA.addUserToRecord(user1); + // Mock user 2 + ICredentialsUsernamePassword user2Creds = + new CredentialsUsernamePassword(null, user2String, passwordString); + ISdvUser user2 = new SdvUserImpl(creds2String, user2Creds, regionaTag, adminRoleString); + user2.setSrrId(srrId2); + user2.setNotRecording(); + rrA.addUserToRecord(user2); + + // Mock recordingRegions + Map recordingRegions = new HashMap<>(); + recordingRegions.put(mockCicsaRegion, rrA); + + String getYamlJcl = + IOUtils.toString(this.getClass().getResourceAsStream(getYamlString), utfString); + + String getYamlAppendedRegionaJcl = IOUtils + .toString(this.getClass().getResourceAsStream("/getYamlRegionA.jcl"), utfString); + + String regionAyaml = IOUtils + .toString(this.getClass().getResourceAsStream("/yamlRegionA.yaml"), utfString); + + // Mock artifactManager + IBundleResources bundleResources = Mockito.mock(IBundleResources.class); + Mockito.when(bundleResources.retrieveSkeletonFileAsString(Mockito.eq(jclGetYamlPathString), + Mockito.any())).thenReturn(getYamlJcl); + IArtifactManager artifactManager = Mockito.mock(IArtifactManager.class); + Mockito.when(artifactManager.getBundleResources(SdvHttpRecorderImpl.class)) + .thenReturn(bundleResources); + + // Mock batchManager + IZosBatchJob zosJobA = Mockito.mock(IZosBatchJob.class); + Mockito.when(zosJobA.waitForJob()).thenReturn(0); + IZosBatchJobOutput batchJobOutputRegionA = Mockito.mock(IZosBatchJobOutput.class); + List spoolFilesRegionA = new ArrayList<>(); + IZosBatchJobOutputSpoolFile spoolYamlFileRegionA = new ZosBatchJobOutputSpoolFileImpl( + zosJobA, "JobA", "ID123", "STEPA", "PROCA", "YAML", "SECA", regionAyaml); + spoolFilesRegionA.add(spoolYamlFileRegionA); + Mockito.when(batchJobOutputRegionA.getSpoolFiles()).thenReturn(spoolFilesRegionA); + Mockito.when(zosJobA.retrieveOutput()).thenReturn(batchJobOutputRegionA); + IZosBatch zosBatchRegionA = Mockito.mock(IZosBatch.class); + Mockito.when(zosBatchRegionA.submitJob(getYamlAppendedRegionaJcl, null)) + .thenReturn(zosJobA); + IZosBatchSpi batchManager = Mockito.mock(IZosBatchSpi.class); + Mockito.when(batchManager.getZosBatch(regionaImage)).thenReturn(zosBatchRegionA); + + Path storedArtifactRoot = Mockito.mock(Path.class); + Path finalYamlPath = Paths.get("/c/dir/" + "bundleF/TestClassF.CICSA.cics-security.yaml"); + Mockito.when(storedArtifactRoot.resolve("bundleF/TestClassF.CICSA.cics-security.yaml")) + .thenReturn(finalYamlPath); + Mockito.when(storedArtifactRoot.resolve("bundleF/TestClassF.CICSB.cics-security.yaml")) + .thenReturn(finalYamlPath); + // Mock SdvRecorderImpl + Class sdvHttpRecorderImplClass = Class.forName(sdvHttpRecorderImplClassString); + SdvHttpRecorderImpl sdvHttpRecorder = (SdvHttpRecorderImpl) sdvHttpRecorderImplClass + .getDeclaredConstructor(IFramework.class, Map.class, IArtifactManager.class, + IZosBatchSpi.class, Path.class, IDynamicStatusStoreService.class, + IHttpManagerSpi.class) + .newInstance(null, recordingRegions, artifactManager, batchManager, + storedArtifactRoot, null, null); + + files.when(() -> Files.write(Mockito.eq(finalYamlPath), + Mockito.eq(regionAyaml.getBytes(utfString)), Mockito.any())) + .thenThrow(new IOException("path not there")); + + // Replace LOG + Field loggerField = sdvHttpRecorderImplClass.getDeclaredField(logVariableString); + loggerField.setAccessible(true); + Field loggerSuperField = + sdvHttpRecorderImplClass.getSuperclass().getDeclaredField(logVariableString); + loggerSuperField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + modifiersField.setInt(loggerSuperField, loggerSuperField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvHttpRecorder, mockLog); + loggerSuperField.set(sdvHttpRecorder, mockLog); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvHttpRecorder.exportRecordings("bundleF", "TestClassF"); + }); + + Assertions.assertEquals( + "Unable to add YAML to Galasa run for CICS Region APPL1. " + + "Attempting to save to path: /c/dir/bundleF/TestClassF.CICSA.cics-security.yaml", + exception.getMessage() + ); + + } + +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvManagerImpl.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvManagerImpl.java new file mode 100644 index 000000000..2e2f11bf8 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvManagerImpl.java @@ -0,0 +1,1928 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.ICredentialsUsernamePassword; +import dev.galasa.ManagerException; +import dev.galasa.ProductVersion; +import dev.galasa.artifact.internal.ArtifactManagerImpl; +import dev.galasa.cicsts.CicstsManagerException; +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.cicsts.internal.CicstsManagerImpl; +import dev.galasa.cicsts.spi.ICicsRegionProvisioned; +import dev.galasa.cicsts.spi.ICicstsManagerSpi; +import dev.galasa.framework.spi.DynamicStatusStoreException; +import dev.galasa.framework.spi.IConfidentialTextService; +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.IManager; +import dev.galasa.framework.spi.IRun; +import dev.galasa.framework.spi.ResourceUnavailableException; +import dev.galasa.framework.spi.Result; +import dev.galasa.framework.spi.creds.CredentialsException; +import dev.galasa.framework.spi.creds.CredentialsUsernamePassword; +import dev.galasa.framework.spi.creds.ICredentialsService; +import dev.galasa.http.internal.HttpManagerImpl; +import dev.galasa.sdv.ISdvUser; +import dev.galasa.sdv.SdvManagerException; +import dev.galasa.sdv.SdvUser; +import dev.galasa.sdv.internal.properties.SdvHlq; +import dev.galasa.sdv.internal.properties.SdvPort; +import dev.galasa.sdv.internal.properties.SdvRole; +import dev.galasa.zos.internal.ZosManagerImpl; +import dev.galasa.zosbatch.IZosBatchJob; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.commons.logging.Log; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + + +class TestSdvManagerImpl { + + private MockedStatic sdvRole; + private MockedStatic sdvPort; + private MockedStatic sdvHlq; + private MockedStatic sdvUserPoolStatic; + + + @SuppressWarnings("PMD") + private static final Log mockLog = Mockito.mock(Log.class); + + private String testCicsTagA = "CICSA"; + private String testCicsTagB = "CICSB"; + private String testCicsTagC = "CICSC"; + private String roleNameTeller = "TELLER"; + private String roleNameAdmin = "ADMIN"; + private String roleNameOperator = "OPERATOR"; + private String testPort = "32000"; + private String sdvManagerImplClassString = "dev.galasa.sdv.internal.SdvManagerImpl"; + private String privateCicsManagerVariableName = "cicsManager"; + private String creds1Tag = "CREDS1"; + private String creds2Tag = "CREDS2"; + private String creds3Tag = "CREDS3"; + private String creds4Tag = "CREDS4"; + private String user1String = "user1"; + private String user2String = "user2"; + private String user3String = "user3"; + private String user4String = "user4"; + private String password1 = "password1"; + private String password2 = "password2"; + private String password3 = "password3"; + private String password4 = "password4"; + private String secOnMsg = "blah\n\nDFHXS1100I: Security initialization has started.\nblah"; + private String testClassString = "testClass"; + private String sdvUsersToRecordListString = "sdvUsersToRecordList"; + private String recordingRegionsString = "recordingRegions"; + private static final String uncheckedString = "unchecked"; + private String frameworkString = "framework"; + private String sdvRecorderVarName = "sdvRecorder"; + private String logString = "LOG"; + private String modifiersString = "modifiers"; + private String regionaApplid = "APPL1"; + private String runName = "RUN123"; + private String regionbApplid = "APPL2"; + + @BeforeAll + public static void beforeClass() { + Mockito.when(mockLog.isInfoEnabled()).thenReturn(true); + Mockito.when(mockLog.isWarnEnabled()).thenReturn(true); + Mockito.when(mockLog.isErrorEnabled()).thenReturn(true); + } + + @BeforeEach + public void setUp() { + // Registering static mocks before each test + sdvRole = Mockito.mockStatic(SdvRole.class); + sdvPort = Mockito.mockStatic(SdvPort.class); + sdvHlq = Mockito.mockStatic(SdvHlq.class); + sdvUserPoolStatic = Mockito.mockStatic(SdvUserPool.class); + } + + @AfterEach + public void tearDown() { + // Closing static mocks after each test + sdvRole.close(); + sdvPort.close(); + sdvHlq.close(); + sdvUserPoolStatic.close(); + } + + @Test + void testGetSdvUser() throws CredentialsException, SdvManagerException, ClassNotFoundException, + NoSuchFieldException, SecurityException, IllegalArgumentException, + IllegalAccessException, InstantiationException, InvocationTargetException, + NoSuchMethodException, ResourceUnavailableException { + // Create variables for common values used throughout test + String roleTag = "R1"; + String username = user1String; + + // Mocks for statics + sdvPort.when(() -> SdvPort.get(testCicsTagA)).thenReturn(testPort); + sdvHlq.when(() -> SdvHlq.get(testCicsTagA)).thenReturn("CICS.INSTALL"); + sdvRole.when(() -> SdvRole.get(roleTag)).thenReturn(roleNameTeller); + + // Mock ISdvUser annotation + Field testField = Mockito.mock(Field.class); + SdvUser sdvUser = Mockito.mock(SdvUser.class); + Mockito.when(sdvUser.cicsTag()).thenReturn(testCicsTagA); + Mockito.when(sdvUser.roleTag()).thenReturn(roleTag); + Mockito.when(testField.getAnnotation(SdvUser.class)).thenReturn(sdvUser); + + // Mock check for CICS region + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + Map mockCicsRegionList = new HashMap<>(); + + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getTag()).thenReturn(testCicsTagA); + + mockCicsRegionList.put(testCicsTagA, mockCicsaRegion); + Mockito.when(cicsManager.getTaggedCicsRegions()).thenReturn(mockCicsRegionList); + + // Replace private cicsManager instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + + // Mock sdvUserPool + SdvUserPool sdvUserPool = Mockito.mock(SdvUserPool.class); + Mockito.when(sdvUserPool.allocateUser(roleNameTeller, mockCicsaRegion)) + .thenReturn(creds1Tag); + Field sdvUserPoolField = sdvManagerImplClass.getDeclaredField("sdvUserPool"); + sdvUserPoolField.setAccessible(true); + sdvUserPoolField.set(sdvManager, sdvUserPool); + + // Mock getFramework().getCredentialsService() + ICredentialsUsernamePassword testCreds = + new CredentialsUsernamePassword(null, username, password1); + ICredentialsService credService = Mockito.mock(ICredentialsService.class); + Mockito.when(credService.getCredentials(creds1Tag)).thenReturn(testCreds); + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getCredentialsService()).thenReturn(credService); + Field frameworkField = + sdvManagerImplClass.getSuperclass().getDeclaredField(frameworkString); + frameworkField.setAccessible(true); + frameworkField.set(sdvManager, framework); + + // Mock cts + IConfidentialTextService cts = Mockito.mock(IConfidentialTextService.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(cts).registerText(password1, "Password for credential tag: " + creds1Tag); + Field ctsField = sdvManagerImplClass.getDeclaredField("cts"); + ctsField.setAccessible(true); + ctsField.set(sdvManager, cts); + + // Make call to funtion under test + ISdvUser resultUser = sdvManager.getSdvUser(testField, null); + + Assertions.assertEquals(creds1Tag, resultUser.getCredentialsTag()); + Assertions.assertEquals(testCicsTagA, resultUser.getCicsTag()); + Assertions.assertEquals(password1, resultUser.getPassword()); + Assertions.assertEquals(roleNameTeller, resultUser.getRole()); + Assertions.assertEquals(username, resultUser.getUsername()); + Assertions.assertEquals(false, resultUser.isRecording()); + } + + @Test + void testGetSdvUserBlankRoleTag() throws ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException { + // Create variables for common values used throughout test + String roleTag = ""; + + // Mock ISdvUser annotation + Field testField = Mockito.mock(Field.class); + SdvUser sdvUser = Mockito.mock(SdvUser.class); + Mockito.when(sdvUser.cicsTag()).thenReturn(testCicsTagA); + Mockito.when(sdvUser.roleTag()).thenReturn(roleTag); + Mockito.when(testField.getAnnotation(SdvUser.class)).thenReturn(sdvUser); + Mockito.when(testField.getName()).thenReturn("testUser"); + + // Get an SdvManager instance + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvManager.getSdvUser(testField, null); + }); + + Assertions.assertEquals("SdvUser testUser cannot have a blank RoleTag.", + exception.getMessage()); + } + + @Test + void testGetSdvUserNoMatchingRole() throws ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException { + // Create variables for common values used throughout test + String roleTag = "R1"; + + // Mocks for statics + sdvRole.when(() -> SdvRole.get(roleTag)).thenReturn(null); + + // Mock ISdvUser annotation + Field testField = Mockito.mock(Field.class); + SdvUser sdvUser = Mockito.mock(SdvUser.class); + Mockito.when(sdvUser.cicsTag()).thenReturn(testCicsTagA); + Mockito.when(sdvUser.roleTag()).thenReturn(roleTag); + Mockito.when(testField.getAnnotation(SdvUser.class)).thenReturn(sdvUser); + + // Get an SdvManager instance + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvManager.getSdvUser(testField, null); + }); + + Assertions + .assertEquals("Cannot find role. Please create or update CPS Property 'sdv.roleTag." + + roleTag + ".role'.", exception.getMessage()); + } + + @Test + void testGetSdvUserNoMatchingCicsRegion() throws ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Create variables for common values used throughout test + String roleTag = "R1"; + + // Mocks for statics + sdvRole.when(() -> SdvRole.get(roleTag)).thenReturn(roleNameTeller); + + // Mock ISdvUser annotation + Field testField = Mockito.mock(Field.class); + SdvUser sdvUser = Mockito.mock(SdvUser.class); + Mockito.when(sdvUser.cicsTag()).thenReturn(testCicsTagA); + Mockito.when(sdvUser.roleTag()).thenReturn(roleTag); + Mockito.when(testField.getAnnotation(SdvUser.class)).thenReturn(sdvUser); + Mockito.when(testField.getName()).thenReturn("testUser"); + + // Mock check for CICS region + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + Map mockCicsRegionList = new HashMap<>(); + Mockito.when(cicsManager.getTaggedCicsRegions()).thenReturn(mockCicsRegionList); + + // Replace private cicsManager instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvManager.getSdvUser(testField, null); + }); + + Assertions.assertEquals("Unable to setup SDV User 'testUser', for region with tag '" + + testCicsTagA + "' as a region with a matching 'cicsTag' tag was not found," + + " or the region was not provisioned.", exception.getMessage()); + } + + @Test + void testGetSdvUserNoPort() throws ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Create variables for common values used throughout test + String roleTag = "R1"; + + // Mocks for statics + sdvPort.when(() -> SdvPort.get(testCicsTagA)).thenReturn(null); + sdvRole.when(() -> SdvRole.get(roleTag)).thenReturn(roleNameTeller); + + // Mock ISdvUser annotation + Field testField = Mockito.mock(Field.class); + SdvUser sdvUser = Mockito.mock(SdvUser.class); + Mockito.when(sdvUser.cicsTag()).thenReturn(testCicsTagA); + Mockito.when(sdvUser.roleTag()).thenReturn(roleTag); + Mockito.when(testField.getAnnotation(SdvUser.class)).thenReturn(sdvUser); + Mockito.when(testField.getName()).thenReturn("testUser"); + + // Mock check for CICS region + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + Map mockCicsRegionList = new HashMap<>(); + + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getTag()).thenReturn(testCicsTagA); + + mockCicsRegionList.put(testCicsTagA, mockCicsaRegion); + Mockito.when(cicsManager.getTaggedCicsRegions()).thenReturn(mockCicsRegionList); + + // Replace private cicsManager instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvManager.getSdvUser(testField, null); + }); + + Assertions.assertEquals( + "Could not find port. Please create or update CPS property 'sdv.cicsTag." + + testCicsTagA + ".port'.", + exception.getMessage()); + } + + @Test + void testGetSdvUserNoHlq() + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, ResourceUnavailableException { + // Create variables for common values used throughout test + String roleTag = "R1"; + + // Mocks for statics + sdvPort.when(() -> SdvPort.get(testCicsTagA)).thenReturn(testPort); + sdvHlq.when(() -> SdvHlq.get(testCicsTagA)).thenReturn(null); + sdvRole.when(() -> SdvRole.get(roleTag)).thenReturn(roleNameTeller); + + // Mock ISdvUser annotation + Field testField = Mockito.mock(Field.class); + SdvUser sdvUser = Mockito.mock(SdvUser.class); + Mockito.when(sdvUser.cicsTag()).thenReturn(testCicsTagA); + Mockito.when(sdvUser.roleTag()).thenReturn(roleTag); + Mockito.when(testField.getAnnotation(SdvUser.class)).thenReturn(sdvUser); + + // Mock check for CICS region + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + Map mockCicsRegionList = new HashMap<>(); + + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getTag()).thenReturn(testCicsTagA); + + mockCicsRegionList.put(testCicsTagA, mockCicsaRegion); + Mockito.when(cicsManager.getTaggedCicsRegions()).thenReturn(mockCicsRegionList); + + // Replace private cicsManager instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvManager.getSdvUser(testField, null); + }); + + Assertions.assertEquals( + "Could not find HLQ. Please create or update CPS property 'sdv.cicsTag." + + testCicsTagA + ".hlq'.", + exception.getMessage()); + } + + @Test + void testGetSdvUserUserAllocationException() throws ClassNotFoundException, + InstantiationException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException, NoSuchMethodException, SecurityException, + NoSuchFieldException, SdvManagerException, ResourceUnavailableException { + // Create variables for common values used throughout test + String roleTag = "R1"; + + // Mocks for statics + sdvPort.when(() -> SdvPort.get(testCicsTagA)).thenReturn(testPort); + sdvHlq.when(() -> SdvHlq.get(testCicsTagA)).thenReturn("CICS.INSTALL"); + sdvRole.when(() -> SdvRole.get(roleTag)).thenReturn(roleNameTeller); + + // Mock ISdvUser annotation + Field testField = Mockito.mock(Field.class); + SdvUser sdvUser = Mockito.mock(SdvUser.class); + Mockito.when(sdvUser.cicsTag()).thenReturn(testCicsTagA); + Mockito.when(sdvUser.roleTag()).thenReturn(roleTag); + Mockito.when(testField.getAnnotation(SdvUser.class)).thenReturn(sdvUser); + + // Mock check for CICS region + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + Map mockCicsRegionList = new HashMap<>(); + + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getTag()).thenReturn(testCicsTagA); + + mockCicsRegionList.put(testCicsTagA, mockCicsaRegion); + Mockito.when(cicsManager.getTaggedCicsRegions()).thenReturn(mockCicsRegionList); + + // Replace private cicsManager instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + + // Mock sdvUserPool + SdvUserPool sdvUserPool = Mockito.mock(SdvUserPool.class); + Mockito.when(sdvUserPool.allocateUser(roleNameTeller, mockCicsaRegion)) + .thenThrow(new ResourceUnavailableException("No users available")); + Field sdvUserPoolField = sdvManagerImplClass.getDeclaredField("sdvUserPool"); + sdvUserPoolField.setAccessible(true); + sdvUserPoolField.set(sdvManager, sdvUserPool); + + // Make call to funtion under test + ResourceUnavailableException exception = + Assertions.assertThrows(ResourceUnavailableException.class, () -> { + sdvManager.getSdvUser(testField, null); + }); + + Assertions.assertEquals("No users available", exception.getMessage()); + } + + @Test + void testGetSdvUserCredentialsNotFound() throws InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, SdvManagerException, + ResourceUnavailableException, CredentialsException, ClassNotFoundException { + // Create variables for common values used throughout test + String roleTag = "R1"; + + // Mocks for statics + sdvPort.when(() -> SdvPort.get(testCicsTagA)).thenReturn(testPort); + sdvHlq.when(() -> SdvHlq.get(testCicsTagA)).thenReturn("CICS.INSTALL"); + sdvRole.when(() -> SdvRole.get(roleTag)).thenReturn(roleNameTeller); + + // Mock ISdvUser annotation + Field testField = Mockito.mock(Field.class); + SdvUser sdvUser = Mockito.mock(SdvUser.class); + Mockito.when(sdvUser.cicsTag()).thenReturn(testCicsTagA); + Mockito.when(sdvUser.roleTag()).thenReturn(roleTag); + Mockito.when(testField.getAnnotation(SdvUser.class)).thenReturn(sdvUser); + + // Mock check for CICS region + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + Map mockCicsRegionList = new HashMap<>(); + + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getTag()).thenReturn(testCicsTagA); + + mockCicsRegionList.put(testCicsTagA, mockCicsaRegion); + Mockito.when(cicsManager.getTaggedCicsRegions()).thenReturn(mockCicsRegionList); + + // Replace private cicsManager instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + + // Mock sdvUserPool + SdvUserPool sdvUserPool = Mockito.mock(SdvUserPool.class); + Mockito.when(sdvUserPool.allocateUser(roleNameTeller, mockCicsaRegion)) + .thenReturn(creds1Tag); + Field sdvUserPoolField = sdvManagerImplClass.getDeclaredField("sdvUserPool"); + sdvUserPoolField.setAccessible(true); + sdvUserPoolField.set(sdvManager, sdvUserPool); + + // Mock getFramework().getCredentialsService() + ICredentialsService credService = Mockito.mock(ICredentialsService.class); + Mockito.when(credService.getCredentials(creds1Tag)) + .thenThrow(new CredentialsException("Did not find user")); + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getCredentialsService()).thenReturn(credService); + Field frameworkField = + sdvManagerImplClass.getSuperclass().getDeclaredField(frameworkString); + frameworkField.setAccessible(true); + frameworkField.set(sdvManager, framework); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvManager.getSdvUser(testField, null); + }); + + Assertions.assertEquals("No credentials were found with the tag: " + creds1Tag, + exception.getMessage()); + } + + @Test + void testProvisionGenerate() throws ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException, + ResourceUnavailableException, ManagerException, CredentialsException { + + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + Map mockCicsRegionList = new HashMap<>(); + + // Mock for CICS region A + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getTag()).thenReturn(testCicsTagA); + // Mock region Product version + ProductVersion mockProductVersion = Mockito.mock(ProductVersion.class); + Mockito.when(mockProductVersion.isEarlierThan(ProductVersion.v(750))).thenReturn(false); + Mockito.when(mockCicsaRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + IZosBatchJob mockIzOsBatchJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(mockIzOsBatchJob.retrieveOutputAsString()).thenReturn(secOnMsg); + Mockito.when(mockCicsaRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagA, mockCicsaRegion); + + // Mock for CICS region B + ICicsRegionProvisioned mockCicsbRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsbRegion.getTag()).thenReturn(testCicsTagA); + // Mock region Product version + Mockito.when(mockCicsbRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + Mockito.when(mockCicsbRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagB, mockCicsbRegion); + + // Mock for CICS region C + ICicsRegionProvisioned mockCicscRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicscRegion.getTag()).thenReturn(testCicsTagA); + // Mock region Product version + Mockito.when(mockCicscRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + Mockito.when(mockCicscRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagC, mockCicscRegion); + + Mockito.when(cicsManager.getTaggedCicsRegions()).thenReturn(mockCicsRegionList); + + // Mock Terminals + ICicsTerminal regionaTerminal = Mockito.mock(ICicsTerminal.class); + Mockito.when(cicsManager.generateCicsTerminal(testCicsTagA)).thenReturn(regionaTerminal); + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + Mockito.when(cicsManager.generateCicsTerminal(testCicsTagB)).thenReturn(regionbTerminal); + ICicsTerminal regioncTerminal = Mockito.mock(ICicsTerminal.class); + Mockito.when(cicsManager.generateCicsTerminal(testCicsTagC)).thenReturn(regioncTerminal); + + // Replace private cicsManager instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + // Replace testClass to bypass generateAnnotatedFields + Field testClass = sdvManagerImplClass.getSuperclass().getDeclaredField(testClassString); + testClass.setAccessible(true); + testClass.set(sdvManager, null); + // Replace sdvUsersToRecordList with a mocked list + List listOfUsersForAllRegions = new ArrayList<>(); + // user1 + ICredentialsUsernamePassword testCreds1 = + new CredentialsUsernamePassword(null, user1String, password1); + SdvUserImpl newSdvUser1 = + new SdvUserImpl(creds1Tag, testCreds1, testCicsTagA, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser1); + // user2 + ICredentialsUsernamePassword testCreds2 = + new CredentialsUsernamePassword(null, user2String, password2); + SdvUserImpl newSdvUser2 = + new SdvUserImpl(creds2Tag, testCreds2, testCicsTagB, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser2); + // user3 + ICredentialsUsernamePassword testCreds3 = + new CredentialsUsernamePassword(null, user3String, password3); + SdvUserImpl newSdvUser3 = + new SdvUserImpl(creds3Tag, testCreds3, testCicsTagA, roleNameAdmin); + listOfUsersForAllRegions.add(newSdvUser3); + // user4 + ICredentialsUsernamePassword testCreds4 = + new CredentialsUsernamePassword(null, user4String, password4); + SdvUserImpl newSdvUser4 = + new SdvUserImpl(creds4Tag, testCreds4, testCicsTagC, roleNameOperator); + listOfUsersForAllRegions.add(newSdvUser4); + + Field sdvUsersToRecordList = + sdvManagerImplClass.getDeclaredField(sdvUsersToRecordListString); + sdvUsersToRecordList.setAccessible(true); + sdvUsersToRecordList.set(sdvManager, listOfUsersForAllRegions); + + // Make call to funtion under test + sdvManager.provisionGenerate(); + + Field recordingRegionsField = sdvManagerImplClass.getDeclaredField(recordingRegionsString); + recordingRegionsField.setAccessible(true); + + @SuppressWarnings(uncheckedString) + Map recordingRegions = + (Map) recordingRegionsField.get(sdvManager); + + // Check correct number of users against each region + Assertions.assertEquals(2, + recordingRegions.get(mockCicsaRegion).getRecordingUsers().size()); + Assertions.assertEquals(1, + recordingRegions.get(mockCicsbRegion).getRecordingUsers().size()); + Assertions.assertEquals(1, + recordingRegions.get(mockCicscRegion).getRecordingUsers().size()); + + // Check correct users against each region + List regionaUsers = new ArrayList<>(); + regionaUsers.add(user1String); + regionaUsers.add(user3String); + for (ISdvUser user : recordingRegions.get(mockCicsaRegion).getRecordingUsers()) { + Assertions.assertTrue(regionaUsers.contains(user.getUsername())); + } + + List regionbUsers = new ArrayList<>(); + regionbUsers.add(user2String); + for (ISdvUser user : recordingRegions.get(mockCicsbRegion).getRecordingUsers()) { + Assertions.assertTrue(regionbUsers.contains(user.getUsername())); + } + + List regioncUsers = new ArrayList<>(); + regioncUsers.add(user4String); + for (ISdvUser user : recordingRegions.get(mockCicscRegion).getRecordingUsers()) { + Assertions.assertTrue(regioncUsers.contains(user.getUsername())); + } + + // Check each region has correct terminal + Assertions.assertEquals(regionaTerminal, + recordingRegions.get(mockCicsaRegion).getMaintenanceTerminal()); + Assertions.assertEquals(regionbTerminal, + recordingRegions.get(mockCicsbRegion).getMaintenanceTerminal()); + Assertions.assertEquals(regioncTerminal, + recordingRegions.get(mockCicscRegion).getMaintenanceTerminal()); + } + + @Test + void testProvisionGenerateOldCicsVersionForRegionA() + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, CredentialsException, + ResourceUnavailableException, ManagerException { + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + Map mockCicsRegionList = new HashMap<>(); + + // Mock for CICS region A + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getTag()).thenReturn(testCicsTagA); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn("OLDREGION"); + // Mock region Product version + ProductVersion mockProductVersion = Mockito.mock(ProductVersion.class); + Mockito.when(mockProductVersion.isEarlierThan(ProductVersion.v(750))).thenReturn(true, + false, false); + Mockito.when(mockCicsaRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + IZosBatchJob mockIzOsBatchJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(mockIzOsBatchJob.retrieveOutputAsString()).thenReturn(secOnMsg); + Mockito.when(mockCicsaRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagA, mockCicsaRegion); + + // Mock for CICS region B + ICicsRegionProvisioned mockCicsbRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsbRegion.getTag()).thenReturn(testCicsTagA); + // Mock region Product version + Mockito.when(mockCicsbRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + Mockito.when(mockCicsbRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagB, mockCicsbRegion); + + // Mock for CICS region C + ICicsRegionProvisioned mockCicscRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicscRegion.getTag()).thenReturn(testCicsTagA); + // Mock region Product version + Mockito.when(mockCicscRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + Mockito.when(mockCicscRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagC, mockCicscRegion); + + Mockito.when(cicsManager.getTaggedCicsRegions()).thenReturn(mockCicsRegionList); + + // Mock Terminals + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + Mockito.when(cicsManager.generateCicsTerminal(testCicsTagB)).thenReturn(regionbTerminal); + ICicsTerminal regioncTerminal = Mockito.mock(ICicsTerminal.class); + Mockito.when(cicsManager.generateCicsTerminal(testCicsTagC)).thenReturn(regioncTerminal); + + // Replace private cicsManager instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + // Replace testClass to bypass generateAnnotatedFields + Field testClass = sdvManagerImplClass.getSuperclass().getDeclaredField(testClassString); + testClass.setAccessible(true); + testClass.set(sdvManager, null); + // Replace sdvUsersToRecordList with a mocked list + List listOfUsersForAllRegions = new ArrayList<>(); + // user1 + ICredentialsUsernamePassword testCreds1 = + new CredentialsUsernamePassword(null, user1String, password1); + SdvUserImpl newSdvUser1 = + new SdvUserImpl(creds1Tag, testCreds1, testCicsTagA, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser1); + // user2 + ICredentialsUsernamePassword testCreds2 = + new CredentialsUsernamePassword(null, user2String, password2); + SdvUserImpl newSdvUser2 = + new SdvUserImpl(creds2Tag, testCreds2, testCicsTagB, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser2); + // user3 + ICredentialsUsernamePassword testCreds3 = + new CredentialsUsernamePassword(null, user3String, password3); + SdvUserImpl newSdvUser3 = + new SdvUserImpl(creds3Tag, testCreds3, testCicsTagA, roleNameAdmin); + listOfUsersForAllRegions.add(newSdvUser3); + // user4 + ICredentialsUsernamePassword testCreds4 = + new CredentialsUsernamePassword(null, user4String, password4); + SdvUserImpl newSdvUser4 = + new SdvUserImpl(creds4Tag, testCreds4, testCicsTagC, roleNameOperator); + listOfUsersForAllRegions.add(newSdvUser4); + + Field sdvUsersToRecordList = + sdvManagerImplClass.getDeclaredField(sdvUsersToRecordListString); + sdvUsersToRecordList.setAccessible(true); + sdvUsersToRecordList.set(sdvManager, listOfUsersForAllRegions); + + // Replace LOG + Field loggerField = sdvManagerImplClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManager, mockLog); + + // Make call to funtion under test + sdvManager.provisionGenerate(); + + Field recordingRegionsField = sdvManagerImplClass.getDeclaredField(recordingRegionsString); + recordingRegionsField.setAccessible(true); + + @SuppressWarnings(uncheckedString) + Map recordingRegions = + (Map) recordingRegionsField.get(sdvManager); + + // Check correct number of users against each region + Assertions.assertEquals(null, recordingRegions.get(mockCicsaRegion)); + Assertions.assertEquals(1, + recordingRegions.get(mockCicsbRegion).getRecordingUsers().size()); + Assertions.assertEquals(1, + recordingRegions.get(mockCicscRegion).getRecordingUsers().size()); + + // Check correct users against each region + List regionbUsers = new ArrayList<>(); + regionbUsers.add(user2String); + for (ISdvUser user : recordingRegions.get(mockCicsbRegion).getRecordingUsers()) { + Assertions.assertTrue(regionbUsers.contains(user.getUsername())); + } + + List regioncUsers = new ArrayList<>(); + regioncUsers.add(user4String); + for (ISdvUser user : recordingRegions.get(mockCicscRegion).getRecordingUsers()) { + Assertions.assertTrue(regioncUsers.contains(user.getUsername())); + } + + // Check each region has correct terminal + Assertions.assertEquals(regionbTerminal, + recordingRegions.get(mockCicsbRegion).getMaintenanceTerminal()); + Assertions.assertEquals(regioncTerminal, + recordingRegions.get(mockCicscRegion).getMaintenanceTerminal()); + + // Check there is a warning in the log indicating Region A won't record + Mockito.verify(mockLog, Mockito.times(1)) + .warn("SDV recording will not take place on CICS region 'OLDREGION'" + + ". Running version earlier than 750."); + + } + + @Test + void testProvisionGenerateNoSecMsg() throws ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException, CredentialsException, + ResourceUnavailableException, ManagerException { + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + Map mockCicsRegionList = new HashMap<>(); + + // Mock for CICS region A + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getTag()).thenReturn(testCicsTagA); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn("NOSEC"); + // Mock region Product version + ProductVersion mockProductVersion = Mockito.mock(ProductVersion.class); + Mockito.when(mockProductVersion.isEarlierThan(ProductVersion.v(750))).thenReturn(false, + false, false); + Mockito.when(mockCicsaRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + IZosBatchJob mockIzOsBatchJobNoSec = Mockito.mock(IZosBatchJob.class); + Mockito.when(mockIzOsBatchJobNoSec.retrieveOutputAsString()) + .thenReturn("blah\n\nDFHXS1102I: Security is inactive.\nblah"); + Mockito.when(mockCicsaRegion.getRegionJob()).thenReturn(mockIzOsBatchJobNoSec); + mockCicsRegionList.put(testCicsTagA, mockCicsaRegion); + + // Mock for CICS region B + ICicsRegionProvisioned mockCicsbRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsbRegion.getTag()).thenReturn(testCicsTagA); + // Mock region Product version + Mockito.when(mockCicsbRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + IZosBatchJob mockIzOsBatchJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(mockIzOsBatchJob.retrieveOutputAsString()).thenReturn(secOnMsg); + Mockito.when(mockCicsbRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagB, mockCicsbRegion); + + // Mock for CICS region C + ICicsRegionProvisioned mockCicscRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicscRegion.getTag()).thenReturn(testCicsTagA); + // Mock region Product version + Mockito.when(mockCicscRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + Mockito.when(mockCicscRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagC, mockCicscRegion); + + Mockito.when(cicsManager.getTaggedCicsRegions()).thenReturn(mockCicsRegionList); + + // Mock Terminals + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + Mockito.when(cicsManager.generateCicsTerminal(testCicsTagB)).thenReturn(regionbTerminal); + ICicsTerminal regioncTerminal = Mockito.mock(ICicsTerminal.class); + Mockito.when(cicsManager.generateCicsTerminal(testCicsTagC)).thenReturn(regioncTerminal); + + // Replace private cicsManager instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + // Replace testClass to bypass generateAnnotatedFields + Field testClass = sdvManagerImplClass.getSuperclass().getDeclaredField(testClassString); + testClass.setAccessible(true); + testClass.set(sdvManager, null); + // Replace sdvUsersToRecordList with a mocked list + List listOfUsersForAllRegions = new ArrayList<>(); + // user1 + ICredentialsUsernamePassword testCreds1 = + new CredentialsUsernamePassword(null, user1String, password1); + SdvUserImpl newSdvUser1 = + new SdvUserImpl(creds1Tag, testCreds1, testCicsTagA, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser1); + // user2 + ICredentialsUsernamePassword testCreds2 = + new CredentialsUsernamePassword(null, user2String, password2); + SdvUserImpl newSdvUser2 = + new SdvUserImpl(creds2Tag, testCreds2, testCicsTagB, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser2); + // user3 + ICredentialsUsernamePassword testCreds3 = + new CredentialsUsernamePassword(null, user3String, password3); + SdvUserImpl newSdvUser3 = + new SdvUserImpl(creds3Tag, testCreds3, testCicsTagA, roleNameAdmin); + listOfUsersForAllRegions.add(newSdvUser3); + // user4 + ICredentialsUsernamePassword testCreds4 = + new CredentialsUsernamePassword(null, user4String, password4); + SdvUserImpl newSdvUser4 = + new SdvUserImpl(creds4Tag, testCreds4, testCicsTagC, roleNameOperator); + listOfUsersForAllRegions.add(newSdvUser4); + + Field sdvUsersToRecordList = + sdvManagerImplClass.getDeclaredField(sdvUsersToRecordListString); + sdvUsersToRecordList.setAccessible(true); + sdvUsersToRecordList.set(sdvManager, listOfUsersForAllRegions); + + // Replace LOG + Field loggerField = sdvManagerImplClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManager, mockLog); + + // Make call to funtion under test + sdvManager.provisionGenerate(); + + Field recordingRegionsField = sdvManagerImplClass.getDeclaredField(recordingRegionsString); + recordingRegionsField.setAccessible(true); + + @SuppressWarnings(uncheckedString) + Map recordingRegions = + (Map) recordingRegionsField.get(sdvManager); + + // Check correct number of users against each region + Assertions.assertEquals(null, recordingRegions.get(mockCicsaRegion)); + Assertions.assertEquals(1, + recordingRegions.get(mockCicsbRegion).getRecordingUsers().size()); + Assertions.assertEquals(1, + recordingRegions.get(mockCicscRegion).getRecordingUsers().size()); + + // Check correct users against each region + List regionbUsers = new ArrayList<>(); + regionbUsers.add(user2String); + for (ISdvUser user : recordingRegions.get(mockCicsbRegion).getRecordingUsers()) { + Assertions.assertTrue(regionbUsers.contains(user.getUsername())); + } + + List regioncUsers = new ArrayList<>(); + regioncUsers.add(user4String); + for (ISdvUser user : recordingRegions.get(mockCicscRegion).getRecordingUsers()) { + Assertions.assertTrue(regioncUsers.contains(user.getUsername())); + } + + // Check each region has correct terminal + Assertions.assertEquals(regionbTerminal, + recordingRegions.get(mockCicsbRegion).getMaintenanceTerminal()); + Assertions.assertEquals(regioncTerminal, + recordingRegions.get(mockCicscRegion).getMaintenanceTerminal()); + + // Check there is a warning in the log indicating Region A won't record + Mockito.verify(mockLog, Mockito.times(1)) + .warn("SDV recording will not take place on CICS region 'NOSEC'" + + ". Security is not active."); + } + + @Test + void testProvisionGenerateNoUsersForRegion() + throws ClassNotFoundException, NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException, CredentialsException, + InstantiationException, InvocationTargetException, NoSuchMethodException, + ResourceUnavailableException, ManagerException { + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + Map mockCicsRegionList = new HashMap<>(); + + // Mock for CICS region A + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getTag()).thenReturn(testCicsTagA); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn("OLDREGION"); + // Mock region Product version + ProductVersion mockProductVersion = Mockito.mock(ProductVersion.class); + Mockito.when(mockProductVersion.isEarlierThan(ProductVersion.v(750))).thenReturn(false, + false, false); + Mockito.when(mockCicsaRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + IZosBatchJob mockIzOsBatchJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(mockIzOsBatchJob.retrieveOutputAsString()).thenReturn(secOnMsg); + Mockito.when(mockCicsaRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagA, mockCicsaRegion); + + // Mock for CICS region B + ICicsRegionProvisioned mockCicsbRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsbRegion.getTag()).thenReturn(testCicsTagA); + // Mock region Product version + Mockito.when(mockCicsbRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + Mockito.when(mockCicsbRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagB, mockCicsbRegion); + + // Mock for CICS region C + ICicsRegionProvisioned mockCicscRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicscRegion.getTag()).thenReturn(testCicsTagA); + // Mock region Product version + Mockito.when(mockCicscRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + Mockito.when(mockCicscRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagC, mockCicscRegion); + + Mockito.when(cicsManager.getTaggedCicsRegions()).thenReturn(mockCicsRegionList); + + // Mock Terminals + ICicsTerminal regionbTerminal = Mockito.mock(ICicsTerminal.class); + Mockito.when(cicsManager.generateCicsTerminal(testCicsTagB)).thenReturn(regionbTerminal); + ICicsTerminal regioncTerminal = Mockito.mock(ICicsTerminal.class); + Mockito.when(cicsManager.generateCicsTerminal(testCicsTagC)).thenReturn(regioncTerminal); + + // Replace private cicsManager instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + // Replace testClass to bypass generateAnnotatedFields + Field testClass = sdvManagerImplClass.getSuperclass().getDeclaredField(testClassString); + testClass.setAccessible(true); + testClass.set(sdvManager, null); + // Replace sdvUsersToRecordList with a mocked list + List listOfUsersForAllRegions = new ArrayList<>(); + // user1 + ICredentialsUsernamePassword testCreds1 = + new CredentialsUsernamePassword(null, user1String, password1); + SdvUserImpl newSdvUser1 = + new SdvUserImpl(creds1Tag, testCreds1, testCicsTagB, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser1); + // user2 + ICredentialsUsernamePassword testCreds2 = + new CredentialsUsernamePassword(null, user2String, password2); + SdvUserImpl newSdvUser2 = + new SdvUserImpl(creds2Tag, testCreds2, testCicsTagB, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser2); + // user3 + ICredentialsUsernamePassword testCreds3 = + new CredentialsUsernamePassword(null, user3String, password3); + SdvUserImpl newSdvUser3 = + new SdvUserImpl(creds3Tag, testCreds3, testCicsTagB, roleNameAdmin); + listOfUsersForAllRegions.add(newSdvUser3); + // user4 + ICredentialsUsernamePassword testCreds4 = + new CredentialsUsernamePassword(null, user4String, password4); + SdvUserImpl newSdvUser4 = + new SdvUserImpl(creds4Tag, testCreds4, testCicsTagC, roleNameOperator); + listOfUsersForAllRegions.add(newSdvUser4); + + Field sdvUsersToRecordList = + sdvManagerImplClass.getDeclaredField(sdvUsersToRecordListString); + sdvUsersToRecordList.setAccessible(true); + sdvUsersToRecordList.set(sdvManager, listOfUsersForAllRegions); + + // Replace LOG + Field loggerField = sdvManagerImplClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManager, mockLog); + + // Make call to funtion under test + sdvManager.provisionGenerate(); + + Field recordingRegionsField = sdvManagerImplClass.getDeclaredField(recordingRegionsString); + recordingRegionsField.setAccessible(true); + + @SuppressWarnings(uncheckedString) + Map recordingRegions = + (Map) recordingRegionsField.get(sdvManager); + + // Check correct number of users against each region + Assertions.assertEquals(null, recordingRegions.get(mockCicsaRegion)); + Assertions.assertEquals(3, + recordingRegions.get(mockCicsbRegion).getRecordingUsers().size()); + Assertions.assertEquals(1, + recordingRegions.get(mockCicscRegion).getRecordingUsers().size()); + + // Check correct users against each region + List regionbUsers = new ArrayList<>(); + regionbUsers.add(user1String); + regionbUsers.add(user2String); + regionbUsers.add(user3String); + for (ISdvUser user : recordingRegions.get(mockCicsbRegion).getRecordingUsers()) { + Assertions.assertTrue(regionbUsers.contains(user.getUsername())); + } + + List regioncUsers = new ArrayList<>(); + regioncUsers.add(user4String); + for (ISdvUser user : recordingRegions.get(mockCicscRegion).getRecordingUsers()) { + Assertions.assertTrue(regioncUsers.contains(user.getUsername())); + } + + // Check each region has correct terminal + Assertions.assertEquals(regionbTerminal, + recordingRegions.get(mockCicsbRegion).getMaintenanceTerminal()); + Assertions.assertEquals(regioncTerminal, + recordingRegions.get(mockCicscRegion).getMaintenanceTerminal()); + + // Check there is a warning in the log indicating Region A won't record + Mockito.verify(mockLog, Mockito.times(1)) + .warn("No users have been listed for recording via the SdvUser " + + "annotation for cicsTag 'CICSA'."); + + } + + @Test + void testProvisionGenerateException() throws CredentialsException, NoSuchFieldException, + SecurityException, IllegalArgumentException, IllegalAccessException, + ResourceUnavailableException, ManagerException, ClassNotFoundException, + InstantiationException, InvocationTargetException, NoSuchMethodException { + + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + Map mockCicsRegionList = new HashMap<>(); + + // Mock for CICS region A + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getTag()).thenReturn(testCicsTagA); + // Mock region Product version + ProductVersion mockProductVersion = Mockito.mock(ProductVersion.class); + Mockito.when(mockProductVersion.isEarlierThan(ProductVersion.v(750))).thenReturn(false); + Mockito.when(mockCicsaRegion.getVersion()).thenReturn(mockProductVersion); + // Mock region SEC=YES log message + IZosBatchJob mockIzOsBatchJob = Mockito.mock(IZosBatchJob.class); + Mockito.when(mockIzOsBatchJob.retrieveOutputAsString()).thenReturn(secOnMsg); + Mockito.when(mockCicsaRegion.getRegionJob()).thenReturn(mockIzOsBatchJob); + mockCicsRegionList.put(testCicsTagA, mockCicsaRegion); + + Mockito.when(cicsManager.getTaggedCicsRegions()).thenReturn(mockCicsRegionList); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn(regionaApplid); + Mockito.when(cicsManager.locateCicsRegion(testCicsTagA)).thenReturn(mockCicsaRegion); + + // Mock Terminals + Mockito.when(cicsManager.generateCicsTerminal(testCicsTagA)) + .thenThrow(new CicstsManagerException("Ooppss")); + + // Replace private cicsManager instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + // Replace testClass to bypass generateAnnotatedFields + Field testClass = sdvManagerImplClass.getSuperclass().getDeclaredField(testClassString); + testClass.setAccessible(true); + testClass.set(sdvManager, null); + // Replace sdvUsersToRecordList with a mocked list + List listOfUsersForAllRegions = new ArrayList<>(); + // user1 + ICredentialsUsernamePassword testCreds1 = + new CredentialsUsernamePassword(null, user1String, password1); + SdvUserImpl newSdvUser1 = + new SdvUserImpl(creds1Tag, testCreds1, testCicsTagA, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser1); + // user3 + ICredentialsUsernamePassword testCreds3 = + new CredentialsUsernamePassword(null, user3String, password3); + SdvUserImpl newSdvUser3 = + new SdvUserImpl(creds3Tag, testCreds3, testCicsTagA, roleNameAdmin); + listOfUsersForAllRegions.add(newSdvUser3); + + Field sdvUsersToRecordList = + sdvManagerImplClass.getDeclaredField(sdvUsersToRecordListString); + sdvUsersToRecordList.setAccessible(true); + sdvUsersToRecordList.set(sdvManager, listOfUsersForAllRegions); + + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Field dssField = sdvManagerImplClass.getDeclaredField("dss"); + dssField.setAccessible(true); + dssField.set(sdvManager, dssService); + + // Mock releaseUsers bits + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds1Tag, regionaApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds3Tag, regionaApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(runName); + Field frameworkField = + sdvManagerImplClass.getSuperclass().getDeclaredField(frameworkString); + frameworkField.setAccessible(true); + frameworkField.set(sdvManager, framework); + + // Make call to funtion under test + ManagerException exception = Assertions.assertThrows(ManagerException.class, () -> { + sdvManager.provisionGenerate(); + }); + + Assertions.assertEquals("Ooppss", exception.getMessage()); + + // Verify users released. + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds1Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds3Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + } + + @Test + void testProvisionStart() throws InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, ClassNotFoundException, SdvManagerException, NoSuchFieldException { + // Replace private sdvRecorder instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + SdvHttpRecorderImpl sdvRecorder = Mockito.mock(SdvHttpRecorderImpl.class); + Field sdvRecorderField = sdvManagerImplClass.getDeclaredField(sdvRecorderVarName); + sdvRecorderField.setAccessible(true); + sdvRecorderField.set(sdvManager, sdvRecorder); + + // Make call to funtion under test + sdvManager.provisionStart(); + + Mockito.verify(sdvRecorder, Mockito.times(1)).prepareEnvironments("LOG_GENERAL_001"); + Mockito.verifyNoMoreInteractions(sdvRecorder); + } + + @Test + void testProvisionStop() throws InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, ClassNotFoundException, SdvManagerException, NoSuchFieldException, + CredentialsException, CicstsManagerException { + // Replace private sdvRecorder instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + SdvHttpRecorderImpl sdvRecorder = Mockito.mock(SdvHttpRecorderImpl.class); + Field sdvRecorderField = sdvManagerImplClass.getDeclaredField(sdvRecorderVarName); + sdvRecorderField.setAccessible(true); + sdvRecorderField.set(sdvManager, sdvRecorder); + + // Replace sdvUsersToRecordList with a mocked list + List listOfUsersForAllRegions = new ArrayList<>(); + // user1 + ICredentialsUsernamePassword testCreds1 = + new CredentialsUsernamePassword(null, user1String, password1); + SdvUserImpl newSdvUser1 = + new SdvUserImpl(creds1Tag, testCreds1, testCicsTagA, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser1); + // user2 + ICredentialsUsernamePassword testCreds2 = + new CredentialsUsernamePassword(null, user2String, password2); + SdvUserImpl newSdvUser2 = + new SdvUserImpl(creds2Tag, testCreds2, testCicsTagB, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser2); + // user3 + ICredentialsUsernamePassword testCreds3 = + new CredentialsUsernamePassword(null, user3String, password3); + SdvUserImpl newSdvUser3 = + new SdvUserImpl(creds3Tag, testCreds3, testCicsTagA, roleNameAdmin); + listOfUsersForAllRegions.add(newSdvUser3); + + Field sdvUsersToRecordList = + sdvManagerImplClass.getDeclaredField(sdvUsersToRecordListString); + sdvUsersToRecordList.setAccessible(true); + sdvUsersToRecordList.set(sdvManager, listOfUsersForAllRegions); + + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + + // Mock cicsManager + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn(regionaApplid); + Mockito.when(cicsManager.locateCicsRegion(testCicsTagA)).thenReturn(mockCicsaRegion); + + ICicsRegionProvisioned mockCicsbRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsbRegion.getApplid()).thenReturn(regionbApplid); + Mockito.when(cicsManager.locateCicsRegion(testCicsTagB)).thenReturn(mockCicsbRegion); + + // Replace private cicsManager instance in sdvManager + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds1Tag, regionaApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds3Tag, regionaApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds2Tag, regionbApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(runName); + Field frameworkField = + sdvManagerImplClass.getSuperclass().getDeclaredField(frameworkString); + frameworkField.setAccessible(true); + frameworkField.set(sdvManager, framework); + + // Make call to funtion under test + sdvManager.provisionStop(); + + Mockito.verify(sdvRecorder, Mockito.times(1)).endRecording(); + Mockito.verify(sdvRecorder, Mockito.times(1)).cleanUpEnvironments(); + Mockito.verifyNoMoreInteractions(sdvRecorder); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds1Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds3Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds2Tag), + Mockito.eq(regionbApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + } + + @Test + void testProvisionStopEndRecordingException() throws InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, ClassNotFoundException, SdvManagerException, + NoSuchFieldException, CredentialsException, CicstsManagerException { + // Replace private sdvRecorder instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + SdvHttpRecorderImpl sdvRecorder = Mockito.mock(SdvHttpRecorderImpl.class); + Mockito.doThrow(new SdvManagerException("test1")).when(sdvRecorder).endRecording(); + Field sdvRecorderField = sdvManagerImplClass.getDeclaredField(sdvRecorderVarName); + sdvRecorderField.setAccessible(true); + sdvRecorderField.set(sdvManager, sdvRecorder); + + // Replace sdvUsersToRecordList with a mocked list + List listOfUsersForAllRegions = new ArrayList<>(); + // user1 + ICredentialsUsernamePassword testCreds1 = + new CredentialsUsernamePassword(null, user1String, password1); + SdvUserImpl newSdvUser1 = + new SdvUserImpl(creds1Tag, testCreds1, testCicsTagA, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser1); + // user2 + ICredentialsUsernamePassword testCreds2 = + new CredentialsUsernamePassword(null, user2String, password2); + SdvUserImpl newSdvUser2 = + new SdvUserImpl(creds2Tag, testCreds2, testCicsTagB, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser2); + // user3 + ICredentialsUsernamePassword testCreds3 = + new CredentialsUsernamePassword(null, user3String, password3); + SdvUserImpl newSdvUser3 = + new SdvUserImpl(creds3Tag, testCreds3, testCicsTagA, roleNameAdmin); + listOfUsersForAllRegions.add(newSdvUser3); + + Field sdvUsersToRecordList = + sdvManagerImplClass.getDeclaredField(sdvUsersToRecordListString); + sdvUsersToRecordList.setAccessible(true); + sdvUsersToRecordList.set(sdvManager, listOfUsersForAllRegions); + + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + + // Mock cicsManager + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn(regionaApplid); + Mockito.when(cicsManager.locateCicsRegion(testCicsTagA)).thenReturn(mockCicsaRegion); + + ICicsRegionProvisioned mockCicsbRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsbRegion.getApplid()).thenReturn(regionbApplid); + Mockito.when(cicsManager.locateCicsRegion(testCicsTagB)).thenReturn(mockCicsbRegion); + + // Replace private cicsManager instance in sdvManager + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds1Tag, regionaApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds3Tag, regionaApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds2Tag, regionbApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(runName); + Field frameworkField = + sdvManagerImplClass.getSuperclass().getDeclaredField(frameworkString); + frameworkField.setAccessible(true); + frameworkField.set(sdvManager, framework); + + // Replace LOG + Field loggerField = sdvManagerImplClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManager, mockLog); + + // Make call to funtion under test + sdvManager.provisionStop(); + + Mockito.verify(sdvRecorder, Mockito.times(1)).endRecording(); + Mockito.verify(sdvRecorder, Mockito.times(1)).cleanUpEnvironments(); + Mockito.verifyNoMoreInteractions(sdvRecorder); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds1Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds3Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds2Tag), + Mockito.eq(regionbApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + // endRecording exception should not have stopped everything else from running, + // but it should had made a log output to make the user aware. + Mockito.verify(mockLog, Mockito.times(1)) + .error(Mockito.eq("Could not stop known SDC recordings in provisionStop."), + Mockito.any(SdvManagerException.class)); + } + + @Test + void testProvisionStopReleaseUsersException() throws InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, ClassNotFoundException, SdvManagerException, + NoSuchFieldException, CredentialsException, CicstsManagerException { + // Replace private sdvRecorder instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + SdvHttpRecorderImpl sdvRecorder = Mockito.mock(SdvHttpRecorderImpl.class); + Field sdvRecorderField = sdvManagerImplClass.getDeclaredField(sdvRecorderVarName); + sdvRecorderField.setAccessible(true); + sdvRecorderField.set(sdvManager, sdvRecorder); + + // Replace sdvUsersToRecordList with a mocked list + List listOfUsersForAllRegions = new ArrayList<>(); + // user1 + ICredentialsUsernamePassword testCreds1 = + new CredentialsUsernamePassword(null, user1String, password1); + SdvUserImpl newSdvUser1 = + new SdvUserImpl(creds1Tag, testCreds1, testCicsTagA, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser1); + // user2 + ICredentialsUsernamePassword testCreds2 = + new CredentialsUsernamePassword(null, user2String, password2); + SdvUserImpl newSdvUser2 = + new SdvUserImpl(creds2Tag, testCreds2, testCicsTagB, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser2); + // user3 + ICredentialsUsernamePassword testCreds3 = + new CredentialsUsernamePassword(null, user3String, password3); + SdvUserImpl newSdvUser3 = + new SdvUserImpl(creds3Tag, testCreds3, testCicsTagA, roleNameAdmin); + listOfUsersForAllRegions.add(newSdvUser3); + + Field sdvUsersToRecordList = + sdvManagerImplClass.getDeclaredField(sdvUsersToRecordListString); + sdvUsersToRecordList.setAccessible(true); + sdvUsersToRecordList.set(sdvManager, listOfUsersForAllRegions); + + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + + // Mock cicsManager + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn(regionaApplid); + Mockito.when(cicsManager.locateCicsRegion(testCicsTagA)) + .thenThrow(new CicstsManagerException("test 2")); + + ICicsRegionProvisioned mockCicsbRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsbRegion.getApplid()).thenReturn(regionbApplid); + Mockito.when(cicsManager.locateCicsRegion(testCicsTagB)).thenReturn(mockCicsbRegion); + + // Replace private cicsManager instance in sdvManager + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds1Tag, regionaApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds3Tag, regionaApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds2Tag, regionbApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(runName); + Field frameworkField = + sdvManagerImplClass.getSuperclass().getDeclaredField(frameworkString); + frameworkField.setAccessible(true); + frameworkField.set(sdvManager, framework); + + // Replace LOG + Field loggerField = sdvManagerImplClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManager, mockLog); + + // Make call to funtion under test + sdvManager.provisionStop(); + + Mockito.verify(sdvRecorder, Mockito.times(1)).endRecording(); + Mockito.verify(sdvRecorder, Mockito.times(1)).cleanUpEnvironments(); + Mockito.verifyNoMoreInteractions(sdvRecorder); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds1Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(0)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds3Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(0)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds2Tag), + Mockito.eq(regionbApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(0)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + // endRecording exception should not have stopped everything else from running, + // but it should had made a log output to make the user aware. + Mockito.verify(mockLog, Mockito.times(1)) + .error(Mockito.eq("Could not release SDV SdvUsers in provisionStop."), + Mockito.any(CicstsManagerException.class)); + } + + @Test + void testProvisionStopcleanUpEnvironmentsException() throws InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, ClassNotFoundException, SdvManagerException, + NoSuchFieldException, CredentialsException, CicstsManagerException { + // Replace private sdvRecorder instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + SdvHttpRecorderImpl sdvRecorder = Mockito.mock(SdvHttpRecorderImpl.class); + Mockito.doThrow(new SdvManagerException("test3")).when(sdvRecorder).cleanUpEnvironments(); + Field sdvRecorderField = sdvManagerImplClass.getDeclaredField(sdvRecorderVarName); + sdvRecorderField.setAccessible(true); + sdvRecorderField.set(sdvManager, sdvRecorder); + + // Replace sdvUsersToRecordList with a mocked list + List listOfUsersForAllRegions = new ArrayList<>(); + // user1 + ICredentialsUsernamePassword testCreds1 = + new CredentialsUsernamePassword(null, user1String, password1); + SdvUserImpl newSdvUser1 = + new SdvUserImpl(creds1Tag, testCreds1, testCicsTagA, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser1); + // user2 + ICredentialsUsernamePassword testCreds2 = + new CredentialsUsernamePassword(null, user2String, password2); + SdvUserImpl newSdvUser2 = + new SdvUserImpl(creds2Tag, testCreds2, testCicsTagB, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser2); + // user3 + ICredentialsUsernamePassword testCreds3 = + new CredentialsUsernamePassword(null, user3String, password3); + SdvUserImpl newSdvUser3 = + new SdvUserImpl(creds3Tag, testCreds3, testCicsTagA, roleNameAdmin); + listOfUsersForAllRegions.add(newSdvUser3); + + Field sdvUsersToRecordList = + sdvManagerImplClass.getDeclaredField(sdvUsersToRecordListString); + sdvUsersToRecordList.setAccessible(true); + sdvUsersToRecordList.set(sdvManager, listOfUsersForAllRegions); + + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + + // Mock cicsManager + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn(regionaApplid); + Mockito.when(cicsManager.locateCicsRegion(testCicsTagA)).thenReturn(mockCicsaRegion); + + ICicsRegionProvisioned mockCicsbRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsbRegion.getApplid()).thenReturn(regionbApplid); + Mockito.when(cicsManager.locateCicsRegion(testCicsTagB)).thenReturn(mockCicsbRegion); + + // Replace private cicsManager instance in sdvManager + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds1Tag, regionaApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds3Tag, regionaApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds2Tag, regionbApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(runName); + Field frameworkField = + sdvManagerImplClass.getSuperclass().getDeclaredField(frameworkString); + frameworkField.setAccessible(true); + frameworkField.set(sdvManager, framework); + + // Replace LOG + Field loggerField = sdvManagerImplClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManager, mockLog); + + // Make call to funtion under test + sdvManager.provisionStop(); + + Mockito.verify(sdvRecorder, Mockito.times(1)).endRecording(); + Mockito.verify(sdvRecorder, Mockito.times(1)).cleanUpEnvironments(); + Mockito.verifyNoMoreInteractions(sdvRecorder); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds1Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds3Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds2Tag), + Mockito.eq(regionbApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + // endRecording exception should not have stopped everything else from running, + // but it should had made a log output to make the user aware. + Mockito.verify(mockLog, Mockito.times(1)) + .error(Mockito.eq("Could not cleanup SDV environments in provisionStop."), + Mockito.any(SdvManagerException.class)); + } + + @Test + void testStartOfTestClass() throws InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, ClassNotFoundException, SdvManagerException, NoSuchFieldException { + // Replace private sdvRecorder instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + SdvHttpRecorderImpl sdvRecorder = Mockito.mock(SdvHttpRecorderImpl.class); + Field sdvRecorderField = sdvManagerImplClass.getDeclaredField(sdvRecorderVarName); + sdvRecorderField.setAccessible(true); + sdvRecorderField.set(sdvManager, sdvRecorder); + + // Make call to funtion under test + sdvManager.startOfTestClass(); + + Mockito.verify(sdvRecorder, Mockito.times(1)).startRecording(); + Mockito.verifyNoMoreInteractions(sdvRecorder); + } + + @Test + void testEndOfTestClassTestPassed() throws InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, ClassNotFoundException, NoSuchFieldException, ManagerException { + // Replace private sdvRecorder instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + SdvHttpRecorderImpl sdvRecorder = Mockito.mock(SdvHttpRecorderImpl.class); + Field sdvRecorderField = sdvManagerImplClass.getDeclaredField(sdvRecorderVarName); + sdvRecorderField.setAccessible(true); + sdvRecorderField.set(sdvManager, sdvRecorder); + + IFramework framework = Mockito.mock(IFramework.class); + IRun testRun = Mockito.mock(IRun.class); + Mockito.when(testRun.getTestBundleName()).thenReturn("bundleA"); + Mockito.when(testRun.getTestClassName()).thenReturn("classA"); + Mockito.when(framework.getTestRun()).thenReturn(testRun); + Field frameworkField = + sdvManagerImplClass.getSuperclass().getDeclaredField(frameworkString); + frameworkField.setAccessible(true); + frameworkField.set(sdvManager, framework); + + // Make call to funtion under test + Result res = Mockito.mock(Result.class); + Mockito.when(res.isPassed()).thenReturn(true); + + sdvManager.endOfTestClass(res, null); + + Mockito.verify(sdvRecorder, Mockito.times(1)).endRecording(); + Mockito.verify(sdvRecorder, Mockito.times(1)).exportRecordings("bundleA", "classA"); + Mockito.verifyNoMoreInteractions(sdvRecorder); + } + + @Test + void testEndOfTestClassTestFailed() throws InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, ClassNotFoundException, NoSuchFieldException, ManagerException { + // Replace private sdvRecorder instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + SdvHttpRecorderImpl sdvRecorder = Mockito.mock(SdvHttpRecorderImpl.class); + Field sdvRecorderField = sdvManagerImplClass.getDeclaredField(sdvRecorderVarName); + sdvRecorderField.setAccessible(true); + sdvRecorderField.set(sdvManager, sdvRecorder); + + IFramework framework = Mockito.mock(IFramework.class); + IRun testRun = Mockito.mock(IRun.class); + Mockito.when(testRun.getTestBundleName()).thenReturn("bundleB"); + Mockito.when(testRun.getTestClassName()).thenReturn("classB"); + Mockito.when(framework.getTestRun()).thenReturn(testRun); + Field frameworkField = + sdvManagerImplClass.getSuperclass().getDeclaredField(frameworkString); + frameworkField.setAccessible(true); + frameworkField.set(sdvManager, framework); + + // Make call to funtion under test + Result res = Mockito.mock(Result.class); + Mockito.when(res.isPassed()).thenReturn(false); + + sdvManager.endOfTestClass(res, null); + + Mockito.verify(sdvRecorder, Mockito.times(1)).endRecording(); + Mockito.verify(sdvRecorder, Mockito.times(0)).exportRecordings("bundleB", "classB"); + Mockito.verifyNoMoreInteractions(sdvRecorder); + } + + @Test + void testAreYouProvisionalDependentOn() throws ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException { + // Replace private sdvRecorder instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + Boolean dependent = false; + // Test ICicstsManagerSpi + IManager cicsManager = new CicstsManagerImpl(); + dependent = sdvManager.areYouProvisionalDependentOn(cicsManager); + Assertions.assertTrue(dependent); + + // Test IArtifactManager + IManager artifactManager = new ArtifactManagerImpl(); + dependent = sdvManager.areYouProvisionalDependentOn(artifactManager); + Assertions.assertTrue(dependent); + + // Test IHttpManagerSpi + IManager httpManager = new HttpManagerImpl(); + dependent = sdvManager.areYouProvisionalDependentOn(httpManager); + Assertions.assertTrue(dependent); + + // Test a random manager + IManager zosManager = new ZosManagerImpl(); + dependent = sdvManager.areYouProvisionalDependentOn(zosManager); + Assertions.assertFalse(dependent); + + } + + @Test + void testReleaseUsersException() throws CredentialsException, NoSuchFieldException, + SecurityException, IllegalArgumentException, IllegalAccessException, + ResourceUnavailableException, ManagerException, ClassNotFoundException, + InstantiationException, InvocationTargetException, NoSuchMethodException { + // Replace private sdvRecorder instance in sdvManager + Class sdvManagerImplClass = Class.forName(sdvManagerImplClassString); + SdvManagerImpl sdvManager = + (SdvManagerImpl) sdvManagerImplClass.getDeclaredConstructor().newInstance(); + + SdvHttpRecorderImpl sdvRecorder = Mockito.mock(SdvHttpRecorderImpl.class); + Field sdvRecorderField = sdvManagerImplClass.getDeclaredField(sdvRecorderVarName); + sdvRecorderField.setAccessible(true); + sdvRecorderField.set(sdvManager, sdvRecorder); + + // Replace sdvUsersToRecordList with a mocked list + List listOfUsersForAllRegions = new ArrayList<>(); + // user1 + ICredentialsUsernamePassword testCreds1 = + new CredentialsUsernamePassword(null, user1String, password1); + SdvUserImpl newSdvUser1 = + new SdvUserImpl(creds1Tag, testCreds1, testCicsTagA, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser1); + // user2 + ICredentialsUsernamePassword testCreds2 = + new CredentialsUsernamePassword(null, user2String, password2); + SdvUserImpl newSdvUser2 = + new SdvUserImpl(creds2Tag, testCreds2, testCicsTagB, roleNameTeller); + listOfUsersForAllRegions.add(newSdvUser2); + // user3 + ICredentialsUsernamePassword testCreds3 = + new CredentialsUsernamePassword(null, user3String, password3); + SdvUserImpl newSdvUser3 = + new SdvUserImpl(creds3Tag, testCreds3, testCicsTagA, roleNameAdmin); + listOfUsersForAllRegions.add(newSdvUser3); + + Field sdvUsersToRecordList = + sdvManagerImplClass.getDeclaredField(sdvUsersToRecordListString); + sdvUsersToRecordList.setAccessible(true); + sdvUsersToRecordList.set(sdvManager, listOfUsersForAllRegions); + + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Field dssField = sdvManagerImplClass.getDeclaredField("dss"); + dssField.setAccessible(true); + dssField.set(sdvManager, dssService); + + // Mock cicsManager + ICicstsManagerSpi cicsManager = Mockito.mock(ICicstsManagerSpi.class); + + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn(regionaApplid); + Mockito.when(cicsManager.locateCicsRegion(testCicsTagA)).thenReturn(mockCicsaRegion); + + ICicsRegionProvisioned mockCicsbRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsbRegion.getApplid()).thenReturn(regionbApplid); + Mockito.when(cicsManager.locateCicsRegion(testCicsTagB)).thenReturn(mockCicsbRegion); + + // Replace private cicsManager instance in sdvManager + Field cicsManagerField = + sdvManagerImplClass.getDeclaredField(privateCicsManagerVariableName); + cicsManagerField.setAccessible(true); + cicsManagerField.set(sdvManager, cicsManager); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds1Tag, regionaApplid, runName, dssService)) + .thenThrow(new DynamicStatusStoreException("could not delete")); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds3Tag, regionaApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + sdvUserPoolStatic + .when(() -> SdvUserPool.deleteDss(creds2Tag, regionbApplid, runName, dssService)) + .thenAnswer(invocation -> { + return null; + }); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn(runName); + Field frameworkField = + sdvManagerImplClass.getSuperclass().getDeclaredField(frameworkString); + frameworkField.setAccessible(true); + frameworkField.set(sdvManager, framework); + + // Replace LOG + Field loggerField = sdvManagerImplClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManager, mockLog); + + // Make call to funtion under test + sdvManager.provisionStop(); + + Mockito.verify(sdvRecorder, Mockito.times(1)).endRecording(); + Mockito.verify(sdvRecorder, Mockito.times(1)).cleanUpEnvironments(); + Mockito.verifyNoMoreInteractions(sdvRecorder); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds1Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds3Tag), + Mockito.eq(regionaApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(creds2Tag), + Mockito.eq(regionbApplid), Mockito.eq(runName), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + Mockito.verify(mockLog, Mockito.times(1)) + .error(Mockito.eq("Could not release SDV User: " + creds1Tag + ", on CICS region " + + regionaApplid + ", for test run " + runName), + Mockito.any(DynamicStatusStoreException.class)); + + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvManagersResourceMonitor.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvManagersResourceMonitor.java new file mode 100644 index 000000000..e4d441276 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvManagersResourceMonitor.java @@ -0,0 +1,460 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.framework.spi.DynamicStatusStoreException; +import dev.galasa.framework.spi.FrameworkException; +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.IFrameworkRuns; +import dev.galasa.framework.spi.IResourceManagement; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.apache.commons.logging.Log; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + + +class TestSdvManagersResourceMonitor { + + private String runningManagersPrefixString = "manager.runningManagers"; + private String sdvManagersResourceMonitorClassString = + "dev.galasa.sdv.internal.SdvManagersResourceMonitor"; + private String logString = "LOG"; + private String modifiersString = "modifiers"; + + private String runOneString = "RUN1"; + private String runTwoString = "RUN2"; + private String runThreeString = "RUN3"; + private String runningManagersApplid1 = "manager.runningManagers.APPL1"; + private String runningManagersApplid2 = "manager.runningManagers.APPL2"; + + @SuppressWarnings("PMD") + private static final Log mockLog = Mockito.mock(Log.class); + + @BeforeEach + public void setUp() { + Mockito.reset(mockLog); + Mockito.when(mockLog.isInfoEnabled()).thenReturn(true); + Mockito.when(mockLog.isWarnEnabled()).thenReturn(true); + Mockito.when(mockLog.isErrorEnabled()).thenReturn(true); + Mockito.when(mockLog.isTraceEnabled()).thenReturn(true); + Mockito.when(mockLog.isDebugEnabled()).thenReturn(true); + } + + @Test + void testRunWithNoActiveRunsOrDssEntries() + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, FrameworkException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + IFrameworkRuns frameworkRuns = Mockito.mock(IFrameworkRuns.class); + + Set allActiveRuns = new HashSet(); + Mockito.when(frameworkRuns.getActiveRunNames()).thenReturn(allActiveRuns); + + Mockito.when(framework.getFrameworkRuns()).thenReturn(frameworkRuns); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map runningManagersInDss = new HashMap<>(); + Mockito.when(dssService.getPrefix(runningManagersPrefixString)) + .thenReturn(runningManagersInDss); + + // Get SdvUserResourceMonitor instance + Class sdvManagersResourceMonitorClass = + Class.forName(sdvManagersResourceMonitorClassString); + SdvManagersResourceMonitor sdvManagersResourceMonitor = + (SdvManagersResourceMonitor) sdvManagersResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvManagersResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManagersResourceMonitor, mockLog); + + // Make call to funtion under test + sdvManagersResourceMonitor.run(); + + Mockito.verify(dssService, Mockito.times(0)).delete(Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(0)).put(Mockito.any(String.class), + Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(0)).performActions(Mockito.any()); + } + + @Test + void testRunWithActiveRunsMatchingDssEntries() + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, FrameworkException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + IFrameworkRuns frameworkRuns = Mockito.mock(IFrameworkRuns.class); + + Set allActiveRuns = new HashSet(); + allActiveRuns.add(runOneString); + allActiveRuns.add(runTwoString); + allActiveRuns.add(runThreeString); + Mockito.when(frameworkRuns.getActiveRunNames()).thenReturn(allActiveRuns); + + Mockito.when(framework.getFrameworkRuns()).thenReturn(frameworkRuns); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map runningManagersInDss = new HashMap<>(); + runningManagersInDss.put(runningManagersApplid1, runOneString + "," + runTwoString); + runningManagersInDss.put(runningManagersApplid2, runThreeString); + Mockito.when(dssService.getPrefix(runningManagersPrefixString)) + .thenReturn(runningManagersInDss); + + // Get SdvUserResourceMonitor instance + Class sdvManagersResourceMonitorClass = + Class.forName(sdvManagersResourceMonitorClassString); + SdvManagersResourceMonitor sdvManagersResourceMonitor = + (SdvManagersResourceMonitor) sdvManagersResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvManagersResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManagersResourceMonitor, mockLog); + + // Make call to funtion under test + sdvManagersResourceMonitor.run(); + + Mockito.verify(dssService, Mockito.times(0)).delete(Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(0)).put(Mockito.any(String.class), + Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(0)).performActions(Mockito.any()); + } + + @Test + void testRunException() + throws DynamicStatusStoreException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.getPrefix(runningManagersPrefixString)) + .thenThrow(new DynamicStatusStoreException("cannot read store")); + + // Get SdvUserResourceMonitor instance + Class sdvManagersResourceMonitorClass = + Class.forName(sdvManagersResourceMonitorClassString); + SdvManagersResourceMonitor sdvManagersResourceMonitor = + (SdvManagersResourceMonitor) sdvManagersResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvManagersResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManagersResourceMonitor, mockLog); + + // Make call to funtion under test + sdvManagersResourceMonitor.run(); + + Mockito.verify(dssService, Mockito.times(0)).delete(Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(0)).put(Mockito.any(String.class), + Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(0)).performActions(Mockito.any()); + + // Verify that although an exception occurred, the program continues, and simply logs + // an error to the log. + Mockito.verify(mockLog, Mockito.times(1)) + .error("Failure during scanning DSS for SDV Managers"); + } + + @Test + void testRunWithDssEntryNotInActiveRunsButNotLastManagerOnRegion() + throws FrameworkException, ClassNotFoundException, NoSuchFieldException, + SecurityException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + IFrameworkRuns frameworkRuns = Mockito.mock(IFrameworkRuns.class); + + Set allActiveRuns = new HashSet(); + allActiveRuns.add(runTwoString); + allActiveRuns.add(runThreeString); + Mockito.when(frameworkRuns.getActiveRunNames()).thenReturn(allActiveRuns); + + Mockito.when(framework.getFrameworkRuns()).thenReturn(frameworkRuns); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map runningManagersInDss = new HashMap<>(); + runningManagersInDss.put(runningManagersApplid1, runOneString + "," + runTwoString); + runningManagersInDss.put(runningManagersApplid2, runThreeString); + Mockito.when(dssService.getPrefix(runningManagersPrefixString)) + .thenReturn(runningManagersInDss); + Mockito.when(dssService.get(runningManagersApplid1)) + .thenReturn(runOneString + "," + runTwoString); + Mockito.when(dssService.get(runningManagersApplid2)).thenReturn(runThreeString); + + // Get SdvUserResourceMonitor instance + Class sdvManagersResourceMonitorClass = + Class.forName(sdvManagersResourceMonitorClassString); + SdvManagersResourceMonitor sdvManagersResourceMonitor = + (SdvManagersResourceMonitor) sdvManagersResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvManagersResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManagersResourceMonitor, mockLog); + + // Make call to funtion under test + sdvManagersResourceMonitor.run(); + + Mockito.verify(dssService, Mockito.times(0)).delete(Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(1)).put(runningManagersApplid1, runTwoString); + Mockito.verify(dssService, Mockito.times(0)).performActions(Mockito.any()); + } + + @Test + void testRunWithDssEntryNotInActiveRunsButIsLastManagerOnRegion() + throws FrameworkException, ClassNotFoundException, NoSuchFieldException, + SecurityException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + IFrameworkRuns frameworkRuns = Mockito.mock(IFrameworkRuns.class); + + Set allActiveRuns = new HashSet(); + allActiveRuns.add(runOneString); + allActiveRuns.add(runTwoString); + Mockito.when(frameworkRuns.getActiveRunNames()).thenReturn(allActiveRuns); + + Mockito.when(framework.getFrameworkRuns()).thenReturn(frameworkRuns); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map runningManagersInDss = new HashMap<>(); + runningManagersInDss.put(runningManagersApplid1, runOneString + "," + runTwoString); + runningManagersInDss.put(runningManagersApplid2, runThreeString); + Mockito.when(dssService.getPrefix(runningManagersPrefixString)) + .thenReturn(runningManagersInDss); + Mockito.when(dssService.get(runningManagersApplid2)).thenReturn(runThreeString); + + // Get SdvUserResourceMonitor instance + Class sdvManagersResourceMonitorClass = + Class.forName(sdvManagersResourceMonitorClassString); + SdvManagersResourceMonitor sdvManagersResourceMonitor = + (SdvManagersResourceMonitor) sdvManagersResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvManagersResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManagersResourceMonitor, mockLog); + + // Make call to funtion under test + sdvManagersResourceMonitor.run(); + + Mockito.verify(dssService, Mockito.times(0)).delete(Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(0)).put(Mockito.any(String.class), + Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(1)).performActions(Mockito.any(), Mockito.any()); + } + + @Test + void testrunFinishedOrDeletedIsLastManagerOnRegion() + throws FrameworkException, ClassNotFoundException, NoSuchFieldException, + SecurityException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map runningManagersInDss = new HashMap<>(); + runningManagersInDss.put(runningManagersApplid1, runOneString + "," + runTwoString); + runningManagersInDss.put(runningManagersApplid2, runThreeString); + Mockito.when(dssService.getPrefix(runningManagersPrefixString)) + .thenReturn(runningManagersInDss); + Mockito.when(dssService.get(runningManagersApplid1)) + .thenReturn(runOneString + "," + runTwoString); + Mockito.when(dssService.get(runningManagersApplid2)).thenReturn(runThreeString); + + // Get SdvUserResourceMonitor instance + Class sdvManagersResourceMonitorClass = + Class.forName(sdvManagersResourceMonitorClassString); + SdvManagersResourceMonitor sdvManagersResourceMonitor = + (SdvManagersResourceMonitor) sdvManagersResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvManagersResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManagersResourceMonitor, mockLog); + + // Make call to funtion under test + sdvManagersResourceMonitor.runFinishedOrDeleted(runOneString); + + Mockito.verify(dssService, Mockito.times(0)).delete(Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(1)).put(runningManagersApplid1, runTwoString); + Mockito.verify(dssService, Mockito.times(0)).performActions(Mockito.any()); + } + + @Test + void testrunFinishedOrDeletedNotLastManagerOnRegion() + throws FrameworkException, ClassNotFoundException, NoSuchFieldException, + SecurityException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map runningManagersInDss = new HashMap<>(); + runningManagersInDss.put(runningManagersApplid1, runOneString + "," + runTwoString); + runningManagersInDss.put(runningManagersApplid2, runThreeString); + Mockito.when(dssService.getPrefix(runningManagersPrefixString)) + .thenReturn(runningManagersInDss); + Mockito.when(dssService.get(runningManagersApplid2)).thenReturn(runThreeString); + + // Get SdvUserResourceMonitor instance + Class sdvManagersResourceMonitorClass = + Class.forName(sdvManagersResourceMonitorClassString); + SdvManagersResourceMonitor sdvManagersResourceMonitor = + (SdvManagersResourceMonitor) sdvManagersResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvManagersResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManagersResourceMonitor, mockLog); + + // Make call to funtion under test + sdvManagersResourceMonitor.runFinishedOrDeleted(runThreeString); + + Mockito.verify(dssService, Mockito.times(0)).delete(Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(0)).put(Mockito.any(String.class), + Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(1)).performActions(Mockito.any(), Mockito.any()); + } + + @Test + void testrunFinishedOrDeletedException() + throws DynamicStatusStoreException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, NoSuchFieldException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.when(dssService.getPrefix(runningManagersPrefixString)) + .thenThrow(new DynamicStatusStoreException("cannot read store")); + + // Get SdvUserResourceMonitor instance + Class sdvManagersResourceMonitorClass = + Class.forName(sdvManagersResourceMonitorClassString); + SdvManagersResourceMonitor sdvManagersResourceMonitor = + (SdvManagersResourceMonitor) sdvManagersResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvManagersResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvManagersResourceMonitor, mockLog); + + // Make call to funtion under test + sdvManagersResourceMonitor.runFinishedOrDeleted(runOneString); + + Mockito.verify(dssService, Mockito.times(0)).delete(Mockito.any(String.class)); + Mockito.verify(dssService, Mockito.times(0)).put(runningManagersApplid1, runTwoString); + Mockito.verify(dssService, Mockito.times(0)).performActions(Mockito.any()); + + // Verify that although an exception occurred, the program continues, and simply logs + // an error to the log. + Mockito.verify(mockLog, Mockito.times(1)) + .error("Failure cleaning up SDV Managers for finished run RUN1"); + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvResourceManagement.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvResourceManagement.java new file mode 100644 index 000000000..f4dd85ccc --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvResourceManagement.java @@ -0,0 +1,135 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.framework.spi.DynamicStatusStoreException; +import dev.galasa.framework.spi.FrameworkException; +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.IResourceManagement; +import dev.galasa.framework.spi.ResourceManagerException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.util.Random; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + + +class TestSdvResourceManagement { + + private String sdvResourceManagementClassString = + "dev.galasa.sdv.internal.SdvResourceManagement"; + + @Test + void testStart() throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, FrameworkException, ResourceManagerException { + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getDynamicStatusStoreService("sdv")).thenReturn(dssService); + Random randomNum = Mockito.mock(Random.class); + Mockito.when(randomNum.nextInt()).thenReturn(16); + Mockito.when(framework.getRandom()).thenReturn(randomNum); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + ScheduledExecutorService exeService = Mockito.mock(ScheduledExecutorService.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(exeService).scheduleWithFixedDelay(Mockito.any(SdvUserResourceMonitor.class), + Mockito.any(int.class), Mockito.eq(20), Mockito.eq(TimeUnit.SECONDS)); + Mockito.doAnswer(invocation -> { + return null; + }).when(exeService).scheduleWithFixedDelay(Mockito.any(SdvManagersResourceMonitor.class), + Mockito.any(int.class), Mockito.eq(20), Mockito.eq(TimeUnit.SECONDS)); + Mockito.when(resMan.getScheduledExecutorService()).thenReturn(exeService); + + // Get SdvUserResourceMonitor instance + Class sdvResourceManagementClass = Class.forName(sdvResourceManagementClassString); + SdvResourceManagement sdvResourceManagement = + (SdvResourceManagement) sdvResourceManagementClass.getDeclaredConstructor() + .newInstance(); + + Boolean initialised = sdvResourceManagement.initialise(framework, resMan); + Assertions.assertTrue(initialised); + + // Make call to funtion under test + sdvResourceManagement.start(); + + Mockito.verify(exeService, Mockito.times(1)).scheduleWithFixedDelay( + Mockito.any(SdvUserResourceMonitor.class), Mockito.any(long.class), + Mockito.any(long.class), Mockito.eq(TimeUnit.SECONDS)); + + Mockito.verify(exeService, Mockito.times(1)).scheduleWithFixedDelay( + Mockito.any(SdvManagersResourceMonitor.class), Mockito.any(long.class), + Mockito.any(long.class), Mockito.eq(TimeUnit.SECONDS)); + } + + @Test + void testRunFinishedOrDeleted() throws ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, ResourceManagerException, + DynamicStatusStoreException, NoSuchFieldException { + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getDynamicStatusStoreService("sdv")).thenReturn(dssService); + Random randomNum = Mockito.mock(Random.class); + Mockito.when(randomNum.nextInt()).thenReturn(16); + Mockito.when(framework.getRandom()).thenReturn(randomNum); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + ScheduledExecutorService exeService = Mockito.mock(ScheduledExecutorService.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(exeService).scheduleWithFixedDelay(Mockito.any(SdvUserResourceMonitor.class), + Mockito.any(int.class), Mockito.eq(20), Mockito.eq(TimeUnit.SECONDS)); + Mockito.doAnswer(invocation -> { + return null; + }).when(exeService).scheduleWithFixedDelay(Mockito.any(SdvManagersResourceMonitor.class), + Mockito.any(int.class), Mockito.eq(20), Mockito.eq(TimeUnit.SECONDS)); + Mockito.when(resMan.getScheduledExecutorService()).thenReturn(exeService); + + // Get SdvUserResourceMonitor instance + Class sdvResourceManagementClass = Class.forName(sdvResourceManagementClassString); + SdvResourceManagement sdvResourceManagement = + (SdvResourceManagement) sdvResourceManagementClass.getDeclaredConstructor() + .newInstance(); + + Boolean initialised = sdvResourceManagement.initialise(framework, resMan); + Assertions.assertTrue(initialised); + + // Replace the monitors + SdvUserResourceMonitor userResMon = Mockito.mock(SdvUserResourceMonitor.class); + SdvManagersResourceMonitor manResMon = Mockito.mock(SdvManagersResourceMonitor.class); + + Field sdvUserResourceMonitorField = + sdvResourceManagementClass.getDeclaredField("sdvUserResourceMonitor"); + sdvUserResourceMonitorField.setAccessible(true); + sdvUserResourceMonitorField.set(sdvResourceManagement, userResMon); + + Field sdvManagersResourceMonitorField = + sdvResourceManagementClass.getDeclaredField("sdvManagersResourceMonitor"); + sdvManagersResourceMonitorField.setAccessible(true); + sdvManagersResourceMonitorField.set(sdvResourceManagement, manResMon); + + // Make call to funtion under test + sdvResourceManagement.runFinishedOrDeleted("RUN123"); + + Mockito.verify(userResMon, Mockito.times(1)).runFinishedOrDeleted("RUN123"); + Mockito.verify(manResMon, Mockito.times(1)).runFinishedOrDeleted("RUN123"); + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserImpl.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserImpl.java new file mode 100644 index 000000000..5d2c6cf19 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserImpl.java @@ -0,0 +1,71 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.ICredentialsUsernamePassword; +import dev.galasa.framework.spi.creds.CredentialsException; +import dev.galasa.framework.spi.creds.CredentialsUsernamePassword; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class TestSdvUserImpl { + + SdvUserImpl ru; + + private static final String TEST_SRR_ID = "1234"; + + @BeforeEach + void beforeEach() throws CredentialsException { + ICredentialsUsernamePassword credentials = + new CredentialsUsernamePassword(null, "user1", "password1"); + ru = new SdvUserImpl("CREDS1", credentials, "CICS1", "TELLER"); + } + + @Test + void testGetCredentials() { + Assertions.assertEquals("CREDS1", ru.getCredentialsTag()); + + Assertions.assertEquals("user1", ru.getUsername()); + Assertions.assertEquals("password1", ru.getPassword()); + } + + @Test + void testGetRole() { + Assertions.assertEquals("TELLER", ru.getRole()); + } + + @Test + void testGetSrrIdAndIsRecordingWhenNotSet() { + Assertions.assertEquals(null, ru.getSrrId()); + Assertions.assertEquals(false, ru.isRecording()); + } + + @Test + void testGetSrrIdAndIsRecordingWhenSet() { + + ru.setSrrId(TEST_SRR_ID); + + Assertions.assertEquals(TEST_SRR_ID, ru.getSrrId()); + Assertions.assertEquals(true, ru.isRecording()); + } + + @Test + void testSetNotRecording() { + + ru.setSrrId(TEST_SRR_ID); + ru.setNotRecording(); + + Assertions.assertEquals(TEST_SRR_ID, ru.getSrrId()); + Assertions.assertEquals(false, ru.isRecording()); + } + + @Test + void testgetCicsTag() { + Assertions.assertEquals("CICS1", ru.getCicsTag()); + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserPool.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserPool.java new file mode 100644 index 000000000..d31a8a923 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserPool.java @@ -0,0 +1,328 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.cicsts.spi.ICicsRegionProvisioned; +import dev.galasa.framework.spi.DssDelete; +import dev.galasa.framework.spi.DynamicStatusStoreException; +import dev.galasa.framework.spi.DynamicStatusStoreMatchException; +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.IResourcePoolingService; +import dev.galasa.framework.spi.InsufficientResourcesAvailableException; +import dev.galasa.framework.spi.ResourceUnavailableException; +import dev.galasa.sdv.SdvManagerException; +import dev.galasa.sdv.internal.properties.SdvPoolUsers; +import dev.galasa.zos.IZosImage; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.logging.Log; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + + +class TestSdvUserPool { + + private MockedStatic sdvPoolUsers; + + private String roleName = "TELLER"; + private String zosImageId = "IMG1"; + private String applidString = "APPL1"; + private String sdvUserPoolClassString = "dev.galasa.sdv.internal.SdvUserPool"; + private String dssVariableString = "dss"; + + @SuppressWarnings("PMD") + private static final Log mockLog = Mockito.mock(Log.class); + + @BeforeEach + public void setUp() { + // Registering static mocks before each test + sdvPoolUsers = Mockito.mockStatic(SdvPoolUsers.class); + + Mockito.when(mockLog.isTraceEnabled()).thenReturn(true); + } + + @AfterEach + public void tearDown() { + // Closing static mocks after each test + sdvPoolUsers.close(); + } + + @Test + void testAllocateUser() throws SdvManagerException, ResourceUnavailableException, + InstantiationException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException, NoSuchMethodException, SecurityException, + InsufficientResourcesAvailableException, NoSuchFieldException, ClassNotFoundException, + DynamicStatusStoreMatchException, DynamicStatusStoreException { + // Mock IZosImage + IZosImage mockZosImage = Mockito.mock(IZosImage.class); + Mockito.when(mockZosImage.getImageID()).thenReturn(zosImageId); + + // Mock CICS region + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getZosImage()).thenReturn(mockZosImage); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn(applidString); + + // Mocks for statics + List userCredList = new ArrayList<>(); + userCredList.add("CREDS11"); + userCredList.add("CREDS22"); + userCredList.add("CREDS33"); + sdvPoolUsers.when(() -> SdvPoolUsers.get(zosImageId, roleName)).thenReturn(userCredList); + + // Get SdvUserPool instance + Class sdvUserPoolClass = Class.forName(sdvUserPoolClassString); + SdvUserPool sdvUserPool = + (SdvUserPool) sdvUserPoolClass.getDeclaredConstructor(IFramework.class, + IDynamicStatusStoreService.class, IResourcePoolingService.class) + .newInstance(null, null, null); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).performActions(Mockito.any()); + Field dssField = sdvUserPoolClass.getDeclaredField(dssVariableString); + dssField.setAccessible(true); + dssField.set(sdvUserPool, dssService); + + // Mock rps + List allocatedUserCredList = new ArrayList<>(); + allocatedUserCredList.add("CREDS33"); + IResourcePoolingService resourcePoolingService = + Mockito.mock(IResourcePoolingService.class); + Mockito.when(resourcePoolingService.obtainResources(userCredList, null, 1, 1, dssService, + "sdvuser.APPL1.")).thenReturn(allocatedUserCredList); + Field rpsField = sdvUserPoolClass.getDeclaredField("rps"); + rpsField.setAccessible(true); + rpsField.set(sdvUserPool, resourcePoolingService); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn("RUN123"); + Field frameworkField = sdvUserPoolClass.getDeclaredField("framework"); + frameworkField.setAccessible(true); + frameworkField.set(sdvUserPool, framework); + + // Replace LOG + Field loggerField = sdvUserPoolClass.getDeclaredField("LOG"); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvUserPool, mockLog); + + // Make call to funtion under test + String userCred = sdvUserPool.allocateUser(roleName, mockCicsaRegion); + + Assertions.assertEquals("CREDS33", userCred); + + // Check there is a warning in the log indicating Region A won't record + Mockito.verify(mockLog, Mockito.times(1)).trace("Allocated SDV User CREDS33 on image " + + zosImageId + " for CICS Applid APPL1 from SDV User pool allocation"); + } + + @Test + void testNoUsersFoundForRoleOnImage() + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, SdvManagerException, ResourceUnavailableException { + // Mock IZosImage + IZosImage mockZosImage = Mockito.mock(IZosImage.class); + Mockito.when(mockZosImage.getImageID()).thenReturn(zosImageId); + + // Mock CICS region + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getZosImage()).thenReturn(mockZosImage); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn(applidString); + + // Mocks for statics + List userCredList = new ArrayList<>(); + sdvPoolUsers.when(() -> SdvPoolUsers.get(zosImageId, roleName)).thenReturn(userCredList); + + // Get SdvUserPool instance + Class sdvUserPoolClass = Class.forName(sdvUserPoolClassString); + SdvUserPool sdvUserPool = + (SdvUserPool) sdvUserPoolClass.getDeclaredConstructor(IFramework.class, + IDynamicStatusStoreService.class, IResourcePoolingService.class) + .newInstance(null, null, null); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvUserPool.allocateUser(roleName, mockCicsaRegion); + }); + + Assertions.assertEquals( + "No user credential tags provided for role '" + roleName + "' on z/OS image '" + + zosImageId + "'. Please create or update CPS property 'sdv.zosImage." + + zosImageId + ".role." + roleName + ".credTags'.", + exception.getMessage()); + } + + @Test + void testNoResourcesAvailable() + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, DynamicStatusStoreMatchException, DynamicStatusStoreException, + NoSuchFieldException, InsufficientResourcesAvailableException { + // Mock IZosImage + IZosImage mockZosImage = Mockito.mock(IZosImage.class); + Mockito.when(mockZosImage.getImageID()).thenReturn(zosImageId); + + // Mock CICS region + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getZosImage()).thenReturn(mockZosImage); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn(applidString); + + // Mocks for statics + List userCredList = new ArrayList<>(); + userCredList.add("CREDS44"); + userCredList.add("CREDS55"); + userCredList.add("CREDS66"); + sdvPoolUsers.when(() -> SdvPoolUsers.get(zosImageId, roleName)).thenReturn(userCredList); + + // Get SdvUserPool instance + Class sdvUserPoolClass = Class.forName(sdvUserPoolClassString); + SdvUserPool sdvUserPool = + (SdvUserPool) sdvUserPoolClass.getDeclaredConstructor(IFramework.class, + IDynamicStatusStoreService.class, IResourcePoolingService.class) + .newInstance(null, null, null); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService).performActions(Mockito.any()); + Field dssField = sdvUserPoolClass.getDeclaredField(dssVariableString); + dssField.setAccessible(true); + dssField.set(sdvUserPool, dssService); + + // Mock rps + List allocatedUserCredList = new ArrayList<>(); + allocatedUserCredList.add("CREDS66"); + IResourcePoolingService resourcePoolingService = + Mockito.mock(IResourcePoolingService.class); + Mockito.when(resourcePoolingService.obtainResources(userCredList, null, 1, 1, dssService, + "sdvuser.APPL1.")) + .thenThrow(new InsufficientResourcesAvailableException("No Users")); + Field rpsField = sdvUserPoolClass.getDeclaredField("rps"); + rpsField.setAccessible(true); + rpsField.set(sdvUserPool, resourcePoolingService); + + // Make call to funtion under test + ResourceUnavailableException exception = + Assertions.assertThrows(ResourceUnavailableException.class, () -> { + sdvUserPool.allocateUser(roleName, mockCicsaRegion); + }); + + Assertions.assertEquals("No Users", exception.getMessage()); + } + + @Test + void testDssError() + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, DynamicStatusStoreMatchException, DynamicStatusStoreException, + NoSuchFieldException, InsufficientResourcesAvailableException { + // Mock IZosImage + IZosImage mockZosImage = Mockito.mock(IZosImage.class); + Mockito.when(mockZosImage.getImageID()).thenReturn(zosImageId); + + // Mock CICS region + ICicsRegionProvisioned mockCicsaRegion = Mockito.mock(ICicsRegionProvisioned.class); + Mockito.when(mockCicsaRegion.getZosImage()).thenReturn(mockZosImage); + Mockito.when(mockCicsaRegion.getApplid()).thenReturn(applidString); + + // Mocks for statics + List userCredList = new ArrayList<>(); + userCredList.add("CREDS77"); + userCredList.add("CREDS88"); + userCredList.add("CREDS99"); + sdvPoolUsers.when(() -> SdvPoolUsers.get(zosImageId, roleName)).thenReturn(userCredList); + + // Get SdvUserPool instance + Class sdvUserPoolClass = Class.forName(sdvUserPoolClassString); + SdvUserPool sdvUserPool = + (SdvUserPool) sdvUserPoolClass.getDeclaredConstructor(IFramework.class, + IDynamicStatusStoreService.class, IResourcePoolingService.class) + .newInstance(null, null, null); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.doThrow(new DynamicStatusStoreException("something went wrong")).when(dssService) + .performActions(Mockito.any(), Mockito.any()); + Field dssField = sdvUserPoolClass.getDeclaredField(dssVariableString); + dssField.setAccessible(true); + dssField.set(sdvUserPool, dssService); + + // Mock rps + List allocatedUserCredList = new ArrayList<>(); + allocatedUserCredList.add("CREDS99"); + IResourcePoolingService resourcePoolingService = + Mockito.mock(IResourcePoolingService.class); + Mockito.when(resourcePoolingService.obtainResources(userCredList, null, 1, 1, dssService, + "sdvuser.APPL1.")).thenReturn(allocatedUserCredList); + Field rpsField = sdvUserPoolClass.getDeclaredField("rps"); + rpsField.setAccessible(true); + rpsField.set(sdvUserPool, resourcePoolingService); + + IFramework framework = Mockito.mock(IFramework.class); + Mockito.when(framework.getTestRunName()).thenReturn("RUN123"); + Field frameworkField = sdvUserPoolClass.getDeclaredField("framework"); + frameworkField.setAccessible(true); + frameworkField.set(sdvUserPool, framework); + + // Make call to funtion under test + SdvManagerException exception = Assertions.assertThrows(SdvManagerException.class, () -> { + sdvUserPool.allocateUser(roleName, mockCicsaRegion); + }); + + Assertions.assertEquals( + "Could not update the DSS for user allocation of SDV User CREDS99 on image " + + zosImageId, + exception.getMessage()); + } + + @Test + void testDeleteDss() + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, DynamicStatusStoreMatchException, DynamicStatusStoreException, + NoSuchFieldException, InsufficientResourcesAvailableException { + // Get SdvUserPool instance + Class sdvUserPoolClass = Class.forName(sdvUserPoolClassString); + SdvUserPool sdvUserPool = + (SdvUserPool) sdvUserPoolClass.getDeclaredConstructor(IFramework.class, + IDynamicStatusStoreService.class, IResourcePoolingService.class) + .newInstance(null, null, null); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Mockito.doAnswer(invocation -> { + return null; + }).when(dssService) + .performActions(Mockito.any(DssDelete.class), Mockito.any(DssDelete.class)); + Field dssField = sdvUserPoolClass.getDeclaredField(dssVariableString); + dssField.setAccessible(true); + dssField.set(sdvUserPool, dssService); + + // Make call to funtion under test + sdvUserPool.deleteDss("user1", "APPL1", "RUN123", dssService); + + // Ensure perform action is called, with 2x dss entries to delete + Mockito.verify(dssService, Mockito.times(1)) + .performActions(Mockito.any(DssDelete.class), Mockito.any(DssDelete.class)); + + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserResourceMonitor.java b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserResourceMonitor.java new file mode 100644 index 000000000..991dc141b --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/java/dev/galasa/sdv/internal/TestSdvUserResourceMonitor.java @@ -0,0 +1,440 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.sdv.internal; + +import dev.galasa.framework.spi.DynamicStatusStoreException; +import dev.galasa.framework.spi.DynamicStatusStoreMatchException; +import dev.galasa.framework.spi.FrameworkException; +import dev.galasa.framework.spi.IDynamicStatusStoreService; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.IFrameworkRuns; +import dev.galasa.framework.spi.IResourceManagement; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.apache.commons.logging.Log; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + + +class TestSdvUserResourceMonitor { + + private MockedStatic sdvUserPoolStatic; + + private String sdvUserString = "sdvuser"; + private String sdvUserResourceMonitorClassString = + "dev.galasa.sdv.internal.SdvUserResourceMonitor"; + private String logString = "LOG"; + private String modifiersString = "modifiers"; + + private String dssEntryUser1RegionA = "sdvuser.APPL1.USER1"; + private String dssEntryUser2RegionA = "sdvuser.APPL1.USER2"; + private String dssEntryUser1RegionB = "sdvuser.APPL2.USER1"; + private String runThreeString = "RUN3"; + private String runFourString = "RUN4"; + private String user1String = "USER1"; + private String user2String = "USER2"; + + @SuppressWarnings("PMD") + private static final Log mockLog = Mockito.mock(Log.class); + + @BeforeEach + public void setUp() { + // Registering static mocks before each test + sdvUserPoolStatic = Mockito.mockStatic(SdvUserPool.class); + + Mockito.reset(mockLog); + Mockito.when(mockLog.isInfoEnabled()).thenReturn(true); + Mockito.when(mockLog.isWarnEnabled()).thenReturn(true); + Mockito.when(mockLog.isErrorEnabled()).thenReturn(true); + Mockito.when(mockLog.isTraceEnabled()).thenReturn(true); + Mockito.when(mockLog.isDebugEnabled()).thenReturn(true); + } + + @AfterEach + public void tearDown() { + // Closing static mocks after each test + sdvUserPoolStatic.close(); + } + + @Test + void testRunWithNoActiveRunsOrDssEntries() + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, FrameworkException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + IFrameworkRuns frameworkRuns = Mockito.mock(IFrameworkRuns.class); + + Set allActiveRuns = new HashSet(); + Mockito.when(frameworkRuns.getActiveRunNames()).thenReturn(allActiveRuns); + + Mockito.when(framework.getFrameworkRuns()).thenReturn(frameworkRuns); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map sdvUsersInDss = new HashMap<>(); + Mockito.when(dssService.getPrefix(sdvUserString)).thenReturn(sdvUsersInDss); + + // Get SdvUserResourceMonitor instance + Class sdvUserResourceMonitorClass = Class.forName(sdvUserResourceMonitorClassString); + SdvUserResourceMonitor sdvUserResourceMonitor = + (SdvUserResourceMonitor) sdvUserResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvUserResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvUserResourceMonitorClass, mockLog); + + // Make call to funtion under test + sdvUserResourceMonitor.run(); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()), Mockito.times(0)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + Assertions.assertTrue(true); + } + + @Test + void testRunWithActiveRunsMatchingDssEntries() + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, + SecurityException, NoSuchFieldException, FrameworkException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + IFrameworkRuns frameworkRuns = Mockito.mock(IFrameworkRuns.class); + + Set allActiveRuns = new HashSet(); + allActiveRuns.add("RUN1"); + allActiveRuns.add("RUN2"); + Mockito.when(frameworkRuns.getActiveRunNames()).thenReturn(allActiveRuns); + + Mockito.when(framework.getFrameworkRuns()).thenReturn(frameworkRuns); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map sdvUsersInDss = new HashMap<>(); + sdvUsersInDss.put(dssEntryUser1RegionA, "RUN1"); + sdvUsersInDss.put(dssEntryUser2RegionA, "RUN1"); + sdvUsersInDss.put(dssEntryUser1RegionB, "RUN2"); + Mockito.when(dssService.getPrefix(sdvUserString)).thenReturn(sdvUsersInDss); + + // Get SdvUserResourceMonitor instance + Class sdvUserResourceMonitorClass = Class.forName(sdvUserResourceMonitorClassString); + SdvUserResourceMonitor sdvUserResourceMonitor = + (SdvUserResourceMonitor) sdvUserResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvUserResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvUserResourceMonitorClass, mockLog); + + // Make call to funtion under test + sdvUserResourceMonitor.run(); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any()), Mockito.times(0)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + Assertions.assertTrue(true); + } + + @Test + void testRunWithDssEntriesNotInActiveRuns() throws FrameworkException, ClassNotFoundException, + NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + IFrameworkRuns frameworkRuns = Mockito.mock(IFrameworkRuns.class); + + Set allActiveRuns = new HashSet(); + allActiveRuns.add(runFourString); + Mockito.when(frameworkRuns.getActiveRunNames()).thenReturn(allActiveRuns); + + Mockito.when(framework.getFrameworkRuns()).thenReturn(frameworkRuns); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map sdvUsersInDss = new HashMap<>(); + sdvUsersInDss.put(dssEntryUser1RegionA, runThreeString); + sdvUsersInDss.put(dssEntryUser2RegionA, runThreeString); + sdvUsersInDss.put(dssEntryUser1RegionB, runFourString); + Mockito.when(dssService.getPrefix(sdvUserString)).thenReturn(sdvUsersInDss); + + // Get SdvUserResourceMonitor instance + Class sdvUserResourceMonitorClass = Class.forName(sdvUserResourceMonitorClassString); + SdvUserResourceMonitor sdvUserResourceMonitor = + (SdvUserResourceMonitor) sdvUserResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvUserResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvUserResourceMonitorClass, mockLog); + + // Make call to funtion under test + sdvUserResourceMonitor.run(); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(user1String), Mockito.any(), + Mockito.eq(runThreeString), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(user2String), Mockito.any(), + Mockito.eq(runThreeString), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + Assertions.assertTrue(true); + } + + @Test + void testRunException() throws FrameworkException, ClassNotFoundException, NoSuchFieldException, + SecurityException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + IFrameworkRuns frameworkRuns = Mockito.mock(IFrameworkRuns.class); + + Set allActiveRuns = new HashSet(); + allActiveRuns.add(runFourString); + Mockito.when(frameworkRuns.getActiveRunNames()).thenReturn(allActiveRuns); + + Mockito.when(framework.getFrameworkRuns()) + .thenThrow(new FrameworkException("cannot access framework")); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map sdvUsersInDss = new HashMap<>(); + sdvUsersInDss.put(dssEntryUser1RegionA, runThreeString); + sdvUsersInDss.put(dssEntryUser2RegionA, runThreeString); + sdvUsersInDss.put(dssEntryUser1RegionB, runFourString); + Mockito.when(dssService.getPrefix(sdvUserString)).thenReturn(sdvUsersInDss); + + // Get SdvUserResourceMonitor instance + Class sdvUserResourceMonitorClass = Class.forName(sdvUserResourceMonitorClassString); + SdvUserResourceMonitor sdvUserResourceMonitor = + (SdvUserResourceMonitor) sdvUserResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvUserResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvUserResourceMonitorClass, mockLog); + + // Make call to funtion under test + sdvUserResourceMonitor.run(); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(user1String), Mockito.any(), + Mockito.eq(runThreeString), Mockito.any()), Mockito.times(0)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(user2String), Mockito.any(), + Mockito.eq(runThreeString), Mockito.any()), Mockito.times(0)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + // Verify that although an exception occurred, the program continues, and simply logs + // an error to the log. + Mockito.verify(mockLog, Mockito.times(1)) + .error("Failure during scanning DSS for SDV Users"); + } + + @Test + void testrunFinishedOrDeleted() throws FrameworkException, ClassNotFoundException, + NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map sdvUsersInDss = new HashMap<>(); + sdvUsersInDss.put(dssEntryUser1RegionA, runThreeString); + sdvUsersInDss.put(dssEntryUser2RegionA, runThreeString); + sdvUsersInDss.put(dssEntryUser1RegionB, runFourString); + Mockito.when(dssService.getPrefix(sdvUserString)).thenReturn(sdvUsersInDss); + + // Get SdvUserResourceMonitor instance + Class sdvUserResourceMonitorClass = Class.forName(sdvUserResourceMonitorClassString); + SdvUserResourceMonitor sdvUserResourceMonitor = + (SdvUserResourceMonitor) sdvUserResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvUserResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvUserResourceMonitorClass, mockLog); + + // Make call to funtion under test + sdvUserResourceMonitor.runFinishedOrDeleted(runThreeString); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(user1String), Mockito.any(), + Mockito.eq(runThreeString), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(user2String), Mockito.any(), + Mockito.eq(runThreeString), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + Assertions.assertTrue(true); + } + + @Test + void testrunFinishedOrDeletedException() throws FrameworkException, ClassNotFoundException, + NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map sdvUsersInDss = new HashMap<>(); + sdvUsersInDss.put(dssEntryUser1RegionA, runThreeString); + sdvUsersInDss.put(dssEntryUser2RegionA, runThreeString); + sdvUsersInDss.put(dssEntryUser1RegionB, runFourString); + Mockito.when(dssService.getPrefix(sdvUserString)) + .thenThrow(new DynamicStatusStoreException("cannot read dss")); + + // Get SdvUserResourceMonitor instance + Class sdvUserResourceMonitorClass = Class.forName(sdvUserResourceMonitorClassString); + SdvUserResourceMonitor sdvUserResourceMonitor = + (SdvUserResourceMonitor) sdvUserResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvUserResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvUserResourceMonitorClass, mockLog); + + // Make call to funtion under test + sdvUserResourceMonitor.runFinishedOrDeleted(runThreeString); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(user1String), Mockito.any(), + Mockito.eq(runThreeString), Mockito.any()), Mockito.times(0)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(user2String), Mockito.any(), + Mockito.eq(runThreeString), Mockito.any()), Mockito.times(0)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + // Verify that although an exception occurred, the program continues, and simply logs + // an error to the log. + Mockito.verify(mockLog, Mockito.times(1)) + .error("Failure cleaning up SDV Users for finished run " + runThreeString); + } + + @Test + void testrunFinishedOrDeletedDssDeleteException() + throws FrameworkException, ClassNotFoundException, NoSuchFieldException, + SecurityException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + // Mock framework + IFramework framework = Mockito.mock(IFramework.class); + + // Mock resourceManagement + IResourceManagement resMan = Mockito.mock(IResourceManagement.class); + + // Mock dss + IDynamicStatusStoreService dssService = Mockito.mock(IDynamicStatusStoreService.class); + Map sdvUsersInDss = new HashMap<>(); + sdvUsersInDss.put(dssEntryUser1RegionA, runThreeString); + sdvUsersInDss.put(dssEntryUser2RegionA, runThreeString); + sdvUsersInDss.put(dssEntryUser1RegionB, runFourString); + Mockito.when(dssService.getPrefix(sdvUserString)).thenReturn(sdvUsersInDss); + + // Get SdvUserResourceMonitor instance + Class sdvUserResourceMonitorClass = Class.forName(sdvUserResourceMonitorClassString); + SdvUserResourceMonitor sdvUserResourceMonitor = + (SdvUserResourceMonitor) sdvUserResourceMonitorClass + .getDeclaredConstructor(IFramework.class, IResourceManagement.class, + IDynamicStatusStoreService.class) + .newInstance(framework, resMan, dssService); + + // Replace LOG + Field loggerField = sdvUserResourceMonitorClass.getDeclaredField(logString); + loggerField.setAccessible(true); + // remove final modifier + Field modifiersField = Field.class.getDeclaredField(modifiersString); + modifiersField.setAccessible(true); + modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL); + loggerField.set(sdvUserResourceMonitorClass, mockLog); + + sdvUserPoolStatic.when(() -> SdvUserPool.deleteDss(Mockito.eq(user1String), Mockito.any(), + Mockito.eq(runThreeString), Mockito.any())) + .thenThrow(new DynamicStatusStoreMatchException("not found")); + + // Make call to funtion under test + sdvUserResourceMonitor.runFinishedOrDeleted(runThreeString); + + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(user1String), Mockito.any(), + Mockito.eq(runThreeString), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verify(() -> SdvUserPool.deleteDss(Mockito.eq(user2String), Mockito.any(), + Mockito.eq(runThreeString), Mockito.any()), Mockito.times(1)); + sdvUserPoolStatic.verifyNoMoreInteractions(); + + // Verify that although an exception occurred, the program continues, and simply logs + // an error to the log. + Mockito.verify(mockLog, Mockito.times(1)) + .error("Failure in discarding SDV User " + user1String + " on CICS Applid APPL1" + + " allocated to run " + runThreeString); + } +} diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYaml.jcl b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYaml.jcl new file mode 100644 index 000000000..e35c7b071 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYaml.jcl @@ -0,0 +1,7 @@ +//MYLIB JCLLIB ORDER=(CICS.INSTALL.SDFHPROC) +//SDVCAPTR EXEC DFHXSDSO, +// HLQ=CICS.INSTALL, +// LOGSTRM=owner1.APPL1.DFHSECR, +// CYL=100 +//EXTRACT.SYSIN DD * +HEADER=NO \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYamlRegionA.jcl b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYamlRegionA.jcl new file mode 100644 index 000000000..a12289b56 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYamlRegionA.jcl @@ -0,0 +1,13 @@ +//MYLIB JCLLIB ORDER=(CICS.INSTALL.SDFHPROC) +//SDVCAPTR EXEC DFHXSDSO, +// HLQ=CICS.INSTALL, +// LOGSTRM=owner1.APPL1.DFHSECR, +// CYL=100 +//EXTRACT.SYSIN DD * +HEADER=NO +MATCHID=_654654 +USERID=user1,ROLE=TELLER +MATCHID=_7676575 +USERID=user2,ROLE=ADMIN +/* +// \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYamlRegionB.jcl b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYamlRegionB.jcl new file mode 100644 index 000000000..210b62f76 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/getYamlRegionB.jcl @@ -0,0 +1,11 @@ +//MYLIB JCLLIB ORDER=(CICS.INSTALL.SDFHPROC) +//SDVCAPTR EXEC DFHXSDSO, +// HLQ=CICS.INSTALL, +// LOGSTRM=owner1.APPL1.DFHSECR, +// CYL=100 +//EXTRACT.SYSIN DD * +HEADER=NO +MATCHID=_4543634 +USERID=user3,ROLE=TELLER +/* +// \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/yamlRegionA.yaml b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/yamlRegionA.yaml new file mode 100644 index 000000000..47cd4ee41 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/yamlRegionA.yaml @@ -0,0 +1 @@ +regionASecurityYAML \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/yamlRegionB.yaml b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/yamlRegionB.yaml new file mode 100644 index 000000000..a304c420a --- /dev/null +++ b/galasa-managers-parent/galasa-managers-testingtools-parent/dev.galasa.sdv.manager/src/test/resources/yamlRegionB.yaml @@ -0,0 +1 @@ +regionBSecurityYAML \ No newline at end of file diff --git a/galasa-managers-parent/gradle.properties b/galasa-managers-parent/gradle.properties index 492e06796..d942f9ac5 100644 --- a/galasa-managers-parent/gradle.properties +++ b/galasa-managers-parent/gradle.properties @@ -1,6 +1,6 @@ org.gradle.jvmargs=-Xmx4096M -jacocoEnabled= false +jacocoEnabled= true isMainOrRelease= false diff --git a/galasa-managers-parent/settings.gradle b/galasa-managers-parent/settings.gradle index 988c9d372..767ec2472 100644 --- a/galasa-managers-parent/settings.gradle +++ b/galasa-managers-parent/settings.gradle @@ -84,6 +84,8 @@ include 'galasa-managers-languages-parent:dev.galasa.java.windows.manager' // galasa-managers-testingtools-parent include 'galasa-managers-testingtools-parent:dev.galasa.jmeter.manager' include 'galasa-managers-testingtools-parent:dev.galasa.jmeter.manager.ivt' +include 'galasa-managers-testingtools-parent:dev.galasa.sdv.manager' +include 'galasa-managers-testingtools-parent:dev.galasa.sdv.manager.ivt' include 'galasa-managers-testingtools-parent:dev.galasa.selenium.manager' include 'galasa-managers-testingtools-parent:dev.galasa.selenium.manager.ivt' include 'galasa-managers-testingtools-parent:dev.galasa.vtp.manager' diff --git a/release.yaml b/release.yaml index ef41acd0f..850117904 100644 --- a/release.yaml +++ b/release.yaml @@ -317,6 +317,21 @@ managers: obr: true bom: true isolated: true + + - artifact: dev.galasa.sdv.manager + version: 0.34.0 + obr: true + javadoc: true + bom: true + mvp: true + isolated: true + codecoverage: true + + - artifact: dev.galasa.sdv.manager.ivt + version: 0.34.0 + obr: true + mvp: true + isolated: true - artifact: dev.galasa.selenium.manager version: 0.34.0