| Index: components/ssl_errors/error_classification_unittest.cc
|
| diff --git a/components/ssl_errors/error_classification_unittest.cc b/components/ssl_errors/error_classification_unittest.cc
|
| index 425a9f2e8ee410597efe509dccba2b9a6ec82687..e436f4e3777597f0b27c5bae5a2a0bfbbb060ade 100644
|
| --- a/components/ssl_errors/error_classification_unittest.cc
|
| +++ b/components/ssl_errors/error_classification_unittest.cc
|
| @@ -8,21 +8,41 @@
|
| #include "base/memory/ptr_util.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/strings/string_split.h"
|
| +#include "base/test/histogram_tester.h"
|
| +#include "base/test/simple_test_clock.h"
|
| +#include "base/test/simple_test_tick_clock.h"
|
| #include "base/time/default_clock.h"
|
| #include "base/time/default_tick_clock.h"
|
| +#include "components/network_time/network_time_test_utils.h"
|
| #include "components/network_time/network_time_tracker.h"
|
| #include "components/prefs/testing_pref_service.h"
|
| #include "net/base/net_errors.h"
|
| #include "net/cert/x509_cert_types.h"
|
| #include "net/cert/x509_certificate.h"
|
| #include "net/test/cert_test_util.h"
|
| +#include "net/test/embedded_test_server/embedded_test_server.h"
|
| +#include "net/test/embedded_test_server/http_response.h"
|
| #include "net/test/test_certificate_data.h"
|
| #include "net/test/test_data_directory.h"
|
| #include "net/url_request/url_request_test_util.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "url/gurl.h"
|
|
|
| -class SSLErrorClassificationTest : public testing::Test {};
|
| +namespace {
|
| +const char kNetworkTimeHistogram[] = "interstitial.ssl.clockstate.network3";
|
| +
|
| +static std::unique_ptr<net::test_server::HttpResponse>
|
| +NetworkErrorResponseHandler(const net::test_server::HttpRequest& request) {
|
| + return std::unique_ptr<net::test_server::HttpResponse>(
|
| + new net::test_server::RawHttpResponse("", ""));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +class SSLErrorClassificationTest : public network_time::FieldTrialTest {
|
| + public:
|
| + SSLErrorClassificationTest() : network_time::FieldTrialTest() {}
|
| +};
|
|
|
| TEST_F(SSLErrorClassificationTest, TestNameMismatch) {
|
| scoped_refptr<net::X509Certificate> google_cert(
|
| @@ -189,6 +209,10 @@ TEST(ErrorClassification, LevenshteinDistance) {
|
| TEST_F(SSLErrorClassificationTest, GetClockState) {
|
| // This test aims to obtain all possible return values of
|
| // |GetClockState|.
|
| + const char kBuildTimeHistogram[] = "interstitial.ssl.clockstate.build_time";
|
| + base::HistogramTester histograms;
|
| + histograms.ExpectTotalCount(kBuildTimeHistogram, 0);
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 0);
|
| TestingPrefServiceSimple pref_service;
|
| network_time::NetworkTimeTracker::RegisterPrefs(pref_service.registry());
|
| base::MessageLoop loop;
|
| @@ -201,18 +225,39 @@ TEST_F(SSLErrorClassificationTest, GetClockState) {
|
| EXPECT_EQ(
|
| ssl_errors::ClockState::CLOCK_STATE_UNKNOWN,
|
| ssl_errors::GetClockState(base::Time::Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kBuildTimeHistogram, 1);
|
| + histograms.ExpectBucketCount(kBuildTimeHistogram,
|
| + ssl_errors::ClockState::CLOCK_STATE_UNKNOWN, 1);
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 1);
|
| + histograms.ExpectBucketCount(
|
| + kNetworkTimeHistogram,
|
| + ssl_errors::NETWORK_CLOCK_STATE_UNKNOWN_NO_SYNC_ATTEMPT, 1);
|
|
|
| ssl_errors::SetBuildTimeForTesting(base::Time::Now() -
|
| base::TimeDelta::FromDays(367));
|
| EXPECT_EQ(
|
| ssl_errors::ClockState::CLOCK_STATE_FUTURE,
|
| ssl_errors::GetClockState(base::Time::Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kBuildTimeHistogram, 2);
|
| + histograms.ExpectBucketCount(kBuildTimeHistogram,
|
| + ssl_errors::ClockState::CLOCK_STATE_FUTURE, 1);
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 2);
|
| + histograms.ExpectBucketCount(
|
| + kNetworkTimeHistogram,
|
| + ssl_errors::NETWORK_CLOCK_STATE_UNKNOWN_NO_SYNC_ATTEMPT, 2);
|
|
|
| ssl_errors::SetBuildTimeForTesting(base::Time::Now() +
|
| base::TimeDelta::FromDays(3));
|
| EXPECT_EQ(
|
| ssl_errors::ClockState::CLOCK_STATE_PAST,
|
| ssl_errors::GetClockState(base::Time::Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kBuildTimeHistogram, 3);
|
| + histograms.ExpectBucketCount(kBuildTimeHistogram,
|
| + ssl_errors::ClockState::CLOCK_STATE_FUTURE, 1);
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 3);
|
| + histograms.ExpectBucketCount(
|
| + kNetworkTimeHistogram,
|
| + ssl_errors::NETWORK_CLOCK_STATE_UNKNOWN_NO_SYNC_ATTEMPT, 3);
|
|
|
| // Intentionally leave the build time alone. It should be ignored
|
| // in favor of network time.
|
| @@ -224,6 +269,10 @@ TEST_F(SSLErrorClassificationTest, GetClockState) {
|
| EXPECT_EQ(
|
| ssl_errors::ClockState::CLOCK_STATE_PAST,
|
| ssl_errors::GetClockState(base::Time::Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kBuildTimeHistogram, 4);
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 4);
|
| + histograms.ExpectBucketCount(
|
| + kNetworkTimeHistogram, ssl_errors::NETWORK_CLOCK_STATE_CLOCK_IN_PAST, 1);
|
|
|
| network_time_tracker.UpdateNetworkTime(
|
| base::Time::Now() - base::TimeDelta::FromHours(1),
|
| @@ -233,6 +282,11 @@ TEST_F(SSLErrorClassificationTest, GetClockState) {
|
| EXPECT_EQ(
|
| ssl_errors::ClockState::CLOCK_STATE_FUTURE,
|
| ssl_errors::GetClockState(base::Time::Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kBuildTimeHistogram, 5);
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 5);
|
| + histograms.ExpectBucketCount(kNetworkTimeHistogram,
|
| + ssl_errors::NETWORK_CLOCK_STATE_CLOCK_IN_FUTURE,
|
| + 1);
|
|
|
| network_time_tracker.UpdateNetworkTime(
|
| base::Time::Now(),
|
| @@ -242,6 +296,10 @@ TEST_F(SSLErrorClassificationTest, GetClockState) {
|
| EXPECT_EQ(
|
| ssl_errors::ClockState::CLOCK_STATE_OK,
|
| ssl_errors::GetClockState(base::Time::Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kBuildTimeHistogram, 6);
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 6);
|
| + histograms.ExpectBucketCount(kNetworkTimeHistogram,
|
| + ssl_errors::NETWORK_CLOCK_STATE_OK, 1);
|
|
|
| // Now clear the network time. The build time should reassert
|
| // itself.
|
| @@ -263,3 +321,123 @@ TEST_F(SSLErrorClassificationTest, GetClockState) {
|
| ssl_errors::ClockState::CLOCK_STATE_UNKNOWN,
|
| ssl_errors::GetClockState(base::Time::Now(), &network_time_tracker));
|
| }
|
| +
|
| +// Tests that all possible NetworkClockState histogram values are recorded
|
| +// appropriately.
|
| +TEST_F(SSLErrorClassificationTest, NetworkClockStateHistogram) {
|
| + base::Thread io_thread("IO thread");
|
| + base::Thread::Options thread_options;
|
| + thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
|
| + EXPECT_TRUE(io_thread.StartWithOptions(thread_options));
|
| +
|
| + net::EmbeddedTestServer test_server;
|
| + ASSERT_TRUE(test_server.Start());
|
| +
|
| + base::HistogramTester histograms;
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 0);
|
| + TestingPrefServiceSimple pref_service;
|
| + network_time::NetworkTimeTracker::RegisterPrefs(pref_service.registry());
|
| + base::SimpleTestTickClock* tick_clock = new base::SimpleTestTickClock;
|
| + base::SimpleTestClock* clock = new base::SimpleTestClock;
|
| + // Do this to be sure that |is_null| returns false.
|
| + clock->Advance(base::TimeDelta::FromDays(111));
|
| + tick_clock->Advance(base::TimeDelta::FromDays(222));
|
| +
|
| + base::MessageLoop loop;
|
| + network_time::NetworkTimeTracker network_time_tracker(
|
| + std::unique_ptr<base::Clock>(clock),
|
| + std::unique_ptr<base::TickClock>(tick_clock), &pref_service,
|
| + new net::TestURLRequestContextGetter(io_thread.task_runner()));
|
| + network_time_tracker.SetTimeServerURLForTesting(test_server.GetURL("/"));
|
| + SetNetworkQueriesWithVariationsService(true, 0.0);
|
| +
|
| + // No sync attempt.
|
| + EXPECT_EQ(
|
| + ssl_errors::ClockState::CLOCK_STATE_UNKNOWN,
|
| + ssl_errors::GetClockState(base::Time::Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 1);
|
| + histograms.ExpectBucketCount(
|
| + kNetworkTimeHistogram,
|
| + ssl_errors::NETWORK_CLOCK_STATE_UNKNOWN_NO_SYNC_ATTEMPT, 1);
|
| +
|
| + // First sync attempt is pending.
|
| + test_server.RegisterRequestHandler(base::Bind(&NetworkErrorResponseHandler));
|
| + EXPECT_TRUE(network_time_tracker.QueryTimeServiceForTesting());
|
| + EXPECT_EQ(
|
| + ssl_errors::ClockState::CLOCK_STATE_UNKNOWN,
|
| + ssl_errors::GetClockState(base::Time::Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 2);
|
| + histograms.ExpectBucketCount(
|
| + kNetworkTimeHistogram,
|
| + ssl_errors::NETWORK_CLOCK_STATE_UNKNOWN_FIRST_SYNC_PENDING, 1);
|
| + network_time_tracker.WaitForFetchForTesting(123123123);
|
| +
|
| + // No successful sync.
|
| + EXPECT_EQ(
|
| + ssl_errors::ClockState::CLOCK_STATE_UNKNOWN,
|
| + ssl_errors::GetClockState(base::Time::Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 3);
|
| + histograms.ExpectBucketCount(
|
| + kNetworkTimeHistogram,
|
| + ssl_errors::NETWORK_CLOCK_STATE_UNKNOWN_NO_SUCCESSFUL_SYNC, 1);
|
| +
|
| + // Subsequent sync attempt is pending.
|
| + EXPECT_TRUE(network_time_tracker.QueryTimeServiceForTesting());
|
| + EXPECT_EQ(
|
| + ssl_errors::ClockState::CLOCK_STATE_UNKNOWN,
|
| + ssl_errors::GetClockState(base::Time::Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 4);
|
| + histograms.ExpectBucketCount(
|
| + kNetworkTimeHistogram,
|
| + ssl_errors::NETWORK_CLOCK_STATE_UNKNOWN_SUBSEQUENT_SYNC_PENDING, 1);
|
| + network_time_tracker.WaitForFetchForTesting(123123123);
|
| +
|
| + // System clock is correct.
|
| + network_time_tracker.UpdateNetworkTime(
|
| + clock->Now(),
|
| + base::TimeDelta::FromSeconds(1), // resolution
|
| + base::TimeDelta::FromMilliseconds(250), // latency
|
| + tick_clock->NowTicks()); // posting time
|
| + EXPECT_EQ(ssl_errors::ClockState::CLOCK_STATE_OK,
|
| + ssl_errors::GetClockState(clock->Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 5);
|
| + histograms.ExpectBucketCount(kNetworkTimeHistogram,
|
| + ssl_errors::NETWORK_CLOCK_STATE_OK, 1);
|
| +
|
| + // System clock is in the past.
|
| + network_time_tracker.UpdateNetworkTime(
|
| + clock->Now() + base::TimeDelta::FromHours(1),
|
| + base::TimeDelta::FromSeconds(1), // resolution
|
| + base::TimeDelta::FromMilliseconds(250), // latency
|
| + tick_clock->NowTicks()); // posting time
|
| + EXPECT_EQ(ssl_errors::ClockState::CLOCK_STATE_PAST,
|
| + ssl_errors::GetClockState(clock->Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 6);
|
| + histograms.ExpectBucketCount(
|
| + kNetworkTimeHistogram, ssl_errors::NETWORK_CLOCK_STATE_CLOCK_IN_PAST, 1);
|
| +
|
| + // System clock is in the future.
|
| + network_time_tracker.UpdateNetworkTime(
|
| + clock->Now() - base::TimeDelta::FromHours(1),
|
| + base::TimeDelta::FromSeconds(1), // resolution
|
| + base::TimeDelta::FromMilliseconds(250), // latency
|
| + tick_clock->NowTicks()); // posting time
|
| + EXPECT_EQ(ssl_errors::ClockState::CLOCK_STATE_FUTURE,
|
| + ssl_errors::GetClockState(clock->Now(), &network_time_tracker));
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 7);
|
| + histograms.ExpectBucketCount(kNetworkTimeHistogram,
|
| + ssl_errors::NETWORK_CLOCK_STATE_CLOCK_IN_FUTURE,
|
| + 1);
|
| +
|
| + // Sync has been lost.
|
| + tick_clock->Advance(base::TimeDelta::FromSeconds(1));
|
| + clock->Advance(base::TimeDelta::FromDays(1));
|
| + // GetClockState() will fall back to the build time heuristic.
|
| + ssl_errors::GetClockState(clock->Now(), &network_time_tracker);
|
| + histograms.ExpectTotalCount(kNetworkTimeHistogram, 8);
|
| + histograms.ExpectBucketCount(
|
| + kNetworkTimeHistogram, ssl_errors::NETWORK_CLOCK_STATE_UNKNOWN_SYNC_LOST,
|
| + 1);
|
| +
|
| + io_thread.Stop();
|
| +}
|
|
|