import static org.junit.Assert.assertFalse import static org.junit.Assert.assertTrue import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.ExpectedException import org.junit.rules.RuleChain import com.sap.piper.Utils import util.* class MulticloudDeployTest extends BasePiperTest { private ExpectedException thrown = new ExpectedException().none() private JenkinsStepRule stepRule = new JenkinsStepRule(this) private JenkinsMockStepRule neoDeployRule = new JenkinsMockStepRule(this, 'neoDeploy') private JenkinsMockStepRule cloudFoundryDeployRule = new JenkinsMockStepRule(this, 'cloudFoundryDeploy') private JenkinsMockStepRule cloudFoundryCreateServiceRule = new JenkinsMockStepRule(this, 'cloudFoundryCreateService') private JenkinsReadMavenPomRule readMavenPomRule = new JenkinsReadMavenPomRule(this, 'test/resources/deploy') private Map neo1 = [:] private Map neo2 = [:] private Map cloudFoundry1 = [:] private Map cloudFoundry2 = [:] private boolean executedOnKubernetes = false private boolean executedOnNode = false private boolean executedInParallel = false @Rule public RuleChain ruleChain = Rules .getCommonRules(this) .around(new JenkinsReadYamlRule(this)) .around(thrown) .around(stepRule) .around(neoDeployRule) .around(cloudFoundryDeployRule) .around(cloudFoundryCreateServiceRule) .around(readMavenPomRule) @Before void init() { helper.registerAllowedMethod("deleteDir", [], null) helper.registerAllowedMethod('dockerExecuteOnKubernetes', [Map.class, Closure.class], {params, body -> executedOnKubernetes = true body() }) helper.registerAllowedMethod('node', [String.class, Closure.class], {s, body -> executedOnNode = true body() }) helper.registerAllowedMethod("parallel", [Map.class], { map -> map.each {key, value -> value() } executedInParallel = true }) neo1 = [ host: 'test.deploy.host1.com', account: 'trialuser1', credentialsId: 'credentialsId1' ] neo2 = [ host: 'test.deploy.host2.com', account: 'trialuser2', credentialsId: 'credentialsId2' ] cloudFoundry1 = [ apiEndpoint: 'apiEndpoint1', appName:'testAppName1', credentialsId: 'cfCredentialsId1', manifest: 'test.yml', mtaExtensionDescriptor: 'targetMtaDescriptor.mtaext', org: 'testOrg1', space: 'testSpace1' ] cloudFoundry2 = [ apiEndpoint: 'apiEndpoint2', appName:'testAppName2', credentialsId: 'cfCredentialsId2', manifest: 'test.yml', org: 'testOrg2', space: 'testSpace2' ] nullScript.commonPipelineEnvironment.configuration = [ general: [ neoTargets: [ neo1, neo2 ], cfTargets: [ cloudFoundry1, cloudFoundry2 ] ], stages: [ acceptance: [ org: 'testOrg', space: 'testSpace', deployUser: 'testUser' ] ], steps: [ cloudFoundryDeploy: [ cloudFoundry : [ apiEndpoint: 'globalApiEndpoint', appName:'globalAppName', credentialsId: 'globalCredentialsId', mtaExtensionDescriptor: 'globalTargetMtaDescriptor.mtaext', org: 'globalOrg', space: 'globalSpace' ], mtaExtensionDescriptor: 'globalMtaDescriptor.mtaext', deployTool: 'cf_native', deployType: 'blue-green', keepOldInstance: true, cf_native: [ dockerImage: 'ppiper/cf-cli:6', dockerWorkspace: '/home/piper' ] ] ] ] helper.registerAllowedMethod('echo', [CharSequence.class], {}) Utils.metaClass.echo = { def m -> } } @After public void tearDown() { Utils.metaClass = null } @Test void errorNoTargetsDefined() { nullScript.commonPipelineEnvironment.configuration.general.neoTargets = [] nullScript.commonPipelineEnvironment.configuration.general.cfTargets = [] thrown.expect(Exception) thrown.expectMessage('Deployment skipped because no targets defined!') stepRule.step.multicloudDeploy( script: nullScript ) } @Test void neoDeploymentTest() { nullScript.commonPipelineEnvironment.configuration.general.neoTargets = [neo1] nullScript.commonPipelineEnvironment.configuration.general.cfTargets = [] stepRule.step.multicloudDeploy( script: nullScript, source: 'file.mtar' ) assert neoDeployRule.hasParameter('script', nullScript) assert neoDeployRule.hasParameter('warAction', 'deploy') assert neoDeployRule.hasParameter('source', 'file.mtar') assert neoDeployRule.hasParameter('neo', neo1) } @Test void neoRollingUpdateTest() { nullScript.commonPipelineEnvironment.configuration.general.neoTargets = [] nullScript.commonPipelineEnvironment.configuration.general.cfTargets = [] def neoParam = [ host: 'test.param.deploy.host.com', account: 'trialparamNeoUser', credentialsId: 'paramNeoCredentialsId' ] stepRule.step.multicloudDeploy( script: nullScript, neoTargets: [neoParam], source: 'file.mtar', enableZeroDowntimeDeployment: true ) assert neoDeployRule.hasParameter('script', nullScript) assert neoDeployRule.hasParameter('warAction', 'rolling-update') assert neoDeployRule.hasParameter('source', 'file.mtar') assert neoDeployRule.hasParameter('neo', neoParam) } @Test void cfDeploymentTest() { nullScript.commonPipelineEnvironment.configuration.general.neoTargets = [] nullScript.commonPipelineEnvironment.configuration.general.cfTargets = [] def cloudFoundry = [ appName:'paramTestAppName', manifest: 'test.yml', org: 'paramTestOrg', space: 'paramTestSpace', credentialsId: 'paramCfCredentialsId' ] stepRule.step.multicloudDeploy([ script: nullScript, cfTargets: [cloudFoundry] ]) assert cloudFoundryDeployRule.hasParameter('script', nullScript) assert cloudFoundryDeployRule.hasParameter('deployType', 'standard') assert cloudFoundryDeployRule.hasParameter('cloudFoundry', cloudFoundry) } @Test void cfBlueGreenDeploymentTest() { nullScript.commonPipelineEnvironment.configuration.general.neoTargets = [] nullScript.commonPipelineEnvironment.configuration.general.cfTargets = [cloudFoundry1] stepRule.step.multicloudDeploy([ script: nullScript, enableZeroDowntimeDeployment: true ]) assert cloudFoundryDeployRule.hasParameter('script', nullScript) assert cloudFoundryDeployRule.hasParameter('deployType', 'blue-green') assert cloudFoundryDeployRule.hasParameter('cloudFoundry', cloudFoundry1) } @Test void multicloudDeploymentTest() { stepRule.step.multicloudDeploy([ script: nullScript, enableZeroDowntimeDeployment: true, source: 'file.mtar' ]) assert neoDeployRule.hasParameter('script', nullScript) assert neoDeployRule.hasParameter('warAction', 'rolling-update') assert neoDeployRule.hasParameter('source', 'file.mtar') assert neoDeployRule.hasParameter('neo', neo1) assert neoDeployRule.hasParameter('neo', neo2) assert cloudFoundryDeployRule.hasParameter('script', nullScript) assert cloudFoundryDeployRule.hasParameter('deployType', 'blue-green') assert cloudFoundryDeployRule.hasParameter('cloudFoundry', cloudFoundry1) assert cloudFoundryDeployRule.hasParameter('cloudFoundry', cloudFoundry2) } @Test void multicloudParallelDeploymentTest() { stepRule.step.multicloudDeploy([ script: nullScript, enableZeroDowntimeDeployment: true, parallelExecution: true, source: 'file.mtar' ]) assert neoDeployRule.hasParameter('script', nullScript) assert neoDeployRule.hasParameter('warAction', 'rolling-update') assert neoDeployRule.hasParameter('source', 'file.mtar') assert neoDeployRule.hasParameter('neo', neo1) assert neoDeployRule.hasParameter('neo', neo2) assert cloudFoundryDeployRule.hasParameter('script', nullScript) assert cloudFoundryDeployRule.hasParameter('deployType', 'blue-green') assert cloudFoundryDeployRule.hasParameter('cloudFoundry', cloudFoundry1) assert cloudFoundryDeployRule.hasParameter('cloudFoundry', cloudFoundry2) } @Test void 'cfCreateServices calls cloudFoundryCreateService step with correct parameters'() { stepRule.step.multicloudDeploy([ script : nullScript, cfCreateServices: [[apiEndpoint: 'http://mycf.org', serviceManifest: 'services-manifest.yml', manifestVariablesFiles: 'vars.yml', space: 'PerformanceTests', org: 'MyOrg', credentialsId: 'MyCred']], source : 'file.mtar' ]) assert cloudFoundryCreateServiceRule.hasParameter('cloudFoundry', [ serviceManifest : 'services-manifest.yml', space : 'PerformanceTests', org : 'MyOrg', credentialsId : 'MyCred', apiEndpoint : 'http://mycf.org', manifestVariablesFiles: 'vars.yml' ]) } @Test void 'cfCreateServices with parallelTestExecution defined in compatible parameter - must run in parallel'() { def closureRun = null helper.registerAllowedMethod('error', [String.class], { s-> if (s == "Deployment skipped because no targets defined!") { // This error is ok because in this test we're not interested in the deployment } else { throw new RuntimeException("Unexpected error in test with message: ${s}") } }) helper.registerAllowedMethod('parallel', [Map.class], {m -> closureRun = m}) nullScript.commonPipelineEnvironment.configuration.general['features'] = [parallelTestExecution: true] stepRule.step.multicloudDeploy([ script: nullScript, cfCreateServices: [[serviceManifest: 'services-manifest.yml', space: 'PerformanceTests', org: 'foo', credentialsId: 'foo']], source: 'file.mtar' ]) assert closureRun != null } @Test void 'cfCreateServices with parallelExecution defined - must run in parallel'() { def closureRun = null helper.registerAllowedMethod('error', [String.class], { s-> if (s == "Deployment skipped because no targets defined!") { // This error is ok because in this test we're not interested in the deployment } else { throw new RuntimeException("Unexpected error in test with message: ${s}") } }) helper.registerAllowedMethod('parallel', [Map.class], {m -> closureRun = m}) nullScript.commonPipelineEnvironment.configuration.general = [parallelExecution: true] stepRule.step.multicloudDeploy([ script: nullScript, cfCreateServices: [[serviceManifest: 'services-manifest.yml', space: 'PerformanceTests', org: 'foo', credentialsId: 'foo']], source: 'file.mtar' ]) assert closureRun != null } @Test void multicloudParallelOnK8sTest() { binding.variables.env.POD_NAME = "name" stepRule.step.multicloudDeploy([ script : nullScript, enableZeroDowntimeDeployment: true, parallelExecution : true, source : 'file.mtar' ]) assertTrue(executedInParallel) assertTrue(executedOnKubernetes) assertFalse(executedOnNode) } @Test void multicloudParallelOnNodeTest() { stepRule.step.multicloudDeploy([ script : nullScript, enableZeroDowntimeDeployment: true, parallelExecution : true, source : 'file.mtar' ]) assertTrue(executedInParallel) assertTrue(executedOnNode) assertFalse(executedOnKubernetes) } @Test void multicloudPreDeploymentHookTest() { def closureRun = null stepRule.step.multicloudDeploy([ script : nullScript, preDeploymentHook : {closureRun = true}, ]) assertTrue(closureRun) } }