// Copyright 2016 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 "components/sync/driver/model_type_controller.h"

#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "components/sync/driver/configure_context.h"
#include "components/sync/engine/commit_queue.h"
#include "components/sync/engine/data_type_activation_response.h"
#include "components/sync/engine/fake_model_type_processor.h"
#include "components/sync/engine/model_type_configurer.h"
#include "components/sync/engine/model_type_processor_proxy.h"
#include "components/sync/model/data_type_activation_request.h"
#include "components/sync/model/sync_merge_result.h"
#include "components/sync/model_impl/forwarding_model_type_controller_delegate.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace syncer {

namespace {

using testing::NiceMock;
using testing::_;

const ModelType kTestModelType = AUTOFILL;
const char kCacheGuid[] = "SomeCacheGuid";
const char kAccountId[] = "SomeAccountId";

const char kStartFailuresHistogram[] = "Sync.DataTypeStartFailures2";
const char kRunFailuresHistogram[] = "Sync.DataTypeRunFailures2";

MATCHER(ErrorIsSet, "") {
  return arg.IsSet();
}

class MockDelegate : public ModelTypeControllerDelegate {
 public:
  MOCK_METHOD2(OnSyncStarting,
               void(const DataTypeActivationRequest& request,
                    StartCallback callback));
  MOCK_METHOD1(OnSyncStopping, void(SyncStopMetadataFate metadata_fate));
  MOCK_METHOD1(GetAllNodesForDebugging, void(AllNodesCallback callback));
  MOCK_METHOD1(GetStatusCountersForDebugging,
               void(StatusCountersCallback callback));
  MOCK_METHOD0(RecordMemoryUsageAndCountsHistograms, void());
};

// A simple processor that trackes connected state.
class TestModelTypeProcessor
    : public FakeModelTypeProcessor,
      public base::SupportsWeakPtr<TestModelTypeProcessor> {
 public:
  TestModelTypeProcessor() {}

  bool is_connected() const { return is_connected_; }

  // ModelTypeProcessor implementation.
  void ConnectSync(std::unique_ptr<CommitQueue> commit_queue) override {
    is_connected_ = true;
  }

  void DisconnectSync() override { is_connected_ = false; }

 private:
  bool is_connected_ = false;

  DISALLOW_COPY_AND_ASSIGN(TestModelTypeProcessor);
};

// A ModelTypeConfigurer that just connects USS types.
class TestModelTypeConfigurer : public ModelTypeConfigurer {
 public:
  TestModelTypeConfigurer() {}
  ~TestModelTypeConfigurer() override {}

  void ConfigureDataTypes(ConfigureParams params) override {
    NOTREACHED() << "Not implemented.";
  }

  void RegisterDirectoryDataType(ModelType type,
                                 ModelSafeGroup group) override {
    NOTREACHED() << "Not implemented.";
  }

  void UnregisterDirectoryDataType(ModelType type) override {
    NOTREACHED() << "Not implemented.";
  }

  void ActivateDirectoryDataType(ModelType type,
                                 ModelSafeGroup group,
                                 ChangeProcessor* change_processor) override {
    NOTREACHED() << "Not implemented.";
  }

  void DeactivateDirectoryDataType(ModelType type) override {
    NOTREACHED() << "Not implemented.";
  }

  void ActivateNonBlockingDataType(ModelType type,
                                   std::unique_ptr<DataTypeActivationResponse>
                                       activation_response) override {
    DCHECK_EQ(kTestModelType, type);
    DCHECK(!processor_);
    processor_ = std::move(activation_response->type_processor);
    processor_->ConnectSync(nullptr);
  }

  void DeactivateNonBlockingDataType(ModelType type) override {
    DCHECK_EQ(kTestModelType, type);
    DCHECK(processor_);
    processor_->DisconnectSync();
    processor_.reset();
  }

 private:
  std::unique_ptr<ModelTypeProcessor> processor_;
};

ConfigureContext MakeConfigureContext() {
  ConfigureContext context;
  context.authenticated_account_id = kAccountId;
  context.cache_guid = kCacheGuid;
  return context;
}

}  // namespace

