Home | History | Annotate | Download | only in feedback
      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