@firfi/quint-connect
Version:
Model-based testing framework connecting Quint specifications to TypeScript implementations
51 lines • 2.89 kB
JavaScript
import { Effect } from "effect";
import { mkdir, mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { compiledEvaluatorTraceAdapter } from "./compiled-evaluator-adapter.js";
import { QuintError } from "./errors.js";
import { platformProcess } from "./platform-process.js";
import { quintCliTraceAdapter } from "./quint-cli-adapter.js";
import { validateTraceGenerationConfiguration } from "./trace-generation-policy.js";
export { QuintError, QuintNotFoundError } from "./errors.js";
const traceGenerationAdapters = [
compiledEvaluatorTraceAdapter,
quintCliTraceAdapter
];
const selectTraceGenerationAdapter = (opts) => traceGenerationAdapters.find((adapter) => adapter.canGenerate(opts)) ?? quintCliTraceAdapter;
const generateTracesInDir = (opts, outDir) => selectTraceGenerationAdapter(opts).generate(opts, outDir);
const generateTracesWithTraceDir = (opts, traceDir) => Effect.gen(function* () {
yield* Effect.tryPromise({
try: () => mkdir(traceDir, { recursive: true }),
catch: (e) => new QuintError({ message: `Failed to create trace directory: ${e}` })
});
return yield* generateTracesInDir(opts, traceDir);
});
const generateTracesWithTempDir = (opts) =>
// Rust parity: upstream transfers `TempDir` ownership into `Traces`, whose Drop
// removes it. Effect's acquire/use/release gives this API the same automatic cleanup,
// including failure and interruption, without requiring callers to provide a scope.
// https://github.com/informalsystems/quint-connect/blob/4f018f54fc7dd4cef341d10111427bab59d3b307/connect/src/trace/generator/mod.rs#L23-L33
Effect.acquireUseRelease(Effect.tryPromise({
try: () => mkdtemp(join(tmpdir(), "quint-")),
catch: (e) => new QuintError({ message: `Failed to create temp directory: ${e}` })
}), (tmpDir) => generateTracesInDir(opts, tmpDir), (tmpDir) => Effect.promise(() => rm(tmpDir, { recursive: true, force: true }).catch(() => { })));
/** Warn if zombie quint_evaluator processes are running because they cause large slowdowns. */
const warnZombieEvaluators = () => Effect.gen(function* () {
const count = yield* platformProcess.countEvaluatorProcesses;
if (count > 0) {
yield* Effect.sync(() => {
console.warn(`[quint-connect] WARNING: Found ${count} running quint_evaluator process(es). `
+ `These consume 100% CPU each and will slow down this run by ~40x. `
+ `Kill them: ${platformProcess.evaluatorCleanupHint}`);
});
}
});
export const generateTraces = (opts) => Effect.gen(function* () {
yield* validateTraceGenerationConfiguration(opts);
yield* warnZombieEvaluators();
return yield* opts.traceDir !== undefined
? generateTracesWithTraceDir(opts, opts.traceDir)
: generateTracesWithTempDir(opts);
});
//# sourceMappingURL=quint.js.map