class ModelTypeControllerTest : public testing::Test {
 public:
  ModelTypeControllerTest()
      : controller_(kTestModelType,
                    std::make_unique<ForwardingModelTypeControllerDelegate>(
                        &mock_delegate_)) {}

  ~ModelTypeControllerTest() {
    // Since we use ModelTypeProcessorProxy, which posts tasks, make sure we
    // don't have anything pending on teardown that would make a test fail or
    // crash.
    base::RunLoop().RunUntilIdle();
  }

  bool LoadModels(bool initial_sync_done = false) {
    base::MockCallback<DataTypeController::ModelLoadCallback> load_models_done;

    ModelTypeControllerDelegate::StartCallback start_callback;
    EXPECT_CALL(mock_delegate_, OnSyncStarting(_, _))
        .WillOnce([&](const DataTypeActivationRequest& request,
                      ModelTypeControllerDelegate::StartCallback callback) {
          start_callback = std::move(callback);
        });

    controller_.LoadModels(MakeConfigureContext(), load_models_done.Get());
    if (!start_callback) {
      return false;
    }

    // Prepare an activation response, which is the outcome of OnSyncStarting().
    auto activation_response = std::make_unique<DataTypeActivationResponse>();
    activation_response->model_type_state.set_initial_sync_done(
        initial_sync_done);
    activation_response->type_processor =
        std::make_unique<ModelTypeProcessorProxy>(
            base::AsWeakPtr(&processor_),
            base::SequencedTaskRunnerHandle::Get());

    // Mimic completion for OnSyncStarting().
    EXPECT_CALL(load_models_done, Run(_, _));
    std::move(start_callback).Run(std::move(activation_response));
    return true;
  }

  void RegisterWithBackend(bool expect_downloaded) {
    base::MockCallback<base::RepeatingCallback<void(bool)>> callback;
    EXPECT_CALL(callback, Run(expect_downloaded));
    controller_.RegisterWithBackend(callback.Get(), &configurer_);
    // ModelTypeProcessorProxy does posting of tasks.
    base::RunLoop().RunUntilIdle();
  }

  void StartAssociating() {
    base::MockCallback<DataTypeController::StartCallback> callback;
    EXPECT_CALL(callback, Run(DataTypeController::OK, _, _));
    controller_.StartAssociating(callback.Get());
  }

  void StopAndWait(ShutdownReason shutdown_reason) {
    // ModelTypeProcessorProxy does posting of tasks, so we need a runloop. This
    // also verifies that the completion callback is run.
    base::RunLoop loop;
    controller_.Stop(shutdown_reason, loop.QuitClosure());
    loop.Run();
  }

  void DeactivateDataTypeAndStop(ShutdownReason shutdown_reason) {
    controller_.DeactivateDataType(&configurer_);
    StopAndWait(shutdown_reason);
  }

  MockDelegate* delegate() { return &mock_delegate_; }
  TestModelTypeProcessor* processor() { return &processor_; }
  DataTypeController* controller() { return &controller_; }

 private:
  base::test::ScopedTaskEnvironment task_environment_;
  NiceMock<MockDelegate> mock_delegate_;
  TestModelTypeConfigurer configurer_;
  TestModelTypeProcessor processor_;
  ModelTypeController controller_;
};

TEST_F(ModelTypeControllerTest, InitialState) {
  EXPECT_EQ(kTestModelType, controller()->type());
  EXPECT_EQ(DataTypeController::NOT_RUNNING, controller()->state());
}

TEST_F(ModelTypeControllerTest, LoadModelsOnBackendThread) {
  base::MockCallback<DataTypeController::ModelLoadCallback> load_models_done;

  ModelTypeControllerDelegate::StartCallback start_callback;
  EXPECT_CALL(*delegate(), OnSyncStarting(_, _))
      .WillOnce([&](const DataTypeActivationRequest& request,
                    ModelTypeControllerDelegate::StartCallback callback) {
        start_callback = std::move(callback);
      });

  controller()->LoadModels(MakeConfigureContext(), load_models_done.Get());
  EXPECT_EQ(DataTypeController::MODEL_STARTING, controller()->state());
  ASSERT_TRUE(start_callback);

  // Mimic completion for OnSyncStarting().
  EXPECT_CALL(load_models_done, Run(kTestModelType, _));
  std::move(start_callback).Run(std::make_unique<DataTypeActivationResponse>());
  EXPECT_EQ(DataTypeController::MODEL_LOADED, controller()->state());
}

