mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-23 17:52:49 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe7644f680 | ||
|
|
3166730e36 |
@@ -1,5 +1,5 @@
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
import {
|
||||
startGitCommandMetrics,
|
||||
stopGitCommandMetrics,
|
||||
waitForGitCommandMetricsIdle,
|
||||
type GitCommandMetricsSnapshot,
|
||||
} from "../src/utils/run-git-command.js";
|
||||
import { CheckoutDiffManager } from "../src/server/checkout-diff-manager.js";
|
||||
@@ -160,6 +161,7 @@ async function measurePhase(input: {
|
||||
serviceMetrics.workspaceRefreshQueuedCount === 0
|
||||
);
|
||||
}, "observation queue to drain");
|
||||
await waitForGitCommandMetricsIdle({ quietMs: 1_500, timeoutMs: 8_000 });
|
||||
} finally {
|
||||
metrics = stopGitCommandMetrics();
|
||||
}
|
||||
@@ -189,7 +191,11 @@ async function closeMeasuredService(input: {
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const tempDir = mkdtempSync(path.join(tmpdir(), "paseo-git-observation-measurement-"));
|
||||
// Git reports physical roots; keep watcher-failure injection in that same
|
||||
// spelling when the system temporary directory is a symlink.
|
||||
const tempDir = realpathSync(
|
||||
mkdtempSync(path.join(tmpdir(), "paseo-git-observation-measurement-")),
|
||||
);
|
||||
const repoDir = path.join(tempDir, "repo");
|
||||
const paseoHome = path.join(tempDir, "paseo-home");
|
||||
const trackedPath = path.join(repoDir, "tracked.txt");
|
||||
@@ -243,7 +249,9 @@ async function main(): Promise<void> {
|
||||
healthy.watcher.subscriptions.size === 2,
|
||||
"healthy bootstrap",
|
||||
);
|
||||
await sleep(250);
|
||||
// Linux startup discovery schedules a one-second debounced refresh even
|
||||
// after subscriptions are ready. Keep that work in the bootstrap phase.
|
||||
await waitForGitCommandMetricsIdle({ quietMs: 1_500, timeoutMs: 8_000 });
|
||||
const bootstrapMetrics = stopGitCommandMetrics();
|
||||
const bootstrapServiceMetrics = healthy.service.getMetrics();
|
||||
phases.bootstrap = {
|
||||
@@ -342,6 +350,7 @@ async function main(): Promise<void> {
|
||||
diffManager = null;
|
||||
await closeMeasuredService({
|
||||
service: healthy.service,
|
||||
observer: healthy.watcher.observer,
|
||||
subscriptions: healthy.watcher.subscriptions,
|
||||
});
|
||||
healthy = null;
|
||||
@@ -357,7 +366,9 @@ async function main(): Promise<void> {
|
||||
degraded.service.getMetrics().workspaceObservationSetupInFlightCount === 0,
|
||||
"degraded bootstrap",
|
||||
);
|
||||
await sleep(250);
|
||||
// Linux startup discovery schedules a one-second debounced refresh even
|
||||
// after subscriptions are ready. Keep that work in the bootstrap phase.
|
||||
await waitForGitCommandMetricsIdle({ quietMs: 1_500, timeoutMs: 8_000 });
|
||||
const degradedBootstrapMetrics = stopGitCommandMetrics();
|
||||
const degradedBootstrapServiceMetrics = degraded.service.getMetrics();
|
||||
phases.degradedBootstrap = {
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import {
|
||||
mkdirSync,
|
||||
mkdtempSync,
|
||||
readFileSync,
|
||||
realpathSync,
|
||||
rmSync,
|
||||
symlinkSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { execFile, execFileSync } from "node:child_process";
|
||||
import { promisify } from "node:util";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import pino from "pino";
|
||||
@@ -522,3 +532,44 @@ test("a late Git-ignored tree is pruned while tracked changes still notify consu
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
}, 15_000);
|
||||
|
||||
test("Git observation measurement separates startup from idle and reaches its degraded summary", async () => {
|
||||
const script = fileURLToPath(
|
||||
new URL("../../scripts/measure-git-observation.ts", import.meta.url),
|
||||
);
|
||||
const root = realpathSync(mkdtempSync(path.join(tmpdir(), "paseo-measurement-test-")));
|
||||
const actualTemp = path.join(root, "actual");
|
||||
const aliasedTemp = path.join(root, "alias");
|
||||
mkdirSync(actualTemp);
|
||||
symlinkSync(actualTemp, aliasedTemp, "junction");
|
||||
cleanup.push(async () => rmSync(root, { recursive: true, force: true }));
|
||||
const { stdout } = await promisify(execFile)(process.execPath, ["--import", "tsx", script], {
|
||||
env: { ...process.env, TMPDIR: aliasedTemp, TMP: aliasedTemp, TEMP: aliasedTemp },
|
||||
timeout: 30_000,
|
||||
maxBuffer: 1024 * 1024,
|
||||
});
|
||||
const summary = stdout
|
||||
.split("\n")
|
||||
.find((line) => line.startsWith("GIT_OBSERVATION_MEASUREMENT "));
|
||||
expect(summary).toBeTypeOf("string");
|
||||
const report = JSON.parse(summary!.slice("GIT_OBSERVATION_MEASUREMENT ".length));
|
||||
expect(Object.keys(report.phases)).toEqual([
|
||||
"bootstrap",
|
||||
"legacyFullRefreshReference",
|
||||
"idle",
|
||||
"activeDiff",
|
||||
"editBurst",
|
||||
"ignoredStorm",
|
||||
"degradedBootstrap",
|
||||
"degradedWatcher",
|
||||
]);
|
||||
expect(report.phases.idle.gitCommands).toBe(0);
|
||||
expect(report.phases.ignoredStorm.gitCommands).toBe(0);
|
||||
expect(report.phases.bootstrap.producers.structural).toBeGreaterThanOrEqual(1);
|
||||
expect(report.phases.activeDiff.producers.worktree).toBeGreaterThanOrEqual(1);
|
||||
expect(report.phases.editBurst.producers.worktree).toBeLessThanOrEqual(2);
|
||||
expect(report.phases.degradedWatcher.producers.worktree).toBeGreaterThanOrEqual(1);
|
||||
for (const phase of Object.values(report.phases) as Array<{ queueAfter: unknown }>) {
|
||||
expect(phase.queueAfter).toEqual({ inFlight: 0, queued: 0 });
|
||||
}
|
||||
}, 35_000);
|
||||
|
||||
Reference in New Issue
Block a user