<webview>: Move name attribute to chrome
[chromium-blink-merge.git] / remoting / host / client_session_unittest.cc
blobf28050a9a43fab6da148ac0752f2736c928c3826
1 // Copyright (c) 2012 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 "base/message_loop/message_loop.h"
6 #include "base/test/test_simple_task_runner.h"
7 #include "remoting/base/auto_thread_task_runner.h"
8 #include "remoting/base/constants.h"
9 #include "remoting/host/audio_capturer.h"
10 #include "remoting/host/client_session.h"
11 #include "remoting/host/desktop_environment.h"
12 #include "remoting/host/host_mock_objects.h"
13 #include "remoting/host/screen_capturer_fake.h"
14 #include "remoting/protocol/protocol_mock_objects.h"
15 #include "testing/gmock/include/gmock/gmock-matchers.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
18 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
19 #include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
21 namespace remoting {
23 using protocol::MockConnectionToClient;
24 using protocol::MockClientStub;
25 using protocol::MockHostStub;
26 using protocol::MockInputStub;
27 using protocol::MockSession;
28 using protocol::MockVideoStub;
29 using protocol::SessionConfig;
31 using testing::_;
32 using testing::AnyNumber;
33 using testing::AtMost;
34 using testing::DeleteArg;
35 using testing::DoAll;
36 using testing::Expectation;
37 using testing::Return;
38 using testing::ReturnRef;
39 using testing::Sequence;
40 using testing::StrEq;
41 using testing::StrictMock;
43 namespace {
45 ACTION_P2(InjectClipboardEvent, connection, event) {
46 connection->clipboard_stub()->InjectClipboardEvent(event);
49 ACTION_P2(InjectKeyEvent, connection, event) {
50 connection->input_stub()->InjectKeyEvent(event);
53 ACTION_P2(InjectMouseEvent, connection, event) {
54 connection->input_stub()->InjectMouseEvent(event);
57 ACTION_P2(LocalMouseMoved, client_session, event) {
58 client_session->OnLocalMouseMoved(
59 webrtc::DesktopVector(event.x(), event.y()));
62 ACTION_P2(SetGnubbyAuthHandlerForTesting, client_session, gnubby_auth_handler) {
63 client_session->SetGnubbyAuthHandlerForTesting(gnubby_auth_handler);
66 ACTION_P2(DeliverClientMessage, client_session, message) {
67 client_session->DeliverClientMessage(message);
72 class ClientSessionTest : public testing::Test {
73 public:
74 ClientSessionTest() : client_jid_("user@domain/rest-of-jid") {}
76 virtual void SetUp() OVERRIDE;
77 virtual void TearDown() OVERRIDE;
79 // Disconnects the client session.
80 void DisconnectClientSession();
82 // Stops and releases the ClientSession, allowing the MessageLoop to quit.
83 void StopClientSession();
85 protected:
86 // Creates a DesktopEnvironment with a fake webrtc::ScreenCapturer, to mock
87 // DesktopEnvironmentFactory::Create().
88 DesktopEnvironment* CreateDesktopEnvironment();
90 // Returns |input_injector_| created and initialized by SetUp(), to mock
91 // DesktopEnvironment::CreateInputInjector().
92 InputInjector* CreateInputInjector();
94 // Creates a fake webrtc::ScreenCapturer, to mock
95 // DesktopEnvironment::CreateVideoCapturer().
96 webrtc::ScreenCapturer* CreateVideoCapturer();
98 // Notifies the client session that the client connection has been
99 // authenticated and channels have been connected. This effectively enables
100 // the input pipe line and starts video capturing.
101 void ConnectClientSession();
103 // Invoked when the last reference to the AutoThreadTaskRunner has been
104 // released and quits the message loop to finish the test.
105 void QuitMainMessageLoop();
107 // Message loop passed to |client_session_| to perform all functions on.
108 base::MessageLoop message_loop_;
110 // ClientSession instance under test.
111 scoped_ptr<ClientSession> client_session_;
113 // ClientSession::EventHandler mock for use in tests.
114 MockClientSessionEventHandler session_event_handler_;
116 // Storage for values to be returned by the protocol::Session mock.
117 SessionConfig session_config_;
118 const std::string client_jid_;
120 // Stubs returned to |client_session_| components by |connection_|.
121 MockClientStub client_stub_;
122 MockVideoStub video_stub_;
124 // DesktopEnvironment owns |input_injector_|, but input injection tests need
125 // to express expectations on it.
126 scoped_ptr<MockInputInjector> input_injector_;
128 // ClientSession owns |connection_| but tests need it to inject fake events.
129 MockConnectionToClient* connection_;
131 scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory_;
134 void ClientSessionTest::SetUp() {
135 // Arrange to run |message_loop_| until no components depend on it.
136 scoped_refptr<AutoThreadTaskRunner> ui_task_runner = new AutoThreadTaskRunner(
137 message_loop_.message_loop_proxy(),
138 base::Bind(&ClientSessionTest::QuitMainMessageLoop,
139 base::Unretained(this)));
141 desktop_environment_factory_.reset(new MockDesktopEnvironmentFactory());
142 EXPECT_CALL(*desktop_environment_factory_, CreatePtr())
143 .Times(AnyNumber())
144 .WillRepeatedly(Invoke(this,
145 &ClientSessionTest::CreateDesktopEnvironment));
146 EXPECT_CALL(*desktop_environment_factory_, SupportsAudioCapture())
147 .Times(AnyNumber())
148 .WillRepeatedly(Return(false));
150 input_injector_.reset(new MockInputInjector());
152 session_config_ = SessionConfig::ForTest();
154 // Mock protocol::Session APIs called directly by ClientSession.
155 protocol::MockSession* session = new MockSession();
156 EXPECT_CALL(*session, config()).WillRepeatedly(ReturnRef(session_config_));
157 EXPECT_CALL(*session, jid()).WillRepeatedly(ReturnRef(client_jid_));
158 EXPECT_CALL(*session, SetEventHandler(_));
160 // Mock protocol::ConnectionToClient APIs called directly by ClientSession.
161 // HostStub is not touched by ClientSession, so we can safely pass NULL.
162 scoped_ptr<MockConnectionToClient> connection(
163 new MockConnectionToClient(session, NULL));
164 EXPECT_CALL(*connection, session()).WillRepeatedly(Return(session));
165 EXPECT_CALL(*connection, client_stub())
166 .WillRepeatedly(Return(&client_stub_));
167 EXPECT_CALL(*connection, video_stub()).WillRepeatedly(Return(&video_stub_));
168 EXPECT_CALL(*connection, Disconnect());
169 connection_ = connection.get();
171 client_session_.reset(new ClientSession(
172 &session_event_handler_,
173 ui_task_runner, // Audio thread.
174 ui_task_runner, // Input thread.
175 ui_task_runner, // Capture thread.
176 ui_task_runner, // Encode thread.
177 ui_task_runner, // Network thread.
178 ui_task_runner, // UI thread.
179 connection.PassAs<protocol::ConnectionToClient>(),
180 desktop_environment_factory_.get(),
181 base::TimeDelta(),
182 NULL));
185 void ClientSessionTest::TearDown() {
186 // Verify that the client session has been stopped.
187 EXPECT_TRUE(!client_session_);
190 void ClientSessionTest::DisconnectClientSession() {
191 client_session_->DisconnectSession();
192 // MockSession won't trigger OnConnectionClosed, so fake it.
193 client_session_->OnConnectionClosed(client_session_->connection(),
194 protocol::OK);
197 void ClientSessionTest::StopClientSession() {
198 client_session_.reset();
200 desktop_environment_factory_.reset();
203 DesktopEnvironment* ClientSessionTest::CreateDesktopEnvironment() {
204 MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment();
205 EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr())
206 .Times(0);
207 EXPECT_CALL(*desktop_environment, CreateInputInjectorPtr())
208 .WillOnce(Invoke(this, &ClientSessionTest::CreateInputInjector));
209 EXPECT_CALL(*desktop_environment, CreateScreenControlsPtr())
210 .Times(AtMost(1));
211 EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr())
212 .WillOnce(Invoke(this, &ClientSessionTest::CreateVideoCapturer));
213 EXPECT_CALL(*desktop_environment, GetCapabilities())
214 .Times(AtMost(1));
215 EXPECT_CALL(*desktop_environment, SetCapabilities(_))
216 .Times(AtMost(1));
218 return desktop_environment;
221 InputInjector* ClientSessionTest::CreateInputInjector() {
222 EXPECT_TRUE(input_injector_);
223 return input_injector_.release();
226 webrtc::ScreenCapturer* ClientSessionTest::CreateVideoCapturer() {
227 return new ScreenCapturerFake();
230 void ClientSessionTest::ConnectClientSession() {
231 client_session_->OnConnectionAuthenticated(client_session_->connection());
232 client_session_->OnConnectionChannelsConnected(client_session_->connection());
235 void ClientSessionTest::QuitMainMessageLoop() {
236 message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
239 MATCHER_P2(EqualsClipboardEvent, m, d, "") {
240 return (strcmp(arg.mime_type().c_str(), m) == 0 &&
241 memcmp(arg.data().data(), d, arg.data().size()) == 0);
244 TEST_F(ClientSessionTest, ClipboardStubFilter) {
245 protocol::ClipboardEvent clipboard_event1;
246 clipboard_event1.set_mime_type(kMimeTypeTextUtf8);
247 clipboard_event1.set_data("a");
249 protocol::ClipboardEvent clipboard_event2;
250 clipboard_event2.set_mime_type(kMimeTypeTextUtf8);
251 clipboard_event2.set_data("b");
253 protocol::ClipboardEvent clipboard_event3;
254 clipboard_event3.set_mime_type(kMimeTypeTextUtf8);
255 clipboard_event3.set_data("c");
257 Expectation authenticated =
258 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
259 .WillOnce(Return(true));
260 EXPECT_CALL(*input_injector_, StartPtr(_))
261 .After(authenticated);
262 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
263 .After(authenticated);
265 // Wait for the first video packet to be captured to make sure that
266 // the injected input will go though. Otherwise mouse events will be blocked
267 // by the mouse clamping filter.
268 Sequence s;
269 EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
270 .InSequence(s)
271 .After(authenticated)
272 .WillOnce(DoAll(
273 // This event should get through to the clipboard stub.
274 InjectClipboardEvent(connection_, clipboard_event2),
275 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
276 // This event should not get through to the clipboard stub,
277 // because the client has disconnected.
278 InjectClipboardEvent(connection_, clipboard_event3),
279 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
280 EXPECT_CALL(*input_injector_, InjectClipboardEvent(EqualsClipboardEvent(
281 kMimeTypeTextUtf8, "b")))
282 .InSequence(s);
283 EXPECT_CALL(session_event_handler_, OnSessionClosed(_))
284 .InSequence(s);
286 // This event should not get through to the clipboard stub,
287 // because the client isn't authenticated yet.
288 connection_->clipboard_stub()->InjectClipboardEvent(clipboard_event1);
290 ConnectClientSession();
291 message_loop_.Run();
294 namespace {
296 MATCHER_P2(EqualsUsbEvent, usb_keycode, pressed, "") {
297 return arg.usb_keycode() == (unsigned int)usb_keycode &&
298 arg.pressed() == pressed;
301 MATCHER_P2(EqualsMouseEvent, x, y, "") {
302 return arg.x() == x && arg.y() == y;
305 MATCHER_P2(EqualsMouseButtonEvent, button, down, "") {
306 return arg.button() == button && arg.button_down() == down;
309 } // namespace
311 TEST_F(ClientSessionTest, InputStubFilter) {
312 protocol::KeyEvent key_event1;
313 key_event1.set_pressed(true);
314 key_event1.set_usb_keycode(1);
316 protocol::KeyEvent key_event2_down;
317 key_event2_down.set_pressed(true);
318 key_event2_down.set_usb_keycode(2);
320 protocol::KeyEvent key_event2_up;
321 key_event2_up.set_pressed(false);
322 key_event2_up.set_usb_keycode(2);
324 protocol::KeyEvent key_event3;
325 key_event3.set_pressed(true);
326 key_event3.set_usb_keycode(3);
328 protocol::MouseEvent mouse_event1;
329 mouse_event1.set_x(100);
330 mouse_event1.set_y(101);
332 protocol::MouseEvent mouse_event2;
333 mouse_event2.set_x(200);
334 mouse_event2.set_y(201);
336 protocol::MouseEvent mouse_event3;
337 mouse_event3.set_x(300);
338 mouse_event3.set_y(301);
340 Expectation authenticated =
341 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
342 .WillOnce(Return(true));
343 EXPECT_CALL(*input_injector_, StartPtr(_))
344 .After(authenticated);
345 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
346 .After(authenticated);
348 // Wait for the first video packet to be captured to make sure that
349 // the injected input will go though. Otherwise mouse events will be blocked
350 // by the mouse clamping filter.
351 Sequence s;
352 EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
353 .InSequence(s)
354 .After(authenticated)
355 .WillOnce(DoAll(
356 // These events should get through to the input stub.
357 InjectKeyEvent(connection_, key_event2_down),
358 InjectKeyEvent(connection_, key_event2_up),
359 InjectMouseEvent(connection_, mouse_event2),
360 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
361 // These events should not get through to the input stub,
362 // because the client has disconnected.
363 InjectKeyEvent(connection_, key_event3),
364 InjectMouseEvent(connection_, mouse_event3),
365 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
366 EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(2, true)))
367 .InSequence(s);
368 EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(2, false)))
369 .InSequence(s);
370 EXPECT_CALL(*input_injector_, InjectMouseEvent(EqualsMouseEvent(200, 201)))
371 .InSequence(s);
372 EXPECT_CALL(session_event_handler_, OnSessionClosed(_))
373 .InSequence(s);
375 // These events should not get through to the input stub,
376 // because the client isn't authenticated yet.
377 connection_->input_stub()->InjectKeyEvent(key_event1);
378 connection_->input_stub()->InjectMouseEvent(mouse_event1);
380 ConnectClientSession();
381 message_loop_.Run();
384 TEST_F(ClientSessionTest, LocalInputTest) {
385 protocol::MouseEvent mouse_event1;
386 mouse_event1.set_x(100);
387 mouse_event1.set_y(101);
388 protocol::MouseEvent mouse_event2;
389 mouse_event2.set_x(200);
390 mouse_event2.set_y(201);
391 protocol::MouseEvent mouse_event3;
392 mouse_event3.set_x(300);
393 mouse_event3.set_y(301);
395 Expectation authenticated =
396 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
397 .WillOnce(Return(true));
398 EXPECT_CALL(*input_injector_, StartPtr(_))
399 .After(authenticated);
400 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
401 .After(authenticated);
403 // Wait for the first video packet to be captured to make sure that
404 // the injected input will go though. Otherwise mouse events will be blocked
405 // by the mouse clamping filter.
406 Sequence s;
407 EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
408 .InSequence(s)
409 .After(authenticated)
410 .WillOnce(DoAll(
411 // This event should get through to the input stub.
412 InjectMouseEvent(connection_, mouse_event1),
413 #if !defined(OS_WIN)
414 // The OS echoes the injected event back.
415 LocalMouseMoved(client_session_.get(), mouse_event1),
416 #endif // !defined(OS_WIN)
417 // This one should get throught as well.
418 InjectMouseEvent(connection_, mouse_event2),
419 // Now this is a genuine local event.
420 LocalMouseMoved(client_session_.get(), mouse_event1),
421 // This one should be blocked because of the previous local input
422 // event.
423 InjectMouseEvent(connection_, mouse_event3),
424 // TODO(jamiewalch): Verify that remote inputs are re-enabled
425 // eventually (via dependency injection, not sleep!)
426 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
427 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
428 EXPECT_CALL(*input_injector_, InjectMouseEvent(EqualsMouseEvent(100, 101)))
429 .InSequence(s);
430 EXPECT_CALL(*input_injector_, InjectMouseEvent(EqualsMouseEvent(200, 201)))
431 .InSequence(s);
432 EXPECT_CALL(session_event_handler_, OnSessionClosed(_))
433 .InSequence(s);
435 ConnectClientSession();
436 message_loop_.Run();
439 TEST_F(ClientSessionTest, RestoreEventState) {
440 protocol::KeyEvent key1;
441 key1.set_pressed(true);
442 key1.set_usb_keycode(1);
444 protocol::KeyEvent key2;
445 key2.set_pressed(true);
446 key2.set_usb_keycode(2);
448 protocol::MouseEvent mousedown;
449 mousedown.set_button(protocol::MouseEvent::BUTTON_LEFT);
450 mousedown.set_button_down(true);
452 Expectation authenticated =
453 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
454 .WillOnce(Return(true));
455 EXPECT_CALL(*input_injector_, StartPtr(_))
456 .After(authenticated);
457 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
458 .After(authenticated);
460 // Wait for the first video packet to be captured to make sure that
461 // the injected input will go though. Otherwise mouse events will be blocked
462 // by the mouse clamping filter.
463 Sequence s;
464 EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
465 .InSequence(s)
466 .After(authenticated)
467 .WillOnce(DoAll(
468 InjectKeyEvent(connection_, key1),
469 InjectKeyEvent(connection_, key2),
470 InjectMouseEvent(connection_, mousedown),
471 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
472 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
473 EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(1, true)))
474 .InSequence(s);
475 EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(2, true)))
476 .InSequence(s);
477 EXPECT_CALL(*input_injector_, InjectMouseEvent(EqualsMouseButtonEvent(
478 protocol::MouseEvent::BUTTON_LEFT, true)))
479 .InSequence(s);
480 EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(1, false)))
481 .InSequence(s);
482 EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(2, false)))
483 .InSequence(s);
484 EXPECT_CALL(*input_injector_, InjectMouseEvent(EqualsMouseButtonEvent(
485 protocol::MouseEvent::BUTTON_LEFT, false)))
486 .InSequence(s);
487 EXPECT_CALL(session_event_handler_, OnSessionClosed(_))
488 .InSequence(s);
490 ConnectClientSession();
491 message_loop_.Run();
494 TEST_F(ClientSessionTest, ClampMouseEvents) {
495 Expectation authenticated =
496 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
497 .WillOnce(Return(true));
498 EXPECT_CALL(*input_injector_, StartPtr(_))
499 .After(authenticated);
500 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
501 .After(authenticated);
502 EXPECT_CALL(session_event_handler_, OnSessionClosed(_))
503 .After(authenticated);
505 Expectation connected = authenticated;
507 int input_x[3] = { -999, 100, 999 };
508 int expected_x[3] = { 0, 100, ScreenCapturerFake::kWidth - 1 };
509 int input_y[3] = { -999, 50, 999 };
510 int expected_y[3] = { 0, 50, ScreenCapturerFake::kHeight - 1 };
512 protocol::MouseEvent expected_event;
513 for (int j = 0; j < 3; j++) {
514 for (int i = 0; i < 3; i++) {
515 protocol::MouseEvent injected_event;
516 injected_event.set_x(input_x[i]);
517 injected_event.set_y(input_y[j]);
519 if (i == 0 && j == 0) {
520 // Inject the 1st event once a video packet has been received.
521 connected =
522 EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
523 .After(connected)
524 .WillOnce(InjectMouseEvent(connection_, injected_event));
525 } else {
526 // Every next event is injected once the previous event has been
527 // received.
528 connected =
529 EXPECT_CALL(*input_injector_,
530 InjectMouseEvent(EqualsMouseEvent(expected_event.x(),
531 expected_event.y())))
532 .After(connected)
533 .WillOnce(InjectMouseEvent(connection_, injected_event));
536 expected_event.set_x(expected_x[i]);
537 expected_event.set_y(expected_y[j]);
541 // Shutdown the connection once the last event has been received.
542 EXPECT_CALL(*input_injector_,
543 InjectMouseEvent(EqualsMouseEvent(expected_event.x(),
544 expected_event.y())))
545 .After(connected)
546 .WillOnce(DoAll(
547 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
548 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
550 ConnectClientSession();
551 message_loop_.Run();
554 TEST_F(ClientSessionTest, NoGnubbyAuth) {
555 protocol::ExtensionMessage message;
556 message.set_type("gnubby-auth");
557 message.set_data("test");
559 Expectation authenticated =
560 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
561 .WillOnce(Return(true));
562 EXPECT_CALL(*input_injector_, StartPtr(_)).After(authenticated);
563 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
564 .After(authenticated)
565 .WillOnce(DoAll(
566 DeliverClientMessage(client_session_.get(), message),
567 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
568 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
569 EXPECT_CALL(session_event_handler_, OnSessionClosed(_));
571 ConnectClientSession();
572 message_loop_.Run();
575 TEST_F(ClientSessionTest, EnableGnubbyAuth) {
576 // Lifetime controlled by object under test.
577 MockGnubbyAuthHandler* gnubby_auth_handler = new MockGnubbyAuthHandler();
579 protocol::ExtensionMessage message;
580 message.set_type("gnubby-auth");
581 message.set_data("test");
583 Expectation authenticated =
584 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
585 .WillOnce(Return(true));
586 EXPECT_CALL(*input_injector_, StartPtr(_)).After(authenticated);
587 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
588 .After(authenticated)
589 .WillOnce(DoAll(
590 SetGnubbyAuthHandlerForTesting(client_session_.get(),
591 gnubby_auth_handler),
592 DeliverClientMessage(client_session_.get(), message),
593 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
594 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
595 EXPECT_CALL(*gnubby_auth_handler, DeliverClientMessage(_));
596 EXPECT_CALL(session_event_handler_, OnSessionClosed(_));
598 ConnectClientSession();
599 message_loop_.Run();
602 } // namespace remoting