1// Copyright (c) 2012 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 <vector>
6
7#include "base/strings/stringprintf.h"
8#include "breakpad/src/client/windows/common/ipc_protocol.h"
9#include "chrome/app/breakpad_field_trial_win.h"
10#include "chrome/app/breakpad_win.h"
11#include "chrome/common/child_process_logging.h"
12#include "chrome/common/metrics/variations/variations_util.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15using breakpad_win::g_custom_entries;
16using breakpad_win::g_experiment_chunks_offset;
17using breakpad_win::g_num_of_experiments_offset;
18
19class ChromeAppBreakpadTest : public testing::Test {
20 public:
21  ChromeAppBreakpadTest() {
22    testing::InitCustomInfoEntries();
23  }
24
25 protected:
26  typedef std::vector<string16> Experiments;
27  void ValidateExperimentChunks(const Experiments& experiments) {
28    std::vector<string16> chunks;
29    chrome_variations::GenerateVariationChunks(experiments, &chunks);
30    testing::SetExperimentChunks(chunks, experiments.size());
31    EXPECT_STREQ(base::StringPrintf(L"%d", experiments.size()).c_str(),
32                 (*g_custom_entries)[g_num_of_experiments_offset].value);
33    // We make a copy of the array that we empty as we find the experiments.
34    Experiments experiments_left(experiments);
35    for (int i = 0; i < kMaxReportedVariationChunks; ++i) {
36      const google_breakpad::CustomInfoEntry& entry =
37          (*g_custom_entries)[g_experiment_chunks_offset + i];
38      EXPECT_STREQ(base::StringPrintf(L"experiment-chunk-%i", i + 1).c_str(),
39                   entry.name);
40      // An empty value should only appear when |experiments_left| is empty.
41      if (wcslen(entry.value) == 0)
42        EXPECT_TRUE(experiments_left.empty());
43      if (experiments_left.empty()) {
44        // All other slots should be empty.
45        EXPECT_STREQ(L"", entry.value);
46      } else {
47        // We can't guarantee the order, so we must search for them all.
48        Experiments::const_iterator experiment = experiments_left.begin();
49        while (experiment != experiments_left.end()) {
50          if (wcsstr(entry.value, experiment->c_str())) {
51            experiment = experiments_left.erase(experiment);
52          } else {
53            ++experiment;
54          }
55        }
56      }
57    }
58    EXPECT_TRUE(experiments_left.empty());
59  }
60
61 private:
62  static const wchar_t* kNumExperiments;
63  static const size_t kNumExperimentsSize;
64};
65
66const wchar_t* ChromeAppBreakpadTest::kNumExperiments = L"num-experiments";
67const size_t ChromeAppBreakpadTest::kNumExperimentsSize =
68    wcslen(ChromeAppBreakpadTest::kNumExperiments);
69
70TEST_F(ChromeAppBreakpadTest, ExperimentList) {
71  Experiments experiments;
72  experiments.push_back(L"ABCDE-12345");
73  ValidateExperimentChunks(experiments);
74
75  experiments.push_back(L"There-You Are");
76  ValidateExperimentChunks(experiments);
77
78  experiments.push_back(L"Peter-Sellers");
79  ValidateExperimentChunks(experiments);
80
81  experiments.push_back(L"Eat me-Drink me");
82  ValidateExperimentChunks(experiments);
83}
84