TEST_F(ModelTypeControllerTest, Activate) {
  base::HistogramTester histogram_tester;
  ASSERT_TRUE(LoadModels());
  EXPECT_EQ(DataTypeController::MODEL_LOADED, controller()->state());
  RegisterWithBackend(/*expect_downloaded=*/false);
  EXPECT_TRUE(processor()->is_connected());

  StartAssociating();
  EXPECT_EQ(DataTypeController::RUNNING, controller()->state());
  histogram_tester.ExpectTotalCount(kStartFailuresHistogram, 0);
}

TEST_F(ModelTypeControllerTest, ActivateWithInitialSyncDone) {
  base::HistogramTester histogram_tester;
  ASSERT_TRUE(LoadModels(/*initial_sync_done=*/true));
  EXPECT_EQ(DataTypeController::MODEL_LOADED, controller()->state());
  RegisterWithBackend(/*expect_downloaded=*/true);
  EXPECT_TRUE(processor()->is_connected());
  histogram_tester.ExpectTotalCount(kStartFailuresHistogram, 0);
}

TEST_F(ModelTypeControllerTest, ActivateWithError) {
  ModelErrorHandler error_handler;
  EXPECT_CALL(*delegate(), OnSyncStarting(_, _))
      .WillOnce([&](const DataTypeActivationRequest& request,
                    ModelTypeControllerDelegate::StartCallback callback) {
        error_handler = request.error_handler;
      });

  base::MockCallback<DataTypeController::ModelLoadCallback> load_models_done;
  controller()->LoadModels(MakeConfigureContext(), load_models_done.Get());
  ASSERT_EQ(DataTypeController::MODEL_STARTING, controller()->state());
  ASSERT_TRUE(error_handler);

  base::HistogramTester histogram_tester;
  // Mimic completion for OnSyncStarting(), with an error.
  EXPECT_CALL(*delegate(), OnSyncStopping(_)).Times(0);
  EXPECT_CALL(load_models_done, Run(_, ErrorIsSet()));
  error_handler.Run(ModelError(FROM_HERE, "Test error"));
  // TODO(mastiz): We shouldn't need RunUntilIdle() here, but
  // ModelTypeController currently uses task-posting for errors.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(DataTypeController::FAILED, controller()->state());
  histogram_tester.ExpectBucketCount(
      kStartFailuresHistogram, ModelTypeToHistogramInt(kTestModelType), 1);
  histogram_tester.ExpectTotalCount(kRunFailuresHistogram, 0);
}

TEST_F(ModelTypeControllerTest, Stop) {
  ASSERT_TRUE(LoadModels());
  RegisterWithBackend(/*expect_downloaded=*/false);
  EXPECT_TRUE(processor()->is_connected());

  StartAssociating();

  DeactivateDataTypeAndStop(STOP_SYNC);
  EXPECT_EQ(DataTypeController::NOT_RUNNING, controller()->state());
}

// Test emulates normal browser shutdown. Ensures that metadata was not cleared.
TEST_F(ModelTypeControllerTest, StopWhenDatatypeEnabled) {
  ASSERT_TRUE(LoadModels());
  StartAssociating();

  // Ensures that metadata was not cleared.
  EXPECT_CALL(*delegate(), OnSyncStopping(KEEP_METADATA));
  DeactivateDataTypeAndStop(STOP_SYNC);
  EXPECT_EQ(DataTypeController::NOT_RUNNING, controller()->state());
  EXPECT_FALSE(processor()->is_connected());
}

// Test emulates scenario when user disables datatype. Metadata should be
// cleared.
TEST_F(ModelTypeControllerTest, StopWhenDatatypeDisabled) {
  ASSERT_TRUE(LoadModels());
  StartAssociating();

  EXPECT_CALL(*delegate(), OnSyncStopping(CLEAR_METADATA));
  DeactivateDataTypeAndStop(DISABLE_SYNC);
  EXPECT_EQ(DataTypeController::NOT_RUNNING, controller()->state());
  EXPECT_FALSE(processor()->is_connected());
}

