tftsr-devops_investigation/node_modules/mocha/lib/nodejs/reporters/parallel-buffered.js

166 lines
4.6 KiB
JavaScript
Raw Normal View History

feat: initial implementation of TFTSR IT Triage & RCA application Implements Phases 1-8 of the TFTSR implementation plan. Rust backend (Tauri 2.x, src-tauri/): - Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama - PII detection engine: 11 regex patterns with overlap resolution - SQLCipher AES-256 encrypted database with 10 versioned migrations - 28 Tauri IPC commands for triage, analysis, document, and system ops - Ollama: hardware probe, model recommendations, pull/delete with events - RCA and blameless post-mortem Markdown document generators - PDF export via printpdf - Audit log: SHA-256 hash of every external data send - Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2) Frontend (React 18 + TypeScript + Vite, src/): - 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings - 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives - 3 Zustand stores: session, settings (persisted), history - Type-safe tauriCommands.ts matching Rust backend types exactly - 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs) DevOps: - .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push - .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload Verified: - cargo check: zero errors - tsc --noEmit: zero errors - vitest run: 13/13 unit tests passing Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
/**
* "Buffered" reporter used internally by a worker process when running in parallel mode.
* @module nodejs/reporters/parallel-buffered
* @public
*/
'use strict';
/**
* Module dependencies.
*/
const {
EVENT_SUITE_BEGIN,
EVENT_SUITE_END,
EVENT_TEST_FAIL,
EVENT_TEST_PASS,
EVENT_TEST_PENDING,
EVENT_TEST_BEGIN,
EVENT_TEST_END,
EVENT_TEST_RETRY,
EVENT_DELAY_BEGIN,
EVENT_DELAY_END,
EVENT_HOOK_BEGIN,
EVENT_HOOK_END,
EVENT_RUN_END
} = require('../../runner').constants;
const {SerializableEvent, SerializableWorkerResult} = require('../serializer');
const debug = require('debug')('mocha:reporters:buffered');
const Base = require('../../reporters/base');
/**
* List of events to listen to; these will be buffered and sent
* when `Mocha#run` is complete (via {@link ParallelBuffered#done}).
*/
const EVENT_NAMES = [
EVENT_SUITE_BEGIN,
EVENT_SUITE_END,
EVENT_TEST_BEGIN,
EVENT_TEST_PENDING,
EVENT_TEST_FAIL,
EVENT_TEST_PASS,
EVENT_TEST_RETRY,
EVENT_TEST_END,
EVENT_HOOK_BEGIN,
EVENT_HOOK_END
];
/**
* Like {@link EVENT_NAMES}, except we expect these events to only be emitted
* by the `Runner` once.
*/
const ONCE_EVENT_NAMES = [EVENT_DELAY_BEGIN, EVENT_DELAY_END];
/**
* The `ParallelBuffered` reporter is used by each worker process in "parallel"
* mode, by default. Instead of reporting to `STDOUT`, etc., it retains a
* list of events it receives and hands these off to the callback passed into
* {@link Mocha#run}. That callback will then return the data to the main
* process.
* @public
*/
class ParallelBuffered extends Base {
/**
* Calls {@link ParallelBuffered#createListeners}
* @param {Runner} runner
*/
constructor(runner, opts) {
super(runner, opts);
/**
* Retained list of events emitted from the {@link Runner} instance.
* @type {BufferedEvent[]}
* @public
*/
this.events = [];
/**
* Map of `Runner` event names to listeners (for later teardown)
* @public
* @type {Map<string,EventListener>}
*/
this.listeners = new Map();
this.createListeners(runner);
}
/**
* Returns a new listener which saves event data in memory to
* {@link ParallelBuffered#events}. Listeners are indexed by `eventName` and stored
* in {@link ParallelBuffered#listeners}. This is a defensive measure, so that we
* don't a) leak memory or b) remove _other_ listeners that may not be
* associated with this reporter.
*
* Subclasses could override this behavior.
*
* @public
* @param {string} eventName - Name of event to create listener for
* @returns {EventListener}
*/
createListener(eventName) {
const listener = (runnable, err) => {
this.events.push(SerializableEvent.create(eventName, runnable, err));
};
return this.listeners.set(eventName, listener).get(eventName);
}
/**
* Creates event listeners (using {@link ParallelBuffered#createListener}) for each
* reporter-relevant event emitted by a {@link Runner}. This array is drained when
* {@link ParallelBuffered#done} is called by {@link Runner#run}.
*
* Subclasses could override this behavior.
* @public
* @param {Runner} runner - Runner instance
* @returns {ParallelBuffered}
* @chainable
*/
createListeners(runner) {
EVENT_NAMES.forEach(evt => {
runner.on(evt, this.createListener(evt));
});
ONCE_EVENT_NAMES.forEach(evt => {
runner.once(evt, this.createListener(evt));
});
runner.once(EVENT_RUN_END, () => {
debug('received EVENT_RUN_END');
this.listeners.forEach((listener, evt) => {
runner.removeListener(evt, listener);
this.listeners.delete(evt);
});
});
return this;
}
/**
* Calls the {@link Mocha#run} callback (`callback`) with the test failure
* count and the array of {@link BufferedEvent} objects. Resets the array.
*
* This is called directly by `Runner#run` and should not be called by any other consumer.
*
* Subclasses could override this.
*
* @param {number} failures - Number of failed tests
* @param {Function} callback - The callback passed to {@link Mocha#run}.
* @public
*/
done(failures, callback) {
callback(SerializableWorkerResult.create(this.events, failures));
this.events = []; // defensive
}
}
/**
* Serializable event data from a `Runner`. Keys of the `data` property
* beginning with `__` will be converted into a function which returns the value
* upon deserialization.
* @typedef {Object} BufferedEvent
* @property {string} name - Event name
* @property {object} data - Event parameters
*/
module.exports = ParallelBuffered;