• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 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 "chrome/browser/metrics/metrics_service.h"
6 
7 #include <string>
8 #include <vector>
9 
10 #include "base/base64.h"
11 #include "base/md5.h"
12 #include "base/values.h"
13 
14 #include "testing/gtest/include/gtest/gtest.h"
15 
16 class MetricsServiceTest : public ::testing::Test {
17 };
18 
19 static const size_t kMaxLocalListSize = 3;
20 
21 // Ensure the ClientId is formatted as expected.
TEST(MetricsServiceTest,ClientIdCorrectlyFormatted)22 TEST(MetricsServiceTest, ClientIdCorrectlyFormatted) {
23   std::string clientid = MetricsService::GenerateClientID();
24   EXPECT_EQ(36U, clientid.length());
25   std::string hexchars = "0123456789ABCDEF";
26   for (uint32 i = 0; i < clientid.length(); i++) {
27     char current = clientid.at(i);
28     if (i == 8 || i == 13 || i == 18 || i == 23) {
29       EXPECT_EQ('-', current);
30     } else {
31       EXPECT_TRUE(std::string::npos != hexchars.find(current));
32     }
33   }
34 }
35 
36 // Store and retrieve empty list.
TEST(MetricsServiceTest,EmptyLogList)37 TEST(MetricsServiceTest, EmptyLogList) {
38   ListValue list;
39   std::vector<std::string> local_list;
40 
41   MetricsService::StoreUnsentLogsHelper(local_list, kMaxLocalListSize, &list);
42   EXPECT_EQ(0U, list.GetSize());
43 
44   local_list.clear();  // RecallUnsentLogsHelper() expects empty |local_list|.
45   EXPECT_EQ(MetricsService::LIST_EMPTY,
46             MetricsService::RecallUnsentLogsHelper(list, &local_list));
47   EXPECT_EQ(0U, local_list.size());
48 }
49 
50 // Store and retrieve a single log value.
TEST(MetricsServiceTest,SingleElementLogList)51 TEST(MetricsServiceTest, SingleElementLogList) {
52   ListValue list;
53   std::vector<std::string> local_list;
54 
55   local_list.push_back("Hello world!");
56   EXPECT_EQ(1U, local_list.size());
57 
58   MetricsService::StoreUnsentLogsHelper(local_list, kMaxLocalListSize, &list);
59 
60   // |list| will now contain the following:
61   // [1, Base64Encode("Hello world!"), MD5("Hello world!")].
62   EXPECT_EQ(3U, list.GetSize());
63 
64   // Examine each element.
65   ListValue::const_iterator it = list.begin();
66   int size = 0;
67   (*it)->GetAsInteger(&size);
68   EXPECT_EQ(1, size);
69 
70   ++it;
71   std::string str;
72   (*it)->GetAsString(&str);  // Base64 encoded "Hello world!" string.
73   std::string encoded;
74   base::Base64Encode("Hello world!", &encoded);
75   EXPECT_TRUE(encoded == str);
76 
77   ++it;
78   (*it)->GetAsString(&str);  // MD5 for encoded "Hello world!" string.
79   EXPECT_TRUE(MD5String(encoded) == str);
80 
81   ++it;
82   EXPECT_TRUE(it == list.end());  // Reached end of list.
83 
84   local_list.clear();
85   EXPECT_EQ(MetricsService::RECALL_SUCCESS,
86             MetricsService::RecallUnsentLogsHelper(list, &local_list));
87   EXPECT_EQ(1U, local_list.size());
88 }
89 
90 // Store elements greater than the limit.
TEST(MetricsServiceTest,OverLimitLogList)91 TEST(MetricsServiceTest, OverLimitLogList) {
92   ListValue list;
93   std::vector<std::string> local_list;
94 
95   local_list.push_back("one");
96   local_list.push_back("two");
97   local_list.push_back("three");
98   local_list.push_back("four");
99   EXPECT_EQ(4U, local_list.size());
100 
101   std::string expected_first;
102   base::Base64Encode(local_list[local_list.size() - kMaxLocalListSize],
103                      &expected_first);
104   std::string expected_last;
105   base::Base64Encode(local_list[local_list.size() - 1],
106                      &expected_last);
107 
108   MetricsService::StoreUnsentLogsHelper(local_list, kMaxLocalListSize, &list);
109   EXPECT_EQ(kMaxLocalListSize + 2, list.GetSize());
110 
111   std::string actual_first;
112   EXPECT_TRUE((*(list.begin() + 1))->GetAsString(&actual_first));
113   EXPECT_TRUE(expected_first == actual_first);
114 
115   std::string actual_last;
116   EXPECT_TRUE((*(list.end() - 2))->GetAsString(&actual_last));
117   EXPECT_TRUE(expected_last == actual_last);
118 
119   local_list.clear();
120   EXPECT_EQ(MetricsService::RECALL_SUCCESS,
121             MetricsService::RecallUnsentLogsHelper(list, &local_list));
122   EXPECT_EQ(kMaxLocalListSize, local_list.size());
123 }
124 
125 // Induce LIST_SIZE_TOO_SMALL corruption
TEST(MetricsServiceTest,SmallRecoveredListSize)126 TEST(MetricsServiceTest, SmallRecoveredListSize) {
127   ListValue list;
128   std::vector<std::string> local_list;
129 
130   local_list.push_back("Hello world!");
131   EXPECT_EQ(1U, local_list.size());
132   MetricsService::StoreUnsentLogsHelper(local_list, kMaxLocalListSize, &list);
133   EXPECT_EQ(3U, list.GetSize());
134 
135   // Remove last element.
136   list.Remove(list.GetSize() - 1, NULL);
137   EXPECT_EQ(2U, list.GetSize());
138 
139   local_list.clear();
140   EXPECT_EQ(MetricsService::LIST_SIZE_TOO_SMALL,
141             MetricsService::RecallUnsentLogsHelper(list, &local_list));
142 }
143 
144 // Remove size from the stored list.
TEST(MetricsServiceTest,RemoveSizeFromLogList)145 TEST(MetricsServiceTest, RemoveSizeFromLogList) {
146   ListValue list;
147   std::vector<std::string> local_list;
148 
149   local_list.push_back("one");
150   local_list.push_back("two");
151   EXPECT_EQ(2U, local_list.size());
152   MetricsService::StoreUnsentLogsHelper(local_list, kMaxLocalListSize, &list);
153   EXPECT_EQ(4U, list.GetSize());
154 
155   list.Remove(0, NULL);  // Delete size (1st element).
156   EXPECT_EQ(3U, list.GetSize());
157 
158   local_list.clear();
159   EXPECT_EQ(MetricsService::LIST_SIZE_MISSING,
160             MetricsService::RecallUnsentLogsHelper(list, &local_list));
161 }
162 
163 // Corrupt size of stored list.
TEST(MetricsServiceTest,CorruptSizeOfLogList)164 TEST(MetricsServiceTest, CorruptSizeOfLogList) {
165   ListValue list;
166   std::vector<std::string> local_list;
167 
168   local_list.push_back("Hello world!");
169   EXPECT_EQ(1U, local_list.size());
170   MetricsService::StoreUnsentLogsHelper(local_list, kMaxLocalListSize, &list);
171   EXPECT_EQ(3U, list.GetSize());
172 
173   // Change list size from 1 to 2.
174   EXPECT_TRUE(list.Set(0, Value::CreateIntegerValue(2)));
175   EXPECT_EQ(3U, list.GetSize());
176 
177   local_list.clear();
178   EXPECT_EQ(MetricsService::LIST_SIZE_CORRUPTION,
179             MetricsService::RecallUnsentLogsHelper(list, &local_list));
180 }
181 
182 // Corrupt checksum of stored list.
TEST(MetricsServiceTest,CorruptChecksumOfLogList)183 TEST(MetricsServiceTest, CorruptChecksumOfLogList) {
184   ListValue list;
185   std::vector<std::string> local_list;
186 
187   local_list.clear();
188   local_list.push_back("Hello world!");
189   EXPECT_EQ(1U, local_list.size());
190   MetricsService::StoreUnsentLogsHelper(local_list, kMaxLocalListSize, &list);
191   EXPECT_EQ(3U, list.GetSize());
192 
193   // Fetch checksum (last element) and change it.
194   std::string checksum;
195   EXPECT_TRUE((*(list.end() - 1))->GetAsString(&checksum));
196   checksum[0] = (checksum[0] == 'a') ? 'b' : 'a';
197   EXPECT_TRUE(list.Set(2, Value::CreateStringValue(checksum)));
198   EXPECT_EQ(3U, list.GetSize());
199 
200   local_list.clear();
201   EXPECT_EQ(MetricsService::CHECKSUM_CORRUPTION,
202             MetricsService::RecallUnsentLogsHelper(list, &local_list));
203 }
204