ConfigProcessor.java

1
/*
2
 * Copyright 2014-2026 Grzegorz Piwowarek, https://4comprehension.com/
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 * https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package com.pivovarit.collectors;
17
18
import java.time.Duration;
19
import java.util.List;
20
import java.util.Objects;
21
import java.util.concurrent.Executor;
22
import java.util.concurrent.ExecutorService;
23
import java.util.concurrent.Executors;
24
import java.util.function.UnaryOperator;
25
26
import static java.util.Objects.requireNonNull;
27
28
final class ConfigProcessor {
29
30
    private static final ExecutorService DEFAULT_EXECUTOR = Executors.newThreadPerTaskExecutor(Thread.ofVirtual()
31
      .name("parallel-collectors-", 0)
32
      .factory());
33
34
    record Config(boolean ordered, boolean batching, int parallelism, Executor executor, Duration timeout) {
35
        Config {
36
            Objects.requireNonNull(executor, "executor can't be null");
37
        }
38
    }
39
40
    static Config process(List<Option> options) {
41
        requireNonNull(options, "options can't be null");
42
43
        Boolean batching = null;
44
        Boolean ordered = null;
45
        Integer parallelism = null;
46
        Executor executor = null;
47
        UnaryOperator<Executor> decorator = null;
48
        UnaryOperator<Runnable> taskDecorator = null;
49
        Duration timeout = null;
50
51
        for (var option : options) {
52
            switch (option) {
53
                case Option.Batched ignored -> batching = true;
54 1 1. process : negated conditional → KILLED
                case Option.Parallelism(var p) -> parallelism = p;
55
                case Option.ThreadPool(var e) -> executor = e;
56
                case Option.Ordered ignored -> ordered = true;
57
                case Option.ExecutorDecorator(var d) -> decorator = d;
58
                case Option.TaskDecorator(var d) -> taskDecorator = d;
59
                case Option.Timeout(var d) -> timeout = d;
60
            }
61
        }
62
63
        var resolvedExecutor = Objects.requireNonNullElse(executor, DEFAULT_EXECUTOR);
64 1 1. process : negated conditional → KILLED
        if (decorator != null) {
65
            resolvedExecutor = decorator.apply(resolvedExecutor);
66 1 1. process : removed call to com/pivovarit/collectors/Preconditions::requireValidExecutor → SURVIVED
            Preconditions.requireValidExecutor(resolvedExecutor);
67
        }
68 1 1. process : negated conditional → KILLED
        if (taskDecorator != null) {
69
            var td = taskDecorator;
70
            var delegate = resolvedExecutor;
71 1 1. lambda$process$0 : removed call to java/util/concurrent/Executor::execute → TIMED_OUT
            resolvedExecutor = r -> delegate.execute(td.apply(r));
72
        }
73
74 1 1. process : replaced return value with null for com/pivovarit/collectors/ConfigProcessor::process → KILLED
        return new Config(
75
          Objects.requireNonNullElse(ordered, false),
76
          Objects.requireNonNullElse(batching, false),
77
          Objects.requireNonNullElse(parallelism, 0),
78
          resolvedExecutor,
79
          timeout);
80
    }
81
82
    static String toHumanReadableString(Option option) {
83 1 1. toHumanReadableString : replaced return value with "" for com/pivovarit/collectors/ConfigProcessor::toHumanReadableString → KILLED
        return switch (option) {
84
            case Option.Batched ignored -> "batching";
85
            case Option.Parallelism ignored -> "parallelism";
86
            case Option.ThreadPool ignored -> "executor";
87
            case Option.Ordered ignored -> "ordered";
88
            case Option.ExecutorDecorator ignored -> "executor decorator";
89
            case Option.TaskDecorator ignored -> "task decorator";
90
            case Option.Timeout ignored -> "timeout";
91
        };
92
    }
93
94
    public sealed interface Option {
95
96
        enum Ordered implements Option {
97
            INSTANCE
98
        }
99
100
        enum Batched implements Option {
101
            INSTANCE
102
        }
103
104
        record ThreadPool(Executor executor) implements Option {
105
            public ThreadPool {
106 1 1. <init> : removed call to com/pivovarit/collectors/Preconditions::requireValidExecutor → KILLED
                Preconditions.requireValidExecutor(executor);
107
            }
108
        }
109
110
        record Parallelism(int parallelism) implements Option {
111
            public Parallelism {
112 1 1. <init> : removed call to com/pivovarit/collectors/Preconditions::requireValidParallelism → KILLED
                Preconditions.requireValidParallelism(parallelism);
113
            }
114
        }
115
116
        record ExecutorDecorator(UnaryOperator<Executor> decorator) implements Option {
117
            public ExecutorDecorator {
118
                Objects.requireNonNull(decorator, "decorator can't be null");
119
            }
120
        }
121
122
        record TaskDecorator(UnaryOperator<Runnable> decorator) implements Option {
123
            public TaskDecorator {
124
                Objects.requireNonNull(decorator, "decorator can't be null");
125
            }
126
        }
127
128
        record Timeout(Duration duration) implements Option {
129
            public Timeout {
130
                Objects.requireNonNull(duration, "duration can't be null");
131 2 1. <init> : negated conditional → KILLED
2. <init> : negated conditional → KILLED
                if (duration.isZero() || duration.isNegative()) {
132
                    throw new IllegalArgumentException("Timeout duration must be greater than 0");
133
                }
134
            }
135
        }
136
    }
137
}

Mutations

54

1.1
Location : process
Killed by : com.pivovarit.collectors.test.BasicParallelismTest.[engine:junit-jupiter]/[class:com.pivovarit.collectors.test.BasicParallelismTest]/[test-factory:shouldProcessEmptyWithMaxParallelism()]/[dynamic-test:#10]
negated conditional → KILLED

64

1.1
Location : process
Killed by : com.pivovarit.collectors.test.ExecutorDecoratorTest.[engine:junit-jupiter]/[class:com.pivovarit.collectors.test.ExecutorDecoratorTest]/[method:shouldRejectDecoratorReturningNull()]
negated conditional → KILLED

66

1.1
Location : process
Killed by : none
removed call to com/pivovarit/collectors/Preconditions::requireValidExecutor → SURVIVED
Covering tests

68

1.1
Location : process
Killed by : com.pivovarit.collectors.test.BasicParallelismTest.[engine:junit-jupiter]/[class:com.pivovarit.collectors.test.BasicParallelismTest]/[test-factory:shouldProcessEmptyWithMaxParallelism()]/[dynamic-test:#3]
negated conditional → KILLED

71

1.1
Location : lambda$process$0
Killed by : none
removed call to java/util/concurrent/Executor::execute → TIMED_OUT

74

1.1
Location : process
Killed by : com.pivovarit.collectors.test.BasicParallelismTest.[engine:junit-jupiter]/[class:com.pivovarit.collectors.test.BasicParallelismTest]/[test-factory:shouldProcessEmptyWithMaxParallelism()]/[dynamic-test:#10]
replaced return value with null for com/pivovarit/collectors/ConfigProcessor::process → KILLED

83

1.1
Location : toHumanReadableString
Killed by : com.pivovarit.collectors.OptionTest.[engine:junit-jupiter]/[class:com.pivovarit.collectors.OptionTest]/[method:shouldThrowOnDuplicateParallelism()]
replaced return value with "" for com/pivovarit/collectors/ConfigProcessor::toHumanReadableString → KILLED

106

1.1
Location : <init>
Killed by : com.pivovarit.collectors.OptionTest.[engine:junit-jupiter]/[class:com.pivovarit.collectors.OptionTest]/[method:shouldThrowOnNullExecutor()]
removed call to com/pivovarit/collectors/Preconditions::requireValidExecutor → KILLED

112

1.1
Location : <init>
Killed by : com.pivovarit.collectors.OptionTest.[engine:junit-jupiter]/[class:com.pivovarit.collectors.OptionTest]/[method:shouldThrowOnInvalidParallelism()]
removed call to com/pivovarit/collectors/Preconditions::requireValidParallelism → KILLED

131

1.1
Location : <init>
Killed by : com.pivovarit.collectors.OptionTest.[engine:junit-jupiter]/[class:com.pivovarit.collectors.OptionTest]/[method:shouldThrowOnNonPositiveTimeoutDuration()]
negated conditional → KILLED

2.2
Location : <init>
Killed by : com.pivovarit.collectors.OptionTest.[engine:junit-jupiter]/[class:com.pivovarit.collectors.OptionTest]/[method:shouldThrowOnDuplicateTimeoutDurationStreaming()]
negated conditional → KILLED

Active mutators

Tests examined


Report generated by PIT 1.30.0 support