1
2
3
4
5 package com.qulice.maven;
6
7 import com.qulice.spi.Environment;
8 import com.qulice.spi.ResourceValidator;
9 import com.qulice.spi.Validator;
10 import com.qulice.spi.Violation;
11 import java.io.File;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.concurrent.CountDownLatch;
15 import java.util.concurrent.TimeoutException;
16 import java.util.concurrent.atomic.AtomicInteger;
17 import org.apache.maven.monitor.logging.DefaultLog;
18 import org.apache.maven.plugin.MojoFailureException;
19 import org.apache.maven.plugin.logging.Log;
20 import org.apache.maven.project.MavenProject;
21 import org.codehaus.plexus.context.Context;
22 import org.codehaus.plexus.context.DefaultContext;
23 import org.codehaus.plexus.logging.AbstractLogger;
24 import org.codehaus.plexus.logging.Logger;
25 import org.junit.jupiter.api.Assertions;
26 import org.junit.jupiter.api.Test;
27
28
29
30
31
32 final class CheckMojoTest {
33
34
35
36
37
38 @Test
39 void skipsExecutionOnSkipFlag() throws Exception {
40 final CheckMojo mojo = new CheckMojo();
41 final Logger logger = new FakeLogger();
42 final Log log = new DefaultLog(logger);
43 mojo.setLog(log);
44 mojo.setSkip(true);
45 mojo.execute();
46 Assertions.assertEquals("[INFO] Execution skipped", logger.toString());
47 }
48
49
50
51
52 @Test
53 void setsTimeoutToForever() {
54 final CheckMojo mojo = new CheckMojo();
55 mojo.setTimeout("forever");
56 final var validator = new BlockedValidator();
57 final ValidatorsProvider provider = new ValidatorsProviderMocker()
58 .withExternalResource(validator)
59 .mock();
60 mojo.setValidatorsProvider(provider);
61 final MavenProject project = new MavenProject();
62 mojo.setProject(project);
63 mojo.setLog(new DefaultLog(new FakeLogger()));
64 new Thread(
65 () -> {
66 try {
67 mojo.execute();
68 } catch (final MojoFailureException exception) {
69 throw new IllegalStateException(exception);
70 }
71 }
72 ).start();
73 validator.await();
74 Assertions.assertEquals(
75 1,
76 validator.count(),
77 "Without the 'await' statement above, this test would run forever"
78 );
79 }
80
81
82
83
84 @Test
85 void setsTimeoutToOneSecond() {
86 final CheckMojo mojo = new CheckMojo();
87 mojo.setTimeout("1s");
88 final ValidatorsProvider provider = new ValidatorsProviderMocker()
89 .withExternalResource(new BlockedValidator())
90 .mock();
91 mojo.setValidatorsProvider(provider);
92 final MavenProject project = new MavenProject();
93 mojo.setProject(project);
94 mojo.setLog(new DefaultLog(new FakeLogger()));
95 Assertions.assertSame(
96 TimeoutException.class,
97 Assertions.assertThrows(
98 IllegalStateException.class,
99 mojo::execute,
100 "Should throw IllegalStateException because of timeout"
101 ).getCause().getClass(),
102 "The cause is expected to be timeout"
103 );
104 }
105
106
107
108
109
110 @Test
111 void validatesUsingAllProvidedValidators() throws Exception {
112 final CheckMojo mojo = new CheckMojo();
113 final FakeValidator external = new FakeValidator("somename");
114 final FakeResourceValidator rexternal = new FakeResourceValidator(
115 "other"
116 );
117 final FakeMavenValidator internal = new FakeMavenValidator();
118 final ValidatorsProvider provider = new ValidatorsProviderMocker()
119 .withInternal(internal)
120 .withExternal(external)
121 .withExternalResource(rexternal)
122 .mock();
123 mojo.setValidatorsProvider(provider);
124 final MavenProject project = new MavenProject();
125 mojo.setProject(project);
126 mojo.setLog(new DefaultLog(new FakeLogger()));
127 final Context context = new DefaultContext();
128 mojo.contextualize(context);
129 mojo.execute();
130 Assertions.assertEquals(1, internal.count());
131 Assertions.assertEquals(1, external.count());
132 Assertions.assertEquals(1, rexternal.count());
133 }
134
135
136
137
138
139
140
141 @SuppressWarnings("PMD.AvoidStringBufferField")
142 private static final class FakeLogger extends AbstractLogger {
143
144
145
146 private static final String[] TAGS = {
147 "[DEBUG] ",
148 "[INFO] ",
149 "[WARNING] ",
150 "[ERROR] ",
151 "[FATAL ERROR] ",
152 };
153
154
155
156
157 private final StringBuilder messages;
158
159 FakeLogger() {
160 this(1, "fakelogger");
161 }
162
163 FakeLogger(final int threshold, final String name) {
164 super(threshold, name);
165 this.messages = new StringBuilder();
166 }
167
168 @Override
169 public void debug(final String message, final Throwable throwable) {
170 if (this.isDebugEnabled()) {
171 this.messages.append(FakeLogger.TAGS[0].concat(message));
172 if (throwable != null) {
173 throwable.printStackTrace(System.out);
174 }
175 }
176 }
177
178 @Override
179 public void info(final String message, final Throwable throwable) {
180 if (this.isInfoEnabled()) {
181 this.messages.append(FakeLogger.TAGS[1].concat(message));
182 if (throwable != null) {
183 throwable.printStackTrace(System.out);
184 }
185 }
186 }
187
188 @Override
189 public void warn(final String message, final Throwable throwable) {
190 if (this.isWarnEnabled()) {
191 this.messages.append(FakeLogger.TAGS[2].concat(message));
192 if (throwable != null) {
193 throwable.printStackTrace(System.out);
194 }
195 }
196 }
197
198 @Override
199 public void error(final String message, final Throwable throwable) {
200 if (this.isErrorEnabled()) {
201 this.messages.append(FakeLogger.TAGS[3].concat(message));
202 if (throwable != null) {
203 throwable.printStackTrace(System.out);
204 }
205 }
206 }
207
208 @Override
209 public void fatalError(
210 final String message,
211 final Throwable throwable
212 ) {
213 if (this.isFatalErrorEnabled()) {
214 this.messages.append(FakeLogger.TAGS[4].concat(message));
215 if (throwable != null) {
216 throwable.printStackTrace(System.out);
217 }
218 }
219 }
220
221 @Override
222 public Logger getChildLogger(final String name) {
223 return this;
224 }
225
226 @Override
227 public String toString() {
228 return this.messages.toString();
229 }
230 }
231
232
233
234
235
236
237
238 private static final class FakeValidator implements Validator {
239
240
241
242 private final String label;
243
244
245
246
247 private final AtomicInteger cnt;
248
249 FakeValidator(final String name) {
250 this.label = name;
251 this.cnt = new AtomicInteger(0);
252 }
253
254 @Override
255 public void validate(final Environment env) {
256 this.cnt.incrementAndGet();
257 }
258
259 @Override
260 public String name() {
261 return this.label;
262 }
263
264 public int count() {
265 return this.cnt.get();
266 }
267 }
268
269
270
271
272
273
274
275 private static final class BlockedValidator implements ResourceValidator {
276
277
278
279
280 private final AtomicInteger cnt;
281
282
283
284
285 private final CountDownLatch latch;
286
287 BlockedValidator() {
288 this.cnt = new AtomicInteger(0);
289 this.latch = new CountDownLatch(1);
290 }
291
292 @Override
293 public Collection<Violation> validate(final Collection<File> ignore) {
294 this.cnt.incrementAndGet();
295 this.latch.countDown();
296 try {
297 Thread.sleep(Long.MAX_VALUE);
298 } catch (final InterruptedException ex) {
299 Thread.currentThread().interrupt();
300 }
301 return Collections.emptyList();
302 }
303
304 @Override
305 public String name() {
306 return "blocked forever";
307 }
308
309 public int count() {
310 return this.cnt.get();
311 }
312
313 public void await() {
314 try {
315 this.latch.await();
316 } catch (final InterruptedException ex) {
317 Thread.currentThread().interrupt();
318 }
319 }
320 }
321
322
323
324
325
326
327
328 private static final class FakeResourceValidator
329 implements ResourceValidator {
330
331
332
333 private final String label;
334
335
336
337
338 private final AtomicInteger cnt;
339
340 FakeResourceValidator(final String name) {
341 this.label = name;
342 this.cnt = new AtomicInteger(0);
343 }
344
345 @Override
346 public Collection<Violation> validate(final Collection<File> files) {
347 this.cnt.incrementAndGet();
348 return Collections.emptyList();
349 }
350
351 @Override
352 public String name() {
353 return this.label;
354 }
355
356 public int count() {
357 return this.cnt.get();
358 }
359 }
360
361
362
363
364
365
366
367
368 private static final class FakeMavenValidator implements MavenValidator {
369
370
371
372 private final AtomicInteger cnt;
373
374 FakeMavenValidator() {
375 this.cnt = new AtomicInteger(0);
376 }
377
378 @Override
379 public void validate(final MavenEnvironment env) {
380 this.cnt.incrementAndGet();
381 }
382
383 public int count() {
384 return this.cnt.get();
385 }
386 }
387 }