Skip to content

Commit ba921c1

Browse files
Alexander Schuerendreamorosi
Alexander Schueren
andauthored
tests(parameters): add comments to SecretsProvider e2e test (#1282)
* fix import to src, instead of lib * clearing cache to fix forceFetch test case * add more comments, create dedicated resource for test 7 * Update packages/parameters/tests/e2e/secretsProvider.class.test.functionCode.ts --------- Co-authored-by: Andrea Amorosi <[email protected]>
1 parent 61080da commit ba921c1

File tree

2 files changed

+74
-38
lines changed

2 files changed

+74
-38
lines changed

Diff for: packages/parameters/tests/e2e/secretsProvider.class.test.functionCode.ts

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { Context } from 'aws-lambda';
2-
import { SecretsProvider } from '../../lib/secrets';
32
import { TinyLogger } from '../helpers/tinyLogger';
4-
import { SecretsGetOptionsInterface } from '../../lib/types';
53
import { SecretsManagerClient } from '@aws-sdk/client-secrets-manager';
64
import { middleware } from '../helpers/sdkMiddlewareRequestCounter';
5+
import { SecretsProvider } from '../../src/secrets';
6+
import { SecretsGetOptionsInterface } from '../../src/types';
77

88
const logger = new TinyLogger();
99
const defaultProvider = new SecretsProvider();
@@ -14,6 +14,7 @@ const secretNameBinary = process.env.SECRET_NAME_BINARY || '';
1414
const secretNameObjectWithSuffix = process.env.SECRET_NAME_OBJECT_WITH_SUFFIX || '';
1515
const secretNameBinaryWithSuffix = process.env.SECRET_NAME_BINARY_WITH_SUFFIX || '';
1616
const secretNamePlainChached = process.env.SECRET_NAME_PLAIN_CACHED || '';
17+
const secretNamePlainForceFetch = process.env.SECRET_NAME_PLAIN_FORCE_FETCH || '';
1718

1819
// Provider test 8, 9
1920
const customClient = new SecretsManagerClient({});
@@ -42,23 +43,23 @@ const _call_get = async (paramName: string, testName: string, options?: SecretsG
4243

4344
export const handler = async (_event: unknown, _context: Context): Promise<void> => {
4445

45-
// Test 1 get single param as plaintext
46+
// Test 1 get single secret as plaintext
4647
await _call_get(secretNamePlain, 'get-plain');
4748

48-
// Test 2 get single param with transform json
49+
// Test 2 get single secret with transform json
4950
await _call_get(secretNameObject, 'get-transform-json', { transform: 'json' });
5051

51-
// Test 3 get single param with transform binary
52+
// Test 3 get single secret with transform binary
5253
await _call_get(secretNameBinary, 'get-transform-binary', { transform: 'binary' });
5354

54-
// Test 4 get single param with transform auto json
55+
// Test 4 get single secret with transform auto json
5556
await _call_get(secretNameObjectWithSuffix, 'get-transform-auto-json', { transform: 'auto' });
5657

57-
// Test 5 get single param with transform auto binary
58+
// Test 5 get single secret with transform auto binary
5859
await _call_get(secretNameBinaryWithSuffix, 'get-transform-auto-binary', { transform: 'auto' });
5960

6061
// Test 6
61-
// get parameter twice with middleware, which counts number of SDK requests, we check later if we only called SecretManager API once
62+
// get secret twice with middleware, which counts number of SDK requests, we check later if we only called SecretManager API once
6263
try {
6364
middleware.counter = 0;
6465
await providerWithMiddleware.get(secretNamePlainChached);
@@ -74,11 +75,12 @@ export const handler = async (_event: unknown, _context: Context): Promise<void>
7475
});
7576
}
7677
// Test 7
77-
// get parameter twice, but force fetch 2nd time, we count number of SDK requests and check that we made two API calls
78+
// get secret twice, but force fetch 2nd time, we count number of SDK requests and check that we made two API calls
7879
try {
7980
middleware.counter = 0;
80-
await providerWithMiddleware.get(secretNamePlainChached);
81-
await providerWithMiddleware.get(secretNamePlainChached, { forceFetch: true });
81+
providerWithMiddleware.clearCache();
82+
await providerWithMiddleware.get(secretNamePlainForceFetch);
83+
await providerWithMiddleware.get(secretNamePlainForceFetch, { forceFetch: true });
8284
logger.log({
8385
test: 'get-plain-force',
8486
value: middleware.counter // should be 2

Diff for: packages/parameters/tests/e2e/secretsProvider.class.test.ts

+61-27
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,51 @@ const runtime: string = process.env.RUNTIME || 'nodejs18x';
2424
if (!isValidRuntimeKey(runtime)) {
2525
throw new Error(`Invalid runtime key: ${runtime}`);
2626
}
27-
28-
const uuid = v4();
29-
const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'secretsProvider');
30-
const functionName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'secretsProvider');
31-
const lambdaFunctionCodeFile = 'secretsProvider.class.test.functionCode.ts';
32-
33-
const secretNamePlain = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretPlain');
34-
const secretNamePlainCached = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretPlainCached');
35-
const secretNameObject = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretObject');
36-
const secretNameBinary = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretBinary');
37-
const secretNameObjectWithSuffix = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretObject.json');
38-
const secretNameBinaryWithSuffix = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretObject.binary');
39-
40-
const invocationCount = 1;
41-
42-
const integTestApp = new App();
43-
let stack: Stack;
44-
27+
/**
28+
* Collection of e2e tests for SecretsProvider utility.
29+
*
30+
* Test 1: create a secret with plain text value, fetch it with no additional options
31+
* Test 2: create a secret with json value, fetch it using `transform: 'json'` option
32+
* Test 3: create a secret with base64 encoded value (technicaly string), fetch it using `transform: 'binary'` option
33+
* Test 4: create a secret with json value and secret name ends with .json, fetch it using `transform: 'auto'` option
34+
* Test 5: create a secret with base64 encoded value (technicaly string) and secert name ends with .binary, fetch it using `transform: 'auto'` option
35+
* Test 6: create a secret with plain text value, fetch it twice, check that value was cached, the number of SDK calls should be 1
36+
* Test 7: create a secret with plain text value, fetch it twice, second time with `forceFetch: true` option, check that value was not cached, the number of SDK calls should be 2
37+
*
38+
* For tests 6 and 7 we use our own AWS SDK custom middleware plugin `sdkMiddlewareRequestCounter.ts`
39+
*
40+
* Adding new test:
41+
* Please keep the state clean, and create dedicated resource for your test, don't reuse resources from other tests.
42+
* Pass the necessary information to lambda function by using enviroment variables
43+
* Make sure to add the right permissions to the lambda function to access the resources. We use our `ResourceAccessGranter` to add permissions.
44+
*
45+
*/
4546
describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () => {
4647

48+
const uuid = v4();
4749
let invocationLogs: InvocationLogs[];
50+
const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'secretsProvider');
51+
const functionName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'secretsProvider');
52+
const lambdaFunctionCodeFile = 'secretsProvider.class.test.functionCode.ts';
53+
54+
const invocationCount = 1;
55+
56+
const integTestApp = new App();
57+
let stack: Stack;
4858

4959
beforeAll(async () => {
60+
61+
// use unique names for each test to keep a clean state
62+
const secretNamePlain = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretPlain');
63+
const secretNameObject = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretObject');
64+
const secretNameBinary = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretBinary');
65+
const secretNameObjectWithSuffix = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretObject.json');
66+
const secretNameBinaryWithSuffix = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretObject.binary');
67+
const secretNamePlainCached = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretPlainCached');
68+
const secretNamePlainForceFetch = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'testSecretPlainForceFetch');
69+
70+
// creates the test fuction that uses powertools secret provider we want to test
71+
// pass env vars with secret names we want to fetch
5072
stack = createStackWithLambdaFunction({
5173
app: integTestApp,
5274
stackName: stackName,
@@ -61,6 +83,7 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () =>
6183
SECRET_NAME_OBJECT_WITH_SUFFIX: secretNameObjectWithSuffix,
6284
SECRET_NAME_BINARY_WITH_SUFFIX: secretNameBinaryWithSuffix,
6385
SECRET_NAME_PLAIN_CACHED: secretNamePlainCached,
86+
SECRET_NAME_PLAIN_FORCE_FETCH: secretNamePlainForceFetch,
6487
},
6588
runtime: runtime
6689
});
@@ -99,7 +122,14 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () =>
99122
secretStringValue: SecretValue.unsafePlainText('foo')
100123
});
101124

