123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- // Copyright 2013 The Chromium 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 "base/sync_socket.h"
- #include "base/memory/raw_ptr.h"
- #include "base/synchronization/waitable_event.h"
- #include "base/threading/platform_thread.h"
- #include "base/threading/simple_thread.h"
- #include "base/time/time.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace base {
- namespace {
- constexpr TimeDelta kReceiveTimeout = base::Milliseconds(750);
- class HangingReceiveThread : public DelegateSimpleThread::Delegate {
- public:
- explicit HangingReceiveThread(SyncSocket* socket, bool with_timeout)
- : socket_(socket),
- thread_(this, "HangingReceiveThread"),
- with_timeout_(with_timeout),
- started_event_(WaitableEvent::ResetPolicy::MANUAL,
- WaitableEvent::InitialState::NOT_SIGNALED),
- done_event_(WaitableEvent::ResetPolicy::MANUAL,
- WaitableEvent::InitialState::NOT_SIGNALED) {
- thread_.Start();
- }
- HangingReceiveThread(const HangingReceiveThread&) = delete;
- HangingReceiveThread& operator=(const HangingReceiveThread&) = delete;
- ~HangingReceiveThread() override = default;
- void Run() override {
- int data = 0;
- ASSERT_EQ(socket_->Peek(), 0u);
- started_event_.Signal();
- if (with_timeout_) {
- ASSERT_EQ(0u, socket_->ReceiveWithTimeout(&data, sizeof(data),
- kReceiveTimeout));
- } else {
- ASSERT_EQ(0u, socket_->Receive(&data, sizeof(data)));
- }
- done_event_.Signal();
- }
- void Stop() {
- thread_.Join();
- }
- WaitableEvent* started_event() { return &started_event_; }
- WaitableEvent* done_event() { return &done_event_; }
- private:
- raw_ptr<SyncSocket> socket_;
- DelegateSimpleThread thread_;
- bool with_timeout_;
- WaitableEvent started_event_;
- WaitableEvent done_event_;
- };
- // Tests sending data between two SyncSockets. Uses ASSERT() and thus will exit
- // early upon failure. Callers should use ASSERT_NO_FATAL_FAILURE() if testing
- // continues after return.
- void SendReceivePeek(SyncSocket* socket_a, SyncSocket* socket_b) {
- int received = 0;
- const int kSending = 123;
- static_assert(sizeof(kSending) == sizeof(received), "invalid data size");
- ASSERT_EQ(0u, socket_a->Peek());
- ASSERT_EQ(0u, socket_b->Peek());
- // Verify |socket_a| can send to |socket_a| and |socket_a| can Receive from
- // |socket_a|.
- ASSERT_EQ(sizeof(kSending), socket_a->Send(&kSending, sizeof(kSending)));
- ASSERT_EQ(sizeof(kSending), socket_b->Peek());
- ASSERT_EQ(sizeof(kSending), socket_b->Receive(&received, sizeof(kSending)));
- ASSERT_EQ(kSending, received);
- ASSERT_EQ(0u, socket_a->Peek());
- ASSERT_EQ(0u, socket_b->Peek());
- // Now verify the reverse.
- received = 0;
- ASSERT_EQ(sizeof(kSending), socket_b->Send(&kSending, sizeof(kSending)));
- ASSERT_EQ(sizeof(kSending), socket_a->Peek());
- ASSERT_EQ(sizeof(kSending), socket_a->Receive(&received, sizeof(kSending)));
- ASSERT_EQ(kSending, received);
- ASSERT_EQ(0u, socket_a->Peek());
- ASSERT_EQ(0u, socket_b->Peek());
- socket_a->Close();
- socket_b->Close();
- }
- } // namespace
- class SyncSocketTest : public testing::Test {
- public:
- void SetUp() override {
- ASSERT_TRUE(SyncSocket::CreatePair(&socket_a_, &socket_b_));
- }
- protected:
- SyncSocket socket_a_;
- SyncSocket socket_b_;
- };
- TEST_F(SyncSocketTest, NormalSendReceivePeek) {
- SendReceivePeek(&socket_a_, &socket_b_);
- }
- TEST_F(SyncSocketTest, ClonedSendReceivePeek) {
- SyncSocket socket_c(socket_a_.Release());
- SyncSocket socket_d(socket_b_.Release());
- SendReceivePeek(&socket_c, &socket_d);
- }
- class CancelableSyncSocketTest : public testing::Test {
- public:
- void SetUp() override {
- ASSERT_TRUE(CancelableSyncSocket::CreatePair(&socket_a_, &socket_b_));
- }
- protected:
- CancelableSyncSocket socket_a_;
- CancelableSyncSocket socket_b_;
- };
- TEST_F(CancelableSyncSocketTest, NormalSendReceivePeek) {
- SendReceivePeek(&socket_a_, &socket_b_);
- }
- TEST_F(CancelableSyncSocketTest, ClonedSendReceivePeek) {
- CancelableSyncSocket socket_c(socket_a_.Release());
- CancelableSyncSocket socket_d(socket_b_.Release());
- SendReceivePeek(&socket_c, &socket_d);
- }
- TEST_F(CancelableSyncSocketTest, ShutdownCancelsReceive) {
- HangingReceiveThread thread(&socket_b_, /* with_timeout = */ false);
- // Wait for the thread to be started. Note that this doesn't guarantee that
- // Receive() is called before Shutdown().
- thread.started_event()->Wait();
- EXPECT_TRUE(socket_b_.Shutdown());
- EXPECT_TRUE(thread.done_event()->TimedWait(kReceiveTimeout));
- thread.Stop();
- }
- TEST_F(CancelableSyncSocketTest, ShutdownCancelsReceiveWithTimeout) {
- HangingReceiveThread thread(&socket_b_, /* with_timeout = */ true);
- // Wait for the thread to be started. Note that this doesn't guarantee that
- // Receive() is called before Shutdown().
- thread.started_event()->Wait();
- EXPECT_TRUE(socket_b_.Shutdown());
- EXPECT_TRUE(thread.done_event()->TimedWait(kReceiveTimeout));
- thread.Stop();
- }
- TEST_F(CancelableSyncSocketTest, ReceiveAfterShutdown) {
- socket_a_.Shutdown();
- int data = 0;
- EXPECT_EQ(0u, socket_a_.Receive(&data, sizeof(data)));
- }
- TEST_F(CancelableSyncSocketTest, ReceiveWithTimeoutAfterShutdown) {
- socket_a_.Shutdown();
- TimeTicks start = TimeTicks::Now();
- int data = 0;
- EXPECT_EQ(0u,
- socket_a_.ReceiveWithTimeout(&data, sizeof(data), kReceiveTimeout));
- // Ensure the receive didn't just timeout.
- EXPECT_LT(TimeTicks::Now() - start, kReceiveTimeout);
- }
- } // namespace base
|