/* * Copyright 2016 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. * * Portions copyright Copyright 2002-2016 JUnit. All Rights Reserved. * Please see LICENSE.txt for applicable license terms and NOTICE.txt for applicable notices. */ import com.amazonaws.auth.AWSSessionCredentials; import com.amazonaws.auth.BasicSessionCredentials; import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; import com.amazonaws.codebuild.jenkinsplugin.CodeBuildBaseCredentials; import com.amazonaws.services.codebuild.model.InvalidInputException; import com.cloudbees.plugins.credentials.*; import hudson.EnvVars; import hudson.model.AbstractProject; import hudson.model.Item; import hudson.model.ItemGroup; import hudson.model.Run; import hudson.util.Secret; import jenkins.model.Jenkins; import org.jenkinsci.plugins.workflow.steps.StepContext; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; 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.io.IOException; import java.util.List; import static com.amazonaws.auth.profile.internal.ProfileKeyConstants.*; import static com.amazonaws.codebuild.jenkinsplugin.Validation.*; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @PowerMockIgnore("javax.management.*") @RunWith(PowerMockRunner.class) @PrepareForTest({CredentialsMatchers.class, CredentialsProvider.class, SystemCredentialsProvider.class, DefaultAWSCredentialsProviderChain.class, Jenkins.class, Secret.class}) public class AWSClientFactoryTest { private static final String REGION = "us-east-1"; private static final String codeBuildDescriptor = "descriptor"; private static final String proxyHost = "host"; private static final String proxyPort = "2"; private final CodeBuildCredentials mockCBCreds = mock(CodeBuildCredentials.class); private final AWSSessionCredentials mockAWSCreds = mock(BasicSessionCredentials.class); private final DefaultAWSCredentialsProviderChain cpChain = mock(DefaultAWSCredentialsProviderChain.class); private final SystemCredentialsProvider mockSysCreds = mock(SystemCredentialsProvider.class); private final Secret awsSecretKey = PowerMockito.mock(Secret.class); private final Run<?, ?> build = mock(Run.class); private final StepContext mockStepContext = mock(StepContext.class); @Before public void setUp() { PowerMockito.mockStatic(CredentialsMatchers.class); PowerMockito.mockStatic(SystemCredentialsProvider.class); PowerMockito.mockStatic(DefaultAWSCredentialsProviderChain.class); when(CredentialsMatchers.firstOrNull(any(Iterable.class), any(CredentialsMatcher.class))).thenReturn(mockCBCreds); when(mockCBCreds.getCredentials()).thenReturn(mockAWSCreds); when(mockCBCreds.getCredentialsDescriptor()).thenReturn(codeBuildDescriptor); when(mockCBCreds.getProxyHost()).thenReturn(proxyHost); when(mockCBCreds.getProxyPort()).thenReturn(proxyPort); when(mockAWSCreds.getAWSAccessKeyId()).thenReturn("a"); when(mockAWSCreds.getAWSSecretKey()).thenReturn("s"); when(mockAWSCreds.getSessionToken()).thenReturn("t"); when(SystemCredentialsProvider.getInstance()).thenReturn(mockSysCreds); when(DefaultAWSCredentialsProviderChain.getInstance()).thenReturn(cpChain); when(awsSecretKey.getPlainText()).thenReturn("s"); } @Test public void testNullInput() { try { new AWSClientFactory(null, null, null, null, null, null, null, null, build, null); } catch (InvalidInputException e) { assert(e.getMessage().contains(CodeBuilderValidation.invalidRegionError)); } } @Test public void testBlankInput() { try { new AWSClientFactory("", "", "", "", "", null, "", "", build, null); } catch (InvalidInputException e) { assert(e.getMessage().contains(CodeBuilderValidation.invalidRegionError)); } } @Test(expected=NumberFormatException.class) public void testInvalidProxyPort() { new AWSClientFactory("keys", "", "", "port", "", awsSecretKey, "", REGION, build, null); } @Test public void testInvalidCredsOption() { try { new AWSClientFactory("bad", "", "", "", "", null, "", REGION, build, null); } catch (InvalidInputException e) { assert(e.getMessage().contains(invalidCredTypeError)); } } @Test public void testSpecifyCreds() { AWSClientFactory awsClientFactory = new AWSClientFactory("keys", "", proxyHost, proxyPort, "a", awsSecretKey, "t", REGION, build, null); assert(awsClientFactory.getProxyHost().equals(proxyHost)); assert(awsClientFactory.getProxyPort().equals(parseInt(proxyPort))); } @Test public void testDefaultCreds() { AWSClientFactory awsClientFactory = new AWSClientFactory("keys", "", proxyHost, proxyPort, "", awsSecretKey, "", REGION, build, null); assert(awsClientFactory.getProxyHost().equals(proxyHost)); assert(awsClientFactory.getProxyPort().equals(parseInt(proxyPort))); } @Test public void testNullCredsId() { try { new AWSClientFactory("jenkins", null, "", "", "", null, "", REGION, build, null); } catch (InvalidInputException e) { assert(e.getMessage().contains(CodeBuilderValidation.invalidCredentialsIdError)); } } @Test public void testEmptyCredsId() { try { new AWSClientFactory("jenkins", "", "", "", "", null, "", REGION, build, null); } catch (InvalidInputException e) { assert(e.getMessage().contains(CodeBuilderValidation.invalidCredentialsIdError)); } } @Test public void testJenkinsCreds() { String credentialsId = "id"; AWSClientFactory awsClientFactory = new AWSClientFactory("jenkins", credentialsId, "", "", "", null, "", REGION, build, null); assert(awsClientFactory.getProxyHost().equals(proxyHost)); assert(awsClientFactory.getProxyPort().equals(parseInt(proxyPort))); assert(awsClientFactory.getCredentialsDescriptor().contains(codeBuildDescriptor)); assert(awsClientFactory.getCredentialsDescriptor().contains(credentialsId)); } @Test public void testNullAwsSecretKey() { try { new AWSClientFactory("keys", null, "", "", "a", null, "", REGION, build, null); } catch (InvalidInputException e) { assert(e.getMessage().contains(invalidSecretKeyError)); } } @Test public void testJenkinsFolderCreds() { String credentialsId = "folder-creds"; String folder = "folder"; Jenkins mockInstance = mock(Jenkins.class); Item mockFolder = mock(Item.class); PowerMockito.mockStatic(Jenkins.class); when(Jenkins.getInstance()).thenReturn(mockInstance); when(mockInstance.getItemByFullName(folder)).thenReturn(mockFolder); PowerMockito.mockStatic(CredentialsProvider.class); List<Credentials> mockFolderCredsList = mock(List.class); when(CredentialsProvider.lookupCredentials(Credentials.class, mockFolder)).thenReturn(mockFolderCredsList); List<Credentials> mockCredsList = mock(List.class); when(mockSysCreds.getCredentials()).thenReturn(mockCredsList); when(CredentialsMatchers.firstOrNull(eq(mockCredsList), any(CredentialsMatcher.class))).thenReturn(null); when(CredentialsMatchers.firstOrNull(eq(mockFolderCredsList), any(CredentialsMatcher.class))).thenReturn(mockCBCreds); AbstractProject mockProject = mock(AbstractProject.class); ItemGroup mockFolderItem = mock(ItemGroup.class); when(build.getParent()).thenReturn(mockProject); when(mockProject.getParent()).thenReturn(mockFolderItem); when(mockFolderItem.getFullName()).thenReturn(folder); AWSClientFactory awsClientFactory = new AWSClientFactory("jenkins", credentialsId, "", "", "", null, "", REGION, build, null); assert(awsClientFactory.getProxyHost().equals(proxyHost)); assert(awsClientFactory.getProxyPort().equals(parseInt(proxyPort))); assert(awsClientFactory.getCredentialsDescriptor().contains(codeBuildDescriptor)); assert(awsClientFactory.getCredentialsDescriptor().contains(credentialsId)); } @Test(expected=InvalidInputException.class) public void testNonExistentCreds() { String credentialsId = "folder-creds"; String folder = "folder"; when(CredentialsMatchers.firstOrNull(any(Iterable.class), any(CredentialsMatcher.class))).thenReturn(null); Jenkins mockInstance = mock(Jenkins.class); Item mockFolder = mock(Item.class); PowerMockito.mockStatic(Jenkins.class); when(Jenkins.getInstance()).thenReturn(mockInstance); when(mockInstance.getItemByFullName(credentialsId)).thenReturn(mockFolder); PowerMockito.mockStatic(CredentialsProvider.class); AbstractProject mockProject = mock(AbstractProject.class); ItemGroup mockFolderItem = mock(ItemGroup.class); when(build.getParent()).thenReturn(mockProject); when(mockProject.getParent()).thenReturn(mockFolderItem); when(mockFolder.getFullName()).thenReturn(folder); try { new AWSClientFactory("jenkins", credentialsId, "", "", "", null, "", REGION, build, null); } catch (InvalidInputException e) { assert(e.getMessage().contains(CodeBuilderValidation.invalidCredentialsIdError)); throw e; } } @Test public void testStepContextBasicCreds() throws IOException, InterruptedException { EnvVars mockEnvVars = mock(EnvVars.class); when(mockEnvVars.get(AWS_ACCESS_KEY_ID)).thenReturn("access"); when(mockEnvVars.get(AWS_SECRET_ACCESS_KEY)).thenReturn("secret"); when(mockEnvVars.get(AWS_SESSION_TOKEN)).thenReturn(null); when(mockStepContext.get(EnvVars.class)).thenReturn(mockEnvVars); when(awsSecretKey.getPlainText()).thenReturn(""); PowerMockito.mockStatic(DefaultAWSCredentialsProviderChain.class); when(DefaultAWSCredentialsProviderChain.getInstance()).thenThrow(new RuntimeException("Should not be accessing the default credentials provider chain.")); AWSClientFactory awsClientFactory = new AWSClientFactory("keys", "", "", "", "", awsSecretKey, "", REGION, build, mockStepContext); assert(awsClientFactory.getCredentialsDescriptor().contains(stepCredentials)); } @Test public void testStepContextSessionCreds() throws IOException, InterruptedException { EnvVars mockEnvVars = mock(EnvVars.class); when(mockEnvVars.get(AWS_ACCESS_KEY_ID)).thenReturn("access"); when(mockEnvVars.get(AWS_SECRET_ACCESS_KEY)).thenReturn("secret"); when(mockEnvVars.get(AWS_SESSION_TOKEN)).thenReturn("token"); when(mockStepContext.get(EnvVars.class)).thenReturn(mockEnvVars); when(awsSecretKey.getPlainText()).thenReturn(""); PowerMockito.mockStatic(DefaultAWSCredentialsProviderChain.class); when(DefaultAWSCredentialsProviderChain.getInstance()).thenThrow(new RuntimeException("Should not be accessing the default credentials provider chain.")); AWSClientFactory awsClientFactory = new AWSClientFactory("keys", "", "", "", "", awsSecretKey, "", REGION, build, mockStepContext); assert(awsClientFactory.getCredentialsDescriptor().contains(stepCredentials)); } @Test public void testStepContextWithKeysSpecified() throws IOException, InterruptedException { EnvVars mockEnvVars = mock(EnvVars.class); when(mockEnvVars.get(AWS_ACCESS_KEY_ID)).thenReturn("access"); when(mockEnvVars.get(AWS_SECRET_ACCESS_KEY)).thenReturn("secret"); when(mockEnvVars.get(AWS_SESSION_TOKEN)).thenReturn("token"); when(mockStepContext.get(EnvVars.class)).thenReturn(mockEnvVars); PowerMockito.mockStatic(DefaultAWSCredentialsProviderChain.class); when(DefaultAWSCredentialsProviderChain.getInstance()).thenThrow(new RuntimeException("Should not be accessing the default credentials provider chain.")); AWSClientFactory awsClientFactory = new AWSClientFactory("keys", "", "", "", "accessKey", awsSecretKey, "", REGION, build, mockStepContext); assert(awsClientFactory.getCredentialsDescriptor().contains(CodeBuildBaseCredentials.BASIC_AWS_CREDS)); } }