From b014812705fc80bff0a5c120dfcef88f349816dc Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 24 Aug 2018 12:15:48 +0200 Subject: BASELINE: Update Chromium to 68.0.3440.125 Change-Id: I23f19369e01f688e496f5bf179abb521ad73874f Reviewed-by: Allan Sandfeld Jensen --- .../browser/autofill_download_manager_unittest.cc | 226 ++++++++++++++++++++- 1 file changed, 218 insertions(+), 8 deletions(-) (limited to 'chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc') diff --git a/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc b/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc index a35d456158b..cccf4753bfd 100644 --- a/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc +++ b/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc @@ -16,7 +16,11 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/task_scheduler/post_task.h" #include "base/test/histogram_tester.h" +#include "base/test/scoped_command_line.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/scoped_task_environment.h" #include "base/test/test_timeouts.h" #include "base/threading/thread_task_runner_handle.h" #include "components/autofill/core/browser/autofill_field.h" @@ -24,8 +28,13 @@ #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/test_autofill_driver.h" +#include "components/autofill/core/common/autofill_features.h" +#include "components/autofill/core/common/autofill_switches.h" #include "components/autofill/core/common/form_data.h" #include "net/http/http_status_code.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" #include "net/url_request/test_url_fetcher_factory.h" #include "net/url_request/url_request_status.h" #include "net/url_request/url_request_test_util.h" @@ -33,11 +42,18 @@ #include "testing/gtest/include/gtest/gtest.h" using base::ASCIIToUTF16; - +using net::test_server::EmbeddedTestServer; +using net::test_server::BasicHttpResponse; +using net::test_server::HttpRequest; +using net::test_server::HttpResponse; namespace autofill { namespace { +const int METHOD_GET = 0; +const int METHOD_POST = 1; +const int CACHE_MISS = 0; +const int CACHE_HIT = 1; // Call |fetcher->OnURLFetchComplete()| as the URLFetcher would when // a response is received. Params allow caller to set fake status. void FakeOnURLFetchComplete(net::TestURLFetcher* fetcher, @@ -135,6 +151,9 @@ class AutofillDownloadManagerTest : public AutofillDownloadManager::Observer, }; TEST_F(AutofillDownloadManagerTest, QueryAndUploadTest) { + base::test::ScopedFeatureList fl; + fl.InitAndEnableFeature(features::kAutofillCacheQueryResponses); + // Create and register factory. net::TestURLFetcherFactory factory; @@ -228,6 +247,7 @@ TEST_F(AutofillDownloadManagerTest, QueryAndUploadTest) { download_manager_.StartQueryRequest(ToRawPointerVector(form_structures))); histogram.ExpectUniqueSample("Autofill.ServerQueryResponse", AutofillMetrics::QUERY_SENT, 1); + histogram.ExpectUniqueSample("Autofill.Query.Method", METHOD_GET, 1); // Request with id 1. EXPECT_TRUE(download_manager_.StartUploadRequest( @@ -260,17 +280,24 @@ TEST_F(AutofillDownloadManagerTest, QueryAndUploadTest) { net::TestURLFetcher* fetcher = factory.GetFetcherByID(1); ASSERT_TRUE(fetcher); FakeOnURLFetchComplete(fetcher, net::HTTP_OK, std::string(responses[1])); + histogram.ExpectBucketCount("Autofill.Upload.HttpResponseCode", net::HTTP_OK, + 1); // Request 2: Unsuccessful upload. fetcher = factory.GetFetcherByID(2); ASSERT_TRUE(fetcher); FakeOnURLFetchComplete(fetcher, net::HTTP_NOT_FOUND, std::string(responses[2])); + histogram.ExpectBucketCount("Autofill.Upload.HttpResponseCode", + net::HTTP_NOT_FOUND, 1); // Request 0: Successful query. fetcher = factory.GetFetcherByID(0); ASSERT_TRUE(fetcher); FakeOnURLFetchComplete(fetcher, net::HTTP_OK, std::string(responses[0])); EXPECT_EQ(3U, responses_.size()); + histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_MISS, 1); + histogram.ExpectBucketCount("Autofill.Query.HttpResponseCode", net::HTTP_OK, + 1); // Check Request 1. EXPECT_EQ(AutofillDownloadManagerTest::UPLOAD_SUCCESSFULL, @@ -313,8 +340,11 @@ TEST_F(AutofillDownloadManagerTest, QueryAndUploadTest) { ASSERT_TRUE(fetcher); histogram.ExpectUniqueSample("Autofill.ServerQueryResponse", AutofillMetrics::QUERY_SENT, 2); + histogram.ExpectUniqueSample("Autofill.Query.Method", METHOD_GET, 2); FakeOnURLFetchComplete(fetcher, net::HTTP_INTERNAL_SERVER_ERROR, std::string(responses[0])); + histogram.ExpectBucketCount("Autofill.Query.HttpResponseCode", + net::HTTP_INTERNAL_SERVER_ERROR, 1); // Check Request 4. EXPECT_EQ(AutofillDownloadManagerTest::REQUEST_QUERY_FAILED, @@ -323,6 +353,45 @@ TEST_F(AutofillDownloadManagerTest, QueryAndUploadTest) { // Expected response on non-query request is an empty string. EXPECT_EQ(std::string(), responses_.front().response); responses_.pop_front(); + + // Request with id 5. Let's pretend we hit the cache. + EXPECT_TRUE( + download_manager_.StartQueryRequest(ToRawPointerVector(form_structures))); + histogram.ExpectBucketCount("Autofill.ServerQueryResponse", + AutofillMetrics::QUERY_SENT, 3); + histogram.ExpectBucketCount("Autofill.Query.Method", METHOD_GET, 3); + fetcher = factory.GetFetcherByID(5); + ASSERT_TRUE(fetcher); + fetcher->set_was_cached(true); + FakeOnURLFetchComplete(fetcher, net::HTTP_OK, std::string(responses[0])); + + // Check Request 5. + EXPECT_EQ(responses_.front().type_of_response, + AutofillDownloadManagerTest::QUERY_SUCCESSFULL); + responses_.pop_front(); + histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_HIT, 1); + + // Test query with caching disabled. + base::test::ScopedFeatureList fl2; + fl2.InitAndDisableFeature(features::kAutofillCacheQueryResponses); + + // Don't hit the in-mem cache. + field.label = ASCIIToUTF16("Address line 3"); + field.name = ASCIIToUTF16("address3"); + field.form_control_type = "text"; + form.fields.push_back(field); + form_structures.push_back(std::make_unique(form)); + + // Request with id 6 + EXPECT_TRUE( + download_manager_.StartQueryRequest(ToRawPointerVector(form_structures))); + histogram.ExpectBucketCount("Autofill.ServerQueryResponse", + AutofillMetrics::QUERY_SENT, 4); + histogram.ExpectBucketCount("Autofill.Query.Method", METHOD_POST, 1); + fetcher = factory.GetFetcherByID(6); + ASSERT_TRUE(fetcher); + FakeOnURLFetchComplete(fetcher, net::HTTP_OK, std::string(responses[0])); + histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_MISS, 2); } TEST_F(AutofillDownloadManagerTest, BackoffLogic_Query) { @@ -365,12 +434,12 @@ TEST_F(AutofillDownloadManagerTest, BackoffLogic_Query) { ASSERT_TRUE(fetcher); // Request error incurs a retry after 1 second. - FakeOnURLFetchComplete(fetcher, net::HTTP_NOT_FOUND, ""); + FakeOnURLFetchComplete(fetcher, net::HTTP_INTERNAL_SERVER_ERROR, ""); EXPECT_EQ(1U, responses_.size()); EXPECT_LT(download_manager_.fetcher_backoff_.GetTimeUntilRelease(), base::TimeDelta::FromMilliseconds(1100)); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), + FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(), base::TimeDelta::FromMilliseconds(1100)); base::RunLoop().Run(); @@ -379,10 +448,20 @@ TEST_F(AutofillDownloadManagerTest, BackoffLogic_Query) { ASSERT_TRUE(fetcher); // Next error incurs a retry after 2 seconds. - FakeOnURLFetchComplete(fetcher, net::HTTP_INTERNAL_SERVER_ERROR, ""); + FakeOnURLFetchComplete(fetcher, net::HTTP_REQUEST_ENTITY_TOO_LARGE, + ""); EXPECT_EQ(2U, responses_.size()); EXPECT_LT(download_manager_.fetcher_backoff_.GetTimeUntilRelease(), base::TimeDelta::FromMilliseconds(2100)); + + // There should not be an additional retry. + fetcher = factory.GetFetcherByID(2); + ASSERT_FALSE(fetcher); + histogram.ExpectBucketCount("Autofill.Query.HttpResponseCode", + net::HTTP_REQUEST_ENTITY_TOO_LARGE, 1); + auto buckets = histogram.GetAllSamples("Autofill.Query.FailingPayloadSize"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_EQ(2, buckets[0].count); } TEST_F(AutofillDownloadManagerTest, BackoffLogic_Upload) { @@ -421,19 +500,19 @@ TEST_F(AutofillDownloadManagerTest, BackoffLogic_Upload) { ASSERT_TRUE(fetcher); // Error incurs a retry after 1 second. - FakeOnURLFetchComplete(fetcher, net::HTTP_NOT_FOUND, ""); + FakeOnURLFetchComplete(fetcher, net::HTTP_INTERNAL_SERVER_ERROR, ""); EXPECT_EQ(1U, responses_.size()); EXPECT_LT(download_manager_.fetcher_backoff_.GetTimeUntilRelease(), base::TimeDelta::FromMilliseconds(1100)); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), + FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(), base::TimeDelta::FromMilliseconds(1100)); base::RunLoop().Run(); // Check that it was a failure. EXPECT_EQ(AutofillDownloadManagerTest::REQUEST_UPLOAD_FAILED, responses_.front().type_of_response); - EXPECT_EQ(net::HTTP_NOT_FOUND, responses_.front().error); + EXPECT_EQ(net::HTTP_INTERNAL_SERVER_ERROR, responses_.front().error); EXPECT_EQ(form_structure->FormSignatureAsStr(), responses_.front().signature); // Expected response on non-query request is an empty string. EXPECT_EQ(std::string(), responses_.front().response); @@ -452,6 +531,21 @@ TEST_F(AutofillDownloadManagerTest, BackoffLogic_Upload) { // Expected response on non-query request is an empty string. EXPECT_EQ(std::string(), responses_.front().response); responses_.pop_front(); + + // Validate no retry on sending a bad request. + base::HistogramTester histogram; + EXPECT_TRUE(download_manager_.StartUploadRequest( + *form_structure, true, ServerFieldTypeSet(), std::string(), true)); + fetcher = factory.GetFetcherByID(2); + ASSERT_TRUE(fetcher); + FakeOnURLFetchComplete(fetcher, net::HTTP_REQUEST_ENTITY_TOO_LARGE, ""); + fetcher = factory.GetFetcherByID(3); + ASSERT_FALSE(fetcher); + histogram.ExpectBucketCount("Autofill.Upload.HttpResponseCode", + net::HTTP_REQUEST_ENTITY_TOO_LARGE, 1); + auto buckets = histogram.GetAllSamples("Autofill.Upload.FailingPayloadSize"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_EQ(1, buckets[0].count); } TEST_F(AutofillDownloadManagerTest, QueryTooManyFieldsTest) { @@ -638,7 +732,7 @@ TEST_F(AutofillDownloadManagerTest, CacheQueryTest) { EXPECT_EQ(responses[2], responses_.back().response); responses_.clear(); - // The first structure should've expired. + // The first structure should have expired. // Request with id 3. EXPECT_TRUE(download_manager_.StartQueryRequest( ToRawPointerVector(form_structures0))); @@ -654,4 +748,120 @@ TEST_F(AutofillDownloadManagerTest, CacheQueryTest) { EXPECT_EQ(responses[0], responses_.front().response); } +namespace { + +class AutofillQueryTest : public AutofillDownloadManager::Observer, + public testing::Test { + protected: + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature( + features::kAutofillCacheQueryResponses); + + // Setup the server. + server_.RegisterRequestHandler(base::BindRepeating( + &AutofillQueryTest::RequestHandler, base::Unretained(this))); + ASSERT_TRUE(server_.Start()); + + scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII( + switches::kAutofillServerURL, + server_.base_url().Resolve("/tbproxy/af/").spec().c_str()); + + // Intialize the autofill driver. + request_context_ = base::MakeRefCounted( + scoped_task_environment_.GetMainThreadTaskRunner()); + driver_ = std::make_unique(); + driver_->SetURLRequestContext(request_context_.get()); + } + + void TearDown() override { + if (server_.Started()) + ASSERT_TRUE(server_.ShutdownAndWaitUntilComplete()); + } + + // AutofillDownloadManager::Observer implementation. + void OnLoadedServerPredictions( + std::string /* response_xml */, + const std::vector& /*form_signatures */) override { + ASSERT_TRUE(run_loop_); + run_loop_->QuitWhenIdle(); + } + + std::unique_ptr RequestHandler(const HttpRequest& request) { + GURL absolute_url = server_.GetURL(request.relative_url); + ++call_count_; + + if (absolute_url.path() != "/tbproxy/af/query") + return nullptr; + + AutofillQueryResponseContents proto; + proto.add_field()->set_overall_type_prediction(NAME_FIRST); + + auto response = std::make_unique(); + response->set_code(net::HTTP_OK); + response->set_content(proto.SerializeAsString()); + response->set_content_type("text/proto"); + response->AddCustomHeader("Cache-Control", "max-age=86400"); + return response; + } + + void SendQueryRequest( + const std::vector>& form_structures) { + ASSERT_TRUE(run_loop_ == nullptr); + run_loop_ = std::make_unique(); + + AutofillDownloadManager download_manager(driver_.get(), this); + ASSERT_TRUE(download_manager.StartQueryRequest( + ToRawPointerVector(form_structures))); + run_loop_->Run(); + run_loop_.reset(); + } + + base::test::ScopedTaskEnvironment scoped_task_environment_{ + base::test::ScopedTaskEnvironment::MainThreadType::IO}; + base::test::ScopedCommandLine scoped_command_line_; + base::test::ScopedFeatureList scoped_feature_list_; + EmbeddedTestServer server_; + std::unique_ptr run_loop_; + size_t call_count_ = 0; + scoped_refptr request_context_; + std::unique_ptr driver_; +}; + +} // namespace + +TEST_F(AutofillQueryTest, CacheableResponse) { + FormFieldData field; + field.label = ASCIIToUTF16("First Name:"); + field.name = ASCIIToUTF16("firstname"); + field.form_control_type = "text"; + + FormData form; + form.fields.push_back(field); + + std::vector> form_structures; + form_structures.push_back(std::make_unique(form)); + + // Query for the form. This should go to the embedded server. + { + SCOPED_TRACE("Firstl Query"); + base::HistogramTester histogram; + ASSERT_NO_FATAL_FAILURE(SendQueryRequest(form_structures)); + EXPECT_EQ(1u, call_count_); + histogram.ExpectBucketCount("Autofill.ServerQueryResponse", + AutofillMetrics::QUERY_SENT, 1); + histogram.ExpectBucketCount("Autofill.Query.Method", METHOD_GET, 1); + histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_MISS, 1); + } + + // Query again for the form. This should go to the local cache. + { + SCOPED_TRACE("Second Query"); + base::HistogramTester histogram; + ASSERT_NO_FATAL_FAILURE(SendQueryRequest(form_structures)); + EXPECT_EQ(1u, call_count_); + histogram.ExpectBucketCount("Autofill.Query.Method", METHOD_GET, 1); + histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_HIT, 1); + } +} + } // namespace autofill -- cgit v1.2.1