1 | package com.github.dakusui.actionunit.utils; | |
2 | ||
3 | import com.github.dakusui.actionunit.exceptions.ActionTimeOutException; | |
4 | ||
5 | import java.lang.reflect.Method; | |
6 | import java.util.Map; | |
7 | import java.util.Objects; | |
8 | import java.util.concurrent.*; | |
9 | import java.util.function.Function; | |
10 | import java.util.function.Supplier; | |
11 | ||
12 | import static com.github.dakusui.actionunit.exceptions.ActionException.wrap; | |
13 | import static com.github.dakusui.actionunit.utils.Checks.checkNotNull; | |
14 | import static java.lang.String.format; | |
15 | import static java.util.Objects.requireNonNull; | |
16 | ||
17 | public enum InternalUtils { | |
18 | ; | |
19 | public static final Method OBJECT_TO_STRING_METHOD = objectToStringMethod(); | |
20 | ||
21 | public static void sleep(long duration, TimeUnit timeUnit) { | |
22 | try { | |
23 |
1
1. sleep : removed call to java/util/concurrent/TimeUnit::sleep → KILLED |
checkNotNull(timeUnit).sleep(duration); |
24 | } catch (InterruptedException e) { | |
25 |
1
1. sleep : removed call to java/lang/Thread::interrupt → SURVIVED |
Thread.currentThread().interrupt(); |
26 | throw wrap(e); | |
27 | } | |
28 | } | |
29 | ||
30 | public static <T> T runWithTimeout(Callable<T> callable, Supplier<String> description, Supplier<String> timeoutDescription, long timeout, TimeUnit timeUnit) { | |
31 | final ExecutorService executor = Executors.newSingleThreadExecutor(); | |
32 | final Future<T> future = executor.submit(callable); | |
33 |
1
1. runWithTimeout : removed call to java/util/concurrent/ExecutorService::shutdown → SURVIVED |
executor.shutdown(); // This does not cancel the already-scheduled task. |
34 | try { | |
35 | Thread.interrupted(); | |
36 |
1
1. runWithTimeout : replaced return value with null for com/github/dakusui/actionunit/utils/InternalUtils::runWithTimeout → SURVIVED |
return future.get(timeout, timeUnit); |
37 | } catch (InterruptedException e) { | |
38 |
1
1. runWithTimeout : removed call to java/lang/Thread::interrupt → SURVIVED |
Thread.currentThread().interrupt(); |
39 | throw wrap(e); | |
40 | } catch (TimeoutException e) { | |
41 | future.cancel(true); | |
42 | throw new ActionTimeOutException( | |
43 | String.format("Action: <%s>; %s with message: <%s>", description.get(), timeoutDescription.get(), e.getMessage()), | |
44 | e); | |
45 | } catch (ExecutionException e) { | |
46 | //unwrap the root cause | |
47 | Throwable cause = e.getCause(); | |
48 |
1
1. runWithTimeout : negated conditional → KILLED |
if (cause instanceof Error) { |
49 | throw (Error) cause; | |
50 | } | |
51 | //// | |
52 | // It's safe to directly cast to RuntimeException, because a Callable can only | |
53 | // throw an Error or a RuntimeException. | |
54 | throw (RuntimeException) cause; | |
55 | } finally { | |
56 | executor.shutdownNow(); | |
57 | } | |
58 | } | |
59 | ||
60 | public static String indent(int level, int indentWidth) { | |
61 | StringBuilder b = new StringBuilder(); | |
62 |
3
1. indent : changed conditional boundary → SURVIVED 2. indent : Changed increment from 1 to -1 → TIMED_OUT 3. indent : negated conditional → TIMED_OUT |
for (int i = 0; i < level; i++) |
63 | b.append(spaces(indentWidth)); | |
64 |
1
1. indent : replaced return value with "" for com/github/dakusui/actionunit/utils/InternalUtils::indent → SURVIVED |
return b.toString(); |
65 | } | |
66 | ||
67 | public static String formatNumberOfTimes(int i) { | |
68 |
1
1. formatNumberOfTimes : negated conditional → KILLED |
if (i == 1) |
69 |
1
1. formatNumberOfTimes : replaced return value with "" for com/github/dakusui/actionunit/utils/InternalUtils::formatNumberOfTimes → KILLED |
return "once"; |
70 |
1
1. formatNumberOfTimes : negated conditional → KILLED |
if (i == 2) |
71 |
1
1. formatNumberOfTimes : replaced return value with "" for com/github/dakusui/actionunit/utils/InternalUtils::formatNumberOfTimes → KILLED |
return "twice"; |
72 |
1
1. formatNumberOfTimes : replaced return value with "" for com/github/dakusui/actionunit/utils/InternalUtils::formatNumberOfTimes → SURVIVED |
return String.format("%s times", i); |
73 | } | |
74 | ||
75 | ||
76 | public static String formatDuration(long durationInNanos) { | |
77 | TimeUnit timeUnit = chooseTimeUnit(durationInNanos); | |
78 |
1
1. formatDuration : replaced return value with "" for com/github/dakusui/actionunit/utils/InternalUtils::formatDuration → KILLED |
return format("%d [%s]", timeUnit.convert(durationInNanos, TimeUnit.NANOSECONDS), timeUnit.toString().toLowerCase()); |
79 | } | |
80 | ||
81 | private static TimeUnit chooseTimeUnit(long intervalInNanos) { | |
82 | // TimeUnit.values() returns elements of TimeUnit in declared order | |
83 | // And they are declared in ascending order. | |
84 | for (TimeUnit timeUnit : TimeUnit.values()) { | |
85 |
2
1. chooseTimeUnit : changed conditional boundary → KILLED 2. chooseTimeUnit : negated conditional → KILLED |
if (1000 > timeUnit.convert(intervalInNanos, TimeUnit.NANOSECONDS)) { |
86 |
1
1. chooseTimeUnit : replaced return value with null for com/github/dakusui/actionunit/utils/InternalUtils::chooseTimeUnit → KILLED |
return timeUnit; |
87 | } | |
88 | } | |
89 |
1
1. chooseTimeUnit : replaced return value with null for com/github/dakusui/actionunit/utils/InternalUtils::chooseTimeUnit → KILLED |
return TimeUnit.DAYS; |
90 | } | |
91 | ||
92 | public static String spaces(int numSpaces) { | |
93 | StringBuilder ret = new StringBuilder(); | |
94 |
3
1. spaces : changed conditional boundary → SURVIVED 2. spaces : negated conditional → SURVIVED 3. spaces : Changed increment from 1 to -1 → KILLED |
for (int i = 0; i < numSpaces; i++) { |
95 | ret.append(" "); | |
96 | } | |
97 |
1
1. spaces : replaced return value with "" for com/github/dakusui/actionunit/utils/InternalUtils::spaces → SURVIVED |
return ret.toString(); |
98 | } | |
99 | ||
100 | public static String summary(String s) { | |
101 |
3
1. summary : changed conditional boundary → NO_COVERAGE 2. summary : negated conditional → NO_COVERAGE 3. summary : replaced return value with "" for com/github/dakusui/actionunit/utils/InternalUtils::summary → NO_COVERAGE |
return requireNonNull(s).length() > 40 |
102 | ? s.substring(0, 40) + "..." | |
103 | : s; | |
104 | } | |
105 | ||
106 | public static String toStringIfOverriddenOrNoname(Object o) { | |
107 |
1
1. toStringIfOverriddenOrNoname : replaced return value with "" for com/github/dakusui/actionunit/utils/InternalUtils::toStringIfOverriddenOrNoname → KILLED |
return objectToStringIfOverridden(o, fallbackFormatter()); |
108 | } | |
109 | ||
110 | public static Function<Object, String> fallbackFormatter() { | |
111 |
2
1. fallbackFormatter : replaced return value with null for com/github/dakusui/actionunit/utils/InternalUtils::fallbackFormatter → KILLED 2. lambda$fallbackFormatter$0 : replaced return value with "" for com/github/dakusui/actionunit/utils/InternalUtils::lambda$fallbackFormatter$0 → KILLED |
return obj -> "(noname)"; |
112 | } | |
113 | ||
114 | public static String objectToStringIfOverridden(Object o, Function<Object, String> formatter) { | |
115 | requireNonNull(formatter); | |
116 | try { | |
117 |
2
1. objectToStringIfOverridden : negated conditional → KILLED 2. objectToStringIfOverridden : replaced return value with "" for com/github/dakusui/actionunit/utils/InternalUtils::objectToStringIfOverridden → KILLED |
return !Objects.equals(o.getClass().getMethod("toString"), OBJECT_TO_STRING_METHOD) ? |
118 | o.toString() : | |
119 | formatter.apply(o); | |
120 | } catch (NoSuchMethodException e) { | |
121 |
1
1. objectToStringIfOverridden : replaced return value with "" for com/github/dakusui/actionunit/utils/InternalUtils::objectToStringIfOverridden → NO_COVERAGE |
return formatter.apply(o); |
122 | } | |
123 | } | |
124 | ||
125 | private static Method objectToStringMethod() { | |
126 | try { | |
127 | return Object.class.getMethod("toString"); | |
128 | } catch (NoSuchMethodException e) { | |
129 | throw wrap(e); | |
130 | } | |
131 | } | |
132 | ||
133 | public static <T, R> Function<T, R> memoize(Function<T, R> function) { | |
134 | Map<T, R> memo = new ConcurrentHashMap<>(); | |
135 |
2
1. lambda$memoize$1 : replaced return value with null for com/github/dakusui/actionunit/utils/InternalUtils::lambda$memoize$1 → NO_COVERAGE 2. memoize : replaced return value with null for com/github/dakusui/actionunit/utils/InternalUtils::memoize → NO_COVERAGE |
return t -> memo.computeIfAbsent(t, function); |
136 | } | |
137 | } | |
Mutations | ||
23 |
1.1 |
|
25 |
1.1 |
|
33 |
1.1 |
|
36 |
1.1 |
|
38 |
1.1 |
|
48 |
1.1 |
|
62 |
1.1 2.2 3.3 |
|
64 |
1.1 |
|
68 |
1.1 |
|
69 |
1.1 |
|
70 |
1.1 |
|
71 |
1.1 |
|
72 |
1.1 |
|
78 |
1.1 |
|
85 |
1.1 2.2 |
|
86 |
1.1 |
|
89 |
1.1 |
|
94 |
1.1 2.2 3.3 |
|
97 |
1.1 |
|
101 |
1.1 2.2 3.3 |
|
107 |
1.1 |
|
111 |
1.1 2.2 |
|
117 |
1.1 2.2 |
|
121 |
1.1 |
|
135 |
1.1 2.2 |