Skip to content

Commit

Permalink
fix incomplete BatchConfiguration
Browse files Browse the repository at this point in the history
  • Loading branch information
jo-pol committed Aug 15, 2024
1 parent 325d398 commit df00f94
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 43 deletions.
8 changes: 6 additions & 2 deletions src/main/java/nl/knaw/dans/dvcli/action/BatchProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package nl.knaw.dans.dvcli.action;

import lombok.Builder;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
Expand All @@ -34,17 +35,20 @@ public class BatchProcessor<I, R> {
/**
* The labeled items to process.
*/
@NonNull
private final List<Pair<String, I>> labeledItems;

/**
* The action to apply to each item.
*/
@NonNull
private final ThrowingFunction<I, R, Exception> action;

/**
* The report to which the results of the actions are reported.
*/
private final Report<I, R> report;
@Builder.Default
private final Report<I, R> report = new ConsoleReport<>();

/**
* The delay in milliseconds between processing items. A delay of 0 or less means no delay.
Expand All @@ -60,7 +64,7 @@ public void process() {
log.info("Processing item {} of {}", ++i, labeledItems.size());
callAction(labeledItem.getFirst(), labeledItem.getSecond());
}
log.info("Finished batch processing");
log.info("Finished batch processing of {} items", labeledItems.size());
}

private void callAction(String label, I item) {
Expand Down
89 changes: 48 additions & 41 deletions src/test/java/nl/knaw/dans/dvcli/action/BatchProcessorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ BatchProcessor.<DatasetApi, String> builder()
DEBUG Sleeping for 1 ms
INFO Processing item 3 of 3
ok
INFO Finished batch processing
INFO Finished batch processing of 3 items
""");
assertThat(TestUtils.messagesOf(logged))
.containsExactly("INFO Starting batch processing",
Expand All @@ -98,7 +98,7 @@ BatchProcessor.<DatasetApi, String> builder()
"INFO Processing item 2 of 3",
"DEBUG Sleeping for 1 ms",
"INFO Processing item 3 of 3",
"INFO Finished batch processing");
"INFO Finished batch processing of 3 items");
}

@Test
Expand Down Expand Up @@ -126,7 +126,7 @@ BatchProcessor.<DatasetApi, String> builder()
DEBUG Sleeping for 1000 ms
INFO Processing item 3 of 3
ok
INFO Finished batch processing
INFO Finished batch processing of 3 items
""");
}

Expand All @@ -153,73 +153,80 @@ BatchProcessor.<DatasetApi, String> builder()
ok
INFO Processing item 3 of 3
ok
INFO Finished batch processing
INFO Finished batch processing of 3 items
""");
}

@Test
public void batchProcessor_fails_fast_on_missing_report() {
var processor = BatchProcessor.<DatasetApi, String> builder()
public void batchProcessor_uses_a_default_report() {
BatchProcessor.<DatasetApi, String> builder()
.labeledItems(List.of(
new Pair<>("A", Mockito.mock(DatasetApi.class)),
new Pair<>("B", Mockito.mock(DatasetApi.class)),
new Pair<>("C", Mockito.mock(DatasetApi.class))
new Pair<>("X", Mockito.mock(DatasetApi.class)),
new Pair<>("Y", Mockito.mock(DatasetApi.class)),
new Pair<>("Z", Mockito.mock(DatasetApi.class))
))
.action(datasetApi -> "ok")
.build();
assertThatThrownBy(processor::process)
.isInstanceOf(NullPointerException.class)
.hasMessage("""
Cannot invoke "nl.knaw.dans.dvcli.action.Report.reportFailure(String, Object, java.lang.Exception)" because "this.report" is null""");
.delay(0L)
.build()
.process();

assertThat(stderr.toString()).isEqualTo("");
assertThat(stderr.toString()).isEqualTo("X: OK. Y: OK. Z: OK. ");
assertThat(stdout.toString()).isEqualTo("""
INFO Starting batch processing
INFO Processing item 1 of 3
ok
INFO Processing item 2 of 3
ok
INFO Processing item 3 of 3
ok
INFO Finished batch processing of 3 items
""");
}

@Test
public void batchProcessor_does_not_fail_on_empty_list() {
var processor = BatchProcessor.<DatasetApi, String> builder()
.labeledItems(new ArrayList<>())
public void batchProcessor_reports_empty_list() {
BatchProcessor.<DatasetApi, String> builder()
.labeledItems(List.of())
.action(datasetApi -> "ok")
.report(new ConsoleReport<>())
.build();
processor.process();
.build()
.process();

assertThat(stderr.toString()).isEqualTo("");
assertThat(stdout.toString()).isEqualTo("""
INFO Starting batch processing
INFO Finished batch processing of 0 items
""");
assertThat(TestUtils.messagesOf(logged)).containsExactly(
"INFO Starting batch processing",
"INFO Finished batch processing of 0 items");
}

@Test
public void batchProcessor_does_not_fail_fast_on_missing_action() {
public void batchProcessor_throws_on_missing_list() {
var processor = BatchProcessor.<DatasetApi, String> builder()
.labeledItems(List.of(
new Pair<>("A", Mockito.mock(DatasetApi.class)),
new Pair<>("B", Mockito.mock(DatasetApi.class)),
new Pair<>("C", Mockito.mock(DatasetApi.class))
))
.report(new ConsoleReport<>())
.build();
processor.process();
.action(datasetApi -> "ok")
.report(new ConsoleReport<>());

assertThat(stderr.toString()).isEqualTo("""
A: FAILED: Exception type = NullPointerException, message = Cannot invoke "nl.knaw.dans.dvcli.action.ThrowingFunction.apply(Object)" because "this.action" is null
B: FAILED: Exception type = NullPointerException, message = Cannot invoke "nl.knaw.dans.dvcli.action.ThrowingFunction.apply(Object)" because "this.action" is null
C: FAILED: Exception type = NullPointerException, message = Cannot invoke "nl.knaw.dans.dvcli.action.ThrowingFunction.apply(Object)" because "this.action" is null
""");
assertThatThrownBy(processor::build)
.isInstanceOf(NullPointerException.class)
.hasMessage("labeledItems is marked non-null but is null");

assertThat(stderr.toString()).isEqualTo("");
assertThat(stdout.toString()).isEqualTo("");
assertThat(TestUtils.messagesOf(logged)).containsExactly();
}

@Test
public void batchProcessor_fails_fast_on_missing_list() {
public void batchProcessor_fails_fast_on_missing_action() {
var processor = BatchProcessor.<DatasetApi, String> builder()
.action(datasetApi -> "ok")
.report(new ConsoleReport<>())
.build();
assertThatThrownBy(processor::process)
.labeledItems(List.of());
assertThatThrownBy(processor::build)
.isInstanceOf(NullPointerException.class)
.hasMessage("""
Cannot invoke "java.util.List.iterator()" because "this.labeledItems" is null""");
.hasMessage("action is marked non-null but is null");

assertThat(stderr.toString()).isEqualTo("");
assertThat(stdout.toString()).isEqualTo("");
assertThat(TestUtils.messagesOf(logged)).containsExactly();
}
}

0 comments on commit df00f94

Please sign in to comment.