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 "fake_io_delegate.h"
18
19 #include <android-base/stringprintf.h>
20
21 #include "logging.h"
22 #include "os.h"
23 #include "tests/test_util.h"
24
25 using android::base::StringAppendF;
26 using android::base::StringPrintf;
27 using std::string;
28 using std::unique_ptr;
29 using std::vector;
30
31 namespace android {
32 namespace aidl {
33 namespace test {
34
35 // Claims to always write successfully, but can't close the file.
36 class BrokenCodeWriter : public CodeWriter {
Write(const char *,...)37 bool Write(const char* /* format */, ...) override { return true; }
Close()38 bool Close() override { return false; }
39 virtual ~BrokenCodeWriter() = default;
40 }; // class BrokenCodeWriter
41
GetFileContents(const string & relative_filename,const string & content_suffix) const42 unique_ptr<string> FakeIoDelegate::GetFileContents(
43 const string& relative_filename,
44 const string& content_suffix) const {
45 string filename = CleanPath(relative_filename);
46 unique_ptr<string> contents;
47 auto it = file_contents_.find(filename);
48 if (it == file_contents_.end()) {
49 return contents;
50 }
51 contents.reset(new string);
52 *contents = it->second;
53 contents->append(content_suffix);
54
55 return contents;
56 }
57
GetLineReader(const string & file_path) const58 unique_ptr<LineReader> FakeIoDelegate::GetLineReader(
59 const string& file_path) const {
60 unique_ptr<LineReader> ret;
61 const auto& it = file_contents_.find(CleanPath(file_path));
62 if (it != file_contents_.cend()) {
63 ret = LineReader::ReadFromMemory(it->second);
64 }
65 return ret;
66 }
67
FileIsReadable(const string & path) const68 bool FakeIoDelegate::FileIsReadable(const string& path) const {
69 return file_contents_.find(CleanPath(path)) != file_contents_.end();
70 }
71
CreatedNestedDirs(const std::string &,const std::vector<std::string> &) const72 bool FakeIoDelegate::CreatedNestedDirs(
73 const std::string& /* base_dir */,
74 const std::vector<std::string>& /* nested_subdirs */) const {
75 // We don't test directory creation explicitly.
76 return true;
77 }
78
GetCodeWriter(const std::string & file_path) const79 std::unique_ptr<CodeWriter> FakeIoDelegate::GetCodeWriter(
80 const std::string& file_path) const {
81 if (broken_files_.count(file_path) > 0) {
82 return unique_ptr<CodeWriter>(new BrokenCodeWriter);
83 }
84 removed_files_.erase(file_path);
85 written_file_contents_[file_path] = "";
86 return GetStringWriter(&written_file_contents_[file_path]);
87 }
88
RemovePath(const std::string & file_path) const89 void FakeIoDelegate::RemovePath(const std::string& file_path) const {
90 removed_files_.insert(file_path);
91 }
92
SetFileContents(const string & filename,const string & contents)93 void FakeIoDelegate::SetFileContents(const string& filename,
94 const string& contents) {
95 file_contents_[filename] = contents;
96 }
97
AddStubParcelable(const string & canonical_name,const string & cpp_header)98 void FakeIoDelegate::AddStubParcelable(const string& canonical_name,
99 const string& cpp_header) {
100 string package, class_name, rel_path;
101 SplitPackageClass(canonical_name, &rel_path, &package, &class_name);
102 string contents;
103 if (cpp_header.empty()) {
104 contents = StringPrintf("package %s;\nparcelable %s;",
105 package.c_str(), class_name.c_str());
106 } else {
107 contents = StringPrintf("package %s;\nparcelable %s cpp_header \"%s\";",
108 package.c_str(), class_name.c_str(),
109 cpp_header.c_str());
110 }
111 SetFileContents(rel_path, contents);
112 }
113
AddStubInterface(const string & canonical_name)114 void FakeIoDelegate::AddStubInterface(const string& canonical_name) {
115 string package, class_name, rel_path;
116 SplitPackageClass(canonical_name, &rel_path, &package, &class_name);
117 string contents = StringPrintf("package %s;\ninterface %s { }",
118 package.c_str(), class_name.c_str());
119 SetFileContents(rel_path, contents);
120 }
121
AddCompoundParcelable(const string & canonical_name,const vector<string> & subclasses)122 void FakeIoDelegate::AddCompoundParcelable(const string& canonical_name,
123 const vector<string>& subclasses) {
124 string package, class_name, rel_path;
125 SplitPackageClass(canonical_name, &rel_path, &package, &class_name);
126 string contents = StringPrintf("package %s;\n", package.c_str());
127 for (const string& subclass : subclasses) {
128 StringAppendF(&contents, "parcelable %s.%s;\n",
129 class_name.c_str(), subclass.c_str());
130 }
131 SetFileContents(rel_path, contents);
132 }
133
AddBrokenFilePath(const std::string & path)134 void FakeIoDelegate::AddBrokenFilePath(const std::string& path) {
135 broken_files_.insert(path);
136 }
137
GetWrittenContents(const string & path,string * content)138 bool FakeIoDelegate::GetWrittenContents(const string& path, string* content) {
139 const auto it = written_file_contents_.find(path);
140 if (it == written_file_contents_.end()) {
141 return false;
142 }
143 if (content) {
144 *content = it->second;
145 }
146 return true;
147 }
148
PathWasRemoved(const std::string & path)149 bool FakeIoDelegate::PathWasRemoved(const std::string& path) {
150 if (removed_files_.count(path) > 0) {
151 return true;
152 }
153 return false;
154 }
155
CleanPath(const string & path) const156 string FakeIoDelegate::CleanPath(const string& path) const {
157 string clean_path = path;
158 while (clean_path.length() >= 2 &&
159 clean_path[0] == '.' &&
160 clean_path[1] == OS_PATH_SEPARATOR) {
161 clean_path = clean_path.substr(2);
162 }
163 return clean_path;
164 }
165
166 } // namespace test
167 } // namespace android
168 } // namespace aidl
169