1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.openehealth.ipf.commons.core.test;
18
19 import org.junit.rules.TestRule;
20 import org.junit.runner.Description;
21 import org.junit.runners.model.Statement;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.function.Predicate;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class ConditionalRule implements TestRule {
53
54 private static final Logger LOG = LoggerFactory.getLogger(ConditionalRule.class);
55 private Predicate<Void> predicate;
56 private String reason;
57
58 public ConditionalRule() {
59 }
60
61
62
63 public ConditionalRule runIf(Predicate<Void> condition) {
64 this.predicate = condition;
65 return this;
66 }
67
68 public ConditionalRule ifSystemProperty(final String property, final Predicate<String> condition) {
69 return runIf(source ->
70 condition.test(System.getProperty(property))).reason("condition matches on system property " + property);
71 }
72
73 public ConditionalRule ifSystemPropertyIs(final String property, final String value) {
74 return ifSystemProperty(property, s ->
75 s != null && s.equalsIgnoreCase(value)).reason("system property " + property + " equals " + value);
76 }
77 public ConditionalRule negate() {
78 if (predicate == null)
79 throw new IllegalArgumentException("Must have defined a condition before negating it");
80 predicate = predicate.negate();
81 reason = "not " + reason;
82 return this;
83 }
84
85 public ConditionalRule skipOnWindows() {
86 return ifSystemProperty("os.name", s ->
87 s.startsWith("Windows")).negate().reason("skipped because running on Windows");
88 }
89
90 public ConditionalRule skipOnTravis() {
91 return ifSystemPropertyIs("TRAVIS", "true")
92 .negate().reason("skipped because running on Travis");
93 }
94
95 public ConditionalRule reason(String reason) {
96 this.reason = reason;
97 return this;
98 }
99
100 public void verify() {
101 if (predicate != null) {
102 if (!predicate.test(null)) throw new IgnoredException();
103 }
104 }
105
106 @Override
107 public Statement apply(Statement base, Description description) {
108 return new ConditionalStatement(this, base, description);
109 }
110
111 public String getReason() {
112 return reason;
113 }
114
115 private static class ConditionalStatement extends Statement {
116 private final Statement statement;
117 private final Description description;
118 private final ConditionalRule conditionalRule;
119
120 public ConditionalStatement(ConditionalRule conditionalRule, Statement statement, Description description) {
121 this.statement = statement;
122 this.conditionalRule = conditionalRule;
123 this.description = description;
124 }
125
126 @Override
127 public void evaluate() throws Throwable {
128 try {
129 conditionalRule.verify();
130 statement.evaluate();
131 } catch (Throwable e) {
132 if (isIgnoredException(e)) {
133 LOG.warn("Did not execute test {}: {} ", description, conditionalRule.getReason());
134 return;
135 }
136 throw e;
137 }
138 }
139 }
140
141 private static boolean isIgnoredException(Throwable throwable) {
142 Throwable t = throwable;
143 List<Throwable> list = new ArrayList<>();
144 while (t != null && !list.contains(t)) {
145 if (t instanceof IgnoredException) return true;
146 list.add(throwable);
147 t = t.getCause();
148 }
149 return false;
150 }
151
152 private static class IgnoredException extends RuntimeException {
153
154 public IgnoredException() {
155 super();
156 }
157 }
158
159 }