From c99e794d26d5c2685f7731a434067d8e198013c7 Mon Sep 17 00:00:00 2001 From: "gh-worker-campaigns-3e9aa4[bot]" <244854796+gh-worker-campaigns-3e9aa4[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 19:16:10 +0000 Subject: [PATCH] sync shared e2e code --- e2e/helpers/AGENTS.md | 5 +++++ e2e/helpers/CLAUDE.md | 1 + e2e/helpers/exec.ts | 9 ++++++--- e2e/helpers/lambda-telemetry-checker.ts | 3 +++ e2e/helpers/lambda-verifier.ts | 16 +++++++++++++++- 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 e2e/helpers/AGENTS.md create mode 100644 e2e/helpers/CLAUDE.md diff --git a/e2e/helpers/AGENTS.md b/e2e/helpers/AGENTS.md new file mode 100644 index 00000000..f09a0497 --- /dev/null +++ b/e2e/helpers/AGENTS.md @@ -0,0 +1,5 @@ +# Shared E2E helpers + +Do not edit the generated helper files in this repository. Change the source files in `serverless-ci/e2e/shared/{go,ts}/` and open a PR in `serverless-ci`; the sync campaign distributes the update. + +Keep helpers runner-agnostic and free of repository-specific configuration. Put tool/platform-specific assertions and configuration in this repository. diff --git a/e2e/helpers/CLAUDE.md b/e2e/helpers/CLAUDE.md new file mode 100644 index 00000000..43c994c2 --- /dev/null +++ b/e2e/helpers/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/e2e/helpers/exec.ts b/e2e/helpers/exec.ts index abec21b6..30000596 100644 --- a/e2e/helpers/exec.ts +++ b/e2e/helpers/exec.ts @@ -27,6 +27,7 @@ export interface ExecOptions { // Serverless / AWS / CFN calls can emit large output; default generous but bounded. // CFN deploys need ~16MB; sls/cdk need more, so callers raise it as needed. maxBuffer?: number; + logOutput?: boolean; // Transient cloud-provider error substrings safe to retry. Supplied by the caller so // each cloud/tool contributes its own patterns; empty means never retry. retryPatterns?: string[]; @@ -39,7 +40,7 @@ const DEFAULT_MAX_ATTEMPTS = 3; const DEFAULT_DELAY_SECONDS = 10; export const execPromise = async (command: string, options: ExecOptions = {}): Promise => { - const {env, cwd, maxBuffer = DEFAULT_MAX_BUFFER} = options; + const {env, cwd, maxBuffer = DEFAULT_MAX_BUFFER, logOutput = true} = options; return new Promise((resolve) => { const child = child_process.exec(command, {env: {...process.env, ...env}, cwd, maxBuffer}, (error, stdout, stderr) => { @@ -50,8 +51,10 @@ export const execPromise = async (command: string, options: ExecOptions = {}): P }); }); - child.stdout?.pipe(process.stdout); - child.stderr?.pipe(process.stderr); + if (logOutput) { + child.stdout?.pipe(process.stdout); + child.stderr?.pipe(process.stderr); + } }); }; diff --git a/e2e/helpers/lambda-telemetry-checker.ts b/e2e/helpers/lambda-telemetry-checker.ts index 0954909e..cf6c11ff 100644 --- a/e2e/helpers/lambda-telemetry-checker.ts +++ b/e2e/helpers/lambda-telemetry-checker.ts @@ -90,6 +90,9 @@ const buildConfiguration = (): client.Configuration => { apiKeyAuth: process.env.DATADOG_API_KEY ?? process.env.DD_API_KEY, appKeyAuth: process.env.DATADOG_APP_KEY ?? process.env.DD_APP_KEY, }, + // node-fetch can fail while decoding compressed search responses. Requesting + // identity encoding keeps polling reliable without changing request payloads. + httpConfig: {compress: false}, }); const site = process.env.DATADOG_SITE ?? process.env.DD_SITE; if (site) { diff --git a/e2e/helpers/lambda-verifier.ts b/e2e/helpers/lambda-verifier.ts index 15692f3d..382f5b5c 100644 --- a/e2e/helpers/lambda-verifier.ts +++ b/e2e/helpers/lambda-verifier.ts @@ -68,10 +68,24 @@ export interface LambdaVerifierConfig { const getConfiguration = async (fnName: string, region: string): Promise => { const result = await execPromise( `aws lambda get-function-configuration --function-name "${fnName}" --region "${region}" --output json`, + {logOutput: false}, ); assert.equal(result.exitCode, 0, `get-function-configuration failed: ${result.stderr}`); - return JSON.parse(result.stdout) as LambdaConfiguration; + const configuration = JSON.parse(result.stdout) as LambdaConfiguration; + const variables = configuration.Environment?.Variables; + if (variables !== undefined) { + const redactedVariables = Object.fromEntries( + Object.keys(variables).map((key) => [key, '[redacted]']), + ); + // eslint-disable-next-line no-console + console.log(JSON.stringify({...configuration, Environment: {Variables: redactedVariables}}, null, 2)); + } else { + // eslint-disable-next-line no-console + console.log(JSON.stringify(configuration, null, 2)); + } + + return configuration; }; const getTags = async (functionArn: string, region: string): Promise> => {