package de.taimos.pipeline.aws; import com.amazonaws.HttpMethod; import com.amazonaws.client.builder.AwsSyncClientBuilder; import com.amazonaws.services.s3.AmazonS3; import hudson.EnvVars; import org.assertj.core.api.Assertions; import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.joda.time.DateTime; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.jvnet.hudson.test.JenkinsRule; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.net.URL; import java.util.Date; @RunWith(PowerMockRunner.class) @PrepareForTest(AWSClientFactory.class) @PowerMockIgnore("javax.crypto.*") public class S3PresignUrlStepTests { @Rule private JenkinsRule jenkinsRule = new JenkinsRule(); private AmazonS3 s3; @Before public void setupSdk() throws Exception { PowerMockito.mockStatic(AWSClientFactory.class); this.s3 = Mockito.mock(AmazonS3.class); PowerMockito.when(AWSClientFactory.create(Mockito.any(AwsSyncClientBuilder.class), Mockito.any(EnvVars.class))) .thenReturn(this.s3); } @Test public void presignWithDefaultExpiration() throws Exception { WorkflowJob job = this.jenkinsRule.jenkins.createProject(WorkflowJob.class, "s3PresignTest"); job.setDefinition(new CpsFlowDefinition("" + "node {\n" + " def url = s3PresignURL(bucket: 'foo', key: 'bar')\n" + " echo \"url=$url\"\n" + "}\n", true) ); //defaults to 1 minute //minus a buffer for the test Date expectedDate = DateTime.now().plusMinutes(1).minusSeconds(10).toDate(); String urlString = "http://localhost:283/sdkd"; URL url = new URL(urlString); Mockito.when(this.s3.generatePresignedUrl(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(url); WorkflowRun run = this.jenkinsRule.assertBuildStatusSuccess(job.scheduleBuild2(0)); jenkinsRule.assertLogContains("url=" + urlString, run); ArgumentCaptor<Date> expirationCaptor = ArgumentCaptor.forClass(Date.class); Mockito.verify(s3).generatePresignedUrl(Mockito.eq("foo"), Mockito.eq("bar"), expirationCaptor.capture(), Mockito.eq(HttpMethod.GET)); Assertions.assertThat(expirationCaptor.getValue()).isAfterOrEqualsTo(expectedDate); } @Test public void presignWithCustomMethod() throws Exception { WorkflowJob job = this.jenkinsRule.jenkins.createProject(WorkflowJob.class, "s3PresignTest"); job.setDefinition(new CpsFlowDefinition("" + "node {\n" + " def url = s3PresignURL(bucket: 'foo', key: 'bar', httpMethod: 'POST')\n" + " echo \"url=$url\"\n" + "}\n", true) ); String urlString = "http://localhost:283/sdkd"; URL url = new URL(urlString); Mockito.when(this.s3.generatePresignedUrl(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(url); WorkflowRun run = this.jenkinsRule.assertBuildStatusSuccess(job.scheduleBuild2(0)); jenkinsRule.assertLogContains("url=" + urlString, run); ArgumentCaptor<Date> expirationCaptor = ArgumentCaptor.forClass(Date.class); Mockito.verify(s3).generatePresignedUrl(Mockito.eq("foo"), Mockito.eq("bar"), Mockito.any(), Mockito.eq(HttpMethod.POST)); } @Test public void presignWithExpiration() throws Exception { WorkflowJob job = this.jenkinsRule.jenkins.createProject(WorkflowJob.class, "s3PresignTest"); job.setDefinition(new CpsFlowDefinition("" + "node {\n" + " def url = s3PresignURL(bucket: 'foo', key: 'bar', durationInSeconds: 10000)\n" + " echo \"url=$url\"\n" + "}\n", true) ); String urlString = "http://localhost:283/sdkd"; URL url = new URL(urlString); Mockito.when(this.s3.generatePresignedUrl(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(url); //minus a buffer for the test Date expectedDate = DateTime.now().plusSeconds(10000).minusSeconds(25).toDate(); WorkflowRun run = this.jenkinsRule.assertBuildStatusSuccess(job.scheduleBuild2(0)); jenkinsRule.assertLogContains("url=" + urlString, run); ArgumentCaptor<Date> expirationCaptor = ArgumentCaptor.forClass(Date.class); Mockito.verify(s3).generatePresignedUrl(Mockito.eq("foo"), Mockito.eq("bar"), expirationCaptor.capture(), Mockito.eq(HttpMethod.GET)); Assertions.assertThat(expirationCaptor.getValue()).isAfterOrEqualsTo(expectedDate); } }