@mapbox/cloudfriend 9.2.1 → 9.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/changelog.md +4 -0
  2. package/lib/shortcuts/api.md +37 -0
  3. package/lib/shortcuts/glue-iceberg-table.js +187 -0
  4. package/lib/shortcuts/index.js +1 -0
  5. package/package.json +3 -3
  6. package/requirements.dev.txt +2 -2
  7. package/test/fixtures/shortcuts/glue-iceberg-table-defaults.json +41 -0
  8. package/test/fixtures/shortcuts/glue-iceberg-table-no-defaults.json +39 -0
  9. package/test/fixtures/shortcuts/glue-iceberg-table-with-all-optimizers.json +101 -0
  10. package/test/fixtures/shortcuts/glue-iceberg-table-with-both-optimizers.json +80 -0
  11. package/test/fixtures/shortcuts/glue-iceberg-table-with-compaction-custom.json +68 -0
  12. package/test/fixtures/shortcuts/glue-iceberg-table-with-compaction-defaults.json +57 -0
  13. package/test/fixtures/shortcuts/glue-iceberg-table-with-optimizer-custom.json +75 -0
  14. package/test/fixtures/shortcuts/glue-iceberg-table-with-optimizer-defaults.json +64 -0
  15. package/test/fixtures/shortcuts/glue-iceberg-table-with-orphan-deletion-custom.json +74 -0
  16. package/test/fixtures/shortcuts/glue-iceberg-table-with-orphan-deletion-defaults.json +62 -0
  17. package/test/shortcuts.test.js +294 -3
  18. package/coverage/clover.xml +0 -598
  19. package/coverage/coverage-final.json +0 -32
  20. package/coverage/lcov-report/base.css +0 -224
  21. package/coverage/lcov-report/block-navigation.js +0 -87
  22. package/coverage/lcov-report/cloudfriend/bin/build-template.js.html +0 -130
  23. package/coverage/lcov-report/cloudfriend/bin/index.html +0 -131
  24. package/coverage/lcov-report/cloudfriend/bin/validate-template.js.html +0 -142
  25. package/coverage/lcov-report/cloudfriend/index.html +0 -116
  26. package/coverage/lcov-report/cloudfriend/index.js.html +0 -307
  27. package/coverage/lcov-report/cloudfriend/lib/build.js.html +0 -217
  28. package/coverage/lcov-report/cloudfriend/lib/conditions.js.html +0 -430
  29. package/coverage/lcov-report/cloudfriend/lib/index.html +0 -206
  30. package/coverage/lcov-report/cloudfriend/lib/intrinsic.js.html +0 -979
  31. package/coverage/lcov-report/cloudfriend/lib/merge.js.html +0 -478
  32. package/coverage/lcov-report/cloudfriend/lib/pseudo.js.html +0 -370
  33. package/coverage/lcov-report/cloudfriend/lib/rules.js.html +0 -349
  34. package/coverage/lcov-report/cloudfriend/lib/shortcuts/cross-account-role.js.html +0 -244
  35. package/coverage/lcov-report/cloudfriend/lib/shortcuts/event-lambda.js.html +0 -367
  36. package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-database.js.html +0 -286
  37. package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-json-table.js.html +0 -235
  38. package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-orc-table.js.html +0 -226
  39. package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-parquet-table.js.html +0 -268
  40. package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-presto-view.js.html +0 -358
  41. package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-spark-view.js.html +0 -241
  42. package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-table.js.html +0 -481
  43. package/coverage/lcov-report/cloudfriend/lib/shortcuts/hookshot.js.html +0 -1504
  44. package/coverage/lcov-report/cloudfriend/lib/shortcuts/index.html +0 -416
  45. package/coverage/lcov-report/cloudfriend/lib/shortcuts/index.js.html +0 -154
  46. package/coverage/lcov-report/cloudfriend/lib/shortcuts/kinesis-firehose-base.js.html +0 -418
  47. package/coverage/lcov-report/cloudfriend/lib/shortcuts/lambda.js.html +0 -832
  48. package/coverage/lcov-report/cloudfriend/lib/shortcuts/log-subscription-lambda.js.html +0 -310
  49. package/coverage/lcov-report/cloudfriend/lib/shortcuts/queue-lambda.js.html +0 -364
  50. package/coverage/lcov-report/cloudfriend/lib/shortcuts/queue.js.html +0 -619
  51. package/coverage/lcov-report/cloudfriend/lib/shortcuts/role.js.html +0 -382
  52. package/coverage/lcov-report/cloudfriend/lib/shortcuts/s3-kinesis-firehose.js.html +0 -568
  53. package/coverage/lcov-report/cloudfriend/lib/shortcuts/scheduled-lambda.js.html +0 -490
  54. package/coverage/lcov-report/cloudfriend/lib/shortcuts/service-role.js.html +0 -307
  55. package/coverage/lcov-report/cloudfriend/lib/shortcuts/stream-lambda.js.html +0 -493
  56. package/coverage/lcov-report/cloudfriend/lib/validate.js.html +0 -154
  57. package/coverage/lcov-report/favicon.png +0 -0
  58. package/coverage/lcov-report/index.html +0 -161
  59. package/coverage/lcov-report/prettify.css +0 -1
  60. package/coverage/lcov-report/prettify.js +0 -2
  61. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  62. package/coverage/lcov-report/sorter.js +0 -210
  63. package/coverage/lcov.info +0 -1240
@@ -0,0 +1,75 @@
1
+ {
2
+ "AWSTemplateFormatVersion": "2010-09-09",
3
+ "Metadata": {},
4
+ "Parameters": {},
5
+ "Rules": {},
6
+ "Mappings": {},
7
+ "Conditions": {},
8
+ "Resources": {
9
+ "OptimizerRole": {
10
+ "Type": "AWS::IAM::Role",
11
+ "Properties": {
12
+ "AssumeRolePolicyDocument": {}
13
+ }
14
+ },
15
+ "MyTable": {
16
+ "Type": "AWS::Glue::Table",
17
+ "Properties": {
18
+ "CatalogId": {
19
+ "Ref": "AWS::AccountId"
20
+ },
21
+ "DatabaseName": "my_database",
22
+ "Name": "my_table",
23
+ "OpenTableFormatInput": {
24
+ "IcebergInput": {
25
+ "MetadataOperation": "CREATE",
26
+ "Version": "2",
27
+ "IcebergTableInput": {
28
+ "Location": "s3://fake/location",
29
+ "Schema": {
30
+ "Type": "struct",
31
+ "Fields": [
32
+ {
33
+ "Name": "column",
34
+ "Type": "string",
35
+ "Id": 1,
36
+ "Required": true
37
+ }
38
+ ]
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ },
45
+ "MyTableRetentionOptimizer": {
46
+ "Type": "AWS::Glue::TableOptimizer",
47
+ "DependsOn": "MyTable",
48
+ "Properties": {
49
+ "CatalogId": {
50
+ "Ref": "AWS::AccountId"
51
+ },
52
+ "DatabaseName": "my_database",
53
+ "TableName": "my_table",
54
+ "Type": "retention",
55
+ "TableOptimizerConfiguration": {
56
+ "RoleArn": {
57
+ "Fn::GetAtt": [
58
+ "OptimizerRole",
59
+ "Arn"
60
+ ]
61
+ },
62
+ "Enabled": true,
63
+ "RetentionConfiguration": {
64
+ "IcebergConfiguration": {
65
+ "SnapshotRetentionPeriodInDays": 7,
66
+ "NumberOfSnapshotsToRetain": 3,
67
+ "CleanExpiredFiles": false
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ },
74
+ "Outputs": {}
75
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "AWSTemplateFormatVersion": "2010-09-09",
3
+ "Metadata": {},
4
+ "Parameters": {},
5
+ "Rules": {},
6
+ "Mappings": {},
7
+ "Conditions": {},
8
+ "Resources": {
9
+ "MyTable": {
10
+ "Type": "AWS::Glue::Table",
11
+ "Properties": {
12
+ "CatalogId": {
13
+ "Ref": "AWS::AccountId"
14
+ },
15
+ "DatabaseName": "my_database",
16
+ "Name": "my_table",
17
+ "OpenTableFormatInput": {
18
+ "IcebergInput": {
19
+ "MetadataOperation": "CREATE",
20
+ "Version": "2",
21
+ "IcebergTableInput": {
22
+ "Location": "s3://fake/location",
23
+ "Schema": {
24
+ "Type": "struct",
25
+ "Fields": [
26
+ {
27
+ "Name": "column",
28
+ "Type": "string",
29
+ "Id": 1,
30
+ "Required": true
31
+ }
32
+ ]
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ },
39
+ "MyTableRetentionOptimizer": {
40
+ "Type": "AWS::Glue::TableOptimizer",
41
+ "DependsOn": "MyTable",
42
+ "Properties": {
43
+ "CatalogId": {
44
+ "Ref": "AWS::AccountId"
45
+ },
46
+ "DatabaseName": "my_database",
47
+ "TableName": "my_table",
48
+ "Type": "retention",
49
+ "TableOptimizerConfiguration": {
50
+ "RoleArn": "arn:aws:iam::123456789012:role/OptimizerRole",
51
+ "Enabled": true,
52
+ "RetentionConfiguration": {
53
+ "IcebergConfiguration": {
54
+ "SnapshotRetentionPeriodInDays": 5,
55
+ "NumberOfSnapshotsToRetain": 1,
56
+ "CleanExpiredFiles": true
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ },
63
+ "Outputs": {}
64
+ }
@@ -0,0 +1,74 @@
1
+ {
2
+ "AWSTemplateFormatVersion": "2010-09-09",
3
+ "Metadata": {},
4
+ "Parameters": {},
5
+ "Rules": {},
6
+ "Mappings": {},
7
+ "Conditions": {},
8
+ "Resources": {
9
+ "OrphanFileDeletionRole": {
10
+ "Type": "AWS::IAM::Role",
11
+ "Properties": {
12
+ "AssumeRolePolicyDocument": {}
13
+ }
14
+ },
15
+ "MyTable": {
16
+ "Type": "AWS::Glue::Table",
17
+ "Properties": {
18
+ "CatalogId": {
19
+ "Ref": "AWS::AccountId"
20
+ },
21
+ "DatabaseName": "my_database",
22
+ "Name": "my_table",
23
+ "OpenTableFormatInput": {
24
+ "IcebergInput": {
25
+ "MetadataOperation": "CREATE",
26
+ "Version": "2",
27
+ "IcebergTableInput": {
28
+ "Location": "s3://fake/location",
29
+ "Schema": {
30
+ "Type": "struct",
31
+ "Fields": [
32
+ {
33
+ "Name": "column",
34
+ "Type": "string",
35
+ "Id": 1,
36
+ "Required": true
37
+ }
38
+ ]
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ },
45
+ "MyTableOrphanFileDeletionOptimizer": {
46
+ "Type": "AWS::Glue::TableOptimizer",
47
+ "DependsOn": "MyTable",
48
+ "Properties": {
49
+ "CatalogId": {
50
+ "Ref": "AWS::AccountId"
51
+ },
52
+ "DatabaseName": "my_database",
53
+ "TableName": "my_table",
54
+ "Type": "orphan_file_deletion",
55
+ "TableOptimizerConfiguration": {
56
+ "RoleArn": {
57
+ "Fn::GetAtt": [
58
+ "OrphanFileDeletionRole",
59
+ "Arn"
60
+ ]
61
+ },
62
+ "Enabled": true,
63
+ "OrphanFileDeletionConfiguration": {
64
+ "IcebergConfiguration": {
65
+ "OrphanFileRetentionPeriodInDays": 7,
66
+ "Location": "s3://fake/location/subdir"
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
72
+ },
73
+ "Outputs": {}
74
+ }
@@ -0,0 +1,62 @@
1
+ {
2
+ "AWSTemplateFormatVersion": "2010-09-09",
3
+ "Metadata": {},
4
+ "Parameters": {},
5
+ "Rules": {},
6
+ "Mappings": {},
7
+ "Conditions": {},
8
+ "Resources": {
9
+ "MyTable": {
10
+ "Type": "AWS::Glue::Table",
11
+ "Properties": {
12
+ "CatalogId": {
13
+ "Ref": "AWS::AccountId"
14
+ },
15
+ "DatabaseName": "my_database",
16
+ "Name": "my_table",
17
+ "OpenTableFormatInput": {
18
+ "IcebergInput": {
19
+ "MetadataOperation": "CREATE",
20
+ "Version": "2",
21
+ "IcebergTableInput": {
22
+ "Location": "s3://fake/location",
23
+ "Schema": {
24
+ "Type": "struct",
25
+ "Fields": [
26
+ {
27
+ "Name": "column",
28
+ "Type": "string",
29
+ "Id": 1,
30
+ "Required": true
31
+ }
32
+ ]
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ },
39
+ "MyTableOrphanFileDeletionOptimizer": {
40
+ "Type": "AWS::Glue::TableOptimizer",
41
+ "DependsOn": "MyTable",
42
+ "Properties": {
43
+ "CatalogId": {
44
+ "Ref": "AWS::AccountId"
45
+ },
46
+ "DatabaseName": "my_database",
47
+ "TableName": "my_table",
48
+ "Type": "orphan_file_deletion",
49
+ "TableOptimizerConfiguration": {
50
+ "RoleArn": "arn:aws:iam::123456789012:role/OrphanFileDeletionRole",
51
+ "Enabled": true,
52
+ "OrphanFileDeletionConfiguration": {
53
+ "IcebergConfiguration": {
54
+ "OrphanFileRetentionPeriodInDays": 3
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ },
61
+ "Outputs": {}
62
+ }
@@ -15,8 +15,13 @@ const noUndefined = (template) => JSON.parse(JSON.stringify(template));
15
15
  describe('[shortcuts] fixture validation', () => {
16
16
  // Runs cfn-lint, ignoring "warnings". Install via pip or Homebrew to run these
17
17
  // tests locally.
18
- const cfnLint = (filepath) => new Promise((resolve, reject) => {
19
- cp.exec(`cfn-lint ${filepath} --ignore-checks W`, (err, stdout) => {
18
+ const cfnLint = (filepath, filename) => new Promise((resolve, reject) => {
19
+ // Ignore E3003 (missing TableInput) and E3002 (unexpected properties) for Iceberg tables only
20
+ // cfn-lint doesn't yet support OpenTableFormatInput (Iceberg table format)
21
+ const isIcebergTable = filename.includes('glue-iceberg-table');
22
+ const ignoreChecks = isIcebergTable ? 'W,E3003,E3002' : 'W';
23
+
24
+ cp.execFile('cfn-lint', [filepath, '--ignore-checks', ignoreChecks], (err, stdout) => {
20
25
  if (err) return reject(new Error(stdout));
21
26
  return resolve();
22
27
  });
@@ -28,7 +33,7 @@ describe('[shortcuts] fixture validation', () => {
28
33
 
29
34
  test.each(toValidate)('%s fixture passes validation', async (filename) => {
30
35
  await Promise.all([
31
- cfnLint(path.join(__dirname, 'fixtures', 'shortcuts', filename)),
36
+ cfnLint(path.join(__dirname, 'fixtures', 'shortcuts', filename), filename),
32
37
  sleep(1000)
33
38
  ]);
34
39
  });
@@ -1246,6 +1251,292 @@ describe('[shortcuts] glue parquet table', () => {
1246
1251
  });
1247
1252
  });
1248
1253
 
1254
+ describe('[shortcuts] glue iceberg table', () => {
1255
+ test('throws without options', () => {
1256
+ expect(() => new cf.shortcuts.GlueIcebergTable()).toThrow('Options required');
1257
+ });
1258
+
1259
+ test('throws without required parameters', () => {
1260
+ expect(() => new cf.shortcuts.GlueIcebergTable({})).toThrow(/You must provide a LogicalName, Name, DatabaseName, Location, and Schema/);
1261
+ });
1262
+
1263
+ test('expected resources generated with defaults', () => {
1264
+ const db = new cf.shortcuts.GlueIcebergTable({
1265
+ LogicalName: 'MyTable',
1266
+ DatabaseName: 'my_database',
1267
+ Name: 'my_table',
1268
+ Schema: {
1269
+ Type: 'struct',
1270
+ Fields: [
1271
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1272
+ ]
1273
+ },
1274
+ Location: 's3://fake/location'
1275
+ });
1276
+
1277
+ const template = cf.merge(db);
1278
+ if (update) fixtures.update('glue-iceberg-table-defaults', template);
1279
+ expect(noUndefined(template)).toEqual(fixtures.get('glue-iceberg-table-defaults'));
1280
+ });
1281
+
1282
+ test('expected resources generated without defaults', () => {
1283
+ const db = new cf.shortcuts.GlueIcebergTable({
1284
+ LogicalName: 'MyTable',
1285
+ DatabaseName: 'my_database',
1286
+ Name: 'my_table',
1287
+ Schema: {
1288
+ Type: 'struct',
1289
+ Fields: [
1290
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1291
+ ]
1292
+ },
1293
+ CatalogId: '1234',
1294
+ Location: 's3://fake/location',
1295
+ IcebergVersion: '2'
1296
+ });
1297
+
1298
+ const template = cf.merge(db);
1299
+ if (update) fixtures.update('glue-iceberg-table-no-defaults', template);
1300
+ expect(noUndefined(template)).toEqual(fixtures.get('glue-iceberg-table-no-defaults'));
1301
+ });
1302
+
1303
+ test('throws when EnableOptimizer is true but OptimizerRoleArn is missing', () => {
1304
+ expect(() => new cf.shortcuts.GlueIcebergTable({
1305
+ LogicalName: 'MyTable',
1306
+ DatabaseName: 'my_database',
1307
+ Name: 'my_table',
1308
+ Schema: {
1309
+ Type: 'struct',
1310
+ Fields: [
1311
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1312
+ ]
1313
+ },
1314
+ Location: 's3://fake/location',
1315
+ EnableOptimizer: true
1316
+ })).toThrow(/You must provide an OptimizerRoleArn when EnableOptimizer is true/);
1317
+ });
1318
+
1319
+ test('expected resources generated with optimizer using default retention settings', () => {
1320
+ const db = new cf.shortcuts.GlueIcebergTable({
1321
+ LogicalName: 'MyTable',
1322
+ DatabaseName: 'my_database',
1323
+ Name: 'my_table',
1324
+ Schema: {
1325
+ Type: 'struct',
1326
+ Fields: [
1327
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1328
+ ]
1329
+ },
1330
+ Location: 's3://fake/location',
1331
+ EnableOptimizer: true,
1332
+ OptimizerRoleArn: 'arn:aws:iam::123456789012:role/OptimizerRole'
1333
+ });
1334
+
1335
+ const template = cf.merge(db);
1336
+ if (update) fixtures.update('glue-iceberg-table-with-optimizer-defaults', template);
1337
+ expect(noUndefined(template)).toEqual(fixtures.get('glue-iceberg-table-with-optimizer-defaults'));
1338
+ });
1339
+
1340
+ test('expected resources generated with optimizer using custom retention settings', () => {
1341
+ const db = new cf.shortcuts.GlueIcebergTable({
1342
+ LogicalName: 'MyTable',
1343
+ DatabaseName: 'my_database',
1344
+ Name: 'my_table',
1345
+ Schema: {
1346
+ Type: 'struct',
1347
+ Fields: [
1348
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1349
+ ]
1350
+ },
1351
+ Location: 's3://fake/location',
1352
+ EnableOptimizer: true,
1353
+ OptimizerRoleArn: cf.getAtt('OptimizerRole', 'Arn'),
1354
+ SnapshotRetentionPeriodInDays: 7,
1355
+ NumberOfSnapshotsToRetain: 3,
1356
+ CleanExpiredFiles: false
1357
+ });
1358
+
1359
+ const template = cf.merge(
1360
+ { Resources: { OptimizerRole: { Type: 'AWS::IAM::Role', Properties: { AssumeRolePolicyDocument: {} } } } },
1361
+ db
1362
+ );
1363
+ if (update) fixtures.update('glue-iceberg-table-with-optimizer-custom', template);
1364
+ expect(noUndefined(template)).toEqual(fixtures.get('glue-iceberg-table-with-optimizer-custom'));
1365
+ });
1366
+
1367
+ test('throws when EnableCompaction is true but CompactionRoleArn is missing', () => {
1368
+ expect(() => new cf.shortcuts.GlueIcebergTable({
1369
+ LogicalName: 'MyTable',
1370
+ DatabaseName: 'my_database',
1371
+ Name: 'my_table',
1372
+ Schema: {
1373
+ Type: 'struct',
1374
+ Fields: [
1375
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1376
+ ]
1377
+ },
1378
+ Location: 's3://fake/location',
1379
+ EnableCompaction: true
1380
+ })).toThrow(/You must provide a CompactionRoleArn when EnableCompaction is true/);
1381
+ });
1382
+
1383
+ test('expected resources generated with compaction using default settings', () => {
1384
+ const db = new cf.shortcuts.GlueIcebergTable({
1385
+ LogicalName: 'MyTable',
1386
+ DatabaseName: 'my_database',
1387
+ Name: 'my_table',
1388
+ Schema: {
1389
+ Type: 'struct',
1390
+ Fields: [
1391
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1392
+ ]
1393
+ },
1394
+ Location: 's3://fake/location',
1395
+ EnableCompaction: true,
1396
+ CompactionRoleArn: 'arn:aws:iam::123456789012:role/CompactionRole'
1397
+ });
1398
+
1399
+ const template = cf.merge(db);
1400
+ if (update) fixtures.update('glue-iceberg-table-with-compaction-defaults', template);
1401
+ expect(noUndefined(template)).toEqual(fixtures.get('glue-iceberg-table-with-compaction-defaults'));
1402
+ });
1403
+
1404
+ test('expected resources generated with compaction using custom settings', () => {
1405
+ const db = new cf.shortcuts.GlueIcebergTable({
1406
+ LogicalName: 'MyTable',
1407
+ DatabaseName: 'my_database',
1408
+ Name: 'my_table',
1409
+ Schema: {
1410
+ Type: 'struct',
1411
+ Fields: [
1412
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1413
+ ]
1414
+ },
1415
+ Location: 's3://fake/location',
1416
+ EnableCompaction: true,
1417
+ CompactionRoleArn: cf.getAtt('CompactionRole', 'Arn')
1418
+ });
1419
+
1420
+ const template = cf.merge(
1421
+ { Resources: { CompactionRole: { Type: 'AWS::IAM::Role', Properties: { AssumeRolePolicyDocument: {} } } } },
1422
+ db
1423
+ );
1424
+ if (update) fixtures.update('glue-iceberg-table-with-compaction-custom', template);
1425
+ expect(noUndefined(template)).toEqual(fixtures.get('glue-iceberg-table-with-compaction-custom'));
1426
+ });
1427
+
1428
+ test('expected resources generated with both retention and compaction optimizers', () => {
1429
+ const db = new cf.shortcuts.GlueIcebergTable({
1430
+ LogicalName: 'MyTable',
1431
+ DatabaseName: 'my_database',
1432
+ Name: 'my_table',
1433
+ Schema: {
1434
+ Type: 'struct',
1435
+ Fields: [
1436
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1437
+ ]
1438
+ },
1439
+ Location: 's3://fake/location',
1440
+ EnableOptimizer: true,
1441
+ OptimizerRoleArn: 'arn:aws:iam::123456789012:role/RetentionRole',
1442
+ EnableCompaction: true,
1443
+ CompactionRoleArn: 'arn:aws:iam::123456789012:role/CompactionRole'
1444
+ });
1445
+
1446
+ const template = cf.merge(db);
1447
+ if (update) fixtures.update('glue-iceberg-table-with-both-optimizers', template);
1448
+ expect(noUndefined(template)).toEqual(fixtures.get('glue-iceberg-table-with-both-optimizers'));
1449
+ });
1450
+
1451
+ test('throws when EnableOrphanFileDeletion is true but OrphanFileDeletionRoleArn is missing', () => {
1452
+ expect(() => new cf.shortcuts.GlueIcebergTable({
1453
+ LogicalName: 'MyTable',
1454
+ DatabaseName: 'my_database',
1455
+ Name: 'my_table',
1456
+ Schema: {
1457
+ Type: 'struct',
1458
+ Fields: [
1459
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1460
+ ]
1461
+ },
1462
+ Location: 's3://fake/location',
1463
+ EnableOrphanFileDeletion: true
1464
+ })).toThrow(/You must provide an OrphanFileDeletionRoleArn when EnableOrphanFileDeletion is true/);
1465
+ });
1466
+
1467
+ test('expected resources generated with orphan file deletion using default settings', () => {
1468
+ const db = new cf.shortcuts.GlueIcebergTable({
1469
+ LogicalName: 'MyTable',
1470
+ DatabaseName: 'my_database',
1471
+ Name: 'my_table',
1472
+ Schema: {
1473
+ Type: 'struct',
1474
+ Fields: [
1475
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1476
+ ]
1477
+ },
1478
+ Location: 's3://fake/location',
1479
+ EnableOrphanFileDeletion: true,
1480
+ OrphanFileDeletionRoleArn: 'arn:aws:iam::123456789012:role/OrphanFileDeletionRole'
1481
+ });
1482
+
1483
+ const template = cf.merge(db);
1484
+ if (update) fixtures.update('glue-iceberg-table-with-orphan-deletion-defaults', template);
1485
+ expect(noUndefined(template)).toEqual(fixtures.get('glue-iceberg-table-with-orphan-deletion-defaults'));
1486
+ });
1487
+
1488
+ test('expected resources generated with orphan file deletion using custom settings', () => {
1489
+ const db = new cf.shortcuts.GlueIcebergTable({
1490
+ LogicalName: 'MyTable',
1491
+ DatabaseName: 'my_database',
1492
+ Name: 'my_table',
1493
+ Schema: {
1494
+ Type: 'struct',
1495
+ Fields: [
1496
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1497
+ ]
1498
+ },
1499
+ Location: 's3://fake/location',
1500
+ EnableOrphanFileDeletion: true,
1501
+ OrphanFileDeletionRoleArn: cf.getAtt('OrphanFileDeletionRole', 'Arn'),
1502
+ OrphanFileRetentionPeriodInDays: 7,
1503
+ OrphanFileDeletionLocation: 's3://fake/location/subdir'
1504
+ });
1505
+
1506
+ const template = cf.merge(
1507
+ { Resources: { OrphanFileDeletionRole: { Type: 'AWS::IAM::Role', Properties: { AssumeRolePolicyDocument: {} } } } },
1508
+ db
1509
+ );
1510
+ if (update) fixtures.update('glue-iceberg-table-with-orphan-deletion-custom', template);
1511
+ expect(noUndefined(template)).toEqual(fixtures.get('glue-iceberg-table-with-orphan-deletion-custom'));
1512
+ });
1513
+
1514
+ test('expected resources generated with all three optimizers using same role', () => {
1515
+ const db = new cf.shortcuts.GlueIcebergTable({
1516
+ LogicalName: 'MyTable',
1517
+ DatabaseName: 'my_database',
1518
+ Name: 'my_table',
1519
+ Schema: {
1520
+ Type: 'struct',
1521
+ Fields: [
1522
+ { Name: 'column', Type: 'string', Id: 1, Required: true }
1523
+ ]
1524
+ },
1525
+ Location: 's3://fake/location',
1526
+ EnableOptimizer: true,
1527
+ OptimizerRoleArn: 'arn:aws:iam::123456789012:role/SharedRole',
1528
+ EnableCompaction: true,
1529
+ CompactionRoleArn: 'arn:aws:iam::123456789012:role/SharedRole',
1530
+ EnableOrphanFileDeletion: true,
1531
+ OrphanFileDeletionRoleArn: 'arn:aws:iam::123456789012:role/SharedRole'
1532
+ });
1533
+
1534
+ const template = cf.merge(db);
1535
+ if (update) fixtures.update('glue-iceberg-table-with-all-optimizers', template);
1536
+ expect(noUndefined(template)).toEqual(fixtures.get('glue-iceberg-table-with-all-optimizers'));
1537
+ });
1538
+ });
1539
+
1249
1540
  describe('[shortcuts] glue view', () => {
1250
1541
  test('throws without options', () => {
1251
1542
  expect(() => new cf.shortcuts.GluePrestoView()).toThrow('Options required');