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
133
134
135
136
137 @Parameter(property = "contractsRepositoryUrl")
138 private String contractsRepositoryUrl;
139
140 @Parameter(property = "contractDependency")
141 private Dependency contractDependency;
142
143
144
145
146
147
148
149 @Parameter(property = "contractsPath")
150 private String contractsPath;
151
152
153
154
155 @Parameter(property = "contractsMode", defaultValue = "CLASSPATH")
156 private StubRunnerProperties.StubsMode contractsMode;
157
158
159
160
161
162
163
164
165
166
167 @Parameter(property = "packageWithBaseClasses")
168 private String packageWithBaseClasses;
169
170
171
172
173
174
175
176
177
178 @Parameter(property = "baseClassMappings")
179 private List<BaseClassMapping> baseClassMappings;
180
181
182
183
184 @Parameter(property = "contractsRepositoryUsername")
185 private String contractsRepositoryUsername;
186
187
188
189
190 @Parameter(property = "contractsRepositoryPassword")
191 private String contractsRepositoryPassword;
192
193
194
195
196 @Parameter(property = "contractsRepositoryProxyHost")
197 private String contractsRepositoryProxyHost;
198
199
200
201
202 @Parameter(property = "contractsRepositoryProxyPort")
203 private Integer contractsRepositoryProxyPort;
204
205
206
207
208
209 @Parameter(property = "deleteStubsAfterTest", defaultValue = "true")
210 private boolean deleteStubsAfterTest;
211
212
213
214
215
216 @Parameter(property = "contractsProperties")
217 private Map<String, String> contractsProperties = new HashMap<>();
218
219
220
221
222
223 @Parameter(property = "failOnNoContracts", defaultValue = "true")
224 private boolean failOnNoContracts;
225
226
227
228
229
230
231
232 @Parameter(property = "failOnInProgress", defaultValue = "true")
233 private boolean failOnInProgress = true;
234
235
236
237
238
239 @Parameter(property = "incrementalContractTests", defaultValue = "true")
240 private boolean incrementalContractTests = true;
241
242 @Parameter(defaultValue = "${mojoExecution}", readonly = true, required = true)
243 private MojoExecution mojoExecution;
244
245 @Parameter(defaultValue = "${session}", readonly = true, required = true)
246 private MavenSession session;
247
248 @Override
249 public void execute() throws MojoExecutionException, MojoFailureException {
250 if (this.skip || this.mavenTestSkip) {
251 if (this.skip) {
252 getLog().info("Skipping Spring Cloud Contract Verifier execution: spring.cloud.contract.verifier.skip="
253 + this.skip);
254 }
255 if (this.mavenTestSkip) {
256 getLog().info(
257 "Skipping Spring Cloud Contract Verifier execution: maven.test.skip=" + this.mavenTestSkip);
258 }
259 return;
260 }
261 getLog().info("Generating server tests source code for Spring Cloud Contract Verifier contract verification");
262 final ContractVerifierConfigProperties config = new ContractVerifierConfigProperties();
263 config.setFailOnInProgress(this.failOnInProgress);
264
265 File contractsDirectory = new MavenContractsDownloader(this.project, this.contractDependency,
266 this.contractsPath, this.contractsRepositoryUrl, this.contractsMode, getLog(),
267 this.contractsRepositoryUsername, this.contractsRepositoryPassword, this.contractsRepositoryProxyHost,
268 this.contractsRepositoryProxyPort, this.deleteStubsAfterTest, this.contractsProperties,
269 this.failOnNoContracts).downloadAndUnpackContractsIfRequired(config, this.contractsDirectory);
270 getLog().info("Directory with contract is present at [" + contractsDirectory + "]");
271
272 if (this.incrementalContractTests
273 && !ChangeDetector.inputFilesChangeDetected(contractsDirectory, mojoExecution, session)) {
274 getLog().info("Nothing to generate - all classes are up to date");
275 return;
276 }
277
278 setupConfig(config, contractsDirectory);
279 this.project.addTestCompileSourceRoot(this.generatedTestSourcesDir.getAbsolutePath());
280 Resource resource = new Resource();
281 resource.setDirectory(this.generatedTestResourcesDir.getAbsolutePath());
282 this.project.addTestResource(resource);
283 if (getLog().isInfoEnabled()) {
284 getLog().info("Test Source directory: " + this.generatedTestSourcesDir.getAbsolutePath() + " added.");
285 getLog().info("Using [" + config.getBaseClassForTests() + "] as base class for test classes, ["
286 + config.getBasePackageForTests() + "] as base " + "package for tests, ["
287 + config.getPackageWithBaseClasses() + "] as package with " + "base classes, base class mappings "
288 + this.baseClassMappings);
289 }
290 try {
291 LeftOverPrevention leftOverPrevention = new LeftOverPrevention(this.generatedTestSourcesDir, mojoExecution,
292 session);
293 TestGenerator generator = new TestGenerator(config);
294 int generatedClasses = generator.generate();
295 getLog().info("Generated " + generatedClasses + " test classes.");
296 leftOverPrevention.deleteLeftOvers();
297 }
298 catch (ContractVerifierException e) {
299 throw new MojoExecutionException(
300 String.format("Spring Cloud Contract Verifier Plugin exception: %s", e.getMessage()), e);
301 }
302 }
303
304 private void setupConfig(ContractVerifierConfigProperties config, File contractsDirectory) {
305 config.setContractsDslDir(contractsDirectory);
306 config.setGeneratedTestSourcesDir(this.generatedTestSourcesDir);
307 config.setGeneratedTestResourcesDir(this.generatedTestResourcesDir);
308 config.setTestFramework(this.testFramework);
309 config.setTestMode(this.testMode);
310 config.setBasePackageForTests(this.basePackageForTests);
311 config.setBaseClassForTests(this.baseClassForTests);
312 config.setRuleClassForTests(this.ruleClassForTests);
313 config.setNameSuffixForTests(this.nameSuffixForTests);
314 config.setImports(this.imports);
315 config.setStaticImports(this.staticImports);
316 config.setIgnoredFiles(this.ignoredFiles);
317 config.setExcludedFiles(this.excludedFiles);
318 config.setIncludedFiles(this.includedFiles);
319 config.setAssertJsonSize(this.assertJsonSize);
320 config.setPackageWithBaseClasses(this.packageWithBaseClasses);
321 if (this.baseClassMappings != null) {
322 config.setBaseClassMappings(mappingsToMap());
323 }
324 }
325
326 public Map<String, String> mappingsToMap() {
327 Map<String, String> map = new HashMap<>();
328 if (this.baseClassMappings == null) {
329 return map;
330 }
331 for (BaseClassMapping mapping : this.baseClassMappings) {
332 map.put(mapping.getContractPackageRegex(), mapping.getBaseClassFQN());
333 }
334 return map;
335 }
336
337 public List<String> getExcludedFiles() {
338 return this.excludedFiles;
339 }
340
341 public void setExcludedFiles(List<String> excludedFiles) {
342 this.excludedFiles = excludedFiles;
343 }
344
345 public List<String> getIgnoredFiles() {
346 return this.ignoredFiles;
347 }
348
349 public void setIgnoredFiles(List<String> ignoredFiles) {
350 this.ignoredFiles = ignoredFiles;
351 }
352
353 public boolean isAssertJsonSize() {
354 return this.assertJsonSize;
355 }
356
357 public void setAssertJsonSize(boolean assertJsonSize) {
358 this.assertJsonSize = assertJsonSize;
359 }
360
361 }