blob: a1be5d8f0256855e2d7a5f79b662cb999b300ef1 [file] [log] [blame]
Casey Dahlina834dd42015-09-23 11:52:15 -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
17#include <string>
18
Elliott Hughes0a620672015-12-04 13:53:18 -080019#include <android-base/stringprintf.h>
Casey Dahlina834dd42015-09-23 11:52:15 -070020#include <gtest/gtest.h>
21
Casey Dahlin2cc93162015-10-02 16:14:17 -070022#include "aidl.h"
Casey Dahlina834dd42015-09-23 11:52:15 -070023#include "aidl_language.h"
24#include "ast_cpp.h"
25#include "code_writer.h"
Christopher Wileyad339272015-10-05 19:11:58 -070026#include "generate_cpp.h"
Christopher Wiley9d6e0b22015-11-13 12:18:16 -080027#include "os.h"
Christopher Wiley4a2884b2015-10-07 11:27:45 -070028#include "tests/fake_io_delegate.h"
Casey Dahlin80ada3d2015-10-20 20:33:56 -070029#include "tests/test_util.h"
Casey Dahlina834dd42015-09-23 11:52:15 -070030
Casey Dahlinb8d9e882015-11-24 10:57:23 -080031using ::android::aidl::test::FakeIoDelegate;
32using ::android::base::StringPrintf;
Casey Dahlina834dd42015-09-23 11:52:15 -070033using std::string;
34using std::unique_ptr;
35
36namespace android {
37namespace aidl {
Christopher Wileyf944e792015-09-29 10:00:46 -070038namespace cpp {
Casey Dahlina834dd42015-09-23 11:52:15 -070039
Casey Dahlinb0966612015-10-19 16:35:26 -070040class ASTTest : public ::testing::Test {
Christopher Wiley0c732db2015-09-29 14:36:44 -070041 protected:
Jiyong Park6f77e0c2018-07-28 16:55:44 +090042 ASTTest(const string& cmdline, const string& file_contents)
43 : options_(Options::From(cmdline)), file_contents_(file_contents) {
Christopher Wiley56799522015-10-31 10:17:04 -070044 }
Casey Dahlinb0966612015-10-19 16:35:26 -070045
Jiyong Parkb034bf02018-07-30 17:44:33 +090046 AidlInterface* ParseSingleInterface() {
Jiyong Park6f77e0c2018-07-28 16:55:44 +090047 io_delegate_.SetFileContents(options_.InputFiles().at(0), file_contents_);
Casey Dahlina834dd42015-09-23 11:52:15 -070048
Jiyong Parkb034bf02018-07-30 17:44:33 +090049 vector<string> imported_files;
Jooyung Han6529b822021-06-11 22:05:26 +090050 ImportResolver import_resolver{io_delegate_, options_.InputFiles().at(0), {"."}};
Jiyong Park6f77e0c2018-07-28 16:55:44 +090051 AidlError err = ::android::aidl::internals::load_and_validate_aidl(
Jiyong Park8e79b7f2020-07-20 20:52:38 +090052 options_.InputFiles().front(), options_, io_delegate_, &typenames_, &imported_files);
Christopher Wiley4a2884b2015-10-07 11:27:45 -070053
Steven Moreland5557f1c2018-07-02 13:50:23 -070054 if (err != AidlError::OK) {
Casey Dahlin2cc93162015-10-02 16:14:17 -070055 return nullptr;
Steven Moreland5557f1c2018-07-02 13:50:23 -070056 }
Casey Dahlina834dd42015-09-23 11:52:15 -070057
Jiyong Park8e79b7f2020-07-20 20:52:38 +090058 const auto& defined_types = typenames_.MainDocument().DefinedTypes();
Jiyong Parkb034bf02018-07-30 17:44:33 +090059 EXPECT_EQ(1ul, defined_types.size());
Jiyong Park8e79b7f2020-07-20 20:52:38 +090060 EXPECT_NE(nullptr, defined_types.front().get()->AsInterface());
Steven Moreland5557f1c2018-07-02 13:50:23 -070061
Jiyong Park8e79b7f2020-07-20 20:52:38 +090062 return defined_types.front().get()->AsInterface();
Christopher Wiley90be4e32015-10-20 14:55:25 -070063 }
Casey Dahlina834dd42015-09-23 11:52:15 -070064
Daniel Norman85aed542019-08-21 12:01:14 -070065 AidlEnumDeclaration* ParseSingleEnumDeclaration() {
66 io_delegate_.SetFileContents(options_.InputFiles().at(0), file_contents_);
67
Daniel Norman85aed542019-08-21 12:01:14 -070068 vector<string> imported_files;
69 AidlError err = ::android::aidl::internals::load_and_validate_aidl(
Jiyong Park8e79b7f2020-07-20 20:52:38 +090070 options_.InputFiles().front(), options_, io_delegate_, &typenames_, &imported_files);
Daniel Norman85aed542019-08-21 12:01:14 -070071
72 if (err != AidlError::OK) {
73 return nullptr;
74 }
75
Jiyong Park8e79b7f2020-07-20 20:52:38 +090076 const auto& defined_types = typenames_.MainDocument().DefinedTypes();
Daniel Norman85aed542019-08-21 12:01:14 -070077 EXPECT_EQ(1ul, defined_types.size());
Jiyong Park8e79b7f2020-07-20 20:52:38 +090078 EXPECT_NE(nullptr, defined_types.front().get()->AsEnumDeclaration());
Daniel Norman85aed542019-08-21 12:01:14 -070079
Jiyong Park8e79b7f2020-07-20 20:52:38 +090080 return defined_types.front().get()->AsEnumDeclaration();
Daniel Norman85aed542019-08-21 12:01:14 -070081 }
82
Christopher Wiley0c732db2015-09-29 14:36:44 -070083 void Compare(Document* doc, const char* expected) {
84 string output;
Jiyong Parkb78e15b2018-07-04 20:31:03 +090085 doc->Write(CodeWriter::ForString(&output).get());
Christopher Wiley0c732db2015-09-29 14:36:44 -070086
Casey Dahlin80ada3d2015-10-20 20:33:56 -070087 if (expected == output) {
88 return; // Success
89 }
90
91 test::PrintDiff(expected, output);
92 FAIL() << "Document contents did not match expected contents";
Christopher Wiley0c732db2015-09-29 14:36:44 -070093 }
Casey Dahlin389781f2015-10-22 13:13:21 -070094
Jiyong Park6f77e0c2018-07-28 16:55:44 +090095 const Options options_;
Casey Dahlin389781f2015-10-22 13:13:21 -070096 const string file_contents_;
97 FakeIoDelegate io_delegate_;
Jeongik Cha047c5ee2019-08-07 23:16:49 +090098 AidlTypenames typenames_;
Christopher Wiley0c732db2015-09-29 14:36:44 -070099};
100
Christopher Wiley9d6e0b22015-11-13 12:18:16 -0800101namespace test_io_handling {
102
103const char kInputPath[] = "a/IFoo.aidl";
104const char kOutputPath[] = "output.cpp";
105const char kHeaderDir[] = "headers";
106const char kInterfaceHeaderRelPath[] = "a/IFoo.h";
107
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900108const string kCmdline = string("aidl-cpp ") + kInputPath + " " + kHeaderDir + " " + kOutputPath;
109
Christopher Wiley9d6e0b22015-11-13 12:18:16 -0800110} // namespace test_io_handling
111
112class IoErrorHandlingTest : public ASTTest {
113 public:
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900114 IoErrorHandlingTest() : ASTTest(test_io_handling::kCmdline, "package a; interface IFoo {}") {}
Christopher Wiley9d6e0b22015-11-13 12:18:16 -0800115};
116
117TEST_F(IoErrorHandlingTest, GenerateCorrectlyAbsentErrors) {
118 // Confirm that this is working correctly without I/O problems.
Jiyong Parkb034bf02018-07-30 17:44:33 +0900119 AidlInterface* interface = ParseSingleInterface();
Christopher Wiley9d6e0b22015-11-13 12:18:16 -0800120 ASSERT_NE(interface, nullptr);
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900121 ASSERT_TRUE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
Christopher Wiley9d6e0b22015-11-13 12:18:16 -0800122}
123
124TEST_F(IoErrorHandlingTest, HandlesBadHeaderWrite) {
125 using namespace test_io_handling;
Jiyong Parkb034bf02018-07-30 17:44:33 +0900126 AidlInterface* interface = ParseSingleInterface();
Christopher Wiley9d6e0b22015-11-13 12:18:16 -0800127 ASSERT_NE(interface, nullptr);
128
129 // Simulate issues closing the interface header.
130 const string header_path =
131 StringPrintf("%s%c%s", kHeaderDir, OS_PATH_SEPARATOR,
132 kInterfaceHeaderRelPath);
133 io_delegate_.AddBrokenFilePath(header_path);
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900134 ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
Christopher Wiley9d6e0b22015-11-13 12:18:16 -0800135 // We should never attempt to write the C++ file if we fail writing headers.
136 ASSERT_FALSE(io_delegate_.GetWrittenContents(kOutputPath, nullptr));
137 // We should remove partial results.
138 ASSERT_TRUE(io_delegate_.PathWasRemoved(header_path));
139}
140
141TEST_F(IoErrorHandlingTest, HandlesBadCppWrite) {
142 using test_io_handling::kOutputPath;
Jiyong Parkb034bf02018-07-30 17:44:33 +0900143 AidlInterface* interface = ParseSingleInterface();
Christopher Wiley9d6e0b22015-11-13 12:18:16 -0800144 ASSERT_NE(interface, nullptr);
145
146 // Simulate issues closing the cpp file.
147 io_delegate_.AddBrokenFilePath(kOutputPath);
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900148 ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
Christopher Wiley9d6e0b22015-11-13 12:18:16 -0800149 // We should remove partial results.
150 ASSERT_TRUE(io_delegate_.PathWasRemoved(kOutputPath));
151}
152
Christopher Wileyf944e792015-09-29 10:00:46 -0700153} // namespace cpp
Casey Dahlina834dd42015-09-23 11:52:15 -0700154} // namespace aidl
155} // namespace android