Add --testdata flag for easier testing

Instead of hardcoding or assuming a path for testdata,
allow the testdata path to be specified via the command
line.
Test: make libandroidfw_tests

Change-Id: Ideae880b21c157b70a11bb5a90a94556771aead6
This commit is contained in:
Adam Lesinski
2016-11-10 14:33:11 -08:00
parent 8fc495ed94
commit ea7897954f
5 changed files with 138 additions and 54 deletions

View File

@@ -28,6 +28,7 @@ testFiles := \
Config_test.cpp \
ConfigLocale_test.cpp \
Idmap_test.cpp \
Main.cpp \
ResTable_test.cpp \
Split_test.cpp \
TestHelpers.cpp \
@@ -59,7 +60,8 @@ LOCAL_STATIC_LIBRARIES := \
libutils \
libcutils \
liblog \
libz \
libz
LOCAL_PICKUP_FILES := $(LOCAL_PATH)/data
include $(BUILD_HOST_NATIVE_TEST)
@@ -80,7 +82,8 @@ LOCAL_SHARED_LIBRARIES := \
libbase \
libcutils \
libutils \
libui \
libui
LOCAL_PICKUP_FILES := $(LOCAL_PATH)/data
include $(BUILD_NATIVE_TEST)
endif # Not SDK_ONLY

View File

