blob: fe14f79c7fe45adc6a13f7c1c8c31f86a98cd63d [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.
#include <lib/ddk/binding_driver.h>
#include <lib/ddk/debug.h>
#include <lib/ddk/device.h>
#include <lib/ddk/driver.h>
#include <limits.h>
#include <zxtest/zxtest.h>
namespace {
zx_device_t* ddk_test_dev;
const char* TEST_STRING = "testing 1 2 3";
TEST(MetadataTest, AddMetadata) {
char buffer[32] = {};
zx_status_t status;
size_t actual;
status = device_get_metadata(ddk_test_dev, 1, buffer, sizeof(buffer), &actual);
ASSERT_EQ(status, ZX_ERR_NOT_FOUND, "device_get_metadata did not return ZX_ERR_NOT_FOUND");
status = device_get_metadata_size(ddk_test_dev, 1, &actual);
ASSERT_EQ(status, ZX_ERR_NOT_FOUND, "device_get_metadata_size should return ZX_ERR_NOT_FOUND");
status = device_add_metadata(ddk_test_dev, 1, TEST_STRING, strlen(TEST_STRING) + 1);
ASSERT_EQ(status, ZX_OK, "device_add_metadata failed");
status = device_get_metadata_size(ddk_test_dev, 1, &actual);
ASSERT_EQ(strlen(TEST_STRING) + 1, actual, "Incorrect output length was returned.");
status = device_get_metadata(ddk_test_dev, 1, buffer, sizeof(buffer), &actual);
ASSERT_EQ(status, ZX_OK, "device_get_metadata failed");
ASSERT_EQ(actual, strlen(TEST_STRING) + 1, "");
ASSERT_EQ(strcmp(buffer, TEST_STRING), 0, "");
}
TEST(MetadataTest, AddMetadataLargeInput) {
size_t large_len = 1024u * 16;
auto large = std::make_unique<char[]>(large_len);
zx_status_t status = device_add_metadata(ddk_test_dev, 1, large.get(), large_len);
EXPECT_EQ(status, ZX_ERR_INVALID_ARGS, "device_add_metadata should return ZX_ERR_INVALID_ARGS");
}
TEST(MetadataTest, GetMetadataWouldOverflow) {
char buffer[32] = {};
zx_status_t status;
size_t actual;
status = device_add_metadata(ddk_test_dev, 2, TEST_STRING, strlen(TEST_STRING) + 1);
ASSERT_EQ(status, ZX_OK, "");
status = device_get_metadata(ddk_test_dev, 2, buffer, 1, &actual);
ASSERT_EQ(status, ZX_ERR_BUFFER_TOO_SMALL, "device_get_metadata overflowed buffer");
}
// A special LogSink that just redirects all output to zxlogf
class LogSink : public zxtest::LogSink {
public:
void Write(const char* format, ...) override {
std::array<char, 1024> line_buf;
va_list args;
va_start(args, format);
vsnprintf(line_buf.data(), line_buf.size(), format, args);
va_end(args);
line_buf[line_buf.size() - 1] = 0;
zxlogf(INFO, "%s", line_buf.data());
}
void Flush() override {}
};
zx_status_t metadata_test_bind(void* ctx, zx_device_t* parent) {
zxtest::Runner::GetInstance()->mutable_reporter()->set_log_sink(std::make_unique<LogSink>());
ddk_test_dev = parent;
if (RUN_ALL_TESTS(0, nullptr) != 0) {
return ZX_ERR_BAD_STATE;
}
static zx_protocol_device_t proto = {
.version = DEVICE_OPS_VERSION,
.release = [](void* ctx) {},
};
device_add_args_t args = {
.version = DEVICE_ADD_ARGS_VERSION,
.name = "temp",
.ctx = parent,
.ops = &proto,
};
zx_device_t* out_device;
return device_add(parent, &args, &out_device);
}
static zx_driver_ops_t metadata_test_driver_ops = {
.version = DRIVER_OPS_VERSION,
.bind = metadata_test_bind,
};
} // namespace
ZIRCON_DRIVER(metadata_test, metadata_test_driver_ops, "zircon", "0.1");