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