Index: blimp/client/session/assignment_source_unittest.cc |
diff --git a/blimp/client/session/assignment_source_unittest.cc b/blimp/client/session/assignment_source_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e5de9b971287f7efdb129f2356d99f6eec6a8b5b |
--- /dev/null |
+++ b/blimp/client/session/assignment_source_unittest.cc |
@@ -0,0 +1,253 @@ |
+// Copyright 2016 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 "blimp/client/session/assignment_source.h" |
+ |
+#include "base/command_line.h" |
+#include "base/json/json_reader.h" |
+#include "base/json/json_writer.h" |
+#include "base/test/test_simple_task_runner.h" |
+#include "base/thread_task_runner_handle.h" |
+#include "base/values.h" |
+#include "blimp/client/app/blimp_client_switches.h" |
+#include "blimp/common/protocol_version.h" |
+#include "net/url_request/test_url_fetcher_factory.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using testing::_; |
+using testing::InSequence; |
+ |
+namespace blimp { |
+namespace client { |
+namespace { |
+ |
+MATCHER_P(AssignmentMatcher, assignment, "") { |
Kevin M
2016/02/17 22:00:15
AssignmentEquals
David Trainor- moved to gerrit
2016/02/17 23:02:31
Done.
|
+ return arg.ip_endpoint == assignment.ip_endpoint && |
+ arg.client_token == assignment.client_token && |
+ arg.certificate == assignment.certificate && |
+ arg.certificate_fingerprint == assignment.certificate_fingerprint; |
+} |
+ |
+net::IPEndPoint BuildIPEndPoint(const std::string& ip, int port) { |
+ net::IPAddress ip_address; |
+ EXPECT_TRUE(ip_address.AssignFromIPLiteral(ip)); |
+ |
+ return net::IPEndPoint(ip_address, port); |
+} |
+ |
+Assignment BuildValidAssignment() { |
+ Assignment assignment; |
+ assignment.ip_endpoint = BuildIPEndPoint("100.150.200.250", 500); |
+ assignment.client_token = "SecretT0kenz"; |
+ assignment.certificate_fingerprint = "WhaleWhaleWhale"; |
+ assignment.certificate = "whaaaaaaaaaaaaale"; |
+ return assignment; |
+} |
+ |
+std::string BuildResponseFromAssignment(const Assignment& assignment) { |
+ base::DictionaryValue dict; |
+ dict.SetString("clientToken", assignment.client_token); |
+ dict.SetString("host", assignment.ip_endpoint.address().ToString()); |
+ dict.SetInteger("port", assignment.ip_endpoint.port()); |
+ dict.SetString("certificateFingerprint", assignment.certificate_fingerprint); |
+ dict.SetString("certificate", assignment.certificate); |
+ |
+ std::string json; |
+ base::JSONWriter::Write(dict, &json); |
+ return json; |
+} |
+ |
+class AssignmentSourceTest : public testing::Test { |
+ public: |
+ AssignmentSourceTest() |
+ : task_runner_(new base::TestSimpleTaskRunner), |
+ task_runner_handle_(task_runner_), |
+ source_(task_runner_, task_runner_) {} |
+ |
+ void GetCustomAssignment() { |
Kevin M
2016/02/17 22:00:15
Comment? What does custom mean here?
David Trainor- moved to gerrit
2016/02/17 23:02:32
Done.
|
+ source_.GetAssignment("", |
+ base::Bind(&AssignmentSourceTest::AssignmentResponse, |
+ base::Unretained(this))); |
+ EXPECT_EQ(nullptr, factory_.GetFetcherByID(0)); |
+ task_runner_->RunUntilIdle(); |
+ } |
+ |
+ // See net/base/net_errors.h for possible status errors. |
+ void GetAssignment(net::HttpStatusCode response_code, |
+ int status, |
+ const std::string& response, |
+ const std::string& client_auth_token, |
+ const std::string& protocol_version) { |
+ source_.GetAssignment(client_auth_token, |
+ base::Bind(&AssignmentSourceTest::AssignmentResponse, |
+ base::Unretained(this))); |
+ |
+ net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); |
+ |
+ task_runner_->RunUntilIdle(); |
+ |
+ EXPECT_NE(nullptr, fetcher); |
+ EXPECT_EQ(kDefaultAssignerURL, fetcher->GetOriginalURL().spec()); |
+ |
+ // Check that the request has a valid protocol_version. |
+ scoped_ptr<base::Value> json = |
+ base::JSONReader::Read(fetcher->upload_data()); |
+ EXPECT_NE(nullptr, json.get()); |
+ |
+ const base::DictionaryValue* dict; |
+ EXPECT_TRUE(json->GetAsDictionary(&dict)); |
+ |
+ std::string uploaded_protocol_version; |
+ EXPECT_TRUE( |
+ dict->GetString("protocol_version", &uploaded_protocol_version)); |
+ EXPECT_EQ(protocol_version, uploaded_protocol_version); |
+ |
+ // Check that the request has a valid authentication header. |
+ net::HttpRequestHeaders headers; |
+ fetcher->GetExtraRequestHeaders(&headers); |
+ |
+ std::string authorization; |
+ EXPECT_TRUE(headers.GetHeader("Authorization", &authorization)); |
+ EXPECT_EQ("Bearer " + client_auth_token, authorization); |
+ |
+ // Send the fake response back. |
+ fetcher->set_response_code(response_code); |
+ fetcher->set_status(net::URLRequestStatus::FromError(status)); |
+ fetcher->SetResponseString(response); |
+ fetcher->delegate()->OnURLFetchComplete(fetcher); |
+ |
+ task_runner_->RunUntilIdle(); |
+ } |
+ |
+ MOCK_METHOD2(AssignmentResponse, |
+ void(AssignmentSource::Result, const Assignment&)); |
+ |
+ protected: |
+ // Used to drive all AssignmentSource tasks. |
+ scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
+ base::ThreadTaskRunnerHandle task_runner_handle_; |
+ |
+ net::TestURLFetcherFactory factory_; |
+ |
+ AssignmentSource source_; |
+}; |
+ |
+TEST_F(AssignmentSourceTest, TestCustomSuccess) { |
Kevin M
2016/02/17 22:00:15
Custom...?
How about TestAlternateEndpointSuccess
David Trainor- moved to gerrit
2016/02/17 23:02:31
Done.
|
+ Assignment assignment; |
+ assignment.ip_endpoint = BuildIPEndPoint("100.150.200.250", 500); |
+ assignment.client_token = kDummyClientToken; |
+ |
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
+ switches::kBlimpletEndpoint, "100.150.200.250:500"); |
+ |
+ EXPECT_CALL(*this, AssignmentResponse(AssignmentSource::Result::RESULT_OK, |
+ AssignmentMatcher(assignment))) |
+ .Times(1); |
+ |
+ GetCustomAssignment(); |
+} |
+ |
+TEST_F(AssignmentSourceTest, TestSuccess) { |
+ Assignment assignment = BuildValidAssignment(); |
+ |
+ EXPECT_CALL(*this, AssignmentResponse(AssignmentSource::Result::RESULT_OK, |
+ AssignmentMatcher(assignment))) |
+ .Times(1); |
+ |
+ GetAssignment(net::HTTP_OK, net::Error::OK, |
+ BuildResponseFromAssignment(assignment), "UserAuthT0kenz", |
+ kEngineVersion); |
+} |
+ |
+TEST_F(AssignmentSourceTest, TestRequestInterruption) { |
Kevin M
2016/02/17 22:00:15
Hmmm... ValidAfterError?
David Trainor- moved to gerrit
2016/02/17 23:02:31
I'll add that test. This is testing that two subs
|
+ InSequence sequence; |
+ Assignment assignment = BuildValidAssignment(); |
+ |
+ source_.GetAssignment("", |
+ base::Bind(&AssignmentSourceTest::AssignmentResponse, |
+ base::Unretained(this))); |
+ |
+ EXPECT_CALL(*this, AssignmentResponse( |
+ AssignmentSource::Result::RESULT_SERVER_INTERRUPTED, |
+ AssignmentMatcher(Assignment()))) |
+ .Times(1) |
+ .RetiresOnSaturation(); |
+ |
+ EXPECT_CALL(*this, AssignmentResponse(AssignmentSource::Result::RESULT_OK, |
+ AssignmentMatcher(assignment))) |
+ .Times(1) |
+ .RetiresOnSaturation(); |
+ |
+ GetAssignment(net::HTTP_OK, net::Error::OK, |
+ BuildResponseFromAssignment(assignment), "UserAuthT0kenz", |
+ kEngineVersion); |
+} |
+ |
+TEST_F(AssignmentSourceTest, TestNetworkFailure) { |
+ EXPECT_CALL(*this, AssignmentResponse( |
+ AssignmentSource::Result::RESULT_NETWORK_FAILURE, _)); |
+ GetAssignment(net::HTTP_OK, net::Error::ERR_INSUFFICIENT_RESOURCES, "", |
+ "UserAuthT0kenz", kEngineVersion); |
+} |
+ |
+TEST_F(AssignmentSourceTest, TestBadRequest) { |
+ EXPECT_CALL(*this, AssignmentResponse( |
+ AssignmentSource::Result::RESULT_BAD_REQUEST, _)); |
+ GetAssignment(net::HTTP_BAD_REQUEST, net::Error::OK, "", "UserAuthT0kenz", |
+ kEngineVersion); |
+} |
+ |
+TEST_F(AssignmentSourceTest, TestUnauthorized) { |
+ EXPECT_CALL(*this, |
+ AssignmentResponse( |
+ AssignmentSource::Result::RESULT_EXPIRED_ACCESS_TOKEN, _)); |
+ GetAssignment(net::HTTP_UNAUTHORIZED, net::Error::OK, "", "UserAuthT0kenz", |
+ kEngineVersion); |
+} |
+ |
+TEST_F(AssignmentSourceTest, TestForbidden) { |
+ EXPECT_CALL(*this, AssignmentResponse( |
+ AssignmentSource::Result::RESULT_USER_INVALID, _)); |
+ GetAssignment(net::HTTP_FORBIDDEN, net::Error::OK, "", "UserAuthT0kenz", |
+ kEngineVersion); |
+} |
+ |
+TEST_F(AssignmentSourceTest, TestTooManyRequests) { |
+ EXPECT_CALL(*this, AssignmentResponse( |
+ AssignmentSource::Result::RESULT_OUT_OF_VMS, _)); |
+ GetAssignment(static_cast<net::HttpStatusCode>(429), net::Error::OK, "", |
+ "UserAuthT0kenz", kEngineVersion); |
+} |
+ |
+TEST_F(AssignmentSourceTest, TestInternalServerError) { |
+ EXPECT_CALL(*this, AssignmentResponse( |
+ AssignmentSource::Result::RESULT_SERVER_ERROR, _)); |
+ GetAssignment(net::HTTP_INTERNAL_SERVER_ERROR, net::Error::OK, "", |
+ "UserAuthT0kenz", kEngineVersion); |
+} |
+ |
+TEST_F(AssignmentSourceTest, TestServerNetBadResposne) { |
Kevin M
2016/02/17 22:00:15
TestUnexpectedNetCodeFallback?
David Trainor- moved to gerrit
2016/02/17 23:02:31
Done.
|
+ EXPECT_CALL(*this, AssignmentResponse( |
+ AssignmentSource::Result::RESULT_BAD_RESPONSE, _)); |
+ GetAssignment(net::HTTP_NOT_IMPLEMENTED, net::Error::OK, "", "UserAuthT0kenz", |
+ kEngineVersion); |
+} |
+ |
+TEST_F(AssignmentSourceTest, TestInvalidJsonResponse) { |
+ Assignment assignment = BuildValidAssignment(); |
+ |
+ // Remove half the response. |
+ std::string response = BuildResponseFromAssignment(assignment); |
+ response = response.substr(response.size() / 2); |
+ |
+ EXPECT_CALL(*this, AssignmentResponse( |
+ AssignmentSource::Result::RESULT_BAD_RESPONSE, _)); |
+ GetAssignment(net::HTTP_OK, net::Error::OK, response, "UserAuthT0kenz", |
+ kEngineVersion); |
+} |
+ |
Kevin M
2016/02/17 22:00:15
Test cases for:
missing response field?
unparseab
David Trainor- moved to gerrit
2016/02/17 23:02:31
Done.
|
+} // namespace |
+} // namespace client |
+} // namespace blimp |