Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04d91871 authored by Yifan Hong's avatar Yifan Hong
Browse files

liblp: Add PropertyFetcher.

Use dependency injection so that GetProperty / GetBoolProperty
can be mocked in tests.

Test: run liblp_test_static
Change-Id: I8efa85fbbd7aebce2541f748f840e512f3729c30
parent 0d061b25
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,7 @@ cc_library {
        "builder.cpp",
        "builder.cpp",
        "images.cpp",
        "images.cpp",
        "partition_opener.cpp",
        "partition_opener.cpp",
        "property_fetcher.cpp",
        "reader.cpp",
        "reader.cpp",
        "utility.cpp",
        "utility.cpp",
        "writer.cpp",
        "writer.cpp",
+4 −20
Original line number Original line Diff line number Diff line
@@ -21,19 +21,16 @@
#include <algorithm>
#include <algorithm>
#include <string_view>
#include <string_view>


#include <android-base/properties.h>
#include <android-base/unique_fd.h>
#include <android-base/unique_fd.h>


#include "liblp/liblp.h"
#include "liblp/liblp.h"
#include "liblp/property_fetcher.h"
#include "reader.h"
#include "reader.h"
#include "utility.h"
#include "utility.h"


namespace android {
namespace android {
namespace fs_mgr {
namespace fs_mgr {


std::optional<bool> MetadataBuilder::sABOverride;
std::optional<bool> MetadataBuilder::sRetrofitDap;

static constexpr std::string_view kDefaultGroup = "default";
static constexpr std::string_view kDefaultGroup = "default";


bool LinearExtent::AddTo(LpMetadata* out) const {
bool LinearExtent::AddTo(LpMetadata* out) const {
@@ -211,14 +208,6 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::NewForUpdate(const IPartitionO
    return New(*metadata.get(), &opener);
    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) {
MetadataBuilder::MetadataBuilder() : auto_slot_suffixing_(false) {
    memset(&geometry_, 0, sizeof(geometry_));
    memset(&geometry_, 0, sizeof(geometry_));
    geometry_.magic = LP_METADATA_GEOMETRY_MAGIC;
    geometry_.magic = LP_METADATA_GEOMETRY_MAGIC;
@@ -1051,17 +1040,12 @@ void MetadataBuilder::SetAutoSlotSuffixing() {
}
}


bool MetadataBuilder::IsABDevice() {
bool MetadataBuilder::IsABDevice() {
    if (sABOverride.has_value()) {
    return !IPropertyFetcher::GetInstance()->GetProperty("ro.boot.slot_suffix", "").empty();
        return *sABOverride;
    }
    return !android::base::GetProperty("ro.boot.slot_suffix", "").empty();
}
}


bool MetadataBuilder::IsRetrofitDynamicPartitionsDevice() {
bool MetadataBuilder::IsRetrofitDynamicPartitionsDevice() {
    if (sRetrofitDap.has_value()) {
    return IPropertyFetcher::GetInstance()->GetBoolProperty("ro.boot.dynamic_partitions_retrofit",
        return *sRetrofitDap;
                                                            false);
    }
    return android::base::GetBoolProperty("ro.boot.dynamic_partitions_retrofit", false);
}
}


bool MetadataBuilder::IsRetrofitMetadata() const {
bool MetadataBuilder::IsRetrofitMetadata() const {
+20 −14
Original line number Original line Diff line number Diff line
@@ -19,36 +19,40 @@
#include <gtest/gtest.h>
#include <gtest/gtest.h>
#include <liblp/builder.h>
#include <liblp/builder.h>


#include "mock_property_fetcher.h"
#include "utility.h"
#include "utility.h"


using namespace std;
using namespace std;
using namespace android::fs_mgr;
using namespace android::fs_mgr;
using ::android::fs_mgr::MockPropertyFetcher;
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::ElementsAre;
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 {
class Environment : public ::testing::Environment {
  public:
  public:
    void SetUp() override {
    void SetUp() override { ResetPropertyFetcher(); }
        MetadataBuilder::OverrideABForTesting(false);
        MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false);
    }
};
};


int main(int argc, char** argv) {
int main(int argc, char** argv) {
    ::testing::AddGlobalTestEnvironment(new Environment);
    ::testing::InitGoogleTest(&argc, argv);
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
    return RUN_ALL_TESTS();
}
}


class BuilderTest : public ::testing::Test {
class BuilderTest : public ::testing::Test {
  public:
  public:
    void SetUp() override {
    void SetUp() override { ResetPropertyFetcher(); }
        MetadataBuilder::OverrideABForTesting(false);
    void TearDown() override { ResetPropertyFetcher(); }
        MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false);
    }
    void TearDown() override {
        MetadataBuilder::OverrideABForTesting(false);
        MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false);
    }
};
};


TEST_F(BuilderTest, BuildBasic) {
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,
    // A and B slots should be allocated from separate halves of the partition,
    // to mitigate allocating too many extents. (b/120433288)
    // 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);
    auto builder = MetadataBuilder::New(device_info, 65536, 2);
    ASSERT_NE(builder, nullptr);
    ASSERT_NE(builder, nullptr);
    Partition* system_a = builder->AddPartition("system_a", 0);
    Partition* system_a = builder->AddPartition("system_a", 0);
+0 −9
Original line number Original line Diff line number Diff line
@@ -196,12 +196,6 @@ class MetadataBuilder {
        return New(device_info, metadata_max_size, metadata_slot_count);
        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
    // Define a new partition group. By default there is one group called
    // "default", with an unrestricted size. A non-zero size will restrict the
    // "default", with an unrestricted size. A non-zero size will restrict the
    // total space used by all partitions in the group.
    // total space used by all partitions in the group.
@@ -347,9 +341,6 @@ class MetadataBuilder {
                                                    const std::vector<Interval>& free_list,
                                                    const std::vector<Interval>& free_list,
                                                    uint64_t sectors_needed) const;
                                                    uint64_t sectors_needed) const;


    static std::optional<bool> sABOverride;
    static std::optional<bool> sRetrofitDap;

    LpMetadataGeometry geometry_;
    LpMetadataGeometry geometry_;
    LpMetadataHeader header_;
    LpMetadataHeader header_;
    std::vector<std::unique_ptr<Partition>> partitions_;
    std::vector<std::unique_ptr<Partition>> partitions_;
+42 −0
Original line number Original line Diff line number Diff line
//
// 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
Loading