Skip to content

Commit

Permalink
test: add multi- and recursive-relationship E2Es, refactor test utils (
Browse files Browse the repository at this point in the history
…aws-amplify#2537)

* chore: refactor configurable-stack to accept sandbox
* chore: refactor duration to common util and use it for timeouts
  • Loading branch information
palpatim authored May 9, 2024
1 parent 7810ac0 commit b07330c
Show file tree
Hide file tree
Showing 92 changed files with 8,351 additions and 1,338 deletions.
810 changes: 436 additions & 374 deletions codebuild_specs/e2e_workflow.yml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as path from 'path';
import { createNewProjectDir, deleteProjectDir } from 'amplify-category-api-e2e-core';
import { initCDKProject, cdkDeploy, cdkDestroy } from '../commands';
import { graphql } from '../graphql-request';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('CDK Resource Utilities', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { createNewProjectDir, deleteProjectDir } from 'amplify-category-api-e2e-
import { initCDKProject, cdkDeploy, cdkDestroy } from '../commands';
import { graphql } from '../graphql-request';
import { invokeGraphqlProxyLambda } from '../lambda-request';
import { DURATION_1_HOUR } from '../utils/duration-constants';
import type { CreateTodoHandlerEvent, CreateTodoResponseData } from './backends/admin-role/apiInvoker';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('CDK Auth Modes', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as path from 'path';
import { createNewProjectDir, deleteProjectDir } from 'amplify-category-api-e2e-core';
import { initCDKProject, cdkDeploy, cdkDestroy } from '../commands';
import { graphql, graphqlRequestWithLambda } from '../graphql-request';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('CDK Auth Modes', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as path from 'path';
import { createNewProjectDir, deleteProjectDir } from 'amplify-category-api-e2e-core';
import { cdkDestroy } from '../commands';
import { setupBackend, testGraphQLOperations } from '../canary-tests-common';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('Canary using Amplify DynamoDB model datasource strategy', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as path from 'path';
import { createNewProjectDir, deleteProjectDir, getDDBTable } from 'amplify-category-api-e2e-core';
import { cdkDestroy, initCDKProject, cdkDeploy, updateCDKAppWithTemplate } from '../commands';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('CDK amplify table 1', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as path from 'path';
import { createNewProjectDir, deleteProjectDir, getDDBTable } from 'amplify-category-api-e2e-core';
import { cdkDestroy, initCDKProject, cdkDeploy, updateCDKAppWithTemplate } from '../commands';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('CDK amplify table 2', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as path from 'path';
import { createNewProjectDir, deleteProjectDir, getDDBTable } from 'amplify-category-api-e2e-core';
import { cdkDestroy, initCDKProject, cdkDeploy, updateCDKAppWithTemplate } from '../commands';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('CDK amplify table 3', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as path from 'path';
import { createNewProjectDir, deleteProjectDir, getDDBTable } from 'amplify-category-api-e2e-core';
import { createNewProjectDir, deleteProjectDir } from 'amplify-category-api-e2e-core';
import { cdkDestroy, initCDKProject, cdkDeploy, updateCDKAppWithTemplate } from '../commands';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('CDK amplify table 4', () => {
let projRoot: string;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import 'source-map-support/register';
import * as fs from 'fs';
import * as path from 'path';
import { App, CfnOutput, Duration, RemovalPolicy, Stack } from 'aws-cdk-lib';
import { CfnUserPoolGroup, UserPool } from 'aws-cdk-lib/aws-cognito';
import { CfnUserPoolGroup, UserPool, UserPoolClient } from 'aws-cdk-lib/aws-cognito';
import {
AmplifyGraphqlApi,
AmplifyGraphqlDefinition,
AuthorizationModes,
IAmplifyGraphqlDefinition,
ModelDataSourceStrategy,
} from '@aws-amplify/graphql-api-construct';
Expand All @@ -20,6 +21,51 @@ interface TestDefinition {
strategy: ModelDataSourceStrategy;
}

// #region Utilities

/**
* Controls stack-level configurations. TODO: Move TestDefinitions into this structure so we can stop writing so many files.
*/
interface StackConfig {
/**
* The prefix to use when naming stack assets. Keep this short (<=15 characters) so you don't bump up against resource length limits
* (e.g., 140 characters for lambda layers). Prefixes longer than 15 characters will be truncated.
* arn:aws:lambda:ap-northeast-2:012345678901:layer:${PREFIX}ApiAmplifyCodegenAssetsAmplifyCodegenAssetsDeploymentAwsCliLayerABCDEF12:1
*/
prefix: string;

/**
* If true, disable Cognito User Pool creation and only use API Key auth in sandbox mode.
*/
useSandbox?: boolean;
}

const createUserPool = (prefix: string): { userPool: UserPool; userPoolClient: UserPoolClient } => {
const userPool = new UserPool(stack, `${prefix}UserPool`, {
deletionProtection: false,
});
userPool.applyRemovalPolicy(RemovalPolicy.DESTROY);

// Create 3 user pool groups for group based auth tests
[1, 2, 3].forEach((idx) => {
new CfnUserPoolGroup(userPool, `${prefix}CUPGroup${idx}`, {
userPoolId: userPool.userPoolId,
groupName: `Group${idx}`,
precedence: idx * 10,
});
});

// Allow username/password without SRP, so our tests can easily login without having to set up an Amplify project and client library. Also
// enable SRP, so we can troubleshoot in the console if need be.
const userPoolClient = userPool.addClient(`${prefix}UserPoolClient`, {
authFlows: {
userPassword: true,
userSrp: true,
},
});
return { userPool, userPoolClient };
};

const definitionFromTestDefinition = (testDefinition: TestDefinition): IAmplifyGraphqlDefinition => {
const { schema, strategy } = testDefinition;
return AmplifyGraphqlDefinition.fromString(schema, strategy);
Expand All @@ -37,57 +83,52 @@ const combineTestDefinitionsInDirectory = (directory: string): IAmplifyGraphqlDe
return AmplifyGraphqlDefinition.combine(definitions);
};

const projRoot = path.normalize(path.join(__dirname, '..'));
const readStackConfig = (projRoot: string): StackConfig => {
const configPath = path.join(projRoot, 'stack-config.json');
const configString = fs.readFileSync(configPath).toString();
const config = JSON.parse(configString);
config.prefix = config.prefix.substring(0, 15);
return config;
};

// Read the prefix to use when naming stack assets. Keep this short (<=15 characters) so you don't bump up against resource length limits
// (e.g., 140 characters for lambda layers). Prefixes longer than 15 characters will be truncated.
// arn:aws:lambda:ap-northeast-2:012345678901:layer:${PREFIX}ApiAmplifyCodegenAssetsAmplifyCodegenAssetsDeploymentAwsCliLayerABCDEF12:1
const PREFIX = fs.readFileSync(path.join(projRoot, 'stack-prefix.txt')).toString().substring(0, 15);
// #endregion Utilities

const projRoot = path.normalize(path.join(__dirname, '..'));

// eslint-disable-next-line @typescript-eslint/no-var-requires
const packageJson = require('../package.json');

// Stack setup
const stackConfig = readStackConfig(projRoot);

const app = new App();
const stackName = packageJson.name.replace(/_/g, '-');
const stack = new Stack(app, stackName, {
env: { region: process.env.CLI_REGION || 'us-west-2' },
});

const userPool = new UserPool(stack, `${PREFIX}UserPool`, {
deletionProtection: false,
});
userPool.applyRemovalPolicy(RemovalPolicy.DESTROY);

// Create 3 user pool groups for group based auth tests
[1, 2, 3].forEach((idx) => {
new CfnUserPoolGroup(userPool, `${PREFIX}CUPGroup${idx}`, {
userPoolId: userPool.userPoolId,
groupName: `Group${idx}`,
precedence: idx * 10,
});
});
let authorizationModes: AuthorizationModes;

// Allow username/password without SRP, so our tests can easily login without having to set up an Amplify project and client library. Also
// enable SRP, so we can troubleshoot in the console if need be.
const userPoolClient = userPool.addClient(`${PREFIX}UserPoolClient`, {
authFlows: {
userPassword: true,
userSrp: true,
},
});
if (stackConfig.useSandbox) {
authorizationModes = {
apiKeyConfig: { expires: Duration.days(2) },
};
} else {
const { userPool, userPoolClient } = createUserPool(stackConfig.prefix);
authorizationModes = {
defaultAuthorizationMode: 'AMAZON_COGNITO_USER_POOLS',
userPoolConfig: { userPool },
apiKeyConfig: { expires: Duration.days(2) },
};
new CfnOutput(stack, 'UserPoolId', { value: userPool.userPoolId });
new CfnOutput(stack, 'UserPoolClientId', { value: userPoolClient.userPoolClientId });
}

const combinedDefinition = combineTestDefinitionsInDirectory(projRoot);

new AmplifyGraphqlApi(stack, `${PREFIX}Api`, {
new AmplifyGraphqlApi(stack, `${stackConfig.prefix}Api`, {
definition: combinedDefinition,
authorizationModes: {
defaultAuthorizationMode: 'AMAZON_COGNITO_USER_POOLS',
userPoolConfig: { userPool },
apiKeyConfig: { expires: Duration.days(2) },
authorizationModes,
translationBehavior: {
sandboxModeEnabled: stackConfig.useSandbox,
},
});

new CfnOutput(stack, 'UserPoolId', { value: userPool.userPoolId });
new CfnOutput(stack, 'UserPoolClientId', { value: userPoolClient.userPoolClientId });
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {
} from 'amplify-category-api-e2e-core';
import { initCDKProject, cdkDeploy, cdkDestroy } from '../commands';
import { graphql } from '../graphql-request';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('CDK GraphQL Transformer', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as path from 'path';
import { createNewProjectDir, deleteProjectDir } from 'amplify-category-api-e2e-core';
import { initCDKProject, cdkDeploy, cdkDestroy } from '../commands';
import { graphql } from '../graphql-request';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('CDK GraphQL Transformer - Custom Logic', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as path from 'path';
import { createNewProjectDir, deleteProjectDir } from 'amplify-category-api-e2e-core';
import { initCDKProject, cdkDeploy, cdkDestroy } from '../commands';
import { graphql } from '../graphql-request';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('Data Construct', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { AuthConstructStackOutputs } from '../types';
import { CognitoIdentityPoolCredentialsFactory } from '../cognito-identity-pool-credentials';
import { assumeIamRole } from '../assume-role';
import { CRUDLTester } from '../crudl-tester';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('CDK DDB Iam Access', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as path from 'path';
import { createNewProjectDir, deleteProjectDir } from 'amplify-category-api-e2e-core';
import { cdkDestroy } from '../commands';
import { setupBackend, testGraphQLOperations } from '../canary-tests-common';
import { DURATION_1_HOUR } from '../utils/duration-constants';

jest.setTimeout(1000 * 60 * 60 /* 1 hour */);
jest.setTimeout(DURATION_1_HOUR);

describe('Canary using default DynamoDB model datasource strategy', () => {
let projRoot: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {
COUNT_10_THOUSAND,
DURATION_30_MINUTES,
MUTATION_THREE_FIELD_CREATE,
SCHEMA_THREE_FIELDS_ALL_INDEXED,
SCHEMA_THREE_FIELDS_NO_INDEX,
} from '../deploy-velocity/deploy-velocity-constants';
import { DURATION_30_MINUTES } from '../../utils/duration-constants';
import {
recordCountDataProvider,
recordCountDataValidator,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {
COUNT_1_THOUSAND,
DURATION_30_MINUTES,
MUTATION_THREE_FIELD_CREATE,
SCHEMA_THREE_FIELDS_ALL_INDEXED,
SCHEMA_THREE_FIELDS_NO_INDEX,
} from '../deploy-velocity/deploy-velocity-constants';
import { DURATION_30_MINUTES } from '../../utils/duration-constants';
import {
recordCountDataProvider,
recordCountDataValidator,
Expand Down
Loading

0 comments on commit b07330c

Please sign in to comment.