blob: 37941c93b8713bdf979930628ff21f7d7508ef58 [file] [log] [blame]
// Copyright (c) 2012 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 "chrome/browser/chromeos/gdata/drive_scheduler.h"
#include "base/bind.h"
#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/chromeos/gdata/drive_function_remove.h"
#include "chrome/browser/chromeos/gdata/drive_test_util.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::AnyNumber;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::_;
namespace gdata {
namespace {
class MockNetworkChangeNotifier : public net::NetworkChangeNotifier {
public:
MOCK_CONST_METHOD0(GetCurrentConnectionType,
net::NetworkChangeNotifier::ConnectionType());
};
class MockDriveFunctionRemove : public DriveFunctionRemove {
public:
MockDriveFunctionRemove() : DriveFunctionRemove(NULL, NULL, NULL) {}
MOCK_METHOD3(Remove, void(const FilePath& file_path,
bool is_recursive,
const FileOperationCallback& callback));
};
// Action used to set mock expectations for
// DriveFunctionRemove::Remove().
ACTION_P(MockRemove, status) {
base::MessageLoopProxy::current()->PostTask(FROM_HERE,
base::Bind(arg2, status));
}
} // namespace
class DriveSchedulerTest : public testing::Test {
public:
DriveSchedulerTest()
: ui_thread_(content::BrowserThread::UI, &message_loop_),
profile_(new TestingProfile) {
}
virtual void SetUp() OVERRIDE {
mock_network_change_notifier_.reset(new MockNetworkChangeNotifier);
scheduler_.reset(new DriveScheduler(profile_.get(),
&mock_remove_function_));
scheduler_->Initialize();
scheduler_->SetDisableThrottling(true);
}
virtual void TearDown() OVERRIDE {
// The scheduler should be deleted before NetworkLibrary, as it
// registers itself as observer of NetworkLibrary.
scheduler_.reset();
test_util::RunBlockingPoolTask();
mock_network_change_notifier_.reset();
}
// Sets up MockNetworkChangeNotifier as if it's connected to a network with
// the specified connection type.
void ChangeConnectionType(net::NetworkChangeNotifier::ConnectionType type) {
EXPECT_CALL(*mock_network_change_notifier_, GetCurrentConnectionType())
.WillRepeatedly(Return(type));
// Notify the sync client that the network is changed. This is done via
// NetworkChangeNotifier in production, but here, we simulate the behavior
// by directly calling OnConnectionTypeChanged().
scheduler_->OnConnectionTypeChanged(type);
}
// Sets up MockNetworkChangeNotifier as if it's connected to wifi network.
void ConnectToWifi() {
ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
}
// Sets up MockNetworkChangeNotifier as if it's connected to cellular network.
void ConnectToCellular() {
ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_2G);
}
// Sets up MockNetworkChangeNotifier as if it's connected to wimax network.
void ConnectToWimax() {
ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_4G);
}
// Sets up MockNetworkChangeNotifier as if it's disconnected.
void ConnectToNone() {
ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE);
}
protected:
MessageLoopForUI message_loop_;
content::TestBrowserThread ui_thread_;
scoped_ptr<TestingProfile> profile_;
scoped_ptr<DriveScheduler> scheduler_;
scoped_ptr<MockNetworkChangeNotifier> mock_network_change_notifier_;
StrictMock<MockDriveFunctionRemove> mock_remove_function_;
};
TEST_F(DriveSchedulerTest, RemoveFile) {
ConnectToWifi();
FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
EXPECT_CALL(mock_remove_function_, Remove(file_in_root, _, _))
.WillOnce(MockRemove(DRIVE_FILE_OK));
DriveFileError error;
scheduler_->Remove(
file_in_root, false,
base::Bind(&test_util::CopyErrorCodeFromFileOperationCallback, &error));
test_util::RunBlockingPoolTask();
ASSERT_EQ(DRIVE_FILE_OK, error);
}
TEST_F(DriveSchedulerTest, RemoveFileRetry) {
ConnectToWifi();
FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
EXPECT_CALL(mock_remove_function_, Remove(file_in_root, _, _))
.WillOnce(MockRemove(DRIVE_FILE_ERROR_FAILED))
.WillOnce(MockRemove(DRIVE_FILE_OK));
DriveFileError error;
scheduler_->Remove(
file_in_root, false,
base::Bind(&test_util::CopyErrorCodeFromFileOperationCallback, &error));
test_util::RunBlockingPoolTask();
ASSERT_EQ(DRIVE_FILE_OK, error);
}
TEST_F(DriveSchedulerTest, QueueOperation_Offline) {
ConnectToNone();
// This file will not be removed, as network is not connected.
EXPECT_CALL(mock_remove_function_, Remove(_, _, _)).Times(0);
FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
DriveFileError error;
scheduler_->Remove(
file_in_root, false,
base::Bind(&test_util::CopyErrorCodeFromFileOperationCallback, &error));
test_util::RunBlockingPoolTask();
}
TEST_F(DriveSchedulerTest, QueueOperation_CelluarDisabled) {
ConnectToCellular();
// This file will not be removed, as fetching over cellular network is
// disabled by default.
EXPECT_CALL(mock_remove_function_, Remove(_, _, _)).Times(0);
FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
DriveFileError error;
scheduler_->Remove(
file_in_root, false,
base::Bind(&test_util::CopyErrorCodeFromFileOperationCallback, &error));
test_util::RunBlockingPoolTask();
}
TEST_F(DriveSchedulerTest, QueueOperation_CelluarEnabled) {
// Enable fetching over cellular network.
profile_->GetPrefs()->SetBoolean(prefs::kDisableGDataOverCellular, false);
ConnectToCellular();
// This file will be removed, as syncing over cellular network is explicitly
// enabled.
EXPECT_CALL(mock_remove_function_, Remove(_, _, _)).Times(1);
FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
DriveFileError error;
scheduler_->Remove(
file_in_root, false,
base::Bind(&test_util::CopyErrorCodeFromFileOperationCallback, &error));
test_util::RunBlockingPoolTask();
}
TEST_F(DriveSchedulerTest, QueueOperation_WimaxDisabled) {
// Then connect to wimax. This will kick off StartSyncLoop().
ConnectToWimax();
// This file will not be removed, as syncing over wimax network is disabled
// by default.
EXPECT_CALL(mock_remove_function_, Remove(_, _, _)).Times(0);
FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
DriveFileError error;
scheduler_->Remove(
file_in_root, false,
base::Bind(&test_util::CopyErrorCodeFromFileOperationCallback, &error));
test_util::RunBlockingPoolTask();
}
TEST_F(DriveSchedulerTest, QueueOperation_CelluarEnabledWithWimax) {
// Enable fetching over cellular network.
profile_->GetPrefs()->SetBoolean(prefs::kDisableGDataOverCellular, false);
ConnectToWimax();
// This file will be removed, as syncing over cellular network is explicitly
// enabled.
EXPECT_CALL(mock_remove_function_, Remove(_, _, _)).Times(1);
FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
DriveFileError error;
scheduler_->Remove(
file_in_root, false,
base::Bind(&test_util::CopyErrorCodeFromFileOperationCallback, &error));
test_util::RunBlockingPoolTask();
}
TEST_F(DriveSchedulerTest, QueueOperation_DriveDisabled) {
// Disable the Drive feature.
profile_->GetPrefs()->SetBoolean(prefs::kDisableGData, true);
// This file will not be removed, as the Drive feature is disabled.
EXPECT_CALL(mock_remove_function_, Remove(_, _, _)).Times(0);
FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
DriveFileError error;
scheduler_->Remove(
file_in_root, false,
base::Bind(&test_util::CopyErrorCodeFromFileOperationCallback, &error));
test_util::RunBlockingPoolTask();
}
} // namespace gdata