1
0

Implementierung für M2 vorläufig abgeschlossen

This commit is contained in:
2026-03-31 21:52:48 +02:00
parent 301f1acf08
commit 9d66a446b3
29 changed files with 1892 additions and 52 deletions

View File

@@ -0,0 +1,122 @@
package de.gecheckt.pdf.umbenenner.adapter.outbound.lock;
import de.gecheckt.pdf.umbenenner.application.port.out.RunLockUnavailableException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.*;
/**
* Unit tests for {@link FilesystemRunLockPortAdapter}.
* <p>
* Tests cover acquire/release success path, lock contention behavior,
* and robust release behavior.
*/
class FilesystemRunLockPortAdapterTest {
@TempDir
Path tempDir;
@Test
void acquire_createsLockFile() {
Path lockFile = tempDir.resolve("test.lock");
FilesystemRunLockPortAdapter adapter = new FilesystemRunLockPortAdapter(lockFile);
adapter.acquire();
assertTrue(Files.exists(lockFile), "Lock file should exist after acquire");
}
@Test
void acquire_writesProcessPidToLockFile() throws Exception {
Path lockFile = tempDir.resolve("test.lock");
FilesystemRunLockPortAdapter adapter = new FilesystemRunLockPortAdapter(lockFile);
adapter.acquire();
String content = Files.readString(lockFile);
long pid = ProcessHandle.current().pid();
assertEquals(String.valueOf(pid), content, "Lock file should contain current PID");
}
@Test
void release_deletesLockFile() throws Exception {
Path lockFile = tempDir.resolve("test.lock");
FilesystemRunLockPortAdapter adapter = new FilesystemRunLockPortAdapter(lockFile);
adapter.acquire();
assertTrue(Files.exists(lockFile));
adapter.release();
assertFalse(Files.exists(lockFile), "Lock file should be deleted after release");
}
@Test
void release_doesNotThrowIfLockFileAbsent() {
Path lockFile = tempDir.resolve("nonexistent.lock");
FilesystemRunLockPortAdapter adapter = new FilesystemRunLockPortAdapter(lockFile);
assertDoesNotThrow(adapter::release, "Release without prior acquire should not throw");
}
@Test
void acquire_throwsRunLockUnavailableExceptionIfLockFileExists() throws Exception {
Path lockFile = tempDir.resolve("test.lock");
Files.writeString(lockFile, "12345");
FilesystemRunLockPortAdapter adapter = new FilesystemRunLockPortAdapter(lockFile);
assertThrows(RunLockUnavailableException.class, adapter::acquire,
"Acquire should throw RunLockUnavailableException when lock file already exists");
}
@Test
void acquire_exceptionMessageContainsLockFilePath() throws Exception {
Path lockFile = tempDir.resolve("test.lock");
Files.writeString(lockFile, "12345");
FilesystemRunLockPortAdapter adapter = new FilesystemRunLockPortAdapter(lockFile);
RunLockUnavailableException ex = assertThrows(RunLockUnavailableException.class, adapter::acquire);
assertTrue(ex.getMessage().contains(lockFile.toString()),
"Exception message should contain lock file path");
}
@Test
void acquire_createsParentDirectoriesIfAbsent() {
Path lockFile = tempDir.resolve("nested").resolve("deep").resolve("test.lock");
FilesystemRunLockPortAdapter adapter = new FilesystemRunLockPortAdapter(lockFile);
adapter.acquire();
assertTrue(Files.exists(lockFile), "Lock file should be created including parent dirs");
}
@Test
void acquireAndRelease_canBeRepeated() {
Path lockFile = tempDir.resolve("test.lock");
FilesystemRunLockPortAdapter adapter = new FilesystemRunLockPortAdapter(lockFile);
adapter.acquire();
adapter.release();
adapter.acquire();
adapter.release();
assertFalse(Files.exists(lockFile), "Lock file should not exist after second release");
}
@Test
void acquire_secondCallThrowsRunLockUnavailableException() {
Path lockFile = tempDir.resolve("test.lock");
FilesystemRunLockPortAdapter adapter = new FilesystemRunLockPortAdapter(lockFile);
adapter.acquire();
assertThrows(RunLockUnavailableException.class, adapter::acquire,
"Second acquire without release should throw RunLockUnavailableException");
}
}