// Test emulates disabling sync when datatype is not loaded yet. Metadata should
// not be cleared as the delegate is potentially not ready to handle it.
TEST_F(ModelTypeControllerTest, StopBeforeLoadModels) {
  EXPECT_CALL(*delegate(), OnSyncStopping(CLEAR_METADATA)).Times(0);

  ASSERT_EQ(DataTypeController::NOT_RUNNING, controller()->state());

  StopAndWait(DISABLE_SYNC);

  EXPECT_EQ(DataTypeController::NOT_RUNNING, controller()->state());
}

// Test emulates disabling sync when datatype is in error state. Metadata should
// not be cleared as the delegate is potentially not ready to handle it.
TEST_F(ModelTypeControllerTest, StopDuringFailedState) {
  EXPECT_CALL(*delegate(), OnSyncStopping(CLEAR_METADATA)).Times(0);

  ModelErrorHandler error_handler;
  EXPECT_CALL(*delegate(), OnSyncStarting(_, _))
      .WillOnce([&](const DataTypeActivationRequest& request,
                    ModelTypeControllerDelegate::StartCallback callback) {
        error_handler = request.error_handler;
      });

  base::MockCallback<DataTypeController::ModelLoadCallback> load_models_done;
  controller()->LoadModels(MakeConfigureContext(), load_models_done.Get());
  ASSERT_EQ(DataTypeController::MODEL_STARTING, controller()->state());
  ASSERT_TRUE(error_handler);
  // Mimic completion for OnSyncStarting(), with an error.
  error_handler.Run(ModelError(FROM_HERE, "Test error"));
  // TODO(mastiz): We shouldn't need RunUntilIdle() here, but
  // ModelTypeController currently uses task-posting for errors.
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(DataTypeController::FAILED, controller()->state());

  StopAndWait(DISABLE_SYNC);

  EXPECT_EQ(DataTypeController::FAILED, controller()->state());
}

// Test emulates disabling sync when datatype is loading. The controller should
// wait for completion of the delegate, before stopping it.
TEST_F(ModelTypeControllerTest, StopWhileStarting) {
  ModelTypeControllerDelegate::StartCallback start_callback;
  EXPECT_CALL(*delegate(), OnSyncStarting(_, _))
      .WillOnce([&](const DataTypeActivationRequest& request,
                    ModelTypeControllerDelegate::StartCallback callback) {
        start_callback = std::move(callback);
      });

  controller()->LoadModels(MakeConfigureContext(), base::DoNothing());
  ASSERT_EQ(DataTypeController::MODEL_STARTING, controller()->state());
  ASSERT_TRUE(start_callback);

  // Stop() should be deferred until OnSyncStarting() finishes.
  base::MockCallback<base::OnceClosure> stop_completion;
  EXPECT_CALL(stop_completion, Run()).Times(0);
  EXPECT_CALL(*delegate(), OnSyncStopping(_)).Times(0);
  controller()->Stop(DISABLE_SYNC, stop_completion.Get());
  EXPECT_EQ(DataTypeController::STOPPING, controller()->state());

  // Mimic completion for OnSyncStarting().
  EXPECT_CALL(*delegate(), OnSyncStopping(_));
  EXPECT_CALL(stop_completion, Run());
  std::move(start_callback).Run(std::make_unique<DataTypeActivationResponse>());
  EXPECT_EQ(DataTypeController::NOT_RUNNING, controller()->state());
}

