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 virtual int Connect(const CompletionCallback
& callback
) OVERRIDE
{
29 virtual void Disconnect() OVERRIDE
{ return; }
31 virtual bool IsConnected() const OVERRIDE
{ return false; }
33 virtual bool IsConnectedAndIdle() const OVERRIDE
{ return false; }
35 virtual int GetPeerAddress(IPEndPoint
* address
) const OVERRIDE
{
39 virtual int GetLocalAddress(IPEndPoint
* address
) const OVERRIDE
{
43 virtual const BoundNetLog
& NetLog() const OVERRIDE
{ return bound_net_log_
; }
45 virtual void SetSubresourceSpeculation() OVERRIDE
{ return; }
46 virtual void SetOmniboxSpeculation() OVERRIDE
{ return; }
48 virtual bool WasEverUsed() const OVERRIDE
{ return false; }
50 virtual bool UsingTCPFastOpen() const OVERRIDE
{ return false; }
52 virtual bool WasNpnNegotiated() const OVERRIDE
{ return false; }
54 virtual NextProto
GetNegotiatedProtocol() const OVERRIDE
{
58 virtual bool GetSSLInfo(SSLInfo
* ssl_info
) OVERRIDE
{ return false; }
60 // Socket implementation
61 virtual int Read(IOBuffer
* buf
,
63 const CompletionCallback
& callback
) OVERRIDE
{
67 virtual int Write(IOBuffer
* buf
,
69 const CompletionCallback
& callback
) OVERRIDE
{
73 virtual int SetReceiveBufferSize(int32 size
) OVERRIDE
{ return ERR_FAILED
; }
75 virtual int SetSendBufferSize(int32 size
) OVERRIDE
{ return ERR_FAILED
; }
78 BoundNetLog bound_net_log_
;
80 DISALLOW_COPY_AND_ASSIGN(FakeStreamSocket
);
83 class FakeWaiter
: public WebSocketEndpointLockManager::Waiter
{
85 FakeWaiter() : called_(false) {}
87 virtual void GotEndpointLock() OVERRIDE
{
92 bool called() const { return called_
; }
98 class WebSocketEndpointLockManagerTest
: public ::testing::Test
{
100 WebSocketEndpointLockManagerTest()
101 : instance_(WebSocketEndpointLockManager::GetInstance()) {}
102 virtual ~WebSocketEndpointLockManagerTest() {
103 // If this check fails then subsequent tests may fail.
104 CHECK(instance_
->IsEmpty());
107 WebSocketEndpointLockManager
* instance() const { return instance_
; }
109 IPEndPoint
DummyEndpoint() {
110 IPAddressNumber ip_address_number
;
111 CHECK(ParseIPLiteralToNumber("127.0.0.1", &ip_address_number
));
112 return IPEndPoint(ip_address_number
, 80);
115 void UnlockDummyEndpoint(int times
) {
116 for (int i
= 0; i
< times
; ++i
) {
117 instance()->UnlockEndpoint(DummyEndpoint());
121 WebSocketEndpointLockManager
* const instance_
;
124 TEST_F(WebSocketEndpointLockManagerTest
, GetInstanceWorks
) {
125 // All the work is done by the test framework.
128 TEST_F(WebSocketEndpointLockManagerTest
, LockEndpointReturnsOkOnce
) {
129 FakeWaiter waiters
[2];
130 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiters
[0]));
131 EXPECT_EQ(ERR_IO_PENDING
,
132 instance()->LockEndpoint(DummyEndpoint(), &waiters
[1]));
134 UnlockDummyEndpoint(2);
137 TEST_F(WebSocketEndpointLockManagerTest
, GotEndpointLockNotCalledOnOk
) {
139 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiter
));
140 EXPECT_FALSE(waiter
.called());
142 UnlockDummyEndpoint(1);
145 TEST_F(WebSocketEndpointLockManagerTest
, GotEndpointLockNotCalledImmediately
) {
146 FakeWaiter waiters
[2];
147 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiters
[0]));
148 EXPECT_EQ(ERR_IO_PENDING
,
149 instance()->LockEndpoint(DummyEndpoint(), &waiters
[1]));
150 EXPECT_FALSE(waiters
[1].called());
152 UnlockDummyEndpoint(2);
155 TEST_F(WebSocketEndpointLockManagerTest
, GotEndpointLockCalledWhenUnlocked
) {
156 FakeWaiter waiters
[2];
157 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiters
[0]));
158 EXPECT_EQ(ERR_IO_PENDING
,
159 instance()->LockEndpoint(DummyEndpoint(), &waiters
[1]));
160 instance()->UnlockEndpoint(DummyEndpoint());
161 EXPECT_TRUE(waiters
[1].called());
163 UnlockDummyEndpoint(1);
166 TEST_F(WebSocketEndpointLockManagerTest
,
167 EndpointUnlockedIfWaiterAlreadyDeleted
) {
168 FakeWaiter first_lock_holder
;
169 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &first_lock_holder
));
172 FakeWaiter short_lived_waiter
;
173 EXPECT_EQ(ERR_IO_PENDING
,
174 instance()->LockEndpoint(DummyEndpoint(), &short_lived_waiter
));
177 instance()->UnlockEndpoint(DummyEndpoint());
179 FakeWaiter second_lock_holder
;
180 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &second_lock_holder
));
182 UnlockDummyEndpoint(1);
185 TEST_F(WebSocketEndpointLockManagerTest
, RememberSocketWorks
) {
186 FakeWaiter waiters
[2];
187 FakeStreamSocket dummy_socket
;
188 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiters
[0]));
189 EXPECT_EQ(ERR_IO_PENDING
,
190 instance()->LockEndpoint(DummyEndpoint(), &waiters
[1]));
192 instance()->RememberSocket(&dummy_socket
, DummyEndpoint());
193 instance()->UnlockSocket(&dummy_socket
);
194 EXPECT_TRUE(waiters
[1].called());
196 UnlockDummyEndpoint(1);
199 // UnlockEndpoint() should cause any sockets remembered for this endpoint
201 TEST_F(WebSocketEndpointLockManagerTest
, SocketAssociationForgottenOnUnlock
) {
203 FakeStreamSocket dummy_socket
;
205 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiter
));
206 instance()->RememberSocket(&dummy_socket
, DummyEndpoint());
207 instance()->UnlockEndpoint(DummyEndpoint());
208 EXPECT_TRUE(instance()->IsEmpty());
211 // When ownership of the endpoint is passed to a new waiter, the new waiter can
212 // call RememberSocket() again.
213 TEST_F(WebSocketEndpointLockManagerTest
, NextWaiterCanCallRememberSocketAgain
) {
214 FakeWaiter waiters
[2];
215 FakeStreamSocket dummy_sockets
[2];
216 EXPECT_EQ(OK
, instance()->LockEndpoint(DummyEndpoint(), &waiters
[0]));
217 EXPECT_EQ(ERR_IO_PENDING
,
218 instance()->LockEndpoint(DummyEndpoint(), &waiters
[1]));
220 instance()->RememberSocket(&dummy_sockets
[0], DummyEndpoint());
221 instance()->UnlockEndpoint(DummyEndpoint());
222 EXPECT_TRUE(waiters
[1].called());
223 instance()->RememberSocket(&dummy_sockets
[1], DummyEndpoint());
225 UnlockDummyEndpoint(1);