Complete folder scheduler verification

This commit is contained in:
JSLMPR 2026-07-10 09:03:31 +02:00
parent 8e67566f0d
commit c08acb5f18
5 changed files with 66 additions and 1 deletions

View File

@ -31,7 +31,7 @@ Note: the local machine's filesystem root is read-only in this workspace, so abs
11. [x] Add unit tests for ordering, invalid-file handling, repeat prevention, and state transitions.
12. [x] Add optional FFmpeg integration test for a short fixture.
13. [x] Add local profile or documented runtime config for enabling the scheduler.
14. [ ] Run verification and mark feature complete.
14. [x] Run verification and mark feature complete.
## Format Recommendation
@ -87,8 +87,20 @@ mvn spring-boot:run -Dspring-boot.run.profiles=folder-scheduler-local
Place source videos in `input/source`. The service creates `input/working`, `input/processed`, and `input/rejected` at startup and writes clips to `output/clips/<video-name>`.
Producers must copy files with a temporary `.part`, `.tmp`, or `.download` suffix and atomically rename them to the final video filename only after the write completes. The scheduler ignores these temporary suffixes, preventing partially written videos from being rejected by `ffprobe`.
For production, keep the default absolute paths and mount persistent writable volumes at `/input` and `/output`. Run only one scheduler replica unless a cross-process lease is added.
## Completion Status
Completed on 2026-07-10.
- `mvn -q clean verify`: passed with 57 tests, 0 failures, 0 errors, and 0 skipped tests.
- Real FFmpeg integration: a generated 17-second H.264/AAC source produced 3 MP4 clips.
- JaCoCo scheduler package coverage: 1,009/1,009 instructions, 52/52 branches, and 205/205 lines covered (100%).
- Coverage enforcement and the HTML/XML/CSV report run automatically during Maven `verify`.
- Final review fixed conditional Spring component creation and explicit constructor injection; the disabled default profile and enabled scheduler pipeline both have context tests.
## Processing Rules
The scheduler should:

View File

@ -135,6 +135,13 @@
</rules>
</configuration>
</execution>
<execution>
<id>coverage-report</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>

View File

@ -1,6 +1,8 @@
package org.example.videoclips.folder;
import org.example.videoclips.config.VideoClippingProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import java.io.IOException;
@ -11,11 +13,13 @@ import java.util.List;
import java.util.stream.Stream;
@Component
@ConditionalOnProperty(name = "video-clipping.folder-scheduler.enabled", havingValue = "true")
public class FolderFfmpegClipper {
private final VideoClippingProperties.FolderScheduler properties;
private final ProcessExecutor processExecutor;
@Autowired
public FolderFfmpegClipper(VideoClippingProperties videoClippingProperties) {
this(videoClippingProperties, FolderFfmpegClipper::execute);
}

View File

@ -1,6 +1,8 @@
package org.example.videoclips.folder;
import org.example.videoclips.config.VideoClippingProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import java.io.IOException;
@ -13,6 +15,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component
@ConditionalOnProperty(name = "video-clipping.folder-scheduler.enabled", havingValue = "true")
public class FolderVideoValidator {
private static final Set<String> ALLOWED_EXTENSIONS = Set.of("mp4", "mov", "m4v", "webm", "mkv");
@ -20,6 +23,7 @@ public class FolderVideoValidator {
private final VideoClippingProperties.FolderScheduler properties;
private final ProcessExecutor processExecutor;
@Autowired
public FolderVideoValidator(VideoClippingProperties videoClippingProperties) {
this(videoClippingProperties, FolderVideoValidator::execute);
}

View File

@ -0,0 +1,38 @@
package org.example.videoclips.folder;
import org.example.videoclips.config.VideoClippingProperties;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import static org.assertj.core.api.Assertions.assertThat;
class FolderSchedulerSpringContextTest {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withBean(VideoClippingProperties.class)
.withUserConfiguration(
FolderVideoValidator.class,
FolderFfmpegClipper.class,
FolderVideoScanScheduler.class
);
@Test
void createsCompleteSchedulerPipelineWhenEnabled() {
contextRunner
.withPropertyValues("video-clipping.folder-scheduler.enabled=true")
.run(context -> {
assertThat(context).hasSingleBean(FolderVideoValidator.class);
assertThat(context).hasSingleBean(FolderFfmpegClipper.class);
assertThat(context).hasSingleBean(FolderVideoScanScheduler.class);
});
}
@Test
void doesNotCreateSchedulerPipelineWhenDisabled() {
contextRunner.run(context -> {
assertThat(context).doesNotHaveBean(FolderVideoValidator.class);
assertThat(context).doesNotHaveBean(FolderFfmpegClipper.class);
assertThat(context).doesNotHaveBean(FolderVideoScanScheduler.class);
});
}
}