metrics_log_unittest.cc revision 4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7
1// Copyright (c) 2006-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 <string> 6 7#include "base/string_util.h" 8#include "base/time.h" 9#include "chrome/browser/metrics/metrics_log.h" 10#include "googleurl/src/gurl.h" 11#include "testing/gtest/include/gtest/gtest.h" 12 13using base::TimeDelta; 14 15namespace { 16 class MetricsLogTest : public testing::Test { 17 }; 18}; 19 20 21// Since buildtime is highly variable, this function will scan an output log and 22// replace it with a consistent number. 23static void NormalizeBuildtime(std::string* xml_encoded) { 24 std::string prefix = "buildtime=\""; 25 const char postfix = '\"'; 26 size_t offset = xml_encoded->find(prefix); 27 ASSERT_GT(offset, 0u); 28 offset += prefix.size(); 29 size_t postfix_position = xml_encoded->find(postfix, offset); 30 ASSERT_GT(postfix_position, offset); 31 for (size_t i = offset; i < postfix_position; ++i) { 32 char digit = xml_encoded->at(i); 33 ASSERT_GE(digit, '0'); 34 ASSERT_LE(digit, '9'); 35 } 36 37 // Insert a single fake buildtime. 38 xml_encoded->replace(offset, postfix_position - offset, "123246"); 39} 40 41TEST(MetricsLogTest, EmptyRecord) { 42 std::string expected_output = StringPrintf( 43 "<log clientid=\"bogus client ID\" buildtime=\"123456789\" " 44 "appversion=\"%s\"/>", MetricsLog::GetVersionString().c_str()); 45 46 MetricsLog log("bogus client ID", 0); 47 log.CloseLog(); 48 49 int size = log.GetEncodedLogSize(); 50 ASSERT_GT(size, 0); 51 52 std::string encoded; 53 // Leave room for the NUL terminator. 54 ASSERT_TRUE(log.GetEncodedLog(WriteInto(&encoded, size + 1), size)); 55 TrimWhitespaceASCII(encoded, TRIM_ALL, &encoded); 56 NormalizeBuildtime(&encoded); 57 NormalizeBuildtime(&expected_output); 58 59 ASSERT_EQ(expected_output, encoded); 60} 61 62#if defined(OS_CHROMEOS) 63TEST(MetricsLogTest, ChromeOSEmptyRecord) { 64 std::string expected_output = StringPrintf( 65 "<log clientid=\"bogus client ID\" buildtime=\"123456789\" " 66 "appversion=\"%s\" hardwareclass=\"sample-class\"/>", 67 MetricsLog::GetVersionString().c_str()); 68 69 MetricsLog log("bogus client ID", 0); 70 log.set_hardware_class("sample-class"); 71 log.CloseLog(); 72 73 int size = log.GetEncodedLogSize(); 74 ASSERT_GT(size, 0); 75 76 std::string encoded; 77 // Leave room for the NUL terminator. 78 ASSERT_TRUE(log.GetEncodedLog(WriteInto(&encoded, size + 1), size)); 79 TrimWhitespaceASCII(encoded, TRIM_ALL, &encoded); 80 NormalizeBuildtime(&encoded); 81 NormalizeBuildtime(&expected_output); 82 83 ASSERT_EQ(expected_output, encoded); 84} 85#endif // OS_CHROMEOS 86 87namespace { 88 89class NoTimeMetricsLog : public MetricsLog { 90 public: 91 NoTimeMetricsLog(std::string client_id, int session_id): 92 MetricsLog(client_id, session_id) {} 93 virtual ~NoTimeMetricsLog() {} 94 95 // Override this so that output is testable. 96 virtual std::string GetCurrentTimeString() { 97 return std::string(); 98 } 99}; 100 101}; // namespace 102 103TEST(MetricsLogTest, WindowEvent) { 104 std::string expected_output = StringPrintf( 105 "<log clientid=\"bogus client ID\" buildtime=\"123456789\" " 106 "appversion=\"%s\">\n" 107 " <window action=\"create\" windowid=\"0\" session=\"0\" time=\"\"/>\n" 108 " <window action=\"open\" windowid=\"1\" parent=\"0\" " 109 "session=\"0\" time=\"\"/>\n" 110 " <window action=\"close\" windowid=\"1\" parent=\"0\" " 111 "session=\"0\" time=\"\"/>\n" 112 " <window action=\"destroy\" windowid=\"0\" session=\"0\" time=\"\"/>\n" 113 "</log>", MetricsLog::GetVersionString().c_str()); 114 115 NoTimeMetricsLog log("bogus client ID", 0); 116 log.RecordWindowEvent(MetricsLog::WINDOW_CREATE, 0, -1); 117 log.RecordWindowEvent(MetricsLog::WINDOW_OPEN, 1, 0); 118 log.RecordWindowEvent(MetricsLog::WINDOW_CLOSE, 1, 0); 119 log.RecordWindowEvent(MetricsLog::WINDOW_DESTROY, 0, -1); 120 log.CloseLog(); 121 122 ASSERT_EQ(4, log.num_events()); 123 124 int size = log.GetEncodedLogSize(); 125 ASSERT_GT(size, 0); 126 127 std::string encoded; 128 // Leave room for the NUL terminator. 129 ASSERT_TRUE(log.GetEncodedLog(WriteInto(&encoded, size + 1), size)); 130 TrimWhitespaceASCII(encoded, TRIM_ALL, &encoded); 131 NormalizeBuildtime(&encoded); 132 NormalizeBuildtime(&expected_output); 133 134 ASSERT_EQ(expected_output, encoded); 135} 136 137TEST(MetricsLogTest, LoadEvent) { 138 std::string expected_output = StringPrintf( 139 "<log clientid=\"bogus client ID\" buildtime=\"123456789\" " 140 "appversion=\"%s\">\n" 141 " <document action=\"load\" docid=\"1\" window=\"3\" loadtime=\"7219\" " 142 "origin=\"link\" session=\"0\" time=\"\"/>\n" 143 "</log>", MetricsLog::GetVersionString().c_str()); 144 145 NoTimeMetricsLog log("bogus client ID", 0); 146 log.RecordLoadEvent(3, GURL("http://google.com"), PageTransition::LINK, 147 1, TimeDelta::FromMilliseconds(7219)); 148 149 log.CloseLog(); 150 151 ASSERT_EQ(1, log.num_events()); 152 153 int size = log.GetEncodedLogSize(); 154 ASSERT_GT(size, 0); 155 156 std::string encoded; 157 // Leave room for the NUL terminator. 158 ASSERT_TRUE(log.GetEncodedLog(WriteInto(&encoded, size + 1), size)); 159 TrimWhitespaceASCII(encoded, TRIM_ALL, &encoded); 160 NormalizeBuildtime(&encoded); 161 NormalizeBuildtime(&expected_output); 162 163 ASSERT_EQ(expected_output, encoded); 164} 165 166#if defined(OS_CHROMEOS) 167TEST(MetricsLogTest, ChromeOSLoadEvent) { 168 std::string expected_output = StringPrintf( 169 "<log clientid=\"bogus client ID\" buildtime=\"123456789\" " 170 "appversion=\"%s\" hardwareclass=\"sample-class\">\n" 171 " <document action=\"load\" docid=\"1\" window=\"3\" loadtime=\"7219\" " 172 "origin=\"link\" session=\"0\" time=\"\"/>\n" 173 "</log>", MetricsLog::GetVersionString().c_str()); 174 175 NoTimeMetricsLog log("bogus client ID", 0); 176 log.RecordLoadEvent(3, GURL("http://google.com"), PageTransition::LINK, 177 1, TimeDelta::FromMilliseconds(7219)); 178 log.set_hardware_class("sample-class"); 179 log.CloseLog(); 180 181 ASSERT_EQ(1, log.num_events()); 182 183 int size = log.GetEncodedLogSize(); 184 ASSERT_GT(size, 0); 185 186 std::string encoded; 187 // Leave room for the NUL terminator. 188 ASSERT_TRUE(log.GetEncodedLog(WriteInto(&encoded, size + 1), size)); 189 TrimWhitespaceASCII(encoded, TRIM_ALL, &encoded); 190 NormalizeBuildtime(&encoded); 191 NormalizeBuildtime(&expected_output); 192 193 ASSERT_EQ(expected_output, encoded); 194} 195#endif // OS_CHROMEOS 196 197// Make sure our ID hashes are the same as what we see on the server side. 198TEST(MetricsLogTest, CreateHash) { 199 static const struct { 200 std::string input; 201 std::string output; 202 } cases[] = { 203 {"Back", "0x0557fa923dcee4d0"}, 204 {"Forward", "0x67d2f6740a8eaebf"}, 205 {"NewTab", "0x290eb683f96572f1"}, 206 }; 207 208 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { 209 std::string hash_string = MetricsLog::CreateHash(cases[i].input); 210 211 // Convert to hex string 212 // We're only checking the first 8 bytes, because that's what 213 // the metrics server uses. 214 std::string hash_hex = "0x"; 215 for (size_t j = 0; j < 8; j++) { 216 base::StringAppendF(&hash_hex, "%02x", 217 static_cast<uint8>(hash_string.data()[j])); 218 } 219 EXPECT_EQ(cases[i].output, hash_hex); 220 } 221}; 222