diff --git a/packages/logger/tests/unit/formatters.test.ts b/packages/logger/tests/unit/formatters.test.ts index e826cbd6a5..f5ed37f419 100644 --- a/packages/logger/tests/unit/formatters.test.ts +++ b/packages/logger/tests/unit/formatters.test.ts @@ -1,5 +1,13 @@ import { AssertionError } from 'node:assert'; -import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest'; +import { + afterAll, + afterEach, + beforeEach, + describe, + expect, + it, + vi, +} from 'vitest'; import { PowertoolsLogFormatter } from '../../src/formatter/PowertoolsLogFormatter.js'; import { LogFormatter, @@ -53,13 +61,8 @@ const unformattedAttributes: UnformattedAttributes = { }, }; -process.env.POWERTOOLS_DEV = 'true'; - -const logger = new Logger(); - const jsonReplacerFn: CustomJsonReplacerFn = (_: string, value: unknown) => value instanceof Set ? [...value] : value; -const loggerWithReplacer = new Logger({ jsonReplacerFn }); /** * A custom log formatter that formats logs using only the message, log level as a number, and timestamp. @@ -90,15 +93,19 @@ class CustomFormatter extends LogFormatter { ); } } -const loggerWithCustomLogFormatter = new Logger({ - logFormatter: new CustomFormatter(), -}); describe('Formatters', () => { - const ENVIRONMENT_VARIABLES = process.env; + // Ensure dev mode is on for logger initialization + vi.stubEnv('POWERTOOLS_DEV', 'true'); + const logger = new Logger(); + const loggerWithReplacer = new Logger({ jsonReplacerFn }); + const loggerWithCustomLogFormatter = new Logger({ + logFormatter: new CustomFormatter(), + }); + vi.unstubAllEnvs(); beforeEach(() => { - process.env = { ...ENVIRONMENT_VARIABLES }; + vi.stubEnv('POWERTOOLS_DEV', 'true'); const mockDate = new Date(1466424490000); vi.useFakeTimers().setSystemTime(mockDate); vi.clearAllMocks(); @@ -109,6 +116,10 @@ describe('Formatters', () => { vi.useRealTimers(); }); + afterEach(() => { + vi.unstubAllEnvs(); + }); + // #region base log keys it('formats the base log keys', () => { @@ -451,8 +462,7 @@ describe('Formatters', () => { it('formats stack as string when not in dev mode', () => { // Prepare - const originalDevMode = process.env.POWERTOOLS_DEV; - delete process.env.POWERTOOLS_DEV; // Ensure dev mode is off + vi.stubEnv('POWERTOOLS_DEV', 'false'); // Ensure dev mode is off const error = new Error('Test error'); const formatter = new PowertoolsLogFormatter(); @@ -463,9 +473,6 @@ describe('Formatters', () => { // Assess expect(formattedError.stack).toEqual(expect.any(String)); expect(Array.isArray(formattedError.stack)).toBe(false); - - // Cleanup - process.env.POWERTOOLS_DEV = originalDevMode; }); it('formats custom errors by including only enumerable properties', () => { @@ -528,7 +535,7 @@ describe('Formatters', () => { it('formats the timestamp to ISO 8601, accounting for the `America/New_York` timezone offset', () => { // Prepare - process.env.TZ = 'America/New_York'; + vi.stubEnv('TZ', 'America/New_York'); /* Difference between UTC and `America/New_York`(GMT -04.00) is 240 minutes. The positive value indicates that `America/New_York` is behind UTC. @@ -544,7 +551,7 @@ describe('Formatters', () => { it('formats the timestamp to ISO 8601 with correct milliseconds for `America/New_York` timezone', () => { // Prepare - process.env.TZ = 'America/New_York'; + vi.stubEnv('TZ', 'America/New_York'); /* Difference between UTC and `America/New_York`(GMT -04.00) is 240 minutes. The positive value indicates that `America/New_York` is behind UTC. @@ -560,7 +567,7 @@ describe('Formatters', () => { it('formats the timestamp to ISO 8601, adjusting for `America/New_York` timezone, preserving milliseconds and accounting for date change', () => { // Prepare - process.env.TZ = 'America/New_York'; + vi.stubEnv('TZ', 'America/New_York'); /* Difference between UTC and `America/New_York`(GMT -04.00) is 240 minutes. The positive value indicates that `America/New_York` is behind UTC. @@ -576,7 +583,7 @@ describe('Formatters', () => { it('it formats the timestamp to ISO 8601 with correct milliseconds for `Asia/Dhaka` timezone', () => { // Prepare - process.env.TZ = 'Asia/Dhaka'; + vi.stubEnv('TZ', 'Asia/Dhaka'); vi.setSystemTime(new Date('2016-06-20T12:08:10.910Z')); /* Difference between UTC and `Asia/Dhaka`(GMT +06.00) is 360 minutes. @@ -594,7 +601,7 @@ describe('Formatters', () => { it('formats the timestamp to ISO 8601, adjusting for `Asia/Dhaka` timezone, preserving milliseconds and accounting for date change', () => { // Prepare - process.env.TZ = 'Asia/Dhaka'; + vi.stubEnv('TZ', 'Asia/Dhaka'); const mockDate = new Date('2016-06-20T20:08:10.910Z'); vi.setSystemTime(mockDate); /* @@ -613,7 +620,7 @@ describe('Formatters', () => { it('returns defaults to :UTC when an env variable service is not set', () => { // Prepare - process.env.TZ = undefined; + vi.stubEnv('TZ', undefined); vi.spyOn(Date.prototype, 'getTimezoneOffset').mockReturnValue(-360); const formatter = new PowertoolsLogFormatter(); @@ -627,7 +634,7 @@ describe('Formatters', () => { it('defaults to :UTC when the TZ env variable is set to :/etc/localtime', () => { // Prepare - process.env.TZ = ':/etc/localtime'; + vi.stubEnv('TZ', ':/etc/localtime'); vi.spyOn(Date.prototype, 'getTimezoneOffset').mockReturnValue(0); const formatter = new PowertoolsLogFormatter(); diff --git a/packages/logger/tests/unit/initializeLogger.test.ts b/packages/logger/tests/unit/initializeLogger.test.ts index 2a1a53c76b..1e2f4c9224 100644 --- a/packages/logger/tests/unit/initializeLogger.test.ts +++ b/packages/logger/tests/unit/initializeLogger.test.ts @@ -1,18 +1,28 @@ -import { beforeEach, describe, expect, it, type Mock, vi } from 'vitest'; +import { + afterEach, + beforeEach, + describe, + expect, + it, + type Mock, + vi, +} from 'vitest'; import { LogJsonIndent, LogLevel } from '../../src/constants.js'; import { Logger } from '../../src/Logger.js'; describe('Log levels', () => { - const ENVIRONMENT_VARIABLES = process.env; - beforeEach(() => { - process.env = { ...ENVIRONMENT_VARIABLES, POWERTOOLS_DEV: 'true' }; + vi.stubEnv('POWERTOOLS_DEV', 'true'); vi.clearAllMocks(); }); + afterEach(() => { + vi.unstubAllEnvs(); + }); + it('uses the default service name when none is provided', () => { // Prepare - process.env.POWERTOOLS_SERVICE_NAME = undefined; + vi.stubEnv('POWERTOOLS_SERVICE_NAME', undefined); const logger = new Logger(); // Act @@ -28,7 +38,7 @@ describe('Log levels', () => { it('uses service name specified in environment variables', () => { // Prepare - process.env.POWERTOOLS_SERVICE_NAME = 'hello-world'; + vi.stubEnv('POWERTOOLS_SERVICE_NAME', 'hello-world'); const logger = new Logger(); // Act @@ -44,7 +54,7 @@ describe('Log levels', () => { it('uses service name specified in the constructor', () => { // Prepare - process.env.POWERTOOLS_SERVICE_NAME = undefined; + vi.stubEnv('POWERTOOLS_SERVICE_NAME', undefined); const logger = new Logger({ serviceName: 'hello-world' }); // Act @@ -60,7 +70,7 @@ describe('Log levels', () => { it('overrides the service name when creating a child logger', () => { // Prepare - process.env.POWERTOOLS_SERVICE_NAME = 'hello-world'; + vi.stubEnv('POWERTOOLS_SERVICE_NAME', 'hello-world'); const logger = new Logger(); const childLogger = logger.createChild({ serviceName: 'child-service' }); @@ -127,7 +137,7 @@ describe('Log levels', () => { it("doesn't use the global console object by default", () => { // Prepare - process.env.POWERTOOLS_DEV = undefined; + vi.stubEnv('POWERTOOLS_DEV', undefined); const logger = new Logger(); // Assess diff --git a/packages/logger/tests/unit/injectLambdaContext.test.ts b/packages/logger/tests/unit/injectLambdaContext.test.ts index 606ce60ca2..48ad337693 100644 --- a/packages/logger/tests/unit/injectLambdaContext.test.ts +++ b/packages/logger/tests/unit/injectLambdaContext.test.ts @@ -1,7 +1,7 @@ import context from '@aws-lambda-powertools/testing-utils/context'; import middy from '@middy/core'; import type { Context } from 'aws-lambda'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { search } from '../../src/correlationId.js'; import { Logger } from '../../src/Logger.js'; import { injectLambdaContext } from '../../src/middleware/middy.js'; @@ -20,16 +20,15 @@ const getContextLogEntries = (overrides?: Record) => ({ }); describe('Inject Lambda Context', () => { - const ENVIRONMENT_VARIABLES = process.env; - beforeEach(() => { - process.env = { - ...ENVIRONMENT_VARIABLES, - POWERTOOLS_DEV: 'true', - }; + vi.stubEnv('POWERTOOLS_DEV', 'true'); vi.clearAllMocks(); }); + afterEach(() => { + vi.unstubAllEnvs(); + }); + it('adds the context to log messages when the feature is enabled', () => { // Prepare const logger = new Logger(); diff --git a/packages/logger/tests/unit/logBuffer.test.ts b/packages/logger/tests/unit/logBuffer.test.ts index 550e92f911..ca1febdbce 100644 --- a/packages/logger/tests/unit/logBuffer.test.ts +++ b/packages/logger/tests/unit/logBuffer.test.ts @@ -1,22 +1,29 @@ import context from '@aws-lambda-powertools/testing-utils/context'; import type { Context } from 'aws-lambda'; import middy from 'middy5'; -import { beforeEach, describe, expect, it, type Mock, vi } from 'vitest'; +import { + afterEach, + beforeEach, + describe, + expect, + it, + type Mock, + vi, +} from 'vitest'; import { LogLevel, UncaughtErrorLogMessage } from '../../src/constants.js'; import { Logger } from '../../src/Logger.js'; import { injectLambdaContext } from '../../src/middleware/middy.js'; describe('Buffer logs', () => { - const ENVIRONMENT_VARIABLES = process.env; - beforeEach(() => { - process.env = { - ...ENVIRONMENT_VARIABLES, - POWERTOOLS_DEV: 'true', - }; + vi.stubEnv('POWERTOOLS_DEV', 'true'); vi.clearAllMocks(); }); + afterEach(() => { + vi.unstubAllEnvs(); + }); + it('does not buffer logs when disabled', () => { // Prepare const logger = new Logger({ @@ -94,7 +101,7 @@ describe('Buffer logs', () => { it('outputs a warning when the Advanced Logging Configuration Log Level is less verbose than the Log Buffering Log Level', () => { // Assemble - process.env.AWS_LAMBDA_LOG_LEVEL = 'INFO'; + vi.stubEnv('AWS_LAMBDA_LOG_LEVEL', 'INFO'); const logger = new Logger({ logLevel: LogLevel.DEBUG, logBufferOptions: { enabled: true, bufferAtVerbosity: 'DEBUG' }, @@ -116,7 +123,7 @@ describe('Buffer logs', () => { it('When the buffer is flushed it outputs a warning if the Advanced Logging Configuration Log Level is less verbose than the Log Buffering Log Level', () => { // Assemble - process.env.AWS_LAMBDA_LOG_LEVEL = 'INFO'; + vi.stubEnv('AWS_LAMBDA_LOG_LEVEL', 'INFO'); const logger = new Logger({ logLevel: LogLevel.DEBUG, logBufferOptions: { enabled: true, bufferAtVerbosity: 'DEBUG' }, @@ -195,7 +202,7 @@ describe('Buffer logs', () => { it('does not output buffered logs when trace id is not set', () => { // Prepare - process.env._X_AMZN_TRACE_ID = undefined; + vi.stubEnv('_X_AMZN_TRACE_ID', undefined); const logger = new Logger({ logBufferOptions: { enabled: true } }); // Act @@ -210,7 +217,7 @@ describe('Buffer logs', () => { it('it safely short circuits when clearBuffer is called without a trace id', () => { // Prepare - process.env._X_AMZN_TRACE_ID = undefined; + vi.stubEnv('_X_AMZN_TRACE_ID', undefined); const logger = new Logger({ logLevel: LogLevel.ERROR, logBufferOptions: { enabled: true, bufferAtVerbosity: LogLevel.DEBUG }, diff --git a/packages/logger/tests/unit/logEvent.test.ts b/packages/logger/tests/unit/logEvent.test.ts index 85f7e40728..a694e96984 100644 --- a/packages/logger/tests/unit/logEvent.test.ts +++ b/packages/logger/tests/unit/logEvent.test.ts @@ -1,7 +1,7 @@ import context from '@aws-lambda-powertools/testing-utils/context'; import middy from '@middy/core'; import type { Context } from 'aws-lambda'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { Logger } from '../../src/Logger.js'; import { injectLambdaContext } from '../../src/middleware/middy.js'; @@ -10,17 +10,16 @@ const event = { }; describe('Log event', () => { - const ENVIRONMENT_VARIABLES = process.env; - beforeEach(() => { - process.env = { - ...ENVIRONMENT_VARIABLES, - POWERTOOLS_LOGGER_LOG_EVENT: 'true', - POWERTOOLS_DEV: 'true', - }; + vi.stubEnv('POWERTOOLS_LOGGER_LOG_EVENT', 'true'); + vi.stubEnv('POWERTOOLS_DEV', 'true'); vi.clearAllMocks(); }); + afterEach(() => { + vi.unstubAllEnvs(); + }); + it('logs the event with the correct log level and message', () => { // Prepare const logger = new Logger(); @@ -35,7 +34,7 @@ describe('Log event', () => { it("doesn't log the event when the feature is disabled", () => { // Prepare - process.env.POWERTOOLS_LOGGER_LOG_EVENT = 'false'; + vi.stubEnv('POWERTOOLS_LOGGER_LOG_EVENT', 'false'); const logger = new Logger(); // Act @@ -112,7 +111,7 @@ describe('Log event', () => { it('prefers the local logEvent configuration over the environment variable', async () => { // Prepare - process.env.POWERTOOLS_LOGGER_LOG_EVENT = 'false'; + vi.stubEnv('POWERTOOLS_LOGGER_LOG_EVENT', 'false'); const logger = new Logger(); const handler = middy(async () => {}).use( injectLambdaContext(logger, { logEvent: true }) @@ -127,7 +126,7 @@ describe('Log event', () => { it('passes down the log event configuration to child loggers', () => { // Prepare - process.env.POWERTOOLS_LOGGER_LOG_EVENT = 'false'; + vi.stubEnv('POWERTOOLS_LOGGER_LOG_EVENT', 'false'); const logger = new Logger(); const childLogger = logger.createChild(); diff --git a/packages/logger/tests/unit/logLevels.test.ts b/packages/logger/tests/unit/logLevels.test.ts index cee4602499..bce3030aa2 100644 --- a/packages/logger/tests/unit/logLevels.test.ts +++ b/packages/logger/tests/unit/logLevels.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { LogLevel, LogLevelThreshold } from '../../src/constants.js'; import { Logger } from '../../src/Logger.js'; import type { ConfigServiceInterface } from '../../src/types/ConfigServiceInterface.js'; @@ -30,13 +30,15 @@ const getConsoleMethod = ( }; describe('Log levels', () => { - const ENVIRONMENT_VARIABLES = process.env; - beforeEach(() => { - process.env = { ...ENVIRONMENT_VARIABLES, POWERTOOLS_DEV: 'true' }; + vi.stubEnv('POWERTOOLS_DEV', 'true'); vi.clearAllMocks(); }); + afterEach(() => { + vi.unstubAllEnvs(); + }); + it('sets the correct log level when initialized with a log level', () => { // Act const logger = new Logger({ logLevel: LogLevel.WARN }); @@ -48,7 +50,7 @@ describe('Log levels', () => { it('defaults to INFO log level when initialized without a log level', () => { // Prepare - process.env.POWERTOOLS_LOG_LEVEL = undefined; + vi.stubEnv('POWERTOOLS_LOG_LEVEL', undefined); // Act const logger = new Logger(); @@ -60,7 +62,7 @@ describe('Log levels', () => { it('defaults to INFO log level when initialized with an invalid log level', () => { // Prepare - process.env.POWERTOOLS_LOG_LEVEL = undefined; + vi.stubEnv('POWERTOOLS_LOG_LEVEL', undefined); // Act const logger = new Logger({ logLevel: 'INVALID' as LogLevelType }); @@ -94,7 +96,7 @@ describe('Log levels', () => { it('sets the correct log level when setting the POWERTOOLS_LOG_LEVEL environment variable', () => { // Prepare - process.env.POWERTOOLS_LOG_LEVEL = LogLevel.CRITICAL; + vi.stubEnv('POWERTOOLS_LOG_LEVEL', LogLevel.CRITICAL); // Act const logger = new Logger(); @@ -106,7 +108,7 @@ describe('Log levels', () => { it('sets the log level to CRITICAL when AWS_LAMBDA_LOG_LEVEL is FATAL', () => { // Prepare - process.env.AWS_LAMBDA_LOG_LEVEL = 'FATAL'; + vi.stubEnv('AWS_LAMBDA_LOG_LEVEL', 'FATAL'); // Act const logger = new Logger(); @@ -117,7 +119,7 @@ describe('Log levels', () => { it('sets the correct log level when using a custom config service', () => { // Prepare - process.env.POWERTOOLS_LOG_LEVEL = undefined; + vi.stubEnv('POWERTOOLS_LOG_LEVEL', undefined); const customConfigService = { getLogLevel: () => LogLevel.WARN, getCurrentEnvironment: vi.fn(), @@ -199,9 +201,9 @@ describe('Log levels', () => { it('emits a warning and falls back to the ALC level when trying to set a more verbose log level than the one set in ALC', () => { // Prepare - process.env.AWS_LAMBDA_LOG_LEVEL = LogLevel.ERROR; - process.env.LOG_LEVEL = undefined; - process.env.POWERTOOLS_LOG_LEVEL = undefined; + vi.stubEnv('AWS_LAMBDA_LOG_LEVEL', LogLevel.ERROR); + vi.stubEnv('LOG_LEVEL', undefined); + vi.stubEnv('POWERTOOLS_LOG_LEVEL', undefined); const logger = new Logger(); const warningSpy = vi.spyOn(logger, 'warn'); @@ -219,9 +221,9 @@ describe('Log levels', () => { it('emits a warning and falls back to the ALC level when trying to init the logger with a more verbose log level than the one set in ALC', () => { // Prepare - process.env.AWS_LAMBDA_LOG_LEVEL = LogLevel.INFO; - process.env.LOG_LEVEL = undefined; - process.env.POWERTOOLS_LOG_LEVEL = undefined; + vi.stubEnv('AWS_LAMBDA_LOG_LEVEL', LogLevel.INFO); + vi.stubEnv('LOG_LEVEL', undefined); + vi.stubEnv('POWERTOOLS_LOG_LEVEL', undefined); const warningSpy = vi.spyOn(console, 'warn'); // Act diff --git a/packages/logger/tests/unit/sampling.test.ts b/packages/logger/tests/unit/sampling.test.ts index 947a8271b9..9e0e453869 100644 --- a/packages/logger/tests/unit/sampling.test.ts +++ b/packages/logger/tests/unit/sampling.test.ts @@ -1,11 +1,13 @@ -import { beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { Logger, LogLevel, LogLevelThreshold } from '../../src/index.js'; describe('Log sampling', () => { - const ENVIRONMENT_VARIABLES = process.env; - beforeEach(() => { - process.env = { ...ENVIRONMENT_VARIABLES, POWERTOOLS_DEV: 'true' }; + vi.stubEnv('POWERTOOLS_DEV', 'true'); + }); + + afterEach(() => { + vi.unstubAllEnvs(); }); it('informs the customer that sample rate is setting the level to DEBUG', () => { @@ -35,7 +37,7 @@ describe('Log sampling', () => { it('changes the log level to debug log sampling is configured via env variable', () => { // Prepare - process.env.POWERTOOLS_LOGGER_SAMPLE_RATE = '1'; + vi.stubEnv('POWERTOOLS_LOGGER_SAMPLE_RATE', '1'); // Act const logger: Logger = new Logger({ @@ -59,7 +61,7 @@ describe('Log sampling', () => { it('prioritizes and uses the sample rate specified in the constructor', () => { // Prepare - process.env.POWERTOOLS_LOGGER_SAMPLE_RATE = '0.5'; + vi.stubEnv('POWERTOOLS_LOGGER_SAMPLE_RATE', '0.5'); // Act const logger: Logger = new Logger({ @@ -84,7 +86,7 @@ describe('Log sampling', () => { ])('ignores invalid sample rate values via $type', ({ options, type }) => { // Prepare if (type === 'env variable') { - process.env.POWERTOOLS_LOGGER_SAMPLE_RATE = '42'; + vi.stubEnv('POWERTOOLS_LOGGER_SAMPLE_RATE', '42'); } // Act diff --git a/packages/logger/tests/unit/workingWithkeys.test.ts b/packages/logger/tests/unit/workingWithkeys.test.ts index 45a13bff3e..ca18259ef3 100644 --- a/packages/logger/tests/unit/workingWithkeys.test.ts +++ b/packages/logger/tests/unit/workingWithkeys.test.ts @@ -1,22 +1,21 @@ import context from '@aws-lambda-powertools/testing-utils/context'; import middy from '@middy/core'; import type { Context } from 'aws-lambda'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { Logger } from '../../src/Logger.js'; import { injectLambdaContext } from '../../src/middleware/middy.js'; import type { ConstructorOptions } from '../../src/types/Logger.js'; describe('Working with keys', () => { - const ENVIRONMENT_VARIABLES = process.env; - beforeEach(() => { - process.env = { - ...ENVIRONMENT_VARIABLES, - POWERTOOLS_DEV: 'true', - }; + vi.stubEnv('POWERTOOLS_DEV', 'true'); vi.clearAllMocks(); }); + afterEach(() => { + vi.unstubAllEnvs(); + }); + it.each([ { inputs: ['Hello, world!', { extra: 'parameter' }],