1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.cloud.contract.maven.verifier;
18
19 import java.io.File;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.apache.maven.execution.MavenSession;
25 import org.apache.maven.model.Dependency;
26 import org.apache.maven.model.Resource;
27 import org.apache.maven.plugin.AbstractMojo;
28 import org.apache.maven.plugin.MojoExecution;
29 import org.apache.maven.plugin.MojoExecutionException;
30 import org.apache.maven.plugin.MojoFailureException;
31 import org.apache.maven.plugins.annotations.LifecyclePhase;
32 import org.apache.maven.plugins.annotations.Mojo;
33 import org.apache.maven.plugins.annotations.Parameter;
34 import org.apache.maven.plugins.annotations.ResolutionScope;
35 import org.apache.maven.project.MavenProject;
36 import org.eclipse.aether.RepositorySystemSession;
37
38 import org.springframework.cloud.contract.spec.ContractVerifierException;
39 import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties;
40 import org.springframework.cloud.contract.verifier.TestGenerator;
41 import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties;
42 import org.springframework.cloud.contract.verifier.config.TestFramework;
43 import org.springframework.cloud.contract.verifier.config.TestMode;
44
45
46
47
48
49
50
51 @Mojo(name = "generateTests", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES,
52 requiresDependencyResolution = ResolutionScope.TEST)
53 public class GenerateTestsMojo extends AbstractMojo {
54
55 @Parameter(defaultValue = "${repositorySystemSession}", readonly = true)
56 private RepositorySystemSession repoSession;
57
58 @Parameter(property = "spring.cloud.contract.verifier.contractsDirectory",
59 defaultValue = "${project.basedir}/src/test/resources/contracts")
60 private File contractsDirectory;
61
62 @Parameter(defaultValue = "${project.build.directory}/generated-test-sources/contracts")
63 private File generatedTestSourcesDir;
64
65 @Parameter(defaultValue = "${project.build.directory}/generated-test-resources/contracts")
66 private File generatedTestResourcesDir;
67
68 @Parameter
69 private String basePackageForTests;
70
71 @Parameter
72 private String baseClassForTests;
73
74 @Parameter(defaultValue = "MOCKMVC")
75 private TestMode testMode;
76
77 @Parameter(defaultValue = "JUNIT5")
78 private TestFramework testFramework;
79
80 @Parameter
81 private String ruleClassForTests;
82
83 @Parameter
84 private String nameSuffixForTests;
85
86
87
88
89 @Parameter
90 private String[] imports;
91
92
93
94
95 @Parameter
96 private String[] staticImports;
97
98
99
100
101 @Parameter
102 private List<String> excludedFiles;
103
104
105
106
107 @Parameter(property = "includedFiles")
108 private List<String> includedFiles;
109
110
111
112
113
114 @Parameter(property = "spring.cloud.contract.verifier.assert.size", defaultValue = "false")
115 private boolean assertJsonSize;
116
117
118
119
120 @Parameter
121 private List<String> ignoredFiles;
122
123 @Parameter(defaultValue = "${project}", readonly = true)
124 private MavenProject project;
125
126 @Parameter(property = "spring.cloud.contract.verifier.skip", defaultValue = "false")
127 private boolean skip;
128
129 @Parameter(property = "maven.test.skip", defaultValue = "false")
130 private boolean mavenTestSkip;
131
132 @Parameter(property = "skipTests", defaultValue = "false")
133 private boolean skipTests;
134
135
136
137
138
139
140 @Parameter(property = "contractsRepositoryUrl")
141 private String contractsRepositoryUrl;
142
143 @Parameter(property = "contractDependency")
144 private Dependency contractDependency;
145
146
147
148
149
150
151
152 @Parameter(property = "contractsPath")
153 private String contractsPath;
154
155
156
157
158 @Parameter(property = "contractsMode", defaultValue = "CLASSPATH")
159 private StubRunnerProperties.StubsMode contractsMode;
160
161
162
163
164
165
166
167
168
169
170 @Parameter(property = "packageWithBaseClasses")
171 private String packageWithBaseClasses;
172
173
174
175
176
177
178
179
180
181 @Parameter(property = "baseClassMappings")
182 private List<BaseClassMapping> baseClassMappings;
183
184
185
186
187 @Parameter(property = "contractsRepositoryUsername")
188 private String contractsRepositoryUsername;
189
190
191
192
193 @Parameter(property = "contractsRepositoryPassword")
194 private String contractsRepositoryPassword;
195
196
197
198
199 @Parameter(property = "contractsRepositoryProxyHost")
200 private String contractsRepositoryProxyHost;
201
202
203
204
205 @Parameter(property = "contractsRepositoryProxyPort")
206 private Integer contractsRepositoryProxyPort;
207
208
209
210
211
212 @Parameter(property = "deleteStubsAfterTest", defaultValue = "true")
213 private boolean deleteStubsAfterTest;
214
215
216
217
218
219 @Parameter(property = "contractsProperties")
220 private Map<String, String> contractsProperties = new HashMap<>();
221
222
223
224
225
226 @Parameter(property = "failOnNoContracts", defaultValue = "true")
227 private boolean failOnNoContracts;
228
229
230
231
232
233
234
235 @Parameter(property = "failOnInProgress", defaultValue = "true")
236 private boolean failOnInProgress = true;
237
238
239
240
241
242 @Parameter(property = "incrementalContractTests", defaultValue = "true")
243 private boolean incrementalContractTests = true;
244
245 @Parameter(defaultValue = "${mojoExecution}", readonly = true, required = true)
246 private MojoExecution mojoExecution;
247
248 @Parameter(defaultValue = "${session}", readonly = true, required = true)
249 private MavenSession session;
250
251 @Override
252 public void execute() throws MojoExecutionException, MojoFailureException {
253 if (this.skip || this.mavenTestSkip || this.skipTests) {
254 if (this.skip) {
255 getLog().info("Skipping Spring Cloud Contract Verifier execution: spring.cloud.contract.verifier.skip="
256 + this.skip);
257 }
258 if (this.mavenTestSkip) {
259 getLog().info(
260 "Skipping Spring Cloud Contract Verifier execution: maven.test.skip=" + this.mavenTestSkip);
261 }
262 if (this.skipTests) {
263 getLog().info("Skipping Spring Cloud Contract Verifier execution: skipTests" + this.skipTests);
264 }
265 return;
266 }
267 getLog().info("Generating server tests source code for Spring Cloud Contract Verifier contract verification");
268 final ContractVerifierConfigProperties config = new ContractVerifierConfigProperties();
269 config.setFailOnInProgress(this.failOnInProgress);
270
271 File contractsDirectory = new MavenContractsDownloader(this.project, this.contractDependency,
272 this.contractsPath, this.contractsRepositoryUrl, this.contractsMode, getLog(),
273 this.contractsRepositoryUsername, this.contractsRepositoryPassword, this.contractsRepositoryProxyHost,
274 this.contractsRepositoryProxyPort, this.deleteStubsAfterTest, this.contractsProperties,
275 this.failOnNoContracts).downloadAndUnpackContractsIfRequired(config, this.contractsDirectory);
276 getLog().info("Directory with contract is present at [" + contractsDirectory + "]");
277
278 if (this.incrementalContractTests
279 && !ChangeDetector.inputFilesChangeDetected(contractsDirectory, mojoExecution, session)) {
280 getLog().info("Nothing to generate - all classes are up to date");
281 return;
282 }
283
284 setupConfig(config, contractsDirectory);
285 this.project.addTestCompileSourceRoot(this.generatedTestSourcesDir.getAbsolutePath());
286 Resource resource = new Resource();
287 resource.setDirectory(this.generatedTestResourcesDir.getAbsolutePath());
288 this.project.addTestResource(resource);
289 if (getLog().isInfoEnabled()) {
290 getLog().info("Test Source directory: " + this.generatedTestSourcesDir.getAbsolutePath() + " added.");
291 getLog().info("Using [" + config.getBaseClassForTests() + "] as base class for test classes, ["
292 + config.getBasePackageForTests() + "] as base " + "package for tests, ["
293 + config.getPackageWithBaseClasses() + "] as package with " + "base classes, base class mappings "
294 + this.baseClassMappings);
295 }
296 try {
297 LeftOverPrevention leftOverPrevention = new LeftOverPrevention(this.generatedTestSourcesDir, mojoExecution,
298 session);
299 TestGenerator generator = new TestGenerator(config);
300 int generatedClasses = generator.generate();
301 getLog().info("Generated " + generatedClasses + " test classes.");
302 leftOverPrevention.deleteLeftOvers();
303 }
304 catch (ContractVerifierException e) {
305 throw new MojoExecutionException(
306 String.format("Spring Cloud Contract Verifier Plugin exception: %s", e.getMessage()), e);
307 }
308 }
309
310 private void setupConfig(ContractVerifierConfigProperties config, File contractsDirectory) {
311 config.setContractsDslDir(contractsDirectory);
312 config.setGeneratedTestSourcesDir(this.generatedTestSourcesDir);
313 config.setGeneratedTestResourcesDir(this.generatedTestResourcesDir);
314 config.setTestFramework(this.testFramework);
315 config.setTestMode(this.testMode);
316 config.setBasePackageForTests(this.basePackageForTests);
317 config.setBaseClassForTests(this.baseClassForTests);
318 config.setRuleClassForTests(this.ruleClassForTests);
319 config.setNameSuffixForTests(this.nameSuffixForTests);
320 config.setImports(this.imports);
321 config.setStaticImports(this.staticImports);
322 config.setIgnoredFiles(this.ignoredFiles);
323 config.setExcludedFiles(this.excludedFiles);
324 config.setIncludedFiles(this.includedFiles);
325 config.setAssertJsonSize(this.assertJsonSize);
326 config.setPackageWithBaseClasses(this.packageWithBaseClasses);
327 if (this.baseClassMappings != null) {
328 config.setBaseClassMappings(mappingsToMap());
329 }
330 }
331
332 public Map<String, String> mappingsToMap() {
333 Map<String, String> map = new HashMap<>();
334 if (this.baseClassMappings == null) {
335 return map;
336 }
337 for (BaseClassMapping mapping : this.baseClassMappings) {
338 map.put(mapping.getContractPackageRegex(), mapping.getBaseClassFQN());
339 }
340 return map;
341 }
342
343 public List<String> getExcludedFiles() {
344 return this.excludedFiles;
345 }
346
347 public void setExcludedFiles(List<String> excludedFiles) {
348 this.excludedFiles = excludedFiles;
349 }
350
351 public List<String> getIgnoredFiles() {
352 return this.ignoredFiles;
353 }
354
355 public void setIgnoredFiles(List<String> ignoredFiles) {
356 this.ignoredFiles = ignoredFiles;
357 }
358
359 public boolean isAssertJsonSize() {
360 return this.assertJsonSize;
361 }
362
363 public void setAssertJsonSize(boolean assertJsonSize) {
364 this.assertJsonSize = assertJsonSize;
365 }
366
367 }