// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include #include #include #include #include namespace metrics { struct SnapshotTest : public CppUnit::TestFixture { void testSnapshotTwoDays(); CPPUNIT_TEST_SUITE(SnapshotTest); CPPUNIT_TEST(testSnapshotTwoDays); CPPUNIT_TEST_SUITE_END(); }; CPPUNIT_TEST_SUITE_REGISTRATION(SnapshotTest); namespace { struct SubSubMetricSet : public MetricSet { const LoadTypeSet& loadTypes; int incVal; LongCountMetric count1; LongCountMetric count2; LoadMetric loadCount; SumMetric countSum; DoubleValueMetric value1; DoubleValueMetric value2; LoadMetric loadValue; SumMetric valueSum; DoubleAverageMetric average1; DoubleAverageMetric average2; LoadMetric loadAverage; SumMetric averageSum; SubSubMetricSet(vespalib::stringref name, const LoadTypeSet& loadTypes_, MetricSet* owner = 0); ~SubSubMetricSet(); MetricSet* clone(std::vector &ownerList, CopyType copyType, metrics::MetricSet* owner, bool includeUnused) const override; void incValues(); }; SubSubMetricSet::SubSubMetricSet(vespalib::stringref name, const LoadTypeSet& loadTypes_, MetricSet* owner) : MetricSet(name, "", "", owner), loadTypes(loadTypes_), incVal(1), count1("count1", "", "", this), count2("count2", "", "", this), loadCount(loadTypes, LongCountMetric("loadCount", "", ""), this), countSum("countSum", "", "", this), value1("value1", "", "", this), value2("value2", "", "", this), loadValue(loadTypes, DoubleValueMetric("loadValue", "", ""), this), valueSum("valueSum", "", "", this), average1("average1", "", "", this), average2("average2", "", "", this), loadAverage(loadTypes, DoubleAverageMetric("loadAverage", "", ""), this), averageSum("averageSum", "", "", this) { countSum.addMetricToSum(count1); countSum.addMetricToSum(count2); valueSum.addMetricToSum(value1); valueSum.addMetricToSum(value2); averageSum.addMetricToSum(average1); averageSum.addMetricToSum(average2); } SubSubMetricSet::~SubSubMetricSet() = default; MetricSet* SubSubMetricSet::clone(std::vector &ownerList, CopyType copyType, metrics::MetricSet* owner, bool includeUnused) const { if (copyType == INACTIVE) { return MetricSet::clone(ownerList, INACTIVE, owner, includeUnused); } return (SubSubMetricSet*) (new SubSubMetricSet( getName(), loadTypes, owner)) ->assignValues(*this); } void SubSubMetricSet::incValues() { count1.inc(incVal); count2.inc(incVal); for (uint32_t i=0; i loadSet; SumMetric setSum; SubMetricSet(vespalib::stringref name, const LoadTypeSet& loadTypes_, MetricSet* owner = 0); ~SubMetricSet(); MetricSet* clone(std::vector &ownerList, CopyType copyType, metrics::MetricSet* owner, bool includeUnused) const override; void incValues(); }; SubMetricSet::SubMetricSet(vespalib::stringref name, const LoadTypeSet& loadTypes_, MetricSet* owner) : MetricSet(name, "", "", owner), loadTypes(loadTypes_), set1("set1", loadTypes, this), set2("set2", loadTypes, this), loadSet(loadTypes, *std::unique_ptr(new SubSubMetricSet("loadSet", loadTypes)), this), setSum("setSum", "", "", this) { setSum.addMetricToSum(set1); setSum.addMetricToSum(set2); } SubMetricSet::~SubMetricSet() = default; MetricSet* SubMetricSet::clone(std::vector &ownerList, CopyType copyType, metrics::MetricSet* owner, bool includeUnused) const { if (copyType == INACTIVE) { return MetricSet::clone(ownerList, INACTIVE, owner, includeUnused); } return (SubMetricSet*) (new SubMetricSet(getName(), loadTypes, owner)) ->assignValues(*this); } void SubMetricSet::incValues() { set1.incValues(); set2.incValues(); for (uint32_t i=0; i loadSet; SumMetric setSum; TestMetricSet(vespalib::stringref name, const LoadTypeSet& loadTypes_, MetricSet* owner = 0); ~TestMetricSet(); void incValues(); }; TestMetricSet::TestMetricSet(vespalib::stringref name, const LoadTypeSet& loadTypes_, MetricSet* owner) : MetricSet(name, "", "", owner), loadTypes(loadTypes_), set1("set1", loadTypes, this), set2("set2", loadTypes, this), loadSet(loadTypes, *std::unique_ptr(new SubMetricSet("loadSet", loadTypes)), this), setSum("setSum", "", "", this) { setSum.addMetricToSum(set1); setSum.addMetricToSum(set2); } TestMetricSet::~TestMetricSet() = default; void TestMetricSet::incValues() { set1.incValues(); set2.incValues(); for (uint32_t i=0; igetLongValue("value"))); } void SnapshotTest::testSnapshotTwoDays() { // Create load types LoadTypeSet loadTypes; loadTypes.push_back(LoadType(1, "foo")); loadTypes.push_back(LoadType(2, "bar")); TestMetricSet set("test", loadTypes); FakeTimer* timer; FastOS_ThreadPool threadPool(256 * 1024); MetricManager mm( std::unique_ptr(timer = new FakeTimer)); { MetricLockGuard lockGuard(mm.getMetricLock()); mm.registerMetric(lockGuard, set); } mm.init("raw:consumer[1]\n" "consumer[0].name \"log\"", threadPool, false); mm.tick(mm.getMetricLock(), timer->_timeInSecs * 1000); for (uint32_t days=0; days<2; ++days) { for (uint32_t hour=0; hour<24; ++hour) { for (uint32_t fiveMin=0; fiveMin<12; ++fiveMin) { set.incValues(); timer->_timeInSecs += 5 * 60; mm.tick(mm.getMetricLock(), timer->_timeInSecs * 1000); } } } // Print all data. Useful for debugging. It's too much to verify // everything, so test will just verify some parts. Add more parts if you // find a failure. /* std::string regex = ".*"; bool verbose = true; std::cout << "\n" << mm.getActiveMetrics().toString(mm, "", regex, verbose) << "\n\n"; std::vector periods(mm.getSnapshotPeriods()); for (uint32_t i=0; i