Chromium Code Reviews| Index: remoting/host/security_key/security_key_auth_handler_posix_unittest.cc |
| diff --git a/remoting/host/security_key/security_key_auth_handler_posix_unittest.cc b/remoting/host/security_key/security_key_auth_handler_posix_unittest.cc |
| index 52d5625d016ae60ca02e3c067f892ff0df67915f..7597233849ac27ad43c19460b5f5ed0a4b5fef35 100644 |
| --- a/remoting/host/security_key/security_key_auth_handler_posix_unittest.cc |
| +++ b/remoting/host/security_key/security_key_auth_handler_posix_unittest.cc |
| @@ -45,6 +45,8 @@ const unsigned char kRequestData[] = { |
| 0x5e, 0xa3, 0xbc, 0x02, 0x5b, 0xec, 0xe4, 0x4b, 0xae, 0x0e, 0xf2, 0xbd, |
| 0xc8, 0xaa}; |
| +const unsigned char kSshErrorData[] = {0x00, 0x00, 0x00, 0x01, 0x05}; |
|
Sergey Ulanov
2016/12/14 00:17:03
Pleaes use uint8_t instead of unsigned char
joedow
2016/12/14 00:41:35
Done.
|
| + |
| void RunUntilIdle() { |
| base::RunLoop run_loop; |
| run_loop.RunUntilIdle(); |
| @@ -125,17 +127,46 @@ class SecurityKeyAuthHandlerPosixTest : public testing::Test { |
| ASSERT_EQ(request_len, bytes_written); |
| } |
| - void WaitForAndVerifyHostMessage(int connection_id) { |
| - WaitForSendMessageToClient(); |
| - std::string expected_data; |
| - expected_data.reserve(sizeof(kRequestData) - 4); |
| + void WaitForResponseData(net::UnixDomainClientSocket* client_socket) { |
| + // The request data is reused for the response data. |
| + WaitForData(client_socket, sizeof(kRequestData)); |
| + } |
| + |
| + void WaitForErrorData(net::UnixDomainClientSocket* client_socket) { |
| + WaitForData(client_socket, sizeof(kSshErrorData)); |
| + } |
| - // Skip first four bytes and build up the response string. |
| - for (size_t i = 4; i < sizeof(kRequestData); ++i) { |
| - expected_data.append(1, static_cast<unsigned char>(kRequestData[i])); |
| + void WaitForData(net::UnixDomainClientSocket* socket, int request_len) { |
| + scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(request_len)); |
| + scoped_refptr<net::DrainableIOBuffer> read_buffer( |
| + new net::DrainableIOBuffer(buffer.get(), request_len)); |
| + net::TestCompletionCallback read_callback; |
| + int bytes_read = 0; |
| + while (bytes_read < request_len) { |
| + int read_result = |
| + socket->Read(read_buffer.get(), read_buffer->BytesRemaining(), |
| + read_callback.callback()); |
| + read_result = read_callback.GetResult(read_result); |
| + ASSERT_GT(read_result, 0); |
| + bytes_read += read_result; |
| + ASSERT_LE(bytes_read, request_len); |
| + read_buffer->DidConsume(bytes_read); |
| } |
| + ASSERT_EQ(request_len, bytes_read); |
| + } |
| + |
| + const std::string& GetExpectedRequestData() { |
| + static std::string expected_data; |
|
Sergey Ulanov
2016/12/14 00:17:03
Any reason this needs to be static?
Style guide do
joedow
2016/12/14 00:41:35
No, I'll make it a class member.
|
| + if (expected_data.empty()) { |
| + expected_data.reserve(sizeof(kRequestData) - 4); |
| - CheckHostDataMessage(connection_id, expected_data); |
| + // Skip first four bytes and build up the response string. |
| + for (size_t i = 4; i < sizeof(kRequestData); ++i) { |
|
Sergey Ulanov
2016/12/14 00:17:03
This loop can be expressed with one assign() call:
joedow
2016/12/14 00:41:35
This is much cleaner, thanks!
|
| + expected_data.append(1, static_cast<unsigned char>(kRequestData[i])); |
| + } |
| + } |
| + |
| + return expected_data; |
| } |
| protected: |
| @@ -171,7 +202,11 @@ TEST_F(SecurityKeyAuthHandlerPosixTest, NotClosedAfterRequest) { |
| // Write the request and verify the response. |
| WriteRequestData(&client_socket); |
| - WaitForAndVerifyHostMessage(1); |
| + WaitForSendMessageToClient(); |
| + CheckHostDataMessage(1, GetExpectedRequestData()); |
| + |
| + auth_handler_->SendClientResponse(1, GetExpectedRequestData()); |
| + WaitForResponseData(&client_socket); |
| // Verify the connection is now valid. |
| ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| @@ -191,14 +226,29 @@ TEST_F(SecurityKeyAuthHandlerPosixTest, HandleTwoRequests) { |
| // Write the request and verify the response. |
| WriteRequestData(&client_socket); |
| - WaitForAndVerifyHostMessage(1); |
| + WaitForSendMessageToClient(); |
| + CheckHostDataMessage(1, GetExpectedRequestData()); |
| // Verify the connection is now valid. |
| ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| + // Send a 'client' response to the socket and verify the data is received. |
| + auth_handler_->SendClientResponse(1, GetExpectedRequestData()); |
| + WaitForResponseData(&client_socket); |
| + |
| + // Verify the connection is still valid. |
| + ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| + |
| // Repeat the request/response cycle. |
| WriteRequestData(&client_socket); |
| - WaitForAndVerifyHostMessage(1); |
| + WaitForSendMessageToClient(); |
| + CheckHostDataMessage(1, GetExpectedRequestData()); |
| + |
| + // Verify the connection is still valid. |
| + ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| + |
| + auth_handler_->SendClientResponse(1, GetExpectedRequestData()); |
| + WaitForResponseData(&client_socket); |
| // Verify the connection is still valid. |
| ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| @@ -219,36 +269,58 @@ TEST_F(SecurityKeyAuthHandlerPosixTest, HandleTwoIndependentRequests) { |
| // Write the request and verify the response. |
| WriteRequestData(&client_socket); |
| - WaitForAndVerifyHostMessage(1); |
| + WaitForSendMessageToClient(); |
| + CheckHostDataMessage(1, GetExpectedRequestData()); |
| // Verify the first connection is now valid. |
| ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| + // Send a 'client' response to the socket and verify the data is received. |
| + auth_handler_->SendClientResponse(1, GetExpectedRequestData()); |
| + WaitForResponseData(&client_socket); |
| + |
| + // Verify the connection is still valid. |
| + ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| + |
| // Disconnect and establish a new connection. |
| client_socket.Disconnect(); |
| + |
| rv = client_socket.Connect(connect_callback.callback()); |
| ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); |
| // Repeat the request/response cycle. |
| WriteRequestData(&client_socket); |
| - WaitForAndVerifyHostMessage(2); |
| + WaitForSendMessageToClient(); |
| + CheckHostDataMessage(2, GetExpectedRequestData()); |
| + |
| + // Verify the connection is now valid. |
| + ASSERT_TRUE(auth_handler_->IsValidConnectionId(2)); |
| + |
| + // Send a 'client' response to the socket and verify the data is received. |
| + auth_handler_->SendClientResponse(2, GetExpectedRequestData()); |
| + WaitForResponseData(&client_socket); |
| // Verify the second connection is valid and the first is not. |
| ASSERT_TRUE(auth_handler_->IsValidConnectionId(2)); |
| ASSERT_FALSE(auth_handler_->IsValidConnectionId(1)); |
| - |
| - // Verify that the initial socket was released properly. |
| ASSERT_EQ(1u, auth_handler_->GetActiveConnectionCountForTest()); |
| } |
| -TEST_F(SecurityKeyAuthHandlerPosixTest, DidReadTimeout) { |
| +TEST_F(SecurityKeyAuthHandlerPosixTest, DoReadTimeout) { |
| CreateSocketAndWait(); |
| + auth_handler_->SetRequestTimeoutForTest(base::TimeDelta()); |
| + |
| net::UnixDomainClientSocket client_socket(socket_path_.value(), false); |
| net::TestCompletionCallback connect_callback; |
| int rv = client_socket.Connect(connect_callback.callback()); |
| ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); |
| - auth_handler_->SetRequestTimeoutForTest(base::TimeDelta()); |
| + |
| + // SSH Error should be received when the connection times out. |
| + WaitForErrorData(&client_socket); |
| + |
| + // Connection should no longer be valid. |
| + ASSERT_FALSE(auth_handler_->IsValidConnectionId(1)); |
| ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest()); |
| } |
| @@ -260,8 +332,27 @@ TEST_F(SecurityKeyAuthHandlerPosixTest, ClientErrorMessageDelivered) { |
| int rv = client_socket.Connect(connect_callback.callback()); |
| ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); |
| + // Write the request and verify the response. This ensures the socket has |
| + // been created and is working before sending the error to tear it down. |
| + WriteRequestData(&client_socket); |
| + WaitForSendMessageToClient(); |
| + CheckHostDataMessage(1, GetExpectedRequestData()); |
| + |
| + // Send a 'client' response to the socket and verify the data is received. |
| + auth_handler_->SendClientResponse(1, GetExpectedRequestData()); |
| + WaitForResponseData(&client_socket); |
| + |
| + ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| + ASSERT_EQ(1u, auth_handler_->GetActiveConnectionCountForTest()); |
| + |
| auth_handler_->SendErrorAndCloseConnection(1); |
| + |
| + // Connection should be removed immediately. |
| + ASSERT_FALSE(auth_handler_->IsValidConnectionId(1)); |
| ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest()); |
| + |
| + // SSH Error should be received. |
| + WaitForErrorData(&client_socket); |
| } |
| } // namespace remoting |