@@ -15,24 +15,27 @@
*/
#include "androidfw/AttributeResolution.h"
#include "android-base/file.h"
#include "android-base/logging.h"
#include "android-base/macros.h"
#include "TestHelpers.h"
#include "data/styles/R.h"
#include <android-base/file.h>
#include <android-base/macros.h>
using namespace android;
using android::base::ReadFileToString;
using com::android::app::R;
namespace android {
class AttributeResolutionTest : public ::testing::Test {
public:
virtual void SetUp() override {
std::string test_source_dir = TestSourceDir();
std::string test_source_dir = GetTestDataPath();
std::string contents;
LOG_ALWAYS_FATAL_IF(!ReadFileToString(test_source_dir + "/styles/resources.arsc", &contents));
LOG_ALWAYS_FATAL_IF(
table_.add(contents.data(), contents.size(), 1 /*cookie*/, true /*copyData*/) != NO_ERROR);
CHECK(base::ReadFileToString(test_source_dir + "/styles/resources.arsc",
&contents));
CHECK(table_.add(contents.data(), contents.size(), 1 /*cookie*/,
true /*copyData*/) == NO_ERROR);
}
protected:
@@ -43,11 +46,12 @@ class AttributeResolutionXmlTest : public AttributeResolutionTest {
public:
virtual void SetUp() override {
AttributeResolutionTest::SetUp();
std::string test_source_dir = TestSourceDir();
std::string test_source_dir = GetTestDataPath();
std::string contents;
LOG_ALWAYS_FATAL_IF(!ReadFileToString(test_source_dir + "/styles/layout.xml", &contents));
LOG_ALWAYS_FATAL_IF(xml_parser_.setTo(contents.data(), contents.size(), true /*copyData*/) !=
NO_ERROR);
CHECK(base::ReadFileToString(test_source_dir + "/styles/layout.xml",
&contents));
CHECK(xml_parser_.setTo(contents.data(), contents.size(),
true /*copyData*/) == NO_ERROR);
// Skip to the first tag.
while (xml_parser_.next() != ResXMLParser::START_TAG) {
@@ -68,8 +72,9 @@ TEST_F(AttributeResolutionTest, Theme) {
values.resize(arraysize(attrs) * 6);
ASSERT_TRUE(ResolveAttrs(&theme, 0 /*def_style_attr*/, 0 /*def_style_res*/,
nullptr /*src_values*/, 0 /*src_values_length*/, attrs, arraysize(attrs),
values.data(), nullptr /*out_indices*/));
nullptr /*src_values*/, 0 /*src_values_length*/,
attrs, arraysize(attrs), values.data(),
nullptr /*out_indices*/));
const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
@@ -111,8 +116,8 @@ TEST_F(AttributeResolutionXmlTest, XmlParser) {
std::vector<uint32_t> values;
values.resize(arraysize(attrs) * 6);
ASSERT_TRUE(RetrieveAttributes(&table_, &xml_parser_, attrs, arraysize(attrs), values.data(),
nullptr /*out_indices*/));
ASSERT_TRUE(RetrieveAttributes(&table_, &xml_parser_, attrs, arraysize(attrs),
values.data(), nullptr /*out_indices*/));
uint32_t* values_cursor = values.data();
EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
@@ -151,13 +156,14 @@ TEST_F(AttributeResolutionXmlTest, ThemeAndXmlParser) {
ResTable::Theme theme(table_);
ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::StyleTwo));
uint32_t attrs[] = {R::attr::attr_one, R::attr::attr_two, R::attr::attr_three, R::attr::attr_four,
R::attr::attr_five};
uint32_t attrs[] = {R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
R::attr::attr_four, R::attr::attr_five};
std::vector<uint32_t> values;
values.resize(arraysize(attrs) * 6);
ASSERT_TRUE(ApplyStyle(&theme, &xml_parser_, 0 /*def_style_attr*/, 0 /*def_style_res*/, attrs,
arraysize(attrs), values.data(), nullptr /*out_indices*/));
ASSERT_TRUE(ApplyStyle(&theme, &xml_parser_, 0 /*def_style_attr*/,
0 /*def_style_res*/, attrs, arraysize(attrs),
values.data(), nullptr /*out_indices*/));
const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
@@ -199,3 +205,5 @@ TEST_F(AttributeResolutionXmlTest, ThemeAndXmlParser) {
EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
}
} // namespace android

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2016 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 <libgen.h>
#include <iostream>
#include <memory>
#include <string>
#include "android-base/file.h"
#include "android-base/strings.h"
#include "gtest/gtest.h"
#include "TestHelpers.h"
// Extract the directory of the current executable path.
static std::string GetExecutableDir() {
const std::string path = android::base::GetExecutablePath();
std::unique_ptr<char, decltype(&std::free)> mutable_path = {
strdup(path.c_str()), std::free};
std::string executable_dir = dirname(mutable_path.get());
return executable_dir;
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
// Set the default test data path to be the executable path directory.
android::SetTestDataPath(GetExecutableDir());
const char* command = argv[0];
++argv;
--argc;
while (argc > 0) {
const std::string arg = *argv;
if (android::base::StartsWith(arg, "--testdata=")) {
android::SetTestDataPath(arg.substr(strlen("--testdata=")));
} else if (arg == "-h" || arg == "--help") {
std::cerr
<< "\nAdditional options specific to this test:\n"
" --testdata=[PATH]\n"
" Specify the location of test data used within the tests.\n";
return 1;
} else {
std::cerr << command << ": Unrecognized argument '" << *argv << "'.\n";
return 1;
}
--argc;
++argv;
}
std::cerr << "using --testdata=" << android::GetTestDataPath() << "\n";
return RUN_ALL_TESTS();
}

View File

@@ -16,26 +16,23 @@
#include "TestHelpers.h"
#include <androidfw/ResourceTypes.h>
#include <gtest/gtest.h>
#include <unistd.h>
#include <utils/String8.h>
std::string TestSourceDir() {
const char* dir = getenv("ANDROID_BUILD_TOP");
LOG_ALWAYS_FATAL_IF(dir == nullptr, "Environment variable ANDROID_BUILD_TOP must be set");
std::string testdir = std::string(dir) + "/frameworks/base/libs/androidfw/tests/data";
// Check that the directory exists.
struct stat filestat;
LOG_ALWAYS_FATAL_IF(stat(testdir.c_str(), &filestat) != 0, "test data path '%s' does not exist",
testdir.c_str());
return testdir;
}
#include "android-base/logging.h"
namespace android {
::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id,
static std::string sTestDataPath;
void SetTestDataPath(const std::string& path) { sTestDataPath = path; }
const std::string& GetTestDataPath() {
CHECK(!sTestDataPath.empty()) << "no test data path set.";
return sTestDataPath;
}
::testing::AssertionResult IsStringEqual(const ResTable& table,
uint32_t resource_id,
const char* expected_str) {
Res_value val;
ssize_t block = table.getResource(resource_id, &val, MAY_NOT_BE_BAG);
@@ -49,7 +46,8 @@ namespace android {
const ResStringPool* pool = table.getTableStringBlock(block);
if (pool == NULL) {
return ::testing::AssertionFailure() << "table has no string pool for block " << block;
return ::testing::AssertionFailure()
<< "table has no string pool for block " << block;
}
const String8 actual_str = pool->string8ObjectAt(val.data);

View File

@@ -14,24 +14,24 @@
* limitations under the License.
*/
#ifndef __TEST_HELPERS_H
#define __TEST_HELPERS_H
#include <androidfw/ResourceTypes.h>
#include <gtest/gtest.h>
#include <utils/String16.h>
#include <utils/String8.h>
#ifndef TEST_HELPERS_H_
#define TEST_HELPERS_H_
#include <ostream>
#include <string>
std::string TestSourceDir();
#include "androidfw/ResourceTypes.h"
#include "gtest/gtest.h"
#include "utils/String16.h"
#include "utils/String8.h"
static inline ::std::ostream& operator<<(::std::ostream& out, const android::String8& str) {
static inline ::std::ostream& operator<<(::std::ostream& out,
const android::String8& str) {
return out << str.string();
}
static inline ::std::ostream& operator<<(::std::ostream& out, const android::String16& str) {
static inline ::std::ostream& operator<<(::std::ostream& out,
const android::String16& str) {
return out << android::String8(str).string();
}
@@ -39,18 +39,24 @@ namespace android {
enum { MAY_NOT_BE_BAG = false };
static inline bool operator==(const android::ResTable_config& a,
const android::ResTable_config& b) {
void SetTestDataPath(const std::string& path);
const std::string& GetTestDataPath();
static inline bool operator==(const ResTable_config& a,
const ResTable_config& b) {
return a.compare(b) == 0;
}
static inline ::std::ostream& operator<<(::std::ostream& out, const android::ResTable_config& c) {
static inline ::std::ostream& operator<<(::std::ostream& out,
const ResTable_config& c) {
return out << c.toString().string();
}
::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id,
::testing::AssertionResult IsStringEqual(const ResTable& table,
uint32_t resource_id,
const char* expected_str);
} // namespace android
#endif // __TEST_HELPERS_H
#endif // TEST_HELPERS_H_