160293197379e522c870c4a28462804207bab505dAdam Lesinski/* 27a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski * Copyright (C) 2016 The Android Open Source Project 360293197379e522c870c4a28462804207bab505dAdam Lesinski * 460293197379e522c870c4a28462804207bab505dAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 560293197379e522c870c4a28462804207bab505dAdam Lesinski * you may not use this file except in compliance with the License. 660293197379e522c870c4a28462804207bab505dAdam Lesinski * You may obtain a copy of the License at 760293197379e522c870c4a28462804207bab505dAdam Lesinski * 860293197379e522c870c4a28462804207bab505dAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 960293197379e522c870c4a28462804207bab505dAdam Lesinski * 1060293197379e522c870c4a28462804207bab505dAdam Lesinski * Unless required by applicable law or agreed to in writing, software 1160293197379e522c870c4a28462804207bab505dAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 1260293197379e522c870c4a28462804207bab505dAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1360293197379e522c870c4a28462804207bab505dAdam Lesinski * See the License for the specific language governing permissions and 1460293197379e522c870c4a28462804207bab505dAdam Lesinski * limitations under the License. 1560293197379e522c870c4a28462804207bab505dAdam Lesinski */ 1660293197379e522c870c4a28462804207bab505dAdam Lesinski 1760293197379e522c870c4a28462804207bab505dAdam Lesinski#include "TestHelpers.h" 1860293197379e522c870c4a28462804207bab505dAdam Lesinski 197ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include <libgen.h> 207a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski#include <unistd.h> 21ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski 227ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include <memory> 237ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include <string> 247ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 257ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include "android-base/file.h" 26ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski#include "android-base/logging.h" 277ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include "android-base/strings.h" 284c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski#include "ziparchive/zip_archive.h" 2960293197379e522c870c4a28462804207bab505dAdam Lesinski 3060293197379e522c870c4a28462804207bab505dAdam Lesinskinamespace android { 3160293197379e522c870c4a28462804207bab505dAdam Lesinski 32ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinskistatic std::string sTestDataPath; 33ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski 347ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski// Extract the directory of the current executable path. 357ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinskistatic std::string GetExecutableDir() { 367ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski const std::string path = base::GetExecutablePath(); 377ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski std::unique_ptr<char, decltype(&std::free)> mutable_path = {strdup(path.c_str()), std::free}; 387ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski std::string executable_dir = dirname(mutable_path.get()); 397ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski return executable_dir; 407ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski} 417ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 427ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinskivoid InitializeTest(int* argc, char** argv) { 437ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski // Set the default test data path to be the executable path directory. 447ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski SetTestDataPath(GetExecutableDir()); 457ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 467ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski for (int i = 1; i < *argc; i++) { 477ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski const std::string arg = argv[i]; 487ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski if (base::StartsWith(arg, "--testdata=")) { 497ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski SetTestDataPath(arg.substr(strlen("--testdata="))); 507ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski for (int j = i; j != *argc; j++) { 517ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski argv[j] = argv[j + 1]; 527ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski } 537ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski --(*argc); 547ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski --i; 557ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski } else if (arg == "-h" || arg == "--help") { 567ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski std::cerr << "\nAdditional options specific to this test:\n" 577ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski " --testdata=[PATH]\n" 587ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski " Specify the location of test data used within the tests.\n"; 597ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski exit(1); 607ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski } 617ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski } 627ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski} 637ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 64ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinskivoid SetTestDataPath(const std::string& path) { sTestDataPath = path; } 65ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski 66ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinskiconst std::string& GetTestDataPath() { 67ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski CHECK(!sTestDataPath.empty()) << "no test data path set."; 68ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski return sTestDataPath; 69ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski} 70ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski 714c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski::testing::AssertionResult ReadFileFromZipToString(const std::string& zip_path, 724c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski const std::string& file, 734c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string* out_contents) { 744c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski out_contents->clear(); 754c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ::ZipArchiveHandle handle; 764c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski int32_t result = OpenArchive(zip_path.c_str(), &handle); 774c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski if (result != 0) { 784c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski return ::testing::AssertionFailure() << "Failed to open zip '" << zip_path 794c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski << "': " << ::ErrorCodeString(result); 804c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski } 814c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 824c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ::ZipString name(file.c_str()); 834c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ::ZipEntry entry; 844c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski result = ::FindEntry(handle, name, &entry); 854c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski if (result != 0) { 864c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ::CloseArchive(handle); 874c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski return ::testing::AssertionFailure() << "Could not find file '" << file << "' in zip '" 884c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski << zip_path << "' : " << ::ErrorCodeString(result); 894c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski } 904c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 914c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski out_contents->resize(entry.uncompressed_length); 924c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski result = ::ExtractToMemory( 934c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski handle, &entry, const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(out_contents->data())), 944c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski out_contents->size()); 954c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski if (result != 0) { 964c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ::CloseArchive(handle); 974c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski return ::testing::AssertionFailure() << "Failed to extract file '" << file << "' from zip '" 984c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski << zip_path << "': " << ::ErrorCodeString(result); 994c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski } 1004c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 1014c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ::CloseArchive(handle); 1024c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski return ::testing::AssertionSuccess(); 1034c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski} 1044c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 1054c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id, 1067a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski const char* expected_str) { 1077a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski Res_value val; 1087a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski ssize_t block = table.getResource(resource_id, &val, MAY_NOT_BE_BAG); 1097a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski if (block < 0) { 1107a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski return ::testing::AssertionFailure() << "could not find resource"; 1117a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski } 1127a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski 1137a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski if (val.dataType != Res_value::TYPE_STRING) { 1147a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski return ::testing::AssertionFailure() << "resource is not a string"; 1157a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski } 1167a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski 1177a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski const ResStringPool* pool = table.getTableStringBlock(block); 1187a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski if (pool == NULL) { 1194c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski return ::testing::AssertionFailure() << "table has no string pool for block " << block; 1207a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski } 1217a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski 1227a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski const String8 actual_str = pool->string8ObjectAt(val.data); 1237a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski if (String8(expected_str) != actual_str) { 1247a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski return ::testing::AssertionFailure() << actual_str.string(); 1257a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski } 1267a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski return ::testing::AssertionSuccess() << actual_str.string(); 12760293197379e522c870c4a28462804207bab505dAdam Lesinski} 12860293197379e522c870c4a28462804207bab505dAdam Lesinski 1297ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinskistd::string GetStringFromPool(const ResStringPool* pool, uint32_t idx) { 1307ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski String8 str = pool->string8ObjectAt(idx); 1317ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski return std::string(str.string(), str.length()); 1327ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski} 1337ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 1347a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski} // namespace android 135