blob: f2b0184392d5dc9ca3c6be990b4ce4c33def41e3 [file] [log] [blame]
// Copyright 2016 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 <assert.h>
#include <stdio.h>
#include <zx/channel.h>
#include <zx/event.h>
#include <zx/eventpair.h>
#include <zx/handle.h>
#include <zx/job.h>
#include <zx/port.h>
#include <zx/process.h>
#include <zx/socket.h>
#include <zx/thread.h>
#include <zx/time.h>
#include <zx/vmar.h>
#include <fbl/type_support.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/syscalls/port.h>
#include <unistd.h>
#include <unittest/unittest.h>
static zx_status_t validate_handle(zx_handle_t handle) {
return zx_object_get_info(handle, ZX_INFO_HANDLE_VALID, 0, NULL, 0u, NULL);
}
static bool handle_invalid_test() {
BEGIN_TEST;
zx::handle handle;
// A default constructed handle is invalid.
ASSERT_EQ(handle.release(), ZX_HANDLE_INVALID);
END_TEST;
}
static bool handle_close_test() {
BEGIN_TEST;
zx_handle_t raw_event;
ASSERT_EQ(zx_event_create(0u, &raw_event), ZX_OK);
ASSERT_EQ(validate_handle(raw_event), ZX_OK);
{
zx::handle handle(raw_event);
}
// Make sure the handle was closed.
ASSERT_EQ(validate_handle(raw_event), ZX_ERR_BAD_HANDLE);
END_TEST;
}
static bool handle_move_test() {
BEGIN_TEST;
zx::event event;
// Check move semantics.
ASSERT_EQ(zx::event::create(0u, &event), ZX_OK);
zx::handle handle(fbl::move(event));
ASSERT_EQ(event.release(), ZX_HANDLE_INVALID);
ASSERT_EQ(validate_handle(handle.get()), ZX_OK);
END_TEST;
}
static bool handle_duplicate_test() {
BEGIN_TEST;
zx_handle_t raw_event;
zx::handle dup;
ASSERT_EQ(zx_event_create(0u, &raw_event), ZX_OK);
zx::handle handle(raw_event);
ASSERT_EQ(handle.duplicate(ZX_RIGHT_SAME_RIGHTS, &dup), ZX_OK);
// The duplicate must be valid as well as the original.
ASSERT_EQ(validate_handle(dup.get()), ZX_OK);
ASSERT_EQ(validate_handle(raw_event), ZX_OK);
END_TEST;
}
static bool handle_replace_test() {
BEGIN_TEST;
zx_handle_t raw_event;
zx::handle rep;
ASSERT_EQ(zx_event_create(0u, &raw_event), ZX_OK);
{
zx::handle handle(raw_event);
ASSERT_EQ(handle.replace(ZX_RIGHT_SAME_RIGHTS, &rep), ZX_OK);
ASSERT_EQ(handle.release(), ZX_HANDLE_INVALID);
}
// The original shoould be invalid and the replacement should be valid.
ASSERT_EQ(validate_handle(raw_event), ZX_ERR_BAD_HANDLE);
ASSERT_EQ(validate_handle(rep.get()), ZX_OK);
END_TEST;
}
static bool event_test() {
BEGIN_TEST;
zx::event event;
ASSERT_EQ(zx::event::create(0u, &event), ZX_OK);
ASSERT_EQ(validate_handle(event.get()), ZX_OK);
// TODO(cpu): test more.
END_TEST;
}
static bool event_duplicate_test() {
BEGIN_TEST;
zx::event event;
zx::event dup;
ASSERT_EQ(zx::event::create(0u, &event), ZX_OK);
ASSERT_EQ(event.duplicate(ZX_RIGHT_SAME_RIGHTS, &dup), ZX_OK);
// The duplicate must be valid as well as the original.
ASSERT_EQ(validate_handle(dup.get()), ZX_OK);
ASSERT_EQ(validate_handle(event.get()), ZX_OK);
END_TEST;
}
static bool channel_test() {
BEGIN_TEST;
zx::channel channel[2];
ASSERT_EQ(zx::channel::create(0u, &channel[0], &channel[1]), ZX_OK);
ASSERT_EQ(validate_handle(channel[0].get()), ZX_OK);
ASSERT_EQ(validate_handle(channel[1].get()), ZX_OK);
// TODO(cpu): test more.
END_TEST;
}
static bool socket_test() {
BEGIN_TEST;
zx::socket socket[2];
ASSERT_EQ(zx::socket::create(0u, &socket[0], &socket[1]), ZX_OK);
ASSERT_EQ(validate_handle(socket[0].get()), ZX_OK);
ASSERT_EQ(validate_handle(socket[1].get()), ZX_OK);
// TODO(cpu): test more.
END_TEST;
}
static bool eventpair_test() {
BEGIN_TEST;
zx::eventpair evpair[2];
ASSERT_EQ(zx::eventpair::create(0u, &evpair[0], &evpair[1]), ZX_OK);
ASSERT_EQ(validate_handle(evpair[0].get()), ZX_OK);
ASSERT_EQ(validate_handle(evpair[1].get()), ZX_OK);
// TODO(cpu): test more.
END_TEST;
}
static bool vmar_test() {
BEGIN_TEST;
zx::vmar vmar;
const size_t size = getpagesize();
uintptr_t addr;
ASSERT_EQ(zx::vmar::root_self().allocate(0u, size, ZX_VM_FLAG_CAN_MAP_READ, &vmar, &addr),
ZX_OK);
ASSERT_EQ(validate_handle(vmar.get()), ZX_OK);
ASSERT_EQ(vmar.destroy(), ZX_OK);
// TODO(teisenbe): test more.
END_TEST;
}
static bool port_test() {
BEGIN_TEST;
zx::port port;
ASSERT_EQ(zx::port::create(0, &port), ZX_OK);
ASSERT_EQ(validate_handle(port.get()), ZX_OK);
zx::channel channel[2];
auto key = 1111ull;
ASSERT_EQ(zx::channel::create(0u, &channel[0], &channel[1]), ZX_OK);
ASSERT_EQ(channel[0].wait_async(
port, key, ZX_CHANNEL_READABLE, ZX_WAIT_ASYNC_ONCE), ZX_OK);
ASSERT_EQ(channel[1].write(0u, "12345", 5, nullptr, 0u), ZX_OK);
zx_port_packet_t packet = {};
ASSERT_EQ(port.wait(0ull, &packet, 0u), ZX_OK);
ASSERT_EQ(packet.key, key);
ASSERT_EQ(packet.type, ZX_PKT_TYPE_SIGNAL_ONE);
ASSERT_EQ(packet.signal.count, 1u);
END_TEST;
}
static bool time_test() {
BEGIN_TEST;
// Just a smoke test
ASSERT_GE(zx::deadline_after(10), 10);
END_TEST;
}
template <typename T>
static bool reference_thing(const T& p) {
BEGIN_HELPER;
ASSERT_TRUE(static_cast<bool>(p), "invalid handle");
END_HELPER;
}
static bool thread_self_test() {
BEGIN_TEST;
zx_handle_t raw = zx_thread_self();
ASSERT_EQ(validate_handle(raw), ZX_OK);
EXPECT_TRUE(reference_thing<zx::thread>(zx::thread::self()));
EXPECT_EQ(validate_handle(raw), ZX_OK);
// This does not compile:
//const zx::thread self = zx::thread::self();
END_TEST;
}
static bool process_self_test() {
BEGIN_TEST;
zx_handle_t raw = zx_process_self();
ASSERT_EQ(validate_handle(raw), ZX_OK);
EXPECT_TRUE(reference_thing<zx::process>(zx::process::self()));
EXPECT_EQ(validate_handle(raw), ZX_OK);
// This does not compile:
//const zx::process self = zx::process::self();
END_TEST;
}
static bool vmar_root_self_test() {
BEGIN_TEST;
zx_handle_t raw = zx_vmar_root_self();
ASSERT_EQ(validate_handle(raw), ZX_OK);
EXPECT_TRUE(reference_thing<zx::vmar>(zx::vmar::root_self()));
EXPECT_EQ(validate_handle(raw), ZX_OK);
// This does not compile:
//const zx::vmar root_self = zx::vmar::root_self();
END_TEST;
}
static bool job_default_test() {
BEGIN_TEST;
zx_handle_t raw = zx_job_default();
ASSERT_EQ(validate_handle(raw), ZX_OK);
EXPECT_TRUE(reference_thing<zx::job>(zx::job::default_job()));
EXPECT_EQ(validate_handle(raw), ZX_OK);
// This does not compile:
//const zx::job default_job = zx::job::default_job();
END_TEST;
}
BEGIN_TEST_CASE(libmx_tests)
RUN_TEST(handle_invalid_test)
RUN_TEST(handle_close_test)
RUN_TEST(handle_move_test)
RUN_TEST(handle_duplicate_test)
RUN_TEST(handle_replace_test)
RUN_TEST(event_test)
RUN_TEST(event_duplicate_test)
RUN_TEST(channel_test)
RUN_TEST(socket_test)
RUN_TEST(eventpair_test)
RUN_TEST(vmar_test)
RUN_TEST(port_test)
RUN_TEST(time_test)
RUN_TEST(thread_self_test)
RUN_TEST(process_self_test)
RUN_TEST(vmar_root_self_test)
RUN_TEST(job_default_test)
END_TEST_CASE(libmx_tests)
int main(int argc, char** argv) {
bool success = unittest_run_all_tests(argc, argv);
return success ? 0 : -1;
}