chromium/components/sync/engine/sync_scheduler_impl_unittest.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/sync/engine/sync_scheduler_impl.h"

#include <stddef.h>
#include <stdint.h>

#include <utility>
#include <vector>

#include "base/functional/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/task/sequenced_task_runner.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "base/test/test_timeouts.h"
#include "base/time/time.h"
#include "components/sync/base/extensions_activity.h"
#include "components/sync/engine/backoff_delay_provider.h"
#include "components/sync/engine/cancelation_signal.h"
#include "components/sync/engine/data_type_activation_response.h"
#include "components/sync/test/data_type_test_util.h"
#include "components/sync/test/fake_data_type_processor.h"
#include "components/sync/test/fake_sync_encryption_handler.h"
#include "components/sync/test/mock_connection_manager.h"
#include "components/sync/test/mock_invalidation.h"
#include "components/sync/test/mock_nudge_handler.h"
#include "net/base/net_errors.h"
#include "net/http/http_status_code.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

TimeTicks;
_;
AtLeast;
DoAll;
Eq;
Invoke;
Mock;
Return;
WithArg;
WithArgs;
WithoutArgs;

namespace syncer {

namespace {
base::OnceClosure g_quit_closure_;
void SimulatePollSuccess(DataTypeSet requested_types, SyncCycle* cycle) {}

void SimulatePollFailed(DataTypeSet requested_types, SyncCycle* cycle) {}

ACTION_P(SimulateThrottled, throttle) {}

ACTION_P2(SimulateTypeThrottled, type, throttle) {}

ACTION_P(SimulatePartialFailure, type) {}

ACTION_P(SimulatePollIntervalUpdate, new_poll) {}

ACTION_P(SimulateGuRetryDelayCommand, delay) {}

void SimulateGetEncryptionKeyFailed(DataTypeSet requsted_types,
                                    sync_pb::SyncEnums::GetUpdatesOrigin origin,
                                    SyncCycle* cycle) {}

void SimulateConfigureSuccess(DataTypeSet requsted_types,
                              sync_pb::SyncEnums::GetUpdatesOrigin origin,
                              SyncCycle* cycle) {}

void SimulateConfigureFailed(DataTypeSet requsted_types,
                             sync_pb::SyncEnums::GetUpdatesOrigin origin,
                             SyncCycle* cycle) {}

void SimulateConfigureConnectionFailure(
    DataTypeSet requsted_types,
    sync_pb::SyncEnums::GetUpdatesOrigin origin,
    SyncCycle* cycle) {}

void SimulateNormalSuccess(DataTypeSet requested_types,
                           NudgeTracker* nudge_tracker,
                           SyncCycle* cycle) {}

void SimulateDownloadUpdatesFailed(DataTypeSet requested_types,
                                   NudgeTracker* nudge_tracker,
                                   SyncCycle* cycle) {}

void SimulateCommitFailed(DataTypeSet requested_types,
                          NudgeTracker* nudge_tracker,
                          SyncCycle* cycle) {}

void SimulateConnectionFailure(DataTypeSet requested_types,
                               NudgeTracker* nudge_tracker,
                               SyncCycle* cycle) {}

class MockSyncer : public Syncer {};

std::unique_ptr<DataTypeActivationResponse> MakeFakeActivationResponse(
    DataType data_type) {}

MockSyncer::MockSyncer() :{}

SyncShareTimes;

void QuitLoopNow() {}

void RunLoop() {}

void PumpLoop() {}

static const size_t kMinNumSamples =;

}  // namespace

// Test harness for the SyncScheduler.  Test the delays and backoff timers used
// in response to various events.  Mock time is used to avoid flakes.
class SyncSchedulerImplTest : public testing::Test {};

const base::TickClock* SyncSchedulerImplTest::tick_clock_ =;

void RecordSyncShareImpl(SyncShareTimes* times) {}

ACTION_P2(RecordSyncShare, times, success) {}

ACTION_P3(RecordSyncShareMultiple, times, quit_after, success) {}

ACTION_P(StopScheduler, scheduler) {}

ACTION(AddFailureAndQuitLoopNow) {}

ACTION_P(QuitLoopNowAction, success) {}

// Test nudge scheduling.
TEST_F(SyncSchedulerImplTest, Nudge) {}

TEST_F(SyncSchedulerImplTest, NudgeForDisabledType) {}

// Make sure a regular config command is scheduled fine in the absence of any
// errors.
TEST_F(SyncSchedulerImplTest, Config) {}

// Simulate a failure and make sure the config request is retried.
TEST_F(SyncSchedulerImplTest, ConfigWithBackingOff) {}

// Simuilate SyncSchedulerImpl::Stop being called in the middle of Configure.
// This can happen if server returns NOT_MY_BIRTHDAY.
TEST_F(SyncSchedulerImplTest, ConfigWithStop) {}

// Verify that in the absence of valid access token the command will fail.
TEST_F(SyncSchedulerImplTest, ConfigNoAccessToken) {}

// Verify that in the absence of valid access token the command will pass if
// local sync backend is used.
TEST_F(SyncSchedulerImplTest, ConfigNoAccessTokenLocalSync) {}

// Issue a nudge when the config has failed. Make sure both the config and
// nudge are executed.
TEST_F(SyncSchedulerImplTest, NudgeWithConfigWithBackingOff) {}

// Test that nudges are coalesced.
TEST_F(SyncSchedulerImplTest, NudgeCoalescing) {}

// Test that nudges are coalesced.
TEST_F(SyncSchedulerImplTest, NudgeCoalescingWithDifferentTimings) {}

// Test nudge scheduling.
TEST_F(SyncSchedulerImplTest, NudgeWithStates) {}

// Test that polling works as expected.
TEST_F(SyncSchedulerImplTest, Polling) {}

TEST_F(SyncSchedulerImplTest, ShouldPollOnBrowserStartup) {}

// Test that polling gets the intervals from the provided context.
TEST_F(SyncSchedulerImplTest, ShouldUseInitialPollIntervalFromContext) {}

// Test that we reuse the previous poll time on startup, triggering the first
// poll based on when the last one happened. Subsequent polls should have the
// normal delay.
TEST_F(SyncSchedulerImplTest, PollingPersistence) {}

// Test that if the persisted poll is in the future, it's ignored (the case
// where the local time has been modified).
TEST_F(SyncSchedulerImplTest, PollingPersistenceBadClock) {}

// Test that polling intervals are updated when needed.
TEST_F(SyncSchedulerImplTest, PollIntervalUpdate) {}

// Test that no syncing occurs when throttled.
TEST_F(SyncSchedulerImplTest, ThrottlingDoesThrottle) {}

TEST_F(SyncSchedulerImplTest, ThrottlingExpiresFromPoll) {}

TEST_F(SyncSchedulerImplTest, ThrottlingExpiresFromNudge) {}

TEST_F(SyncSchedulerImplTest, ThrottlingExpiresFromConfigure) {}

TEST_F(SyncSchedulerImplTest, TypeThrottlingBlocksNudge) {}

TEST_F(SyncSchedulerImplTest, TypeBackingOffBlocksNudge) {}

TEST_F(SyncSchedulerImplTest, TypeBackingOffWillExpire) {}

TEST_F(SyncSchedulerImplTest, TypeBackingOffAndThrottling) {}

TEST_F(SyncSchedulerImplTest, TypeThrottlingBackingOffBlocksNudge) {}

TEST_F(SyncSchedulerImplTest, TypeThrottlingDoesBlockOtherSources) {}

TEST_F(SyncSchedulerImplTest, TypeBackingOffDoesBlockOtherSources) {}

// Test nudges / polls don't run in config mode and config tasks do.
TEST_F(SyncSchedulerImplTest, ConfigurationMode) {}

class BackoffTriggersSyncSchedulerImplTest : public SyncSchedulerImplTest {};

// Have the syncer fail during commit.  Expect that the scheduler enters
// backoff.
TEST_F(BackoffTriggersSyncSchedulerImplTest, FailCommitOnce) {}

// Have the syncer fail during download updates and succeed on the first
// retry.  Expect that this clears the backoff state.
TEST_F(BackoffTriggersSyncSchedulerImplTest, FailDownloadOnceThenSucceed) {}

// Have the syncer fail during commit and succeed on the first retry.  Expect
// that this clears the backoff state.
TEST_F(BackoffTriggersSyncSchedulerImplTest, FailCommitOnceThenSucceed) {}

// Have the syncer fail to download updates and fail again on the retry.
// Expect this will leave the scheduler in backoff.
TEST_F(BackoffTriggersSyncSchedulerImplTest, FailDownloadTwice) {}

// Have the syncer fail to get the encryption key yet succeed in downloading
// updates. Expect this will leave the scheduler in backoff.
TEST_F(BackoffTriggersSyncSchedulerImplTest, FailGetEncryptionKey) {}

// Test that no polls or extraneous nudges occur when in backoff.
TEST_F(SyncSchedulerImplTest, BackoffDropsJobs) {}

// Test that backoff is shaping traffic properly with consecutive errors.
TEST_F(SyncSchedulerImplTest, BackoffElevation) {}

// Test that things go back to normal once a retry makes forward progress.
TEST_F(SyncSchedulerImplTest, BackoffRelief) {}

// Test that poll failures are treated like any other failure. They should
// result in retry with backoff.
TEST_F(SyncSchedulerImplTest, TransientPollFailure) {}

// Test that starting the syncer thread without a valid connection doesn't
// break things when a connection is detected.
TEST_F(SyncSchedulerImplTest, StartWhenNotConnected) {}

// Test that when disconnect signal (CONNECTION_NONE) is received, normal sync
// share is not called.
TEST_F(SyncSchedulerImplTest, SyncShareNotCalledWhenDisconnected) {}

TEST_F(SyncSchedulerImplTest, ServerConnectionChangeDuringBackoff) {}

// Tests that there's no crash trying to run two jobs at once if the scheduler
// received extra connection status change notifications.  See crbug.com/190085.
TEST_F(SyncSchedulerImplTest, DoubleConnectionChangeDuringConfigure) {}

TEST_F(SyncSchedulerImplTest, PollAfterAuthError) {}

TEST_F(SyncSchedulerImplTest, SuccessfulRetry) {}

TEST_F(SyncSchedulerImplTest, FailedRetry) {}

ACTION_P2(VerifyRetryTimerDelay, scheduler_test, expected_delay) {}

TEST_F(SyncSchedulerImplTest, ReceiveNewRetryDelay) {}

TEST_F(SyncSchedulerImplTest, PartialFailureWillExponentialBackoff) {}

// If a datatype is in backoff or throttling, pending_wakeup_timer_ should
// schedule a delay job for OnTypesUnblocked. SyncScheduler sometimes use
// pending_wakeup_timer_ to schdule PerformDelayedNudge job before
// OnTypesUnblocked got run. This test will verify after ran
// PerformDelayedNudge, OnTypesUnblocked will be rescheduled if any datatype is
// in backoff or throttling.
TEST_F(SyncSchedulerImplTest, TypeBackoffAndSuccessfulSync) {}

// Verify that the timer is scheduled for an unblock job after one datatype is
// unblocked, and there is another one still blocked.
TEST_F(SyncSchedulerImplTest, TypeBackingOffAndFailureSync) {}

TEST_F(SyncSchedulerImplTest, InterleavedNudgesStillRestart) {}

}  // namespace syncer