|
| 1 | +import * as fs from 'node:fs'; |
| 2 | +import * as path from 'node:path'; |
1 | 3 | import { Template } from '../../assertions'; |
| 4 | +import { AssertionError } from '../../assertions/lib/private/error'; |
2 | 5 | import * as notifications from '../../aws-codestarnotifications'; |
3 | 6 | import * as iam from '../../aws-iam'; |
4 | 7 | import { ServicePrincipal } from '../../aws-iam'; |
5 | 8 | import * as kms from '../../aws-kms'; |
6 | 9 | import { CfnKey } from '../../aws-kms'; |
7 | 10 | import * as cdk from '../../core'; |
| 11 | +import { Stage } from '../../core'; |
8 | 12 | import * as sns from '../lib'; |
9 | 13 | import { TopicGrants } from '../lib'; |
10 | 14 |
|
@@ -1082,4 +1086,67 @@ describe('Topic', () => { |
1082 | 1086 | ).toThrow('`fifoThroughputScope` can only be set for FIFO SNS topics.'); |
1083 | 1087 | }); |
1084 | 1088 | }); |
| 1089 | + |
| 1090 | + /* |
| 1091 | + This is a representative test suite for source tracing. |
| 1092 | + What we are asserting here about CfnTopic applies to all L1 constructs. |
| 1093 | + */ |
| 1094 | + describe('Source tracing', () => { |
| 1095 | + test('Metadata contains propertyAssignment and stack trace with CDK_DEBUG=1', () => { |
| 1096 | + try { |
| 1097 | + process.env.CDK_DEBUG = '1'; |
| 1098 | + const stack = new cdk.Stack(); |
| 1099 | + |
| 1100 | + const topic = new sns.CfnTopic(stack, 'MyTopic', { |
| 1101 | + topicName: 'topicName', |
| 1102 | + }); |
| 1103 | + |
| 1104 | + topic.displayName = 'something'; |
| 1105 | + const lineWherePropertyWasSet = getLineNumber() - 1; // the one before this one |
| 1106 | + |
| 1107 | + const asm = synth(stack); |
| 1108 | + const metadata = JSON.parse(fs.readFileSync(path.join(asm.directory, 'Default.metadata.json'), 'utf8')); |
| 1109 | + const propertyAssignmentEntry = metadata['/Default/MyTopic'].find((e: any) => e.type === 'aws:cdk:propertyAssignment'); |
| 1110 | + |
| 1111 | + expect(propertyAssignmentEntry).toBeDefined(); |
| 1112 | + expect(propertyAssignmentEntry.data.propertyName).toEqual('DisplayName'); |
| 1113 | + expect(propertyAssignmentEntry.data.stackTrace.some( |
| 1114 | + (t: string) => t.includes(`${__filename}:${lineWherePropertyWasSet}`)), |
| 1115 | + ).toBe(true); |
| 1116 | + } finally { |
| 1117 | + delete process.env.CDK_DEBUG; |
| 1118 | + } |
| 1119 | + }); |
| 1120 | + |
| 1121 | + test('Metadata does not contain propertyAssignment by default', () => { |
| 1122 | + const stack = new cdk.Stack(); |
| 1123 | + |
| 1124 | + const topic = new sns.CfnTopic(stack, 'MyTopic', { |
| 1125 | + topicName: 'topicName', |
| 1126 | + }); |
| 1127 | + |
| 1128 | + topic.displayName = 'something'; |
| 1129 | + |
| 1130 | + const asm = synth(stack); |
| 1131 | + const metadata = JSON.parse(fs.readFileSync(path.join(asm.directory, 'Default.metadata.json'), 'utf8')); |
| 1132 | + const propertyAssignmentEntry = metadata['/Default/MyTopic'].find((e: any) => e.type === 'aws:cdk:propertyAssignment'); |
| 1133 | + |
| 1134 | + expect(propertyAssignmentEntry).toBeUndefined(); |
| 1135 | + }); |
| 1136 | + }); |
1085 | 1137 | }); |
| 1138 | + |
| 1139 | +function synth(stack: cdk.Stack) { |
| 1140 | + const stage = Stage.of(stack); |
| 1141 | + if (!Stage.isStage(stage)) { |
| 1142 | + throw new AssertionError('unexpected: all stacks must be part of a Stage or an App'); |
| 1143 | + } |
| 1144 | + |
| 1145 | + return stage.synth(); |
| 1146 | +} |
| 1147 | + |
| 1148 | +function getLineNumber(): number { |
| 1149 | + const err = new Error(); |
| 1150 | + const line = err.stack?.split('\n')[2]?.match(/:(\d+):\d+\)?$/)?.[1]; |
| 1151 | + return Number(line); |
| 1152 | +} |
0 commit comments