[ovs-dev] [RFC 06/10] ovs-thread-stats: Added simple testcase
Daniele Di Proietto
ddiproietto at vmware.com
Wed Oct 8 21:09:52 UTC 2014
Signed-off-by: Daniele Di Proietto <ddiproietto at vmware.com>
---
tests/automake.mk | 2 +
tests/test-stats.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/testsuite.at | 1 +
tests/threadstats.at | 4 ++
4 files changed, 169 insertions(+)
create mode 100644 tests/test-stats.c
create mode 100644 tests/threadstats.at
diff --git a/tests/automake.mk b/tests/automake.mk
index 1f13230..37c232f 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -30,6 +30,7 @@ TESTSUITE_AT = \
tests/aes128.at \
tests/unixctl-py.at \
tests/uuid.at \
+ tests/threadstats.at \
tests/json.at \
tests/jsonrpc.at \
tests/jsonrpc-py.at \
@@ -237,6 +238,7 @@ tests_ovstest_SOURCES = \
tests/test-rstp.c \
tests/test-sflow.c \
tests/test-sha1.c \
+ tests/test-stats.c \
tests/test-stp.c \
tests/test-util.c \
tests/test-uuid.c \
diff --git a/tests/test-stats.c b/tests/test-stats.c
new file mode 100644
index 0000000..f009bcf
--- /dev/null
+++ b/tests/test-stats.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014 Nicira, 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>
+
+#include "fatal-signal.h"
+#include "ovstest.h"
+#include "ovs-thread.h"
+#include "ovs-thread-stats.h"
+
+enum {N_WRITES = 100000};
+enum {N_READS = 100};
+struct info_thread
+{
+ int n_create; /* How many stats buckets should I create? */
+ int n_waste; /* How many stats buckets should I create and destroy? */
+ int n_total; /* How many stats buckets are there(minimum)? */
+ struct ovs_barrier barrier;
+};
+
+static void
+aggr_cb(void *aux, struct ovsthread_stats_bucket *b)
+{
+ uint64_t *i = (uint64_t *)aux;
+ *i += b->data[0];
+}
+
+static void *
+stats_writer(void *aux_)
+{
+ struct info_thread *aux = aux_;
+ int *buckets;
+ int i,j;
+
+ buckets = xmalloc(aux->n_create * sizeof(*buckets));
+
+ for (i = 0; i < aux->n_create; i++) {
+ buckets[i] = ovsthread_stats_create_bucket();
+ }
+
+ ovs_barrier_block(&aux->barrier);
+
+ for (j = 0; j < N_WRITES; j++) {
+ for (i = 0; i < aux->n_create; i++) {
+ struct ovsthread_stats_bucket *b;
+ uint32_t seq;
+
+ b = ovsthread_stats_get_bucket(buckets[i], &seq);
+ b->data[0]++;
+ ovsthread_stats_bucket_done(b, seq);
+ }
+ }
+
+ for (i = 0; i < aux->n_create; i++) {
+ uint64_t v = 0;
+ ovsthread_stats_aggregate(buckets[i], &v, aggr_cb);
+ ovs_assert(v == N_WRITES);
+ }
+
+ ovs_barrier_block(&aux->barrier);
+
+ for (i = 0; i < aux->n_create; i++) {
+ ovsthread_stats_destroy_bucket(buckets[i]);
+ }
+
+ ovsthread_stats_create_bucket();
+ return NULL;
+}
+
+static void *
+stats_reader(void *aux_)
+{
+ struct info_thread *aux = aux_;
+ int i,j;
+
+ for (i = 0; i < aux->n_waste; i++) {
+ int b = ovsthread_stats_create_bucket();
+ ovsthread_stats_destroy_bucket(b);
+ }
+
+ ovs_barrier_block(&aux->barrier);
+
+ /* XXX this works because buckets id are small numbers. */
+ for (j = 0; j < N_READS; j++) {
+ for (i = 0; i < aux->n_total; i++) {
+ uint64_t v = 0;
+ ovsthread_stats_aggregate(i, &v, aggr_cb);
+ ovs_assert(v <= N_WRITES);
+ }
+ }
+
+ ovs_barrier_block(&aux->barrier);
+
+ for (j = 0; j < N_READS; j++) {
+ for (i = 0; i < aux->n_total; i++) {
+ uint64_t v = 0;
+ ovsthread_stats_aggregate(i, &v, aggr_cb);
+ ovs_assert(v == N_WRITES || v == 0);
+ }
+ }
+
+ return NULL;
+}
+
+static void
+test_stats(int n_readers, int n_writers)
+{
+ int i;
+ pthread_t *readers, *writers;
+ struct info_thread t;
+
+ t.n_create = 20;
+ t.n_total = 20 * n_writers;
+ t.n_waste = 5;
+
+ ovs_barrier_init(&t.barrier, n_readers + n_writers + 1);
+
+ readers = xmalloc(n_readers * sizeof *readers);
+ writers = xmalloc(n_writers * sizeof *writers);
+
+ for (i = 0; i < n_writers; i++) {
+ writers[i] = ovs_thread_create("writer", stats_writer, &t);
+ }
+ for (i = 0; i < n_readers; i++) {
+ readers[i] = ovs_thread_create("reader", stats_reader, &t);
+ }
+
+ ovs_barrier_block(&t.barrier);
+
+ ovs_barrier_block(&t.barrier);
+
+ for (i = 0; i < n_writers; i++) {
+ xpthread_join(writers[i], NULL);
+ }
+ for (i = 0; i < n_readers; i++) {
+ xpthread_join(readers[i], NULL);
+ }
+
+ ovs_barrier_destroy(&t.barrier);
+}
+
+static void
+test_stats_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
+{
+ fatal_signal_init();
+ test_stats(5, 5);
+}
+
+OVSTEST_REGISTER("test-stats", test_stats_main);
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 8712277..2fddcc9 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -139,6 +139,7 @@ m4_include([tests/file_name.at])
m4_include([tests/aes128.at])
m4_include([tests/unixctl-py.at])
m4_include([tests/uuid.at])
+m4_include([tests/threadstats.at])
m4_include([tests/json.at])
m4_include([tests/jsonrpc.at])
m4_include([tests/jsonrpc-py.at])
diff --git a/tests/threadstats.at b/tests/threadstats.at
new file mode 100644
index 0000000..24f7982
--- /dev/null
+++ b/tests/threadstats.at
@@ -0,0 +1,4 @@
+AT_BANNER([Per thread statistics])
+AT_SETUP([multiple readers/writers])
+AT_CHECK([ovstest test-stats], [0], [], [])
+AT_CLEANUP
--
2.1.0.rc1
More information about the dev
mailing list