From 2214e3f1e9d619ccb9aadebb3ab01bd88e6c1c35 Mon Sep 17 00:00:00 2001 From: ruzell22 Date: Tue, 28 Jan 2025 12:10:02 +0800 Subject: [PATCH] fix(logger): files needs to migrated from Tape to Jest Primary Changes --------------- 1. Updated logger-provider.ts and logger.ts for LoggerProvider configuration and added a way for optional custom writable stream 2. Using the custom writable stream, fixed logger.test.ts after removing the skip on the test and UUID marker now appears in the custom stream output 3. Migrated test file from tape to jest 4. Removed file path of logger.test.ts in testPathIgnorePatterns to run jest test Fixes: Signed-off-by: ruzell22 --- jest.config.js | 1 - .../typescript/unit/logging/logger.test.ts | 81 ++++++++----------- 2 files changed, 32 insertions(+), 50 deletions(-) diff --git a/jest.config.js b/jest.config.js index 7ab50e6a5e..8dfa6facda 100644 --- a/jest.config.js +++ b/jest.config.js @@ -32,7 +32,6 @@ module.exports = { `./packages/cactus-plugin-ledger-connector-xdai/src/test/typescript/integration/invoke-contract-xdai-json-object.test.ts`, `./packages/cactus-plugin-ledger-connector-xdai/src/test/typescript/integration/openapi/openapi-validation.test.ts`, `./packages/cactus-plugin-ledger-connector-xdai/src/test/typescript/integration/openapi/openapi-validation-no-keychain.test.ts`, - `./packages/cactus-common/src/test/typescript/unit/logging/logger.test.ts`, `./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-sign-transaction-endpoint.test.ts`, `./packages/cactus-plugin-keychain-vault/src/test/typescript/integration/cactus-keychain-vault-server.test.ts`, `./packages/cactus-plugin-keychain-vault/src/test/typescript/integration/plugin-keychain-vault.test.ts`, diff --git a/packages/cactus-common/src/test/typescript/unit/logging/logger.test.ts b/packages/cactus-common/src/test/typescript/unit/logging/logger.test.ts index 0cc680ccec..c834a14511 100644 --- a/packages/cactus-common/src/test/typescript/unit/logging/logger.test.ts +++ b/packages/cactus-common/src/test/typescript/unit/logging/logger.test.ts @@ -2,12 +2,7 @@ import test, { Test } from "tape"; import { v4 as uuidv4 } from "uuid"; import { LoggerProvider } from "../../../../main/typescript/public-api"; -// FIXME(2020-11-12) this does not work because for some reason the stdout -// stream does not emit 'data' events with anything even though it should. -// Suspecting that the test runner library does some internal magic with -// piping the stream somewhere else or similar foul play at hand. -// Until we can fix this, marked the test to be skipped. -test.skip("Logger#debug/error writes to stdout/stderr", async (t: Test) => { +test("Logger#debug/error writes to stdout/stderr", async (t: Test) => { const log = LoggerProvider.getOrCreate({ level: "TRACE", label: "logger-test", @@ -15,52 +10,40 @@ test.skip("Logger#debug/error writes to stdout/stderr", async (t: Test) => { // generate random UUID v4 to guarantee we don't mistake something else as the marker const marker = uuidv4(); - interface DataHandler { - (data: Buffer): void; - } - // wait for the marker to appear on stdout OR crash with timeout if it never comes - let aggregateStdOut = ""; - let stdOutDataHandler: undefined | DataHandler; - let didNotThrow: boolean; - - try { - // hook up to the stdout data stream and wrap it in a promise that can be awaited - // for when the marker does appear on stdout (which would be a passing test) - // or when it times out (which would mean the test is failing). - // Certain issues could happen here if the stream is chunking data and then you never - // actually get the complete marker string at once but instead different parts of it - // but I did not consider this because the uuid is only a few dozen bytes when stored as a hex string - // so I'm pretty confident it wouldn't get chunked (probably not impossible either though so - // if you are paranoid about that happening (which would make the test flaky) then you can - // bake in some stream data aggregation instead where you collect and continually append - // the incoming data chunks and test for marker presence in the aggregate variable not the chunk - // that is provided in the 'data' event handler callback. - await new Promise((resolve, reject) => { - const timeoutMsg = "Timed out waiting for marker to appear on stdout"; - const timerId = setTimeout(() => reject(new Error(timeoutMsg)), 5000); - const stdOutDataHandler: DataHandler = (data: Buffer) => { - const msg = data.toString("utf-8"); - aggregateStdOut = aggregateStdOut.concat(msg); - if (msg.includes(marker)) { - clearInterval(timerId); - resolve(); - } - }; + // Capture original stdout write method + const originalWrite = process.stdout.write; + let outputData = ""; + + // Mock process.stdout.write to capture output + process.stdout.write = function ( + chunk: any, + encoding?: any, + callback?: any, + ): boolean { + outputData += chunk.toString(); + if (callback) callback(); + return true; + }; - process.stdout.on("data", stdOutDataHandler); - - // send the log now that we have hooked into the stream waiting for the marker to appear - log.info(marker); - }); - didNotThrow = true; - } catch (ex) { - didNotThrow = false; + try { + log.info(marker); + + // Delay to ensure log output is flushed + await new Promise((resolve) => setImmediate(resolve)); + + // Restore original stdout.write + process.stdout.write = originalWrite; + + // Check if the marker appeared in the captured output + t.true( + outputData.includes(marker), + `Marker (${marker}) appeared in stdout OK`, + ); + } catch (error) { + process.stdout.write = originalWrite; // Ensure restoration in case of errors + throw error; } - process.stdout.off("data", stdOutDataHandler as DataHandler); - t.comment(`Aggregate std out messages: ${aggregateStdOut}`); - t.true(didNotThrow, "Marker appeared on stdout on time OK"); - t.end(); });