1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 #include "usage_stats/usage_stats_uploader.h"
31
32 #ifdef OS_ANDROID
33 #include <jni.h>
34 #endif // OS_ANDROID
35
36 #include <algorithm>
37 #include <map>
38 #include <string>
39 #include <utility>
40 #include <vector>
41
42 #include "base/clock.h"
43 #include "base/port.h"
44 #include "base/singleton.h"
45 #include "base/system_util.h"
46 #include "base/util.h"
47 #include "base/version.h"
48 #include "base/win_util.h"
49 #include "config/config_handler.h"
50 #include "net/http_client.h"
51 #include "storage/registry.h"
52 #include "storage/storage_interface.h"
53 #include "testing/base/public/gunit.h"
54 #include "usage_stats/usage_stats.h"
55 #include "usage_stats/usage_stats.pb.h"
56 #include "usage_stats/usage_stats_testing_util.h"
57
58 #ifdef OS_ANDROID
59 #include "base/android_jni_mock.h"
60 #include "base/android_jni_proxy.h"
61 #include "base/android_util.h"
62 #endif // OS_ANDROID
63
64 DECLARE_string(test_tmpdir);
65
66 namespace mozc {
67 namespace usage_stats {
68 namespace {
69
70 class TestableUsageStatsUploader : public UsageStatsUploader {
71 public:
72 // Change access rights.
73 using UsageStatsUploader::LoadStats;
74 using UsageStatsUploader::GetClientId;
75 };
76
77 class TestHTTPClient : public HTTPClientInterface {
78 public:
Get(const string & url,const HTTPClient::Option & option,string * output) const79 bool Get(const string &url, const HTTPClient::Option &option,
80 string *output) const { return true; }
Head(const string & url,const HTTPClient::Option & option,string * output) const81 bool Head(const string &url, const HTTPClient::Option &option,
82 string *output) const { return true; }
Post(const string & url,const string & data,const HTTPClient::Option & option,string * output) const83 bool Post(const string &url, const string &data,
84 const HTTPClient::Option &option, string *output) const {
85 LOG(INFO) << "url: " << url;
86 LOG(INFO) << "data: " << data;
87 if (result_.expected_url != url) {
88 LOG(INFO) << "expected_url: " << result_.expected_url;
89 return false;
90 }
91
92 std::vector<string> data_set;
93 Util::SplitStringUsing(data, "&", &data_set);
94 for (size_t i = 0; i < expected_data_.size(); ++i) {
95 std::vector<string>::const_iterator itr =
96 std::find(data_set.begin(), data_set.end(), expected_data_[i]);
97 const bool found = (itr != data_set.end());
98 // we can't compile EXPECT_NE(itr, data_set.end()), so we use EXPECT_TRUE
99 EXPECT_TRUE(found) << expected_data_[i];
100 }
101
102 *output = result_.expected_result;
103 return true;
104 }
105
106 struct Result {
107 string expected_url;
108 string expected_result;
109 };
110
set_result(const Result & result)111 void set_result(const Result &result) {
112 result_ = result;
113 }
114
115 // TODO(toshiyuki): integrate with struct Result
AddExpectedData(const string & data)116 void AddExpectedData(const string &data) {
117 expected_data_.push_back(data);
118 }
119
120 private:
121 // usage stats key and value parameter
122 // format is "<key>:<type>=<value>"
123 std::vector<string> expected_data_;
124 Result result_;
125 };
126
127 const uint32 kOneDaySec = 24 * 60 * 60; // 24 hours
128 const uint32 kHalfDaySec = 12 * 60 * 60; // 12 hours
129 const char kBaseUrl[] =
130 #ifdef OS_NACL
131 "https://clients4.google.com/tbproxy/usagestats";
132 #else // OS_NACL
133 "http://clients4.google.com/tbproxy/usagestats";
134 #endif // OS_NACL
135 const char kTestClientId[] = "TestClientId";
136 const char kCountStatsKey[] = "Commit";
137 const uint32 kCountStatsDefaultValue = 100;
138 const char kIntegerStatsKey[] = "UserRegisteredWord";
139 const int kIntegerStatsDefaultValue = 2;
140
SetUpMetaDataWithMozcVersion(uint32 last_upload_time,const string & mozc_version)141 void SetUpMetaDataWithMozcVersion(uint32 last_upload_time,
142 const string &mozc_version) {
143 EXPECT_TRUE(storage::Registry::Insert("usage_stats.last_upload",
144 last_upload_time));
145 EXPECT_TRUE(storage::Registry::Insert("usage_stats.mozc_version",
146 mozc_version));
147 }
148
SetUpMetaData(uint32 last_upload_time)149 void SetUpMetaData(uint32 last_upload_time) {
150 SetUpMetaDataWithMozcVersion(last_upload_time, Version::GetMozcVersion());
151 }
152
153 class TestClientId : public ClientIdInterface {
154 public:
TestClientId()155 TestClientId() {}
~TestClientId()156 virtual ~TestClientId() {}
GetClientId(string * output)157 void GetClientId(string *output) {
158 *output = kTestClientId;
159 }
160 };
161
162 class UsageStatsUploaderTest : public ::testing::Test {
163 protected:
SetUp()164 virtual void SetUp() {
165 SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);
166
167 TestableUsageStatsUploader::SetClientIdHandler(&client_id_);
168 HTTPClient::SetHTTPClientHandler(&client_);
169 EXPECT_TRUE(storage::Registry::Clear());
170
171 // save test stats
172 UsageStats::IncrementCountBy(kCountStatsKey, kCountStatsDefaultValue);
173 EXPECT_COUNT_STATS(kCountStatsKey, kCountStatsDefaultValue);
174 UsageStats::SetInteger(kIntegerStatsKey, kIntegerStatsDefaultValue);
175 EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
176 }
177
TearDown()178 virtual void TearDown() {
179 TestableUsageStatsUploader::SetClientIdHandler(NULL);
180 HTTPClient::SetHTTPClientHandler(NULL);
181 EXPECT_TRUE(storage::Registry::Clear());
182 }
183
SetValidResult()184 void SetValidResult() {
185 std::vector<std::pair<string, string> > params;
186 params.push_back(std::make_pair("sourceid", "ime"));
187 params.push_back(std::make_pair("hl", "ja"));
188 params.push_back(std::make_pair("v", Version::GetMozcVersion()));
189 params.push_back(std::make_pair("client_id", kTestClientId));
190 params.push_back(
191 std::make_pair("os_ver", SystemUtil::GetOSVersionString()));
192 #ifdef OS_ANDROID
193 params.push_back(
194 std::make_pair("model",
195 AndroidUtil::GetSystemProperty(
196 AndroidUtil::kSystemPropertyModel, "Unknown")));
197 #endif // OS_ANDROID
198
199 string url = string(kBaseUrl) + "?";
200 Util::AppendCGIParams(params, &url);
201 TestHTTPClient::Result result;
202 result.expected_url = url;
203 client_.set_result(result);
204 }
205
206 TestHTTPClient client_;
207 TestClientId client_id_;
208 scoped_usage_stats_enabler usage_stats_enabler_;
209 };
210
TEST_F(UsageStatsUploaderTest,SendTest)211 TEST_F(UsageStatsUploaderTest, SendTest) {
212 const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
213 const uint32 last_upload_sec = current_sec - kOneDaySec;
214 SetUpMetaData(last_upload_sec);
215 SetValidResult();
216
217 EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
218
219 // COUNT stats are cleared
220 EXPECT_STATS_NOT_EXIST(kCountStatsKey);
221 // INTEGER stats are not cleared
222 EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
223 uint32 recorded_sec;
224 string recorded_version;
225 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
226 &recorded_sec));
227 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.mozc_version",
228 &recorded_version));
229 EXPECT_LE(current_sec, recorded_sec);
230 EXPECT_EQ(Version::GetMozcVersion(), recorded_version);
231 }
232
TEST_F(UsageStatsUploaderTest,FirstTimeSendTest)233 TEST_F(UsageStatsUploaderTest, FirstTimeSendTest) {
234 const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
235 // Don't call SetUpMetaData()..
236 SetValidResult();
237
238 uint32 recorded_sec;
239 string recorded_version;
240 EXPECT_FALSE(storage::Registry::Lookup("usage_stats.last_upload",
241 &recorded_sec));
242 EXPECT_FALSE(storage::Registry::Lookup("usage_stats.mozc_version",
243 &recorded_version));
244
245 EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
246
247 EXPECT_STATS_NOT_EXIST(kCountStatsKey);
248 EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
249 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
250 &recorded_sec));
251 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.mozc_version",
252 &recorded_version));
253 EXPECT_LE(current_sec, recorded_sec);
254 EXPECT_EQ(Version::GetMozcVersion(), recorded_version);
255 }
256
TEST_F(UsageStatsUploaderTest,SendFailTest)257 TEST_F(UsageStatsUploaderTest, SendFailTest) {
258 const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
259 const uint32 last_upload_sec = current_sec - kHalfDaySec;
260 SetUpMetaData(last_upload_sec);
261 SetValidResult();
262
263 EXPECT_FALSE(TestableUsageStatsUploader::Send(NULL));
264
265 EXPECT_COUNT_STATS(kCountStatsKey, kCountStatsDefaultValue);
266 EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
267 uint32 recorded_sec;
268 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
269 &recorded_sec));
270 EXPECT_EQ(last_upload_sec, recorded_sec);
271 }
272
TEST_F(UsageStatsUploaderTest,InvalidLastUploadTest)273 TEST_F(UsageStatsUploaderTest, InvalidLastUploadTest) {
274 const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
275 // future time
276 // for example: time zone has changed
277 const uint32 invalid_sec = current_sec + kHalfDaySec;
278 SetUpMetaData(invalid_sec);
279 SetValidResult();
280
281 EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
282
283 EXPECT_STATS_NOT_EXIST(kCountStatsKey);
284 EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
285 uint32 recorded_sec;
286 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
287 &recorded_sec));
288 // Save new last_upload_time
289 EXPECT_LE(current_sec, recorded_sec);
290 }
291
TEST_F(UsageStatsUploaderTest,MozcVersionMismatchTest)292 TEST_F(UsageStatsUploaderTest, MozcVersionMismatchTest) {
293 const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
294 const uint32 last_upload_sec = current_sec - kOneDaySec;
295 SetUpMetaDataWithMozcVersion(last_upload_sec, "invalid_mozc_version");
296 SetValidResult();
297
298 EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
299
300 EXPECT_STATS_NOT_EXIST(kCountStatsKey);
301 EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
302 uint32 recorded_sec;
303 string recorded_version;
304 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
305 &recorded_sec));
306 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.mozc_version",
307 &recorded_version));
308 // Save new last_upload_time and recorded_version.
309 EXPECT_LE(current_sec, recorded_sec);
310 EXPECT_EQ(Version::GetMozcVersion(), recorded_version);
311 }
312
313 class TestStorage: public storage::StorageInterface {
314 public:
Open(const string & filename)315 bool Open(const string &filename) { return true; }
Sync()316 bool Sync() { return true; }
Lookup(const string & key,string * value) const317 bool Lookup(const string &key, string *value) const { return false; }
318 // return false
Insert(const string & key,const string & value)319 bool Insert(const string &key, const string &value) { return false; }
Erase(const string & key)320 bool Erase(const string &key) { return true; }
Clear()321 bool Clear() { return true; }
Size() const322 size_t Size() const { return 0; }
TestStorage()323 TestStorage() {}
~TestStorage()324 virtual ~TestStorage() {}
325 };
326
TEST_F(UsageStatsUploaderTest,SaveMetadataFailTest)327 TEST_F(UsageStatsUploaderTest, SaveMetadataFailTest) {
328 const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
329 const uint32 last_upload_sec = current_sec - kOneDaySec;
330 const string current_version = Version::GetMozcVersion();
331 SetUpMetaData(last_upload_sec);
332 SetValidResult();
333
334 // set the TestStorage as a storage handler.
335 // writing to the registry will be failed.
336 storage::Registry::SetStorage(Singleton<TestStorage>::get());
337 // confirm that we can not insert.
338 EXPECT_FALSE(storage::Registry::Insert("usage_stats.last_upload",
339 last_upload_sec));
340 EXPECT_FALSE(storage::Registry::Insert("usage_stats.mozc_version",
341 current_version));
342
343 EXPECT_FALSE(TestableUsageStatsUploader::Send(NULL));
344 // restore
345 storage::Registry::SetStorage(NULL);
346
347 // stats data are kept
348 EXPECT_COUNT_STATS(kCountStatsKey, kCountStatsDefaultValue);
349 EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
350 uint32 recorded_sec;
351 string recorded_version;
352 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
353 &recorded_sec));
354 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.mozc_version",
355 &recorded_version));
356 EXPECT_EQ(last_upload_sec, recorded_sec);
357 EXPECT_EQ(current_version, recorded_version);
358 }
359
TEST_F(UsageStatsUploaderTest,UploadFailTest)360 TEST_F(UsageStatsUploaderTest, UploadFailTest) {
361 const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
362 const uint32 last_upload_sec = current_sec - kOneDaySec;
363 SetUpMetaData(last_upload_sec);
364 SetValidResult();
365
366 TestHTTPClient::Result result;
367 // set dummy result url so that upload will be failed.
368 result.expected_url = "fail_url";
369 client_.set_result(result);
370
371 EXPECT_FALSE(TestableUsageStatsUploader::Send(NULL));
372
373 // stats data are not cleared
374 EXPECT_COUNT_STATS(kCountStatsKey, kCountStatsDefaultValue);
375 EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
376 // "UsageStatsUploadFailed" is incremented
377 EXPECT_COUNT_STATS("UsageStatsUploadFailed", 1);
378 uint32 recorded_sec;
379 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
380 &recorded_sec));
381 // last_upload is not updated
382 EXPECT_EQ(last_upload_sec, recorded_sec);
383 }
384
TEST_F(UsageStatsUploaderTest,UploadRetryTest)385 TEST_F(UsageStatsUploaderTest, UploadRetryTest) {
386 const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
387 const uint32 last_upload_sec = current_sec - kOneDaySec;
388 SetUpMetaData(last_upload_sec);
389 SetValidResult();
390
391 TestHTTPClient::Result result;
392 // set dummy result url so that upload will be failed.
393 result.expected_url = "fail_url";
394 client_.set_result(result);
395
396 EXPECT_FALSE(TestableUsageStatsUploader::Send(NULL));
397
398 // stats data are not cleared
399 EXPECT_COUNT_STATS(kCountStatsKey, kCountStatsDefaultValue);
400 EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
401 uint32 recorded_sec;
402 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
403 &recorded_sec));
404 // last_upload is not updated
405 EXPECT_EQ(last_upload_sec, recorded_sec);
406
407 // retry
408 SetValidResult();
409 // We can send stats if network is available.
410 EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
411
412 // Stats are cleared
413 EXPECT_STATS_NOT_EXIST(kCountStatsKey);
414 // However, INTEGER stats are not cleared
415 EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
416 // last upload is updated
417 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
418 &recorded_sec));
419 EXPECT_LE(last_upload_sec, recorded_sec);
420 }
421
TEST_F(UsageStatsUploaderTest,UploadDataTest)422 TEST_F(UsageStatsUploaderTest, UploadDataTest) {
423 const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
424 const uint32 last_upload_sec = current_sec - kOneDaySec;
425 SetUpMetaData(last_upload_sec);
426 SetValidResult();
427
428 #ifdef OS_WIN
429 const string win64 = (string("WindowsX64:b=")
430 + (SystemUtil::IsWindowsX64()? "t" : "f"));
431 client_.AddExpectedData(win64);
432 #endif
433 client_.AddExpectedData(Util::StringPrintf("%s:c=%u", kCountStatsKey,
434 kCountStatsDefaultValue));
435 client_.AddExpectedData(Util::StringPrintf("%s:i=%d", kIntegerStatsKey,
436 kIntegerStatsDefaultValue));
437 client_.AddExpectedData("Daily");
438
439 EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
440 }
441
SetDoubleValueStats(uint32 num,double total,double square_total,usage_stats::Stats::DoubleValueStats * double_stats)442 void SetDoubleValueStats(
443 uint32 num, double total, double square_total,
444 usage_stats::Stats::DoubleValueStats *double_stats) {
445 double_stats->set_num(num);
446 double_stats->set_total(total);
447 double_stats->set_square_total(square_total);
448 }
449
SetEventStats(uint32 source_id,uint32 sx_num,double sx_total,double sx_square_total,uint32 sy_num,double sy_total,double sy_square_total,uint32 dx_num,double dx_total,double dx_square_total,uint32 dy_num,double dy_total,double dy_square_total,uint32 tl_num,double tl_total,double tl_square_total,usage_stats::Stats::TouchEventStats * event_stats)450 void SetEventStats(
451 uint32 source_id,
452 uint32 sx_num, double sx_total, double sx_square_total,
453 uint32 sy_num, double sy_total, double sy_square_total,
454 uint32 dx_num, double dx_total, double dx_square_total,
455 uint32 dy_num, double dy_total, double dy_square_total,
456 uint32 tl_num, double tl_total, double tl_square_total,
457 usage_stats::Stats::TouchEventStats *event_stats) {
458 event_stats->set_source_id(source_id);
459 SetDoubleValueStats(sx_num, sx_total, sx_square_total,
460 event_stats->mutable_start_x_stats());
461 SetDoubleValueStats(sy_num, sy_total, sy_square_total,
462 event_stats->mutable_start_y_stats());
463 SetDoubleValueStats(dx_num, dx_total, dx_square_total,
464 event_stats->mutable_direction_x_stats());
465 SetDoubleValueStats(dy_num, dy_total, dy_square_total,
466 event_stats->mutable_direction_y_stats());
467 SetDoubleValueStats(tl_num, tl_total, tl_square_total,
468 event_stats->mutable_time_length_stats());
469 }
470
TEST_F(UsageStatsUploaderTest,UploadTouchEventStats)471 TEST_F(UsageStatsUploaderTest, UploadTouchEventStats) {
472 // save last_upload
473 const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
474 const uint32 last_upload_sec = current_sec - kOneDaySec;
475 SetUpMetaData(last_upload_sec);
476 SetValidResult();
477
478 EXPECT_STATS_NOT_EXIST("VirtualKeyboardStats");
479 EXPECT_STATS_NOT_EXIST("VirtualKeyboardMissStats");
480 std::map<string, std::map<uint32, Stats::TouchEventStats> > touch_stats;
481 std::map<string, std::map<uint32, Stats::TouchEventStats> > miss_touch_stats;
482
483 Stats::TouchEventStats &event_stats1 = touch_stats["KEYBOARD_01"][10];
484 SetEventStats(10, 2, 3, 8, 2, 4, 10, 2, 5, 16, 2, 2, 2,
485 2, 3, 9, &event_stats1);
486
487 Stats::TouchEventStats &event_stats2 = touch_stats["KEYBOARD_02"][20];
488 SetEventStats(20, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
489 114, 115, 116, &event_stats2);
490
491 Stats::TouchEventStats &event_stats3 = touch_stats["KEYBOARD_01"][20];
492 SetEventStats(20, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
493 214, 215, 216, &event_stats3);
494
495 Stats::TouchEventStats &event_stats4 = miss_touch_stats["KEYBOARD_01"][20];
496 SetEventStats(20, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313,
497 314, 315, 316, &event_stats4);
498
499 Stats::TouchEventStats &event_stats5 = miss_touch_stats["KEYBOARD_01"][30];
500 SetEventStats(30, 404, 406, 408, 410, 412, 414, 416, 418, 420, 422, 424, 426,
501 428, 430, 432, &event_stats5);
502
503 UsageStats::StoreTouchEventStats("VirtualKeyboardStats", touch_stats);
504 UsageStats::StoreTouchEventStats("VirtualKeyboardMissStats",
505 miss_touch_stats);
506
507 Stats stats;
508 EXPECT_TRUE(UsageStats::GetVirtualKeyboardForTest("VirtualKeyboardStats",
509 &stats));
510 EXPECT_EQ(2, stats.virtual_keyboard_stats_size());
511 EXPECT_EQ("KEYBOARD_01",
512 stats.virtual_keyboard_stats(0).keyboard_name());
513 EXPECT_EQ("KEYBOARD_02",
514 stats.virtual_keyboard_stats(1).keyboard_name());
515 EXPECT_EQ(2, stats.virtual_keyboard_stats(0).touch_event_stats_size());
516 EXPECT_EQ(1, stats.virtual_keyboard_stats(1).touch_event_stats_size());
517
518 EXPECT_EQ(event_stats1.DebugString(),
519 stats.virtual_keyboard_stats(0).touch_event_stats(0).DebugString());
520 EXPECT_EQ(event_stats3.DebugString(),
521 stats.virtual_keyboard_stats(0).touch_event_stats(1).DebugString());
522 EXPECT_EQ(event_stats2.DebugString(),
523 stats.virtual_keyboard_stats(1).touch_event_stats(0).DebugString());
524
525 EXPECT_TRUE(UsageStats::GetVirtualKeyboardForTest("VirtualKeyboardMissStats",
526 &stats));
527 EXPECT_EQ(1, stats.virtual_keyboard_stats_size());
528 EXPECT_EQ("KEYBOARD_01",
529 stats.virtual_keyboard_stats(0).keyboard_name());
530 EXPECT_EQ(2, stats.virtual_keyboard_stats(0).touch_event_stats_size());
531 EXPECT_EQ(event_stats4.DebugString(),
532 stats.virtual_keyboard_stats(0).touch_event_stats(0).DebugString());
533 EXPECT_EQ(event_stats5.DebugString(),
534 stats.virtual_keyboard_stats(0).touch_event_stats(1).DebugString());
535
536 client_.AddExpectedData(string("vks%5Fname%5FKEYBOARD%5F01:i=0"));
537 client_.AddExpectedData(string("vks%5Fname%5FKEYBOARD%5F02:i=1"));
538 client_.AddExpectedData(string("vkms%5Fname%5FKEYBOARD%5F01:i=0"));
539
540 // Average = total / num
541 // Variance = square_total / num - (total / num) ^ 2
542 // Because the current log analysis system can only deal with int values,
543 // we multiply these values by a scale factor and send them to server.
544 // sxa, sya, dxa, dya : scale = 10000000
545 // sxv, syv, dxv, dyv : scale = 10000000
546 // tla, tlv : scale = 10000000
547
548 // (3 / 2) * 10000000
549 client_.AddExpectedData(string("vks%5F0%5F10%5Fsxa:i=15000000"));
550 // (8 / 2 - (3 / 2) ^ 2) * 10000000
551 client_.AddExpectedData(string("vks%5F0%5F10%5Fsxv:i=17500000"));
552 // (4 / 2) * 10000000
553 client_.AddExpectedData(string("vks%5F0%5F10%5Fsya:i=20000000"));
554 // (10 / 2 - (4 / 2) ^ 2) * 10000000
555 client_.AddExpectedData(string("vks%5F0%5F10%5Fsyv:i=10000000"));
556 // (5 / 2) * 10000000
557 client_.AddExpectedData(string("vks%5F0%5F10%5Fdxa:i=25000000"));
558 // (16 / 2 - (5 / 2) ^ 2) * 10000000
559 client_.AddExpectedData(string("vks%5F0%5F10%5Fdxv:i=17500000"));
560 // (2 / 2) * 10000000
561 client_.AddExpectedData(string("vks%5F0%5F10%5Fdya:i=10000000"));
562 // (2 / 2 - (2 / 2) ^ 2) * 10000000
563 client_.AddExpectedData(string("vks%5F0%5F10%5Fdyv:i=0"));
564 // (3 / 2) * 10000000
565 client_.AddExpectedData(string("vks%5F0%5F10%5Ftla:i=15000000"));
566 // (9 / 2 - (3 / 2) ^ 2) * 10000000
567 client_.AddExpectedData(string("vks%5F0%5F10%5Ftlv:i=22500000"));
568 EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
569 }
570
TEST(ClientIdTest,CreateClientIdTest)571 TEST(ClientIdTest, CreateClientIdTest) {
572 // test default client id handler here
573 TestableUsageStatsUploader::SetClientIdHandler(NULL);
574 SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);
575 EXPECT_TRUE(storage::Registry::Clear());
576 string client_id1;
577 TestableUsageStatsUploader::GetClientId(&client_id1);
578 string client_id_in_storage1;
579 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.client_id",
580 &client_id_in_storage1));
581 EXPECT_TRUE(storage::Registry::Clear());
582 string client_id2;
583 TestableUsageStatsUploader::GetClientId(&client_id2);
584 string client_id_in_storage2;
585 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.client_id",
586 &client_id_in_storage2));
587
588 EXPECT_NE(client_id1, client_id2);
589 EXPECT_NE(client_id_in_storage1, client_id_in_storage2);
590 }
591
TEST(ClientIdTest,GetClientIdTest)592 TEST(ClientIdTest, GetClientIdTest) {
593 // test default client id handler here.
594 TestableUsageStatsUploader::SetClientIdHandler(NULL);
595 SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);
596 EXPECT_TRUE(storage::Registry::Clear());
597 string client_id1;
598 TestableUsageStatsUploader::GetClientId(&client_id1);
599 string client_id2;
600 TestableUsageStatsUploader::GetClientId(&client_id2);
601 // we can get same client id.
602 EXPECT_EQ(client_id1, client_id2);
603
604 string client_id_in_storage;
605 EXPECT_TRUE(storage::Registry::Lookup("usage_stats.client_id",
606 &client_id_in_storage));
607 // encrypted value is in storage
608 EXPECT_NE(client_id1, client_id_in_storage);
609 }
610
TEST(ClientIdTest,GetClientIdFailTest)611 TEST(ClientIdTest, GetClientIdFailTest) {
612 // test default client id handler here.
613 TestableUsageStatsUploader::SetClientIdHandler(NULL);
614 SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);
615 EXPECT_TRUE(storage::Registry::Clear());
616 string client_id1;
617 TestableUsageStatsUploader::GetClientId(&client_id1);
618 // insert invalid data
619 EXPECT_TRUE(storage::Registry::Insert("usage_stats.client_id",
620 "invalid_data"));
621
622 string client_id2;
623 // decript should be failed
624 TestableUsageStatsUploader::GetClientId(&client_id2);
625 // new id should be generated
626 EXPECT_NE(client_id1, client_id2);
627 }
628
629 } // namespace
630 } // namespace usage_stats
631 } // namespace mozc
632