// Test emulates disabling sync when datatype is loading. The controller should
// wait for completion of the delegate, before stopping it. In this test,
// loading produces an error, so the resulting state should be FAILED.
TEST_F(ModelTypeControllerTest, StopWhileStartingWithError) {
  ModelErrorHandler error_handler;
  EXPECT_CALL(*delegate(), OnSyncStarting(_, _))
      .WillOnce([&](const DataTypeActivationRequest& request,
                    ModelTypeControllerDelegate::StartCallback callback) {
        error_handler = request.error_handler;
      });

  controller()->LoadModels(MakeConfigureContext(), base::DoNothing());
  ASSERT_EQ(DataTypeController::MODEL_STARTING, controller()->state());
  ASSERT_TRUE(error_handler);

  // Stop() should be deferred until OnSyncStarting() finishes.
  base::MockCallback<base::OnceClosure> stop_completion;
  EXPECT_CALL(stop_completion, Run()).Times(0);
  EXPECT_CALL(*delegate(), OnSyncStopping(_)).Times(0);
  controller()->Stop(DISABLE_SYNC, stop_completion.Get());
  EXPECT_EQ(DataTypeController::STOPPING, controller()->state());

  base::HistogramTester histogram_tester;
  // Mimic completion for OnSyncStarting(), with an error.
  EXPECT_CALL(*delegate(), OnSyncStopping(_)).Times(0);
  EXPECT_CALL(stop_completion, Run());
  error_handler.Run(ModelError(FROM_HERE, "Test error"));
  // TODO(mastiz): We shouldn't need RunUntilIdle() here, but
  // ModelTypeController currently uses task-posting for errors.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(DataTypeController::FAILED, controller()->state());
  histogram_tester.ExpectBucketCount(kStartFailuresHistogram,
                                     ModelTypeToHistogramInt(kTestModelType),
                                     /*count=*/1);
  histogram_tester.ExpectTotalCount(kRunFailuresHistogram, 0);
}

// Test emulates a controller talking to a delegate (processor) in a backend
// thread, which necessarily involves task posting (usually via
// ProxyModelTypeControllerDelegate), where the backend posts an error
// simultaneously to the UI stopping the datatype.
TEST_F(ModelTypeControllerTest, StopWhileErrorInFlight) {
  ModelTypeControllerDelegate::StartCallback start_callback;
  ModelErrorHandler error_handler;
  EXPECT_CALL(*delegate(), OnSyncStarting(_, _))
      .WillOnce([&](const DataTypeActivationRequest& request,
                    ModelTypeControllerDelegate::StartCallback callback) {
        start_callback = std::move(callback);
        error_handler = request.error_handler;
      });

  controller()->LoadModels(MakeConfigureContext(), base::DoNothing());
  ASSERT_EQ(DataTypeController::MODEL_STARTING, controller()->state());
  ASSERT_TRUE(start_callback);
  ASSERT_TRUE(error_handler);

  // Mimic completion for OnSyncStarting().
  std::move(start_callback).Run(std::make_unique<DataTypeActivationResponse>());
  ASSERT_EQ(DataTypeController::MODEL_LOADED, controller()->state());

  // At this point, the UI stops the datatype, but it's possible that the
  // backend has already posted a task to the UI thread, which we'll process
  // later below.
  StopAndWait(DISABLE_SYNC);
  ASSERT_EQ(DataTypeController::NOT_RUNNING, controller()->state());

  base::HistogramTester histogram_tester;
  // In the next loop iteration, the UI thread receives the error.
  error_handler.Run(ModelError(FROM_HERE, "Test error"));
  // TODO(mastiz): We shouldn't need RunUntilIdle() here, but
  // ModelTypeController currently uses task-posting for errors.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(DataTypeController::FAILED, controller()->state());
  histogram_tester.ExpectTotalCount(kStartFailuresHistogram, 0);
  histogram_tester.ExpectTotalCount(kRunFailuresHistogram, 0);
}

