1 /*
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 
17 #include <memory>
18 #include <string>
19 #include <vector>
20 
21 #include <android-base/logging.h>
22 #include <gtest/gtest.h>
23 
24 #include "aidl.h"
25 #include "options.h"
26 #include "tests/fake_io_delegate.h"
27 #include "tests/test_data.h"
28 #include "tests/test_util.h"
29 
30 using android::aidl::test::CanonicalNameToPath;
31 using android::aidl::test::FakeIoDelegate;
32 using std::string;
33 using std::unique_ptr;
34 using std::vector;
35 
36 namespace android {
37 namespace aidl {
38 
39 class EndToEndTest : public ::testing::Test {
40  protected:
SetUp()41   void SetUp() override {
42   }
43 
AddStubAidls(const char ** parcelables,const char ** interfaces,const char * cpp_header=nullptr)44   void AddStubAidls(const char** parcelables, const char** interfaces,
45                     const char* cpp_header=nullptr) {
46     for ( ; *parcelables; ++parcelables) {
47       io_delegate_.AddStubParcelable(
48           *parcelables, (cpp_header) ? cpp_header : "");
49     }
50     for ( ; *interfaces; ++interfaces) {
51       io_delegate_.AddStubInterface(*interfaces);
52     }
53   }
54 
CheckFileContents(const string & rel_path,const string & expected_content)55   void CheckFileContents(const string& rel_path,
56                          const string& expected_content) {
57     string actual_content;
58     ASSERT_TRUE(io_delegate_.GetWrittenContents(rel_path, &actual_content))
59         << "Expected aidl to write to " << rel_path << " but it did not.";
60 
61     if (actual_content == expected_content) {
62       return;  // success!
63     }
64 
65     test::PrintDiff(expected_content, actual_content);
66     FAIL() << "Actual contents of " << rel_path
67            << " did not match expected content";
68   }
69 
70   FakeIoDelegate io_delegate_;
71 };
72 
TEST_F(EndToEndTest,IExampleInterface)73 TEST_F(EndToEndTest, IExampleInterface) {
74   using namespace ::android::aidl::test_data::example_interface;
75 
76   vector<string> args = {
77     "aidl",
78     "-b",
79     "-I .",
80     "-d an/arbitrary/path/to/dep.P",
81     CanonicalNameToPath(kCanonicalName, ".aidl"),
82     kJavaOutputPath};
83   Options options = Options::From(args);
84 
85   // Load up our fake file system with data.
86   io_delegate_.SetFileContents(options.InputFiles().front(), kInterfaceDefinition);
87   io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable",
88                                      {"Subclass1", "Subclass2"});
89   AddStubAidls(kImportedParcelables, kImportedInterfaces);
90 
91   // Check that we parse correctly.
92   EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
93   CheckFileContents(kJavaOutputPath, kExpectedJavaOutput);
94   CheckFileContents(options.DependencyFile(), kExpectedJavaDepsOutput);
95 }
96 
TEST_F(EndToEndTest,IExampleInterface_WithTrace)97 TEST_F(EndToEndTest, IExampleInterface_WithTrace) {
98   using namespace ::android::aidl::test_data::example_interface;
99 
100   vector<string> args = {
101     "aidl",
102     "-b",
103     "-I .",
104     "-t", //trace
105     "-d an/arbitrary/path/to/dep.P",
106     CanonicalNameToPath(kCanonicalName, ".aidl"),
107     kJavaOutputPath};
108   Options options = Options::From(args);
109 
110   // Load up our fake file system with data.
111   io_delegate_.SetFileContents(options.InputFiles().front(), kInterfaceDefinition);
112   io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable",
113                                      {"Subclass1", "Subclass2"});
114   AddStubAidls(kImportedParcelables, kImportedInterfaces);
115 
116   // Check that we parse correctly.
117   EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
118   CheckFileContents(kJavaOutputPath, kExpectedJavaOutputWithTrace);
119   CheckFileContents(options.DependencyFile(), kExpectedJavaDepsOutput);
120 }
121 
TEST_F(EndToEndTest,IExampleInterface_WithTransactionNames)122 TEST_F(EndToEndTest, IExampleInterface_WithTransactionNames) {
123   using namespace ::android::aidl::test_data::example_interface;
124 
125   vector<string> args = {
126     "aidl",
127     "-b",
128     "-I .",
129     "--transaction_name", //trace
130     "-d an/arbitrary/path/to/dep.P",
131     CanonicalNameToPath(kCanonicalName, ".aidl"),
132     kJavaOutputPath};
133   Options options = Options::From(args);
134 
135   // Load up our fake file system with data.
136   io_delegate_.SetFileContents(options.InputFiles().front(), kInterfaceDefinition);
137   io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable",
138                                      {"Subclass1", "Subclass2"});
139   AddStubAidls(kImportedParcelables, kImportedInterfaces);
140 
141   // Check that we parse correctly.
142   EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
143   CheckFileContents(kJavaOutputPath, kExpectedJavaOutputWithTransactionNames);
144   CheckFileContents(options.DependencyFile(), kExpectedJavaDepsOutput);
145 }
146 
TEST_F(EndToEndTest,IExampleInterface_Outlining)147 TEST_F(EndToEndTest, IExampleInterface_Outlining) {
148   using namespace ::android::aidl::test_data::example_interface;
149 
150   vector<string> args = {
151     "aidl",
152     "-b",
153     "-I .",
154     "-d an/arbitrary/path/to/dep.P",
155     CanonicalNameToPath(kCanonicalName, ".aidl"),
156     kJavaOutputPath};
157   Options options = Options::From(args);
158   options.onTransact_outline_threshold_ = 4;
159   options.onTransact_non_outline_count_ = 3;
160 
161   // Load up our fake file system with data.
162   io_delegate_.SetFileContents(options.InputFiles().front(), kInterfaceDefinitionOutlining);
163   io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable",
164                                      {"Subclass1", "Subclass2"});
165   AddStubAidls(kImportedParcelables, kImportedInterfaces);
166 
167   // Check that we parse correctly.
168   EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
169   CheckFileContents(kJavaOutputPath, kExpectedJavaOutputOutlining);
170   CheckFileContents(options.DependencyFile(), kExpectedJavaDepsOutput);
171 }
172 
TEST_F(EndToEndTest,IExampleInterface_WithVersionAndHash)173 TEST_F(EndToEndTest, IExampleInterface_WithVersionAndHash) {
174   using namespace ::android::aidl::test_data::example_interface;
175 
176   vector<string> args = {
177     "aidl",
178     "-b",
179     "-I .",
180     "-d an/arbitrary/path/to/dep.P",
181     "--version=10",
182     "--hash=abcdefg",
183     CanonicalNameToPath(kCanonicalName, ".aidl"),
184     kJavaOutputPath};
185   Options options = Options::From(args);
186   options.onTransact_outline_threshold_ = 4;
187   options.onTransact_non_outline_count_ = 3;
188 
189   // Load up our fake file system with data.
190   io_delegate_.SetFileContents(options.InputFiles().front(), kInterfaceDefinitionOutlining);
191   io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable",
192                                      {"Subclass1", "Subclass2"});
193   AddStubAidls(kImportedParcelables, kImportedInterfaces);
194 
195   // Check that we parse correctly.
196   EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
197   CheckFileContents(kJavaOutputPath, kExpectedJavaOutputWithVersionAndHash);
198   CheckFileContents(options.DependencyFile(), kExpectedJavaDepsOutput);
199 }
200 
201 
TEST_F(EndToEndTest,IPingResponderCpp)202 TEST_F(EndToEndTest, IPingResponderCpp) {
203   using namespace ::android::aidl::test_data::ping_responder;
204 
205   vector<string> args = {
206     "aidl-cpp",
207     "-d deps.P",
208     "-I .",
209     CanonicalNameToPath(kCanonicalName, ".aidl"),
210     kGenHeaderDir,
211     kCppOutputPath};
212   Options options = Options::From(args);
213 
214   // Set up input paths.
215   io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);
216   AddStubAidls(kImportedParcelables, kImportedInterfaces, kCppParcelableHeader);
217 
218   // Check that we parse and generate code correctly.
219   EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
220   CheckFileContents(kCppOutputPath, kExpectedCppOutput);
221   CheckFileContents(kGenInterfaceHeaderPath, kExpectedIHeaderOutput);
222   CheckFileContents(kGenClientHeaderPath, kExpectedBpHeaderOutput);
223   CheckFileContents(kGenServerHeaderPath, kExpectedBnHeaderOutput);
224   CheckFileContents(options.DependencyFile(), kExpectedCppDepsOutput);
225 }
226 
TEST_F(EndToEndTest,IPingResponderCpp_WithVersionAndHash)227 TEST_F(EndToEndTest, IPingResponderCpp_WithVersionAndHash) {
228   using namespace ::android::aidl::test_data::ping_responder;
229 
230   vector<string> args = {
231     "aidl-cpp",
232     "-d deps.P",
233     "-I .",
234     "--version=10",
235     "--hash=abcdefg",
236     CanonicalNameToPath(kCanonicalName, ".aidl"),
237     kGenHeaderDir,
238     kCppOutputPath};
239   Options options = Options::From(args);
240 
241   // Set up input paths.
242   io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);
243   AddStubAidls(kImportedParcelables, kImportedInterfaces, kCppParcelableHeader);
244 
245   // Check that we parse and generate code correctly.
246   EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
247   CheckFileContents(kCppOutputPath, kExpectedCppOutputWithVersionAndHash);
248   CheckFileContents(kGenInterfaceHeaderPath, kExpectedIHeaderOutputWithVersionAndHash);
249   CheckFileContents(kGenClientHeaderPath, kExpectedBpHeaderOutputWithVersionAndHash);
250   CheckFileContents(kGenServerHeaderPath, kExpectedBnHeaderOutputWithVersionAndHash);
251   CheckFileContents(options.DependencyFile(), kExpectedCppDepsOutput);
252 }
253 
TEST_F(EndToEndTest,StringConstantsInCpp)254 TEST_F(EndToEndTest, StringConstantsInCpp) {
255   using namespace ::android::aidl::test_data::string_constants;
256 
257   vector<string> args = {
258     "aidl-cpp",
259     CanonicalNameToPath(kCanonicalName, ".aidl"),
260     kGenHeaderDir,
261     kCppOutputPath};
262   Options options = Options::From(args);
263 
264   // Set up input paths.
265   io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);
266 
267   // Check that we parse and generate code correctly.
268   EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
269   CheckFileContents(kCppOutputPath, kExpectedCppOutput);
270   CheckFileContents(kGenInterfaceHeaderPath, kExpectedIHeaderOutput);
271 }
272 
TEST_F(EndToEndTest,StringConstantsInJava)273 TEST_F(EndToEndTest, StringConstantsInJava) {
274   using namespace ::android::aidl::test_data::string_constants;
275 
276   vector<string> args = {
277     "aidl",
278     "-b",
279     CanonicalNameToPath(kCanonicalName, ".aidl"),
280     kJavaOutputPath};
281   Options options = Options::From(args);
282 
283   // Load up our fake file system with data.
284   io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);
285 
286   // Check that we parse correctly.
287   EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
288   CheckFileContents(kJavaOutputPath, kExpectedJavaOutput);
289 }
290 
TEST_F(EndToEndTest,StringConstantsInCpp_WithVersionAndHash)291 TEST_F(EndToEndTest, StringConstantsInCpp_WithVersionAndHash) {
292   using namespace ::android::aidl::test_data::string_constants;
293 
294   vector<string> args = {
295     "aidl-cpp",
296     "--version=10",
297     "--hash=abcdefg",
298     CanonicalNameToPath(kCanonicalName, ".aidl"),
299     kGenHeaderDir,
300     kCppOutputPath};
301   Options options = Options::From(args);
302 
303   // Set up input paths.
304   io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);
305 
306   // Check that we parse and generate code correctly.
307   EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
308   CheckFileContents(kCppOutputPath, kExpectedCppOutputWithVersionAndHash);
309   CheckFileContents(kGenInterfaceHeaderPath, kExpectedIHeaderOutputWithVersionAndHash);
310 }
311 
TEST_F(EndToEndTest,StringConstantsInJava_WithVersionAndHash)312 TEST_F(EndToEndTest, StringConstantsInJava_WithVersionAndHash) {
313   using namespace ::android::aidl::test_data::string_constants;
314 
315   vector<string> args = {
316     "aidl",
317     "-b",
318     "--version=10",
319     "--hash=abcdefg",
320     CanonicalNameToPath(kCanonicalName, ".aidl"),
321     kJavaOutputPath};
322   Options options = Options::From(args);
323 
324   // Load up our fake file system with data.
325   io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);
326 
327   // Check that we parse correctly.
328   EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
329   CheckFileContents(kJavaOutputPath, kExpectedJavaOutputWithVersionAndHash);
330 }
331 
332 }  // namespace aidl
333 }  // namespace android
334