blob: 31bddcfbcdb94098a9f3752444f0a5a0f37c62b2 [file] [log] [blame]
// Copyright 2018 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.
#pragma once
#include <limits.h>
#include <stddef.h>
#include <fbl/macros.h>
#include <fbl/unique_fd.h>
#include <zircon/types.h>
#include <fbl/vector.h>
namespace blkctl {
namespace testing {
constexpr size_t kBlockCount = 512;
constexpr size_t kBlockSize = 512;
constexpr size_t kSliceSize = 8192;
constexpr size_t kSliceCount = (kBlockCount * kBlockSize) / kSliceSize;
// |ScopedDevice| is the base class for creating block devices during testing that will
// automatically clean up on test completion.
class ScopedDevice {
public:
ScopedDevice() : path_{0} {}
virtual ~ScopedDevice() {}
const char* path() const { return path_; }
// Sets up the device.
virtual bool Init(fbl::unique_fd* out = nullptr) = 0;
protected:
// Saves the topological path of the device referred to by |fd| and wraps that argument in a
// unique_fd.
bool Set(int fd, fbl::unique_fd* out);
// Waits for a |child| driver to bind to the |parent| device, then opens it and returns the
// unique_fd via |out|.
bool Open(const char* parent, const char* child, fbl::unique_fd* out);
private:
DISALLOW_COPY_ASSIGN_AND_MOVE(ScopedDevice);
// Topological path of this device
char path_[PATH_MAX];
};
// |ScopedRamdisk| creates a ramdisk that is destroyed when the object goes out of scope.
class ScopedRamdisk final : public ScopedDevice {
public:
ScopedRamdisk() : size_(0) {}
~ScopedRamdisk() override;
size_t size() const { return size_; }
// Creates the ramdisk
bool Init(fbl::unique_fd* out = nullptr) override;
private:
// Size of the ramdisk, in bytes
size_t size_;
};
// |ScopedRamdisk| creates an FVM volume backed by a ramdisk that is destroyed when the object goes
// out of scope.
class ScopedFvmVolume final : public ScopedDevice {
public:
ScopedFvmVolume() : slices_(0) {}
const ScopedRamdisk& ramdisk() const { return ramdisk_; }
size_t slices() const { return slices_; }
// Creates the ramdisk and FVM volume
bool Init(fbl::unique_fd* out = nullptr) override;
private:
// Ramdisk backing this FVM volume
ScopedRamdisk ramdisk_;
// Number of allocatable slices in the volume
size_t slices_;
};
// |ScopedRamdisk| creates an FVM partition that has half the slices of a created FVM volume backed
// by a ramdisk that is destroyed when the object goes out of scope.
class ScopedFvmPartition : public ScopedDevice {
public:
ScopedFvmPartition() {}
const ScopedFvmVolume& volume() const { return volume_; }
size_t slices() const { return slices_; }
// Creates the ramdisk, FVM volume, and partition
bool Init(fbl::unique_fd* out = nullptr) override;
private:
// FVM volume containing this partition
ScopedFvmVolume volume_;
// Number of slices initially allocated to this partition
size_t slices_;
};
// Prints formatted command line arguments to |buf| using |fmt| and the trailing arguments, then
// breaks them up into individual arguments returned via |out|. Useful for creating "argv" from
// printf-style arguments that can be passed to |Command::Parse|.
bool SplitArgs(fbl::Vector<char*>* out, char* buf, size_t buf_len, const char* fmt, ...);
// Produces a formatted command line from |fmt| and the trailing arguments, then parses and runs it.
// If parsing returns an error, it it checked against |expected|, otherwise the result of running it
// is checked.
bool ParseAndRun(zx_status_t expected, const char* fmt, ...);
} // namespace testing
} // namespace blkctl