|
1 | | -import { promises as fs } from 'fs'; |
| 1 | +import { promises as fs, existsSync } from 'fs'; |
2 | 2 | import * as os from 'os'; |
3 | 3 | import * as path from 'path'; |
4 | 4 | import { retry, sleep } from '../helpers/aws'; |
5 | 5 | import { cloneDirectory, MAJOR_VERSION, shell, withDefaultFixture } from '../helpers/cdk'; |
| 6 | +import { randomInteger, withSamIntegrationFixture } from '../helpers/sam'; |
6 | 7 | import { integTest } from '../helpers/test-helpers'; |
7 | 8 |
|
8 | 9 | jest.setTimeout(600_000); |
@@ -757,6 +758,222 @@ integTest('templates on disk contain metadata resource, also in nested assemblie |
757 | 758 | expect(JSON.parse(nestedTemplateContents).Resources.CDKMetadata).toBeTruthy(); |
758 | 759 | })); |
759 | 760 |
|
| 761 | +integTest('CDK synth add the metadata properties expected by sam', withSamIntegrationFixture(async (fixture) => { |
| 762 | + // Synth first |
| 763 | + await fixture.cdkSynth(); |
| 764 | + |
| 765 | + const template = fixture.template('TestStack'); |
| 766 | + |
| 767 | + const expectedResources = [ |
| 768 | + { |
| 769 | + // Python Layer Version |
| 770 | + id: 'PythonLayerVersion39495CEF', |
| 771 | + cdkId: 'PythonLayerVersion', |
| 772 | + isBundled: true, |
| 773 | + property: 'Content', |
| 774 | + }, |
| 775 | + { |
| 776 | + // Layer Version |
| 777 | + id: 'LayerVersion3878DA3A', |
| 778 | + cdkId: 'LayerVersion', |
| 779 | + isBundled: false, |
| 780 | + property: 'Content', |
| 781 | + }, |
| 782 | + { |
| 783 | + // Bundled layer version |
| 784 | + id: 'BundledLayerVersionPythonRuntime6BADBD6E', |
| 785 | + cdkId: 'BundledLayerVersionPythonRuntime', |
| 786 | + isBundled: true, |
| 787 | + property: 'Content', |
| 788 | + }, |
| 789 | + { |
| 790 | + // Python Function |
| 791 | + id: 'PythonFunction0BCF77FD', |
| 792 | + cdkId: 'PythonFunction', |
| 793 | + isBundled: true, |
| 794 | + property: 'Code', |
| 795 | + }, |
| 796 | + { |
| 797 | + // Log Retention Function |
| 798 | + id: 'LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A', |
| 799 | + cdkId: 'LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a', |
| 800 | + isBundled: false, |
| 801 | + property: 'Code', |
| 802 | + }, |
| 803 | + { |
| 804 | + // Function |
| 805 | + id: 'FunctionPythonRuntime28CBDA05', |
| 806 | + cdkId: 'FunctionPythonRuntime', |
| 807 | + isBundled: false, |
| 808 | + property: 'Code', |
| 809 | + }, |
| 810 | + { |
| 811 | + // Bundled Function |
| 812 | + id: 'BundledFunctionPythonRuntime4D9A0918', |
| 813 | + cdkId: 'BundledFunctionPythonRuntime', |
| 814 | + isBundled: true, |
| 815 | + property: 'Code', |
| 816 | + }, |
| 817 | + { |
| 818 | + // NodeJs Function |
| 819 | + id: 'NodejsFunction09C1F20F', |
| 820 | + cdkId: 'NodejsFunction', |
| 821 | + isBundled: true, |
| 822 | + property: 'Code', |
| 823 | + }, |
| 824 | + { |
| 825 | + // Go Function |
| 826 | + id: 'GoFunctionCA95FBAA', |
| 827 | + cdkId: 'GoFunction', |
| 828 | + isBundled: true, |
| 829 | + property: 'Code', |
| 830 | + }, |
| 831 | + { |
| 832 | + // Docker Image Function |
| 833 | + id: 'DockerImageFunction28B773E6', |
| 834 | + cdkId: 'DockerImageFunction', |
| 835 | + dockerFilePath: 'Dockerfile', |
| 836 | + property: 'Code.ImageUri', |
| 837 | + }, |
| 838 | + { |
| 839 | + // Spec Rest Api |
| 840 | + id: 'SpecRestAPI7D4B3A34', |
| 841 | + cdkId: 'SpecRestAPI', |
| 842 | + property: 'BodyS3Location', |
| 843 | + }, |
| 844 | + ]; |
| 845 | + |
| 846 | + for (const resource of expectedResources) { |
| 847 | + fixture.output.write(`validate assets metadata for resource ${resource}`); |
| 848 | + expect(resource.id in template.Resources).toBeTruthy(); |
| 849 | + expect(template.Resources[resource.id]).toEqual(expect.objectContaining({ |
| 850 | + Metadata: { |
| 851 | + 'aws:cdk:path': `${fixture.fullStackName('TestStack')}/${resource.cdkId}/Resource`, |
| 852 | + 'aws:asset:path': expect.stringMatching(/asset\.[0-9a-zA-Z]{64}/), |
| 853 | + 'aws:asset:is-bundled': resource.isBundled, |
| 854 | + 'aws:asset:dockerfile-path': resource.dockerFilePath, |
| 855 | + 'aws:asset:property': resource.property, |
| 856 | + }, |
| 857 | + })); |
| 858 | + } |
| 859 | + |
| 860 | + // Nested Stack |
| 861 | + fixture.output.write('validate assets metadata for nested stack resource'); |
| 862 | + expect('NestedStackNestedStackNestedStackNestedStackResourceB70834FD' in template.Resources).toBeTruthy(); |
| 863 | + expect(template.Resources.NestedStackNestedStackNestedStackNestedStackResourceB70834FD).toEqual(expect.objectContaining({ |
| 864 | + Metadata: { |
| 865 | + 'aws:cdk:path': `${fixture.fullStackName('TestStack')}/NestedStack.NestedStack/NestedStack.NestedStackResource`, |
| 866 | + 'aws:asset:path': expect.stringMatching(`${fixture.stackNamePrefix.replace(/-/, '')}TestStackNestedStack[0-9A-Z]{8}\.nested\.template\.json`), |
| 867 | + 'aws:asset:property': 'TemplateURL', |
| 868 | + }, |
| 869 | + })); |
| 870 | +})); |
| 871 | + |
| 872 | +integTest('CDK synth bundled functions as expected', withSamIntegrationFixture(async (fixture) => { |
| 873 | + // Synth first |
| 874 | + await fixture.cdkSynth(); |
| 875 | + |
| 876 | + const template = fixture.template('TestStack'); |
| 877 | + |
| 878 | + const expectedBundledAssets = [ |
| 879 | + { |
| 880 | + // Python Layer Version |
| 881 | + id: 'PythonLayerVersion39495CEF', |
| 882 | + files: [ |
| 883 | + 'python/layer_version_dependency.py', |
| 884 | + 'python/geonamescache/__init__.py', |
| 885 | + 'python/geonamescache-1.3.0.dist-info', |
| 886 | + ], |
| 887 | + }, |
| 888 | + { |
| 889 | + // Layer Version |
| 890 | + id: 'LayerVersion3878DA3A', |
| 891 | + files: [ |
| 892 | + 'layer_version_dependency.py', |
| 893 | + 'requirements.txt', |
| 894 | + ], |
| 895 | + }, |
| 896 | + { |
| 897 | + // Bundled layer version |
| 898 | + id: 'BundledLayerVersionPythonRuntime6BADBD6E', |
| 899 | + files: [ |
| 900 | + 'python/layer_version_dependency.py', |
| 901 | + 'python/geonamescache/__init__.py', |
| 902 | + 'python/geonamescache-1.3.0.dist-info', |
| 903 | + ], |
| 904 | + }, |
| 905 | + { |
| 906 | + // Python Function |
| 907 | + id: 'PythonFunction0BCF77FD', |
| 908 | + files: [ |
| 909 | + 'app.py', |
| 910 | + 'geonamescache/__init__.py', |
| 911 | + 'geonamescache-1.3.0.dist-info', |
| 912 | + ], |
| 913 | + }, |
| 914 | + { |
| 915 | + // Function |
| 916 | + id: 'FunctionPythonRuntime28CBDA05', |
| 917 | + files: [ |
| 918 | + 'app.py', |
| 919 | + 'requirements.txt', |
| 920 | + ], |
| 921 | + }, |
| 922 | + { |
| 923 | + // Bundled Function |
| 924 | + id: 'BundledFunctionPythonRuntime4D9A0918', |
| 925 | + files: [ |
| 926 | + 'app.py', |
| 927 | + 'geonamescache/__init__.py', |
| 928 | + 'geonamescache-1.3.0.dist-info', |
| 929 | + ], |
| 930 | + }, |
| 931 | + { |
| 932 | + // NodeJs Function |
| 933 | + id: 'NodejsFunction09C1F20F', |
| 934 | + files: [ |
| 935 | + 'index.js', |
| 936 | + ], |
| 937 | + }, |
| 938 | + { |
| 939 | + // Go Function |
| 940 | + id: 'GoFunctionCA95FBAA', |
| 941 | + files: [ |
| 942 | + 'bootstrap', |
| 943 | + ], |
| 944 | + }, |
| 945 | + { |
| 946 | + // Docker Image Function |
| 947 | + id: 'DockerImageFunction28B773E6', |
| 948 | + files: [ |
| 949 | + 'app.js', |
| 950 | + 'Dockerfile', |
| 951 | + 'package.json', |
| 952 | + ], |
| 953 | + }, |
| 954 | + ]; |
| 955 | + |
| 956 | + for (const resource of expectedBundledAssets) { |
| 957 | + const assetPath = template.Resources[resource.id].Metadata['aws:asset:path']; |
| 958 | + for (const file of resource.files) { |
| 959 | + fixture.output.write(`validate Path ${file} for resource ${resource}`); |
| 960 | + expect(existsSync(path.join(fixture.integTestDir, 'cdk.out', assetPath, file))).toBeTruthy(); |
| 961 | + } |
| 962 | + } |
| 963 | +})); |
| 964 | + |
| 965 | +integTest('sam can locally test the synthesized cdk application', withSamIntegrationFixture(async (fixture) => { |
| 966 | + // Synth first |
| 967 | + await fixture.cdkSynth(); |
| 968 | + |
| 969 | + const result = await fixture.samLocalStartApi( |
| 970 | + 'TestStack', false, randomInteger(30000, 40000), '/restapis/spec/pythonFunction'); |
| 971 | + expect(result.actionSucceeded).toBeTruthy(); |
| 972 | + expect(result.actionOutput).toEqual(expect.objectContaining({ |
| 973 | + message: 'Hello World', |
| 974 | + })); |
| 975 | +})); |
| 976 | + |
760 | 977 | integTest('skips notice refresh', withDefaultFixture(async (fixture) => { |
761 | 978 | const output = await fixture.cdkSynth({ |
762 | 979 | options: ['--no-notices'], |
|
0 commit comments