1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "components/feedback/feedback_uploader.h" 6 7 #include <set> 8 9 #include "base/bind.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/prefs/testing_pref_service.h" 12 #include "base/run_loop.h" 13 #include "base/stl_util.h" 14 #include "components/feedback/feedback_uploader_chrome.h" 15 #include "components/feedback/feedback_uploader_factory.h" 16 #include "components/user_prefs/user_prefs.h" 17 #include "content/public/test/test_browser_context.h" 18 #include "content/public/test/test_browser_thread.h" 19 #include "testing/gmock/include/gmock/gmock.h" 20 #include "testing/gtest/include/gtest/gtest.h" 21 22 namespace { 23 24 const char kReportOne[] = "one"; 25 const char kReportTwo[] = "two"; 26 const char kReportThree[] = "three"; 27 const char kReportFour[] = "four"; 28 const char kReportFive[] = "five"; 29 30 const base::TimeDelta kRetryDelayForTest = 31 base::TimeDelta::FromMilliseconds(100); 32 33 KeyedService* CreateFeedbackUploaderService(content::BrowserContext* context) { 34 return new feedback::FeedbackUploaderChrome(context); 35 } 36 37 } // namespace 38 39 namespace feedback { 40 41 class FeedbackUploaderTest : public testing::Test { 42 protected: 43 FeedbackUploaderTest() 44 : ui_thread_(content::BrowserThread::UI, &message_loop_), 45 context_(new content::TestBrowserContext()), 46 prefs_(new TestingPrefServiceSimple()), 47 dispatched_reports_count_(0), 48 expected_reports_(0) { 49 user_prefs::UserPrefs::Set(context_.get(), prefs_.get()); 50 FeedbackUploaderFactory::GetInstance()->SetTestingFactory( 51 context_.get(), &CreateFeedbackUploaderService); 52 53 uploader_ = FeedbackUploaderFactory::GetForBrowserContext(context_.get()); 54 uploader_->setup_for_test( 55 base::Bind(&FeedbackUploaderTest::MockDispatchReport, 56 base::Unretained(this)), 57 kRetryDelayForTest); 58 } 59 60 virtual ~FeedbackUploaderTest() { 61 FeedbackUploaderFactory::GetInstance()->SetTestingFactory( 62 context_.get(), NULL); 63 } 64 65 void QueueReport(const std::string& data) { 66 uploader_->QueueReport(data); 67 } 68 69 void ReportFailure(const std::string& data) { 70 uploader_->RetryReport(data); 71 } 72 73 void MockDispatchReport(const std::string& report_data) { 74 if (ContainsKey(dispatched_reports_, report_data)) { 75 dispatched_reports_[report_data]++; 76 } else { 77 dispatched_reports_[report_data] = 1; 78 } 79 dispatched_reports_count_++; 80 81 // Dispatch will always update the timer, whether successful or not, 82 // simulate the same behavior. 83 uploader_->UpdateUploadTimer(); 84 85 if (ProcessingComplete()) { 86 if (run_loop_.get()) 87 run_loop_->Quit(); 88 } 89 } 90 91 bool ProcessingComplete() { 92 return (dispatched_reports_count_ >= expected_reports_); 93 } 94 95 void RunMessageLoop() { 96 if (ProcessingComplete()) 97 return; 98 run_loop_.reset(new base::RunLoop()); 99 run_loop_->Run(); 100 } 101 102 base::MessageLoop message_loop_; 103 scoped_ptr<base::RunLoop> run_loop_; 104 content::TestBrowserThread ui_thread_; 105 scoped_ptr<content::TestBrowserContext> context_; 106 scoped_ptr<PrefService> prefs_; 107 108 FeedbackUploader* uploader_; 109 110 std::map<std::string, unsigned int> dispatched_reports_; 111 size_t dispatched_reports_count_; 112 size_t expected_reports_; 113 }; 114 115 #if defined(OS_LINUX) || defined(OS_MACOSX) 116 #define MAYBE_QueueMultiple QueueMultiple 117 #else 118 // crbug.com/330547 119 #define MAYBE_QueueMultiple DISABLED_QueueMultiple 120 #endif 121 TEST_F(FeedbackUploaderTest, MAYBE_QueueMultiple) { 122 dispatched_reports_.clear(); 123 QueueReport(kReportOne); 124 QueueReport(kReportTwo); 125 QueueReport(kReportThree); 126 QueueReport(kReportFour); 127 128 EXPECT_EQ(dispatched_reports_.size(), 4u); 129 EXPECT_EQ(dispatched_reports_[kReportOne], 1u); 130 EXPECT_EQ(dispatched_reports_[kReportTwo], 1u); 131 EXPECT_EQ(dispatched_reports_[kReportThree], 1u); 132 EXPECT_EQ(dispatched_reports_[kReportFour], 1u); 133 } 134 135 #if defined(OS_WIN) || defined(OS_ANDROID) 136 // crbug.com/330547 137 #define MAYBE_QueueMultipleWithFailures DISABLED_QueueMultipleWithFailures 138 #else 139 #define MAYBE_QueueMultipleWithFailures QueueMultipleWithFailures 140 #endif 141 TEST_F(FeedbackUploaderTest, MAYBE_QueueMultipleWithFailures) { 142 dispatched_reports_.clear(); 143 144 QueueReport(kReportOne); 145 QueueReport(kReportTwo); 146 QueueReport(kReportThree); 147 QueueReport(kReportFour); 148 149 ReportFailure(kReportThree); 150 ReportFailure(kReportTwo); 151 QueueReport(kReportFive); 152 153 expected_reports_ = 7; 154 RunMessageLoop(); 155 156 EXPECT_EQ(dispatched_reports_.size(), 5u); 157 EXPECT_EQ(dispatched_reports_[kReportOne], 1u); 158 EXPECT_EQ(dispatched_reports_[kReportTwo], 2u); 159 EXPECT_EQ(dispatched_reports_[kReportThree], 2u); 160 EXPECT_EQ(dispatched_reports_[kReportFour], 1u); 161 EXPECT_EQ(dispatched_reports_[kReportFive], 1u); 162 } 163 164 } // namespace feedback 165