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