|
| 1 | +/* |
| 2 | + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one |
| 3 | + * or more contributor license agreements. Licensed under the Elastic License; |
| 4 | + * you may not use this file except in compliance with the Elastic License. |
| 5 | + */ |
| 6 | + |
| 7 | +#include "CExpandingWindowTest.h" |
| 8 | + |
| 9 | +#include <core/CContainerPrinter.h> |
| 10 | +#include <core/CLogger.h> |
| 11 | +#include <core/CRapidXmlStatePersistInserter.h> |
| 12 | +#include <core/CRapidXmlStateRestoreTraverser.h> |
| 13 | +#include <core/Constants.h> |
| 14 | + |
| 15 | +#include <maths/CBasicStatistics.h> |
| 16 | +#include <maths/CExpandingWindow.h> |
| 17 | + |
| 18 | +#include <test/CRandomNumbers.h> |
| 19 | + |
| 20 | +#include <boost/math/constants/constants.hpp> |
| 21 | + |
| 22 | +#include <vector> |
| 23 | + |
| 24 | +using namespace ml; |
| 25 | + |
| 26 | +namespace { |
| 27 | +using TDoubleVec = std::vector<double>; |
| 28 | +using TTimeVec = std::vector<core_t::TTime>; |
| 29 | +using TTimeCRng = core::CVectorRange<const TTimeVec>; |
| 30 | +using TFloatMeanAccumulator = |
| 31 | + maths::CBasicStatistics::SSampleMean<maths::CFloatStorage>::TAccumulator; |
| 32 | +using TFloatMeanAccumulatorVec = std::vector<TFloatMeanAccumulator>; |
| 33 | + |
| 34 | +TTimeVec BUCKET_LENGTHS{300, 600, 1800, 3600}; |
| 35 | +} |
| 36 | + |
| 37 | +void CExpandingWindowTest::testPersistence() { |
| 38 | + // Test persist and restore is idempotent. |
| 39 | + |
| 40 | + core_t::TTime bucketLength{300}; |
| 41 | + std::size_t size{336}; |
| 42 | + double decayRate{0.01}; |
| 43 | + |
| 44 | + test::CRandomNumbers rng; |
| 45 | + |
| 46 | + maths::CExpandingWindow origWindow{bucketLength, TTimeCRng{BUCKET_LENGTHS, 0, 4}, |
| 47 | + size, decayRate}; |
| 48 | + |
| 49 | + TDoubleVec values; |
| 50 | + rng.generateUniformSamples(0.0, 10.0, size, values); |
| 51 | + for (core_t::TTime time = 0; time < static_cast<core_t::TTime>(size) * bucketLength; |
| 52 | + time += bucketLength) { |
| 53 | + double value{values[time / bucketLength]}; |
| 54 | + origWindow.add(time, value); |
| 55 | + } |
| 56 | + |
| 57 | + std::string origXml; |
| 58 | + { |
| 59 | + core::CRapidXmlStatePersistInserter inserter("root"); |
| 60 | + origWindow.acceptPersistInserter(inserter); |
| 61 | + inserter.toXml(origXml); |
| 62 | + } |
| 63 | + LOG_TRACE(<< "Window XML = " << origXml); |
| 64 | + LOG_DEBUG(<< "Window XML size = " << origXml.size()); |
| 65 | + |
| 66 | + // Restore the XML into a new window. |
| 67 | + { |
| 68 | + core::CRapidXmlParser parser; |
| 69 | + CPPUNIT_ASSERT(parser.parseStringIgnoreCdata(origXml)); |
| 70 | + core::CRapidXmlStateRestoreTraverser traverser(parser); |
| 71 | + maths::CExpandingWindow restoredWindow{ |
| 72 | + bucketLength, TTimeCRng{BUCKET_LENGTHS, 0, 4}, size, decayRate}; |
| 73 | + CPPUNIT_ASSERT_EQUAL( |
| 74 | + true, traverser.traverseSubLevel(boost::bind(&maths::CExpandingWindow::acceptRestoreTraverser, |
| 75 | + &restoredWindow, _1))); |
| 76 | + |
| 77 | + LOG_DEBUG(<< "orig checksum = " << origWindow.checksum() |
| 78 | + << ", new checksum = " << restoredWindow.checksum()); |
| 79 | + CPPUNIT_ASSERT_EQUAL(origWindow.checksum(), restoredWindow.checksum()); |
| 80 | + } |
| 81 | +} |
| 82 | + |
| 83 | +CppUnit::Test* CExpandingWindowTest::suite() { |
| 84 | + CppUnit::TestSuite* suiteOfTests = new CppUnit::TestSuite("CExpandingWindowTest"); |
| 85 | + |
| 86 | + suiteOfTests->addTest(new CppUnit::TestCaller<CExpandingWindowTest>( |
| 87 | + "CExpandingWindowTest::testPersistence", &CExpandingWindowTest::testPersistence)); |
| 88 | + |
| 89 | + return suiteOfTests; |
| 90 | +} |
0 commit comments