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. 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. 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. 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. 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 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. 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. 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. 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