From 31c3cfe43e21f34d830aef877acd91223e77385b Mon Sep 17 00:00:00 2001 From: Federico Jaramillo Martinez Date: Tue, 28 Jul 2026 19:59:27 +0200 Subject: [PATCH] test(sessions): resolve POSIX fixture paths that are drive-relative on Windows Five tests failed only on the Windows runner. Their fixtures used bare POSIX-absolute paths such as /srv/other-worktree and /old-project, which win32 treats as absolute but drive-relative: resolve() maps them onto the runner's current drive (D:\...). The code under test canonicalizes stored cwds by contract, so assertions comparing against the raw fixture string never matched on Windows: - parentSessionLocator and crossWorkspace listings annotate parentSessionCwd with canonicalizeStoredCwd(header.cwd); - cleanup forgets unread via canonicalizeStoredCwd(record.cwd), which missed the marker the test seeded with the raw path. Resolve the fixture paths once at declaration, matching the existing WORKSPACE_CWD = resolve("/workspace") convention, so fixtures model what a real Windows Pi would record. Linux behavior is unchanged. --- src/server/sessions/parentSessionLocator.test.ts | 5 ++++- .../sessions/piSessionService.crossWorkspace.test.ts | 7 +++++-- src/server/sessions/piSessionService.unread.test.ts | 12 ++++++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/server/sessions/parentSessionLocator.test.ts b/src/server/sessions/parentSessionLocator.test.ts index 99acb8b..41133e0 100644 --- a/src/server/sessions/parentSessionLocator.test.ts +++ b/src/server/sessions/parentSessionLocator.test.ts @@ -1,10 +1,13 @@ +import { resolve } from "node:path"; import { describe, expect, it, vi } from "vitest"; import { countOutOfListingChildren, locateOutOfListingParents } from "./parentSessionLocator.js"; import type { SessionHeaderSummary } from "./sessionFileHeader.js"; const PARENT_PATH = "/sessions/--srv-other--/parent.jsonl"; const LISTING_CWD = "/srv/dev/pi-web"; -const PARENT_CWD = "/srv/other-worktree"; +// Resolved because the locator canonicalizes header cwds: a bare "/srv/..." is +// drive-relative on Windows and would land on the runner's current drive. +const PARENT_CWD = resolve("/srv/other-worktree"); describe("locateOutOfListingParents", () => { it("reports the cwd and id of a parent that is not in the listing", async () => { diff --git a/src/server/sessions/piSessionService.crossWorkspace.test.ts b/src/server/sessions/piSessionService.crossWorkspace.test.ts index f0dbb69..38848c8 100644 --- a/src/server/sessions/piSessionService.crossWorkspace.test.ts +++ b/src/server/sessions/piSessionService.crossWorkspace.test.ts @@ -1,13 +1,16 @@ import { mkdtemp, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; -import { join } from "node:path"; +import { join, resolve } from "node:path"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { PiSessionService, type PiSessionListEntry } from "./piSessionService.js"; import { CapturingSessionEventHub, emptyArchiveStore, fakeSessionManager, sessionRecord, testModelRuntime, type SessionGateway } from "./piSessionService.testSupport.js"; const TEST_AGENT_DIR = "/tmp/pi-web-test-agent"; const CHILD_CWD = "/srv/dev/pi-web"; -const PARENT_CWD = "/srv/dev/pi-web-feature"; +// Resolved because the service canonicalizes header cwds before annotating: a +// bare "/srv/..." is drive-relative on Windows and would land on the runner's +// current drive. +const PARENT_CWD = resolve("/srv/dev/pi-web-feature"); let tempDir: string; diff --git a/src/server/sessions/piSessionService.unread.test.ts b/src/server/sessions/piSessionService.unread.test.ts index 4268136..42cf4d6 100644 --- a/src/server/sessions/piSessionService.unread.test.ts +++ b/src/server/sessions/piSessionService.unread.test.ts @@ -694,9 +694,13 @@ describe("PiSessionService daemon-owned unread state", () => { it("clears unread for sessions archived and deleted by cleanup", async () => { const unreadStore = new SessionUnreadStore({ createCatalogId: () => "catalog-test" }); - completeStoreWork(unreadStore, "cleanup-archive", "/old-project"); - completeStoreWork(unreadStore, "cleanup-delete", "/old-project"); - const archivedRecord = { sessionId: "cleanup-delete", cwd: "/old-project", archivedAt: "2026-04-01T00:00:00.000Z", archivePath: "/archive/cleanup-delete.jsonl" }; + // Resolved because the service canonicalizes cwds before forgetting unread: + // a bare "/old-project" is drive-relative on Windows and would land on the + // runner's current drive, so the seeded marker would never match. + const oldProjectCwd = resolve("/old-project"); + completeStoreWork(unreadStore, "cleanup-archive", oldProjectCwd); + completeStoreWork(unreadStore, "cleanup-delete", oldProjectCwd); + const archivedRecord = { sessionId: "cleanup-delete", cwd: oldProjectCwd, archivedAt: "2026-04-01T00:00:00.000Z", archivePath: "/archive/cleanup-delete.jsonl" }; const service = new PiSessionService(new CapturingSessionEventHub(), { agentDir: TEST_AGENT_DIR, modelRuntime: testModelRuntime, @@ -705,7 +709,7 @@ describe("PiSessionService daemon-owned unread state", () => { sessionManager: { create: () => fakeSessionManager(), list: () => Promise.resolve([]), - listAll: () => Promise.resolve([sessionRecord("cleanup-archive", "/old-project")]), + listAll: () => Promise.resolve([sessionRecord("cleanup-archive", oldProjectCwd)]), open: () => fakeSessionManager(), }, archiveStore: {