blob: 50b4a4e5defed8fabcaef6592511ee7f52cc82c1 [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 <fuchsia/hardware/block/partition/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/devmgr-integration-test/fixture.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/device/block.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 devmgr_integration_test::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;
}
fbl::unique_fd fd;
EXPECT_OK(RecursiveWaitForFile(devfs_root, de->d_name, &fd), "%s/%s", DEV_BLOCK, de->d_name);
ASSERT_TRUE(fd);
fdio_cpp::FdioCaller caller(std::move(fd));
std::string partition_name = GetLabel(caller);
if (mapping.count(partition_name)) {
std::string expected_type = mapping.at(partition_name);
EXPECT_EQ(GetType(caller), expected_type);
}
}
}
static std::string GetType(const fdio_cpp::FdioCaller& caller) {
auto guid_resp = fidl::WireCall<fuchsia_partition::Partition>(
fidl::UnownedClientEnd<fuchsia_partition::Partition>(caller.channel()))
.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 fdio_cpp::FdioCaller& caller) {
auto name_resp = fidl::WireCall<fuchsia_partition::Partition>(
fidl::UnownedClientEnd<fuchsia_partition::Partition>(caller.channel()))
.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);
}