liblp: Add PropertyFetcher.
Use dependency injection so that GetProperty / GetBoolProperty can be mocked in tests. Test: run liblp_test_static Change-Id: I8efa85fbbd7aebce2541f748f840e512f3729c30
This commit is contained in:
parent
0d061b258a
commit
04d91871df
|
@ -36,6 +36,7 @@ cc_library {
|
|||
"builder.cpp",
|
||||
"images.cpp",
|
||||
"partition_opener.cpp",
|
||||
"property_fetcher.cpp",
|
||||
"reader.cpp",
|
||||
"utility.cpp",
|
||||
"writer.cpp",
|
||||
|
|
|
@ -21,19 +21,16 @@
|
|||
#include <algorithm>
|
||||
#include <string_view>
|
||||
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
|
||||
#include "liblp/liblp.h"
|
||||
#include "liblp/property_fetcher.h"
|
||||
#include "reader.h"
|
||||
#include "utility.h"
|
||||
|
||||
namespace android {
|
||||
namespace fs_mgr {
|
||||
|
||||
std::optional<bool> MetadataBuilder::sABOverride;
|
||||
std::optional<bool> MetadataBuilder::sRetrofitDap;
|
||||
|
||||
static constexpr std::string_view kDefaultGroup = "default";
|
||||
|
||||
bool LinearExtent::AddTo(LpMetadata* out) const {
|
||||
|
@ -211,14 +208,6 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::NewForUpdate(const IPartitionO
|
|||
return New(*metadata.get(), &opener);
|
||||
}
|
||||
|
||||
void MetadataBuilder::OverrideABForTesting(bool ab_device) {
|
||||
sABOverride = ab_device;
|
||||
}
|
||||
|
||||
void MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(bool retrofit) {
|
||||
sRetrofitDap = retrofit;
|
||||
}
|
||||
|
||||
MetadataBuilder::MetadataBuilder() : auto_slot_suffixing_(false) {
|
||||
memset(&geometry_, 0, sizeof(geometry_));
|
||||
geometry_.magic = LP_METADATA_GEOMETRY_MAGIC;
|
||||
|
@ -1051,17 +1040,12 @@ void MetadataBuilder::SetAutoSlotSuffixing() {
|
|||
}
|
||||
|
||||
bool MetadataBuilder::IsABDevice() {
|
||||
if (sABOverride.has_value()) {
|
||||
return *sABOverride;
|
||||
}
|
||||
return !android::base::GetProperty("ro.boot.slot_suffix", "").empty();
|
||||
return !IPropertyFetcher::GetInstance()->GetProperty("ro.boot.slot_suffix", "").empty();
|
||||
}
|
||||
|
||||
bool MetadataBuilder::IsRetrofitDynamicPartitionsDevice() {
|
||||
if (sRetrofitDap.has_value()) {
|
||||
return *sRetrofitDap;
|
||||
}
|
||||
return android::base::GetBoolProperty("ro.boot.dynamic_partitions_retrofit", false);
|
||||
return IPropertyFetcher::GetInstance()->GetBoolProperty("ro.boot.dynamic_partitions_retrofit",
|
||||
false);
|
||||
}
|
||||
|
||||
bool MetadataBuilder::IsRetrofitMetadata() const {
|
||||
|
|
|
@ -19,36 +19,40 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <liblp/builder.h>
|
||||
|
||||
#include "mock_property_fetcher.h"
|
||||
#include "utility.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace android::fs_mgr;
|
||||
using ::android::fs_mgr::MockPropertyFetcher;
|
||||
using ::testing::_;
|
||||
using ::testing::AnyNumber;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::NiceMock;
|
||||
using ::testing::Return;
|
||||
|
||||
static void ResetPropertyFetcher() {
|
||||
IPropertyFetcher::OverrideForTesting(std::make_unique<NiceMock<MockPropertyFetcher>>());
|
||||
}
|
||||
|
||||
MockPropertyFetcher* GetMockedInstance() {
|
||||
return static_cast<MockPropertyFetcher*>(IPropertyFetcher::GetInstance());
|
||||
}
|
||||
|
||||
class Environment : public ::testing::Environment {
|
||||
public:
|
||||
void SetUp() override {
|
||||
MetadataBuilder::OverrideABForTesting(false);
|
||||
MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false);
|
||||
}
|
||||
void SetUp() override { ResetPropertyFetcher(); }
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::AddGlobalTestEnvironment(new Environment);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
class BuilderTest : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
MetadataBuilder::OverrideABForTesting(false);
|
||||
MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false);
|
||||
}
|
||||
void TearDown() override {
|
||||
MetadataBuilder::OverrideABForTesting(false);
|
||||
MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false);
|
||||
}
|
||||
void SetUp() override { ResetPropertyFetcher(); }
|
||||
void TearDown() override { ResetPropertyFetcher(); }
|
||||
};
|
||||
|
||||
TEST_F(BuilderTest, BuildBasic) {
|
||||
|
@ -785,7 +789,9 @@ TEST_F(BuilderTest, ABExtents) {
|
|||
|
||||
// A and B slots should be allocated from separate halves of the partition,
|
||||
// to mitigate allocating too many extents. (b/120433288)
|
||||
MetadataBuilder::OverrideABForTesting(true);
|
||||
ON_CALL(*GetMockedInstance(), GetProperty("ro.boot.slot_suffix", _))
|
||||
.WillByDefault(Return("_a"));
|
||||
|
||||
auto builder = MetadataBuilder::New(device_info, 65536, 2);
|
||||
ASSERT_NE(builder, nullptr);
|
||||
Partition* system_a = builder->AddPartition("system_a", 0);
|
||||
|
|
|
@ -196,12 +196,6 @@ class MetadataBuilder {
|
|||
return New(device_info, metadata_max_size, metadata_slot_count);
|
||||
}
|
||||
|
||||
// Used by the test harness to override whether the device is "A/B".
|
||||
static void OverrideABForTesting(bool ab_device);
|
||||
|
||||
// Used by the test harness to override whether the device is "retrofitting dynamic partitions".
|
||||
static void OverrideRetrofitDynamicParititonsForTesting(bool retrofit);
|
||||
|
||||
// Define a new partition group. By default there is one group called
|
||||
// "default", with an unrestricted size. A non-zero size will restrict the
|
||||
// total space used by all partitions in the group.
|
||||
|
@ -347,9 +341,6 @@ class MetadataBuilder {
|
|||
const std::vector<Interval>& free_list,
|
||||
uint64_t sectors_needed) const;
|
||||
|
||||
static std::optional<bool> sABOverride;
|
||||
static std::optional<bool> sRetrofitDap;
|
||||
|
||||
LpMetadataGeometry geometry_;
|
||||
LpMetadataHeader header_;
|
||||
std::vector<std::unique_ptr<Partition>> partitions_;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// Copyright (C) 2019 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.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace android {
|
||||
namespace fs_mgr {
|
||||
|
||||
class IPropertyFetcher {
|
||||
public:
|
||||
virtual ~IPropertyFetcher() = default;
|
||||
virtual std::string GetProperty(const std::string& key, const std::string& defaultValue) = 0;
|
||||
virtual bool GetBoolProperty(const std::string& key, bool defaultValue) = 0;
|
||||
|
||||
static IPropertyFetcher* GetInstance();
|
||||
static void OverrideForTesting(std::unique_ptr<IPropertyFetcher>&&);
|
||||
};
|
||||
|
||||
class PropertyFetcher : public IPropertyFetcher {
|
||||
public:
|
||||
~PropertyFetcher() = default;
|
||||
std::string GetProperty(const std::string& key, const std::string& defaultValue) override;
|
||||
bool GetBoolProperty(const std::string& key, bool defaultValue) override;
|
||||
};
|
||||
|
||||
} // namespace fs_mgr
|
||||
} // namespace android
|
|
@ -23,10 +23,12 @@
|
|||
#include <android-base/unique_fd.h>
|
||||
#include <fs_mgr.h>
|
||||
#include <fstab/fstab.h>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <liblp/builder.h>
|
||||
|
||||
#include "images.h"
|
||||
#include "mock_property_fetcher.h"
|
||||
#include "reader.h"
|
||||
#include "test_partition_opener.h"
|
||||
#include "utility.h"
|
||||
|
@ -34,6 +36,8 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace android::fs_mgr;
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using unique_fd = android::base::unique_fd;
|
||||
|
||||
// Our tests assume a 128KiB disk with two 512 byte metadata slots.
|
||||
|
@ -664,7 +668,8 @@ TEST(liblp, AutoSlotSuffixing) {
|
|||
}
|
||||
|
||||
TEST(liblp, UpdateRetrofit) {
|
||||
MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(true);
|
||||
ON_CALL(*GetMockedInstance(), GetBoolProperty("ro.boot.dynamic_partitions_retrofit", _))
|
||||
.WillByDefault(Return(true));
|
||||
|
||||
unique_ptr<MetadataBuilder> builder = CreateDefaultBuilder();
|
||||
ASSERT_NE(builder, nullptr);
|
||||
|
@ -695,7 +700,8 @@ TEST(liblp, UpdateRetrofit) {
|
|||
}
|
||||
|
||||
TEST(liblp, UpdateNonRetrofit) {
|
||||
MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false);
|
||||
ON_CALL(*GetMockedInstance(), GetBoolProperty("ro.boot.dynamic_partitions_retrofit", _))
|
||||
.WillByDefault(Return(false));
|
||||
|
||||
unique_fd fd = CreateFlashedDisk();
|
||||
ASSERT_GE(fd, 0);
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include <liblp/property_fetcher.h>
|
||||
|
||||
namespace android {
|
||||
namespace fs_mgr {
|
||||
|
||||
class MockPropertyFetcher : public IPropertyFetcher {
|
||||
public:
|
||||
MOCK_METHOD2(GetProperty, std::string(const std::string&, const std::string&));
|
||||
MOCK_METHOD2(GetBoolProperty, bool(const std::string&, bool));
|
||||
|
||||
// By default, return default_value for all functions.
|
||||
MockPropertyFetcher() {
|
||||
using ::testing::_;
|
||||
using ::testing::Invoke;
|
||||
ON_CALL(*this, GetProperty(_, _)).WillByDefault(Invoke([](const auto&, const auto& def) {
|
||||
return def;
|
||||
}));
|
||||
ON_CALL(*this, GetBoolProperty(_, _)).WillByDefault(Invoke([](const auto&, auto def) {
|
||||
return def;
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace fs_mgr
|
||||
} // namespace android
|
||||
|
||||
android::fs_mgr::MockPropertyFetcher* GetMockedInstance();
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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 "liblp/property_fetcher.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <android-base/properties.h>
|
||||
|
||||
namespace android {
|
||||
namespace fs_mgr {
|
||||
|
||||
std::string PropertyFetcher::GetProperty(const std::string& key, const std::string& default_value) {
|
||||
return android::base::GetProperty(key, default_value);
|
||||
}
|
||||
|
||||
bool PropertyFetcher::GetBoolProperty(const std::string& key, bool default_value) {
|
||||
return android::base::GetBoolProperty(key, default_value);
|
||||
}
|
||||
|
||||
static std::unique_ptr<IPropertyFetcher>* GetInstanceAllocation() {
|
||||
static std::unique_ptr<IPropertyFetcher> instance = std::make_unique<PropertyFetcher>();
|
||||
return &instance;
|
||||
}
|
||||
|
||||
IPropertyFetcher* IPropertyFetcher::GetInstance() {
|
||||
return GetInstanceAllocation()->get();
|
||||
}
|
||||
|
||||
void IPropertyFetcher::OverrideForTesting(std::unique_ptr<IPropertyFetcher>&& fetcher) {
|
||||
GetInstanceAllocation()->swap(fetcher);
|
||||
fetcher.reset();
|
||||
}
|
||||
|
||||
} // namespace fs_mgr
|
||||
} // namespace android
|
Loading…
Reference in New Issue