end_to_end_tests.cpp revision 856a869ccab7efe1bc73311d1ee8843cee2f705f
1856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley/*
2856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley * Copyright (C) 2015, The Android Open Source Project
3856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley *
4856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley * Licensed under the Apache License, Version 2.0 (the "License");
5856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley * you may not use this file except in compliance with the License.
6856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley * You may obtain a copy of the License at
7856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley *
8856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley *     http://www.apache.org/licenses/LICENSE-2.0
9856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley *
10856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley * Unless required by applicable law or agreed to in writing, software
11856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley * distributed under the License is distributed on an "AS IS" BASIS,
12856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley * See the License for the specific language governing permissions and
14856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley * limitations under the License.
15856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley */
16856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
17856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley#include <memory>
18856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley#include <string>
19856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley#include <vector>
20856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
21856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley#include <base/logging.h>
22856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley#include <base/files/file_path.h>
23856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley#include <base/files/file_util.h>
24856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley#include <gtest/gtest.h>
25856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
26856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley#include "aidl.h"
27856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley#include "options.h"
28856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley#include "tests/test_data.h"
29856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
30856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wileyusing base::FilePath;
31856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wileyusing std::string;
32856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wileyusing std::unique_ptr;
33856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wileyusing std::vector;
34856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
35856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wileyusing namespace aidl::test_data;
36856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
37856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wileynamespace {
38856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
39856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wileyconst char kDiffTemplate[] = "diff %s %s";
40856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wileyconst char kStubInterfaceTemplate[] = "package %s;\ninterface %s { }";
41856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wileyconst char kStubParcelableTemplate[] = "package %s;\nparcelable %s;";
42856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
43856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher WileyFilePath GetPathForPackageClass(const char* package_class,
44856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                                const char* extension) {
45856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  string rel_path{package_class};
46856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  for (char& c : rel_path) {
47856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    if (c == '.') {
48856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      c = FilePath::kSeparators[0];
49856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    }
50856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  }
51856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  rel_path += extension;
52856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  return FilePath(rel_path);
53856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley}
54856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
55856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wileyvoid SplitPackageClass(const string& package_class,
56856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                       FilePath* rel_path,
57856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                       string* package,
58856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                       string* class_name) {
59856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  *package = string{package_class, 0, package_class.rfind('.')};
60856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  *class_name = string{package_class, package_class.rfind('.') + 1};
61856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  *rel_path = GetPathForPackageClass(package_class.c_str(), ".aidl");
62856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley}
63856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
64856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley}  // namespace
65856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
66856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wileyclass EndToEndTest : public ::testing::Test {
67856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley protected:
68856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  virtual void SetUp() {
69856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    ASSERT_TRUE(base::CreateNewTempDirectory(
70856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley        string{"end_to_end_testsyyyy"}, &tmpDir_));
71856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    inputDir_ = tmpDir_.Append("input");
72856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    outputDir_ = tmpDir_.Append("output");
73856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    ASSERT_TRUE(base::CreateDirectory(inputDir_));
74856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    ASSERT_TRUE(base::CreateDirectory(outputDir_));
75856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  }
76856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
77856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  virtual void TearDown() {
78856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    ASSERT_TRUE(DeleteFile(tmpDir_, true))
79856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley        << "Failed to remove temp directory: " << tmpDir_.value();
80856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  }
81856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
82856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  FilePath CreateInputFile(const FilePath& relative_path,
83856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                           const char contents[],
84856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                           int size) {
85856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    const FilePath created_file = inputDir_.Append(relative_path);
86856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    EXPECT_TRUE(base::CreateDirectory(created_file.DirName()));
87856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    EXPECT_TRUE(base::WriteFile(created_file, contents, size));
88856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    return created_file;
89856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  }
90856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
91856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  void CreateStubAidlFile(const string& package_class,
92856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                          const char* file_template) {
93856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    string package, class_name;
94856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    FilePath rel_path;
95856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    SplitPackageClass(package_class, &rel_path, &package, &class_name);
96856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    const size_t buf_len =
97856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley        strlen(file_template) + package.length() + class_name.length() + 1;
98856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    unique_ptr<char[]> contents(new char[buf_len]);
99856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    const int written = snprintf(contents.get(), buf_len, file_template,
100856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                                 package.c_str(), class_name.c_str());
101856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    EXPECT_GT(written, 0);
102856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    CreateInputFile(rel_path, contents.get(), written);
103856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  }
104856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
105856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  void WriteStubAidls(const char** parcelables, const char** interfaces) {
106856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    while (*parcelables) {
107856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      CreateStubAidlFile(string{*parcelables}, kStubParcelableTemplate);
108856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      ++parcelables;
109856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    }
110856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    while (*interfaces) {
111856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      CreateStubAidlFile(string{*interfaces}, kStubInterfaceTemplate);
112856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      ++interfaces;
113856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    }
114856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  }
115856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
116856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  void CheckFileContents(const FilePath& rel_path,
117856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                         const string& expected_content) {
118856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    string actual_contents;
119856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    FilePath actual_path = outputDir_.Append(rel_path);
120856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    if (!ReadFileToString(actual_path, &actual_contents)) {
121856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      FAIL() << "Failed to read expected output file: " << rel_path.value();
122856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    }
123856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    // Generated .java files mention the "original" file as part of their
124856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    // comment header.  Thus we look for expected_content being a substring.
125856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    if (actual_contents.find(expected_content) == string::npos) {
126856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      // When the match fails, display a diff of what's wrong.  This greatly
127856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      // aids in debugging.
128856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      FilePath expected_path;
129856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      EXPECT_TRUE(CreateTemporaryFileInDir(tmpDir_, &expected_path));
130856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      base::WriteFile(expected_path, expected_content.c_str(),
131856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                      expected_content.length());
132856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      const size_t buf_len =
133856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley          strlen(kDiffTemplate) + actual_path.value().length() +
134856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley          expected_path.value().length() + 1;
135856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      unique_ptr<char[]> diff_cmd(new char[buf_len]);
136856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      EXPECT_GT(snprintf(diff_cmd.get(), buf_len, kDiffTemplate,
137856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                         expected_path.value().c_str(),
138856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                         actual_path.value().c_str()), 0);
139856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      system(diff_cmd.get());
140856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      FAIL() << "Actual contents of " << rel_path.value()
141856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley             << " did not match expected content";
142856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley    }
143856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  }
144856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
145856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  FilePath tmpDir_;
146856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  FilePath inputDir_;
147856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  FilePath outputDir_;
148856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley};
149856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley
150856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher WileyTEST_F(EndToEndTest, IExampleInterface) {
151856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  Options options;
152856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  options.failOnParcelable = true;
153856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  options.importPaths.push_back(inputDir_.value());
154856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  options.inputFileName =
155856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley      CreateInputFile(GetPathForPackageClass(kIExampleInterfaceClass, ".aidl"),
156856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                      kIExampleInterfaceContents,
157856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                      strlen(kIExampleInterfaceContents)).value();
158856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  options.autoDepFile = true;
159856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  options.outputBaseFolder = outputDir_.value();
160856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  WriteStubAidls(kIExampleInterfaceParcelables, kIExampleInterfaceInterfaces);
161856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  EXPECT_EQ(compile_aidl(options), 0);
162856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  CheckFileContents(GetPathForPackageClass(kIExampleInterfaceClass, ".java"),
163856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley                    kIExampleInterfaceJava);
164856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley  // We'd like to check the depends file, but it mentions unique file paths.
165856a869ccab7efe1bc73311d1ee8843cee2f705fChristopher Wiley}
166