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
24 changes: 24 additions & 0 deletions src/test/aws/common/cdkConfig/configs.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,29 @@
"growthFactor": 100,
"replicateTo": "NONE"
}
},
"appWithDefaults": {
"application": {
"name": "test-application-defaults",
"description": "test-application defaults"
},
"environment": {
"description": "test-env defaults"
},
"configurationProfile": {
"name": "test-profile-defaults",
"description": "test-profile defaults"
}
},
"appWithStrategy": {
"application": {
"name": "test-application-strategy",
"description": "test-application strategy"
},
"deploymentStrategy": {
"deploymentDurationInMinutes": 5,
"growthFactor": 50,
"replicateTo": "NONE"
}
}
}
45 changes: 40 additions & 5 deletions src/test/aws/common/cdkConfig/ecs.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
{
"testCluster": {
"clusterName": "test-cluster",
"clusterName": "test-cluster"
},
"testClusterWithTags": {
"clusterName": "test-cluster-tags",
"tags": [
{
"key": "testTagName1",
"value": "testTagValue1"
"key": "Environment",
"value": "test"
},
{
"key": "testTagName2",
"value": "testTagValue2"
"key": "Project",
"value": "test-project"
}
]
},
Expand All @@ -19,5 +22,37 @@
"logging": {
"multilinePattern": "^(DEBUG|ERROR|INFO|LOG|WARN)"
}
},
"testTaskWithOptions": {
"family": "test-task-opts",
"cpu": "512",
"memoryMiB": "1024",
"logging": {
"multilinePattern": "^(DEBUG|ERROR|INFO|LOG|WARN)"
},
"tags": [
{
"key": "TaskType",
"value": "batch"
}
]
},
"testFargateService": {
"loadBalancerName": "test-lb",
"serviceName": "test-service",
"assignPublicIp": false,
"healthCheckGracePeriod": 120,
"taskImageOptions": {
"containerPort": 80,
"enableLogging": false
},
"healthCheck": {
"path": "/health",
"intervalInSecs": 30,
"timeoutInSecs": 5
},
"logging": {
"multilinePattern": "^(DEBUG|ERROR|INFO|LOG|WARN)"
}
}
}
16 changes: 16 additions & 0 deletions src/test/aws/common/cdkConfig/lambdas-with-alias.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"testIamLambdaWithAlias": {
"architecture": "arm64",
"description": "Test lambda with alias",
"functionName": "test-iam-lambda-with-alias",
"memorySize": 1024,
"runtime": "nodejs24.x",
"timeout": 60,
"lambdaAliases": [
{
"aliasName": "live",
"version": "$LATEST"
}
]
}
}
213 changes: 211 additions & 2 deletions src/test/aws/common/common-stack.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ describe('TestCommonStack', () => {
expect(commonStack.props).toHaveProperty('testAttribute')
expect(commonStack.props.testAttribute).toEqual('success')
})
})

describe('TestCommonStack', () => {
test('synthesises as expected', () => {
/* test if number of resources are correctly synthesised */
template.resourceCountIs('Custom::TestCustomResourceTypeName', 1)
Expand All @@ -66,3 +64,214 @@ describe('TestCommonStack', () => {
})
})
})

describe('TestCommonStackWithoutSubdomain', () => {
test('fullyQualifiedDomain returns domain without subdomain', () => {
const propsWithoutSubdomain = {
domainName: 'example.com',
name: 'test-no-subdomain',
region: 'us-east-1',
stackName: 'test-no-sub',
stage: 'test',
}

class TestStackNoSubdomain extends CommonStack {
constructor(parent: cdk.App, name: string, props: TestStackProps) {
super(parent, name, propsWithoutSubdomain)
new CustomResource(this, `${props.stackName}-no-sub`, {
properties: {
domain: this.fullyQualifiedDomain(),
},
resourceType: 'Custom::TestNoSubdomainResource',
serviceToken: 'dummy-resource',
})
}
}

const appNoSub = new cdk.App({ context: propsWithoutSubdomain })
const stackNoSub = new TestStackNoSubdomain(appNoSub, 'test-no-subdomain-stack', propsWithoutSubdomain)
const templateNoSub = Template.fromStack(stackNoSub)

templateNoSub.hasResourceProperties('Custom::TestNoSubdomainResource', {
domain: 'example.com',
})
})
})

describe('TestCommonStackNoExtraContexts', () => {
test('handles missing extraContexts gracefully', () => {
const propsNoExtra = {
domainName: 'gradientedge.io',
name: 'test-no-extra',
region: 'eu-west-1',
stackName: 'test-no-extra',
stage: 'test',
}

class TestStackNoExtra extends CommonStack {
constructor(parent: cdk.App, name: string, props: any) {
super(parent, name, propsNoExtra)
}
}

const appNoExtra = new cdk.App({ context: propsNoExtra })
const stackNoExtra = new TestStackNoExtra(appNoExtra, 'test-no-extra-stack', propsNoExtra)

expect(stackNoExtra.props.name).toEqual('test-no-extra')
})
})

