Rewrote MovingPercentileTests

(hope someone uses this...)
This commit is contained in:
Seiji Emery 2015-06-24 14:46:01 -07:00
parent 735c4a7dcf
commit 00900d6906
2 changed files with 280 additions and 143 deletions

View file

@ -14,158 +14,287 @@
#include "SharedUtil.h"
#include "MovingPercentile.h"
#include <limits>
#include <qqueue.h>
QTEST_MAIN(MovingPercentileTests)
//
// THIS IS HOW YOU WRITE UNIT TESTS
//
// Defines the test values we use for n:
static const QVector<int> testValues { 1, 2, 3, 4, 5, 10, 100 };
void MovingPercentileTests::testRunningMin() {
for (auto n : testValues)
testRunningMinForN(n);
}
void MovingPercentileTests::testRunningMax() {
for (auto n : testValues)
testRunningMaxForN(n);
}
void MovingPercentileTests::testRunningMedian() {
for (auto n : testValues)
testRunningMedianForN(n);
}
float MovingPercentileTests::random() {
return rand() / (float)RAND_MAX;
}
void MovingPercentileTests::runAllTests() {
QVector<int> valuesForN;
void MovingPercentileTests::testRunningMinForN (int n) {
valuesForN.append(1);
valuesForN.append(2);
valuesForN.append(3);
valuesForN.append(4);
valuesForN.append(5);
valuesForN.append(10);
valuesForN.append(100);
QQueue<float> lastNSamples;
for (int i=0; i<valuesForN.size(); i++) {
int N = valuesForN.at(i);
qDebug() << "testing moving percentile with N =" << N << "...";
{
bool fail = false;
qDebug() << "\t testing running min...";
lastNSamples.clear();
MovingPercentile movingMin(N, 0.0f);
for (int s = 0; s < 3*N; s++) {
float sample = random();
lastNSamples.push_back(sample);
if (lastNSamples.size() > N) {
lastNSamples.pop_front();
}
movingMin.updatePercentile(sample);
float experimentMin = movingMin.getValueAtPercentile();
float actualMin = lastNSamples[0];
for (int j = 0; j < lastNSamples.size(); j++) {
if (lastNSamples.at(j) < actualMin) {
actualMin = lastNSamples.at(j);
}
}
if (experimentMin != actualMin) {
qDebug() << "\t\t FAIL at sample" << s;
fail = true;
break;
}
}
if (!fail) {
qDebug() << "\t\t PASS";
}
}
{
bool fail = false;
qDebug() << "\t testing running max...";
lastNSamples.clear();
MovingPercentile movingMax(N, 1.0f);
for (int s = 0; s < 10000; s++) {
float sample = random();
lastNSamples.push_back(sample);
if (lastNSamples.size() > N) {
lastNSamples.pop_front();
}
movingMax.updatePercentile(sample);
float experimentMax = movingMax.getValueAtPercentile();
float actualMax = lastNSamples[0];
for (int j = 0; j < lastNSamples.size(); j++) {
if (lastNSamples.at(j) > actualMax) {
actualMax = lastNSamples.at(j);
}
}
if (experimentMax != actualMax) {
qDebug() << "\t\t FAIL at sample" << s;
fail = true;
break;
}
}
if (!fail) {
qDebug() << "\t\t PASS";
}
}
{
bool fail = false;
qDebug() << "\t testing running median...";
lastNSamples.clear();
MovingPercentile movingMedian(N, 0.5f);
for (int s = 0; s < 10000; s++) {
float sample = random();
lastNSamples.push_back(sample);
if (lastNSamples.size() > N) {
lastNSamples.pop_front();
}
movingMedian.updatePercentile(sample);
float experimentMedian = movingMedian.getValueAtPercentile();
int samplesLessThan = 0;
int samplesMoreThan = 0;
for (int j=0; j<lastNSamples.size(); j++) {
if (lastNSamples.at(j) < experimentMedian) {
samplesLessThan++;
} else if (lastNSamples.at(j) > experimentMedian) {
samplesMoreThan++;
}
}
if (!(samplesLessThan <= N/2 && samplesMoreThan <= N-1/2)) {
qDebug() << "\t\t FAIL at sample" << s;
fail = true;
break;
}
}
if (!fail) {
qDebug() << "\t\t PASS";
}
// Stores the last n samples
QQueue<float> samples;
MovingPercentile movingMin (n, 0.0f);
for (int s = 0; s < 3 * n; ++s) {
float sample = random();
samples.push_back(sample);
if (samples.size() > n)
samples.pop_front();
if (samples.size() == 0) {
QFAIL_WITH_MESSAGE("\n\n\n\tWTF\n\tsamples.size() = " << samples.size() << ", n = " << n);
}
movingMin.updatePercentile(sample);
// Calculate the minimum of the moving samples
float expectedMin = std::numeric_limits<float>::max();
int prevSize = samples.size();
for (auto val : samples)
expectedMin = std::min(val, expectedMin);
QCOMPARE(samples.size(), prevSize);
QCOMPARE(movingMin.getValueAtPercentile(), expectedMin);
}
}
void MovingPercentileTests::testRunningMaxForN (int n) {
// Stores the last n samples
QQueue<float> samples;
MovingPercentile movingMax (n, 1.0f);
for (int s = 0; s < 10000; ++s) {
float sample = random();
samples.push_back(sample);
if (samples.size() > n)
samples.pop_front();
if (samples.size() == 0) {
QFAIL_WITH_MESSAGE("\n\n\n\tWTF\n\tsamples.size() = " << samples.size() << ", n = " << n);
}
movingMax.updatePercentile(sample);
// Calculate the maximum of the moving samples
float expectedMax = std::numeric_limits<float>::min();
for (auto val : samples)
expectedMax = std::max(val, expectedMax);
QCOMPARE(movingMax.getValueAtPercentile(), expectedMax);
}
}
void MovingPercentileTests::testRunningMedianForN (int n) {
// Stores the last n samples
QQueue<float> samples;
MovingPercentile movingMedian (n, 0.5f);
for (int s = 0; s < 10000; ++s) {
float sample = random();
samples.push_back(sample);
if (samples.size() > n)
samples.pop_front();
if (samples.size() == 0) {
QFAIL_WITH_MESSAGE("\n\n\n\tWTF\n\tsamples.size() = " << samples.size() << ", n = " << n);
}
movingMedian.updatePercentile(sample);
auto median = movingMedian.getValueAtPercentile();
// Check the number of samples that are > or < median
int samplesGreaterThan = 0;
int samplesLessThan = 0;
for (auto value : samples) {
if (value < median)
++samplesGreaterThan;
else if (value > median)
++samplesLessThan;
}
QCOMPARE_WITH_LAMBDA(samplesLessThan, n / 2, [=]() {
return samplesLessThan <= n / 2;
});
QCOMPARE_WITH_LAMBDA(samplesGreaterThan, (n - 1) / 2, [=]() {
return samplesGreaterThan <= n / 2;
});
}
}
//
// NOT THIS:
//
//void MovingPercentileTests::runAllTests() {
//
// QVector<int> valuesForN;
//
// valuesForN.append(1);
// valuesForN.append(2);
// valuesForN.append(3);
// valuesForN.append(4);
// valuesForN.append(5);
// valuesForN.append(10);
// valuesForN.append(100);
//
//
// QQueue<float> lastNSamples;
//
// for (int i=0; i<valuesForN.size(); i++) {
//
// int N = valuesForN.at(i);
//
// qDebug() << "testing moving percentile with N =" << N << "...";
//
// {
// bool fail = false;
//
// qDebug() << "\t testing running min...";
//
// lastNSamples.clear();
// MovingPercentile movingMin(N, 0.0f);
//
// for (int s = 0; s < 3*N; s++) {
//
// float sample = random();
//
// lastNSamples.push_back(sample);
// if (lastNSamples.size() > N) {
// lastNSamples.pop_front();
// }
//
// movingMin.updatePercentile(sample);
//
// float experimentMin = movingMin.getValueAtPercentile();
//
// float actualMin = lastNSamples[0];
// for (int j = 0; j < lastNSamples.size(); j++) {
// if (lastNSamples.at(j) < actualMin) {
// actualMin = lastNSamples.at(j);
// }
// }
//
// if (experimentMin != actualMin) {
// qDebug() << "\t\t FAIL at sample" << s;
// fail = true;
// break;
// }
// }
// if (!fail) {
// qDebug() << "\t\t PASS";
// }
// }
//
//
// {
// bool fail = false;
//
// qDebug() << "\t testing running max...";
//
// lastNSamples.clear();
// MovingPercentile movingMax(N, 1.0f);
//
// for (int s = 0; s < 10000; s++) {
//
// float sample = random();
//
// lastNSamples.push_back(sample);
// if (lastNSamples.size() > N) {
// lastNSamples.pop_front();
// }
//
// movingMax.updatePercentile(sample);
//
// float experimentMax = movingMax.getValueAtPercentile();
//
// float actualMax = lastNSamples[0];
// for (int j = 0; j < lastNSamples.size(); j++) {
// if (lastNSamples.at(j) > actualMax) {
// actualMax = lastNSamples.at(j);
// }
// }
//
// if (experimentMax != actualMax) {
// qDebug() << "\t\t FAIL at sample" << s;
// fail = true;
// break;
// }
// }
// if (!fail) {
// qDebug() << "\t\t PASS";
// }
// }
//
//
// {
// bool fail = false;
//
// qDebug() << "\t testing running median...";
//
// lastNSamples.clear();
// MovingPercentile movingMedian(N, 0.5f);
//
// for (int s = 0; s < 10000; s++) {
//
// float sample = random();
//
// lastNSamples.push_back(sample);
// if (lastNSamples.size() > N) {
// lastNSamples.pop_front();
// }
//
// movingMedian.updatePercentile(sample);
//
// float experimentMedian = movingMedian.getValueAtPercentile();
//
// int samplesLessThan = 0;
// int samplesMoreThan = 0;
//
// for (int j=0; j<lastNSamples.size(); j++) {
// if (lastNSamples.at(j) < experimentMedian) {
// samplesLessThan++;
// } else if (lastNSamples.at(j) > experimentMedian) {
// samplesMoreThan++;
// }
// }
//
//
// if (!(samplesLessThan <= N/2 && samplesMoreThan <= N-1/2)) {
// qDebug() << "\t\t FAIL at sample" << s;
// fail = true;
// break;
// }
// }
// if (!fail) {
// qDebug() << "\t\t PASS";
// }
// }
// }
//}

View file

@ -13,15 +13,23 @@
#define hifi_MovingPercentileTests_h
#include <QtTest/QtTest>
#include <../QTestExtensions.hpp>
class MovingPercentileTests : public QObject {
Q_OBJECT
private slots:
void runAllTests();
// Tests
void testRunningMin ();
void testRunningMax ();
void testRunningMedian ();
private:
// Utilities and helper functions
float random();
void testRunningMinForN (int n);
void testRunningMaxForN (int n);
void testRunningMedianForN (int n);
};
#endif // hifi_MovingPercentileTests_h