1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "uploader/metrics_log_base.h" 18 19 #include <string> 20 21 #include <base/metrics/bucket_ranges.h> 22 #include <base/metrics/sample_vector.h> 23 #include <gtest/gtest.h> 24 25 #include "uploader/proto/chrome_user_metrics_extension.pb.h" 26 27 namespace metrics { 28 29 namespace { 30 31 class TestMetricsLogBase : public MetricsLogBase { 32 public: 33 TestMetricsLogBase() 34 : MetricsLogBase("client_id", 1, MetricsLogBase::ONGOING_LOG, "1.2.3.4") { 35 } 36 virtual ~TestMetricsLogBase() {} 37 38 using MetricsLogBase::uma_proto; 39 40 private: 41 DISALLOW_COPY_AND_ASSIGN(TestMetricsLogBase); 42 }; 43 44 } // namespace 45 46 TEST(MetricsLogBaseTest, LogType) { 47 MetricsLogBase log1("id", 0, MetricsLogBase::ONGOING_LOG, "1.2.3"); 48 EXPECT_EQ(MetricsLogBase::ONGOING_LOG, log1.log_type()); 49 50 MetricsLogBase log2("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "1.2.3"); 51 EXPECT_EQ(MetricsLogBase::INITIAL_STABILITY_LOG, log2.log_type()); 52 } 53 54 TEST(MetricsLogBaseTest, EmptyRecord) { 55 MetricsLogBase log("totally bogus client ID", 137, 56 MetricsLogBase::ONGOING_LOG, "bogus version"); 57 log.set_hardware_class("sample-class"); 58 log.CloseLog(); 59 60 std::string encoded; 61 log.GetEncodedLog(&encoded); 62 63 // A couple of fields are hard to mock, so these will be copied over directly 64 // for the expected output. 65 metrics::ChromeUserMetricsExtension parsed; 66 ASSERT_TRUE(parsed.ParseFromString(encoded)); 67 68 metrics::ChromeUserMetricsExtension expected; 69 expected.set_client_id(5217101509553811875); // Hashed bogus client ID 70 expected.set_session_id(137); 71 expected.mutable_system_profile()->set_build_timestamp( 72 parsed.system_profile().build_timestamp()); 73 expected.mutable_system_profile()->set_app_version("bogus version"); 74 expected.mutable_system_profile()->mutable_hardware()->set_hardware_class( 75 "sample-class"); 76 77 EXPECT_EQ(expected.SerializeAsString(), encoded); 78 } 79 80 TEST(MetricsLogBaseTest, HistogramBucketFields) { 81 // Create buckets: 1-5, 5-7, 7-8, 8-9, 9-10, 10-11, 11-12. 82 base::BucketRanges ranges(8); 83 ranges.set_range(0, 1); 84 ranges.set_range(1, 5); 85 ranges.set_range(2, 7); 86 ranges.set_range(3, 8); 87 ranges.set_range(4, 9); 88 ranges.set_range(5, 10); 89 ranges.set_range(6, 11); 90 ranges.set_range(7, 12); 91 92 base::SampleVector samples(&ranges); 93 samples.Accumulate(3, 1); // Bucket 1-5. 94 samples.Accumulate(6, 1); // Bucket 5-7. 95 samples.Accumulate(8, 1); // Bucket 8-9. (7-8 skipped) 96 samples.Accumulate(10, 1); // Bucket 10-11. (9-10 skipped) 97 samples.Accumulate(11, 1); // Bucket 11-12. 98 99 TestMetricsLogBase log; 100 log.RecordHistogramDelta("Test", samples); 101 102 const metrics::ChromeUserMetricsExtension* uma_proto = log.uma_proto(); 103 const metrics::HistogramEventProto& histogram_proto = 104 uma_proto->histogram_event(uma_proto->histogram_event_size() - 1); 105 106 // Buckets with samples: 1-5, 5-7, 8-9, 10-11, 11-12. 107 // Should become: 1-/, 5-7, /-9, 10-/, /-12. 108 ASSERT_EQ(5, histogram_proto.bucket_size()); 109 110 // 1-5 becomes 1-/ (max is same as next min). 111 EXPECT_TRUE(histogram_proto.bucket(0).has_min()); 112 EXPECT_FALSE(histogram_proto.bucket(0).has_max()); 113 EXPECT_EQ(1, histogram_proto.bucket(0).min()); 114 115 // 5-7 stays 5-7 (no optimization possible). 116 EXPECT_TRUE(histogram_proto.bucket(1).has_min()); 117 EXPECT_TRUE(histogram_proto.bucket(1).has_max()); 118 EXPECT_EQ(5, histogram_proto.bucket(1).min()); 119 EXPECT_EQ(7, histogram_proto.bucket(1).max()); 120 121 // 8-9 becomes /-9 (min is same as max - 1). 122 EXPECT_FALSE(histogram_proto.bucket(2).has_min()); 123 EXPECT_TRUE(histogram_proto.bucket(2).has_max()); 124 EXPECT_EQ(9, histogram_proto.bucket(2).max()); 125 126 // 10-11 becomes 10-/ (both optimizations apply, omit max is prioritized). 127 EXPECT_TRUE(histogram_proto.bucket(3).has_min()); 128 EXPECT_FALSE(histogram_proto.bucket(3).has_max()); 129 EXPECT_EQ(10, histogram_proto.bucket(3).min()); 130 131 // 11-12 becomes /-12 (last record must keep max, min is same as max - 1). 132 EXPECT_FALSE(histogram_proto.bucket(4).has_min()); 133 EXPECT_TRUE(histogram_proto.bucket(4).has_max()); 134 EXPECT_EQ(12, histogram_proto.bucket(4).max()); 135 } 136 137 } // namespace metrics 138