| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/socket/websocket_endpoint_lock_manager.h" | 5 #include "net/socket/websocket_endpoint_lock_manager.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| 11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 12 #include "net/base/ip_address.h" | 12 #include "net/base/ip_address.h" |
| 13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 14 #include "net/socket/next_proto.h" | 14 #include "net/socket/next_proto.h" |
| 15 #include "net/socket/socket_test_util.h" | 15 #include "net/socket/socket_test_util.h" |
| 16 #include "net/socket/stream_socket.h" | 16 #include "net/socket/stream_socket.h" |
| 17 #include "net/test/gtest_util.h" |
| 18 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 20 |
| 21 using net::test::IsOk; |
| 22 |
| 19 namespace net { | 23 namespace net { |
| 20 | 24 |
| 21 namespace { | 25 namespace { |
| 22 | 26 |
| 23 // A StreamSocket implementation with no functionality at all. | 27 // A StreamSocket implementation with no functionality at all. |
| 24 // TODO(ricea): If you need to use this in another file, please move it to | 28 // TODO(ricea): If you need to use this in another file, please move it to |
| 25 // socket_test_util.h. | 29 // socket_test_util.h. |
| 26 class FakeStreamSocket : public StreamSocket { | 30 class FakeStreamSocket : public StreamSocket { |
| 27 public: | 31 public: |
| 28 FakeStreamSocket() {} | 32 FakeStreamSocket() {} |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 WebSocketEndpointLockManager* const instance_; | 156 WebSocketEndpointLockManager* const instance_; |
| 153 ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_; | 157 ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_; |
| 154 }; | 158 }; |
| 155 | 159 |
| 156 TEST_F(WebSocketEndpointLockManagerTest, GetInstanceWorks) { | 160 TEST_F(WebSocketEndpointLockManagerTest, GetInstanceWorks) { |
| 157 // All the work is done by the test framework. | 161 // All the work is done by the test framework. |
| 158 } | 162 } |
| 159 | 163 |
| 160 TEST_F(WebSocketEndpointLockManagerTest, LockEndpointReturnsOkOnce) { | 164 TEST_F(WebSocketEndpointLockManagerTest, LockEndpointReturnsOkOnce) { |
| 161 FakeWaiter waiters[2]; | 165 FakeWaiter waiters[2]; |
| 162 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); | 166 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk()); |
| 163 EXPECT_EQ(ERR_IO_PENDING, | 167 EXPECT_EQ(ERR_IO_PENDING, |
| 164 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); | 168 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); |
| 165 | 169 |
| 166 UnlockDummyEndpoint(2); | 170 UnlockDummyEndpoint(2); |
| 167 } | 171 } |
| 168 | 172 |
| 169 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledOnOk) { | 173 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledOnOk) { |
| 170 FakeWaiter waiter; | 174 FakeWaiter waiter; |
| 171 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiter)); | 175 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiter), IsOk()); |
| 172 RunUntilIdle(); | 176 RunUntilIdle(); |
| 173 EXPECT_FALSE(waiter.called()); | 177 EXPECT_FALSE(waiter.called()); |
| 174 | 178 |
| 175 UnlockDummyEndpoint(1); | 179 UnlockDummyEndpoint(1); |
| 176 } | 180 } |
| 177 | 181 |
| 178 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledImmediately) { | 182 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledImmediately) { |
| 179 FakeWaiter waiters[2]; | 183 FakeWaiter waiters[2]; |
| 180 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); | 184 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk()); |
| 181 EXPECT_EQ(ERR_IO_PENDING, | 185 EXPECT_EQ(ERR_IO_PENDING, |
| 182 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); | 186 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); |
| 183 RunUntilIdle(); | 187 RunUntilIdle(); |
| 184 EXPECT_FALSE(waiters[1].called()); | 188 EXPECT_FALSE(waiters[1].called()); |
| 185 | 189 |
| 186 UnlockDummyEndpoint(2); | 190 UnlockDummyEndpoint(2); |
| 187 } | 191 } |
| 188 | 192 |
| 189 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockCalledWhenUnlocked) { | 193 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockCalledWhenUnlocked) { |
| 190 FakeWaiter waiters[2]; | 194 FakeWaiter waiters[2]; |
| 191 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); | 195 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk()); |
| 192 EXPECT_EQ(ERR_IO_PENDING, | 196 EXPECT_EQ(ERR_IO_PENDING, |
| 193 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); | 197 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); |
| 194 instance()->UnlockEndpoint(DummyEndpoint()); | 198 instance()->UnlockEndpoint(DummyEndpoint()); |
| 195 RunUntilIdle(); | 199 RunUntilIdle(); |
| 196 EXPECT_TRUE(waiters[1].called()); | 200 EXPECT_TRUE(waiters[1].called()); |
| 197 | 201 |
| 198 UnlockDummyEndpoint(1); | 202 UnlockDummyEndpoint(1); |
| 199 } | 203 } |
| 200 | 204 |
| 201 TEST_F(WebSocketEndpointLockManagerTest, | 205 TEST_F(WebSocketEndpointLockManagerTest, |
| 202 EndpointUnlockedIfWaiterAlreadyDeleted) { | 206 EndpointUnlockedIfWaiterAlreadyDeleted) { |
| 203 FakeWaiter first_lock_holder; | 207 FakeWaiter first_lock_holder; |
| 204 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &first_lock_holder)); | 208 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &first_lock_holder), |
| 209 IsOk()); |
| 205 | 210 |
| 206 { | 211 { |
| 207 FakeWaiter short_lived_waiter; | 212 FakeWaiter short_lived_waiter; |
| 208 EXPECT_EQ(ERR_IO_PENDING, | 213 EXPECT_EQ(ERR_IO_PENDING, |
| 209 instance()->LockEndpoint(DummyEndpoint(), &short_lived_waiter)); | 214 instance()->LockEndpoint(DummyEndpoint(), &short_lived_waiter)); |
| 210 } | 215 } |
| 211 | 216 |
| 212 instance()->UnlockEndpoint(DummyEndpoint()); | 217 instance()->UnlockEndpoint(DummyEndpoint()); |
| 213 RunUntilIdle(); | 218 RunUntilIdle(); |
| 214 | 219 |
| 215 FakeWaiter second_lock_holder; | 220 FakeWaiter second_lock_holder; |
| 216 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &second_lock_holder)); | 221 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &second_lock_holder), |
| 222 IsOk()); |
| 217 | 223 |
| 218 UnlockDummyEndpoint(1); | 224 UnlockDummyEndpoint(1); |
| 219 } | 225 } |
| 220 | 226 |
| 221 TEST_F(WebSocketEndpointLockManagerTest, RememberSocketWorks) { | 227 TEST_F(WebSocketEndpointLockManagerTest, RememberSocketWorks) { |
| 222 FakeWaiter waiters[2]; | 228 FakeWaiter waiters[2]; |
| 223 FakeStreamSocket dummy_socket; | 229 FakeStreamSocket dummy_socket; |
| 224 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); | 230 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk()); |
| 225 EXPECT_EQ(ERR_IO_PENDING, | 231 EXPECT_EQ(ERR_IO_PENDING, |
| 226 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); | 232 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); |
| 227 | 233 |
| 228 instance()->RememberSocket(&dummy_socket, DummyEndpoint()); | 234 instance()->RememberSocket(&dummy_socket, DummyEndpoint()); |
| 229 instance()->UnlockSocket(&dummy_socket); | 235 instance()->UnlockSocket(&dummy_socket); |
| 230 RunUntilIdle(); | 236 RunUntilIdle(); |
| 231 EXPECT_TRUE(waiters[1].called()); | 237 EXPECT_TRUE(waiters[1].called()); |
| 232 | 238 |
| 233 UnlockDummyEndpoint(1); | 239 UnlockDummyEndpoint(1); |
| 234 } | 240 } |
| 235 | 241 |
| 236 // UnlockEndpoint() should cause any sockets remembered for this endpoint | 242 // UnlockEndpoint() should cause any sockets remembered for this endpoint |
| 237 // to be forgotten. | 243 // to be forgotten. |
| 238 TEST_F(WebSocketEndpointLockManagerTest, SocketAssociationForgottenOnUnlock) { | 244 TEST_F(WebSocketEndpointLockManagerTest, SocketAssociationForgottenOnUnlock) { |
| 239 FakeWaiter waiter; | 245 FakeWaiter waiter; |
| 240 FakeStreamSocket dummy_socket; | 246 FakeStreamSocket dummy_socket; |
| 241 | 247 |
| 242 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiter)); | 248 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiter), IsOk()); |
| 243 instance()->RememberSocket(&dummy_socket, DummyEndpoint()); | 249 instance()->RememberSocket(&dummy_socket, DummyEndpoint()); |
| 244 instance()->UnlockEndpoint(DummyEndpoint()); | 250 instance()->UnlockEndpoint(DummyEndpoint()); |
| 245 RunUntilIdle(); | 251 RunUntilIdle(); |
| 246 EXPECT_TRUE(instance()->IsEmpty()); | 252 EXPECT_TRUE(instance()->IsEmpty()); |
| 247 } | 253 } |
| 248 | 254 |
| 249 // When ownership of the endpoint is passed to a new waiter, the new waiter can | 255 // When ownership of the endpoint is passed to a new waiter, the new waiter can |
| 250 // call RememberSocket() again. | 256 // call RememberSocket() again. |
| 251 TEST_F(WebSocketEndpointLockManagerTest, NextWaiterCanCallRememberSocketAgain) { | 257 TEST_F(WebSocketEndpointLockManagerTest, NextWaiterCanCallRememberSocketAgain) { |
| 252 FakeWaiter waiters[2]; | 258 FakeWaiter waiters[2]; |
| 253 FakeStreamSocket dummy_sockets[2]; | 259 FakeStreamSocket dummy_sockets[2]; |
| 254 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); | 260 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk()); |
| 255 EXPECT_EQ(ERR_IO_PENDING, | 261 EXPECT_EQ(ERR_IO_PENDING, |
| 256 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); | 262 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); |
| 257 | 263 |
| 258 instance()->RememberSocket(&dummy_sockets[0], DummyEndpoint()); | 264 instance()->RememberSocket(&dummy_sockets[0], DummyEndpoint()); |
| 259 instance()->UnlockEndpoint(DummyEndpoint()); | 265 instance()->UnlockEndpoint(DummyEndpoint()); |
| 260 RunUntilIdle(); | 266 RunUntilIdle(); |
| 261 EXPECT_TRUE(waiters[1].called()); | 267 EXPECT_TRUE(waiters[1].called()); |
| 262 instance()->RememberSocket(&dummy_sockets[1], DummyEndpoint()); | 268 instance()->RememberSocket(&dummy_sockets[1], DummyEndpoint()); |
| 263 | 269 |
| 264 UnlockDummyEndpoint(1); | 270 UnlockDummyEndpoint(1); |
| 265 } | 271 } |
| 266 | 272 |
| 267 // Calling UnlockSocket() after UnlockEndpoint() does nothing. | 273 // Calling UnlockSocket() after UnlockEndpoint() does nothing. |
| 268 TEST_F(WebSocketEndpointLockManagerTest, | 274 TEST_F(WebSocketEndpointLockManagerTest, |
| 269 UnlockSocketAfterUnlockEndpointDoesNothing) { | 275 UnlockSocketAfterUnlockEndpointDoesNothing) { |
| 270 FakeWaiter waiters[3]; | 276 FakeWaiter waiters[3]; |
| 271 FakeStreamSocket dummy_socket; | 277 FakeStreamSocket dummy_socket; |
| 272 | 278 |
| 273 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); | 279 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk()); |
| 274 EXPECT_EQ(ERR_IO_PENDING, | 280 EXPECT_EQ(ERR_IO_PENDING, |
| 275 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); | 281 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); |
| 276 EXPECT_EQ(ERR_IO_PENDING, | 282 EXPECT_EQ(ERR_IO_PENDING, |
| 277 instance()->LockEndpoint(DummyEndpoint(), &waiters[2])); | 283 instance()->LockEndpoint(DummyEndpoint(), &waiters[2])); |
| 278 instance()->RememberSocket(&dummy_socket, DummyEndpoint()); | 284 instance()->RememberSocket(&dummy_socket, DummyEndpoint()); |
| 279 instance()->UnlockEndpoint(DummyEndpoint()); | 285 instance()->UnlockEndpoint(DummyEndpoint()); |
| 280 instance()->UnlockSocket(&dummy_socket); | 286 instance()->UnlockSocket(&dummy_socket); |
| 281 RunUntilIdle(); | 287 RunUntilIdle(); |
| 282 EXPECT_TRUE(waiters[1].called()); | 288 EXPECT_TRUE(waiters[1].called()); |
| 283 EXPECT_FALSE(waiters[2].called()); | 289 EXPECT_FALSE(waiters[2].called()); |
| 284 | 290 |
| 285 UnlockDummyEndpoint(2); | 291 UnlockDummyEndpoint(2); |
| 286 } | 292 } |
| 287 | 293 |
| 288 // UnlockEndpoint() should always be asynchronous. | 294 // UnlockEndpoint() should always be asynchronous. |
| 289 TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsAsynchronous) { | 295 TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsAsynchronous) { |
| 290 FakeWaiter waiters[2]; | 296 FakeWaiter waiters[2]; |
| 291 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); | 297 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk()); |
| 292 EXPECT_EQ(ERR_IO_PENDING, | 298 EXPECT_EQ(ERR_IO_PENDING, |
| 293 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); | 299 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); |
| 294 | 300 |
| 295 instance()->UnlockEndpoint(DummyEndpoint()); | 301 instance()->UnlockEndpoint(DummyEndpoint()); |
| 296 EXPECT_FALSE(waiters[1].called()); | 302 EXPECT_FALSE(waiters[1].called()); |
| 297 RunUntilIdle(); | 303 RunUntilIdle(); |
| 298 EXPECT_TRUE(waiters[1].called()); | 304 EXPECT_TRUE(waiters[1].called()); |
| 299 | 305 |
| 300 UnlockDummyEndpoint(1); | 306 UnlockDummyEndpoint(1); |
| 301 } | 307 } |
| 302 | 308 |
| 303 // UnlockEndpoint() should normally have a delay. | 309 // UnlockEndpoint() should normally have a delay. |
| 304 TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsDelayed) { | 310 TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsDelayed) { |
| 305 using base::TimeTicks; | 311 using base::TimeTicks; |
| 306 | 312 |
| 307 // This 1ms delay is too short for very slow environments (usually those | 313 // This 1ms delay is too short for very slow environments (usually those |
| 308 // running memory checkers). In those environments, the code takes >1ms to run | 314 // running memory checkers). In those environments, the code takes >1ms to run |
| 309 // and no delay is needed. Rather than increase the delay and slow down the | 315 // and no delay is needed. Rather than increase the delay and slow down the |
| 310 // test everywhere, the test doesn't explicitly verify that a delay has been | 316 // test everywhere, the test doesn't explicitly verify that a delay has been |
| 311 // applied. Instead it just verifies that the whole thing took >=1ms. 1ms is | 317 // applied. Instead it just verifies that the whole thing took >=1ms. 1ms is |
| 312 // easily enough for normal compiles even on Android, so the fact that there | 318 // easily enough for normal compiles even on Android, so the fact that there |
| 313 // is a delay is still checked on every platform. | 319 // is a delay is still checked on every platform. |
| 314 const base::TimeDelta unlock_delay = base::TimeDelta::FromMilliseconds(1); | 320 const base::TimeDelta unlock_delay = base::TimeDelta::FromMilliseconds(1); |
| 315 instance()->SetUnlockDelayForTesting(unlock_delay); | 321 instance()->SetUnlockDelayForTesting(unlock_delay); |
| 316 FakeWaiter fake_waiter; | 322 FakeWaiter fake_waiter; |
| 317 BlockingWaiter blocking_waiter; | 323 BlockingWaiter blocking_waiter; |
| 318 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &fake_waiter)); | 324 EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &fake_waiter), IsOk()); |
| 319 EXPECT_EQ(ERR_IO_PENDING, | 325 EXPECT_EQ(ERR_IO_PENDING, |
| 320 instance()->LockEndpoint(DummyEndpoint(), &blocking_waiter)); | 326 instance()->LockEndpoint(DummyEndpoint(), &blocking_waiter)); |
| 321 | 327 |
| 322 TimeTicks before_unlock = TimeTicks::Now(); | 328 TimeTicks before_unlock = TimeTicks::Now(); |
| 323 instance()->UnlockEndpoint(DummyEndpoint()); | 329 instance()->UnlockEndpoint(DummyEndpoint()); |
| 324 blocking_waiter.WaitForLock(); | 330 blocking_waiter.WaitForLock(); |
| 325 TimeTicks after_unlock = TimeTicks::Now(); | 331 TimeTicks after_unlock = TimeTicks::Now(); |
| 326 EXPECT_GE(after_unlock - before_unlock, unlock_delay); | 332 EXPECT_GE(after_unlock - before_unlock, unlock_delay); |
| 327 instance()->SetUnlockDelayForTesting(base::TimeDelta()); | 333 instance()->SetUnlockDelayForTesting(base::TimeDelta()); |
| 328 UnlockDummyEndpoint(1); | 334 UnlockDummyEndpoint(1); |
| 329 } | 335 } |
| 330 | 336 |
| 331 } // namespace | 337 } // namespace |
| 332 | 338 |
| 333 } // namespace net | 339 } // namespace net |
| OLD | NEW |