// Tests that StorageOption is honored when the controller has been constructed
// with two delegates.
TEST(ModelTypeControllerWithMultiDelegateTest, ToggleStorageOption) {
  base::test::ScopedTaskEnvironment task_environment;
  NiceMock<MockDelegate> delegate_on_disk;
  NiceMock<MockDelegate> delegate_in_memory;

  ModelTypeController controller(
      kTestModelType,
      std::make_unique<ForwardingModelTypeControllerDelegate>(
          &delegate_on_disk),
      std::make_unique<ForwardingModelTypeControllerDelegate>(
          &delegate_in_memory));

  ConfigureContext context;
  context.authenticated_account_id = kAccountId;
  context.cache_guid = kCacheGuid;

  ModelTypeControllerDelegate::StartCallback start_callback;

  // Start sync with STORAGE_IN_MEMORY.
  EXPECT_CALL(delegate_on_disk, OnSyncStarting(_, _)).Times(0);
  EXPECT_CALL(delegate_in_memory, OnSyncStarting(_, _))
      .WillOnce([&](const DataTypeActivationRequest& request,
                    ModelTypeControllerDelegate::StartCallback callback) {
        start_callback = std::move(callback);
      });
  context.storage_option = STORAGE_IN_MEMORY;
  controller.LoadModels(context, base::DoNothing());

  ASSERT_EQ(DataTypeController::MODEL_STARTING, controller.state());
  ASSERT_TRUE(start_callback);

  // Mimic completion for OnSyncStarting().
  std::move(start_callback).Run(std::make_unique<DataTypeActivationResponse>());
  ASSERT_EQ(DataTypeController::MODEL_LOADED, controller.state());

  // Stop sync.
  EXPECT_CALL(delegate_on_disk, OnSyncStopping(_)).Times(0);
  EXPECT_CALL(delegate_in_memory, OnSyncStopping(_));
  controller.Stop(DISABLE_SYNC, base::DoNothing());
  ASSERT_EQ(DataTypeController::NOT_RUNNING, controller.state());

  // Start sync with STORAGE_ON_DISK.
  EXPECT_CALL(delegate_in_memory, OnSyncStarting(_, _)).Times(0);
  EXPECT_CALL(delegate_on_disk, OnSyncStarting(_, _))
      .WillOnce([&](const DataTypeActivationRequest& request,
                    ModelTypeControllerDelegate::StartCallback callback) {
        start_callback = std::move(callback);
      });
  context.storage_option = STORAGE_ON_DISK;
  controller.LoadModels(context, base::DoNothing());

  ASSERT_EQ(DataTypeController::MODEL_STARTING, controller.state());
  ASSERT_TRUE(start_callback);

  // Mimic completion for OnSyncStarting().
  std::move(start_callback).Run(std::make_unique<DataTypeActivationResponse>());
  ASSERT_EQ(DataTypeController::MODEL_LOADED, controller.state());

  // Stop sync.
  EXPECT_CALL(delegate_in_memory, OnSyncStopping(_)).Times(0);
  EXPECT_CALL(delegate_on_disk, OnSyncStopping(_));
  controller.Stop(DISABLE_SYNC, base::DoNothing());
  ASSERT_EQ(DataTypeController::NOT_RUNNING, controller.state());
}

TEST_F(ModelTypeControllerTest, ReportErrorAfterLoaded) {
  base::HistogramTester histogram_tester;
  // Capture the callbacks.
  ModelErrorHandler error_handler;
  ModelTypeControllerDelegate::StartCallback start_callback;
  EXPECT_CALL(*delegate(), OnSyncStarting(_, _))
      .WillOnce([&](const DataTypeActivationRequest& request,
                    ModelTypeControllerDelegate::StartCallback callback) {
        error_handler = request.error_handler;
        start_callback = std::move(callback);
      });
  controller()->LoadModels(MakeConfigureContext(), base::DoNothing());
  ASSERT_EQ(DataTypeController::MODEL_STARTING, controller()->state());
  ASSERT_TRUE(error_handler);
  ASSERT_TRUE(start_callback);

  // Mimic completion for OnSyncStarting().
  std::move(start_callback).Run(std::make_unique<DataTypeActivationResponse>());
  ASSERT_EQ(DataTypeController::MODEL_LOADED, controller()->state());

  StartAssociating();
  ASSERT_EQ(DataTypeController::RUNNING, controller()->state());

  // Now trigger the run-time error.
  error_handler.Run(ModelError(FROM_HERE, "Test error"));
  // TODO(mastiz): We shouldn't need RunUntilIdle() here, but
  // ModelTypeController currently uses task-posting for errors.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(DataTypeController::FAILED, controller()->state());
  histogram_tester.ExpectTotalCount(kStartFailuresHistogram, 0);
  histogram_tester.ExpectBucketCount(kRunFailuresHistogram,
                                     ModelTypeToHistogramInt(kTestModelType),
                                     /*count=*/1);
}

}  // namespace syncer
