// Copyright 2014 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/feedback/feedback_uploader.h" #include <set> #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "base/prefs/testing_pref_service.h" #include "base/run_loop.h" #include "base/stl_util.h" #include "components/feedback/feedback_uploader_chrome.h" #include "components/feedback/feedback_uploader_factory.h" #include "components/user_prefs/user_prefs.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace { const char kReportOne[] = "one"; const char kReportTwo[] = "two"; const char kReportThree[] = "three"; const char kReportFour[] = "four"; const char kReportFive[] = "five"; const base::TimeDelta kRetryDelayForTest = base::TimeDelta::FromMilliseconds(100); KeyedService* CreateFeedbackUploaderService(content::BrowserContext* context) { return new feedback::FeedbackUploaderChrome(context); } } // namespace namespace feedback { class FeedbackUploaderTest : public testing::Test { protected: FeedbackUploaderTest() : ui_thread_(content::BrowserThread::UI, &message_loop_), context_(new content::TestBrowserContext()), prefs_(new TestingPrefServiceSimple()), dispatched_reports_count_(0), expected_reports_(0) { user_prefs::UserPrefs::Set(context_.get(), prefs_.get()); FeedbackUploaderFactory::GetInstance()->SetTestingFactory( context_.get(), &CreateFeedbackUploaderService); uploader_ = FeedbackUploaderFactory::GetForBrowserContext(context_.get()); uploader_->setup_for_test( base::Bind(&FeedbackUploaderTest::MockDispatchReport, base::Unretained(this)), kRetryDelayForTest); } virtual ~FeedbackUploaderTest() { FeedbackUploaderFactory::GetInstance()->SetTestingFactory( context_.get(), NULL); } void QueueReport(const std::string& data) { uploader_->QueueReport(data); } void ReportFailure(const std::string& data) { uploader_->RetryReport(data); } void MockDispatchReport(const std::string& report_data) { if (ContainsKey(dispatched_reports_, report_data)) { dispatched_reports_[report_data]++; } else { dispatched_reports_[report_data] = 1; } dispatched_reports_count_++; // Dispatch will always update the timer, whether successful or not, // simulate the same behavior. uploader_->UpdateUploadTimer(); if (ProcessingComplete()) { if (run_loop_.get()) run_loop_->Quit(); } } bool ProcessingComplete() { return (dispatched_reports_count_ >= expected_reports_); } void RunMessageLoop() { if (ProcessingComplete()) return; run_loop_.reset(new base::RunLoop()); run_loop_->Run(); } base::MessageLoop message_loop_; scoped_ptr<base::RunLoop> run_loop_; content::TestBrowserThread ui_thread_; scoped_ptr<content::TestBrowserContext> context_; scoped_ptr<PrefService> prefs_; FeedbackUploader* uploader_; std::map<std::string, unsigned int> dispatched_reports_; size_t dispatched_reports_count_; size_t expected_reports_; }; #if defined(OS_LINUX) || defined(OS_MACOSX) #define MAYBE_QueueMultiple QueueMultiple #else // crbug.com/330547 #define MAYBE_QueueMultiple DISABLED_QueueMultiple #endif TEST_F(FeedbackUploaderTest, MAYBE_QueueMultiple) { dispatched_reports_.clear(); QueueReport(kReportOne); QueueReport(kReportTwo); QueueReport(kReportThree); QueueReport(kReportFour); EXPECT_EQ(dispatched_reports_.size(), 4u); EXPECT_EQ(dispatched_reports_[kReportOne], 1u); EXPECT_EQ(dispatched_reports_[kReportTwo], 1u); EXPECT_EQ(dispatched_reports_[kReportThree], 1u); EXPECT_EQ(dispatched_reports_[kReportFour], 1u); } #if defined(OS_WIN) || defined(OS_ANDROID) // crbug.com/330547 #define MAYBE_QueueMultipleWithFailures DISABLED_QueueMultipleWithFailures #else #define MAYBE_QueueMultipleWithFailures QueueMultipleWithFailures #endif TEST_F(FeedbackUploaderTest, MAYBE_QueueMultipleWithFailures) { dispatched_reports_.clear(); QueueReport(kReportOne); QueueReport(kReportTwo); QueueReport(kReportThree); QueueReport(kReportFour); ReportFailure(kReportThree); ReportFailure(kReportTwo); QueueReport(kReportFive); expected_reports_ = 7; RunMessageLoop(); EXPECT_EQ(dispatched_reports_.size(), 5u); EXPECT_EQ(dispatched_reports_[kReportOne], 1u); EXPECT_EQ(dispatched_reports_[kReportTwo], 2u); EXPECT_EQ(dispatched_reports_[kReportThree], 2u); EXPECT_EQ(dispatched_reports_[kReportFour], 1u); EXPECT_EQ(dispatched_reports_[kReportFive], 1u); } } // namespace feedback