blob: 8aab1c58004a7e344bf9ac7ae4c657e4b32b8bbf [file] [log] [blame]
// Copyright 2014 The Chromium OS 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 <utime.h>
#include <string>
#include <vector>
#include <base/at_exit.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/guid.h>
#include <base/strings/stringprintf.h>
#include <base/message_loop/message_loop.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "components/feedback/feedback_common.h"
#include "components/feedback/feedback_report.h"
#include "components/feedback/feedback_uploader.h"
#include "components/feedback/proto/extension.pb.h"
#include "feedback/feedback_service.h"
namespace feedback {
namespace {
static const int kMaxPoolThreads = 1;
static const char kPoolName[] = "FeedbackWorkerPool";
static const base::FilePath::CharType kFeedbackReportPath[] =
FILE_PATH_LITERAL("Feedback Reports");
static const int kTestProductId = 84;
} // namespace
class MockFeedbackUploader : public feedback::FeedbackUploader {
public:
MockFeedbackUploader(
const base::FilePath& path,
base::SequencedWorkerPool* pool) : FeedbackUploader(path, pool) {}
MOCK_METHOD1(DispatchReport, void(const std::string&));
};
class MockFeedbackUploaderQueue : public MockFeedbackUploader {
public:
MockFeedbackUploaderQueue(
const base::FilePath& path,
base::SequencedWorkerPool* pool) : MockFeedbackUploader(path, pool) {}
MOCK_METHOD1(QueueReport, void(const std::string&));
};
class FailedFeedbackUploader : public MockFeedbackUploader {
public:
FailedFeedbackUploader(
const base::FilePath& path,
base::SequencedWorkerPool* pool) : MockFeedbackUploader(path, pool) {}
void DispatchReport(const std::string& data) {
MockFeedbackUploader::DispatchReport(data);
RetryReport(data);
}
feedback::FeedbackReport* GetFirstReport() {
scoped_refptr<feedback::FeedbackReport> report = reports_queue_.top();
return report.get();
}
};
class FeedbackServiceTest : public testing::Test {
public:
FeedbackServiceTest() : message_loop_(base::MessageLoop::TYPE_IO) {}
static void CallbackFeedbackResult(bool expected_result, bool result,
const std::string& err) {
EXPECT_EQ(result, expected_result);
}
userfeedback::ExtensionSubmit GetBaseReport() {
userfeedback::ExtensionSubmit report;
report.mutable_common_data();
report.mutable_web_data();
report.set_type_id(0);
report.set_product_id(kTestProductId);
return report;
}
void WaitOnPool() {
pool_->FlushForTesting();
}
protected:
virtual void SetUp() {
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
CreateDirectory(temp_dir_.path().Append(kFeedbackReportPath));
pool_ = new base::SequencedWorkerPool(kMaxPoolThreads, kPoolName);
}
virtual void TearDown() {
WaitOnPool();
pool_->Shutdown();
}
base::ScopedTempDir temp_dir_;
base::MessageLoop message_loop_;
scoped_refptr<base::SequencedWorkerPool> pool_;
};
TEST_F(FeedbackServiceTest, SendFeedback) {
MockFeedbackUploaderQueue uploader(temp_dir_.path(), pool_.get());
std::string data;
userfeedback::ExtensionSubmit report = GetBaseReport();
report.SerializeToString(&data);
EXPECT_CALL(uploader, QueueReport(data)).Times(1);
scoped_refptr<FeedbackService> svc = new FeedbackService(&uploader);
svc->SendFeedback(report,
base::Bind(&FeedbackServiceTest::CallbackFeedbackResult, true));
}
TEST_F(FeedbackServiceTest, DispatchTest) {
MockFeedbackUploader uploader(temp_dir_.path(), pool_.get());
std::string data;
userfeedback::ExtensionSubmit report = GetBaseReport();
report.SerializeToString(&data);
EXPECT_CALL(uploader, DispatchReport(data)).Times(1);
scoped_refptr<FeedbackService> svc = new FeedbackService(&uploader);
svc->SendFeedback(report,
base::Bind(&FeedbackServiceTest::CallbackFeedbackResult, true));
}
TEST_F(FeedbackServiceTest, UploadFailure) {
FailedFeedbackUploader uploader(temp_dir_.path(), pool_.get());
std::string data;
userfeedback::ExtensionSubmit report = GetBaseReport();
report.SerializeToString(&data);
EXPECT_CALL(uploader, DispatchReport(data)).Times(1);
scoped_refptr<FeedbackService> svc = new FeedbackService(&uploader);
svc->SendFeedback(report,
base::Bind(&FeedbackServiceTest::CallbackFeedbackResult, true));
WaitOnPool();
// Verify that this got put back on the queue.
EXPECT_TRUE(uploader.GetFirstReport() != nullptr);
EXPECT_EQ(uploader.GetFirstReport()->data(), data);
}
} // namespace feedback
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
// Some libchrome calls need this.
base::AtExitManager at_exit_manager;
return RUN_ALL_TESTS();
}