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:
1 parent
9d277d9e72
commit
c1ef2ee97a
9 files changed
+420
-37
No files matched your search
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user