blob: 1645e5c8cdfbd11ac242d1fda2ce093b770fd73c [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 "../block.h"
#include <lib/fake_ddk/fake_ddk.h>
#include <fbl/string.h>
#include <zxtest/zxtest.h>
#include "../usb-mass-storage.h"
namespace {
struct Context {
ums::UmsBlockDevice* dev;
fbl::String name;
block_info_t info;
block_op_t* op;
zx_status_t status;
ums::Transaction* txn;
};
class Binder : public fake_ddk::Bind {
public:
zx_status_t DeviceRemove(zx_device_t* dev) {
Context* context = reinterpret_cast<Context*>(dev);
context->dev->DdkRelease();
return ZX_OK;
}
zx_status_t DeviceAdd(zx_driver_t* drv, zx_device_t* parent, device_add_args_t* args,
zx_device_t** out) {
*out = parent;
Context* context = reinterpret_cast<Context*>(parent);
context->name = fbl::String(args->name);
return ZX_OK;
}
};
static void BlockCallback(void* ctx, zx_status_t status, block_op_t* op) {
Context* context = reinterpret_cast<Context*>(ctx);
context->status = status;
context->op = op;
}
TEST(UmsBlock, ConstructorTest) {
Binder ddk;
Context context;
ums::UmsBlockDevice dev(reinterpret_cast<zx_device_t*>(&context), 5,
[&](ums::Transaction* txn) { context.txn = txn; });
context.dev = &dev;
ums::BlockDeviceParameters params = {};
params.lun = 5;
EXPECT_TRUE(params == dev.GetBlockDeviceParameters(),
"Parameters must be set to user-provided values.");
dev.Adopt();
EXPECT_TRUE(dev.Release(), "Expected to free the device");
}
TEST(UmsBlock, AddTest) {
Binder ddk;
Context context;
auto fake_zxdev = reinterpret_cast<zx_device_t*>(&context);
ums::UmsBlockDevice dev(fake_zxdev, 5,
[&](ums::Transaction* txn) { context.txn = txn; });
context.dev = &dev;
ums::BlockDeviceParameters params = {};
params.lun = 5;
EXPECT_TRUE(params == dev.GetBlockDeviceParameters(),
"Parameters must be set to user-provided values.");
dev.Adopt();
EXPECT_EQ(ZX_OK, dev.Add(), "Expected Add to succeed");
dev.DdkUnbind(ddk::UnbindTxn(fake_zxdev));
EXPECT_TRUE(dev.Release(), "Expected to free the device");
}
TEST(UmsBlock, GetSizeTest) {
Binder ddk;
Context context;
auto fake_zxdev = reinterpret_cast<zx_device_t*>(&context);
ums::UmsBlockDevice dev(fake_zxdev, 5, [&](ums::Transaction* txn) { context.txn = txn; });
context.dev = &dev;
ums::BlockDeviceParameters params = {};
params.lun = 5;
dev.Adopt();
EXPECT_TRUE(params == dev.GetBlockDeviceParameters(),
"Parameters must be set to user-provided values.");
EXPECT_EQ(ZX_OK, dev.Add(), "Expected Add to succeed");
EXPECT_TRUE(fbl::String("lun-005") == context.name);
params = dev.GetBlockDeviceParameters();
params.block_size = 15;
params.total_blocks = 700;
context.info.block_size = params.block_size;
context.info.block_count = params.total_blocks;
dev.SetBlockDeviceParameters(params);
EXPECT_EQ(params.block_size * params.total_blocks, dev.DdkGetSize());
dev.DdkUnbind(ddk::UnbindTxn(fake_zxdev));
EXPECT_TRUE(dev.Release(), "Expected to free the device");
}
TEST(UmsBlock, NotSupportedTest) {
Binder ddk;
Context context;
auto fake_zxdev = reinterpret_cast<zx_device_t*>(&context);
ums::UmsBlockDevice dev(fake_zxdev, 5, [&](ums::Transaction* txn) { context.txn = txn; });
context.dev = &dev;
dev.Adopt();
EXPECT_EQ(ZX_OK, dev.Add(), "Expected Add to succeed");
EXPECT_TRUE(fbl::String("lun-005") == context.name);
ums::Transaction txn;
txn.op.command = BLOCK_OP_MASK;
dev.BlockImplQueue(&txn.op, BlockCallback, &context);
EXPECT_EQ(ZX_ERR_NOT_SUPPORTED, context.status);
dev.DdkUnbind(ddk::UnbindTxn(fake_zxdev));
EXPECT_TRUE(dev.Release(), "Expected to free the device");
}
TEST(UmsBlock, ReadTest) {
Binder ddk;
Context context;
auto fake_zxdev = reinterpret_cast<zx_device_t*>(&context);
ums::UmsBlockDevice dev(fake_zxdev, 5, [&](ums::Transaction* txn) { context.txn = txn; });
context.dev = &dev;
dev.Adopt();
EXPECT_EQ(ZX_OK, dev.Add(), "Expected Add to succeed");
EXPECT_TRUE(fbl::String("lun-005") == context.name);
ums::Transaction txn;
txn.op.command = BLOCK_OP_READ;
dev.BlockImplQueue(&txn.op, BlockCallback, &context);
dev.DdkUnbind(ddk::UnbindTxn(fake_zxdev));
EXPECT_TRUE(dev.Release(), "Expected to free the device");
}
TEST(UmsBlock, WriteTest) {
Binder ddk;
Context context;
auto fake_zxdev = reinterpret_cast<zx_device_t*>(&context);
ums::UmsBlockDevice dev(fake_zxdev, 5, [&](ums::Transaction* txn) { context.txn = txn; });
context.dev = &dev;
dev.Adopt();
EXPECT_EQ(ZX_OK, dev.Add(), "Expected Add to succeed");
EXPECT_TRUE(fbl::String("lun-005") == context.name);
ums::Transaction txn;
txn.op.command = BLOCK_OP_WRITE;
dev.BlockImplQueue(&txn.op, BlockCallback, &context);
EXPECT_EQ(&txn, context.txn);
dev.DdkUnbind(ddk::UnbindTxn(fake_zxdev));
EXPECT_TRUE(dev.Release(), "Expected to free the device");
}
TEST(UmsBlock, FlushTest) {
Binder ddk;
Context context;
auto fake_zxdev = reinterpret_cast<zx_device_t*>(&context);
ums::UmsBlockDevice dev(fake_zxdev, 5, [&](ums::Transaction* txn) { context.txn = txn; });
context.dev = &dev;
dev.Adopt();
EXPECT_EQ(ZX_OK, dev.Add(), "Expected Add to succeed");
EXPECT_TRUE(fbl::String("lun-005") == context.name);
ums::Transaction txn;
txn.op.command = BLOCK_OP_FLUSH;
dev.BlockImplQueue(&txn.op, BlockCallback, &context);
EXPECT_EQ(&txn, context.txn);
dev.DdkUnbind(ddk::UnbindTxn(fake_zxdev));
EXPECT_TRUE(dev.Release(), "Expected to free the device");
}
} // namespace