History

test(server): pin git config for fixtures and compare native realpaths (#9570)

Julius Marminge committed 2 months ago

Commit 12b6d021 parent f083f524 files · +61 −29Browse files

Unified · Split

4 files
  1. apps/server/src/project/RepositoryIdentityResolver.test.ts +8 −4
  2. apps/server/src/testUtils/gitConfig.setup.ts +21 −0
  3. apps/server/src/vcs/GitVcsDriverCore.test.ts +31 −25
  4. apps/server/vite.config.ts +1 −0
apps/server/src/project/RepositoryIdentityResolver.test.ts+8−4
@@ -1,3 +1,5 @@
1// @effect-diagnostics nodeBuiltinImport:off - realpathSync.native resolves Windows 8.3 short names, which the Effect realPath does not.
2import * as NodeFS from "node:fs";
1import * as NodeServices from "@effect/platform-node/NodeServices";3import * as NodeServices from "@effect/platform-node/NodeServices";
2import { expect, it } from "@effect/vitest";4import { expect, it } from "@effect/vitest";
3import * as Duration from "effect/Duration";5import * as Duration from "effect/Duration";
@@ -131,9 +133,11 @@ it.layer(NodeServices.layer)("RepositoryIdentityResolverLive", (it) => { · 127 unmodified lines
131 133
132 const resolver = yield* RepositoryIdentityResolver.RepositoryIdentityResolver;134 const resolver = yield* RepositoryIdentityResolver.RepositoryIdentityResolver;
133 const identity = yield* resolver.resolve(cwd);135 const identity = yield* resolver.resolve(cwd);
136 // Native realpath, since git reports the long form of a directory the
137 // temp dir may name by its 8.3 short form on Windows.
134 const resolvedIdentityRoot =138 const resolvedIdentityRoot =
135 identity?.rootPath === undefined ? "" : yield* fileSystem.realPath(identity.rootPath);139 identity?.rootPath === undefined ? "" : NodeFS.realpathSync.native(identity.rootPath);
136 const resolvedCwd = yield* fileSystem.realPath(cwd);140 const resolvedCwd = NodeFS.realpathSync.native(cwd);
137 141
138 expect(identity).not.toBeNull();142 expect(identity).not.toBeNull();
139 expect(identity?.canonicalKey).toBe("github.com/t3tools/t3code");143 expect(identity?.canonicalKey).toBe("github.com/t3tools/t3code");
@@ -161,8 +165,8 @@ it.layer(NodeServices.layer)("RepositoryIdentityResolverLive", (it) => { · 21 unmodified lines
161 const resolver = yield* RepositoryIdentityResolver.RepositoryIdentityResolver;165 const resolver = yield* RepositoryIdentityResolver.RepositoryIdentityResolver;
162 const identity = yield* resolver.resolve(nestedWorkspace);166 const identity = yield* resolver.resolve(nestedWorkspace);
163 const resolvedIdentityRoot =167 const resolvedIdentityRoot =
164 identity?.rootPath === undefined ? "" : yield* fileSystem.realPath(identity.rootPath);168 identity?.rootPath === undefined ? "" : NodeFS.realpathSync.native(identity.rootPath);
165 const resolvedRepoRoot = yield* fileSystem.realPath(repoRoot);169 const resolvedRepoRoot = NodeFS.realpathSync.native(repoRoot);
166 170
167 expect(identity).not.toBeNull();171 expect(identity).not.toBeNull();
168 expect(identity?.canonicalKey).toBe("github.com/t3tools/t3code");172 expect(identity?.canonicalKey).toBe("github.com/t3tools/t3code");
apps/server/src/testUtils/gitConfig.setup.ts+21−0
@@ -0,0 +1,21 @@
1// Pins git behaviour for every repository the suite creates, ahead of the
2// host's ~/.gitconfig. Git for Windows installs with core.autocrlf=true,
3// which checks committed LF files out as CRLF and breaks every byte-exact
4// content assertion; a signing key or a non-default init branch on the
5// developer's machine breaks fixtures the same way. Set as environment so
6// each git child the driver spawns sees it without touching the fixtures.
7const entries: ReadonlyArray<readonly [key: string, value: string]> = [
8 ["core.autocrlf", "false"],
9 ["core.filemode", "false"],
10 ["core.longpaths", "true"],
11 ["commit.gpgsign", "false"],
12 ["tag.gpgsign", "false"],
13 ["init.defaultBranch", "main"],
14];
15
16const existing = Number(process.env.GIT_CONFIG_COUNT ?? "0");
17process.env.GIT_CONFIG_COUNT = String(existing + entries.length);
18entries.forEach(([key, value], index) => {
19 process.env[`GIT_CONFIG_KEY_${existing + index}`] = key;
20 process.env[`GIT_CONFIG_VALUE_${existing + index}`] = value;
21});
apps/server/src/vcs/GitVcsDriverCore.test.ts+31−25
@@ -1,4 +1,7 @@
1// @effect-diagnostics nodeBuiltinImport:off - realpathSync.native resolves Windows 8.3 short names, which the Effect realPath does not.
2import * as NodeFS from "node:fs";
1import * as NodeServices from "@effect/platform-node/NodeServices";3import * as NodeServices from "@effect/platform-node/NodeServices";
4import { HostProcessPlatform } from "@t3tools/shared/hostProcess";
2import { assert, it, describe } from "@effect/vitest";5import { assert, it, describe } from "@effect/vitest";
3import * as Deferred from "effect/Deferred";6import * as Deferred from "effect/Deferred";
4import * as Effect from "effect/Effect";7import * as Effect from "effect/Effect";
@@ -570,7 +573,6 @@ it.effect("backs off failed upstream refreshes across linked worktrees", () => · 565 unmodified lines
570 const driver = yield* makeGitVcsDriverCore().pipe(573 const driver = yield* makeGitVcsDriverCore().pipe(
571 Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, failingFetchSpawner),574 Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, failingFetchSpawner),
572 );575 );
573 const fileSystem = yield* FileSystem.FileSystem;
574 const cwd = yield* makeTmpDir();576 const cwd = yield* makeTmpDir();
575 const remote = yield* makeTmpDir("git-vcs-driver-remote-");577 const remote = yield* makeTmpDir("git-vcs-driver-remote-");
576 const worktreesRoot = yield* makeTmpDir("git-vcs-driver-worktrees-");578 const worktreesRoot = yield* makeTmpDir("git-vcs-driver-worktrees-");
@@ -606,9 +608,11 @@ it.effect("backs off failed upstream refreshes across linked worktrees", () => · 29 unmodified lines
606 "rev-parse",608 "rev-parse",
607 "--git-common-dir",609 "--git-common-dir",
608 ])).stdout.trim();610 ])).stdout.trim();
611 // Native realpath, since git reports the long form of a directory the
612 // temp dir may name by its 8.3 short form on Windows.
609 assert.equal(613 assert.equal(
610 yield* fileSystem.realPath(pathService.resolve(cwd, rootCommonDir)),614 NodeFS.realpathSync.native(pathService.resolve(cwd, rootCommonDir)),
611 yield* fileSystem.realPath(pathService.resolve(worktreePath, linkedCommonDir)),615 NodeFS.realpathSync.native(pathService.resolve(worktreePath, linkedCommonDir)),
612 );616 );
613 yield* Ref.set(fetchAttempts, 0);617 yield* Ref.set(fetchAttempts, 0);
614 618
@@ -1376,31 +1380,33 @@ it.layer(TestLayer)("GitVcsDriver core integration", (it) => { · 761 unmodified lines
1376 });1380 });
1377 1381
1378 describe("worktree operations", () => {1382 describe("worktree operations", () => {
1379 it.effect("preserves newline characters in worktree paths when listing refs", () =>1383 // NTFS rejects a newline in a file name, so there is nothing to preserve there.
1380 Effect.gen(function* () {1384 it.effect.skipIf(HostProcessPlatform.defaultValue() === "win32")(
1381 const cwd = yield* makeTmpDir();1385 "preserves newline characters in worktree paths when listing refs",
1382 yield* initRepoWithCommit(cwd);1386 () =>
1383 const worktreesRoot = yield* makeTmpDir("git-vcs-driver-worktrees-");1387 Effect.gen(function* () {
1384 const fileSystem = yield* FileSystem.FileSystem;1388 const cwd = yield* makeTmpDir();
1385 const pathService = yield* Path.Path;1389 yield* initRepoWithCommit(cwd);
1386 const worktreePath = pathService.join(worktreesRoot, "linked\nworktree");1390 const worktreesRoot = yield* makeTmpDir("git-vcs-driver-worktrees-");
1387 const driver = yield* GitVcsDriver.GitVcsDriver;1391 const pathService = yield* Path.Path;
1392 const worktreePath = pathService.join(worktreesRoot, "linked\nworktree");
1393 const driver = yield* GitVcsDriver.GitVcsDriver;
1388 1394
1389 yield* git(cwd, ["worktree", "add", "-b", "feature/newline-path", worktreePath]);1395 yield* git(cwd, ["worktree", "add", "-b", "feature/newline-path", worktreePath]);
1390 1396
1391 const refs = yield* driver.listRefs({ cwd, refresh: true });1397 const refs = yield* driver.listRefs({ cwd, refresh: true });
1392 const listedPath = refs.refs.find(1398 const listedPath = refs.refs.find(
1393 (ref) => ref.name === "feature/newline-path",1399 (ref) => ref.name === "feature/newline-path",
1394 )?.worktreePath;1400 )?.worktreePath;
1395 1401
1396 if (typeof listedPath !== "string") {1402 if (typeof listedPath !== "string") {
1397 return assert.fail("expected the linked branch to include its worktree path");1403 return assert.fail("expected the linked branch to include its worktree path");
1398 }1404 }
1399 assert.equal(1405 assert.equal(
1400 yield* fileSystem.realPath(listedPath),1406 NodeFS.realpathSync.native(listedPath),
1401 yield* fileSystem.realPath(worktreePath),1407 NodeFS.realpathSync.native(worktreePath),
1402 );1408 );
1403 }),1409 }),
1404 );1410 );
1405 1411
1406 it.effect("checks out submodules in a new worktree", () =>1412 it.effect("checks out submodules in a new worktree", () =>
apps/server/vite.config.ts+1−0
@@ -78,6 +78,7 @@ export default mergeConfig( · 77 unmodified lines
78 // The server suite exercises sqlite, git, temp worktrees, and orchestration78 // The server suite exercises sqlite, git, temp worktrees, and orchestration
79 // runtimes heavily. Running files in parallel introduces load-sensitive flakes.79 // runtimes heavily. Running files in parallel introduces load-sensitive flakes.
80 fileParallelism: false,80 fileParallelism: false,
81 setupFiles: ["./src/testUtils/gitConfig.setup.ts"],
81 // Server integration tests exercise sqlite, git, and orchestration together.82 // Server integration tests exercise sqlite, git, and orchestration together.
82 // Under package-wide runs they can exceed the default budget on loaded CI hosts.83 // Under package-wide runs they can exceed the default budget on loaded CI hosts.
83 hookTimeout: 120_000,84 hookTimeout: 120_000,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t