• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <grpc/grpc.h>
19 #include <grpc/support/log_windows.h>
20 #include <gtest/gtest.h>
21 
22 #include "absl/status/status.h"
23 #include "absl/time/time.h"
24 #include "src/core/lib/event_engine/common_closures.h"
25 #include "src/core/lib/event_engine/thread_pool/thread_pool.h"
26 #include "src/core/lib/event_engine/windows/iocp.h"
27 #include "src/core/lib/event_engine/windows/win_socket.h"
28 #include "src/core/lib/iomgr/error.h"
29 #include "src/core/util/notification.h"
30 #include "test/core/event_engine/windows/create_sockpair.h"
31 
32 namespace {
33 using ::grpc_event_engine::experimental::AnyInvocableClosure;
34 using ::grpc_event_engine::experimental::CreateSockpair;
35 using ::grpc_event_engine::experimental::IOCP;
36 using ::grpc_event_engine::experimental::ThreadPool;
37 using ::grpc_event_engine::experimental::WinSocket;
38 }  // namespace
39 
40 class WinSocketTest : public testing::Test {
41  public:
WinSocketTest()42   WinSocketTest()
43       : thread_pool_(grpc_event_engine::experimental::MakeThreadPool(8)) {
44     CreateSockpair(sockpair_, IOCP::GetDefaultSocketFlags());
45     wrapped_client_socket_ =
46         std::make_unique<WinSocket>(sockpair_[0], thread_pool_.get());
47     wrapped_server_socket_ =
48         std::make_unique<WinSocket>(sockpair_[1], thread_pool_.get());
49   }
50 
~WinSocketTest()51   ~WinSocketTest() override {
52     wrapped_client_socket_->Shutdown();
53     wrapped_server_socket_->Shutdown();
54     thread_pool_->Quiesce();
55   }
56 
57  protected:
58   std::shared_ptr<ThreadPool> thread_pool_;
59   SOCKET sockpair_[2];
60   std::unique_ptr<WinSocket> wrapped_client_socket_;
61   std::unique_ptr<WinSocket> wrapped_server_socket_;
62 };
63 
TEST_F(WinSocketTest,ManualReadEventTriggeredWithoutIO)64 TEST_F(WinSocketTest, ManualReadEventTriggeredWithoutIO) {
65   grpc_core::Notification read_called;
66   AnyInvocableClosure on_read([&read_called]() { read_called.Notify(); });
67   wrapped_client_socket_->NotifyOnRead(&on_read);
68   AnyInvocableClosure on_write([] { FAIL() << "No Write expected"; });
69   wrapped_client_socket_->NotifyOnWrite(&on_write);
70   wrapped_client_socket_->read_info()->SetReady();
71   read_called.WaitForNotification();
72 }
73 
TEST_F(WinSocketTest,NotificationCalledImmediatelyOnShutdownWinSocket)74 TEST_F(WinSocketTest, NotificationCalledImmediatelyOnShutdownWinSocket) {
75   wrapped_client_socket_->Shutdown();
76   grpc_core::Notification read_called;
77   AnyInvocableClosure closure([this, &read_called] {
78     ASSERT_EQ(wrapped_client_socket_->read_info()->result().bytes_transferred,
79               0u);
80     ASSERT_EQ(wrapped_client_socket_->read_info()->result().wsa_error,
81               WSAESHUTDOWN);
82     read_called.Notify();
83   });
84   wrapped_client_socket_->NotifyOnRead(&closure);
85   read_called.WaitForNotification();
86 }
87 
TEST_F(WinSocketTest,UnsetNotificationWorks)88 TEST_F(WinSocketTest, UnsetNotificationWorks) {
89   AnyInvocableClosure read_closure{
90       []() { grpc_core::Crash("read callback called"); }};
91   wrapped_client_socket_->NotifyOnRead(&read_closure);
92   AnyInvocableClosure write_closure{
93       []() { grpc_core::Crash("write callback called"); }};
94   wrapped_client_socket_->NotifyOnWrite(&write_closure);
95   wrapped_client_socket_->UnregisterReadCallback();
96   wrapped_client_socket_->UnregisterWriteCallback();
97   // Give this time to fail.
98   absl::SleepFor(absl::Seconds(1));
99 }
100 
TEST_F(WinSocketTest,UnsetNotificationCanBeDoneRepeatedly)101 TEST_F(WinSocketTest, UnsetNotificationCanBeDoneRepeatedly) {
102   // This should crash if a callback is already registered.
103   AnyInvocableClosure closure{
104       []() { grpc_core::Crash("read callback 1 called"); }};
105   wrapped_client_socket_->NotifyOnRead(&closure);
106   wrapped_client_socket_->UnregisterReadCallback();
107   wrapped_client_socket_->NotifyOnRead(&closure);
108   wrapped_client_socket_->UnregisterReadCallback();
109   wrapped_client_socket_->NotifyOnRead(&closure);
110   wrapped_client_socket_->UnregisterReadCallback();
111   // Give this time to fail.
112   absl::SleepFor(absl::Seconds(1));
113 }
114 
main(int argc,char ** argv)115 int main(int argc, char** argv) {
116   ::testing::InitGoogleTest(&argc, argv);
117   grpc_init();
118   int status = RUN_ALL_TESTS();
119   grpc_shutdown();
120   return status;
121 }
122 
123 #else  // not GPR_WINDOWS
main(int,char **)124 int main(int /* argc */, char** /* argv */) { return 0; }
125 #endif
126