describe('TestCommonStackDevStage', () => {
test('handles dev stage correctly', () => {
const devStageProps = {
domainName: 'gradientedge.io',
name: 'test-dev',
region: 'eu-west-1',
stackName: 'test-dev',
stage: 'dev',
stageContextPath: 'src/test/aws/common/cdkEnv',
}

class TestStackDev extends CommonStack {
constructor(parent: cdk.App, name: string, props: any) {
super(parent, name, devStageProps)
}
}

const appDev = new cdk.App({ context: devStageProps })
const stackDev = new TestStackDev(appDev, 'test-dev-stack', devStageProps)

expect(stackDev.props.stage).toEqual('dev')
})
})

describe('TestCommonStackMissingStageContext', () => {
test('handles missing stage context file gracefully', () => {
const missingStageProps = {
domainName: 'gradientedge.io',
name: 'test-missing-stage',
region: 'eu-west-1',
stackName: 'test-missing',
stage: 'production',
stageContextPath: 'src/test/aws/common/cdkEnv',
}

class TestStackMissingStage extends CommonStack {
constructor(parent: cdk.App, name: string, props: any) {
super(parent, name, missingStageProps)
}
}

const appMissingStage = new cdk.App({ context: missingStageProps })
const stackMissingStage = new TestStackMissingStage(appMissingStage, 'test-missing-stage-stack', missingStageProps)

expect(stackMissingStage.props.stage).toEqual('production')
})
})

describe('TestCommonStackStageContextWithObjects', () => {
test('merges object properties from stage context', () => {
const objStageProps = {
domainName: 'gradientedge.io',
name: 'test-obj-stage',
region: 'eu-west-1',
stackName: 'test-obj',
stage: 'test',
stageContextPath: 'src/test/aws/common/cdkEnv',
}

class TestStackObjStage extends CommonStack {
constructor(parent: cdk.App, name: string, props: any) {
super(parent, name, objStageProps)
}

protected determineConstructProps(props: cdk.StackProps) {
return {
...super.determineConstructProps(props),
...{
nestedConfig: this.node.tryGetContext('nestedConfig'),
simpleValue: this.node.tryGetContext('simpleValue'),
},
}
}
}

const appObjStage = new cdk.App({ context: objStageProps })
const stackObjStage = new TestStackObjStage(appObjStage, 'test-obj-stage-stack', objStageProps)

expect(stackObjStage.props.stage).toEqual('test')
})
})

describe('TestCommonStackErrorHandling', () => {
test('throws error when extra context file not found', () => {
const errorProps = {
domainName: 'gradientedge.io',
extraContexts: ['src/test/aws/common/cdkConfig/nonexistent.json'],
name: 'test-error',
region: 'eu-west-1',
stackName: 'test-error',
stage: 'test',
}

class TestStackError extends CommonStack {
constructor(parent: cdk.App, name: string, props: any) {
super(parent, name, errorProps)
}
}

const appError = new cdk.App({ context: errorProps })
const error = () => new TestStackError(appError, 'test-error-stack', errorProps)

expect(error).toThrow('Extra context properties unavailable')
})
})

describe('TestCommonStackDefaultNodejsRuntime', () => {
test('uses default NODEJS runtime when not provided', () => {
const runtimeProps = {
domainName: 'gradientedge.io',
name: 'test-runtime',
region: 'eu-west-1',
stackName: 'test-runtime',
stage: 'test',
}

class TestStackRuntime extends CommonStack {
constructor(parent: cdk.App, name: string, props: any) {
super(parent, name, runtimeProps)
}
}

const appRuntime = new cdk.App({ context: runtimeProps })
const stackRuntime = new TestStackRuntime(appRuntime, 'test-runtime-stack', runtimeProps)

expect(stackRuntime.props.nodejsRuntime).toEqual(CommonStack.NODEJS_RUNTIME)
})
})

describe('TestCommonStackDefaultStackName', () => {
test('uses default stack name when not provided', () => {
const defaultNameProps = {
domainName: 'gradientedge.io',
name: undefined,
region: 'eu-west-1',
stage: 'test',
}

class TestStackDefaultName extends CommonStack {
constructor(parent: cdk.App, name: string, props: cdk.StackProps) {
super(parent, name, props)
}
}

const appDefaultName = new cdk.App({ context: defaultNameProps })
const stackDefaultName = new TestStackDefaultName(
appDefaultName,
'test-default-name-stack',
defaultNameProps as cdk.StackProps
)

expect(stackDefaultName.props.name).toEqual('cdk-utils')
})
})
3 changes: 3 additions & 0 deletions src/test/aws/common/nodejs/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM public.ecr.aws/lambda/nodejs:18
COPY lib/ ${LAMBDA_TASK_ROOT}/
CMD ["index.handler"]
Loading