blob: 8b3c28c6571a1af23313ac3595eb61ebecc3ff17 [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 <limits.h>
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.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 shoud return ZX_ERR_INVALID_ARGS");
}
TEST(MetadataTest, PublishMetadata) {
char buffer[32] = {};
zx_status_t status;
size_t actual;
// This should fail since the path does not match us or our potential children.
status = device_publish_metadata(ddk_test_dev, "/dev/misc/null", 2, TEST_STRING,
strlen(TEST_STRING) + 1);
ASSERT_EQ(status, ZX_ERR_ACCESS_DENIED, "");
// We are allowed to add metadata to own path.
status = device_publish_metadata(ddk_test_dev, "/dev/test/test", 2, TEST_STRING,
strlen(TEST_STRING) + 1);
ASSERT_EQ(status, ZX_OK, "");
status = device_get_metadata(ddk_test_dev, 2, 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, "");
// We are allowed to add metadata to our potential children.
status = device_publish_metadata(ddk_test_dev, "/dev/test/test/child", 2, TEST_STRING,
strlen(TEST_STRING) + 1);
ASSERT_EQ(status, ZX_OK, "");
}
TEST(MetadataTest, PublishMetadataLargeInput) {
size_t large_len = 1024u * 16;
auto large = std::make_unique<char[]>(large_len);
zx_status_t status =
device_publish_metadata(ddk_test_dev, "/dev/test/test/child", 2, large.get(), large_len);
EXPECT_EQ(status, ZX_ERR_INVALID_ARGS, "device_add_metadata shoud return ZX_ERR_INVALID_ARGS");
}
TEST(MetadataTest, GetMetadataWouldOverflow) {
char buffer[32] = {};
zx_status_t status;
size_t actual;
status = device_publish_metadata(ddk_test_dev, "/dev/test/test", 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) {
zxlogf(ERROR, "HERE IN BIND");
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;
}
return ZX_OK;
}
static zx_driver_ops_t metadata_test_driver_ops = {
.version = DRIVER_OPS_VERSION,
.bind = metadata_test_bind,
};
} // namespace
// clang-format off
ZIRCON_DRIVER_BEGIN(metadata_test, metadata_test_driver_ops, "zircon", "0.1", 2)
BI_ABORT_IF_AUTOBIND,
BI_MATCH(),
ZIRCON_DRIVER_END(metadata_test)