102-
Aspects.of(stack).add(new ResourceAccessGranter([ secretString, secretObject, secretBinary, secretObjectWithSuffix, secretBinaryWithSuffix, secretStringCached ]));
125+
const secretStringForceFetch = new Secret(stack, 'testSecretStringForceFetch', {
126+
secretName: secretNamePlainForceFetch,
127+
secretStringValue: SecretValue.unsafePlainText('foo')
128+
});
129+
130+
// add secrets here to grant lambda permisisons to access secrets
131+
Aspects.of(stack).add(new ResourceAccessGranter([
132+
secretString, secretObject, secretBinary, secretObjectWithSuffix, secretBinaryWithSuffix, secretStringCached, secretStringForceFetch ]));
103133

104134
await deployStack(integTestApp, stack);
105135

@@ -108,7 +138,8 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () =>
108138
}, SETUP_TIMEOUT);
109139

110140
describe('SecretsProvider usage', () => {
111-
it('should retrieve a single parameter', async () => {
141+
142+
it('should retrieve a secret as plain string', async () => {
112143

113144
const logs = invocationLogs[0].getFunctionLogs();
114145
const testLog = InvocationLogs.parseFunctionLog(logs[0]);
@@ -119,7 +150,7 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () =>
119150
});
120151
}, TEST_CASE_TIMEOUT);
121152

122-
it('should retrieve a single parameter with transform json', async () => {
153+
it('should retrieve a secret using transform json option', async () => {
123154
const logs = invocationLogs[0].getFunctionLogs();
124155
const testLog = InvocationLogs.parseFunctionLog(logs[1]);
125156

@@ -129,7 +160,7 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () =>
129160
});
130161
}, TEST_CASE_TIMEOUT);
131162

132-
it('should retrieve single param with transform binary', async () => {
163+
it('should retrieve a secret using transform binary option', async () => {
133164
const logs = invocationLogs[0].getFunctionLogs();
134165
const testLog = InvocationLogs.parseFunctionLog(logs[2]);
135166

@@ -140,17 +171,18 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () =>
140171
}, TEST_CASE_TIMEOUT);
141172
});
142173

143-
it('should retrieve single param with transform auto json', async () => {
174+
it('should retrieve a secret using transform auto option with implicit json', async () => {
144175
const logs = invocationLogs[0].getFunctionLogs();
145176
const testLog = InvocationLogs.parseFunctionLog(logs[3]);
146177

178+
// result should be a json object
147179
expect(testLog).toStrictEqual({
148180
test: 'get-transform-auto-json',
149181
value: { foo: 'bar' }
150182
});
151183
}, TEST_CASE_TIMEOUT);
152184

153-
it('should retrieve single param wit transform auto binary', async () => {
185+
it('should retrieve a secret using transform auto option with implicit binary', async () => {
154186
const logs = invocationLogs[0].getFunctionLogs();
155187
const testLog = InvocationLogs.parseFunctionLog(logs[4]);
156188

@@ -160,23 +192,25 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () =>
160192
});
161193
});
162194

163-
it('should retrieve single parameter cached', async () => {
195+
it('should retrieve a secret twice with cached value', async () => {
164196
const logs = invocationLogs[0].getFunctionLogs();
165197
const testLogFirst = InvocationLogs.parseFunctionLog(logs[5]);
166198

199+
// we fetch twice, but we expect to make an API call only once
167200
expect(testLogFirst).toStrictEqual({
168201
test: 'get-plain-cached',
169202
value: 1
170203
});
171204
});
172205

173-
it('should retrieve single parameter twice without caching', async () => {
206+
it('should retrieve a secret twice with forceFetch second time', async () => {
174207
const logs = invocationLogs[0].getFunctionLogs();
175208
const testLogFirst = InvocationLogs.parseFunctionLog(logs[6]);
176209

210+
// we fetch twice, 2nd time with forceFetch: true flag, we expect two api calls
177211
expect(testLogFirst).toStrictEqual({
178212
test: 'get-plain-force',
179-
value: 1
213+
value: 2
180214
});
181215
});
182216

0 commit comments

Comments
 (0)