blob: 4a94bfb90aa3ee4b6d636a0342ea50e3f5c10003 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fidl/fuchsia.hardware.block.partition/cpp/wire.h>
#include <fuchsia/hardware/block/driver/c/banjo.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/device-watcher/cpp/device-watcher.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fit/defer.h>
#include <stdlib.h>
#include <unistd.h>
#include <zircon/status.h>
#include <zircon/types.h>
#include <unordered_map>
#include <fbl/string.h>
#include <fbl/unique_fd.h>
#include <gpt/c/gpt.h>
#include <gpt/guid.h>
#include <zxtest/base/log-sink.h>
#include <zxtest/zxtest.h>
#include "src/lib/fsl/io/device_watcher.h"
namespace fuchsia_partition = fuchsia_hardware_block_partition;
using device_watcher::RecursiveWaitForFile;
#define DEV_BLOCK "/dev/class/block"
class PartitionMappingTest : public zxtest::Test {
protected:
static void ScanBlockAndValidateMapping(
const std::unordered_map<std::string, std::string>& mapping) {
fbl::unique_fd devfs_root(open(DEV_BLOCK, O_RDONLY));
ASSERT_TRUE(devfs_root);
struct dirent* de;
DIR* dir = opendir(DEV_BLOCK);
ASSERT_NOT_NULL(dir);
auto cleanup = fit::defer([&dir]() { closedir(dir); });
while ((de = readdir(dir)) != nullptr) {
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
continue;
}
zx::result channel = RecursiveWaitForFile(devfs_root.get(), de->d_name);
EXPECT_OK(channel.status_value(), "%s/%s", DEV_BLOCK, de->d_name);
fidl::ClientEnd<fuchsia_partition::Partition> client_end(std::move(channel.value()));
std::string partition_name = GetLabel(client_end);
if (mapping.count(partition_name)) {
std::string expected_type = mapping.at(partition_name);
EXPECT_EQ(GetType(client_end), expected_type);
}
}
}
static std::string GetType(const fidl::ClientEnd<fuchsia_partition::Partition>& client_end) {
auto guid_resp = fidl::WireCall(client_end)->GetTypeGuid();
if (guid_resp.ok() && guid_resp->status == ZX_OK && guid_resp->guid) {
return gpt::KnownGuid::TypeDescription(guid_resp->guid->value.data());
}
return {};
}
static std::string GetLabel(const fidl::ClientEnd<fuchsia_partition::Partition>& client_end) {
auto name_resp = fidl::WireCall(client_end)->GetName();
if (name_resp.ok() && name_resp->status == ZX_OK) {
return std::string(name_resp->name.data(), name_resp->name.size());
}
return {};
}
};
TEST_F(PartitionMappingTest, NelsonPartitionMapping) {
std::unordered_map<std::string, std::string> mapping = {
{"misc", "misc"}, {"boot_a", "zircon-a"}, {"boot_b", "zircon-b"},
{"cache", "zircon-r"}, {"zircon_r", "zircon-r"}, {"vbmeta_a", "vbmeta_a"},
{"vbmeta_b", "vbmeta_b"}, {"reserved_c", "vbmeta_r"}, {"vbmeta_r", "vbmeta_r"},
{"fvm", "fuchsia-fvm"},
};
ScanBlockAndValidateMapping(mapping);
}