From e8cef414cd696250f4045b0ab0b7b2c7b875d381 Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Tue, 15 Oct 2024 09:11:30 -0400 Subject: [PATCH] ci: Onboard the repo to the testing infra --- .github/workflows/aws-ci.yml | 46 +++++++++++++++++++ buildtools/ci.buildspec.yml | 16 +++++++ ...nitoAuthentication.IntegrationTests.csproj | 11 +++-- .../AuthenticationConfirmUserTests.cs | 12 ++--- .../AuthenticationCreateUserTests.cs | 4 +- .../AuthenticationSignUpUserTests.cs | 8 ++-- .../CognitoAWSCredentialsTests.cs | 27 +++++------ .../MfaAuthenticationTests.cs | 7 +-- .../SessionTests.cs | 16 +++---- ...ons.CognitoAuthentication.UnitTests.csproj | 11 +++-- .../BigIntegerExtensionsTests.cs | 6 +-- 11 files changed, 117 insertions(+), 47 deletions(-) create mode 100644 .github/workflows/aws-ci.yml create mode 100644 buildtools/ci.buildspec.yml diff --git a/.github/workflows/aws-ci.yml b/.github/workflows/aws-ci.yml new file mode 100644 index 0000000..f35e624 --- /dev/null +++ b/.github/workflows/aws-ci.yml @@ -0,0 +1,46 @@ +name: AWS CI + +on: + workflow_dispatch: + pull_request: + branches: + - master + - dev + - 'feature/**' + +permissions: + id-token: write + +jobs: + run-ci: + runs-on: ubuntu-latest + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 #v4 + with: + role-to-assume: ${{ secrets.CI_MAIN_TESTING_ACCOUNT_ROLE_ARN }} + role-duration-seconds: 7200 + aws-region: us-west-2 + - name: Invoke Load Balancer Lambda + id: lambda + shell: pwsh + run: | + aws lambda invoke response.json --function-name "${{ secrets.CI_TESTING_LOAD_BALANCER_LAMBDA_NAME }}" --cli-binary-format raw-in-base64-out --payload '{"Roles": "${{ secrets.CI_TEST_RUNNER_ACCOUNT_ROLES }}", "ProjectName": "${{ secrets.CI_TESTING_CODE_BUILD_PROJECT_NAME }}", "Branch": "${{ github.sha }}"}' + $roleArn=$(cat ./response.json) + "roleArn=$($roleArn -replace '"', '')" >> $env:GITHUB_OUTPUT + - name: Configure Test Runner Credentials + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 #v4 + with: + role-to-assume: ${{ steps.lambda.outputs.roleArn }} + role-duration-seconds: 7200 + aws-region: us-west-2 + - name: Run Tests on AWS + id: codebuild + uses: aws-actions/aws-codebuild-run-build@v1 + with: + project-name: ${{ secrets.CI_TESTING_CODE_BUILD_PROJECT_NAME }} + - name: CodeBuild Link + shell: pwsh + run: | + $buildId = "${{ steps.codebuild.outputs.aws-build-id }}" + echo $buildId \ No newline at end of file diff --git a/buildtools/ci.buildspec.yml b/buildtools/ci.buildspec.yml new file mode 100644 index 0000000..4ba2cba --- /dev/null +++ b/buildtools/ci.buildspec.yml @@ -0,0 +1,16 @@ +version: 0.2 + +phases: + install: + runtime-versions: + dotnet: 8.x + build: + commands: + - dotnet test test/Amazon.Extensions.CognitoAuthentication.UnitTests/Amazon.Extensions.CognitoAuthentication.UnitTests.csproj -c Release --logger trx --results-directory ./testresults + - dotnet test test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/Amazon.Extensions.CognitoAuthentication.IntegrationTests.csproj -c Release --logger trx --results-directory ./testresults +reports: + aws-ssm-data-protection-provider-for-aspnet-tests: + file-format: VisualStudioTrx + files: + - '**/*' + base-directory: './testresults' \ No newline at end of file diff --git a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/Amazon.Extensions.CognitoAuthentication.IntegrationTests.csproj b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/Amazon.Extensions.CognitoAuthentication.IntegrationTests.csproj index 8ded8cd..100a95b 100644 --- a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/Amazon.Extensions.CognitoAuthentication.IntegrationTests.csproj +++ b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/Amazon.Extensions.CognitoAuthentication.IntegrationTests.csproj @@ -1,7 +1,7 @@  - netcoreapp2.0 + net8 @@ -12,9 +12,12 @@ - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationConfirmUserTests.cs b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationConfirmUserTests.cs index 01a670f..3afebcb 100644 --- a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationConfirmUserTests.cs +++ b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationConfirmUserTests.cs @@ -54,7 +54,7 @@ public AuthenticationConfirmUserTests() : base() //Tests SRP authentication flow for web applications [Fact] - public async void TestGenericSrpAuthentication() + public async Task TestGenericSrpAuthentication() { string password = "PassWord1!"; @@ -62,7 +62,7 @@ public async void TestGenericSrpAuthentication() await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest() { Password = password - }).ConfigureAwait(false); + }); Assert.True(user.SessionTokens.IsValid()); } @@ -78,14 +78,14 @@ public async Task TestDeleteUser() await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest() { Password = "PassWord1!" - }).ConfigureAwait(false); + }); ListUsersRequest listUsersRequest = new ListUsersRequest() { Limit = 60, UserPoolId = pool.PoolID }; - ListUsersResponse listUsersReponse = await provider.ListUsersAsync(listUsersRequest).ConfigureAwait(false); + ListUsersResponse listUsersReponse = await provider.ListUsersAsync(listUsersRequest); foreach (UserType listUser in listUsersReponse.Users) { users.Add(listUser.Username); @@ -93,9 +93,9 @@ await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest() Assert.Contains(userID, users); - await user.DeleteUserAsync().ConfigureAwait(false); + await user.DeleteUserAsync(); - listUsersReponse = await provider.ListUsersAsync(listUsersRequest).ConfigureAwait(false); + listUsersReponse = await provider.ListUsersAsync(listUsersRequest); users.Clear(); foreach(UserType listUser in listUsersReponse.Users) { diff --git a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationCreateUserTests.cs b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationCreateUserTests.cs index e079052..054ca3e 100644 --- a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationCreateUserTests.cs +++ b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationCreateUserTests.cs @@ -57,7 +57,7 @@ public async Task TestNewPasswordRequiredFlow() await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest() { Password = password - }).ConfigureAwait(false); + }); Assert.Equal(context.ChallengeName, ChallengeNameType.NEW_PASSWORD_REQUIRED); @@ -65,7 +65,7 @@ await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest() { SessionID = context.SessionID, NewPassword = "NewPassword1!" - }).ConfigureAwait(false); + }); Assert.True(user.SessionTokens.IsValid()); } diff --git a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationSignUpUserTests.cs b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationSignUpUserTests.cs index 5a394db..2267bf5 100644 --- a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationSignUpUserTests.cs +++ b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/AuthenticationSignUpUserTests.cs @@ -61,14 +61,14 @@ public async Task TestSignUpProcess() { CognitoConstants.UserAttrEmail, "xxx@yyy.zzz"} }; - await pool.SignUpAsync(userID, password, userAttributes, validationData).ConfigureAwait(false); + await pool.SignUpAsync(userID, password, userAttributes, validationData); ListUsersRequest listUsersRequest = new ListUsersRequest() { Limit = 2, UserPoolId = pool.PoolID }; - ListUsersResponse listUsersResponse = await provider.ListUsersAsync(listUsersRequest).ConfigureAwait(false); + ListUsersResponse listUsersResponse = await provider.ListUsersAsync(listUsersRequest); bool containsUser55 = false; foreach (UserType user in listUsersResponse.Users) @@ -84,9 +84,9 @@ public async Task TestSignUpProcess() // Tests that ConfirmSignUp reaches the proper failure point with incorrect confirmation code [Fact] - public void TestConfirmSignUpFail() + public async Task TestConfirmSignUpFail() { - Assert.ThrowsAsync(() => user.ConfirmSignUpAsync("fakeConfirmationCode", false)); + await Assert.ThrowsAsync(() => user.ConfirmSignUpAsync("fakeConfirmationCode", false)); } } } diff --git a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/CognitoAWSCredentialsTests.cs b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/CognitoAWSCredentialsTests.cs index 6068177..9718c5b 100644 --- a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/CognitoAWSCredentialsTests.cs +++ b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/CognitoAWSCredentialsTests.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; using System.Threading; +using System.Threading.Tasks; using Xunit; using Amazon; @@ -44,7 +45,7 @@ public class CognitoCredentialsTests : AuthenticationConfirmUserTests [Fact] //Tests GetCognitoAWSCredentials - public async void TestGetCognitoAWSCredentials() + public async Task TestGetCognitoAWSCredentials() { string password = "PassWord1!"; string poolRegion = user.UserPool.PoolID.Substring(0, user.UserPool.PoolID.IndexOf("_")); @@ -54,7 +55,7 @@ public async void TestGetCognitoAWSCredentials() await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest() { Password = password - }).ConfigureAwait(false); + }); //Create identity pool identityClient = new AmazonCognitoIdentityClient(clientCredentials, clientRegion); @@ -68,29 +69,29 @@ await identityClient.CreateIdentityPoolAsync(new CreateIdentityPoolRequest() }, IdentityPoolName = "TestIdentityPool" + DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), - }).ConfigureAwait(false); + }); identityPoolId = poolResponse.IdentityPoolId; //Create role for identity pool managementClient = new AmazonIdentityManagementServiceClient(clientCredentials, clientRegion); - CreateRoleResponse roleResponse = managementClient.CreateRoleAsync(new CreateRoleRequest() + CreateRoleResponse roleResponse = await managementClient.CreateRoleAsync(new CreateRoleRequest() { RoleName = "_TestRole_" + DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), AssumeRolePolicyDocument = "{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect" + "\": \"Allow\",\"Principal\": {\"Federated\": \"cognito-identity.amazonaws.com\"}," + "\"Action\": \"sts:AssumeRoleWithWebIdentity\",\"Condition\": {\"StringEquals\": {" + "\"cognito-identity.amazonaws.com:aud\": [\"" + identityPoolId + "\"]}}}]}" - }).Result; + }); roleName = roleResponse.Role.RoleName; //Create and attach policy for role - CreatePolicyResponse policyResponse = managementClient.CreatePolicyAsync(new CreatePolicyRequest() + CreatePolicyResponse policyResponse = await managementClient.CreatePolicyAsync(new CreatePolicyRequest() { PolicyDocument = "{\"Version\": \"2012-10-17\",\"Statement\": " + "[{\"Effect\": \"Allow\",\"Action\": [\"mobileanalytics:PutEvents\",\"cog" + "nito-sync:*\",\"cognito-identity:*\",\"s3:*\"],\"Resource\": [\"*\"]}]}", PolicyName = "_Cognito_" + DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), - }).Result; + }); policyArn = policyResponse.Policy.Arn; AttachRolePolicyRequest attachRequest = new AttachRolePolicyRequest() @@ -98,7 +99,7 @@ await identityClient.CreateIdentityPoolAsync(new CreateIdentityPoolRequest() PolicyArn = policyArn, RoleName = roleName }; - AttachRolePolicyResponse attachRolePolicyResponse = managementClient.AttachRolePolicyAsync(attachRequest).Result; + AttachRolePolicyResponse attachRolePolicyResponse = await managementClient.AttachRolePolicyAsync(attachRequest); //Set the role for the identity pool await identityClient.SetIdentityPoolRolesAsync(new SetIdentityPoolRolesRequest() @@ -109,7 +110,7 @@ await identityClient.SetIdentityPoolRolesAsync(new SetIdentityPoolRolesRequest() { "authenticated", roleResponse.Role.Arn }, { "unauthenticated", roleResponse.Role.Arn } }, - }).ConfigureAwait(false); + }); //Create and test credentials CognitoAWSCredentials credentials = user.GetCognitoAWSCredentials(identityPoolId, clientRegion); @@ -122,17 +123,17 @@ await identityClient.SetIdentityPoolRolesAsync(new SetIdentityPoolRolesRequest() { try { - bucketsResponse = await client.ListBucketsAsync(new ListBucketsRequest()).ConfigureAwait(false); + bucketsResponse = await client.ListBucketsAsync(new ListBucketsRequest()); break; } - catch (Exception ex) + catch (Exception) { - System.Threading.Thread.Sleep(5000); + Thread.Sleep(5000); } } Assert.True(null != bucketsResponse, "Failed to list buckets after 5 tries"); - Assert.Equal(bucketsResponse.HttpStatusCode, System.Net.HttpStatusCode.OK); + Assert.Equal(System.Net.HttpStatusCode.OK, bucketsResponse.HttpStatusCode); } } diff --git a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/MfaAuthenticationTests.cs b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/MfaAuthenticationTests.cs index bd5f393..0b75c28 100644 --- a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/MfaAuthenticationTests.cs +++ b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/MfaAuthenticationTests.cs @@ -15,6 +15,7 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using Xunit; using Amazon.Runtime; @@ -35,7 +36,7 @@ public class MfaAuthenticationTests : BaseAuthenticationTestClass //Tests MFA authentication flow [Fact] - public async void TestMfaAuthenticationFlow() + public async Task TestMfaAuthenticationFlow() { string password = "PassWord1!"; @@ -43,7 +44,7 @@ public async void TestMfaAuthenticationFlow() await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest() { Password = password - }).ConfigureAwait(false); + }); Assert.Equal(context.ChallengeName, ChallengeNameType.SMS_MFA); @@ -51,7 +52,7 @@ await Assert.ThrowsAsync(() => user.RespondToSmsMfaAuthAs { MfaCode = "fakeMfaCode", SessionID = context.SessionID - })).ConfigureAwait(false); + })); } /// diff --git a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/SessionTests.cs b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/SessionTests.cs index acdbdee..e8e8329 100644 --- a/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/SessionTests.cs +++ b/test/Amazon.Extensions.CognitoAuthentication.IntegrationTests/SessionTests.cs @@ -27,9 +27,9 @@ public class SessionTests : AuthenticationConfirmUserTests { // Tests the ChangePassword method in CognitoUser to fail due to no valid session [Fact] - public async void TestFailedChangePassword() + public async Task TestFailedChangePassword() { - await Assert.ThrowsAsync(() => user.ChangePasswordAsync("PassWord1!", "PassWord2!")).ConfigureAwait(false); + await Assert.ThrowsAsync(() => user.ChangePasswordAsync("PassWord1!", "PassWord2!")); } // Tests that a CognitoUser object has a valid session object after being authenticated @@ -40,7 +40,7 @@ public async Task TestValidSession() await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest() { Password = "PassWord1!" - }).ConfigureAwait(false); + }); Assert.True(user.SessionTokens.IsValid()); } @@ -53,10 +53,10 @@ public async Task TestGetUserDetails() await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest() { Password = "PassWord1!" - }).ConfigureAwait(false); - GetUserResponse userDetails = await user.GetUserDetailsAsync().ConfigureAwait(false); + }); + GetUserResponse userDetails = await user.GetUserDetailsAsync(); - Assert.True(userDetails.UserAttributes.Any(x => string.Equals(x.Name, CognitoConstants.UserAttrEmail, StringComparison.Ordinal))); + Assert.Contains(userDetails.UserAttributes, x => string.Equals(x.Name, CognitoConstants.UserAttrEmail, StringComparison.Ordinal)); Assert.Empty(userDetails.MFAOptions); } @@ -68,9 +68,9 @@ public async Task TestGlobalSignOut() await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest() { Password = "PassWord1!" - }).ConfigureAwait(false); + }); - await user.GlobalSignOutAsync().ConfigureAwait(false); + await user.GlobalSignOutAsync(); Assert.Null(user.SessionTokens); } diff --git a/test/Amazon.Extensions.CognitoAuthentication.UnitTests/Amazon.Extensions.CognitoAuthentication.UnitTests.csproj b/test/Amazon.Extensions.CognitoAuthentication.UnitTests/Amazon.Extensions.CognitoAuthentication.UnitTests.csproj index d32cfe0..f952e5c 100644 --- a/test/Amazon.Extensions.CognitoAuthentication.UnitTests/Amazon.Extensions.CognitoAuthentication.UnitTests.csproj +++ b/test/Amazon.Extensions.CognitoAuthentication.UnitTests/Amazon.Extensions.CognitoAuthentication.UnitTests.csproj @@ -1,7 +1,7 @@  - netcoreapp2.0 + net8 @@ -14,9 +14,12 @@ - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/test/Amazon.Extensions.CognitoAuthentication.UnitTests/BigIntegerExtensionsTests.cs b/test/Amazon.Extensions.CognitoAuthentication.UnitTests/BigIntegerExtensionsTests.cs index a79697f..bd25bc9 100644 --- a/test/Amazon.Extensions.CognitoAuthentication.UnitTests/BigIntegerExtensionsTests.cs +++ b/test/Amazon.Extensions.CognitoAuthentication.UnitTests/BigIntegerExtensionsTests.cs @@ -9,7 +9,7 @@ namespace Amazon.Extensions.CognitoAuthentication.UnitTests public class BigIntegerExtensionsTests { [Fact] - public void TestFromHexPositive() + public void TestFromHexPositiveTest() { TestFromHexPositive("0", 0, 0); TestFromHexPositive("1", 1, 1); @@ -53,7 +53,7 @@ private void TestFromHexPositive(string hex, int expectedFromHexPositive, int ex } [Fact] - public void TestTrueMod() + public void TestTrueModTest() { TestTrueMod(10, 3, 1); TestTrueMod(10, 5, 0); @@ -72,7 +72,7 @@ private void TestTrueMod(int numerator, int denominator, int expectedTrueMod) } [Fact] - public void TestFromBigEndianPositive() + public void TestFromBigEndianPositiveTest() { TestFromBigEndianPositive(300, new byte[] { 1, 44 }, 300); TestFromBigEndianPositive(-266, new byte[] { 254, 246 }, 65270);