test: validate M3 imports and locking on PostgreSQL

Add isolated PostgreSQL fixtures, two-session locking coverage, and a disposable remote Docker test runner. Correct the canonical-root fixture and document verified SQLite and PostgreSQL results.
This commit is contained in:
Cline committed 2026-10-12 13:19:10 -05:00
1 parent 9d277d9e72
commit c1ef2ee97a
9 files changed
+420 -37

No files matched your search

+15 -21
View File
@@ -42,9 +42,13 @@ final class ImportPipelineTest extends TestCase
protected function tearDown(): void
{
unset($this->pdo, $this->jobs, $this->catalog);
@unlink($this->database);
RepositoryDatabase::remove($this->library);
RepositoryDatabase::remove($this->source);
RepositoryDatabase::cleanup($this->database);
if (isset($this->library)) {
RepositoryDatabase::remove($this->library);
}
if (isset($this->source)) {
RepositoryDatabase::remove($this->source);
}
}
private function service(?SpaceChecker $space = null): ImportService
@@ -374,22 +378,15 @@ final class ImportPipelineTest extends TestCase
public function testWorkerUsesCanonicalLibraryRootForRelativePaths(): void
{
// Test that the worker uses canonical (realpath) library root for
// computing relative paths, not the raw string which might have
// symlinks or case differences.
//
// Create library with a symlink in the path
$realLibrary = $this->library;
$linkLibrary = $realLibrary . '-link';
if (!@symlink($realLibrary, $linkLibrary)) {
self::markTestSkipped('Host cannot create symlinks.');
}
// A trailing separator is safe but differs from the canonical root.
// Symlink roots are deliberately rejected by PathSafety.
$rawLibrary = $this->library . DIRECTORY_SEPARATOR;
$this->writeStl('planes/wing.stl');
$job = $this->service()->import($this->source);
// Create worker with symlinked library root
$safety = new PathSafety($linkLibrary);
$safety = new PathSafety($rawLibrary);
self::assertNotSame($rawLibrary, $safety->libraryRoot());
$sourceSafety = new PathSafety($this->source);
$worker = new ImportWorker(
$this->jobs,
@@ -399,20 +396,17 @@ final class ImportPipelineTest extends TestCase
new StlValidator($sourceSafety),
$safety,
new SpaceChecker(),
$linkLibrary, // Symlinked path
$rawLibrary,
new NullLogger(),
);
$worker->runOnce();
$item = $this->jobs->items($job)[0];
// The managed_path should be relative to the CANONICAL root, not the symlink
self::assertStringNotContainsString('link', $item['managed_path']);
self::assertSame('Completed', $item['status']);
self::assertStringStartsWith('planes/', $item['managed_path']);
$published = $this->library . DIRECTORY_SEPARATOR
. str_replace('/', DIRECTORY_SEPARATOR, $item['managed_path']);
self::assertFileExists($published);
// Cleanup
unlink($linkLibrary);
}
}