| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "remoting/host/gcd_state_updater.h" |
| |
| #include <algorithm> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/memory/ptr_util.h" |
| #include "base/strings/stringize_macros.h" |
| #include "base/test/simple_test_clock.h" |
| #include "base/test/test_mock_time_task_runner.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "net/url_request/test_url_fetcher_factory.h" |
| #include "remoting/base/constants.h" |
| #include "remoting/base/fake_oauth_token_getter.h" |
| #include "remoting/host/gcd_rest_client.h" |
| #include "remoting/signaling/fake_signal_strategy.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using testing::_; |
| using testing::Return; |
| |
| namespace remoting { |
| |
| class GcdStateUpdaterTest : public testing::Test { |
| public: |
| GcdStateUpdaterTest() |
| : task_runner_(new base::TestMockTimeTaskRunner()), |
| runner_handler_(task_runner_), |
| clock_(task_runner_->GetMockClock()), |
| token_getter_(OAuthTokenGetter::SUCCESS, |
| "<fake_user_email>", |
| "<fake_access_token>"), |
| rest_client_(new GcdRestClient("http://gcd_base_url", |
| "<gcd_device_id>", |
| nullptr, |
| &token_getter_)), |
| signal_strategy_(SignalingAddress("local_jid")) { |
| rest_client_->SetClockForTest(base::WrapUnique(new base::SimpleTestClock)); |
| } |
| |
| void OnSuccess() { on_success_count_++; } |
| |
| void OnHostIdError() { on_host_id_error_count_++; } |
| |
| protected: |
| scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; |
| base::ThreadTaskRunnerHandle runner_handler_; |
| std::unique_ptr<base::Clock> clock_; |
| net::TestURLFetcherFactory url_fetcher_factory_; |
| FakeOAuthTokenGetter token_getter_; |
| std::unique_ptr<GcdRestClient> rest_client_; |
| FakeSignalStrategy signal_strategy_; |
| int on_success_count_ = 0; |
| int on_host_id_error_count_ = 0; |
| }; |
| |
| TEST_F(GcdStateUpdaterTest, Success) { |
| std::unique_ptr<GcdStateUpdater> updater(new GcdStateUpdater( |
| base::Bind(&GcdStateUpdaterTest::OnSuccess, base::Unretained(this)), |
| base::Bind(&GcdStateUpdaterTest::OnHostIdError, base::Unretained(this)), |
| &signal_strategy_, std::move(rest_client_))); |
| |
| signal_strategy_.Connect(); |
| task_runner_->RunUntilIdle(); |
| net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); |
| ASSERT_TRUE(fetcher); |
| EXPECT_EQ("{\"patches\":[{\"patch\":{" |
| "\"base\":{\"_hostVersion\":\"" STRINGIZE(VERSION) "\"," |
| "\"_jabberId\":\"local_jid\"}}," |
| "\"timeMs\":0.0}],\"requestTimeMs\":0.0}", |
| fetcher->upload_data()); |
| fetcher->set_response_code(200); |
| fetcher->delegate()->OnURLFetchComplete(fetcher); |
| EXPECT_EQ(1, on_success_count_); |
| |
| updater.reset(); |
| |
| EXPECT_EQ(0, on_host_id_error_count_); |
| } |
| |
| TEST_F(GcdStateUpdaterTest, QueuedRequests) { |
| std::unique_ptr<GcdStateUpdater> updater(new GcdStateUpdater( |
| base::Bind(&GcdStateUpdaterTest::OnSuccess, base::Unretained(this)), |
| base::Bind(&GcdStateUpdaterTest::OnHostIdError, base::Unretained(this)), |
| &signal_strategy_, std::move(rest_client_))); |
| |
| // Connect, then re-connect with a different JID while the status |
| // update for the first connection is pending. |
| signal_strategy_.Connect(); |
| task_runner_->RunUntilIdle(); |
| signal_strategy_.Disconnect(); |
| task_runner_->RunUntilIdle(); |
| signal_strategy_.SetLocalAddress(SignalingAddress("local_jid2")); |
| signal_strategy_.Connect(); |
| task_runner_->RunUntilIdle(); |
| |
| // Let the first status update finish. This should be a no-op in |
| // the updater because the local JID has changed since this request |
| // was issued. |
| net::TestURLFetcher* fetcher0 = url_fetcher_factory_.GetFetcherByID(0); |
| fetcher0->set_response_code(200); |
| fetcher0->delegate()->OnURLFetchComplete(fetcher0); |
| EXPECT_EQ(0, on_success_count_); |
| |
| // Wait for the next retry. |
| task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1)); |
| |
| // There should be a new pending request now with the new local JID. |
| net::TestURLFetcher* fetcher1 = url_fetcher_factory_.GetFetcherByID(0); |
| ASSERT_TRUE(fetcher1); |
| EXPECT_EQ("{\"patches\":[{\"patch\":{" |
| "\"base\":{\"_hostVersion\":\"" STRINGIZE(VERSION) "\"," |
| "\"_jabberId\":\"local_jid2\"}}," |
| "\"timeMs\":0.0}],\"requestTimeMs\":0.0}", |
| fetcher1->upload_data()); |
| fetcher1->set_response_code(200); |
| fetcher1->delegate()->OnURLFetchComplete(fetcher1); |
| EXPECT_EQ(1, on_success_count_); |
| |
| updater.reset(); |
| |
| EXPECT_EQ(0, on_host_id_error_count_); |
| } |
| |
| TEST_F(GcdStateUpdaterTest, Retry) { |
| std::unique_ptr<GcdStateUpdater> updater(new GcdStateUpdater( |
| base::Bind(&GcdStateUpdaterTest::OnSuccess, base::Unretained(this)), |
| base::Bind(&GcdStateUpdaterTest::OnHostIdError, base::Unretained(this)), |
| &signal_strategy_, std::move(rest_client_))); |
| |
| signal_strategy_.Connect(); |
| task_runner_->RunUntilIdle(); |
| net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); |
| ASSERT_TRUE(fetcher); |
| fetcher->set_response_code(0); |
| fetcher->delegate()->OnURLFetchComplete(fetcher); |
| task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1)); |
| EXPECT_EQ(1.0, clock_->Now().ToDoubleT()); |
| fetcher = url_fetcher_factory_.GetFetcherByID(0); |
| ASSERT_TRUE(fetcher); |
| fetcher->set_response_code(200); |
| fetcher->delegate()->OnURLFetchComplete(fetcher); |
| EXPECT_EQ(1, on_success_count_); |
| |
| updater.reset(); |
| |
| EXPECT_EQ(0, on_host_id_error_count_); |
| } |
| |
| TEST_F(GcdStateUpdaterTest, UnknownHost) { |
| std::unique_ptr<GcdStateUpdater> updater(new GcdStateUpdater( |
| base::Bind(&GcdStateUpdaterTest::OnSuccess, base::Unretained(this)), |
| base::Bind(&GcdStateUpdaterTest::OnHostIdError, base::Unretained(this)), |
| &signal_strategy_, std::move(rest_client_))); |
| |
| signal_strategy_.Connect(); |
| task_runner_->RunUntilIdle(); |
| net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); |
| ASSERT_TRUE(fetcher); |
| fetcher->set_response_code(404); |
| fetcher->delegate()->OnURLFetchComplete(fetcher); |
| EXPECT_EQ(0, on_success_count_); |
| EXPECT_EQ(1, on_host_id_error_count_); |
| } |
| |
| } // namespace remoting |