xref: /aosp_15_r20/external/grpc-grpc/test/core/event_engine/windows/win_socket_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Copyright 2022 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <grpc/support/port_platform.h>
16 
17 #ifdef GPR_WINDOWS
18 #include <gtest/gtest.h>
19 
20 #include "absl/status/status.h"
21 #include "absl/time/time.h"
22 
23 #include <grpc/grpc.h>
24 #include <grpc/support/log_windows.h>
25 
26 #include "src/core/lib/event_engine/common_closures.h"
27 #include "src/core/lib/event_engine/thread_pool/thread_pool.h"
28 #include "src/core/lib/event_engine/windows/iocp.h"
29 #include "src/core/lib/event_engine/windows/win_socket.h"
30 #include "src/core/lib/gprpp/notification.h"
31 #include "src/core/lib/iomgr/error.h"
32 #include "test/core/event_engine/windows/create_sockpair.h"
33 
34 namespace {
35 using ::grpc_event_engine::experimental::AnyInvocableClosure;
36 using ::grpc_event_engine::experimental::CreateSockpair;
37 using ::grpc_event_engine::experimental::IOCP;
38 using ::grpc_event_engine::experimental::ThreadPool;
39 using ::grpc_event_engine::experimental::WinSocket;
40 }  // namespace
41 
42 class WinSocketTest : public testing::Test {
43  public:
WinSocketTest()44   WinSocketTest()
45       : thread_pool_(grpc_event_engine::experimental::MakeThreadPool(8)) {
46     CreateSockpair(sockpair_, IOCP::GetDefaultSocketFlags());
47     wrapped_client_socket_ =
48         std::make_unique<WinSocket>(sockpair_[0], thread_pool_.get());
49     wrapped_server_socket_ =
50         std::make_unique<WinSocket>(sockpair_[1], thread_pool_.get());
51   }
52 
~WinSocketTest()53   ~WinSocketTest() override {
54     wrapped_client_socket_->Shutdown();
55     wrapped_server_socket_->Shutdown();
56     thread_pool_->Quiesce();
57   }
58 
59  protected:
60   std::shared_ptr<ThreadPool> thread_pool_;
61   SOCKET sockpair_[2];
62   std::unique_ptr<WinSocket> wrapped_client_socket_;
63   std::unique_ptr<WinSocket> wrapped_server_socket_;
64 };
65 
TEST_F(WinSocketTest,ManualReadEventTriggeredWithoutIO)66 TEST_F(WinSocketTest, ManualReadEventTriggeredWithoutIO) {
67   grpc_core::Notification read_called;
68   AnyInvocableClosure on_read([&read_called]() { read_called.Notify(); });
69   wrapped_client_socket_->NotifyOnRead(&on_read);
70   AnyInvocableClosure on_write([] { FAIL() << "No Write expected"; });
71   wrapped_client_socket_->NotifyOnWrite(&on_write);
72   wrapped_client_socket_->read_info()->SetReady();
73   read_called.WaitForNotification();
74 }
75 
TEST_F(WinSocketTest,NotificationCalledImmediatelyOnShutdownWinSocket)76 TEST_F(WinSocketTest, NotificationCalledImmediatelyOnShutdownWinSocket) {
77   wrapped_client_socket_->Shutdown();
78   grpc_core::Notification read_called;
79   AnyInvocableClosure closure([this, &read_called] {
80     ASSERT_EQ(wrapped_client_socket_->read_info()->result().bytes_transferred,
81               0u);
82     ASSERT_EQ(wrapped_client_socket_->read_info()->result().wsa_error,
83               WSAESHUTDOWN);
84     read_called.Notify();
85   });
86   wrapped_client_socket_->NotifyOnRead(&closure);
87   read_called.WaitForNotification();
88 }
89 
TEST_F(WinSocketTest,UnsetNotificationWorks)90 TEST_F(WinSocketTest, UnsetNotificationWorks) {
91   AnyInvocableClosure read_closure{
92       []() { grpc_core::Crash("read callback called"); }};
93   wrapped_client_socket_->NotifyOnRead(&read_closure);
94   AnyInvocableClosure write_closure{
95       []() { grpc_core::Crash("write callback called"); }};
96   wrapped_client_socket_->NotifyOnWrite(&write_closure);
97   wrapped_client_socket_->UnregisterReadCallback();
98   wrapped_client_socket_->UnregisterWriteCallback();
99   // Give this time to fail.
100   absl::SleepFor(absl::Seconds(1));
101 }
102 
TEST_F(WinSocketTest,UnsetNotificationCanBeDoneRepeatedly)103 TEST_F(WinSocketTest, UnsetNotificationCanBeDoneRepeatedly) {
104   // This should crash if a callback is already registered.
105   AnyInvocableClosure closure{
106       []() { grpc_core::Crash("read callback 1 called"); }};
107   wrapped_client_socket_->NotifyOnRead(&closure);
108   wrapped_client_socket_->UnregisterReadCallback();
109   wrapped_client_socket_->NotifyOnRead(&closure);
110   wrapped_client_socket_->UnregisterReadCallback();
111   wrapped_client_socket_->NotifyOnRead(&closure);
112   wrapped_client_socket_->UnregisterReadCallback();
113   // Give this time to fail.
114   absl::SleepFor(absl::Seconds(1));
115 }
116 
main(int argc,char ** argv)117 int main(int argc, char** argv) {
118   ::testing::InitGoogleTest(&argc, argv);
119   grpc_init();
120   int status = RUN_ALL_TESTS();
121   grpc_shutdown();
122   return status;
123 }
124 
125 #else  // not GPR_WINDOWS
main(int,char **)126 int main(int /* argc */, char** /* argv */) { return 0; }
127 #endif
128