Commit 0a15edda authored by Dominic Battre's avatar Dominic Battre Committed by Commit Bot

Support API Server for ServerCacheReplayer

The ServerCacheReplayer replays captured communication with the autofill
server. With the switch of the legacy autofill server to the new API
server we want to keep using the traces recorded with the old server.

This CL extends the ServerCacheReplayer to intercept traffic to the old
and the new server, to read recorded traffice to the old and the new
server, and performs the conversion as necessary.

The ServerCacheReplayer is parameterized with a server type that is set
according to the features::kAutofillUseApi feature. If the feature is
configured to use the API server, the ServerCacheReplayer will re-encode
all stored network traffic to follow the new API server's format when
loading the data from disk. Analog steps are taken if the
ServerCacheReplayer is configured to serve as a legacy server.

Bug: 1079488
Change-Id: I59cb1fe50bddcc4bbc98b7a45fddc7dcc953eaf5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2209078Reviewed-by: default avatarVincent Boisselle <vincb@google.com>
Reviewed-by: default avatarVasilii Sukhanov <vasilii@chromium.org>
Reviewed-by: default avatarDominic Battré <battre@chromium.org>
Commit-Queue: Dominic Battré <battre@chromium.org>
Cr-Commit-Position: refs/heads/master@{#771954}
parent 03f08667
......@@ -207,7 +207,10 @@ class AutofillCapturedSitesInteractiveTest
std::make_unique<test::ServerCacheReplayer>(
GetParam().capture_file_path,
test::ServerCacheReplayer::kOptionFailOnInvalidJsonRecord |
test::ServerCacheReplayer::kOptionSplitRequestsByForm)));
test::ServerCacheReplayer::kOptionSplitRequestsByForm,
base::FeatureList::IsEnabled(features::kAutofillUseApi)
? test::AutofillServerType::kApi
: test::AutofillServerType::kLegacy)));
}
void TearDownOnMainThread() override {
......@@ -225,6 +228,7 @@ class AutofillCapturedSitesInteractiveTest
// Allow access exception to live Autofill Server for
// overriding cache replay behavior.
host_resolver()->AllowDirectLookup("clients1.google.com");
host_resolver()->AllowDirectLookup("content-autofill.googleapis.com");
AutofillUiTest::SetUpInProcessBrowserTestFixture();
}
......@@ -234,9 +238,9 @@ class AutofillCapturedSitesInteractiveTest
// prediction. Test will check this attribute on all the relevant input
// elements in a form to determine if the form is ready for interaction.
feature_list_.InitWithFeatures(
/*enabled_features=*/{features::kAutofillShowTypePredictions},
/*disabled_features=*/{features::kAutofillCacheQueryResponses,
features::kAutofillUseApi});
/*enabled_features=*/{features::kAutofillShowTypePredictions,
features::kAutofillUseApi},
/*disabled_features=*/{features::kAutofillCacheQueryResponses});
command_line->AppendSwitch(switches::kShowAutofillTypePredictions);
command_line->AppendSwitchASCII(::switches::kForceFieldTrials,
"AutofillFieldMetadata/Enabled/");
......
......@@ -13,6 +13,7 @@
#include "components/autofill/core/browser/proto/api_v1.pb.h"
#include "components/autofill/core/browser/proto/server.pb.h"
#include "content/public/test/url_loader_interceptor.h"
#include "third_party/protobuf/src/google/protobuf/stubs/statusor.h"
namespace autofill {
namespace test {
......@@ -38,14 +39,17 @@ std::ostream& operator<<(
const autofill::AutofillQueryResponseContents& response);
std::ostream& operator<<(std::ostream& out,
const autofill::AutofillQueryResponse& response);
enum class RequestType {
kQueryProtoGET,
kQueryProtoPOST,
kNone,
};
class LegacyEnv {
public:
using Query = AutofillQueryContents;
using Response = AutofillQueryResponseContents;
};
// Gets a key from a given query request.
std::string GetKeyFromQueryRequest(const AutofillQueryContents& query_request);
class ApiEnv {
public:
......@@ -53,7 +57,26 @@ class ApiEnv {
using Response = AutofillQueryResponse;
};
enum class RequestType { kLegacyQueryProtoGET, kLegacyQueryProtoPOST };
// Gets a key from a given query request.
template <typename Env>
std::string GetKeyFromQuery(const typename Env::Query& query_request);
template <>
std::string GetKeyFromQuery<LegacyEnv>(const LegacyEnv::Query& query_request);
template <>
std::string GetKeyFromQuery<ApiEnv>(const ApiEnv::Query& query_request);
template <typename Env>
bool GetResponseForQuery(const ServerCache& cache,
const typename Env::Query& query,
std::string* http_text);
template <>
bool GetResponseForQuery<LegacyEnv>(const ServerCache& cache,
const typename LegacyEnv::Query& query,
std::string* http_text);
template <>
bool GetResponseForQuery<ApiEnv>(const ServerCache& cache,
const typename ApiEnv::Query& query,
std::string* http_text);
// Conversion between different versions of queries.
template <typename ReadEnv, typename WriteEnv>
......@@ -91,6 +114,8 @@ enum class AutofillServerBehaviorType {
};
// Check for command line flags to determine Autofill Server Behavior type.
AutofillServerBehaviorType ParseAutofillServerBehaviorType();
// The type of server that shall be emulated.
enum class AutofillServerType { kLegacy, kApi };
// Replayer for Autofill Server cache. Can be used in concurrency.
class ServerCacheReplayer {
......@@ -124,7 +149,10 @@ class ServerCacheReplayer {
// }
// You can set the replayer's behavior by setting |options| with a mix of
// Options. Will crash if there is a failure when loading the cache.
ServerCacheReplayer(const base::FilePath& json_file_path, int options);
ServerCacheReplayer(
const base::FilePath& json_file_path,
int options,
AutofillServerType server_type = AutofillServerType::kLegacy);
// Constructs the replayer from an already populated cache.
explicit ServerCacheReplayer(ServerCache server_cache,
bool split_requests_by_form = false);
......@@ -134,25 +162,23 @@ class ServerCacheReplayer {
// key. Returns false if there was no match or the response could no be
// decompressed. Nothing will be assigned to |http_text| on error. Leaves a
// log when there is an error. Can be used in concurrency.
bool GetResponseForQuery(const AutofillQueryContents& query,
std::string* http_text) const;
bool GetLegacyServerResponseForQuery(const AutofillQueryContents& query,
std::string* http_text) const;
bool GetApiServerResponseForQuery(const AutofillPageQueryRequest& query,
std::string* http_text) const;
const ServerCache& cache() const { return cache_; }
bool split_requests_by_form() const { return split_requests_by_form_; }
private:
// Server's cache. Will only be modified during construction of
// ServerCacheReplayer.
ServerCache cache_;
// Represents the cache at read time.
const ServerCache& const_cache_ = cache_;
// Controls the type of matching behavior. If False, will cache form signature
// groupings as they are recorded in the WPR archive. If True, will cache each
// form individually and attempt to stitch them together on retrieval, which
// allows a higher hit rate.
const bool split_requests_by_form_;
// Assumes key exists, and decompresses and returns http body which is stored
// at that location.
bool RetrieveAndDecompressStoredHTTP(const std::string& key,
std::string* decompressed_http) const;
};
// Url loader that intercepts Autofill Server calls and serves back cached
......
......@@ -15,6 +15,7 @@
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
#include "chrome/browser/ui/tab_dialogs.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/browser/test_password_store.h"
#include "components/password_manager/core/common/password_manager_features.h"
......@@ -167,7 +168,10 @@ class CapturedSitesPasswordManagerBrowserTest
std::make_unique<ServerUrlLoader>(std::make_unique<ServerCacheReplayer>(
GetParam().capture_file_path,
ServerCacheReplayer::kOptionFailOnInvalidJsonRecord |
ServerCacheReplayer::kOptionSplitRequestsByForm)));
ServerCacheReplayer::kOptionSplitRequestsByForm,
base::FeatureList::IsEnabled(autofill::features::kAutofillUseApi)
? autofill::test::AutofillServerType::kApi
: autofill::test::AutofillServerType::kLegacy)));
}
void SetUpCommandLine(base::CommandLine* command_line) override {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment