123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828 |
- // Copyright 2020 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 "net/dns/httpssvc_metrics.h"
- #include <string>
- #include <tuple>
- #include "base/feature_list.h"
- #include "base/strings/strcat.h"
- #include "base/strings/string_number_conversions.h"
- #include "base/strings/string_piece.h"
- #include "base/strings/string_util.h"
- #include "base/test/metrics/histogram_tester.h"
- #include "base/test/scoped_feature_list.h"
- #include "net/base/features.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace net {
- // int: number of domains
- // bool: extra leading comma
- // bool: extra trailing comma
- using DomainListQuirksTuple = std::tuple<int, bool, bool>;
- // bool: DnsHttpssvc feature is enabled
- // bool: DnsHttpssvcUseIntegrity feature param
- // bool: DnsHttpssvcUseHttpssvc feature param
- // bool: DnsHttpssvcControlDomainWildcard feature param
- using HttpssvcFeatureTuple = std::tuple<bool, bool, bool, bool>;
- // DomainListQuirksTuple: quirks for the experimental domain list.
- // DomainListQuirksTuple: quirks for the control domain list.
- // HttpssvcFeatureTuple: config for the whole DnsHttpssvc feature.
- using ParsingTestParamTuple = std::
- tuple<DomainListQuirksTuple, DomainListQuirksTuple, HttpssvcFeatureTuple>;
- // bool: whether we are querying for an experimental domain or a control domain
- // HttpssvcFeatureTuple: config for the whole DnsHttpssvc feature.
- using MetricsTestParamTuple = std::tuple<bool, HttpssvcFeatureTuple>;
- // Create a comma-separated list of |domains| with the given |quirks|.
- std::string FlattenDomainList(const std::vector<std::string>& domains,
- DomainListQuirksTuple quirks) {
- auto [num_domains, leading_comma, trailing_comma] = quirks;
- CHECK_EQ(static_cast<size_t>(num_domains), domains.size());
- std::string flattened = base::JoinString(domains, ",");
- if (leading_comma)
- flattened.insert(flattened.begin(), ',');
- if (trailing_comma)
- flattened.push_back(',');
- return flattened;
- }
- // Intermediate representation constructed from test parameters.
- struct HttpssvcFeatureConfig {
- HttpssvcFeatureConfig() = default;
- explicit HttpssvcFeatureConfig(const HttpssvcFeatureTuple& feature_tuple,
- base::StringPiece experiment_domains,
- base::StringPiece control_domains)
- : experiment_domains(experiment_domains),
- control_domains(control_domains) {
- std::tie(enabled, use_integrity, use_httpssvc, control_domain_wildcard) =
- feature_tuple;
- }
- void Apply(base::test::ScopedFeatureList* scoped_feature_list) const {
- if (!enabled) {
- scoped_feature_list->InitAndDisableFeature(features::kDnsHttpssvc);
- return;
- }
- auto stringify = [](bool b) -> std::string { return b ? "true" : "false"; };
- scoped_feature_list->InitAndEnableFeatureWithParameters(
- features::kDnsHttpssvc,
- {
- {"DnsHttpssvcUseHttpssvc", stringify(use_httpssvc)},
- {"DnsHttpssvcUseIntegrity", stringify(use_integrity)},
- {"DnsHttpssvcEnableQueryOverInsecure", "false"},
- {"DnsHttpssvcExperimentDomains", experiment_domains},
- {"DnsHttpssvcControlDomains", control_domains},
- {"DnsHttpssvcControlDomainWildcard",
- stringify(control_domain_wildcard)},
- });
- }
- bool enabled = false;
- bool use_integrity = false;
- bool use_httpssvc = false;
- bool control_domain_wildcard = false;
- std::string experiment_domains;
- std::string control_domains;
- };
- std::vector<std::string> GenerateDomainList(base::StringPiece label, int n) {
- std::vector<std::string> domains;
- for (int i = 0; i < n; i++) {
- domains.push_back(base::StrCat(
- {"domain", base::NumberToString(i), ".", label, ".example"}));
- }
- return domains;
- }
- // Base for testing domain list parsing functions in
- // net::features::dns_httpssvc_experiment.
- class HttpssvcDomainParsingTest
- : public ::testing::TestWithParam<ParsingTestParamTuple> {
- public:
- void SetUp() override {
- auto [domain_quirks_experimental, domain_quirks_control, httpssvc_feature] =
- GetParam();
- expected_experiment_domains_ = GenerateDomainList(
- "experiment", std::get<0>(domain_quirks_experimental));
- expected_control_domains_ =
- GenerateDomainList("control", std::get<0>(domain_quirks_control));
- config_ = HttpssvcFeatureConfig(
- httpssvc_feature,
- FlattenDomainList(expected_experiment_domains_,
- domain_quirks_experimental),
- FlattenDomainList(expected_control_domains_, domain_quirks_control));
- config_.Apply(&scoped_feature_list_);
- }
- const HttpssvcFeatureConfig& config() { return config_; }
- protected:
- // The expected results of parsing the comma-separated domain lists in
- // |experiment_domains| and |control_domains|, respectively.
- std::vector<std::string> expected_experiment_domains_;
- std::vector<std::string> expected_control_domains_;
- private:
- HttpssvcFeatureConfig config_;
- base::test::ScopedFeatureList scoped_feature_list_;
- };
- // This instantiation tests the domain list parser against various quirks,
- // e.g. leading comma.
- INSTANTIATE_TEST_SUITE_P(
- HttpssvcMetricsTestDomainParsing,
- HttpssvcDomainParsingTest,
- testing::Combine(
- // DomainListQuirksTuple for experimental domains. To fight back
- // combinatorial explosion of tests, this tuple is pared down more than
- // the one for control domains. This should not significantly hurt test
- // coverage because |IsExperimentDomain| and |IsControlDomain| rely on a
- // shared helper function.
- testing::Combine(testing::Values(0, 1),
- testing::Values(false),
- testing::Values(false)),
- // DomainListQuirksTuple for control domains.
- testing::Combine(testing::Range(0, 3),
- testing::Bool(),
- testing::Bool()),
- // HttpssvcFeatureTuple
- testing::Combine(
- testing::Bool() /* DnsHttpssvc feature enabled? */,
- testing::Bool() /* DnsHttpssvcUseIntegrity */,
- testing::Bool() /* DnsHttpssvcUseHttpssvc */,
- testing::Values(false) /* DnsHttpssvcControlDomainWildcard */)));
- // Base for testing the metrics collection code in |HttpssvcMetrics|.
- class HttpssvcMetricsTest
- : public ::testing::TestWithParam<std::tuple<bool, bool>> {
- public:
- void SetUp() override {
- std::tie(secure_, querying_experimental_) = GetParam();
- config_ = HttpssvcFeatureConfig(
- {true /* enabled */, true /* use_integrity */, true /* use_httpssvc */,
- false /* control_domain_wildcard */},
- "", "");
- config_.Apply(&scoped_feature_list_);
- }
- std::string BuildMetricNamePrefix(base::StringPiece record_type_str,
- base::StringPiece expect_str) const {
- return base::StrCat({"Net.DNS.HTTPSSVC.", record_type_str, ".",
- secure_ ? "Secure." : "Insecure.", expect_str, "."});
- }
- template <typename T>
- void ExpectSample(base::StringPiece name, absl::optional<T> sample) const {
- if (sample)
- histo().ExpectUniqueSample(name, *sample, 1);
- else
- histo().ExpectTotalCount(name, 0);
- }
- void ExpectSample(base::StringPiece name,
- absl::optional<base::TimeDelta> sample) const {
- absl::optional<int64_t> sample_ms;
- if (sample)
- sample_ms = {sample->InMilliseconds()};
- ExpectSample<int64_t>(name, sample_ms);
- }
- void VerifyAddressResolveTimeMetric(
- absl::optional<base::TimeDelta> expect_intact_time = absl::nullopt,
- absl::optional<base::TimeDelta> expect_noerror_time = absl::nullopt) {
- const std::string kExpectIntact =
- base::StrCat({BuildMetricNamePrefix("RecordHttps", "ExpectIntact"),
- "ResolveTimeAddress"});
- const std::string kExpectNoerror =
- base::StrCat({BuildMetricNamePrefix("RecordHttps", "ExpectNoerror"),
- "ResolveTimeAddress"});
- ExpectSample(kExpectIntact, expect_intact_time);
- ExpectSample(kExpectNoerror, expect_noerror_time);
- }
- void VerifyIntegrityMetricsForExpectIntact(
- absl::optional<HttpssvcDnsRcode> rcode,
- absl::optional<bool> integrity,
- absl::optional<bool> record_with_error,
- absl::optional<base::TimeDelta> resolve_time_integrity,
- absl::optional<int> resolve_time_ratio) const {
- const std::string kPrefix =
- BuildMetricNamePrefix("RecordIntegrity", "ExpectIntact");
- const std::string kMetricDnsRcode = base::StrCat({kPrefix, "DnsRcode"});
- const std::string kMetricIntegrity = base::StrCat({kPrefix, "Integrity"});
- const std::string kMetricRecordWithError =
- base::StrCat({kPrefix, "RecordWithError"});
- const std::string kMetricResolveTimeExperimental =
- base::StrCat({kPrefix, "ResolveTimeExperimental"});
- const std::string kMetricResolveTimeRatio =
- base::StrCat({kPrefix, "ResolveTimeRatio"});
- ExpectSample(kMetricDnsRcode, rcode);
- ExpectSample(kMetricIntegrity, integrity);
- ExpectSample(kMetricRecordWithError, record_with_error);
- ExpectSample(kMetricResolveTimeExperimental, resolve_time_integrity);
- ExpectSample(kMetricResolveTimeRatio, resolve_time_ratio);
- }
- void VerifyHttpsMetricsForExpectIntact(
- absl::optional<HttpssvcDnsRcode> rcode = absl::nullopt,
- absl::optional<bool> parsable = absl::nullopt,
- absl::optional<bool> record_with_error = absl::nullopt,
- absl::optional<base::TimeDelta> resolve_time_https = absl::nullopt,
- absl::optional<int> resolve_time_ratio = absl::nullopt) const {
- const std::string kPrefix =
- BuildMetricNamePrefix("RecordHttps", "ExpectIntact");
- const std::string kMetricDnsRcode = base::StrCat({kPrefix, "DnsRcode"});
- const std::string kMetricParsable = base::StrCat({kPrefix, "Parsable"});
- const std::string kMetricRecordWithError =
- base::StrCat({kPrefix, "RecordWithError"});
- const std::string kMetricResolveTimeExperimental =
- base::StrCat({kPrefix, "ResolveTimeExperimental"});
- const std::string kMetricResolveTimeRatio =
- base::StrCat({kPrefix, "ResolveTimeRatio"});
- ExpectSample(kMetricDnsRcode, rcode);
- ExpectSample(kMetricParsable, parsable);
- ExpectSample(kMetricRecordWithError, record_with_error);
- ExpectSample(kMetricResolveTimeExperimental, resolve_time_https);
- ExpectSample(kMetricResolveTimeRatio, resolve_time_ratio);
- }
- void VerifyIntegrityMetricsForExpectNoerror(
- absl::optional<HttpssvcDnsRcode> rcode,
- absl::optional<int> record_received,
- absl::optional<base::TimeDelta> resolve_time_integrity,
- absl::optional<int> resolve_time_ratio) const {
- const std::string kPrefix =
- BuildMetricNamePrefix("RecordIntegrity", "ExpectNoerror");
- const std::string kMetricDnsRcode = base::StrCat({kPrefix, "DnsRcode"});
- const std::string kMetricRecordReceived =
- base::StrCat({kPrefix, "RecordReceived"});
- const std::string kMetricResolveTimeExperimental =
- base::StrCat({kPrefix, "ResolveTimeExperimental"});
- const std::string kMetricResolveTimeRatio =
- base::StrCat({kPrefix, "ResolveTimeRatio"});
- ExpectSample(kMetricDnsRcode, rcode);
- ExpectSample(kMetricRecordReceived, record_received);
- ExpectSample(kMetricResolveTimeExperimental, resolve_time_integrity);
- ExpectSample(kMetricResolveTimeRatio, resolve_time_ratio);
- }
- void VerifyHttpsMetricsForExpectNoerror(
- absl::optional<HttpssvcDnsRcode> rcode = absl::nullopt,
- absl::optional<bool> parsable = absl::nullopt,
- absl::optional<bool> record_with_error = absl::nullopt,
- absl::optional<base::TimeDelta> resolve_time_https = absl::nullopt,
- absl::optional<int> resolve_time_ratio = absl::nullopt) const {
- const std::string kPrefix =
- BuildMetricNamePrefix("RecordHttps", "ExpectNoerror");
- const std::string kMetricDnsRcode = base::StrCat({kPrefix, "DnsRcode"});
- const std::string kMetricParsable = base::StrCat({kPrefix, "Parsable"});
- const std::string kMetricRecordWithError =
- base::StrCat({kPrefix, "RecordWithError"});
- const std::string kMetricResolveTimeExperimental =
- base::StrCat({kPrefix, "ResolveTimeExperimental"});
- const std::string kMetricResolveTimeRatio =
- base::StrCat({kPrefix, "ResolveTimeRatio"});
- ExpectSample(kMetricDnsRcode, rcode);
- ExpectSample(kMetricParsable, parsable);
- ExpectSample(kMetricRecordWithError, record_with_error);
- ExpectSample(kMetricResolveTimeExperimental, resolve_time_https);
- ExpectSample(kMetricResolveTimeRatio, resolve_time_ratio);
- }
- void VerifyIntegrityMetricsForExpectIntact() {
- VerifyIntegrityMetricsForExpectIntact(absl::nullopt, absl::nullopt,
- absl::nullopt, absl::nullopt,
- absl::nullopt);
- }
- void VerifyIntegrityMetricsForExpectNoerror() {
- VerifyIntegrityMetricsForExpectNoerror(absl::nullopt, absl::nullopt,
- absl::nullopt, absl::nullopt);
- }
- const base::HistogramTester& histo() const { return histogram_; }
- const HttpssvcFeatureConfig& config() const { return config_; }
- protected:
- bool secure_;
- bool querying_experimental_;
- private:
- HttpssvcFeatureConfig config_;
- base::test::ScopedFeatureList scoped_feature_list_;
- base::HistogramTester histogram_;
- };
- // This instantiation focuses on whether the correct metrics are recorded. The
- // domain list parser is already tested against encoding quirks in
- // |HttpssvcMetricsTestDomainParsing|, so we fix the quirks at false.
- INSTANTIATE_TEST_SUITE_P(
- HttpssvcMetricsTestSimple,
- HttpssvcMetricsTest,
- testing::Combine(
- testing::Bool(), // Querying over DoH or Do53.
- testing::Bool() // Whether we are querying an experimental domain.
- ));
- TEST_P(HttpssvcDomainParsingTest, ParseFeatureParamIntegrityDomains) {
- HttpssvcExperimentDomainCache domain_cache;
- const std::string kReservedDomain = "neither.example";
- EXPECT_FALSE(domain_cache.IsExperimental(kReservedDomain));
- EXPECT_EQ(domain_cache.IsControl(kReservedDomain),
- config().enabled && config().control_domain_wildcard);
- // If |config().use_integrity| is true, then we expect all domains in
- // |expected_experiment_domains_| to be experimental (same goes for
- // control domains). Otherwise, no domain should be considered experimental or
- // control.
- if (!config().enabled) {
- // When the HTTPSSVC feature is disabled, no domain should be considered
- // experimental or control.
- for (const std::string& experiment_domain : expected_experiment_domains_) {
- EXPECT_FALSE(domain_cache.IsExperimental(experiment_domain));
- EXPECT_FALSE(domain_cache.IsControl(experiment_domain));
- }
- for (const std::string& control_domain : expected_control_domains_) {
- EXPECT_FALSE(domain_cache.IsExperimental(control_domain));
- EXPECT_FALSE(domain_cache.IsControl(control_domain));
- }
- } else if (config().use_integrity || config().use_httpssvc) {
- for (const std::string& experiment_domain : expected_experiment_domains_) {
- EXPECT_TRUE(domain_cache.IsExperimental(experiment_domain));
- EXPECT_FALSE(domain_cache.IsControl(experiment_domain));
- }
- for (const std::string& control_domain : expected_control_domains_) {
- EXPECT_FALSE(domain_cache.IsExperimental(control_domain));
- EXPECT_TRUE(domain_cache.IsControl(control_domain));
- }
- return;
- }
- }
- // Only record metrics for a non-integrity query.
- TEST_P(HttpssvcMetricsTest, AddressAndExperimentalMissing) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- VerifyAddressResolveTimeMetric();
- VerifyIntegrityMetricsForExpectIntact();
- VerifyHttpsMetricsForExpectIntact();
- VerifyIntegrityMetricsForExpectNoerror();
- VerifyHttpsMetricsForExpectNoerror();
- }
- TEST_P(HttpssvcMetricsTest, AddressAndIntegrityIntact) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- const base::TimeDelta kResolveTimeIntegrity = base::Milliseconds(15);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForIntegrity(HttpssvcDnsRcode::kNoError, {true},
- kResolveTimeIntegrity);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- VerifyHttpsMetricsForExpectIntact();
- VerifyHttpsMetricsForExpectNoerror();
- if (querying_experimental_) {
- VerifyAddressResolveTimeMetric({kResolveTime} /* expect_intact_time */);
- VerifyIntegrityMetricsForExpectIntact(
- absl::nullopt /* rcode */, {true} /* integrity */,
- absl::nullopt /* record_with_error */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- VerifyIntegrityMetricsForExpectNoerror();
- return;
- }
- VerifyIntegrityMetricsForExpectIntact();
- VerifyAddressResolveTimeMetric(absl::nullopt /* expect_intact_time */,
- {kResolveTime} /* expect_noerror_time */);
- VerifyIntegrityMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kNoError} /* rcode */, {1} /* record_received */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- }
- TEST_P(HttpssvcMetricsTest, AddressAndHttpsParsable) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- const base::TimeDelta kResolveTimeHttps = base::Milliseconds(15);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForHttps(HttpssvcDnsRcode::kNoError, {true}, kResolveTimeHttps);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- VerifyIntegrityMetricsForExpectIntact();
- VerifyIntegrityMetricsForExpectNoerror();
- if (querying_experimental_) {
- VerifyAddressResolveTimeMetric({kResolveTime} /* expect_intact_time */);
- VerifyHttpsMetricsForExpectIntact(
- absl::nullopt /* rcode */, {true} /* parsable */,
- absl::nullopt /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {15} /* resolve_time_ratio */);
- VerifyHttpsMetricsForExpectNoerror();
- return;
- }
- VerifyHttpsMetricsForExpectIntact();
- VerifyAddressResolveTimeMetric(absl::nullopt /* expect_intact_time */,
- {kResolveTime} /* expect_noerror_time */);
- VerifyHttpsMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kNoError} /* rcode */, {true} /* parsable */,
- absl::nullopt /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {15} /* resolve_time_ratio */);
- }
- TEST_P(HttpssvcMetricsTest, AddressAndIntegrityIntactAndHttpsParsable) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- const base::TimeDelta kResolveTimeIntegrity = base::Milliseconds(15);
- const base::TimeDelta kResolveTimeHttps = base::Milliseconds(20);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForIntegrity(HttpssvcDnsRcode::kNoError, {true},
- kResolveTimeIntegrity);
- metrics->SaveForHttps(HttpssvcDnsRcode::kNoError, {true}, kResolveTimeHttps);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- if (querying_experimental_) {
- VerifyAddressResolveTimeMetric({kResolveTime} /* expect_intact_time */);
- VerifyIntegrityMetricsForExpectIntact(
- absl::nullopt /* rcode */, {true} /* integrity */,
- absl::nullopt /* record_with_error */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- VerifyHttpsMetricsForExpectIntact(
- absl::nullopt /* rcode */, {true} /* parsable */,
- absl::nullopt /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {20} /* resolve_time_ratio */);
- VerifyIntegrityMetricsForExpectNoerror();
- VerifyHttpsMetricsForExpectNoerror();
- return;
- }
- VerifyIntegrityMetricsForExpectIntact();
- VerifyHttpsMetricsForExpectIntact();
- VerifyAddressResolveTimeMetric(absl::nullopt /* expect_intact_time */,
- {kResolveTime} /* expect_noerror_time */);
- VerifyIntegrityMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kNoError} /* rcode */, {1} /* record_received */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- VerifyHttpsMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kNoError} /* rcode */, {true} /* parsable */,
- absl::nullopt /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {20} /* resolve_time_ratio */);
- }
- // This test simulates an INTEGRITY response that includes no INTEGRITY records,
- // but does have an error value for the RCODE.
- TEST_P(HttpssvcMetricsTest, AddressAndIntegrityMissingWithRcode) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- const base::TimeDelta kResolveTimeIntegrity = base::Milliseconds(15);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForIntegrity(HttpssvcDnsRcode::kNxDomain, {},
- kResolveTimeIntegrity);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- VerifyHttpsMetricsForExpectIntact();
- VerifyHttpsMetricsForExpectNoerror();
- if (querying_experimental_) {
- VerifyAddressResolveTimeMetric({kResolveTime} /* expect_intact_time */);
- VerifyIntegrityMetricsForExpectIntact(
- {HttpssvcDnsRcode::kNxDomain} /* rcode */,
- absl::nullopt /* integrity */, absl::nullopt /* record_with_error */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- VerifyIntegrityMetricsForExpectNoerror();
- return;
- }
- VerifyIntegrityMetricsForExpectIntact();
- VerifyAddressResolveTimeMetric(absl::nullopt /* expect_intact_time */,
- {kResolveTime} /* expect_noerror_time */);
- VerifyIntegrityMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kNxDomain} /* rcode */,
- absl::nullopt /* record_received */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- }
- // This test simulates an HTTPS response that includes no HTTPS records,
- // but does have an error value for the RCODE.
- TEST_P(HttpssvcMetricsTest, AddressAndHttpsMissingWithRcode) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- const base::TimeDelta kResolveTimeHttps = base::Milliseconds(15);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForHttps(HttpssvcDnsRcode::kNxDomain, {}, kResolveTimeHttps);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- VerifyIntegrityMetricsForExpectIntact();
- VerifyIntegrityMetricsForExpectNoerror();
- if (querying_experimental_) {
- VerifyAddressResolveTimeMetric({kResolveTime} /* expect_intact_time */);
- VerifyHttpsMetricsForExpectIntact(
- {HttpssvcDnsRcode::kNxDomain} /* rcode */, absl::nullopt /* parsable */,
- absl::nullopt /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {15} /* resolve_time_ratio */);
- VerifyHttpsMetricsForExpectNoerror();
- return;
- }
- VerifyHttpsMetricsForExpectIntact();
- VerifyAddressResolveTimeMetric(absl::nullopt /* expect_intact_time */,
- {kResolveTime} /* expect_noerror_time */);
- VerifyHttpsMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kNxDomain} /* rcode */, absl::nullopt /* parsable */,
- absl::nullopt /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {15} /* resolve_time_ratio */);
- }
- // This test simulates an INTEGRITY response that includes an intact INTEGRITY
- // record, but also has an error RCODE.
- TEST_P(HttpssvcMetricsTest, AddressAndIntegrityIntactWithRcode) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- const base::TimeDelta kResolveTimeIntegrity = base::Milliseconds(15);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForIntegrity(HttpssvcDnsRcode::kNxDomain, {true},
- kResolveTimeIntegrity);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- VerifyHttpsMetricsForExpectIntact();
- VerifyHttpsMetricsForExpectNoerror();
- if (querying_experimental_) {
- VerifyAddressResolveTimeMetric({kResolveTime} /* expect_intact_time */);
- VerifyIntegrityMetricsForExpectIntact(
- // "DnsRcode" metric is omitted because we received an INTEGRITY record.
- absl::nullopt /* rcode */,
- // "Integrity" metric is omitted because the RCODE is not NOERROR.
- absl::nullopt /* integrity */, {true} /* record_with_error */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- VerifyIntegrityMetricsForExpectNoerror();
- return;
- }
- VerifyIntegrityMetricsForExpectIntact();
- VerifyAddressResolveTimeMetric(absl::nullopt /* expect_intact_time */,
- {kResolveTime} /* expect_noerror_time */);
- VerifyIntegrityMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kNxDomain} /* rcode */, {true} /* record_received */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- }
- // This test simulates an HTTPS response that includes a parsable HTTPS
- // record, but also has an error RCODE.
- TEST_P(HttpssvcMetricsTest, AddressAndHttpsParsableWithRcode) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- const base::TimeDelta kResolveTimeHttps = base::Milliseconds(15);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForHttps(HttpssvcDnsRcode::kNxDomain, {true}, kResolveTimeHttps);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- VerifyIntegrityMetricsForExpectIntact();
- VerifyIntegrityMetricsForExpectNoerror();
- if (querying_experimental_) {
- VerifyAddressResolveTimeMetric({kResolveTime} /* expect_intact_time */);
- VerifyHttpsMetricsForExpectIntact(
- // "DnsRcode" metric is omitted because we received an HTTPS record.
- absl::nullopt /* rcode */,
- // "parsable" metric is omitted because the RCODE is not NOERROR.
- absl::nullopt /* parsable */, {true} /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {15} /* resolve_time_ratio */);
- VerifyHttpsMetricsForExpectNoerror();
- return;
- }
- VerifyHttpsMetricsForExpectIntact();
- VerifyAddressResolveTimeMetric(absl::nullopt /* expect_intact_time */,
- {kResolveTime} /* expect_noerror_time */);
- VerifyHttpsMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kNxDomain} /* rcode */,
- // "parsable" metric is omitted because the RCODE is not NOERROR.
- absl::nullopt /* parsable */, {true} /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {15} /* resolve_time_ratio */);
- }
- // This test simulates an INTEGRITY response that includes a mangled INTEGRITY
- // record *and* has an error RCODE.
- TEST_P(HttpssvcMetricsTest, AddressAndIntegrityMangledWithRcode) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- const base::TimeDelta kResolveTimeIntegrity = base::Milliseconds(15);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForIntegrity(HttpssvcDnsRcode::kNxDomain, {false},
- kResolveTimeIntegrity);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- VerifyHttpsMetricsForExpectIntact();
- VerifyHttpsMetricsForExpectNoerror();
- if (querying_experimental_) {
- VerifyAddressResolveTimeMetric({kResolveTime} /* expect_intact_time */);
- VerifyIntegrityMetricsForExpectIntact(
- // "DnsRcode" metric is omitted because we received an INTEGRITY record.
- absl::nullopt /* rcode */,
- // "Integrity" metric is omitted because the RCODE is not NOERROR.
- absl::nullopt /* integrity */, {true} /* record_with_error */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- VerifyIntegrityMetricsForExpectNoerror();
- return;
- }
- VerifyIntegrityMetricsForExpectIntact();
- VerifyAddressResolveTimeMetric(absl::nullopt /* expect_intact_time */,
- {kResolveTime} /* expect_noerror_time */);
- VerifyIntegrityMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kNxDomain} /* rcode */, {true} /* record_received */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- }
- // This test simulates an HTTPS response that includes a mangled HTTPS
- // record *and* has an error RCODE.
- TEST_P(HttpssvcMetricsTest, AddressAndHttpsMangledWithRcode) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- const base::TimeDelta kResolveTimeHttps = base::Milliseconds(15);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForHttps(HttpssvcDnsRcode::kNxDomain, {false},
- kResolveTimeHttps);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- VerifyIntegrityMetricsForExpectIntact();
- VerifyIntegrityMetricsForExpectNoerror();
- if (querying_experimental_) {
- VerifyAddressResolveTimeMetric({kResolveTime} /* expect_intact_time */);
- VerifyHttpsMetricsForExpectIntact(
- // "DnsRcode" metric is omitted because we received an HTTPS record.
- absl::nullopt /* rcode */,
- // "parsable" metric is omitted because the RCODE is not NOERROR.
- absl::nullopt /* parsable */, {true} /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {15} /* resolve_time_ratio */);
- VerifyHttpsMetricsForExpectNoerror();
- return;
- }
- VerifyHttpsMetricsForExpectIntact();
- VerifyAddressResolveTimeMetric(absl::nullopt /* expect_intact_time */,
- {kResolveTime} /* expect_noerror_time */);
- VerifyHttpsMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kNxDomain} /* rcode */,
- // "parsable" metric is omitted because the RCODE is not NOERROR.
- absl::nullopt /* parsable */, {true} /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {15} /* resolve_time_ratio */);
- }
- // This test simulates successful address queries and an INTEGRITY query that
- // timed out.
- TEST_P(HttpssvcMetricsTest, AddressAndIntegrityTimedOut) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- const base::TimeDelta kResolveTimeIntegrity = base::Milliseconds(15);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForIntegrity(HttpssvcDnsRcode::kTimedOut, {},
- kResolveTimeIntegrity);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- VerifyHttpsMetricsForExpectIntact();
- VerifyHttpsMetricsForExpectNoerror();
- if (querying_experimental_) {
- VerifyAddressResolveTimeMetric({kResolveTime} /* expect_intact_time */);
- VerifyIntegrityMetricsForExpectIntact(
- {HttpssvcDnsRcode::kTimedOut} /* rcode */,
- // "Integrity" metric is omitted because the RCODE is not NOERROR.
- absl::nullopt /* integrity */, absl::nullopt /* record_with_error */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- VerifyIntegrityMetricsForExpectNoerror();
- return;
- }
- VerifyIntegrityMetricsForExpectIntact();
- VerifyAddressResolveTimeMetric(absl::nullopt /* expect_intact_time */,
- {kResolveTime} /* expect_noerror_time */);
- VerifyIntegrityMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kTimedOut} /* rcode */,
- absl::nullopt /* record_received */,
- {kResolveTimeIntegrity} /* resolve_time_integrity */,
- {15} /* resolve_time_ratio */);
- }
- // This test simulates successful address queries and an HTTPS query that
- // timed out.
- TEST_P(HttpssvcMetricsTest, AddressAndHttpsTimedOut) {
- const base::TimeDelta kResolveTime = base::Milliseconds(10);
- const base::TimeDelta kResolveTimeHttps = base::Milliseconds(15);
- auto metrics =
- absl::make_optional<HttpssvcMetrics>(secure_, querying_experimental_);
- metrics->SaveForHttps(HttpssvcDnsRcode::kTimedOut, {}, kResolveTimeHttps);
- metrics->SaveForAddressQuery(kResolveTime, HttpssvcDnsRcode::kNoError);
- metrics.reset(); // Record the metrics to UMA.
- VerifyIntegrityMetricsForExpectIntact();
- VerifyIntegrityMetricsForExpectNoerror();
- if (querying_experimental_) {
- VerifyAddressResolveTimeMetric({kResolveTime} /* expect_intact_time */);
- VerifyHttpsMetricsForExpectIntact(
- {HttpssvcDnsRcode::kTimedOut} /* rcode */,
- // "parsable" metric is omitted because the RCODE is not NOERROR.
- absl::nullopt /* parsable */, absl::nullopt /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {15} /* resolve_time_ratio */);
- VerifyIntegrityMetricsForExpectNoerror();
- return;
- }
- VerifyHttpsMetricsForExpectIntact();
- VerifyAddressResolveTimeMetric(absl::nullopt /* expect_intact_time */,
- {kResolveTime} /* expect_noerror_time */);
- VerifyHttpsMetricsForExpectNoerror(
- {HttpssvcDnsRcode::kTimedOut} /* rcode */,
- // "parsable" metric is omitted because the RCODE is not NOERROR.
- absl::nullopt /* parsable */, absl::nullopt /* record_with_error */,
- {kResolveTimeHttps} /* resolve_time_https */,
- {15} /* resolve_time_ratio */);
- }
- } // namespace net
|