Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(integ-tests): cannot make two or more identical assertions #27380

Merged
merged 10 commits into from
Oct 10, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export class DeployAssert extends Construct implements IDeployAssert {
}

public scope: Stack;
private assertionIdCounts = new Map<string, number>();

constructor(scope: Construct, props?: DeployAssertProps) {
super(scope, 'Default');
Expand All @@ -65,7 +66,7 @@ export class DeployAssert extends Construct implements IDeployAssert {
hash = md5hash(this.scope.resolve(parameters));
} catch {}

return new AwsApiCall(this.scope, `AwsApiCall${service}${api}${hash}`, {
return new AwsApiCall(this.scope, this.uniqueAssertionId(`AwsApiCall${service}${api}${hash}`), {
api,
service,
parameters,
Expand All @@ -87,15 +88,15 @@ export class DeployAssert extends Construct implements IDeployAssert {
const parsedUrl = new URL(url);
append = `${parsedUrl.hostname}${parsedUrl.pathname}`;
}
return new HttpApiCall(this.scope, `HttpApiCall${append}${hash}`, {
return new HttpApiCall(this.scope, this.uniqueAssertionId(`HttpApiCall${append}${hash}`), {
url,
fetchOptions: options,
});
}

public invokeFunction(props: LambdaInvokeFunctionProps): IApiCall {
const hash = md5hash(this.scope.resolve(props));
return new LambdaInvokeFunction(this.scope, `LambdaInvoke${hash}`, props);
return new LambdaInvokeFunction(this.scope, this.uniqueAssertionId(`LambdaInvoke${hash}`), props);
}

public expect(id: string, expected: ExpectedResult, actual: ActualResult): void {
Expand All @@ -104,4 +105,22 @@ export class DeployAssert extends Construct implements IDeployAssert {
actual,
});
}

/**
* Gets a unique logical id based on a proposed assertion id.
*/
private uniqueAssertionId(id: string): string {
const count = this.assertionIdCounts.get(id);

if (count === undefined) {
// If we've never seen this id before, we'll return the id unchanged
// to maintain backward compatibility.
this.assertionIdCounts.set(id, 1);
return id;
}

// Otherwise, we'll increment the counter and return a unique id.
this.assertionIdCounts.set(id, count + 1);
return `${id}${count}`;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ describe('DeployAssert', () => {
},
});
});

test('multiple identical calls can be configured', () => {
// GIVEN
const app = new App();

// WHEN
const deployAssert = new DeployAssert(app);
deployAssert.invokeFunction({ functionName: 'my-func' });
deployAssert.invokeFunction({ functionName: 'my-func' });

// THEN
const template = Template.fromStack(deployAssert.scope);
template.resourceCountIs('AWS::Lambda::Function', 1);
template.resourceCountIs('Custom::DeployAssert@SdkCallLambdainvoke', 2);
});
});

describe('assertions', () => {
Expand Down Expand Up @@ -145,6 +160,21 @@ describe('DeployAssert', () => {
template.resourceCountIs('Custom::DeployAssert@SdkCallMyServiceMyApi2', 1);
});

test('multiple identical calls can be configured', () => {
misterjoshua marked this conversation as resolved.
Show resolved Hide resolved
// GIVEN
const app = new App();

// WHEN
const deployAssert = new DeployAssert(app);
deployAssert.awsApiCall('MyService', 'MyApi');
deployAssert.awsApiCall('MyService', 'MyApi');

// THEN
const template = Template.fromStack(deployAssert.scope);
template.resourceCountIs('AWS::Lambda::Function', 1);
template.resourceCountIs('Custom::DeployAssert@SdkCallMyServiceMyApi', 2);
});

test('custom resource type length is truncated when greater than 60 characters', () => {
// GIVEN
const app = new App();
Expand Down Expand Up @@ -203,6 +233,21 @@ describe('DeployAssert', () => {
template.resourceCountIs('Custom::DeployAssert@HttpCallexamplecomtest789', 1);
});

test('multiple identical calls can be configured', () => {
// GIVEN
const app = new App();

// WHEN
const deployAssert = new DeployAssert(app);
deployAssert.httpApiCall('https://example.com/test');
deployAssert.httpApiCall('https://example.com/test');

// THEN
const template = Template.fromStack(deployAssert.scope);
template.resourceCountIs('AWS::Lambda::Function', 1);
template.resourceCountIs('Custom::DeployAssert@HttpCallexamplecomtest', 2);
});

test('call with fetch options', () => {
// GIVEN
const app = new App();
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading