ActionPerformer.java

1
package com.github.dakusui.actionunit.visitors;
2
3
import com.github.dakusui.actionunit.actions.*;
4
import com.github.dakusui.actionunit.core.Action;
5
import com.github.dakusui.actionunit.core.Context;
6
import com.github.dakusui.actionunit.utils.InternalUtils;
7
8
import java.util.Map;
9
import java.util.concurrent.ConcurrentHashMap;
10
import java.util.function.Function;
11
import java.util.stream.Stream;
12
13
import static com.github.dakusui.actionunit.exceptions.ActionException.wrap;
14
import static java.util.Objects.requireNonNull;
15
import static java.util.concurrent.TimeUnit.NANOSECONDS;
16
17
public abstract class ActionPerformer implements Action.Visitor {
18
  public static final String  ONGOING_EXCEPTIONS_TABLE_NAME = "ONGOING_EXCEPTIONS";
19
  protected           Context context;
20
21
  protected ActionPerformer(Context context) {
22
    this.context = requireNonNull(context);
23
    Map<Action, Throwable> ongoingExceptions = new ConcurrentHashMap<>();
24
    this.context.assignTo(ONGOING_EXCEPTIONS_TABLE_NAME, ongoingExceptions);
25
  }
26
27
  @Override
28
  public void visit(Leaf action) {
29 1 1. visit : removed call to java/lang/Runnable::run → KILLED
    action.runnable(context).run();
30
  }
31
32
  @Override
33
  public void visit(Named action) {
34 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
    callAccept(action.action(), this);
35
  }
36
37
  @Override
38
  public void visit(Composite action) {
39 1 1. visit : negated conditional → KILLED
    Stream<Action> actionStream = action.isParallel()
40
        ? action.children().parallelStream()
41
        : action.children().stream();
42 1 1. visit : removed call to java/util/stream/Stream::forEach → KILLED
    actionStream.forEach(
43 1 1. lambda$visit$0 : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
        a -> callAccept(a,
44 1 1. lambda$visit$0 : negated conditional → TIMED_OUT
            action.isParallel() ?
45
                newInstance(this.context.createChild()) :
46
                this));
47
  }
48
49
  @Override
50
  public <E> void visit(ForEach<E> action) {
51
    Stream<E> data = action.valueSource().apply(this.context);
52
    Function<E, Action.Visitor> visitorFactory = v -> {
53
      this.context.assignTo(action.internalVariableName(), v);
54 1 1. lambda$visit$1 : replaced return value with null for com/github/dakusui/actionunit/visitors/ActionPerformer::lambda$visit$1 → KILLED
      return this;
55
    };
56 1 1. visit : negated conditional → KILLED
    if (action.isParallel()) {
57
      data = data.parallel();
58 1 1. lambda$visit$2 : replaced return value with null for com/github/dakusui/actionunit/visitors/ActionPerformer::lambda$visit$2 → KILLED
      visitorFactory = v -> newInstance(this.context.createChild().assignTo(action.internalVariableName(), v));
59
    }
60
    Function<E, Action.Visitor> finalVisitorFactory = visitorFactory;
61 2 1. lambda$visit$3 : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
2. visit : removed call to java/util/stream/Stream::forEach → KILLED
    data.forEach(each -> callAccept(
62
        action.action(),
63
        finalVisitorFactory.apply(each)));
64
  }
65
66
  @Override
67
  public void visit(While action) {
68 1 1. visit : negated conditional → KILLED
    while (action.condition().test(this.context)) {
69 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → TIMED_OUT
      callAccept(action.perform(), this);
70
    }
71
  }
72
73
  @Override
74
  public void visit(When action) {
75 1 1. visit : negated conditional → KILLED
    if (action.cond().test(this.context)) {
76 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
      callAccept(action.perform(), this);
77
    } else {
78 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
      callAccept(action.otherwise(), this);
79
    }
80
  }
81
82
  @Override
83
  public <V> void visit(With<V> action) {
84
    Context originalContext = this.context;
85
    this.context = this.context.createChild();
86
    context.assignTo(action.internalVariableName(), action.valueSource().apply(context));
87
    try {
88 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
      callAccept(action.action(), this);
89
    } finally {
90 2 1. lambda$visit$4 : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → SURVIVED
2. visit : removed call to java/util/Optional::ifPresent → SURVIVED
      action.close().ifPresent(a -> callAccept(a, this));
91
      this.context = originalContext;
92
    }
93
  }
94
95
  @Override
96
  public void visit(Attempt action) {
97
    Context originalContext = this.context;
98
    try {
99 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
      callAccept(action.perform(), this);
100
    } catch (Throwable t) {
101 1 1. visit : negated conditional → KILLED
      if (action.targetExceptionClass().isAssignableFrom(t.getClass())) {
102
        this.context = this.context.createChild();
103 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
        callAccept(action.recover(), newInstance(
104
            originalContext.assignTo(Context.Impl.ONGOING_EXCEPTION, t)
105
        ));
106
      } else
107
        throw wrap(t);
108
    } finally {
109 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
      callAccept(action.ensure(), this);
110
      this.context = originalContext;
111
    }
112
  }
113
114
  @Override
115
  public void visit(Retry action) {
116
    boolean succeeded = false;
117
    Action targetAction = action.perform();
118
    Throwable lastException = null;
119 3 1. visit : Changed increment from 1 to -1 → TIMED_OUT
2. visit : changed conditional boundary → KILLED
3. visit : negated conditional → KILLED
    for (int i = 0; i <= action.times(); i++) {
120
      try {
121 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
        callAccept(targetAction, this);
122
        succeeded = true;
123
        break;
124
      } catch (Throwable t) {
125 1 1. visit : negated conditional → KILLED
        if (action.targetExceptionClass().isAssignableFrom(t.getClass())) {
126
          lastException = t;
127 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::registerLastExceptionFor → SURVIVED
          registerLastExceptionFor(targetAction, lastException);
128 1 1. visit : removed call to com/github/dakusui/actionunit/utils/InternalUtils::sleep → SURVIVED
          InternalUtils.sleep(action.intervalInNanoseconds(), NANOSECONDS);
129
        } else {
130
          throw wrap(t);
131
        }
132
      }
133
    }
134 1 1. visit : negated conditional → KILLED
    if (succeeded) {
135 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::unregisterLastExceptionFor → SURVIVED
      unregisterLastExceptionFor(targetAction);
136
    } else {
137
      throw wrap(lastException);
138
    }
139
  }
140
141
  @Override
142
  public void visit(TimeOut action) {
143
    InternalUtils.runWithTimeout(
144
        () -> {
145 1 1. lambda$visit$5 : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
          callAccept(action.perform(), ActionPerformer.this);
146 1 1. lambda$visit$5 : replaced Boolean return with False for com/github/dakusui/actionunit/visitors/ActionPerformer::lambda$visit$5 → SURVIVED
          return true;
147
        },
148 1 1. lambda$visit$6 : replaced return value with "" for com/github/dakusui/actionunit/visitors/ActionPerformer::lambda$visit$6 → SURVIVED
        () -> String.format("%s", action),
149 1 1. lambda$visit$7 : replaced return value with "" for com/github/dakusui/actionunit/visitors/ActionPerformer::lambda$visit$7 → SURVIVED
        () -> formatOngoingExceptions(action.perform()),
150
        action.durationInNanos(),
151
        NANOSECONDS);
152
  }
153
154
  @Override
155
  public void visit(Ensured action) {
156 1 1. visit : negated conditional → KILLED
    if (action.ensurers().isEmpty()) {
157 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → NO_COVERAGE
      callAccept(action.target(), this);
158
      return;
159
    }
160
    Throwable t = null;
161 1 1. visit : Replaced integer subtraction with addition → KILLED
    Action lastEnsurer = action.ensurers().get(action.ensurers().size() - 1);
162
    for (Action each : action.ensurers()) {
163
      t = null;
164
      try {
165 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → SURVIVED
        callAccept(each, this);
166 1 1. visit : removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED
        callAccept(action.target(), this);
167
        break;
168
      } catch (OutOfMemoryError | StackOverflowError e) {
169
        throw e;
170
      } catch (Exception | Error e) {
171 1 1. visit : negated conditional → KILLED
        if (!action.isRecoverable(e)) {
172
          throw (RuntimeException) action.rethrow(e);
173 1 1. visit : negated conditional → KILLED
        } else if (each == lastEnsurer) {
174
          t = e;
175
        }
176
      }
177
    }
178 1 1. visit : negated conditional → KILLED
    if (t != null) {
179
      throw wrap(t);
180
    }
181
  }
182
183
  protected abstract Action.Visitor newInstance(Context context);
184
185
  protected abstract void callAccept(Action action, Action.Visitor visitor);
186
187
  private void registerLastExceptionFor(Action action, Throwable e) {
188
    ongoingExceptionsTable().put(action, e);
189
  }
190
191
  private void unregisterLastExceptionFor(Action action) {
192
    ongoingExceptionsTable().remove(action);
193
  }
194
195
  private Map<Action, Throwable> ongoingExceptionsTable() {
196 1 1. ongoingExceptionsTable : replaced return value with Collections.emptyMap for com/github/dakusui/actionunit/visitors/ActionPerformer::ongoingExceptionsTable → KILLED
    return this.context.valueOf(ONGOING_EXCEPTIONS_TABLE_NAME);
197
  }
198
199
  private String formatOngoingExceptions(Action action) {
200
    StringBuilder b = new StringBuilder();
201
    b.append("[").append(action).append("]");
202
    for (Action ongoingAction : ongoingExceptionsTable().keySet()) {
203
      b.append(String.format("%n%s%n----%n", ongoingAction));
204
      Throwable e = ongoingExceptionsTable().get(ongoingAction);
205
      b.append(e.getMessage());
206
      b.append(String.format("%n"));
207
      for (StackTraceElement element : e.getStackTrace()) {
208
        b.append("\t");
209
        b.append(element);
210
        b.append(String.format("%n"));
211
      }
212
    }
213 1 1. formatOngoingExceptions : replaced return value with "" for com/github/dakusui/actionunit/visitors/ActionPerformer::formatOngoingExceptions → SURVIVED
    return b.toString();
214
  }
215
}

Mutations

29

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.simpleTest(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
removed call to java/lang/Runnable::run → KILLED

34

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.givenWhenAction$whenPerform$thenObjectAdded(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

39

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.sequentialTest(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
negated conditional → KILLED

42

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.concurrentTest$runtimeExceptionThrown(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
removed call to java/util/stream/Stream::forEach → KILLED

43

1.1
Location : lambda$visit$0
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.concurrentTest$runtimeExceptionThrown(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

44

1.1
Location : lambda$visit$0
Killed by : none
negated conditional → TIMED_OUT

54

1.1
Location : lambda$visit$1
Killed by : com.github.dakusui.actionunit.ut.VariationTest.forEachAndPipedAction(com.github.dakusui.actionunit.ut.VariationTest)
replaced return value with null for com/github/dakusui/actionunit/visitors/ActionPerformer::lambda$visit$1 → KILLED

56

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.ut.VariationTest.doubleLoop(com.github.dakusui.actionunit.ut.VariationTest)
negated conditional → KILLED

58

1.1
Location : lambda$visit$2
Killed by : com.github.dakusui.actionunit.scenarios.ActionSupportTest.giveExampleScenarioThatThrowsError$whenPerform$thenExceptionThrown(com.github.dakusui.actionunit.scenarios.ActionSupportTest)
replaced return value with null for com/github/dakusui/actionunit/visitors/ActionPerformer::lambda$visit$2 → KILLED

61

1.1
Location : lambda$visit$3
Killed by : com.github.dakusui.actionunit.ut.VariationTest.doubleLoop(com.github.dakusui.actionunit.ut.VariationTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

2.2
Location : visit
Killed by : com.github.dakusui.actionunit.ut.VariationTest.doubleLoop(com.github.dakusui.actionunit.ut.VariationTest)
removed call to java/util/stream/Stream::forEach → KILLED

68

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.ut.actions.WhileTest.givenWhileActionWithConditionNeverMet_whenPerform_thenNothingHappens(com.github.dakusui.actionunit.ut.actions.WhileTest)
negated conditional → KILLED

69

1.1
Location : visit
Killed by : none
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → TIMED_OUT

75

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.givenWhenAction$whenPerform$thenObjectAdded(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
negated conditional → KILLED

76

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.givenWhenAction$whenPerform$thenObjectAdded(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

78

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.ut.actions.WhenTest.givenOneValue$when_NotMatchingWhen_$thenWorksFine(com.github.dakusui.actionunit.ut.actions.WhenTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

88

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.ut.actions.WithTest.givenWithAction_whenPerform2(com.github.dakusui.actionunit.ut.actions.WithTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

90

1.1
Location : lambda$visit$4
Killed by : none
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → SURVIVED

2.2
Location : visit
Killed by : none
removed call to java/util/Optional::ifPresent → SURVIVED

99

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.ut.actions.AttemptTest.givenAttemptAction$whenPerform$thenWorksFine(com.github.dakusui.actionunit.ut.actions.AttemptTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

101

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.ut.actions.AttemptTest.givenAttemptAction$whenPerform$thenWorksFine(com.github.dakusui.actionunit.ut.actions.AttemptTest)
negated conditional → KILLED

103

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.ut.actions.AttemptTest.givenAttemptAction$whenPerform$thenWorksFine(com.github.dakusui.actionunit.ut.actions.AttemptTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

109

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.ut.actions.AttemptTest.givenAttemptAction$whenPerform$thenWorksFine(com.github.dakusui.actionunit.ut.actions.AttemptTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

119

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.retryTest(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
changed conditional boundary → KILLED

2.2
Location : visit
Killed by : none
Changed increment from 1 to -1 → TIMED_OUT

3.3
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.ActionSupportTest.givenRetryWithPassingAction$whenPerform$thenNoRetry(com.github.dakusui.actionunit.scenarios.ActionSupportTest)
negated conditional → KILLED

121

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.retryTest(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

125

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.retryTest$failOnce(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
negated conditional → KILLED

127

1.1
Location : visit
Killed by : none
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::registerLastExceptionFor → SURVIVED

128

1.1
Location : visit
Killed by : none
removed call to com/github/dakusui/actionunit/utils/InternalUtils::sleep → SURVIVED

134

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.ActionSupportTest.givenRetryWithPassingAction$whenPerform$thenNoRetry(com.github.dakusui.actionunit.scenarios.ActionSupportTest)
negated conditional → KILLED

135

1.1
Location : visit
Killed by : none
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::unregisterLastExceptionFor → SURVIVED

145

1.1
Location : lambda$visit$5
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.givenTimeOutAtTopLevel$whenRuntimeExceptionThrownFromInside$thenRuntimeException(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

146

1.1
Location : lambda$visit$5
Killed by : none
replaced Boolean return with False for com/github/dakusui/actionunit/visitors/ActionPerformer::lambda$visit$5 → SURVIVED

148

1.1
Location : lambda$visit$6
Killed by : none
replaced return value with "" for com/github/dakusui/actionunit/visitors/ActionPerformer::lambda$visit$6 → SURVIVED

149

1.1
Location : lambda$visit$7
Killed by : none
replaced return value with "" for com/github/dakusui/actionunit/visitors/ActionPerformer::lambda$visit$7 → SURVIVED

156

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.EnsuredTest.givenEnsureWithThreeEnsurers_whenPerform_thenBehavesAsExpected(com.github.dakusui.actionunit.scenarios.EnsuredTest)
negated conditional → KILLED

157

1.1
Location : visit
Killed by : none
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → NO_COVERAGE

161

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.EnsuredTest.givenEnsureWithTwoEnsurers_whenPerformActionPassingOnThirdAttempt_thenFail(com.github.dakusui.actionunit.scenarios.EnsuredTest)
Replaced integer subtraction with addition → KILLED

165

1.1
Location : visit
Killed by : none
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → SURVIVED

166

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.EnsuredTest.givenEnsureWithTwoEnsurers_whenPerformActionPassingOnThirdAttempt_thenFail(com.github.dakusui.actionunit.scenarios.EnsuredTest)
removed call to com/github/dakusui/actionunit/visitors/ActionPerformer::callAccept → KILLED

171

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.EnsuredTest.givenEnsureWithThreeEnsurers_whenPerform_thenBehavesAsExpected(com.github.dakusui.actionunit.scenarios.EnsuredTest)
negated conditional → KILLED

173

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.EnsuredTest.givenEnsureWithTwoEnsurers_whenPerformActionPassingOnThirdAttempt_thenFail(com.github.dakusui.actionunit.scenarios.EnsuredTest)
negated conditional → KILLED

178

1.1
Location : visit
Killed by : com.github.dakusui.actionunit.scenarios.EnsuredTest.givenEnsureWithTwoEnsurers_whenPerformActionPassingOnThirdAttempt_thenFail(com.github.dakusui.actionunit.scenarios.EnsuredTest)
negated conditional → KILLED

196

1.1
Location : ongoingExceptionsTable
Killed by : com.github.dakusui.actionunit.scenarios.CompatActionSupportTest.retryTest$failForever(com.github.dakusui.actionunit.scenarios.CompatActionSupportTest)
replaced return value with Collections.emptyMap for com/github/dakusui/actionunit/visitors/ActionPerformer::ongoingExceptionsTable → KILLED

213

1.1
Location : formatOngoingExceptions
Killed by : none
replaced return value with "" for com/github/dakusui/actionunit/visitors/ActionPerformer::formatOngoingExceptions → SURVIVED

Active mutators

Tests examined


Report generated by PIT 1.7.3