/*
* Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.amazonaws.codepipeline.jenkinsplugin;
import static com.amazonaws.codepipeline.jenkinsplugin.TestUtils.assertContainsIgnoreCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import com.amazonaws.codepipeline.jenkinsplugin.CodePipelineStateModel.CompressionType;
import com.amazonaws.services.codepipeline.AWSCodePipeline;
import com.amazonaws.services.codepipeline.model.Artifact;
import com.amazonaws.services.codepipeline.model.ArtifactLocation;
import com.amazonaws.services.codepipeline.model.EncryptionKey;
import com.amazonaws.services.codepipeline.model.EncryptionKeyType;
import com.amazonaws.services.codepipeline.model.PutJobFailureResultRequest;
import com.amazonaws.services.codepipeline.model.PutJobSuccessResultRequest;
import com.amazonaws.services.codepipeline.model.S3ArtifactLocation;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.CompleteMultipartUploadRequest;
import com.amazonaws.services.s3.model.InitiateMultipartUploadRequest;
import com.amazonaws.services.s3.model.InitiateMultipartUploadResult;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.SSEAwsKeyManagementParams;
import com.amazonaws.services.s3.model.UploadPartRequest;
import com.amazonaws.services.s3.model.UploadPartResult;
public class PublisherToolsTest {
private static Path PATH_TO_COMPRESS = Paths.get(TestUtils.TEST_DIR);
private ByteArrayOutputStream outContent;
@Mock private AWSCodePipeline mockCodePipelineClient;
@Mock private AmazonS3 mockS3Client;
@Mock private Artifact mockArtifact;
@Mock private ArtifactLocation mockLocation;
@Mock private S3ArtifactLocation s3ArtifactLocation;
@Mock private InitiateMultipartUploadResult mockUploadResult;
@Mock private UploadPartResult mockPartRequest;
@Mock private EncryptionKey mockEncryptionKey;
@Captor private ArgumentCaptor<InitiateMultipartUploadRequest> initiateCaptor;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mockS3Client.initiateMultipartUpload(any(InitiateMultipartUploadRequest.class)))
.thenReturn(mockUploadResult);
when(mockS3Client.uploadPart(any(UploadPartRequest.class))).thenReturn(mockPartRequest);
when(mockUploadResult.getUploadId()).thenReturn("123");
when(mockArtifact.getLocation()).thenReturn(mockLocation);
when(mockLocation.getS3Location()).thenReturn(s3ArtifactLocation);
when(s3ArtifactLocation.getBucketName()).thenReturn("Bucket");
when(s3ArtifactLocation.getObjectKey()).thenReturn("Key");
outContent = TestUtils.setOutputStream();
}
@Test
public void putJobResultBuildSucceededSuccess() {
final String message = "[AWS CodePipeline Plugin] Build succeeded, calling PutJobSuccessResult\n";
PublisherTools.putJobResult(
true, // Build Succeeded
"", // Error Message
"0", // ActionID
"1", // Job ID
mockCodePipelineClient,
null); // Listener
verify(mockCodePipelineClient, times(1)).putJobSuccessResult(any(PutJobSuccessResultRequest.class));
assertEquals(outContent.toString().toLowerCase(), message.toLowerCase());
}
@Test
public void putJobResultBuildFailureSuccess() {
final String message = "[AWS CodePipeline Plugin] Build failed, calling PutJobFailureResult\n";
PublisherTools.putJobResult(
false, // Build Succeeded
"Generic Error", // Error Message
"0", // ActionID
"1", // Job ID
mockCodePipelineClient,
null); // Listener
final ArgumentCaptor<PutJobFailureResultRequest> failureRequest =
ArgumentCaptor.forClass(PutJobFailureResultRequest.class);
verify(mockCodePipelineClient, times(1)).putJobFailureResult(failureRequest.capture());
assertEquals("Generic Error".toLowerCase(),
failureRequest.getValue().getFailureDetails().getMessage().toLowerCase());
assertEquals(outContent.toString().toLowerCase(), message.toLowerCase());
}
@Test
public void uploadFileSuccess() throws IOException {
TestUtils.initializeTestingFolders();
final File compressedFile = CompressionTools.compressFile(
"ZipProject",
PATH_TO_COMPRESS,
CompressionType.Zip,
null);
PublisherTools.uploadFile(
compressedFile,
mockArtifact,
CompressionType.Zip,
null, // No custom encryption key
mockS3Client,
null); // Listener
final InOrder inOrder = inOrder(mockS3Client);
inOrder.verify(mockS3Client, times(1)).initiateMultipartUpload(initiateCaptor.capture());
// Total size is less than 5MB, should only be one upload
inOrder.verify(mockS3Client, times(1)).uploadPart(any(UploadPartRequest.class));
inOrder.verify(mockS3Client, times(1)).completeMultipartUpload(any(CompleteMultipartUploadRequest.class));
assertContainsIgnoreCase("[AWS CodePipeline Plugin] Uploading artifact:", outContent.toString());
assertContainsIgnoreCase("[AWS CodePipeline Plugin] Upload successful\n", outContent.toString());
final InitiateMultipartUploadRequest request = initiateCaptor.getValue();
final SSEAwsKeyManagementParams encryptionParams = request.getSSEAwsKeyManagementParams();
assertNotNull(encryptionParams);
assertNull(encryptionParams.getAwsKmsKeyId());
assertEquals("aws:kms", encryptionParams.getEncryption());
compressedFile.delete();
TestUtils.cleanUpTestingFolders();
}
@Test
public void uploadWithCustomKmsEncryptionKey() throws IOException {
TestUtils.initializeTestingFolders();
when(mockEncryptionKey.getId()).thenReturn("KMS-KEY-ARN");
when(mockEncryptionKey.getType()).thenReturn(EncryptionKeyType.KMS.toString());
final File compressedFile = CompressionTools.compressFile(
"ZipProject",
PATH_TO_COMPRESS,
CompressionType.Zip,
null);
PublisherTools.uploadFile(
compressedFile,
mockArtifact,
CompressionType.Zip,
mockEncryptionKey,
mockS3Client,
null); // Listener
verify(mockS3Client).initiateMultipartUpload(initiateCaptor.capture());
assertContainsIgnoreCase("[AWS CodePipeline Plugin] Upload successful\n", outContent.toString());
final InitiateMultipartUploadRequest request = initiateCaptor.getValue();
final SSEAwsKeyManagementParams encryptionParams = request.getSSEAwsKeyManagementParams();
assertNotNull(encryptionParams);
assertEquals("KMS-KEY-ARN", encryptionParams.getAwsKmsKeyId());
assertEquals("aws:kms", encryptionParams.getEncryption());
compressedFile.delete();
TestUtils.cleanUpTestingFolders();
}
@Test
public void uploadWithUnknownEncryptionKeyType() throws IOException {
TestUtils.initializeTestingFolders();
when(mockEncryptionKey.getId()).thenReturn("KMS-KEY-ARN");
when(mockEncryptionKey.getType()).thenReturn("Custom");
final File compressedFile = CompressionTools.compressFile(
"ZipProject",
PATH_TO_COMPRESS,
CompressionType.Zip,
null);
PublisherTools.uploadFile(
compressedFile,
mockArtifact,
CompressionType.Zip,
mockEncryptionKey,
mockS3Client,
null); // Listener
verify(mockS3Client).initiateMultipartUpload(initiateCaptor.capture());
assertContainsIgnoreCase("[AWS CodePipeline Plugin] Upload successful\n", outContent.toString());
final InitiateMultipartUploadRequest request = initiateCaptor.getValue();
final SSEAwsKeyManagementParams encryptionParams = request.getSSEAwsKeyManagementParams();
assertNotNull(encryptionParams);
assertNull(encryptionParams.getAwsKmsKeyId());
assertEquals("aws:kms", encryptionParams.getEncryption());
compressedFile.delete();
TestUtils.cleanUpTestingFolders();
}
@Test
public void createObjectMetadataForZipCompressionType() {
final ObjectMetadata metadata = PublisherTools.createObjectMetadata(CompressionType.Zip);
assertEquals("application/zip", metadata.getContentType());
}
@Test
public void createObjectMetadataForTarCompressionType() {
final ObjectMetadata metadata = PublisherTools.createObjectMetadata(CompressionType.Tar);
assertEquals("application/tar", metadata.getContentType());
}
@Test
public void createObjectMetadataForTarGzCompressionType() {
final ObjectMetadata metadata = PublisherTools.createObjectMetadata(CompressionType.TarGz);
assertEquals("application/gzip", metadata.getContentType());
}
@Test
public void createObjectMetadataForUnknownCompressionType() {
final ObjectMetadata metadata = PublisherTools.createObjectMetadata(CompressionType.None);
assertNull(metadata.getContentType());
}
}