blob: 25030d77356dbe9f9fe73b1ed0e129eded2e024d [file] [log] [blame]
// Copyright 2017 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.
// This file contains tests for socketpair() behaviors specific to the
// fdio implementation. Cross-platform tests for socketpair() behaviors
// should go into socketpair.cc.
#ifndef __Fuchsia__
#error This file is Fuchsia-specific
#endif
#include <errno.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/unsafe.h>
#include <lib/zx/handle.h>
#include <poll.h>
#include <unistd.h>
#include <zircon/syscalls.h>
#include <zircon/threads.h>
#include <fbl/unique_fd.h>
#include <gtest/gtest.h>
#include "sdk/lib/fdio/tests/socketpair_test_helpers.h"
#include "src/lib/testing/predicates/status.h"
using fdio_tests::SocketPair;
using fdio_tests::TypeToString;
TEST_P(SocketPair, CloneOrUnwrapAndWrap) {
zx::handle handle;
ASSERT_OK(fdio_fd_clone(fds()[0].get(), handle.reset_and_get_address()));
fbl::unique_fd cloned_fd;
ASSERT_OK(fdio_fd_create(handle.release(), cloned_fd.reset_and_get_address()));
ASSERT_OK(fdio_fd_transfer(mutable_fds()[0].release(), handle.reset_and_get_address()));
fbl::unique_fd transferred_fd;
ASSERT_OK(fdio_fd_create(handle.release(), transferred_fd.reset_and_get_address()));
// Verify that an operation specific to socketpairs works on these fds.
ASSERT_EQ(shutdown(transferred_fd.get(), SHUT_WR), 0) << strerror(errno);
ASSERT_EQ(shutdown(cloned_fd.get(), SHUT_RD), 0) << strerror(errno);
}
TEST_P(SocketPair, WaitBeginEnd) {
fdio_t* io = fdio_unsafe_fd_to_io(fds()[0].get());
// fdio_unsafe_wait_begin
zx::handle handle;
{
zx_signals_t signals;
fdio_unsafe_wait_begin(io, POLLIN, handle.reset_and_get_address(), &signals);
EXPECT_NE(handle.get(), ZX_HANDLE_INVALID);
EXPECT_EQ(signals, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED | ZX_SOCKET_PEER_WRITE_DISABLED);
}
{
zx_signals_t signals;
fdio_unsafe_wait_begin(io, POLLOUT, handle.reset_and_get_address(), &signals);
EXPECT_NE(handle.get(), ZX_HANDLE_INVALID);
EXPECT_EQ(signals, ZX_SOCKET_WRITABLE | ZX_SOCKET_WRITE_DISABLED);
}
{
zx_signals_t signals;
fdio_unsafe_wait_begin(io, POLLRDHUP, handle.reset_and_get_address(), &signals);
EXPECT_NE(handle.get(), ZX_HANDLE_INVALID);
EXPECT_EQ(signals, ZX_SOCKET_PEER_CLOSED | ZX_SOCKET_PEER_WRITE_DISABLED);
}
{
zx_signals_t signals;
fdio_unsafe_wait_begin(io, POLLHUP, handle.reset_and_get_address(), &signals);
EXPECT_NE(handle.get(), ZX_HANDLE_INVALID);
EXPECT_EQ(signals, ZX_SIGNAL_NONE);
}
// fdio_unsafe_wait_end
{
uint32_t events;
fdio_unsafe_wait_end(io, ZX_SOCKET_READABLE, &events);
EXPECT_EQ(int32_t(events), POLLIN);
}
{
uint32_t events;
fdio_unsafe_wait_end(io, ZX_SOCKET_PEER_CLOSED, &events);
EXPECT_EQ(int32_t(events), POLLIN | POLLRDHUP);
}
{
uint32_t events;
fdio_unsafe_wait_end(io, ZX_SOCKET_PEER_WRITE_DISABLED, &events);
EXPECT_EQ(int32_t(events), POLLIN | POLLRDHUP);
}
{
uint32_t events;
fdio_unsafe_wait_end(io, ZX_SOCKET_WRITABLE, &events);
EXPECT_EQ(int32_t(events), POLLOUT);
}
{
uint32_t events;
fdio_unsafe_wait_end(io, ZX_SOCKET_WRITE_DISABLED, &events);
EXPECT_EQ(int32_t(events), POLLOUT);
}
fdio_unsafe_release(io);
}