| OLD | NEW |
| (Empty) |
| 1 // Copyright 2006-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 // | |
| 16 // metrics report unit testing | |
| 17 #include "omaha/third_party/gtest/include/gtest/gtest.h" | |
| 18 #include "metrics.h" | |
| 19 #include <algorithm> | |
| 20 #include <new> | |
| 21 | |
| 22 DECLARE_METRIC_count(count); | |
| 23 DEFINE_METRIC_count(count); | |
| 24 | |
| 25 DECLARE_METRIC_timing(timing); | |
| 26 DEFINE_METRIC_timing(timing); | |
| 27 | |
| 28 DECLARE_METRIC_integer(integer); | |
| 29 DEFINE_METRIC_integer(integer); | |
| 30 | |
| 31 DECLARE_METRIC_bool(bool); | |
| 32 DEFINE_METRIC_bool(bool); | |
| 33 | |
| 34 using namespace stats_report; | |
| 35 | |
| 36 namespace { | |
| 37 | |
| 38 class MetricsTest: public testing::Test { | |
| 39 protected: | |
| 40 MetricCollection coll_; | |
| 41 }; | |
| 42 | |
| 43 class MetricsEnumTest: public MetricsTest { | |
| 44 public: | |
| 45 virtual void SetUp() { | |
| 46 coll_.Initialize(); | |
| 47 } | |
| 48 | |
| 49 virtual void TearDown() { | |
| 50 coll_.Uninitialize(); | |
| 51 } | |
| 52 | |
| 53 protected: | |
| 54 MetricsEnumTest(): count_("count", &coll_), timing_("timing", &coll_), | |
| 55 integer_("integer", &coll_), bool_("bool", &coll_){ | |
| 56 } | |
| 57 | |
| 58 CountMetric count_; | |
| 59 TimingMetric timing_; | |
| 60 IntegerMetric integer_; | |
| 61 BoolMetric bool_; | |
| 62 }; | |
| 63 | |
| 64 } // namespace | |
| 65 | |
| 66 // Validates that the above-declared metrics are available | |
| 67 // in the expected namespace | |
| 68 TEST_F(MetricsTest, Globals) { | |
| 69 EXPECT_EQ(0, ::metric_count.Reset()); | |
| 70 TimingMetric::TimingData data = ::metric_timing.Reset(); | |
| 71 EXPECT_EQ(0, data.count); | |
| 72 EXPECT_EQ(0, data.maximum); | |
| 73 EXPECT_EQ(0, data.minimum); | |
| 74 EXPECT_EQ(0, data.sum); | |
| 75 | |
| 76 EXPECT_EQ(0, ::metric_integer.value()); | |
| 77 EXPECT_EQ(BoolMetric::kBoolUnset, ::metric_bool.Reset()); | |
| 78 | |
| 79 // Check for correct initialization | |
| 80 EXPECT_STREQ("count", metric_count.name()); | |
| 81 EXPECT_STREQ("timing", metric_timing.name()); | |
| 82 EXPECT_STREQ("integer", metric_integer.name()); | |
| 83 EXPECT_STREQ("bool", metric_bool.name()); | |
| 84 } | |
| 85 | |
| 86 | |
| 87 // make GTest happy | |
| 88 inline std::ostream &operator << (std::ostream &str, const MetricIterator &it) { | |
| 89 str << std::hex << (void*)*it; | |
| 90 return str; | |
| 91 } | |
| 92 | |
| 93 TEST_F(MetricsTest, CollectionInitialization) { | |
| 94 // The global MetricCollection is aliased to zero memory so as to ensure | |
| 95 // no initialization order snafus. If an initialized MetricCollection | |
| 96 // sets any of its storage to non-zero, there's a good chance that e.g. a | |
| 97 // vtbl has snuck in there, which must not happen | |
| 98 char buf1[sizeof(MetricCollection)] = { 0 }; | |
| 99 char buf2[sizeof(MetricCollection)] = { 0 }; | |
| 100 | |
| 101 // Placement new a MetricCollection to one of the buffers | |
| 102 new (buf1) MetricCollection(); | |
| 103 | |
| 104 // and check they're still equivalent | |
| 105 EXPECT_EQ(0, memcmp(buf1, buf2, sizeof(MetricCollection))); | |
| 106 | |
| 107 // MetricCollection must not extend MetricCollectionBase in size | |
| 108 EXPECT_EQ(sizeof(MetricCollection), sizeof(MetricCollectionBase)); | |
| 109 } | |
| 110 | |
| 111 TEST_F(MetricsTest, Count) { | |
| 112 CountMetric foo("foo", &coll_); | |
| 113 | |
| 114 EXPECT_EQ(0, foo.Reset()); | |
| 115 EXPECT_EQ(kCountType, foo.type()); | |
| 116 CountMetric &foo_ref = foo.AsCount(); | |
| 117 | |
| 118 ++foo; | |
| 119 EXPECT_EQ(1, foo.value()); | |
| 120 foo++; | |
| 121 EXPECT_EQ(2, foo.value()); | |
| 122 | |
| 123 foo += 100; | |
| 124 EXPECT_EQ(102, foo.value()); | |
| 125 } | |
| 126 | |
| 127 TEST_F(MetricsTest, Timing) { | |
| 128 TimingMetric foo("foo", &coll_); | |
| 129 | |
| 130 EXPECT_EQ(kTimingType, foo.type()); | |
| 131 TimingMetric &foo_ref = foo.AsTiming(); | |
| 132 | |
| 133 foo.AddSample(100); | |
| 134 foo.AddSample(50); | |
| 135 | |
| 136 EXPECT_EQ(2, foo.count()); | |
| 137 EXPECT_EQ(150, foo.sum()); | |
| 138 EXPECT_EQ(100, foo.maximum()); | |
| 139 EXPECT_EQ(50, foo.minimum()); | |
| 140 EXPECT_EQ(75, foo.average()); | |
| 141 | |
| 142 TimingMetric::TimingData data = foo.Reset(); | |
| 143 EXPECT_EQ(2, data.count); | |
| 144 EXPECT_EQ(150, data.sum); | |
| 145 EXPECT_EQ(100, data.maximum); | |
| 146 EXPECT_EQ(50, data.minimum); | |
| 147 | |
| 148 EXPECT_EQ(0, foo.count()); | |
| 149 EXPECT_EQ(0, foo.sum()); | |
| 150 EXPECT_EQ(0, foo.maximum()); | |
| 151 EXPECT_EQ(0, foo.minimum()); | |
| 152 EXPECT_EQ(0, foo.average()); | |
| 153 | |
| 154 // Test counted samples | |
| 155 foo.AddSamples(10, 1000); | |
| 156 foo.AddSamples(10, 500); | |
| 157 EXPECT_EQ(20, foo.count()); | |
| 158 EXPECT_EQ(1500, foo.sum()); | |
| 159 EXPECT_EQ(100, foo.maximum()); | |
| 160 EXPECT_EQ(50, foo.minimum()); | |
| 161 EXPECT_EQ(75, foo.average()); | |
| 162 } | |
| 163 | |
| 164 TEST_F(MetricsTest, TimingSample) { | |
| 165 TimingMetric foo("foo", &coll_); | |
| 166 | |
| 167 // add a sample to foo | |
| 168 { | |
| 169 TimingSample sample(foo); | |
| 170 | |
| 171 ::Sleep(30); | |
| 172 } | |
| 173 | |
| 174 TimingMetric::TimingData data = foo.Reset(); | |
| 175 | |
| 176 // Should be precisely one sample in there | |
| 177 EXPECT_EQ(1, data.count); | |
| 178 | |
| 179 // Let's hope the scheduler doesn't leave us hanging more than 10 ms. | |
| 180 // Increased time from 40 to 100 because test failed intermittently on Pulse. | |
| 181 EXPECT_GE(30 + 70, data.sum); | |
| 182 // The sleep above seems to often terminate early on the build server, | |
| 183 // I've observed captured times down to 18 ms, which is strange. | |
| 184 // TODO(omaha): figure out whether the timer is broken or whether | |
| 185 // sleep is breaking its promise, or whether e.g. we're getting different | |
| 186 // walltimes on different CPUs due to BIOS bugs on the build server | |
| 187 EXPECT_LE(14, data.sum); | |
| 188 | |
| 189 // again, this time with a non-unity count | |
| 190 { | |
| 191 TimingSample sample(foo, 2); | |
| 192 | |
| 193 EXPECT_EQ(2, sample.count()); | |
| 194 ::Sleep(30); | |
| 195 } | |
| 196 | |
| 197 data = foo.Reset(); | |
| 198 | |
| 199 // Should be precisely two samples in there | |
| 200 EXPECT_EQ(2, data.count); | |
| 201 | |
| 202 // Let's hope the scheduler doesn't leave us hanging more than 10 ms. | |
| 203 // Increased time from 40 to 100 because test failed intermittently on Pulse. | |
| 204 EXPECT_GE(30 + 70, data.sum); | |
| 205 EXPECT_LE(14, data.sum); | |
| 206 | |
| 207 // now with zero count | |
| 208 { | |
| 209 TimingSample sample(foo, 0); | |
| 210 } | |
| 211 | |
| 212 data = foo.Reset(); | |
| 213 | |
| 214 // Should be no samples in there | |
| 215 EXPECT_EQ(0, data.count); | |
| 216 } | |
| 217 | |
| 218 TEST_F(MetricsTest, Integer) { | |
| 219 IntegerMetric foo("foo", &coll_); | |
| 220 | |
| 221 EXPECT_EQ(kIntegerType, foo.type()); | |
| 222 IntegerMetric &foo_ref = foo.AsInteger(); | |
| 223 | |
| 224 EXPECT_EQ(0, foo.value()); | |
| 225 foo.Set(1005); | |
| 226 EXPECT_EQ(1005, foo.value()); | |
| 227 foo = 1009UL; | |
| 228 EXPECT_EQ(1009, foo.value()); | |
| 229 | |
| 230 foo.Set(0); | |
| 231 | |
| 232 ++foo; | |
| 233 EXPECT_EQ(1, foo.value()); | |
| 234 foo++; | |
| 235 EXPECT_EQ(2, foo.value()); | |
| 236 | |
| 237 foo += 100; | |
| 238 EXPECT_EQ(102, foo.value()); | |
| 239 | |
| 240 foo -= 100; | |
| 241 EXPECT_EQ(2, foo.value()); | |
| 242 foo--; | |
| 243 EXPECT_EQ(1, foo.value()); | |
| 244 --foo; | |
| 245 EXPECT_EQ(0, foo.value()); | |
| 246 } | |
| 247 | |
| 248 TEST_F(MetricsTest, Bool) { | |
| 249 BoolMetric foo("foo", &coll_); | |
| 250 | |
| 251 EXPECT_EQ(kBoolType, foo.type()); | |
| 252 BoolMetric &foo_ref = foo.AsBool(); | |
| 253 | |
| 254 EXPECT_EQ(BoolMetric::kBoolUnset, foo.Reset()); | |
| 255 foo.Set(true); | |
| 256 EXPECT_EQ(BoolMetric::kBoolTrue, foo.Reset()); | |
| 257 foo.Set(false); | |
| 258 EXPECT_EQ(BoolMetric::kBoolFalse, foo.Reset()); | |
| 259 EXPECT_EQ(BoolMetric::kBoolUnset, foo.Reset()); | |
| 260 } | |
| 261 | |
| 262 TEST_F(MetricsEnumTest, Enumeration) { | |
| 263 MetricBase *metrics[] = { | |
| 264 &count_, | |
| 265 &timing_, | |
| 266 &integer_, | |
| 267 &bool_, | |
| 268 }; | |
| 269 | |
| 270 for (int i = 0; i < sizeof(metrics) / sizeof(metrics[0]); ++i) { | |
| 271 MetricBase *stat = metrics[i]; | |
| 272 MetricBase *curr = coll_.first(); | |
| 273 | |
| 274 for (; NULL != curr; curr = curr->next()) { | |
| 275 if (stat == curr) | |
| 276 break; | |
| 277 } | |
| 278 | |
| 279 // if NULL, we didn't find our counter | |
| 280 EXPECT_TRUE(NULL != curr); | |
| 281 } | |
| 282 } | |
| 283 | |
| 284 TEST_F(MetricsEnumTest, Iterator) { | |
| 285 typedef MetricBase *MetricBasePtr; | |
| 286 MetricBasePtr metrics[] = { &count_, &timing_, &integer_, &bool_, }; | |
| 287 int num_stats = sizeof(metrics) / sizeof(metrics[0]); | |
| 288 | |
| 289 MetricIterator it(coll_), end; | |
| 290 EXPECT_NE(it, end); | |
| 291 | |
| 292 // copy construction | |
| 293 EXPECT_EQ(it, MetricIterator(it)); | |
| 294 EXPECT_EQ(end, MetricIterator(end)); | |
| 295 | |
| 296 // # of iterations | |
| 297 int i = 0; | |
| 298 while (it++ != end) | |
| 299 ++i; | |
| 300 DCHECK_EQ(i, num_stats); | |
| 301 DCHECK_EQ(it, end); | |
| 302 | |
| 303 // increment past end is idempotent | |
| 304 ++it; | |
| 305 DCHECK_EQ(it, end); | |
| 306 | |
| 307 // Check that we return no garbage or nonsense | |
| 308 for (it = MetricIterator(coll_); it != end; ++it) { | |
| 309 MetricBasePtr *stats_end = &metrics[num_stats]; | |
| 310 EXPECT_NE(stats_end, std::find(metrics, stats_end, *it)); | |
| 311 } | |
| 312 | |
| 313 // and that all metrics can be found | |
| 314 for (int i = 0; i < sizeof(metrics) / sizeof(metrics[0]); ++i) { | |
| 315 MetricBase *stat = metrics[i]; | |
| 316 | |
| 317 EXPECT_EQ(stat, *std::find(MetricIterator(coll_), end, stat)); | |
| 318 } | |
| 319 } | |
| 320 | |
| 321 TEST_F(MetricsTest, SimpleConstruction) { | |
| 322 const CountMetric c("c", 100); | |
| 323 | |
| 324 EXPECT_EQ(100, c.value()); | |
| 325 EXPECT_EQ(kCountType, c.type()); | |
| 326 EXPECT_STREQ("c", c.name()); | |
| 327 EXPECT_TRUE(NULL == c.next()); | |
| 328 | |
| 329 TimingMetric::TimingData data = { 10, 0, 1000, 10, 500 }; | |
| 330 const TimingMetric t("t", data); | |
| 331 | |
| 332 EXPECT_EQ(10, t.count()); | |
| 333 EXPECT_EQ(1000, t.sum()); | |
| 334 EXPECT_EQ(10, t.minimum()); | |
| 335 EXPECT_EQ(500, t.maximum()); | |
| 336 EXPECT_EQ(kTimingType, t.type()); | |
| 337 EXPECT_STREQ("t", t.name()); | |
| 338 EXPECT_TRUE(NULL == t.next()); | |
| 339 | |
| 340 const IntegerMetric i("i", 200); | |
| 341 | |
| 342 EXPECT_EQ(200, i.value()); | |
| 343 EXPECT_EQ(kIntegerType, i.type()); | |
| 344 EXPECT_STREQ("i", i.name()); | |
| 345 EXPECT_TRUE(NULL == i.next()); | |
| 346 | |
| 347 const BoolMetric bool_true("bool_true", BoolMetric::kBoolTrue); | |
| 348 | |
| 349 EXPECT_EQ(BoolMetric::kBoolTrue, bool_true.value()); | |
| 350 EXPECT_EQ(kBoolType, bool_true.type()); | |
| 351 EXPECT_STREQ("bool_true", bool_true.name()); | |
| 352 EXPECT_TRUE(NULL == bool_true.next()); | |
| 353 | |
| 354 const BoolMetric bool_false("bool_false", BoolMetric::kBoolFalse); | |
| 355 | |
| 356 EXPECT_EQ(BoolMetric::kBoolFalse, bool_false.value()); | |
| 357 EXPECT_EQ(kBoolType, bool_false.type()); | |
| 358 EXPECT_STREQ("bool_false", bool_false.name()); | |
| 359 EXPECT_TRUE(NULL == bool_false.next()); | |
| 360 } | |
| 361 | |
| OLD | NEW |