Home | History | Annotate | Download | only in metrics
      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