Skip to content

Commit 615c5e0

Browse files
authored
Merge pull request #28 from greyshi/dryrun
fix: allow dry run to check if function exists
2 parents 612742f + 23d183e commit 615c5e0

File tree

5 files changed

+341
-266
lines changed

5 files changed

+341
-266
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ Validate parameters and permissions without any function code or configuration m
103103
code-artifacts-dir: my-code-artifacts-dir
104104
dry-run: true
105105
```
106+
**Note**: Dry run will still call `GetFunctionConfiguration` to check if the function exists and perform configuration diffs against what's currently deployed.
106107
## Build from Source
107108

108109
To automate building your source code, add a build step based on your runtime and build process. This build step should be performed before the AWS Lambda Deploy step, and AWS Lambda Deploy's `code-artifacts-dir` parameter will typically be set to the build step's code artifact output directory.

__tests__/dry_run_mode.test.js

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,73 @@ describe('Dry Run Mode Tests', () => {
3838

3939
await mainModule.run();
4040
});
41-
});
41+
42+
test('should check if function exists even in dry run mode', async () => {
43+
const mockSend = jest.fn()
44+
// First call: checkFunctionExists - function exists
45+
.mockResolvedValueOnce({ Runtime: 'nodejs18.x' })
46+
// Second call: GetFunctionConfigurationCommand for config check
47+
.mockResolvedValueOnce({ Runtime: 'nodejs18.x', MemorySize: 256 })
48+
// Third call: UpdateFunctionCodeCommand dry run
49+
.mockResolvedValueOnce({
50+
FunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:test-function',
51+
Version: '$LATEST'
52+
});
53+
54+
const mockClient = { send: mockSend };
55+
LambdaClient.mockImplementation(() => mockClient);
56+
57+
validations.validateAllInputs = jest.fn().mockReturnValue({
58+
valid: true,
59+
functionName: 'test-function',
60+
parsedEnvironment: {},
61+
dryRun: true,
62+
codeArtifactsDir: './code'
63+
});
64+
65+
jest.spyOn(mainModule, 'packageCodeArtifacts').mockResolvedValue('/tmp/test.zip');
66+
const fs = require('fs/promises');
67+
fs.readFile = jest.fn().mockResolvedValue(Buffer.from('test'));
68+
69+
await mainModule.run();
70+
71+
// Verify that checkFunctionExists was called (first send call should be GetFunctionConfigurationCommand)
72+
expect(mockSend).toHaveBeenCalled();
73+
expect(mockSend.mock.calls[0][0].constructor.name).toEqual('GetFunctionConfigurationCommand');
74+
75+
// Verify dry run proceeded successfully
76+
expect(core.info).toHaveBeenCalledWith('Checking if test-function exists');
77+
expect(core.info).toHaveBeenCalledWith('DRY RUN MODE: No AWS resources will be created or modified');
78+
expect(core.setFailed).not.toHaveBeenCalledWith('DRY RUN MODE can only be used for updating function code of existing functions');
79+
});
80+
81+
test('should fail dry run mode when function does not exist', async () => {
82+
const mockSend = jest.fn()
83+
// checkFunctionExists - function does not exist (ResourceNotFoundException)
84+
.mockRejectedValueOnce({ name: 'ResourceNotFoundException' });
85+
86+
const mockClient = { send: mockSend };
87+
LambdaClient.mockImplementation(() => mockClient);
88+
89+
validations.validateAllInputs = jest.fn().mockReturnValue({
90+
valid: true,
91+
functionName: 'non-existent-function',
92+
parsedEnvironment: {},
93+
dryRun: true,
94+
codeArtifactsDir: './code'
95+
});
96+
97+
jest.spyOn(mainModule, 'packageCodeArtifacts').mockResolvedValue('/tmp/test.zip');
98+
99+
await mainModule.run();
100+
101+
// Verify that checkFunctionExists was called (first send call should be GetFunctionConfigurationCommand)
102+
expect(mockSend).toHaveBeenCalled();
103+
expect(mockSend.mock.calls[0][0].constructor.name).toEqual('GetFunctionConfigurationCommand');
104+
105+
// Verify dry run failed with correct error message
106+
expect(core.info).toHaveBeenCalledWith('Checking if non-existent-function exists');
107+
expect(core.info).toHaveBeenCalledWith('DRY RUN MODE: No AWS resources will be created or modified');
108+
expect(core.setFailed).toHaveBeenCalledWith('DRY RUN MODE can only be used for updating function code of existing functions');
109+
});
110+
});

__tests__/s3_key_generation.test.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,26 @@ describe('S3 Key Generation and Dry Run Tests', () => {
3737
});
3838

3939
test('should log dry run message and fail when function does not exist', async () => {
40+
const mockSend = jest.fn()
41+
// checkFunctionExists - function does not exist (ResourceNotFoundException)
42+
.mockRejectedValueOnce({ name: 'ResourceNotFoundException' });
43+
44+
const mockClient = { send: mockSend };
45+
LambdaClient.mockImplementation(() => mockClient);
46+
4047
validations.validateAllInputs = jest.fn().mockReturnValue({
4148
valid: true,
4249
functionName: 'test-function',
43-
dryRun: true
50+
parsedEnvironment: {},
51+
dryRun: true,
52+
codeArtifactsDir: './code'
4453
});
4554

46-
jest.spyOn(mainModule, 'checkFunctionExists').mockResolvedValue(false);
55+
jest.spyOn(mainModule, 'packageCodeArtifacts').mockResolvedValue('/tmp/test.zip');
4756

4857
await mainModule.run();
4958

5059
expect(core.info).toHaveBeenCalledWith('DRY RUN MODE: No AWS resources will be created or modified');
5160
expect(core.setFailed).toHaveBeenCalledWith('DRY RUN MODE can only be used for updating function code of existing functions');
5261
});
53-
});
62+
});

0 commit comments

Comments
 (0)