Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,9 @@ jobs:
make bootstrap
make deploy

- name: Smoke Test
- name: Integration Tests
run: |
awslocal --version
awslocal lambda invoke --cli-binary-format raw-in-base64-out --function-name my-lambda-rds-query-helper --payload '{"sqlQuery": "show tables", "secretName":"/rdsinitexample/rds/creds/mysql-01"}' output
echo "show tables:"
cat output
awslocal lambda invoke --cli-binary-format raw-in-base64-out --function-name my-lambda-rds-query-helper --payload '{"sqlQuery": "select Author from Books", "secretName":"/rdsinitexample/rds/creds/mysql-01"}' output
echo "select Author from Books:"
cat output
return_status=$(cat output | jq -r .status)
if [ "SUCCESS" != ${return_status} ]; then
echo "unexpected response: ${return_status}"
cat output
exit 1
fi
npm test

- name: Show Logs
if: always()
Expand Down
3 changes: 2 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
roots: ['<rootDir>/test'],
testEnvironment: 'node',
roots: ['<rootDir>/tests'],
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.tsx?$': 'ts-jest'
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
"jest": "^27.2.4",
"ts-jest": "^27.0.5",
"ts-node": "^10.2.1",
"typescript": "^4.4.3"
"typescript": "^4.4.3",
"@aws-sdk/client-lambda": "^3.0.0",
"@aws-sdk/client-rds": "^3.0.0",
"@aws-sdk/client-secrets-manager": "^3.0.0",
"@aws-sdk/client-s3": "^3.0.0"
},
"dependencies": {
"aws-cdk-lib": "^2.0.0",
Expand Down
122 changes: 122 additions & 0 deletions tests/cdk-rds.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { Template } from 'aws-cdk-lib/assertions';
import * as cdk from 'aws-cdk-lib';
import {
LambdaClient,
InvokeCommand,
GetFunctionCommand
} from '@aws-sdk/client-lambda';
import {
RDSClient,
DescribeDBInstancesCommand,
DBInstance
} from '@aws-sdk/client-rds';
import {
SecretsManagerClient,
GetSecretValueCommand
} from '@aws-sdk/client-secrets-manager';
import {
S3Client,
ListBucketsCommand
} from '@aws-sdk/client-s3';

const config = {
endpoint: 'http://localhost:4566',
region: 'us-east-1',
credentials: {
accessKeyId: 'test',
secretAccessKey: 'test'
}
};

const lambdaClient = new LambdaClient(config);
const rdsClient = new RDSClient(config);
const secretsClient = new SecretsManagerClient(config);
const s3Client = new S3Client(config);

describe('CDK RDS Stack', () => {
test('Lambda function exists', async () => {
try {
const command = new GetFunctionCommand({
FunctionName: 'my-lambda-rds-query-helper'
});
const response = await lambdaClient.send(command);
expect(response.Configuration?.FunctionName).toBe('my-lambda-rds-query-helper');
} catch (error) {
expect(error).toBeFalsy();
}
});

test('RDS instance exists', async () => {
try {
const command = new DescribeDBInstancesCommand({});
const response = await rdsClient.send(command);
expect(response.DBInstances?.length).toBeGreaterThan(0);
const instance = response.DBInstances?.find((db: DBInstance) => db.Engine === 'mysql');
expect(instance).toBeDefined();
} catch (error) {
expect(error).toBeFalsy();
}
});

test('Secrets Manager secret exists', async () => {
try {
const command = new GetSecretValueCommand({
SecretId: '/rdsinitexample/rds/creds/mysql-01'
});
const response = await secretsClient.send(command);
expect(response.SecretString).toBeDefined();
} catch (error) {
expect(error).toBeFalsy();
}
});

test('Lambda function returns correct response for show tables', async () => {
const payload = {
sqlQuery: 'show tables',
secretName: '/rdsinitexample/rds/creds/mysql-01'
};

try {
const command = new InvokeCommand({
FunctionName: 'my-lambda-rds-query-helper',
Payload: Buffer.from(JSON.stringify(payload))
});

const response = await lambdaClient.send(command);
const result = JSON.parse(Buffer.from(response.Payload!).toString());
expect(result.status).toBe('SUCCESS');
expect(Array.isArray(result.results)).toBeTruthy();
// Verify the expected tables are present
const tables = result.results.map((r: any) => r.Tables_in_main);
expect(tables).toContain('Books');
expect(tables).toContain('OrderDetails');
} catch (error) {
expect(error).toBeFalsy();
}
});

test('Lambda function returns correct response for select query', async () => {
const payload = {
sqlQuery: 'select Author from Books',
secretName: '/rdsinitexample/rds/creds/mysql-01'
};

try {
const command = new InvokeCommand({
FunctionName: 'my-lambda-rds-query-helper',
Payload: Buffer.from(JSON.stringify(payload))
});

const response = await lambdaClient.send(command);
const result = JSON.parse(Buffer.from(response.Payload!).toString());
expect(result.status).toBe('SUCCESS');
expect(Array.isArray(result.results)).toBeTruthy();
// Verify we have author data
const authors = result.results.map((r: any) => r.Author);
expect(authors).toContain('Jane Doe');
expect(authors).toContain('LocalStack');
} catch (error) {
expect(error).toBeFalsy();
}
});
});