blob: 24265d4c9632ec26a6438852b805a0c77155d6a5 [file] [log] [blame] [edit]
// Copyright 2021 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 "src/sys/fuzzing/common/transceiver.h"
#include <gtest/gtest.h>
namespace fuzzing {
namespace {
TEST(TransceiverTest, Receive) {
Transceiver transceiver;
Input input({0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce});
zx::socket sender;
zx_status_t rx_result;
Input rx_input;
FidlInput fidl_input1;
sync_completion_t sync;
EXPECT_EQ(zx::socket::create(ZX_SOCKET_STREAM, &sender, &fidl_input1.socket), ZX_OK);
fidl_input1.size = input.size();
fit::result<Input, zx_status_t> receive_result;
transceiver.Receive(std::move(fidl_input1), [&](zx_status_t result, Input received) {
rx_result = result;
rx_input = std::move(received);
sync_completion_signal(&sync);
});
// Send data all at once.
EXPECT_EQ(sender.write(0, input.data(), input.size(), nullptr), ZX_OK);
sync_completion_wait(&sync, ZX_TIME_INFINITE);
EXPECT_EQ(rx_result, ZX_OK);
EXPECT_EQ(rx_input, input);
FidlInput fidl_input2;
sync_completion_reset(&sync);
fidl_input2.size = input.size();
EXPECT_EQ(zx::socket::create(ZX_SOCKET_STREAM, &sender, &fidl_input2.socket), ZX_OK);
transceiver.Receive(std::move(fidl_input2), [&](zx_status_t result, Input received) {
rx_result = result;
rx_input = std::move(received);
sync_completion_signal(&sync);
});
// Send data in pieces.
auto split = input.size() / 2;
auto* data = input.data();
zx::nanosleep(zx::deadline_after(zx::usec(1)));
EXPECT_EQ(sender.write(0, &data[0], split, nullptr), ZX_OK);
zx::nanosleep(zx::deadline_after(zx::usec(1)));
EXPECT_EQ(sender.write(0, &data[split], input.size() - split, nullptr), ZX_OK);
sync_completion_wait(&sync, ZX_TIME_INFINITE);
EXPECT_EQ(rx_result, ZX_OK);
EXPECT_EQ(rx_input, input);
// Try to receive after shutdown.
FidlInput fidl_input3;
sync_completion_reset(&sync);
fidl_input3.size = input.size();
EXPECT_EQ(zx::socket::create(ZX_SOCKET_STREAM, &sender, &fidl_input3.socket), ZX_OK);
transceiver.Shutdown();
transceiver.Receive(std::move(fidl_input3), [&](zx_status_t result, Input received) {
rx_result = result;
sync_completion_signal(&sync);
});
sync_completion_wait(&sync, ZX_TIME_INFINITE);
EXPECT_EQ(rx_result, ZX_ERR_BAD_STATE);
}
TEST(TransceiverTest, Transmit) {
Transceiver transceiver;
Input input({0xfe, 0xed, 0xfa, 0xce});
FidlInput fidl_input;
EXPECT_EQ(transceiver.Transmit(input.Duplicate(), &fidl_input), ZX_OK);
EXPECT_EQ(fidl_input.size, input.size());
auto* data = input.data();
for (size_t i = 0; i < input.size(); ++i) {
uint8_t u8;
EXPECT_EQ(fidl_input.socket.wait_one(ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED,
zx::time::infinite(), nullptr),
ZX_OK);
EXPECT_EQ(fidl_input.socket.read(0, &u8, sizeof(u8), nullptr), ZX_OK);
EXPECT_EQ(data[i], u8);
}
// Try to transmit after shutdown.
transceiver.Shutdown();
EXPECT_EQ(transceiver.Transmit(input.Duplicate(), &fidl_input), ZX_ERR_BAD_STATE);
}
} // namespace
} // namespace fuzzing