• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.turbine.options;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static com.google.common.truth.Truth8.assertThat;
21 import static org.junit.Assert.assertThrows;
22 import static org.junit.Assert.fail;
23 
24 import com.google.common.collect.ImmutableList;
25 import com.google.common.collect.Iterables;
26 import com.google.turbine.options.TurbineOptions.ReducedClasspathMode;
27 import java.nio.charset.StandardCharsets;
28 import java.nio.file.Files;
29 import java.nio.file.Path;
30 import java.util.Arrays;
31 import org.junit.Rule;
32 import org.junit.Test;
33 import org.junit.rules.TemporaryFolder;
34 import org.junit.runner.RunWith;
35 import org.junit.runners.JUnit4;
36 
37 @RunWith(JUnit4.class)
38 public class TurbineOptionsTest {
39 
40   @Rule public final TemporaryFolder tmpFolder = new TemporaryFolder();
41 
42   static final ImmutableList<String> BASE_ARGS =
43       ImmutableList.of("--output", "out.jar", "--target_label", "//java/com/google/test");
44 
45   @Test
exhaustiveArgs()46   public void exhaustiveArgs() throws Exception {
47     String[] lines = {
48       "--output",
49       "out.jar",
50       "--source_jars",
51       "sources1.srcjar",
52       "sources2.srcjar",
53       "--processors",
54       "com.foo.MyProcessor",
55       "com.foo.OtherProcessor",
56       "--processorpath",
57       "libproc1.jar",
58       "libproc2.jar",
59       "--classpath",
60       "lib1.jar",
61       "lib2.jar",
62       "--bootclasspath",
63       "rt.jar",
64       "zipfs.jar",
65       "--javacopts",
66       "-source",
67       "8",
68       "-target",
69       "8",
70       "--",
71       "--sources",
72       "Source1.java",
73       "Source2.java",
74       "--output_deps",
75       "out.jdeps",
76       "--target_label",
77       "//java/com/google/test",
78       "--injecting_rule_kind",
79       "foo_library",
80     };
81 
82     TurbineOptions options =
83         TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines)));
84 
85     assertThat(options.output()).hasValue("out.jar");
86     assertThat(options.sourceJars())
87         .containsExactly("sources1.srcjar", "sources2.srcjar")
88         .inOrder();
89     assertThat(options.processors())
90         .containsExactly("com.foo.MyProcessor", "com.foo.OtherProcessor")
91         .inOrder();
92     assertThat(options.processorPath()).containsExactly("libproc1.jar", "libproc2.jar").inOrder();
93     assertThat(options.classPath()).containsExactly("lib1.jar", "lib2.jar").inOrder();
94     assertThat(options.bootClassPath()).containsExactly("rt.jar", "zipfs.jar").inOrder();
95     assertThat(options.javacOpts()).containsExactly("-source", "8", "-target", "8").inOrder();
96     assertThat(options.sources()).containsExactly("Source1.java", "Source2.java");
97     assertThat(options.outputDeps()).hasValue("out.jdeps");
98     assertThat(options.targetLabel()).hasValue("//java/com/google/test");
99     assertThat(options.injectingRuleKind()).hasValue("foo_library");
100     assertThat(options.reducedClasspathMode()).isEqualTo(ReducedClasspathMode.NONE);
101   }
102 
103   @Test
strictJavaDepsArgs()104   public void strictJavaDepsArgs() throws Exception {
105     String[] lines = {
106       "--classpath",
107       "blaze-out/foo/libbar.jar",
108       "blaze-out/foo/libbaz1.jar",
109       "blaze-out/foo/libbaz2.jar",
110       "blaze-out/proto/libproto.jar",
111       "--direct_dependencies",
112       "blaze-out/foo/libbar.jar",
113       "--deps_artifacts",
114       "foo.jdeps",
115       "bar.jdeps",
116       "",
117     };
118 
119     TurbineOptions options =
120         TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines)));
121 
122     assertThat(options.targetLabel()).hasValue("//java/com/google/test");
123     assertThat(options.directJars()).containsExactly("blaze-out/foo/libbar.jar");
124     assertThat(options.depsArtifacts()).containsExactly("foo.jdeps", "bar.jdeps");
125   }
126 
127   @Test
classpathArgs()128   public void classpathArgs() throws Exception {
129     String[] lines = {
130       "--classpath",
131       "liba.jar",
132       "libb.jar",
133       "libc.jar",
134       "--processorpath",
135       "libpa.jar",
136       "libpb.jar",
137       "libpc.jar",
138     };
139 
140     TurbineOptions options =
141         TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines)));
142 
143     assertThat(options.classPath()).containsExactly("liba.jar", "libb.jar", "libc.jar").inOrder();
144     assertThat(options.processorPath())
145         .containsExactly("libpa.jar", "libpb.jar", "libpc.jar")
146         .inOrder();
147   }
148 
149   @Test
repeatedClasspath()150   public void repeatedClasspath() throws Exception {
151     String[] lines = {
152       "--classpath",
153       "liba.jar",
154       "libb.jar",
155       "libc.jar",
156       "--processorpath",
157       "libpa.jar",
158       "libpb.jar",
159       "libpc.jar",
160     };
161 
162     TurbineOptions options =
163         TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines)));
164 
165     assertThat(options.classPath()).containsExactly("liba.jar", "libb.jar", "libc.jar").inOrder();
166     assertThat(options.processorPath())
167         .containsExactly("libpa.jar", "libpb.jar", "libpc.jar")
168         .inOrder();
169   }
170 
171   @Test
optionalTargetLabel()172   public void optionalTargetLabel() throws Exception {
173     String[] lines = {
174       "--output",
175       "out.jar",
176       "--classpath",
177       "liba.jar",
178       "libb.jar",
179       "libc.jar",
180       "--processorpath",
181       "libpa.jar",
182       "libpb.jar",
183       "libpc.jar",
184     };
185 
186     TurbineOptions options = TurbineOptionsParser.parse(Arrays.asList(lines));
187 
188     assertThat(options.targetLabel()).isEmpty();
189     assertThat(options.injectingRuleKind()).isEmpty();
190   }
191 
192   @Test
paramsFile()193   public void paramsFile() throws Exception {
194     Iterable<String> paramsArgs =
195         Iterables.concat(
196             BASE_ARGS, Arrays.asList("--javacopts", "-source", "8", "-target", "8", "--"));
197     Path params = tmpFolder.newFile("params.txt").toPath();
198     Files.write(params, paramsArgs, StandardCharsets.UTF_8);
199 
200     // @ is a prefix for external repository targets, and the prefix for params files. Targets
201     // are disambiguated by prepending an extra @.
202     String[] lines = {
203       "@" + params.toAbsolutePath(), "--target_label", "//custom/label",
204     };
205 
206     TurbineOptions options = TurbineOptionsParser.parse(Arrays.asList(lines));
207 
208     // assert that options were read from params file
209     assertThat(options.javacOpts()).containsExactly("-source", "8", "-target", "8").inOrder();
210     // ... and directly from the command line
211     assertThat(options.targetLabel()).hasValue("//custom/label");
212   }
213 
214   @Test
escapedExternalRepositoryLabel()215   public void escapedExternalRepositoryLabel() throws Exception {
216     // @ is a prefix for external repository targets, and the prefix for params files. Targets
217     // are disambiguated by prepending an extra @.
218     String[] lines = {
219       "--target_label", "@@other-repo//foo:local-jam",
220     };
221 
222     TurbineOptions options =
223         TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines)));
224 
225     assertThat(options.targetLabel()).hasValue("@other-repo//foo:local-jam");
226   }
227 
228   @Test
tolerateMissingOutput()229   public void tolerateMissingOutput() throws Exception {
230     TurbineOptions options = TurbineOptions.builder().build();
231     assertThat(options.output()).isEmpty();
232   }
233 
234   @Test
paramsFileExists()235   public void paramsFileExists() throws Exception {
236     String[] lines = {
237       "@/NOSUCH", "--javacopts", "-source", "7", "--",
238     };
239     AssertionError expected = null;
240     try {
241       TurbineOptionsParser.parse(Arrays.asList(lines));
242     } catch (AssertionError e) {
243       expected = e;
244     }
245     if (expected == null) {
246       fail();
247     }
248     assertThat(expected).hasMessageThat().contains("params file does not exist");
249   }
250 
251   @Test
emptyParamsFiles()252   public void emptyParamsFiles() throws Exception {
253     Path params = tmpFolder.newFile("params.txt").toPath();
254     Files.write(params, new byte[0]);
255     String[] lines = {
256       "--sources", "A.java", "@" + params.toAbsolutePath(), "B.java",
257     };
258     TurbineOptions options =
259         TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines)));
260     assertThat(options.sources()).containsExactly("A.java", "B.java").inOrder();
261   }
262 
263   @Test
javacopts()264   public void javacopts() throws Exception {
265     String[] lines = {
266       "--javacopts",
267       "--release",
268       "8",
269       "--",
270       "--sources",
271       "Test.java",
272       "--javacopts",
273       "--release",
274       "9",
275       "--",
276     };
277 
278     TurbineOptions options =
279         TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines)));
280 
281     assertThat(options.javacOpts()).containsExactly("--release", "8", "--release", "9").inOrder();
282     assertThat(options.sources()).containsExactly("Test.java");
283   }
284 
285   @Test
unknownOption()286   public void unknownOption() throws Exception {
287     IllegalArgumentException e =
288         assertThrows(
289             IllegalArgumentException.class,
290             () ->
291                 TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList("--nosuch"))));
292     assertThat(e).hasMessageThat().contains("unknown option");
293   }
294 
295   @Test
unterminatedJavacopts()296   public void unterminatedJavacopts() throws Exception {
297     IllegalArgumentException e =
298         assertThrows(
299             IllegalArgumentException.class,
300             () ->
301                 TurbineOptionsParser.parse(
302                     Iterables.concat(BASE_ARGS, Arrays.asList("--javacopts", "--release", "8"))));
303     assertThat(e).hasMessageThat().contains("javacopts should be terminated by `--`");
304   }
305 
306   @Test
miscOutputs()307   public void miscOutputs() throws Exception {
308     TurbineOptions options =
309         TurbineOptionsParser.parse(
310             Iterables.concat(
311                 BASE_ARGS,
312                 ImmutableList.of("--gensrc_output", "gensrc.jar", "--profile", "turbine.prof")));
313     assertThat(options.gensrcOutput()).hasValue("gensrc.jar");
314     assertThat(options.profile()).hasValue("turbine.prof");
315   }
316 
317   @Test
unescape()318   public void unescape() throws Exception {
319     String[] lines = {
320       "--sources", "Test.java", "'Foo$Bar.java'",
321     };
322     TurbineOptions options =
323         TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines)));
324     assertThat(options.sources()).containsExactly("Test.java", "Foo$Bar.java").inOrder();
325   }
326 
327   @Test
invalidUnescape()328   public void invalidUnescape() throws Exception {
329     String[] lines = {"--sources", "'Foo$Bar.java"};
330     assertThrows(
331         IllegalArgumentException.class,
332         () -> TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines))));
333   }
334 
335   @Test
builtinProcessors()336   public void builtinProcessors() throws Exception {
337     String[] lines = {"--builtin_processors", "BuiltinProcessor"};
338     TurbineOptions options =
339         TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines)));
340     assertThat(options.builtinProcessors()).containsExactly("BuiltinProcessor");
341   }
342 
343   @Test
reducedClasspathMode()344   public void reducedClasspathMode() throws Exception {
345     for (ReducedClasspathMode mode : ReducedClasspathMode.values()) {
346       TurbineOptions options =
347           TurbineOptionsParser.parse(
348               Iterables.concat(
349                   BASE_ARGS, ImmutableList.of("--reduce_classpath_mode", mode.name())));
350       assertThat(options.reducedClasspathMode()).isEqualTo(mode);
351     }
352   }
353 
354   @Test
javaBuilderCompatibility()355   public void javaBuilderCompatibility() throws Exception {
356     TurbineOptions options =
357         TurbineOptionsParser.parse(
358             Iterables.concat(
359                 BASE_ARGS,
360                 ImmutableList.of(
361                     "--output_deps_proto",
362                     "output_deps.proto",
363                     "--generated_sources_output",
364                     "generated_sources.jar",
365                     "--experimental_fix_deps_tool",
366                     "ignored",
367                     "--strict_java_deps",
368                     "ignored",
369                     "--native_header_output",
370                     "ignored",
371                     "--compress_jar")));
372     assertThat(options.outputDeps()).hasValue("output_deps.proto");
373     assertThat(options.gensrcOutput()).hasValue("generated_sources.jar");
374   }
375 
376   @Test
requiredValue()377   public void requiredValue() throws Exception {
378     IllegalArgumentException e =
379         assertThrows(
380             IllegalArgumentException.class,
381             () ->
382                 TurbineOptionsParser.parse(
383                     Iterables.concat(BASE_ARGS, ImmutableList.of("--output", "--system"))));
384     assertThat(e).hasMessageThat().contains("missing required argument for: --output");
385   }
386 }
387