blob: 377861ba53b0591bcc96e2c0054bc1d5e65f4091 [file] [log] [blame]
Christopher Wiley3616d132015-09-01 11:07:48 -07001/*
2 * Copyright (C) 2015, The Android Open Source Project
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
Jiyong Park74595c12018-07-23 15:22:50 +090017#include "options.h"
18
Christopher Wileyd93c5b72015-09-14 13:21:37 -070019#include <iostream>
Jiyong Park74595c12018-07-23 15:22:50 +090020#include <memory>
Christopher Wiley3616d132015-09-01 11:07:48 -070021#include <string>
22#include <vector>
23
Jooyung Hanc522ac82020-10-23 14:24:12 +090024#include <gmock/gmock.h>
Christopher Wiley3616d132015-09-01 11:07:48 -070025#include <gtest/gtest.h>
26
Christopher Wileyd93c5b72015-09-14 13:21:37 -070027using std::cerr;
28using std::endl;
Christopher Wiley3616d132015-09-01 11:07:48 -070029using std::string;
Christopher Wiley4427d862015-09-14 11:07:39 -070030using std::unique_ptr;
31using std::vector;
Jooyung Hanc522ac82020-10-23 14:24:12 +090032using testing::internal::CaptureStderr;
33using testing::internal::GetCapturedStderr;
Christopher Wiley4427d862015-09-14 11:07:39 -070034
35namespace android {
36namespace aidl {
37namespace {
Christopher Wiley3616d132015-09-01 11:07:48 -070038
39const char kPreprocessCommandOutputFile[] = "output_file_name";
Jiyong Park74595c12018-07-23 15:22:50 +090040const char kPreprocessCommandInput1[] = "input1.aidl";
41const char kPreprocessCommandInput2[] = "input2.aidl";
42const char kPreprocessCommandInput3[] = "input3.aidl";
Christopher Wiley3616d132015-09-01 11:07:48 -070043const char* kPreprocessCommand[] = {
44 "aidl", "--preprocess",
45 kPreprocessCommandOutputFile,
46 kPreprocessCommandInput1,
47 kPreprocessCommandInput2,
48 kPreprocessCommandInput3,
Christopher Wileyd93c5b72015-09-14 13:21:37 -070049 nullptr,
Christopher Wiley3616d132015-09-01 11:07:48 -070050};
51
Christopher Wiley4432ccf2015-09-18 18:32:08 -070052const char kCompileCommandInput[] = "directory/ITool.aidl";
Christopher Wileyd93c5b72015-09-14 13:21:37 -070053const char kCompileCommandIncludePath[] = "-Iinclude_path";
54const char* kCompileJavaCommand[] = {
55 "aidl",
56 "-b",
57 kCompileCommandIncludePath,
58 kCompileCommandInput,
59 nullptr,
60};
Christopher Wiley4432ccf2015-09-18 18:32:08 -070061const char kCompileCommandJavaOutput[] = "directory/ITool.java";
Christopher Wileyd93c5b72015-09-14 13:21:37 -070062
Steven Morelandb436cb72018-07-06 11:33:47 -070063const char kCompileDepFileNinja[] = "--ninja";
Dan Willemsen93298ee2016-11-10 23:55:55 -080064const char* kCompileJavaCommandNinja[] = {
65 "aidl",
66 "-b",
67 kCompileDepFileNinja,
68 kCompileCommandIncludePath,
69 kCompileCommandInput,
70 nullptr,
71};
72
Christopher Wileya590de82015-09-15 15:46:28 -070073const char kCompileDepFile[] = "-doutput.deps";
Jiyong Park05463732018-08-09 16:03:02 +090074const char kCompileCommandHeaderDir[] = "output/dir/";
Christopher Wiley054afbd2015-10-16 17:08:43 -070075const char kCompileCommandCppOutput[] = "some/file.cpp";
Christopher Wileya590de82015-09-15 15:46:28 -070076const char* kCompileCppCommand[] = {
77 "aidl-cpp",
78 kCompileCommandIncludePath,
79 kCompileDepFile,
80 kCompileCommandInput,
Christopher Wiley054afbd2015-10-16 17:08:43 -070081 kCompileCommandHeaderDir,
82 kCompileCommandCppOutput,
Christopher Wileya590de82015-09-15 15:46:28 -070083 nullptr,
84};
Dan Willemsen93298ee2016-11-10 23:55:55 -080085const char* kCompileCppCommandNinja[] = {
86 "aidl-cpp",
87 kCompileCommandIncludePath,
88 kCompileDepFile,
89 kCompileDepFileNinja,
90 kCompileCommandInput,
91 kCompileCommandHeaderDir,
92 kCompileCommandCppOutput,
93 nullptr,
94};
Christopher Wileya590de82015-09-15 15:46:28 -070095
Jiyong Park74595c12018-07-23 15:22:50 +090096unique_ptr<Options> GetOptions(const char* command[],
97 Options::Language default_lang = Options::Language::JAVA) {
Christopher Wileyd93c5b72015-09-14 13:21:37 -070098 int argc = 0;
99 const char** command_part = command;
100 for (; *command_part; ++argc, ++command_part) {}
Jiyong Park74595c12018-07-23 15:22:50 +0900101 unique_ptr<Options> ret(new Options(argc, command, default_lang));
102 if (!ret->Ok()) {
103 cerr << ret->GetErrorMessage();
Christopher Wileyd93c5b72015-09-14 13:21:37 -0700104 cerr << "Failed to parse command line:";
105 for (int i = 0; i < argc; ++i) {
106 cerr << " " << command[i];
107 cerr << endl;
108 }
109 }
Jiyong Park74595c12018-07-23 15:22:50 +0900110 EXPECT_NE(ret, nullptr) << "Failed to parse options!";
111 return ret;
Christopher Wileyd93c5b72015-09-14 13:21:37 -0700112}
113
Christopher Wiley4427d862015-09-14 11:07:39 -0700114} // namespace
115
Jiyong Park74595c12018-07-23 15:22:50 +0900116TEST(OptionsTests, ParsesPreprocess) {
117 unique_ptr<Options> options = GetOptions(kPreprocessCommand);
118 EXPECT_EQ(Options::Task::PREPROCESS, options->GetTask());
119 EXPECT_EQ(false, options->FailOnParcelable());
Jiyong Park3c35e392018-08-30 13:10:30 +0900120 EXPECT_EQ(0u, options->ImportDirs().size());
Jiyong Park74595c12018-07-23 15:22:50 +0900121 EXPECT_EQ(0u, options->PreprocessedFiles().size());
122 EXPECT_EQ(string{kPreprocessCommandOutputFile}, options->OutputFile());
123 EXPECT_EQ(false, options->AutoDepFile());
Christopher Wiley3616d132015-09-01 11:07:48 -0700124 const vector<string> expected_input{kPreprocessCommandInput1,
125 kPreprocessCommandInput2,
126 kPreprocessCommandInput3};
Jiyong Park74595c12018-07-23 15:22:50 +0900127 EXPECT_EQ(expected_input, options->InputFiles());
Christopher Wileyd93c5b72015-09-14 13:21:37 -0700128}
129
Jiyong Park74595c12018-07-23 15:22:50 +0900130TEST(OptionsTests, ParsesCompileJava) {
131 unique_ptr<Options> options = GetOptions(kCompileJavaCommand);
132 EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
133 EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
134 EXPECT_EQ(true, options->FailOnParcelable());
Jiyong Park3c35e392018-08-30 13:10:30 +0900135 EXPECT_EQ(1u, options->ImportDirs().size());
Jiyong Park74595c12018-07-23 15:22:50 +0900136 EXPECT_EQ(0u, options->PreprocessedFiles().size());
137 EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
138 EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
139 EXPECT_EQ(false, options->AutoDepFile());
Dan Willemsen93298ee2016-11-10 23:55:55 -0800140 EXPECT_EQ(false, options->DependencyFileNinja());
141}
142
Jiyong Park74595c12018-07-23 15:22:50 +0900143TEST(OptionsTests, ParsesCompileJavaNinja) {
144 unique_ptr<Options> options = GetOptions(kCompileJavaCommandNinja);
145 EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
146 EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
147 EXPECT_EQ(true, options->FailOnParcelable());
Jiyong Park3c35e392018-08-30 13:10:30 +0900148 EXPECT_EQ(1u, options->ImportDirs().size());
Jiyong Park74595c12018-07-23 15:22:50 +0900149 EXPECT_EQ(0u, options->PreprocessedFiles().size());
150 EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
151 EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
152 EXPECT_EQ(false, options->AutoDepFile());
Dan Willemsen93298ee2016-11-10 23:55:55 -0800153 EXPECT_EQ(true, options->DependencyFileNinja());
Christopher Wiley3616d132015-09-01 11:07:48 -0700154}
Christopher Wiley4427d862015-09-14 11:07:39 -0700155
Jiyong Park74595c12018-07-23 15:22:50 +0900156TEST(OptionsTests, ParsesCompileCpp) {
157 unique_ptr<Options> options = GetOptions(kCompileCppCommand, Options::Language::CPP);
Jiyong Park3c35e392018-08-30 13:10:30 +0900158 ASSERT_EQ(1u, options->ImportDirs().size());
Jiyong Park8c380532018-08-30 14:55:26 +0900159 EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin());
Jiyong Park74595c12018-07-23 15:22:50 +0900160 EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile());
Dan Willemsen93298ee2016-11-10 23:55:55 -0800161 EXPECT_EQ(false, options->DependencyFileNinja());
Jiyong Park74595c12018-07-23 15:22:50 +0900162 EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
Dan Willemsen93298ee2016-11-10 23:55:55 -0800163 EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
Jiyong Park74595c12018-07-23 15:22:50 +0900164 EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
Dan Willemsen93298ee2016-11-10 23:55:55 -0800165}
166
Jiyong Park74595c12018-07-23 15:22:50 +0900167TEST(OptionsTests, ParsesCompileCppNinja) {
168 unique_ptr<Options> options = GetOptions(kCompileCppCommandNinja, Options::Language::CPP);
Jiyong Park3c35e392018-08-30 13:10:30 +0900169 ASSERT_EQ(1u, options->ImportDirs().size());
Jiyong Park8c380532018-08-30 14:55:26 +0900170 EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin());
Jiyong Park74595c12018-07-23 15:22:50 +0900171 EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile());
Dan Willemsen93298ee2016-11-10 23:55:55 -0800172 EXPECT_EQ(true, options->DependencyFileNinja());
Jiyong Park74595c12018-07-23 15:22:50 +0900173 EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
Christopher Wiley054afbd2015-10-16 17:08:43 -0700174 EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
Jiyong Park74595c12018-07-23 15:22:50 +0900175 EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
Christopher Wiley4432ccf2015-09-18 18:32:08 -0700176}
177
Jiyong Park74595c12018-07-23 15:22:50 +0900178TEST(OptionsTests, ParsesCompileJavaMultiInput) {
179 const char* argv[] = {
180 "aidl",
181 "--lang=java",
182 kCompileCommandIncludePath,
183 "-o src_out",
184 "directory/input1.aidl",
185 "directory/input2.aidl",
186 "directory/input3.aidl",
187 nullptr,
188 };
189 unique_ptr<Options> options = GetOptions(argv);
190 EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
191 EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
192 EXPECT_EQ(false, options->FailOnParcelable());
Jiyong Park3c35e392018-08-30 13:10:30 +0900193 EXPECT_EQ(1u, options->ImportDirs().size());
Jiyong Park74595c12018-07-23 15:22:50 +0900194 EXPECT_EQ(0u, options->PreprocessedFiles().size());
195 const vector<string> expected_input{"directory/input1.aidl", "directory/input2.aidl",
196 "directory/input3.aidl"};
197 EXPECT_EQ(expected_input, options->InputFiles());
198 EXPECT_EQ(string{""}, options->OutputFile());
199 EXPECT_EQ(false, options->AutoDepFile());
200 EXPECT_EQ(false, options->DependencyFileNinja());
201 EXPECT_EQ(string{""}, options->OutputHeaderDir());
Jiyong Park05463732018-08-09 16:03:02 +0900202 EXPECT_EQ(string{"src_out/"}, options->OutputDir());
Christopher Wiley4432ccf2015-09-18 18:32:08 -0700203}
204
Andrei Homescub62afd92020-05-11 19:24:59 -0700205TEST(OptionsTests, ParsesCompileRust) {
206 const char* argv[] = {
207 "aidl", "--lang=rust", kCompileCommandIncludePath,
208 "-o src_out", kCompileCommandInput, nullptr,
209 };
210 unique_ptr<Options> options = GetOptions(argv);
211 EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
212 EXPECT_EQ(Options::Language::RUST, options->TargetLanguage());
213 EXPECT_EQ(false, options->FailOnParcelable());
214 EXPECT_EQ(1u, options->ImportDirs().size());
215 EXPECT_EQ(0u, options->PreprocessedFiles().size());
216 EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
217 EXPECT_EQ(string{""}, options->OutputFile());
218 EXPECT_EQ(string{""}, options->OutputHeaderDir());
219 EXPECT_EQ(string{"src_out/"}, options->OutputDir());
220 EXPECT_EQ(false, options->AutoDepFile());
221 EXPECT_EQ(false, options->DependencyFileNinja());
Andrei Homescub62afd92020-05-11 19:24:59 -0700222}
223
Jooyung Hanc522ac82020-10-23 14:24:12 +0900224TEST(OptionsTests, ParsesCompileJavaInvalid_OutRequired) {
Jiyong Park74595c12018-07-23 15:22:50 +0900225 // -o option is required
Jooyung Hanc522ac82020-10-23 14:24:12 +0900226 string expected_error = "Output directory is not set. Set with --out.";
227 CaptureStderr();
Jiyong Park74595c12018-07-23 15:22:50 +0900228 const char* arg_with_no_out_dir[] = {
229 "aidl",
230 "--lang=java",
231 kCompileCommandIncludePath,
232 "directory/input1.aidl",
233 "directory/input2.aidl",
234 "directory/input3.aidl",
235 nullptr,
Christopher Wiley4432ccf2015-09-18 18:32:08 -0700236 };
Jiyong Park74595c12018-07-23 15:22:50 +0900237 EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok());
Jooyung Hanc522ac82020-10-23 14:24:12 +0900238 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
239}
Jiyong Park74595c12018-07-23 15:22:50 +0900240
Jooyung Hanc522ac82020-10-23 14:24:12 +0900241TEST(OptionsTests, ParsesCompileJavaInvalid_RejectHeaderOut) {
242 string expected_error = "Header output directory is set, which does not make sense for Java.";
243 CaptureStderr();
Jiyong Park74595c12018-07-23 15:22:50 +0900244 // -h options is not for Java
245 const char* arg_with_header_dir[] = {
246 "aidl", "--lang=java", kCompileCommandIncludePath, "-o src_out",
247 "-h header_out", "directory/input1.aidl", "directory/input2.aidl", "directory/input3.aidl",
248 nullptr,
Christopher Wiley4432ccf2015-09-18 18:32:08 -0700249 };
Jiyong Park74595c12018-07-23 15:22:50 +0900250 EXPECT_EQ(false, GetOptions(arg_with_header_dir)->Ok());
Jooyung Hanc522ac82020-10-23 14:24:12 +0900251 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
Jiyong Park74595c12018-07-23 15:22:50 +0900252}
253
254TEST(OptionsTests, ParsesCompileCppMultiInput) {
255 const char* argv[] = {
256 "aidl",
257 "--lang=cpp",
258 kCompileCommandIncludePath,
259 "-h header_out",
260 "-o src_out",
261 "directory/input1.aidl",
262 "directory/input2.aidl",
263 "directory/input3.aidl",
264 nullptr,
265 };
266 unique_ptr<Options> options = GetOptions(argv);
267 EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
268 EXPECT_EQ(Options::Language::CPP, options->TargetLanguage());
269 EXPECT_EQ(false, options->FailOnParcelable());
Jiyong Park3c35e392018-08-30 13:10:30 +0900270 EXPECT_EQ(1u, options->ImportDirs().size());
Jiyong Park74595c12018-07-23 15:22:50 +0900271 EXPECT_EQ(0u, options->PreprocessedFiles().size());
272 const vector<string> expected_input{"directory/input1.aidl", "directory/input2.aidl",
273 "directory/input3.aidl"};
274 EXPECT_EQ(expected_input, options->InputFiles());
275 EXPECT_EQ(string{""}, options->OutputFile());
276 EXPECT_EQ(false, options->AutoDepFile());
277 EXPECT_EQ(false, options->DependencyFileNinja());
Jiyong Park05463732018-08-09 16:03:02 +0900278 EXPECT_EQ(string{"header_out/"}, options->OutputHeaderDir());
279 EXPECT_EQ(string{"src_out/"}, options->OutputDir());
Jiyong Park74595c12018-07-23 15:22:50 +0900280}
281
Jooyung Hanc522ac82020-10-23 14:24:12 +0900282TEST(OptionsTests, ParsesCompileCppInvalid_OutRequired) {
Jiyong Park74595c12018-07-23 15:22:50 +0900283 // -o option is required
Jooyung Hanc522ac82020-10-23 14:24:12 +0900284 string expected_error = "Output directory is not set. Set with --out.";
285 CaptureStderr();
Jiyong Park74595c12018-07-23 15:22:50 +0900286 const char* arg_with_no_out_dir[] = {
287 "aidl",
288 "--lang=cpp",
289 kCompileCommandIncludePath,
290 "directory/input1.aidl",
291 "directory/input2.aidl",
292 "directory/input3.aidl",
293 nullptr,
294 };
295 EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok());
Jooyung Hanc522ac82020-10-23 14:24:12 +0900296 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
297}
Jiyong Park74595c12018-07-23 15:22:50 +0900298
Jooyung Hanc522ac82020-10-23 14:24:12 +0900299TEST(OptionsTests, ParsesCompileCppInvalid_HeaderOutRequired) {
Jiyong Park74595c12018-07-23 15:22:50 +0900300 // -h options is required as well
Jooyung Hanc522ac82020-10-23 14:24:12 +0900301 string expected_error = "Header output directory is not set. Set with --header_out";
302 CaptureStderr();
Jiyong Park74595c12018-07-23 15:22:50 +0900303 const char* arg_with_no_header_dir[] = {
304 "aidl",
305 "--lang=cpp",
306 kCompileCommandIncludePath,
307 "-o src_out",
308 "directory/input1.aidl",
309 "directory/input2.aidl",
310 "directory/input3.aidl",
311 nullptr,
312 };
313 EXPECT_EQ(false, GetOptions(arg_with_no_header_dir)->Ok());
Jooyung Hanc522ac82020-10-23 14:24:12 +0900314 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
Christopher Wileya590de82015-09-15 15:46:28 -0700315}
316
Jooyung Hanc522ac82020-10-23 14:24:12 +0900317TEST(OptionsTests, ParsesCompileRustInvalid_OutRequired) {
Andrei Homescub62afd92020-05-11 19:24:59 -0700318 // -o option is required
Jooyung Hanc522ac82020-10-23 14:24:12 +0900319 string expected_error = "Output directory is not set. Set with --out";
320 CaptureStderr();
Andrei Homescub62afd92020-05-11 19:24:59 -0700321 const char* arg_with_no_out_dir[] = {
322 "aidl",
323 "--lang=rust",
324 kCompileCommandIncludePath,
325 "directory/input1.aidl",
326 "directory/input2.aidl",
327 "directory/input3.aidl",
328 nullptr,
329 };
330 EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok());
Jooyung Hanc522ac82020-10-23 14:24:12 +0900331 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
332}
Andrei Homescub62afd92020-05-11 19:24:59 -0700333
Jooyung Hanc522ac82020-10-23 14:24:12 +0900334TEST(OptionsTests, ParsesCompileRustInvalid_RejectHeaderOut) {
335 string expected_error = "Header output directory is set, which does not make sense for Rust.";
336 CaptureStderr();
Andrei Homescub62afd92020-05-11 19:24:59 -0700337 // -h options is not for Rust
338 const char* arg_with_header_dir[] = {
339 "aidl", "--lang=rust", kCompileCommandIncludePath, "-o src_out",
340 "-h header_out", "directory/input1.aidl", "directory/input2.aidl", "directory/input3.aidl",
341 nullptr,
342 };
343 EXPECT_EQ(false, GetOptions(arg_with_header_dir)->Ok());
Jooyung Hanc522ac82020-10-23 14:24:12 +0900344 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
Andrei Homescub62afd92020-05-11 19:24:59 -0700345}
346
Christopher Wiley4427d862015-09-14 11:07:39 -0700347} // namespace aidl
Steven Morelandf4c64df2019-07-29 19:54:04 -0700348} // namespace android