173 lines
6.1 KiB
C++
173 lines
6.1 KiB
C++
/*
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "test/Fixture.h"
|
|
|
|
#include <dirent.h>
|
|
|
|
#include "android-base/errors.h"
|
|
#include "android-base/file.h"
|
|
#include "android-base/stringprintf.h"
|
|
#include "android-base/utf8.h"
|
|
#include "androidfw/StringPiece.h"
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "cmd/Compile.h"
|
|
#include "cmd/Link.h"
|
|
#include "io/FileStream.h"
|
|
#include "io/Util.h"
|
|
#include "util/Files.h"
|
|
|
|
using testing::Eq;
|
|
using testing::Ne;
|
|
|
|
namespace aapt {
|
|
|
|
const char* CommandTestFixture::kDefaultPackageName = "com.aapt.command.test";
|
|
|
|
void ClearDirectory(const android::StringPiece& path) {
|
|
const std::string root_dir = path.to_string();
|
|
std::unique_ptr<DIR, decltype(closedir)*> dir(opendir(root_dir.data()), closedir);
|
|
if (!dir) {
|
|
StdErrDiagnostics().Error(DiagMessage() << android::base::SystemErrorCodeToString(errno));
|
|
return;
|
|
}
|
|
|
|
while (struct dirent* entry = readdir(dir.get())) {
|
|
// Do not delete hidden files and do not recurse to the parent of this directory
|
|
if (util::StartsWith(entry->d_name, ".")) {
|
|
continue;
|
|
}
|
|
|
|
std::string full_path = file::BuildPath({root_dir, entry->d_name});
|
|
if (file::GetFileType(full_path) == file::FileType::kDirectory) {
|
|
ClearDirectory(full_path);
|
|
#ifdef _WIN32
|
|
_rmdir(full_path.c_str());
|
|
#else
|
|
rmdir(full_path.c_str());
|
|
#endif
|
|
} else {
|
|
android::base::utf8::unlink(full_path.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
void TestDirectoryFixture::SetUp() {
|
|
temp_dir_ = file::BuildPath({android::base::GetExecutableDirectory(),
|
|
"_temp",
|
|
testing::UnitTest::GetInstance()->current_test_case()->name(),
|
|
testing::UnitTest::GetInstance()->current_test_info()->name()});
|
|
ASSERT_TRUE(file::mkdirs(temp_dir_));
|
|
ClearDirectory(temp_dir_);
|
|
}
|
|
|
|
void TestDirectoryFixture::TearDown() {
|
|
ClearDirectory(temp_dir_);
|
|
}
|
|
|
|
void TestDirectoryFixture::WriteFile(const std::string& path, const std::string& contents) {
|
|
CHECK(util::StartsWith(path, temp_dir_))
|
|
<< "Attempting to create a file outside of test temporary directory.";
|
|
|
|
// Create any intermediate directories specified in the path
|
|
auto pos = std::find(path.rbegin(), path.rend(), file::sDirSep);
|
|
if (pos != path.rend()) {
|
|
std::string dirs = path.substr(0, (&*pos - path.data()));
|
|
file::mkdirs(dirs);
|
|
}
|
|
|
|
CHECK(android::base::WriteStringToFile(contents, path));
|
|
}
|
|
|
|
bool CommandTestFixture::CompileFile(const std::string& path, const std::string& contents,
|
|
const android::StringPiece& out_dir, IDiagnostics* diag) {
|
|
WriteFile(path, contents);
|
|
CHECK(file::mkdirs(out_dir.data()));
|
|
return CompileCommand(diag).Execute({path, "-o", out_dir, "-v"}, &std::cerr) == 0;
|
|
}
|
|
|
|
bool CommandTestFixture::Link(const std::vector<std::string>& args, IDiagnostics* diag) {
|
|
std::vector<android::StringPiece> link_args;
|
|
for(const std::string& arg : args) {
|
|
link_args.emplace_back(arg);
|
|
}
|
|
|
|
// Link against the android SDK
|
|
std::string android_sdk = file::BuildPath({android::base::GetExecutableDirectory(),
|
|
"integration-tests", "CommandTests",
|
|
"android-28.jar"});
|
|
link_args.insert(link_args.end(), {"-I", android_sdk});
|
|
|
|
return LinkCommand(diag).Execute(link_args, &std::cerr) == 0;
|
|
}
|
|
|
|
bool CommandTestFixture::Link(const std::vector<std::string>& args,
|
|
const android::StringPiece& flat_dir, IDiagnostics* diag) {
|
|
std::vector<android::StringPiece> link_args;
|
|
for(const std::string& arg : args) {
|
|
link_args.emplace_back(arg);
|
|
}
|
|
|
|
// Link against the android SDK
|
|
std::string android_sdk = file::BuildPath({android::base::GetExecutableDirectory(),
|
|
"integration-tests", "CommandTests",
|
|
"android-28.jar"});
|
|
link_args.insert(link_args.end(), {"-I", android_sdk});
|
|
|
|
// Add the files from the compiled resources directory to the link file arguments
|
|
Maybe<std::vector<std::string>> compiled_files = file::FindFiles(flat_dir, diag);
|
|
if (compiled_files) {
|
|
for (std::string& compile_file : compiled_files.value()) {
|
|
compile_file = file::BuildPath({flat_dir, compile_file});
|
|
link_args.emplace_back(std::move(compile_file));
|
|
}
|
|
}
|
|
|
|
return LinkCommand(diag).Execute(link_args, &std::cerr) == 0;
|
|
}
|
|
|
|
std::string CommandTestFixture::GetDefaultManifest(const char* package_name) {
|
|
const std::string manifest_file = GetTestPath("AndroidManifest.xml");
|
|
WriteFile(manifest_file, android::base::StringPrintf(R"(
|
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
package="%s">
|
|
</manifest>)", package_name));
|
|
return manifest_file;
|
|
}
|
|
|
|
std::unique_ptr<io::IData> CommandTestFixture::OpenFileAsData(LoadedApk* apk,
|
|
const android::StringPiece& path) {
|
|
return apk
|
|
->GetFileCollection()
|
|
->FindFile(path)
|
|
->OpenAsData();
|
|
}
|
|
|
|
void CommandTestFixture::AssertLoadXml(LoadedApk* apk, const io::IData* data,
|
|
android::ResXMLTree *out_tree) {
|
|
ASSERT_THAT(apk, Ne(nullptr));
|
|
|
|
out_tree->setTo(data->data(), data->size());
|
|
ASSERT_THAT(out_tree->getError(), Eq(android::OK));
|
|
while (out_tree->next() != android::ResXMLTree::START_TAG) {
|
|
ASSERT_THAT(out_tree->getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
|
|
ASSERT_THAT(out_tree->getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
|
|
}
|
|
}
|
|
|
|
} // namespace aapt
|