[ovs-dev] [PATCH v6] tests: Add tests for stopwatch module
Jakub Sitnicki
jkbs at redhat.com
Mon Mar 5 15:24:45 UTC 2018
Check if stopwatch module is calculating statistics as expected.
Signed-off-by: Jakub Sitnicki <jkbs at redhat.com>
---
Hey Mark,
I've removed the remaining FIXME's from the tests.
Could you pull this patch into the next iteration?
-Jakub
v5 -> v6:
* Use 0 as first sample in tests for trivial input now that the bug with minimum
calculation is fixed.
lib/stopwatch.c | 2 +-
tests/automake.mk | 3 +-
tests/library.at | 5 ++
tests/test-stopwatch.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 203 insertions(+), 2 deletions(-)
create mode 100644 tests/test-stopwatch.c
diff --git a/lib/stopwatch.c b/lib/stopwatch.c
index 185f4a32f..ce48e3981 100644
--- a/lib/stopwatch.c
+++ b/lib/stopwatch.c
@@ -245,7 +245,7 @@ stopwatch_get_stats_protected(const char *name,
return false;
}
- stats->count = perf->samples;
+ stats->count = perf->n_samples;
stats->unit = perf->units;
stats->max = perf->max;
stats->min = perf->min;
diff --git a/tests/automake.mk b/tests/automake.mk
index 18698ebc3..4d43af0a5 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -364,7 +364,8 @@ tests_ovstest_SOURCES = \
tests/test-uuid.c \
tests/test-bitmap.c \
tests/test-vconn.c \
- tests/test-aa.c
+ tests/test-aa.c \
+ tests/test-stopwatch.c
if !WIN32
tests_ovstest_SOURCES += \
diff --git a/tests/library.at b/tests/library.at
index 5efbfbb7c..1e81a80be 100644
--- a/tests/library.at
+++ b/tests/library.at
@@ -251,3 +251,8 @@ AT_CLEANUP
AT_SETUP([rcu])
AT_CHECK([ovstest test-rcu-quiesce], [0], [])
AT_CLEANUP
+
+AT_SETUP([stopwatch module])
+AT_CHECK([ovstest test-stopwatch], [0], [......
+], [ignore])
+AT_CLEANUP
diff --git a/tests/test-stopwatch.c b/tests/test-stopwatch.c
new file mode 100644
index 000000000..b49641cd7
--- /dev/null
+++ b/tests/test-stopwatch.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2018 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#undef NDEBUG
+#include "stopwatch.h"
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include "ovstest.h"
+#include "util.h"
+
+#define MAX_SAMPLES 100
+#define UNIT SW_MS
+
+struct test_data {
+ const char *name;
+ unsigned long long samples[MAX_SAMPLES];
+ size_t num_samples;
+ struct stopwatch_stats expected_stats;
+};
+
+static struct test_data data_sets[] = {
+ {
+ .name = "1-interval-zero-length",
+ .samples = { 0, 0 },
+ .num_samples = 2,
+ .expected_stats = {
+ .count = 1,
+ .unit = UNIT,
+ .max = 0,
+ .min = 0,
+ .pctl_95 = 0,
+ .ewma_50 = 0,
+ .ewma_1 = 0,
+ },
+ },
+ {
+ .name = "1-interval-unit-length",
+ .samples = { 0, 1 },
+ .num_samples = 2,
+ .expected_stats = {
+ .count = 1,
+ .unit = UNIT,
+ .max = 1,
+ .min = 1,
+ .pctl_95 = 0,
+ .ewma_50 = 1,
+ .ewma_1 = 1,
+ },
+ },
+ {
+ .name = "10-intervals-unit-length",
+ .samples = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
+ .num_samples = 11,
+ .expected_stats = {
+ .count = 10,
+ .unit = UNIT,
+ .max = 1,
+ .min = 1,
+ .pctl_95 = 1,
+ .ewma_50 = 1,
+ .ewma_1 = 1,
+ },
+ },
+ {
+ .name = "10-intervals-linear-growth",
+ .samples = { 1, 2, 4, 7, 11, 16, 22, 29, 37, 46, 56 },
+ .num_samples = 11,
+ .expected_stats = {
+ .count = 10,
+ .unit = UNIT,
+ .max = 10,
+ .min = 1,
+ .pctl_95 = 10.0,
+ .ewma_50 = 9.0,
+ .ewma_1 = 1.4,
+ },
+ },
+ {
+ .name = "60-intervals-unit-length",
+ .samples = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, },
+ .num_samples = 61,
+ .expected_stats = {
+ .count = 60,
+ .unit = UNIT,
+ .max = 1,
+ .min = 1,
+ .pctl_95 = 1,
+ .ewma_50 = 1,
+ .ewma_1 = 1,
+ },
+ },
+ {
+ .name = "60-intervals-linear-growth",
+ .samples = { 1, 2, 4, 7, 11, 16, 22, 29, 37, 46,
+ 56, 67, 79, 92, 106, 121, 137, 154, 172, 191,
+ 211, 232, 254, 277, 301, 326, 352, 379, 407, 436,
+ 466, 497, 529, 562, 596, 631, 667, 704, 742, 781,
+ 821, 862, 904, 947, 991, 1036, 1082, 1129, 1177, 1226,
+ 1276, 1327, 1379, 1432, 1486, 1541, 1597, 1654, 1712, 1771,
+ 1831, },
+ .num_samples = 61,
+ .expected_stats = {
+ .count = 60,
+ .unit = UNIT,
+ .max = 60,
+ .min = 1,
+ /* 95th percentile is actually closer to 57, but the estimate is
+ * pretty dang close */
+ .pctl_95 = 56,
+ .ewma_50 = 59,
+ .ewma_1 = 15.7,
+ },
+ },
+};
+
+#define ASSERT_MSG(COND, MSG, ...) \
+ if (!(COND)) { \
+ fprintf(stderr, MSG "\n", ##__VA_ARGS__); \
+ assert(COND); \
+ }
+
+#define ASSERT_ULL_EQ(a, b) \
+ ASSERT_MSG(a == b, \
+ "Assertion '%s == %s' failed: %llu == %llu", \
+ #a, #b, a, b)
+
+#define ASSERT_DOUBLE_EQ(a, b, eps) \
+ ASSERT_MSG(fabs(a - b) < eps, \
+ "Assertion '|%s - %s| < %s' failed: |%g - %g| < %g", \
+ #a, #b, #eps, a, b, eps)
+
+#define ASSERT_STATS_EQ(a, b) \
+ do { \
+ ASSERT_ULL_EQ((a)->count, (b)->count); \
+ ASSERT_ULL_EQ((a)->max, (b)->max); \
+ ASSERT_ULL_EQ((a)->min, (b)->min); \
+ ASSERT_DOUBLE_EQ((a)->pctl_95, (b)->pctl_95, 1e-1); \
+ ASSERT_DOUBLE_EQ((a)->ewma_50, (b)->ewma_50, 1e-1); \
+ ASSERT_DOUBLE_EQ((a)->ewma_1, (b)->ewma_1, 1e-1); \
+ } while (0)
+
+static void
+test_stopwatch_calculate_stats(void)
+{
+ struct test_data *d;
+
+ for (size_t i = 0; i < ARRAY_SIZE(data_sets); i++) {
+ d = &data_sets[i];
+
+ fprintf(stderr, "TEST '%s'\n", d->name);
+
+ stopwatch_create(d->name, UNIT);
+ for (size_t j = 0; j < d->num_samples - 1; j ++) {
+ stopwatch_start(d->name, d->samples[j]);
+ stopwatch_stop(d->name, d->samples[j + 1]);
+ }
+ stopwatch_sync();
+
+ struct stopwatch_stats stats = { 0 };
+ stopwatch_get_stats(d->name, &stats);
+ ASSERT_STATS_EQ(&stats, &d->expected_stats);
+
+ printf(".");
+ }
+}
+
+static void
+test_stopwatch_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
+{
+ test_stopwatch_calculate_stats();
+ printf("\n");
+}
+
+OVSTEST_REGISTER("test-stopwatch", test_stopwatch_main);
--
2.14.3
More information about the dev
mailing list