@@ -3,6 +3,7 @@ import * as path from 'path';
3
3
import * as cxschema from '@aws-cdk/cloud-assembly-schema' ;
4
4
import * as cxapi from '@aws-cdk/cx-api' ;
5
5
import { CloudAssemblyBuilder } from '@aws-cdk/cx-api' ;
6
+ import { WorkGraph } from '../lib/util/work-graph' ;
6
7
import { WorkGraphBuilder } from '../lib/util/work-graph-builder' ;
7
8
import { AssetBuildNode , AssetPublishNode , StackNode , WorkNode } from '../lib/util/work-graph-types' ;
8
9
@@ -36,14 +37,14 @@ describe('with some stacks and assets', () => {
36
37
37
38
expect ( graph . node ( 'F1:D1-publish' ) ) . toEqual ( expect . objectContaining ( {
38
39
type : 'asset-publish' ,
39
- dependencies : new Set ( [ 'F1:D1 -build' ] ) ,
40
+ dependencies : new Set ( [ 'F1-build' ] ) ,
40
41
} as Partial < AssetPublishNode > ) ) ;
41
42
} ) ;
42
43
43
44
test ( 'with prebuild off, asset building inherits dependencies from their parent stack' , ( ) => {
44
45
const graph = new WorkGraphBuilder ( false ) . build ( assembly . artifacts ) ;
45
46
46
- expect ( graph . node ( 'F1:D1 -build' ) ) . toEqual ( expect . objectContaining ( {
47
+ expect ( graph . node ( 'F1-build' ) ) . toEqual ( expect . objectContaining ( {
47
48
type : 'asset-build' ,
48
49
dependencies : new Set ( [ 'stack0' , 'stack1' ] ) ,
49
50
} as Partial < AssetBuildNode > ) ) ;
@@ -52,7 +53,7 @@ describe('with some stacks and assets', () => {
52
53
test ( 'with prebuild on, assets only have their own dependencies' , ( ) => {
53
54
const graph = new WorkGraphBuilder ( true ) . build ( assembly . artifacts ) ;
54
55
55
- expect ( graph . node ( 'F1:D1 -build' ) ) . toEqual ( expect . objectContaining ( {
56
+ expect ( graph . node ( 'F1-build' ) ) . toEqual ( expect . objectContaining ( {
56
57
type : 'asset-build' ,
57
58
dependencies : new Set ( [ 'stack0' ] ) ,
58
59
} as Partial < AssetBuildNode > ) ) ;
@@ -138,17 +139,11 @@ describe('tests that use assets', () => {
138
139
139
140
const assembly = rootBuilder . buildAssembly ( ) ;
140
141
141
- const traversal : string [ ] = [ ] ;
142
142
const graph = new WorkGraphBuilder ( true ) . build ( assembly . artifacts ) ;
143
- await graph . doParallel ( 1 , {
144
- deployStack : async ( node ) => { traversal . push ( node . id ) ; } ,
145
- buildAsset : async ( node ) => { traversal . push ( node . id ) ; } ,
146
- publishAsset : async ( node ) => { traversal . push ( node . id ) ; } ,
147
- } ) ;
143
+ const traversal = await traverseAndRecord ( graph ) ;
148
144
149
- expect ( traversal ) . toHaveLength ( 4 ) ; // 1 asset build, 1 asset publish, 2 stacks
150
145
expect ( traversal ) . toEqual ( [
151
- 'work-graph-builder.test.js:D1 -build' ,
146
+ 'work-graph-builder.test.js-build' ,
152
147
'work-graph-builder.test.js:D1-publish' ,
153
148
'StackA' ,
154
149
'StackB' ,
@@ -171,6 +166,53 @@ describe('tests that use assets', () => {
171
166
// THEN
172
167
expect ( graph . findCycle ( ) ) . toBeUndefined ( ) ;
173
168
} ) ;
169
+
170
+ test ( 'the same asset to different destinations is only built once' , async ( ) => {
171
+ addStack ( rootBuilder , 'StackA' , {
172
+ environment : 'aws://11111/us-east-1' ,
173
+ dependencies : [ 'StackA.assets' ] ,
174
+ } ) ;
175
+ addAssets ( rootBuilder , 'StackA.assets' , {
176
+ files : {
177
+ abcdef : {
178
+ source : { path : __dirname } ,
179
+ destinations : {
180
+ D1 : { bucketName : 'bucket1' , objectKey : 'key' } ,
181
+ D2 : { bucketName : 'bucket2' , objectKey : 'key' } ,
182
+ } ,
183
+ } ,
184
+ } ,
185
+ } ) ;
186
+
187
+ addStack ( rootBuilder , 'StackB' , {
188
+ environment : 'aws://11111/us-east-1' ,
189
+ dependencies : [ 'StackB.assets' , 'StackA' ] ,
190
+ } ) ;
191
+ addAssets ( rootBuilder , 'StackB.assets' , {
192
+ files : {
193
+ abcdef : {
194
+ source : { path : __dirname } ,
195
+ destinations : {
196
+ D3 : { bucketName : 'bucket3' , objectKey : 'key' } ,
197
+ } ,
198
+ } ,
199
+ } ,
200
+ } ) ;
201
+
202
+ const assembly = rootBuilder . buildAssembly ( ) ;
203
+
204
+ const graph = new WorkGraphBuilder ( true ) . build ( assembly . artifacts ) ;
205
+ const traversal = await traverseAndRecord ( graph ) ;
206
+
207
+ expect ( traversal ) . toEqual ( [
208
+ 'abcdef-build' ,
209
+ 'abcdef:D1-publish' ,
210
+ 'abcdef:D2-publish' ,
211
+ 'StackA' ,
212
+ 'abcdef:D3-publish' ,
213
+ 'StackB' ,
214
+ ] ) ;
215
+ } ) ;
174
216
} ) ;
175
217
176
218
/**
@@ -251,3 +293,13 @@ function assertableNode<A extends WorkNode>(x: A) {
251
293
dependencies : Array . from ( x . dependencies ) ,
252
294
} ;
253
295
}
296
+
297
+ async function traverseAndRecord ( graph : WorkGraph ) {
298
+ const ret : string [ ] = [ ] ;
299
+ await graph . doParallel ( 1 , {
300
+ deployStack : async ( node ) => { ret . push ( node . id ) ; } ,
301
+ buildAsset : async ( node ) => { ret . push ( node . id ) ; } ,
302
+ publishAsset : async ( node ) => { ret . push ( node . id ) ; } ,
303
+ } ) ;
304
+ return ret ;
305
+ }
0 commit comments