15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include <stdint.h>
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/files/file_path.h"
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/memory/scoped_vector.h"
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/path_service.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/testing_pref_service.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/strings/stringprintf.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/about_flags.h"
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/pref_service_flags_storage.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/chromium_strings.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "third_party/libxml/chromium/libxml_utils.h"
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFlags1[] = "flag1";
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFlags2[] = "flag2";
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFlags3[] = "flag3";
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFlags4[] = "flag4";
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kFlags5[] = "flag5";
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSwitch1[] = "switch";
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSwitch2[] = "switch2";
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSwitch3[] = "switch3";
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kValueForSwitch2[] = "value_for_switch2";
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMultiSwitch1[] = "multi_switch1";
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMultiSwitch2[] = "multi_switch2";
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kValueForMultiSwitch2[] = "value_for_multi_switch2";
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kEnableDisableValue1[] = "value1";
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kEnableDisableValue2[] = "value2";
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitypedef base::HistogramBase::Sample Sample;
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitypedef std::map<std::string, Sample> SwitchToIdMap;
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// This is a helper function to the ReadEnumFromHistogramsXml().
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Extracts single enum (with integer values) from histograms.xml.
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Expects |reader| to point at given enum.
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Returns map { value => label }.
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Returns empty map on error.
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::map<Sample, std::string> ParseEnumFromHistogramsXml(
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::string& enum_name,
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    XmlReader* reader) {
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  int entries_index = -1;
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::map<Sample, std::string> result;
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool success = true;
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  while (true) {
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::string node_name = reader->NodeName();
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (node_name == "enum" && reader->IsClosingElement())
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      break;
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (node_name == "int") {
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ++entries_index;
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      std::string value_str;
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      std::string label;
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const bool has_value = reader->NodeAttribute("value", &value_str);
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const bool has_label = reader->NodeAttribute("label", &label);
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (!has_value) {
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        ADD_FAILURE() << "Bad " << enum_name << " enum entry (at index "
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << entries_index << ", label='" << label
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << "'): No 'value' attribute.";
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        success = false;
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      }
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (!has_label) {
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        ADD_FAILURE() << "Bad " << enum_name << " enum entry (at index "
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << entries_index << ", value_str='" << value_str
806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << "'): No 'label' attribute.";
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        success = false;
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      }
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Sample value;
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (has_value && !base::StringToInt(value_str, &value)) {
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        ADD_FAILURE() << "Bad " << enum_name << " enum entry (at index "
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << entries_index << ", label='" << label
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << "', value_str='" << value_str
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << "'): 'value' attribute is not integer.";
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        success = false;
916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      }
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (result.count(value)) {
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        ADD_FAILURE() << "Bad " << enum_name << " enum entry (at index "
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << entries_index << ", label='" << label
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << "', value_str='" << value_str
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << "'): duplicate value '" << value_str
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << "' found in enum. The previous one has label='"
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      << result[value] << "'.";
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        success = false;
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      }
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (success) {
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        result[value] = label;
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      }
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // All enum entries are on the same level, so it is enough to iterate
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // until possible.
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    reader->Next();
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return (success ? result : std::map<Sample, std::string>());
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Find and read given enum (with integer values) from histograms.xml.
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// |enum_name| - enum name.
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// |histograms_xml| - must be loaded histograms.xml file.
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Returns map { value => label } so that:
1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//   <int value="9" label="enable-pinch-virtual-viewport"/>
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// becomes:
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//   { 9 => "enable-pinch-virtual-viewport" }
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Returns empty map on error.
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::map<Sample, std::string> ReadEnumFromHistogramsXml(
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::string& enum_name,
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    XmlReader* histograms_xml) {
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::map<Sample, std::string> login_custom_flags;
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Implement simple depth first search.
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  while (true) {
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::string node_name = histograms_xml->NodeName();
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (node_name == "enum") {
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      std::string name;
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (histograms_xml->NodeAttribute("name", &name) && name == enum_name) {
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        if (!login_custom_flags.empty()) {
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          EXPECT_TRUE(login_custom_flags.empty())
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              << "Duplicate enum '" << enum_name << "' found in histograms.xml";
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          return std::map<Sample, std::string>();
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        }
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        const bool got_into_enum = histograms_xml->Read();
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        if (got_into_enum) {
1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          login_custom_flags =
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              ParseEnumFromHistogramsXml(enum_name, histograms_xml);
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          EXPECT_FALSE(login_custom_flags.empty())
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              << "Bad enum '" << enum_name
1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              << "' found in histograms.xml (format error).";
1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        } else {
1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          EXPECT_TRUE(got_into_enum)
1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              << "Bad enum '" << enum_name
1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              << "' (looks empty) found in histograms.xml.";
1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        }
1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        if (login_custom_flags.empty())
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          return std::map<Sample, std::string>();
1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      }
1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Go deeper if possible (stops at the closing tag of the deepest node).
1556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (histograms_xml->Read())
1566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      continue;
1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Try next node on the same level (skips closing tag).
1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (histograms_xml->Next())
1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      continue;
1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Go up until next node on the same level exists.
1636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    while (histograms_xml->Depth() && !histograms_xml->SkipToElement()) {
1646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Reached top. histograms.xml consists of the single top level node
1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // 'histogram-configuration', so this is the end.
1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!histograms_xml->Depth())
1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      break;
1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_FALSE(login_custom_flags.empty())
1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      << "Enum '" << enum_name << "' is not found in histograms.xml.";
1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return login_custom_flags;
1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)std::string FilePathStringTypeToString(const base::FilePath::StringType& path) {
1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(OS_WIN)
1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return base::UTF16ToUTF8(path);
1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#else
1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return path;
1816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif
1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)std::set<std::string> GetAllSwitchesForTesting() {
1856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::set<std::string> result;
1866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  size_t num_experiments = 0;
1886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const about_flags::Experiment* experiments =
1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      about_flags::testing::GetExperiments(&num_experiments);
1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (size_t i = 0; i < num_experiments; ++i) {
1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const about_flags::Experiment& experiment = experiments[i];
1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (experiment.type == about_flags::Experiment::SINGLE_VALUE) {
1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      result.insert(experiment.command_line_switch);
1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } else if (experiment.type == about_flags::Experiment::MULTI_VALUE) {
1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      for (int j = 0; j < experiment.num_choices; ++j) {
1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        result.insert(experiment.choices[j].command_line_switch);
1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      }
1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } else {
2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      DCHECK_EQ(experiment.type, about_flags::Experiment::ENABLE_DISABLE_VALUE);
2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      result.insert(experiment.command_line_switch);
2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      result.insert(experiment.disable_command_line_switch);
2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return result;
2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // anonymous namespace
2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace about_flags {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Experiment::Choice kMultiChoices[] = {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { IDS_PRODUCT_NAME, "", "" },
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { IDS_PRODUCT_NAME, kMultiSwitch1, "" },
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { IDS_PRODUCT_NAME, kMultiSwitch2, kValueForMultiSwitch2 },
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The experiments that are set for these tests. The 3rd experiment is not
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// supported on the current platform, all others are.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Experiment kExperiments[] = {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kFlags1,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDS_PRODUCT_NAME,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDS_PRODUCT_NAME,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,  // Ends up being mapped to the current platform.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Experiment::SINGLE_VALUE,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSwitch1,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "",
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NULL,
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NULL,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  },
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kFlags2,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDS_PRODUCT_NAME,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDS_PRODUCT_NAME,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,  // Ends up being mapped to the current platform.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Experiment::SINGLE_VALUE,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSwitch2,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kValueForSwitch2,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NULL,
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NULL,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  },
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kFlags3,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDS_PRODUCT_NAME,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDS_PRODUCT_NAME,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,  // This ends up enabling for an OS other than the current.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Experiment::SINGLE_VALUE,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSwitch3,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "",
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NULL,
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NULL,
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  },
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kFlags4,
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDS_PRODUCT_NAME,
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDS_PRODUCT_NAME,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,  // Ends up being mapped to the current platform.
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Experiment::MULTI_VALUE,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "",
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "",
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "",
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "",
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kMultiChoices,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    arraysize(kMultiChoices)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  },
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kFlags5,
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IDS_PRODUCT_NAME,
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IDS_PRODUCT_NAME,
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0,  // Ends up being mapped to the current platform.
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Experiment::ENABLE_DISABLE_VALUE,
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kSwitch1,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kEnableDisableValue1,
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kSwitch2,
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kEnableDisableValue2,
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NULL,
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    3
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  },
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AboutFlagsTest : public ::testing::Test {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AboutFlagsTest() : flags_storage_(&prefs_) {
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    prefs_.registry()->RegisterListPref(prefs::kEnabledLabsExperiments);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testing::ClearState();
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kExperiments); ++i)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kExperiments[i].supported_platforms = GetCurrentPlatform();
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int os_other_than_current = 1;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (os_other_than_current == GetCurrentPlatform())
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      os_other_than_current <<= 1;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kExperiments[2].supported_platforms = os_other_than_current;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testing::SetExperiments(kExperiments, arraysize(kExperiments));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testing::SetExperiments(NULL, 0);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestingPrefServiceSimple prefs_;
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PrefServiceFlagsStorage flags_storage_;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AboutFlagsTest, NoChangeNoRestart) {
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(IsRestartNeededToCommitChanges());
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags1, false);
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(IsRestartNeededToCommitChanges());
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AboutFlagsTest, ChangeNeedsRestart) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsRestartNeededToCommitChanges());
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags1, true);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(IsRestartNeededToCommitChanges());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AboutFlagsTest, MultiFlagChangeNeedsRestart) {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Experiment& experiment = kExperiments[3];
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(kFlags4, experiment.internal_name);
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(IsRestartNeededToCommitChanges());
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Enable the 2nd choice of the multi-value.
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, experiment.NameForChoice(2), true);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IsRestartNeededToCommitChanges());
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  testing::ClearState();
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(IsRestartNeededToCommitChanges());
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Enable the default choice now.
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, experiment.NameForChoice(0), true);
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IsRestartNeededToCommitChanges());
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AboutFlagsTest, AddTwoFlagsRemoveOne) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add two experiments, check they're there.
3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags1, true);
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags2, true);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::ListValue* experiments_list = prefs_.GetList(
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kEnabledLabsExperiments);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(experiments_list != NULL);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, experiments_list->GetSize());
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string s0;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(experiments_list->GetString(0, &s0));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string s1;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(experiments_list->GetString(1, &s1));
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(s0 == kFlags1 || s1 == kFlags1);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(s0 == kFlags2 || s1 == kFlags2);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove one experiment, check the other's still around.
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags2, false);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  experiments_list = prefs_.GetList(prefs::kEnabledLabsExperiments);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(experiments_list != NULL);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, experiments_list->GetSize());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(experiments_list->GetString(0, &s0));
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(s0 == kFlags1);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AboutFlagsTest, AddTwoFlagsRemoveBoth) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add two experiments, check the pref exists.
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags1, true);
3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags2, true);
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::ListValue* experiments_list = prefs_.GetList(
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kEnabledLabsExperiments);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(experiments_list != NULL);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove both, the pref should have been removed completely.
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags1, false);
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags2, false);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  experiments_list = prefs_.GetList(prefs::kEnabledLabsExperiments);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(experiments_list == NULL || experiments_list->GetSize() == 0);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AboutFlagsTest, ConvertFlagsToSwitches) {
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags1, true);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine command_line(CommandLine::NO_PROGRAM);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_line.AppendSwitch("foo");
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(command_line.HasSwitch("foo"));
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(command_line.HasSwitch("foo"));
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
399d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(command_line.HasSwitch(switches::kFlagSwitchesBegin));
400d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(command_line.HasSwitch(switches::kFlagSwitchesEnd));
401d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
402d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  CommandLine command_line2(CommandLine::NO_PROGRAM);
403d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
404d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ConvertFlagsToSwitches(&flags_storage_, &command_line2, kNoSentinels);
405d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
406d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(command_line2.HasSwitch(kSwitch1));
407d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesBegin));
408d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesEnd));
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)CommandLine::StringType CreateSwitch(const std::string& value) {
4126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(OS_WIN)
4136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return base::ASCIIToUTF16(value);
4146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#else
4156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return value;
4166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif
4176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
4186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(AboutFlagsTest, CompareSwitchesToCurrentCommandLine) {
4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags1, true);
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const std::string kDoubleDash("--");
4236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CommandLine command_line(CommandLine::NO_PROGRAM);
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  command_line.AppendSwitch("foo");
4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CommandLine new_command_line(CommandLine::NO_PROGRAM);
428d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ConvertFlagsToSwitches(&flags_storage_, &new_command_line, kAddSentinels);
4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(
4316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new_command_line, command_line, NULL));
4326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  {
4336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    std::set<CommandLine::StringType> difference;
4346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(
4356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        new_command_line, command_line, &difference));
4366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(1U, difference.size());
4376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(1U, difference.count(CreateSwitch(kDoubleDash + kSwitch1)));
4386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
440d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine(
4436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new_command_line, command_line, NULL));
4446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  {
4456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    std::set<CommandLine::StringType> difference;
4466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine(
4476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        new_command_line, command_line, &difference));
4486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_TRUE(difference.empty());
4496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Now both have flags but different.
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags1, false);
4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags2, true);
4547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CommandLine another_command_line(CommandLine::NO_PROGRAM);
456d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ConvertFlagsToSwitches(&flags_storage_, &another_command_line, kAddSentinels);
4577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(
4596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new_command_line, another_command_line, NULL));
4606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  {
4616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    std::set<CommandLine::StringType> difference;
4626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(
4636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        new_command_line, another_command_line, &difference));
4646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(2U, difference.size());
4656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(1U, difference.count(CreateSwitch(kDoubleDash + kSwitch1)));
4666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(1U,
4676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              difference.count(CreateSwitch(kDoubleDash + kSwitch2 + "=" +
4686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                            kValueForSwitch2)));
4696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
4707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AboutFlagsTest, RemoveFlagSwitches) {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<std::string, CommandLine::StringType> switch_list;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch_list[kSwitch1] = CommandLine::StringType();
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch_list[switches::kFlagSwitchesBegin] = CommandLine::StringType();
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch_list[switches::kFlagSwitchesEnd] = CommandLine::StringType();
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch_list["foo"] = CommandLine::StringType();
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags1, true);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This shouldn't do anything before ConvertFlagsToSwitches() wasn't called.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveFlagsSwitches(&switch_list);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4u, switch_list.size());
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(switch_list.find(kSwitch1) != switch_list.end());
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(switch_list.find(switches::kFlagSwitchesBegin) !=
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              switch_list.end());
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(switch_list.find(switches::kFlagSwitchesEnd) !=
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              switch_list.end());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(switch_list.find("foo") != switch_list.end());
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call ConvertFlagsToSwitches(), then RemoveFlagsSwitches() again.
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine command_line(CommandLine::NO_PROGRAM);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_line.AppendSwitch("foo");
494d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveFlagsSwitches(&switch_list);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the about:flags-related switch should have been removed.
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, switch_list.size());
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(switch_list.find("foo") != switch_list.end());
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests enabling experiments that aren't supported on the current platform.
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AboutFlagsTest, PersistAndPrune) {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable experiments 1 and 3.
5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags1, true);
5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags3, true);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine command_line(CommandLine::NO_PROGRAM);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(command_line.HasSwitch(kSwitch3));
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert the flags to switches. Experiment 3 shouldn't be among the switches
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as it is not applicable to the current platform.
513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(command_line.HasSwitch(kSwitch3));
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Experiment 3 should show still be persisted in preferences though.
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::ListValue* experiments_list =
51990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs_.GetList(prefs::kEnabledLabsExperiments);
52090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(experiments_list);
52190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2U, experiments_list->GetSize());
52290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string s0;
52390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(experiments_list->GetString(0, &s0));
52490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(kFlags1, s0);
52590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string s1;
52690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(experiments_list->GetString(1, &s1));
52790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(kFlags3, s1);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that switches which should have values get them in the command
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// line.
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AboutFlagsTest, CheckValues) {
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable experiments 1 and 2.
5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags1, true);
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, kFlags2, true);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine command_line(CommandLine::NO_PROGRAM);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert the flags to switches.
541d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(), command_line.GetSwitchValueASCII(kSwitch1));
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(command_line.HasSwitch(kSwitch2));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kValueForSwitch2),
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            command_line.GetSwitchValueASCII(kSwitch2));
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Confirm that there is no '=' in the command line for simple switches.
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string switch1_with_equals = std::string("--") +
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    std::string(kSwitch1) +
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    std::string("=");
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::wstring::npos,
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            command_line.GetCommandLineString().find(
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                base::ASCIIToWide(switch1_with_equals)));
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string::npos,
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            command_line.GetCommandLineString().find(switch1_with_equals));
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And confirm there is a '=' for switches with values.
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string switch2_with_equals = std::string("--") +
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    std::string(kSwitch2) +
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    std::string("=");
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(std::wstring::npos,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            command_line.GetCommandLineString().find(
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                base::ASCIIToWide(switch2_with_equals)));
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(std::string::npos,
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            command_line.GetCommandLineString().find(switch2_with_equals));
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // And it should persist.
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::ListValue* experiments_list =
57690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs_.GetList(prefs::kEnabledLabsExperiments);
57790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(experiments_list);
57890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2U, experiments_list->GetSize());
57990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string s0;
58090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(experiments_list->GetString(0, &s0));
58190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(kFlags1, s0);
58290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string s1;
58390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(experiments_list->GetString(1, &s1));
58490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(kFlags2, s1);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests multi-value type experiments.
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AboutFlagsTest, MultiValues) {
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Experiment& experiment = kExperiments[3];
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(kFlags4, experiment.internal_name);
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initially, the first "deactivated" option of the multi experiment should
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be set.
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLine command_line(CommandLine::NO_PROGRAM);
596d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable the 2nd choice of the multi-value.
6027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, experiment.NameForChoice(2), true);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLine command_line(CommandLine::NO_PROGRAM);
605d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(command_line.HasSwitch(kMultiSwitch2));
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(std::string(kValueForMultiSwitch2),
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              command_line.GetSwitchValueASCII(kMultiSwitch2));
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable the multi-value experiment.
6137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, experiment.NameForChoice(0), true);
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommandLine command_line(CommandLine::NO_PROGRAM);
616d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AboutFlagsTest, EnableDisableValues) {
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Experiment& experiment = kExperiments[4];
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(kFlags5, experiment.internal_name);
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Nothing selected.
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommandLine command_line(CommandLine::NO_PROGRAM);
629d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // "Enable" option selected.
6357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, experiment.NameForChoice(1), true);
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommandLine command_line(CommandLine::NO_PROGRAM);
638d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kEnableDisableValue1, command_line.GetSwitchValueASCII(kSwitch1));
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // "Disable" option selected.
6457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, experiment.NameForChoice(2), true);
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommandLine command_line(CommandLine::NO_PROGRAM);
648d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(command_line.HasSwitch(kSwitch2));
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kEnableDisableValue2, command_line.GetSwitchValueASCII(kSwitch2));
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // "Default" option selected, same as nothing selected.
6557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetExperimentEnabled(&flags_storage_, experiment.NameForChoice(0), true);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLine command_line(CommandLine::NO_PROGRAM);
658d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Makes sure there are no separators in any of the experiment names.
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AboutFlagsTest, NoSeparators) {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  testing::SetExperiments(NULL, 0);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t count;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Experiment* experiments = testing::GetExperiments(&count);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < count; ++i) {
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name = experiments->internal_name;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(std::string::npos, name.find(testing::kMultiSeparator)) << i;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class AboutFlagsHistogramTest : public ::testing::Test {
6766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) protected:
6776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // This is a helper function to check that all IDs in enum LoginCustomFlags in
6786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // histograms.xml are unique.
6796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void SetSwitchToHistogramIdMapping(const std::string& switch_name,
6801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     const Sample switch_histogram_id,
6811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     std::map<std::string, Sample>* out_map) {
6821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::pair<std::map<std::string, Sample>::iterator, bool> status =
6836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        out_map->insert(std::make_pair(switch_name, switch_histogram_id));
6846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!status.second) {
6856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      EXPECT_TRUE(status.first->second == switch_histogram_id)
6866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          << "Duplicate switch '" << switch_name
6876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          << "' found in enum 'LoginCustomFlags' in histograms.xml.";
6886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
6896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
6906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // This method generates a hint for the user for what string should be added
6926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // to the enum LoginCustomFlags to make in consistent.
6936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string GetHistogramEnumEntryText(const std::string& switch_name,
6941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                        Sample value) {
6956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return base::StringPrintf(
6961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "<int value=\"%d\" label=\"%s\"/>", value, switch_name.c_str());
6976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
6986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)};
6996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
7006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(AboutFlagsHistogramTest, CheckHistograms) {
7016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::FilePath histograms_xml_file_path;
7026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_TRUE(
7036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      PathService::Get(base::DIR_SOURCE_ROOT, &histograms_xml_file_path));
7046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  histograms_xml_file_path = histograms_xml_file_path.AppendASCII("tools")
7056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      .AppendASCII("metrics")
7066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      .AppendASCII("histograms")
7076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      .AppendASCII("histograms.xml");
7086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
7096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  XmlReader histograms_xml;
7106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_TRUE(histograms_xml.LoadFile(
7116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      FilePathStringTypeToString(histograms_xml_file_path.value())));
7121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::map<Sample, std::string> login_custom_flags =
7136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ReadEnumFromHistogramsXml("LoginCustomFlags", &histograms_xml);
7146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_TRUE(login_custom_flags.size())
7156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      << "Error reading enum 'LoginCustomFlags' from histograms.xml.";
7166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
7176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Build reverse map {switch_name => id} from login_custom_flags.
7186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SwitchToIdMap histograms_xml_switches_ids;
7196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
7206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_TRUE(login_custom_flags.count(kBadSwitchFormatHistogramId))
7216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      << "Entry for UMA ID of incorrect command-line flag is not found in "
7226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         "histograms.xml enum LoginCustomFlags. "
7236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         "Consider adding entry:\n"
7246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      << "  " << GetHistogramEnumEntryText("BAD_FLAG_FORMAT", 0);
7256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Check that all LoginCustomFlags entries have correct values.
7261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (std::map<Sample, std::string>::const_iterator it =
7276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           login_custom_flags.begin();
7286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       it != login_custom_flags.end();
7296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       ++it) {
7306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (it->first == kBadSwitchFormatHistogramId) {
7316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // Add eror value with empty name.
7326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      SetSwitchToHistogramIdMapping(
7336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          "", it->first, &histograms_xml_switches_ids);
7346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      continue;
7356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
7361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const Sample uma_id = GetSwitchUMAId(it->second);
7376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(uma_id, it->first)
7386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        << "histograms.xml enum LoginCustomFlags "
7396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           "entry '" << it->second << "' has incorrect value=" << it->first
7406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        << ", but " << uma_id << " is expected. Consider changing entry to:\n"
7416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        << "  " << GetHistogramEnumEntryText(it->second, uma_id);
7426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SetSwitchToHistogramIdMapping(
7436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        it->second, it->first, &histograms_xml_switches_ids);
7446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
7456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
7466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Check that all flags in about_flags.cc have entries in login_custom_flags.
7476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::set<std::string> all_switches = GetAllSwitchesForTesting();
7486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (std::set<std::string>::const_iterator it = all_switches.begin();
7496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       it != all_switches.end();
7506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       ++it) {
7516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Skip empty placeholders.
7526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (it->empty())
7536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      continue;
7541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const Sample uma_id = GetSwitchUMAId(*it);
7556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_NE(kBadSwitchFormatHistogramId, uma_id)
7566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        << "Command-line switch '" << *it
7576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        << "' from about_flags.cc has UMA ID equal to reserved value "
7586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           "kBadSwitchFormatHistogramId=" << kBadSwitchFormatHistogramId
7596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        << ". Please modify switch name.";
7606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SwitchToIdMap::iterator enum_entry =
7616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        histograms_xml_switches_ids.lower_bound(*it);
7626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
7636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Ignore case here when switch ID is incorrect - it has already been
7646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // reported in the previous loop.
7656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_TRUE(enum_entry != histograms_xml_switches_ids.end() &&
7666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                enum_entry->first == *it)
7676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        << "histograms.xml enum LoginCustomFlags doesn't contain switch '"
7686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        << *it << "' (value=" << uma_id
7696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        << " expected). Consider adding entry:\n"
7706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        << "  " << GetHistogramEnumEntryText(*it, uma_id);
7716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
7726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
7736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace about_flags
775