1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/socket/websocket_endpoint_lock_manager.h"
7 #include "net/base/net_errors.h"
8 #include "net/socket/next_proto.h"
9 #include "net/socket/socket_test_util.h"
10 #include "net/socket/stream_socket.h"
11 #include "testing/gtest/include/gtest/gtest.h"
17 // A StreamSocket implementation with no functionality at all.
18 // TODO(ricea): If you need to use this in another file, please move it to
19 // socket_test_util.h.
20 class FakeStreamSocket
: public StreamSocket
{
24 // StreamSocket implementation
25 int Connect(const CompletionCallback
& callback
) override
{
29 void Disconnect() override
{ return; }
31 bool IsConnected() const override
{ return false; }
33 bool IsConnectedAndIdle() const override
{ return false; }
35 int GetPeerAddress(IPEndPoint
* address
) const override
{ return ERR_FAILED
; }
37 int GetLocalAddress(IPEndPoint
* address
) const override
{ return ERR_FAILED
; }
39 const BoundNetLog
& NetLog() const override
{ return bound_net_log_
; }
41 void SetSubresourceSpeculation() override
{ return; }
42 void SetOmniboxSpeculation() override
{ return; }
44 bool WasEverUsed() const override
{ return false; }
46 bool UsingTCPFastOpen() const override
{ return false; }
48 bool WasNpnNegotiated() const override
{ return false; }
50 NextProto
GetNegotiatedProtocol() const override
{ return kProtoUnknown
; }
52 bool GetSSLInfo(SSLInfo
* ssl_info
) override
{ return false; }
54 // Socket implementation
55 int Read(IOBuffer
* buf
,
57 const CompletionCallback
& callback
) override
{
61 int Write(IOBuffer
* buf
,
63 const CompletionCallback
& callback
) override
{
67 int SetReceiveBufferSize(int32 size
) override
{ return ERR_FAILED
; }
69 int SetSendBufferSize(int32 size
) override
{ return ERR_FAILED
; }
72 BoundNetLog bound_net_log_
;
74 DISALLOW_COPY_AND_ASSIGN(FakeStreamSocket
);
77 class FakeWaiter
: public WebSocketEndpointLockManager::Waiter
{
79 FakeWaiter() : called_(false) {}
81 void GotEndpointLock() override
{
86 bool called() const { return called_
; }
92 class WebSocketEndpointLockManagerTest
: public ::testing::Test
{
94 WebSocketEndpointLockManagerTest()
95 : instance_(WebSocketEndpointLockManager::GetInstance()) {}
96 ~WebSocketEndpointLockManagerTest() override
{
97 // If this check fails then subsequent tests may fail.
98 CHECK(instance_
->IsEmpty());
101 WebSocketEndpointLockManager
* instance() const { return instance_
; }
103 IPEndPoint
DummyEndpoint() {
104 IPAddressNumber ip_address_number
;
105 CHECK(ParseIPLiteralToNumber("127.0.0.1", &ip_address_number
));
106 return IPEndPoint(ip_address_number
, 80);
109 void UnlockDummyEndpoint(int times
) {
110 for (int i
= 0; i
< times
; ++i
) {
111 instance()->UnlockEndpoint(DummyEndpoint());
115 WebSocketEndpointLockManager
* const instance_
;
118 TEST_F(WebSocketEndpointLockManagerTest
, GetInstanceWorks
) {
119 // All the work is done by the test framework.
122 TEST_F(WebSocketEndpointLockManagerTest
, LockEndpointReturnsOkOnce
) {
123 FakeWaiter waiters
[2];
124 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiters
[0]));
125 EXPECT_EQ(ERR_IO_PENDING
,
126 instance()->LockEndpoint(DummyEndpoint(), &waiters
[1]));
128 UnlockDummyEndpoint(2);
131 TEST_F(WebSocketEndpointLockManagerTest
, GotEndpointLockNotCalledOnOk
) {
133 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiter
));
134 EXPECT_FALSE(waiter
.called());
136 UnlockDummyEndpoint(1);
139 TEST_F(WebSocketEndpointLockManagerTest
, GotEndpointLockNotCalledImmediately
) {
140 FakeWaiter waiters
[2];
141 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiters
[0]));
142 EXPECT_EQ(ERR_IO_PENDING
,
143 instance()->LockEndpoint(DummyEndpoint(), &waiters
[1]));
144 EXPECT_FALSE(waiters
[1].called());
146 UnlockDummyEndpoint(2);
149 TEST_F(WebSocketEndpointLockManagerTest
, GotEndpointLockCalledWhenUnlocked
) {
150 FakeWaiter waiters
[2];
151 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiters
[0]));
152 EXPECT_EQ(ERR_IO_PENDING
,
153 instance()->LockEndpoint(DummyEndpoint(), &waiters
[1]));
154 instance()->UnlockEndpoint(DummyEndpoint());
155 EXPECT_TRUE(waiters
[1].called());
157 UnlockDummyEndpoint(1);
160 TEST_F(WebSocketEndpointLockManagerTest
,
161 EndpointUnlockedIfWaiterAlreadyDeleted
) {
162 FakeWaiter first_lock_holder
;
163 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &first_lock_holder
));
166 FakeWaiter short_lived_waiter
;
167 EXPECT_EQ(ERR_IO_PENDING
,
168 instance()->LockEndpoint(DummyEndpoint(), &short_lived_waiter
));
171 instance()->UnlockEndpoint(DummyEndpoint());
173 FakeWaiter second_lock_holder
;
174 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &second_lock_holder
));
176 UnlockDummyEndpoint(1);
179 TEST_F(WebSocketEndpointLockManagerTest
, RememberSocketWorks
) {
180 FakeWaiter waiters
[2];
181 FakeStreamSocket dummy_socket
;
182 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiters
[0]));
183 EXPECT_EQ(ERR_IO_PENDING
,
184 instance()->LockEndpoint(DummyEndpoint(), &waiters
[1]));
186 instance()->RememberSocket(&dummy_socket
, DummyEndpoint());
187 instance()->UnlockSocket(&dummy_socket
);
188 EXPECT_TRUE(waiters
[1].called());
190 UnlockDummyEndpoint(1);
193 // UnlockEndpoint() should cause any sockets remembered for this endpoint
195 TEST_F(WebSocketEndpointLockManagerTest
, SocketAssociationForgottenOnUnlock
) {
197 FakeStreamSocket dummy_socket
;
199 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiter
));
200 instance()->RememberSocket(&dummy_socket
, DummyEndpoint());
201 instance()->UnlockEndpoint(DummyEndpoint());
202 EXPECT_TRUE(instance()->IsEmpty());
205 // When ownership of the endpoint is passed to a new waiter, the new waiter can
206 // call RememberSocket() again.
207 TEST_F(WebSocketEndpointLockManagerTest
, NextWaiterCanCallRememberSocketAgain
) {
208 FakeWaiter waiters
[2];
209 FakeStreamSocket dummy_sockets
[2];
210 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiters
[0]));
211 EXPECT_EQ(ERR_IO_PENDING
,
212 instance()->LockEndpoint(DummyEndpoint(), &waiters
[1]));
214 instance()->RememberSocket(&dummy_sockets
[0], DummyEndpoint());
215 instance()->UnlockEndpoint(DummyEndpoint());
216 EXPECT_TRUE(waiters
[1].called());
217 instance()->RememberSocket(&dummy_sockets
[1], DummyEndpoint());
219 UnlockDummyEndpoint(1);