• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 "TestHelpers.h"
18 
19 #include <libgen.h>
20 #include <unistd.h>
21 
22 #include <memory>
23 #include <string>
24 
25 #include "android-base/file.h"
26 #include "android-base/logging.h"
27 #include "android-base/strings.h"
28 #include "ziparchive/zip_archive.h"
29 
30 namespace android {
31 
32 static std::string sTestDataPath;
33 
34 // Extract the directory of the current executable path.
GetExecutableDir()35 static std::string GetExecutableDir() {
36   const std::string path = base::GetExecutablePath();
37   std::unique_ptr<char, decltype(&std::free)> mutable_path = {strdup(path.c_str()), std::free};
38   std::string executable_dir = dirname(mutable_path.get());
39   return executable_dir;
40 }
41 
InitializeTest(int * argc,char ** argv)42 void InitializeTest(int* argc, char** argv) {
43   // Set the default test data path to be the executable path directory.
44   SetTestDataPath(GetExecutableDir());
45 
46   for (int i = 1; i < *argc; i++) {
47     const std::string arg = argv[i];
48     if (base::StartsWith(arg, "--testdata=")) {
49       SetTestDataPath(arg.substr(strlen("--testdata=")));
50       for (int j = i; j != *argc; j++) {
51         argv[j] = argv[j + 1];
52       }
53       --(*argc);
54       --i;
55     } else if (arg == "-h" || arg == "--help") {
56       std::cerr << "\nAdditional options specific to this test:\n"
57                    "  --testdata=[PATH]\n"
58                    "      Specify the location of test data used within the tests.\n";
59       exit(1);
60     }
61   }
62 }
63 
SetTestDataPath(const std::string & path)64 void SetTestDataPath(const std::string& path) { sTestDataPath = path; }
65 
GetTestDataPath()66 const std::string& GetTestDataPath() {
67   CHECK(!sTestDataPath.empty()) << "no test data path set.";
68   return sTestDataPath;
69 }
70 
ReadFileFromZipToString(const std::string & zip_path,const std::string & file,std::string * out_contents)71 ::testing::AssertionResult ReadFileFromZipToString(const std::string& zip_path,
72                                                    const std::string& file,
73                                                    std::string* out_contents) {
74   out_contents->clear();
75   ::ZipArchiveHandle handle;
76   int32_t result = OpenArchive(zip_path.c_str(), &handle);
77   if (result != 0) {
78     return ::testing::AssertionFailure() << "Failed to open zip '" << zip_path
79                                          << "': " << ::ErrorCodeString(result);
80   }
81 
82   ::ZipString name(file.c_str());
83   ::ZipEntry entry;
84   result = ::FindEntry(handle, name, &entry);
85   if (result != 0) {
86     ::CloseArchive(handle);
87     return ::testing::AssertionFailure() << "Could not find file '" << file << "' in zip '"
88                                          << zip_path << "' : " << ::ErrorCodeString(result);
89   }
90 
91   out_contents->resize(entry.uncompressed_length);
92   result = ::ExtractToMemory(
93       handle, &entry, const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(out_contents->data())),
94       out_contents->size());
95   if (result != 0) {
96     ::CloseArchive(handle);
97     return ::testing::AssertionFailure() << "Failed to extract file '" << file << "' from zip '"
98                                          << zip_path << "': " << ::ErrorCodeString(result);
99   }
100 
101   ::CloseArchive(handle);
102   return ::testing::AssertionSuccess();
103 }
104 
IsStringEqual(const ResTable & table,uint32_t resource_id,const char * expected_str)105 ::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id,
106                                          const char* expected_str) {
107   Res_value val;
108   ssize_t block = table.getResource(resource_id, &val, MAY_NOT_BE_BAG);
109   if (block < 0) {
110     return ::testing::AssertionFailure() << "could not find resource";
111   }
112 
113   if (val.dataType != Res_value::TYPE_STRING) {
114     return ::testing::AssertionFailure() << "resource is not a string";
115   }
116 
117   const ResStringPool* pool = table.getTableStringBlock(block);
118   if (pool == NULL) {
119     return ::testing::AssertionFailure() << "table has no string pool for block " << block;
120   }
121 
122   const String8 actual_str = pool->string8ObjectAt(val.data);
123   if (String8(expected_str) != actual_str) {
124     return ::testing::AssertionFailure() << actual_str.string();
125   }
126   return ::testing::AssertionSuccess() << actual_str.string();
127 }
128 
GetStringFromPool(const ResStringPool * pool,uint32_t idx)129 std::string GetStringFromPool(const ResStringPool* pool, uint32_t idx) {
130   String8 str = pool->string8ObjectAt(idx);
131   return std::string(str.string(), str.length());
132 }
133 
134 }  // namespace android
135