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
@@ -4,8 +4,11 @@ import de.gecheckt.pdf.umbenenner.adapter.inbound.cli.SchedulerBatchCommand;
import de.gecheckt.pdf.umbenenner.application.config.InvalidStartConfigurationException;
import de.gecheckt.pdf.umbenenner.application.config.StartConfiguration;
import de.gecheckt.pdf.umbenenner.application.config.StartConfigurationValidator;
import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunOutcome;
import de.gecheckt.pdf.umbenenner.application.port.in.RunBatchProcessingUseCase;
import de.gecheckt.pdf.umbenenner.application.port.out.ConfigurationPort;
import de.gecheckt.pdf.umbenenner.application.port.out.RunLockPort;
import de.gecheckt.pdf.umbenenner.domain.model.BatchRunContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -35,8 +38,9 @@ class BootstrapRunnerTest {
// Create mock factories that return working components
BootstrapRunner runner = new BootstrapRunner(
() -> mockConfigPort,
lockFile -> new MockRunLockPort(),
StartConfigurationValidator::new,
port -> new MockRunBatchProcessingUseCase(true),
(port, lock) -> new MockRunBatchProcessingUseCase(true),
useCase -> new SchedulerBatchCommand(useCase)
);
@@ -60,8 +64,9 @@ class BootstrapRunnerTest {
BootstrapRunner runner = new BootstrapRunner(
() -> mockConfigPort,
lockFile -> new MockRunLockPort(),
() -> failingValidator,
port -> new MockRunBatchProcessingUseCase(true),
(port, lock) -> new MockRunBatchProcessingUseCase(true),
useCase -> new SchedulerBatchCommand(useCase)
);
@@ -79,8 +84,9 @@ class BootstrapRunnerTest {
BootstrapRunner runner = new BootstrapRunner(
() -> failingConfigPort,
lockFile -> new MockRunLockPort(),
StartConfigurationValidator::new,
port -> new MockRunBatchProcessingUseCase(true),
(port, lock) -> new MockRunBatchProcessingUseCase(true),
useCase -> new SchedulerBatchCommand(useCase)
);
@@ -98,8 +104,9 @@ class BootstrapRunnerTest {
BootstrapRunner runner = new BootstrapRunner(
() -> throwingConfigPort,
lockFile -> new MockRunLockPort(),
StartConfigurationValidator::new,
port -> new MockRunBatchProcessingUseCase(true),
(port, lock) -> new MockRunBatchProcessingUseCase(true),
useCase -> new SchedulerBatchCommand(useCase)
);
@@ -109,23 +116,45 @@ class BootstrapRunnerTest {
}
@Test
void run_returnsOneWhenCommandReturnsFalse() throws Exception {
void run_returnsOneWhenBatchFails() throws Exception {
// Create a mock configuration port that returns valid config
ConfigurationPort mockConfigPort = new MockConfigurationPort(tempDir, true);
// Create a use case that returns false
RunBatchProcessingUseCase failingUseCase = () -> false;
// Create a use case that returns failure outcome
RunBatchProcessingUseCase failingUseCase = (context) -> BatchRunOutcome.FAILURE;
BootstrapRunner runner = new BootstrapRunner(
() -> mockConfigPort,
lockFile -> new MockRunLockPort(),
StartConfigurationValidator::new,
port -> failingUseCase,
(port, lock) -> failingUseCase,
useCase -> new SchedulerBatchCommand(useCase)
);
int exitCode = runner.run();
assertEquals(1, exitCode, "Command returning false should return exit code 1");
assertEquals(1, exitCode, "Batch failure outcome should return exit code 1");
}
@Test
void run_returnsOneWhenLockUnavailable() throws Exception {
// AP-007: controlled early termination because another instance is already running
// maps to exit code 1 (start protection counts as a hard startup failure)
ConfigurationPort mockConfigPort = new MockConfigurationPort(tempDir, true);
RunBatchProcessingUseCase lockUnavailableUseCase = (context) -> BatchRunOutcome.LOCK_UNAVAILABLE;
BootstrapRunner runner = new BootstrapRunner(
() -> mockConfigPort,
lockFile -> new MockRunLockPort(),
StartConfigurationValidator::new,
(port, lock) -> lockUnavailableUseCase,
useCase -> new SchedulerBatchCommand(useCase)
);
int exitCode = runner.run();
assertEquals(1, exitCode, "Lock unavailable (another instance running) should return exit code 1");
}
@Test
@@ -194,8 +223,23 @@ class BootstrapRunnerTest {
}
@Override
public boolean execute() {
return shouldSucceed;
public BatchRunOutcome execute(BatchRunContext context) {
return shouldSucceed ? BatchRunOutcome.SUCCESS : BatchRunOutcome.FAILURE;
}
}
/**
* Mock RunLockPort for testing.
*/
private static class MockRunLockPort implements RunLockPort {
@Override
public void acquire() {
// Mock: no-op
}
@Override
public void release() {
// Mock: no-op
}
}
}