Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Side by Side Diff: remoting/host/security_key/security_key_auth_handler_win_unittest.cc

Issue 2663103003: Fixing Intermittent SecurityKey Unittest Failures (Closed)
Patch Set: Fixing some threading issues in the current unit tests. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "remoting/host/security_key/security_key_auth_handler.h" 5 #include "remoting/host/security_key/security_key_auth_handler.h"
6 6
7 #include <cstdint> 7 #include <cstdint>
8 #include <memory> 8 #include <memory>
9 #include <string> 9 #include <string>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/weak_ptr.h" 13 #include "base/memory/weak_ptr.h"
14 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h" 15 #include "base/run_loop.h"
16 #include "ipc/ipc_channel.h" 16 #include "ipc/ipc_channel.h"
17 #include "ipc/ipc_listener.h" 17 #include "ipc/ipc_listener.h"
18 #include "ipc/ipc_message.h" 18 #include "ipc/ipc_message.h"
19 #include "ipc/ipc_message_macros.h" 19 #include "ipc/ipc_message_macros.h"
20 #include "mojo/edk/embedder/scoped_ipc_support.h"
21 #include "remoting/host/host_mock_objects.h" 20 #include "remoting/host/host_mock_objects.h"
22 #include "remoting/host/security_key/fake_security_key_ipc_client.h" 21 #include "remoting/host/security_key/fake_security_key_ipc_client.h"
23 #include "remoting/host/security_key/fake_security_key_ipc_server.h" 22 #include "remoting/host/security_key/fake_security_key_ipc_server.h"
24 #include "remoting/host/security_key/security_key_ipc_constants.h" 23 #include "remoting/host/security_key/security_key_ipc_constants.h"
25 #include "testing/gmock/include/gmock/gmock.h" 24 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
27 26
28 namespace { 27 namespace {
29 const int kConnectionId1 = 1; 28 const int kConnectionId1 = 1;
30 const int kConnectionId2 = 2; 29 const int kConnectionId2 = 2;
31 } // namespace 30 } // namespace
32 31
33 namespace remoting { 32 namespace remoting {
34 33
35 class SecurityKeyAuthHandlerWinTest : public testing::Test { 34 class SecurityKeyAuthHandlerWinTest : public testing::Test {
36 public: 35 public:
37 SecurityKeyAuthHandlerWinTest(); 36 SecurityKeyAuthHandlerWinTest();
38 ~SecurityKeyAuthHandlerWinTest() override; 37 ~SecurityKeyAuthHandlerWinTest() override;
39 38
40 // Passed to the object used for testing to be called back to signal 39 // Passed to the object used for testing to be called back to signal
41 // completion of an IPC channel state change or reception of an IPC message. 40 // completion of an IPC channel state change or reception of an IPC message.
42 void OperationComplete(); 41 void OperationComplete();
43 42
44 protected: 43 protected:
45 // Waits until the current |run_loop_| instance is signaled, then resets it. 44 // Waits until the current |run_loop_| instance is signaled, then resets it.
46 void WaitForOperationComplete(); 45 void WaitForOperationComplete();
47 46
47 // Waits until all tasks have been run on the current message loop.
48 void WaitForPendingOperations();
49
48 // Used as a callback given to the object under test, expected to be called 50 // Used as a callback given to the object under test, expected to be called
49 // back when a security key request is received by it. 51 // back when a security key request is received by it.
50 void SendMessageToClient(int connection_id, const std::string& data); 52 void SendMessageToClient(int connection_id, const std::string& data);
51 53
52 // Creates a new security key connection on the object under test. 54 // Creates a new security key connection on the object under test.
53 void CreateSecurityKeyConnection( 55 void CreateSecurityKeyConnection(
54 const mojo::edk::NamedPlatformHandle& channel_handle); 56 const mojo::edk::NamedPlatformHandle& channel_handle);
55 57
56 // Uses |fake_ipc_client| to connect to the IPC server channel, it then 58 // Uses |fake_ipc_client| to connect to the IPC server channel, it then
57 // validates internal state of the object under test and closes the connection 59 // validates internal state of the object under test and closes the connection
(...skipping 23 matching lines...) Expand all
81 const base::WeakPtr<FakeSecurityKeyIpcServer>& fake_ipc_server, 83 const base::WeakPtr<FakeSecurityKeyIpcServer>& fake_ipc_server,
82 int connection_id); 84 int connection_id);
83 85
84 // Returns a unique IPC channel handle which prevents conflicts when running 86 // Returns a unique IPC channel handle which prevents conflicts when running
85 // tests concurrently. 87 // tests concurrently.
86 std::string GetUniqueTestChannelHandle(); 88 std::string GetUniqueTestChannelHandle();
87 89
88 // IPC tests require a valid MessageLoop to run. 90 // IPC tests require a valid MessageLoop to run.
89 base::MessageLoopForIO message_loop_; 91 base::MessageLoopForIO message_loop_;
90 92
91 mojo::edk::ScopedIPCSupport ipc_support_;
92
93 // Used to allow |message_loop_| to run during tests. The instance is reset 93 // Used to allow |message_loop_| to run during tests. The instance is reset
94 // after each stage of the tests has been completed. 94 // after each stage of the tests has been completed.
95 std::unique_ptr<base::RunLoop> run_loop_; 95 std::unique_ptr<base::RunLoop> run_loop_;
96 96
97 // The object under test. 97 // The object under test.
98 std::unique_ptr<SecurityKeyAuthHandler> auth_handler_; 98 std::unique_ptr<SecurityKeyAuthHandler> auth_handler_;
99 99
100 // Set as the default factory to create SecurityKeyIpcServerFactory 100 // Set as the default factory to create SecurityKeyIpcServerFactory
101 // instances, this class will track each objects creation and allow the tests 101 // instances, this class will track each objects creation and allow the tests
102 // to access it and use it for driving tests and validating state. 102 // to access it and use it for driving tests and validating state.
103 FakeSecurityKeyIpcServerFactory ipc_server_factory_; 103 FakeSecurityKeyIpcServerFactory ipc_server_factory_;
104 104
105 // Used to validate the object under test uses the correct ID when 105 // Used to validate the object under test uses the correct ID when
106 // communicating over the IPC channel. 106 // communicating over the IPC channel.
107 int last_connection_id_received_ = -1; 107 int last_connection_id_received_ = -1;
108 108
109 // Stores the contents of the last IPC message received for validation. 109 // Stores the contents of the last IPC message received for validation.
110 std::string last_message_received_; 110 std::string last_message_received_;
111 111
112 private: 112 private:
113 testing::NiceMock<MockClientSessionDetails> mock_client_session_details_; 113 testing::NiceMock<MockClientSessionDetails> mock_client_session_details_;
114 114
115 DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerWinTest); 115 DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerWinTest);
116 }; 116 };
117 117
118 SecurityKeyAuthHandlerWinTest::SecurityKeyAuthHandlerWinTest() 118 SecurityKeyAuthHandlerWinTest::SecurityKeyAuthHandlerWinTest()
119 : ipc_support_(message_loop_.task_runner(), 119 : run_loop_(new base::RunLoop()) {
120 mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST),
121 run_loop_(new base::RunLoop()) {
122 auth_handler_ = remoting::SecurityKeyAuthHandler::Create( 120 auth_handler_ = remoting::SecurityKeyAuthHandler::Create(
123 &mock_client_session_details_, 121 &mock_client_session_details_,
124 base::Bind(&SecurityKeyAuthHandlerWinTest::SendMessageToClient, 122 base::Bind(&SecurityKeyAuthHandlerWinTest::SendMessageToClient,
125 base::Unretained(this)), 123 base::Unretained(this)),
126 /*file_task_runner=*/nullptr); 124 /*file_task_runner=*/nullptr);
127 } 125 }
128 126
129 SecurityKeyAuthHandlerWinTest::~SecurityKeyAuthHandlerWinTest() {} 127 SecurityKeyAuthHandlerWinTest::~SecurityKeyAuthHandlerWinTest() {}
130 128
131 void SecurityKeyAuthHandlerWinTest::OperationComplete() { 129 void SecurityKeyAuthHandlerWinTest::OperationComplete() {
132 run_loop_->Quit(); 130 run_loop_->Quit();
133 } 131 }
134 132
135 void SecurityKeyAuthHandlerWinTest::WaitForOperationComplete() { 133 void SecurityKeyAuthHandlerWinTest::WaitForOperationComplete() {
136 run_loop_->Run(); 134 run_loop_->Run();
137 run_loop_.reset(new base::RunLoop()); 135 run_loop_.reset(new base::RunLoop());
138 } 136 }
139 137
138 void SecurityKeyAuthHandlerWinTest::WaitForPendingOperations() {
139 // Ensure we have a new, runnable instance.
140 run_loop_.reset(new base::RunLoop());
141
142 // Run until there are no pending work items in the queue.
143 run_loop_->RunUntilIdle();
144
145 // Create a new instance for future operations.
146 run_loop_.reset(new base::RunLoop());
147 }
148
140 void SecurityKeyAuthHandlerWinTest::SendMessageToClient( 149 void SecurityKeyAuthHandlerWinTest::SendMessageToClient(
141 int connection_id, 150 int connection_id,
142 const std::string& data) { 151 const std::string& data) {
143 last_connection_id_received_ = connection_id; 152 last_connection_id_received_ = connection_id;
144 last_message_received_ = data; 153 last_message_received_ = data;
145 OperationComplete(); 154 OperationComplete();
146 } 155 }
147 156
148 void SecurityKeyAuthHandlerWinTest::CreateSecurityKeyConnection( 157 void SecurityKeyAuthHandlerWinTest::CreateSecurityKeyConnection(
149 const mojo::edk::NamedPlatformHandle& channel_handle) { 158 const mojo::edk::NamedPlatformHandle& channel_handle) {
150 ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest()); 159 ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest());
151 160
152 remoting::SetSecurityKeyIpcChannelForTest(channel_handle); 161 remoting::SetSecurityKeyIpcChannelForTest(channel_handle);
153 162
154 // Create a new SecurityKey IPC Server connection. 163 // Create a new SecurityKey IPC Server connection.
155 auth_handler_->CreateSecurityKeyConnection(); 164 auth_handler_->CreateSecurityKeyConnection();
156 } 165 }
157 166
158 void SecurityKeyAuthHandlerWinTest::EstablishIpcConnection( 167 void SecurityKeyAuthHandlerWinTest::EstablishIpcConnection(
159 FakeSecurityKeyIpcClient* fake_ipc_client, 168 FakeSecurityKeyIpcClient* fake_ipc_client,
160 int expected_connection_id, 169 int expected_connection_id,
161 const mojo::edk::NamedPlatformHandle& channel_handle, 170 const mojo::edk::NamedPlatformHandle& channel_handle,
162 bool close_connection) { 171 bool close_connection) {
163 size_t expected_connection_count = 172 size_t expected_connection_count =
164 auth_handler_->GetActiveConnectionCountForTest() + 1; 173 auth_handler_->GetActiveConnectionCountForTest() + 1;
165 174
166 ASSERT_FALSE(auth_handler_->IsValidConnectionId(expected_connection_id)); 175 ASSERT_FALSE(auth_handler_->IsValidConnectionId(expected_connection_id));
176 fake_ipc_client->set_on_channel_connected_callback(
177 base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
178 base::Unretained(this)));
167 ASSERT_TRUE(fake_ipc_client->ConnectViaIpc(channel_handle)); 179 ASSERT_TRUE(fake_ipc_client->ConnectViaIpc(channel_handle));
168 WaitForOperationComplete(); 180 WaitForOperationComplete();
169 181
182 // Retrieve the IPC server instance created when the client connected.
183 base::WeakPtr<FakeSecurityKeyIpcServer> fake_ipc_server =
184 ipc_server_factory_.GetIpcServerObject(expected_connection_id);
185 ASSERT_TRUE(fake_ipc_server.get());
186 fake_ipc_server->SendConnectionReadyMessage();
187 WaitForOperationComplete();
188
170 // Verify the internal state of the SecurityKeyAuthHandler is correct. 189 // Verify the internal state of the SecurityKeyAuthHandler is correct.
171 ASSERT_TRUE(auth_handler_->IsValidConnectionId(expected_connection_id)); 190 ASSERT_TRUE(auth_handler_->IsValidConnectionId(expected_connection_id));
172 ASSERT_EQ(expected_connection_count, 191 ASSERT_EQ(expected_connection_count,
173 auth_handler_->GetActiveConnectionCountForTest()); 192 auth_handler_->GetActiveConnectionCountForTest());
174 193
175 if (close_connection) { 194 if (close_connection) {
176 fake_ipc_client->CloseIpcConnection(); 195 fake_ipc_client->CloseIpcConnection();
177 WaitForOperationComplete(); 196 WaitForOperationComplete();
178 } 197 }
179 } 198 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 std::string SecurityKeyAuthHandlerWinTest::GetUniqueTestChannelHandle() { 260 std::string SecurityKeyAuthHandlerWinTest::GetUniqueTestChannelHandle() {
242 std::string channel_name("Uber_Awesome_Super_Mega_Test_Channel."); 261 std::string channel_name("Uber_Awesome_Super_Mega_Test_Channel.");
243 channel_name.append(IPC::Channel::GenerateUniqueRandomChannelID()); 262 channel_name.append(IPC::Channel::GenerateUniqueRandomChannelID());
244 263
245 return channel_name; 264 return channel_name;
246 } 265 }
247 266
248 TEST_F(SecurityKeyAuthHandlerWinTest, HandleSingleSecurityKeyRequest) { 267 TEST_F(SecurityKeyAuthHandlerWinTest, HandleSingleSecurityKeyRequest) {
249 mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelHandle()); 268 mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelHandle());
250 CreateSecurityKeyConnection(channel_handle); 269 CreateSecurityKeyConnection(channel_handle);
251
252 ASSERT_FALSE(auth_handler_->IsValidConnectionId(kConnectionId1)); 270 ASSERT_FALSE(auth_handler_->IsValidConnectionId(kConnectionId1));
253 271
254 // Create a fake client and connect to the IPC server channel. 272 // Create a fake client and connect to the IPC server channel.
255 FakeSecurityKeyIpcClient fake_ipc_client( 273 FakeSecurityKeyIpcClient fake_ipc_client(
256 base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete, 274 base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
257 base::Unretained(this))); 275 base::Unretained(this)));
258 EstablishIpcConnection(&fake_ipc_client, kConnectionId1, channel_handle, 276 EstablishIpcConnection(&fake_ipc_client, kConnectionId1, channel_handle,
259 /*close_connection=*/true); 277 /*close_connection=*/true);
260 278
261 // Retrieve the IPC server instance created when the client connected. 279 // Retrieve the IPC server instance created when the client connected.
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 ASSERT_FALSE(fake_ipc_server.get()); 441 ASSERT_FALSE(fake_ipc_server.get());
424 ASSERT_FALSE(auth_handler_->IsValidConnectionId(kConnectionId1)); 442 ASSERT_FALSE(auth_handler_->IsValidConnectionId(kConnectionId1));
425 ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest()); 443 ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest());
426 444
427 // Attempt to connect again after the error. 445 // Attempt to connect again after the error.
428 EstablishIpcConnection(&fake_ipc_client, kConnectionId2, channel_handle, 446 EstablishIpcConnection(&fake_ipc_client, kConnectionId2, channel_handle,
429 /*close_connection=*/true); 447 /*close_connection=*/true);
430 } 448 }
431 449
432 } // namespace remoting 450 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698