1
1
import { promises as fs , existsSync } from 'fs' ;
2
2
import * as os from 'os' ;
3
3
import * as path from 'path' ;
4
- import { integTest , cloneDirectory , shell , withDefaultFixture , retry , sleep , randomInteger , withSamIntegrationFixture , RESOURCES_DIR , withCDKMigrateFixture } from '../../lib' ;
4
+ import { integTest , cloneDirectory , shell , withDefaultFixture , retry , sleep , randomInteger , withSamIntegrationFixture , RESOURCES_DIR , withCDKMigrateFixture , withExtendedTimeoutFixture } from '../../lib' ;
5
5
6
6
jest . setTimeout ( 2 * 60 * 60_000 ) ; // Includes the time to acquire locks, worst-case single-threaded runtime
7
7
@@ -571,9 +571,9 @@ integTest('deploy with role', withDefaultFixture(async (fixture) => {
571
571
}
572
572
} ) ) ;
573
573
574
- // TODO add go back in when template synths properly
574
+ // TODO add more testing that ensures the symmetry of the generated constructs to the resources.
575
575
[ 'typescript' , 'python' , 'csharp' , 'java' ] . forEach ( language => {
576
- integTest ( `cdk migrate ${ language } ` , withCDKMigrateFixture ( language , async ( fixture ) => {
576
+ integTest ( `cdk migrate ${ language } deploys successfully ` , withCDKMigrateFixture ( language , async ( fixture ) => {
577
577
if ( language === 'python' ) {
578
578
await fixture . shell ( [ 'pip' , 'install' , '-r' , 'requirements.txt' ] ) ;
579
579
}
@@ -588,6 +588,118 @@ integTest('deploy with role', withDefaultFixture(async (fixture) => {
588
588
} ) ) ;
589
589
} ) ;
590
590
591
+ integTest ( 'cdk migrate generates migrate.json' , withCDKMigrateFixture ( 'typescript' , async ( fixture ) => {
592
+
593
+ const migrateFile = await fs . readFile ( path . join ( fixture . integTestDir , 'migrate.json' ) , 'utf8' ) ;
594
+ const expectedFile = `{
595
+ \"//\": \"This file is generated by cdk migrate. It will be automatically deleted after the first successful deployment of this app to the environment of the original resources.\",
596
+ \"Source\": \"localfile\"
597
+ }` ;
598
+ expect ( JSON . parse ( migrateFile ) ) . toEqual ( JSON . parse ( expectedFile ) ) ;
599
+ await fixture . cdkDestroy ( fixture . stackNamePrefix ) ;
600
+ } ) ) ;
601
+
602
+ integTest ( 'cdk migrate --from-scan with AND/OR filters correctly filters resources' , withExtendedTimeoutFixture ( async ( fixture ) => {
603
+ const stackName = `cdk-migrate-integ-${ fixture . randomString } ` ;
604
+
605
+ await fixture . cdkDeploy ( 'migrate-stack' , {
606
+ modEnv : { SAMPLE_RESOURCES : '1' } ,
607
+ } ) ;
608
+ await fixture . cdk (
609
+ [ 'migrate' , '--stack-name' , stackName , '--from-scan' , 'new' , '--filter' , 'type=AWS::SNS::Topic,tag-key=tag1' , 'type=AWS::SQS::Queue,tag-key=tag3' ] ,
610
+ { modEnv : { MIGRATE_INTEG_TEST : '1' } , neverRequireApproval : true , verbose : true , captureStderr : false } ,
611
+ ) ;
612
+
613
+ try {
614
+ const response = await fixture . aws . cloudFormation ( 'describeGeneratedTemplate' , {
615
+ GeneratedTemplateName : stackName ,
616
+ } ) ;
617
+ const resourceNames = [ ] ;
618
+ for ( const resource of response . Resources || [ ] ) {
619
+ if ( resource . LogicalResourceId ) {
620
+ resourceNames . push ( resource . LogicalResourceId ) ;
621
+ }
622
+ }
623
+ fixture . log ( `Resources: ${ resourceNames } ` ) ;
624
+ expect ( resourceNames . some ( ele => ele && ele . includes ( 'migratetopic1' ) ) ) . toBeTruthy ( ) ;
625
+ expect ( resourceNames . some ( ele => ele && ele . includes ( 'migratequeue1' ) ) ) . toBeTruthy ( ) ;
626
+ } finally {
627
+ await fixture . cdkDestroy ( 'migrate-stack' ) ;
628
+ await fixture . aws . cloudFormation ( 'deleteGeneratedTemplate' , {
629
+ GeneratedTemplateName : stackName ,
630
+ } ) ;
631
+ }
632
+ } ) ) ;
633
+
634
+ integTest ( 'cdk migrate --from-scan for resources with Write Only Properties generates warnings' , withExtendedTimeoutFixture ( async ( fixture ) => {
635
+ const stackName = `cdk-migrate-integ-${ fixture . randomString } ` ;
636
+
637
+ await fixture . cdkDeploy ( 'migrate-stack' , {
638
+ modEnv : {
639
+ LAMBDA_RESOURCES : '1' ,
640
+ } ,
641
+ } ) ;
642
+ await fixture . cdk (
643
+ [ 'migrate' , '--stack-name' , stackName , '--from-scan' , 'new' , '--filter' , 'type=AWS::Lambda::Function,tag-key=lambda-tag' ] ,
644
+ { modEnv : { MIGRATE_INTEG_TEST : '1' } , neverRequireApproval : true , verbose : true , captureStderr : false } ,
645
+ ) ;
646
+
647
+ try {
648
+
649
+ const response = await fixture . aws . cloudFormation ( 'describeGeneratedTemplate' , {
650
+ GeneratedTemplateName : stackName ,
651
+ } ) ;
652
+ const resourceNames = [ ] ;
653
+ for ( const resource of response . Resources || [ ] ) {
654
+ if ( resource . LogicalResourceId && resource . ResourceType === 'AWS::Lambda::Function' ) {
655
+ resourceNames . push ( resource . LogicalResourceId ) ;
656
+ }
657
+ }
658
+ fixture . log ( `Resources: ${ resourceNames } ` ) ;
659
+ const readmePath = path . join ( fixture . integTestDir , stackName , 'README.md' ) ;
660
+ const readme = await fs . readFile ( readmePath , 'utf8' ) ;
661
+ expect ( readme ) . toContain ( '## Warnings' ) ;
662
+ for ( const resourceName of resourceNames ) {
663
+ expect ( readme ) . toContain ( `### ${ resourceName } ` ) ;
664
+ }
665
+ } finally {
666
+ await fixture . cdkDestroy ( 'migrate-stack' ) ;
667
+ await fixture . aws . cloudFormation ( 'deleteGeneratedTemplate' , {
668
+ GeneratedTemplateName : stackName ,
669
+ } ) ;
670
+ }
671
+ } ) ) ;
672
+
673
+ [ 'typescript' , 'python' , 'csharp' , 'java' ] . forEach ( language => {
674
+ integTest ( `cdk migrate --from-stack creates deployable ${ language } app` , withExtendedTimeoutFixture ( async ( fixture ) => {
675
+ const migrateStackName = fixture . fullStackName ( 'migrate-stack' ) ;
676
+ await fixture . aws . cloudFormation ( 'createStack' , {
677
+ StackName : migrateStackName ,
678
+ TemplateBody : await fs . readFile ( path . join ( __dirname , '..' , '..' , 'resources' , 'templates' , 'sqs-template.json' ) , 'utf8' ) ,
679
+ } ) ;
680
+ try {
681
+ let stackStatus = 'CREATE_IN_PROGRESS' ;
682
+ while ( stackStatus === 'CREATE_IN_PROGRESS' ) {
683
+ stackStatus = await ( await ( fixture . aws . cloudFormation ( 'describeStacks' , { StackName : migrateStackName } ) ) ) . Stacks ?. [ 0 ] . StackStatus ! ;
684
+ await sleep ( 1000 ) ;
685
+ }
686
+ await fixture . cdk (
687
+ [ 'migrate' , '--stack-name' , migrateStackName , '--from-stack' ] ,
688
+ { modEnv : { MIGRATE_INTEG_TEST : '1' } , neverRequireApproval : true , verbose : true , captureStderr : false } ,
689
+ ) ;
690
+ await fixture . shell ( [ 'cd' , path . join ( fixture . integTestDir , migrateStackName ) ] ) ;
691
+ await fixture . cdk ( [ 'deploy' , migrateStackName ] , { neverRequireApproval : true , verbose : true , captureStderr : false } ) ;
692
+ const response = await fixture . aws . cloudFormation ( 'describeStacks' , {
693
+ StackName : migrateStackName ,
694
+ } ) ;
695
+
696
+ expect ( response . Stacks ?. [ 0 ] . StackStatus ) . toEqual ( 'UPDATE_COMPLETE' ) ;
697
+ } finally {
698
+ await fixture . cdkDestroy ( 'migrate-stack' ) ;
699
+ }
700
+ } ) ) ;
701
+ } ) ;
702
+
591
703
integTest ( 'cdk diff' , withDefaultFixture ( async ( fixture ) => {
592
704
const diff1 = await fixture . cdk ( [ 'diff' , fixture . fullStackName ( 'test-1' ) ] ) ;
593
705
expect ( diff1 ) . toContain ( 'AWS::SNS::Topic' ) ;
0 commit comments