about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-06-28 12:54:41 -0700
committerGraydon Hoare <graydon@mozilla.com>2011-06-28 16:12:34 -0700
commitf6f8a06d6bf010b8d30c23786976792cccfbd6de (patch)
tree7aeb93091cdb19e6ac3b2a63fd7f828a4b3c1499
parent657e5a2bd579f7f1698f8ba88cb1142ced7a477f (diff)
downloadrust-f6f8a06d6bf010b8d30c23786976792cccfbd6de.tar.gz
rust-f6f8a06d6bf010b8d30c23786976792cccfbd6de.zip
Resurrecting the runtime unit tests, and modifying them so they compile under the latest refactoring changes.
-rw-r--r--mk/rt.mk6
-rw-r--r--src/rt/rust_internal.h4
-rw-r--r--src/rt/rust_kernel.h4
-rw-r--r--src/rt/test/rust_test_harness.cpp40
-rw-r--r--src/rt/test/rust_test_harness.h22
-rw-r--r--src/rt/test/rust_test_runtime.cpp67
-rw-r--r--src/rt/test/rust_test_runtime.h51
-rw-r--r--src/rt/test/rust_test_util.cpp78
-rw-r--r--src/rt/test/rust_test_util.h41
9 files changed, 311 insertions, 2 deletions
diff --git a/mk/rt.mk b/mk/rt.mk
index bd935d660ff..7ada4c00695 100644
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -25,6 +25,9 @@ RUNTIME_CS := rt/sync/timer.cpp \
               rt/rust_srv.cpp \
               rt/rust_kernel.cpp \
               rt/memory_region.cpp \
+              rt/test/rust_test_harness.cpp \
+              rt/test/rust_test_runtime.cpp \
+              rt/test/rust_test_util.cpp \
               rt/arch/i386/context.cpp \
 
 RUNTIME_LL :=
@@ -56,6 +59,9 @@ RUNTIME_HDR := rt/globals.h \
                rt/rust_kernel.h \
                rt/memory_region.h \
                rt/memory.h \
+               rt/test/rust_test_harness.h \
+               rt/test/rust_test_runtime.h \
+               rt/test/rust_test_util.h \
                rt/arch/i386/context.h \
 
 RUNTIME_DEF := rt/rustrt$(CFG_DEF_SUFFIX)
diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h
index a57ef607f60..f10e55d40a0 100644
--- a/src/rt/rust_internal.h
+++ b/src/rt/rust_internal.h
@@ -249,6 +249,10 @@ typedef ptr_vec<rust_alarm> rust_wait_queue;
 #include "rust_port.h"
 #include "memory.h"
 
+#include "test/rust_test_harness.h"
+#include "test/rust_test_util.h"
+#include "test/rust_test_runtime.h"
+
 //
 // Local Variables:
 // mode: C++
diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h
index a1fba33bf89..bea5afd5de3 100644
--- a/src/rt/rust_kernel.h
+++ b/src/rt/rust_kernel.h
@@ -68,11 +68,11 @@ class rust_kernel : public rust_thread {
     rust_handle<rust_scheduler> *
     internal_get_sched_handle(rust_scheduler *sched);
 
+    array_list<rust_task_thread *> threads;
+
     rust_scheduler *create_scheduler(const char *name);
     void destroy_scheduler();
 
-    array_list<rust_task_thread *> threads;
-
 public:
     rust_scheduler *sched;
     lock_and_signal scheduler_lock;
diff --git a/src/rt/test/rust_test_harness.cpp b/src/rt/test/rust_test_harness.cpp
new file mode 100644
index 00000000000..cca199dcdb9
--- /dev/null
+++ b/src/rt/test/rust_test_harness.cpp
@@ -0,0 +1,40 @@
+#include "../rust_internal.h"
+
+bool
+rust_test::run() {
+    return false;
+}
+
+const char *
+rust_test::name() {
+    return "untitled";
+}
+
+rust_test_suite::rust_test_suite() {
+    tests.append(new rust_domain_test());
+    tests.append(new rust_task_test(this));
+    tests.append(new rust_array_list_test());
+    tests.append(new rust_synchronized_indexed_list_test());
+}
+
+rust_test_suite::~rust_test_suite() {
+
+}
+
+bool
+rust_test_suite::run() {
+    bool pass = true;
+    for (size_t i = 0; i < tests.size(); i++) {
+        rust_test *test = tests[i];
+        printf("test: %s running ... \n", test->name());
+        timer timer;
+        bool result = tests[i]->run();
+        printf("test: %s %s %.2f ms\n", test->name(),
+               result ? "PASSED" : "FAILE", timer.get_elapsed_time_in_ms());
+        if (result == false) {
+            pass = false;
+        }
+    }
+    return pass;
+}
+
diff --git a/src/rt/test/rust_test_harness.h b/src/rt/test/rust_test_harness.h
new file mode 100644
index 00000000000..401015e4508
--- /dev/null
+++ b/src/rt/test/rust_test_harness.h
@@ -0,0 +1,22 @@
+#ifndef RUST_TEST_HARNESS_H
+#define RUST_TEST_HARNESS_H
+
+#define CHECK(x) if ((x) == false)                               \
+    { printf("condition: %s failed at file: %s, line: %d\n", #x, \
+             __FILE__, __LINE__ ); return false; }
+
+class rust_test {
+public:
+    virtual bool run();
+    virtual const char *name();
+};
+
+class rust_test_suite : public rust_test {
+public:
+    array_list<rust_test*> tests;
+    rust_test_suite();
+    virtual ~rust_test_suite();
+    bool run();
+};
+
+#endif /* RUST_TEST_HARNESS_H */
diff --git a/src/rt/test/rust_test_runtime.cpp b/src/rt/test/rust_test_runtime.cpp
new file mode 100644
index 00000000000..acb3557b8c1
--- /dev/null
+++ b/src/rt/test/rust_test_runtime.cpp
@@ -0,0 +1,67 @@
+#include "rust_test_runtime.h"
+
+rust_test_runtime::rust_test_runtime() {
+}
+
+rust_test_runtime::~rust_test_runtime() {
+}
+
+#define DOMAINS 32
+#define TASKS 32
+
+void
+rust_domain_test::worker::run() {
+    rust_scheduler *handle = kernel->get_scheduler();
+    for (int i = 0; i < TASKS; i++) {
+        handle->create_task(NULL, "child");
+    }
+    sync::random_sleep(1000);
+}
+
+bool
+rust_domain_test::run() {
+    rust_srv srv;
+    rust_kernel kernel(&srv);
+
+    array_list<worker *> workers;
+    for (int i = 0; i < DOMAINS; i++) {
+        worker *worker = new rust_domain_test::worker (&kernel);
+        workers.append(worker);
+        worker->start();
+    }
+
+    // We don't join the worker threads here in order to simulate ad-hoc
+    // termination of domains. If we join_all_domains before all domains
+    // are actually spawned, this could crash, thus the reason for the
+    // sleep below.
+
+    sync::sleep(100);
+    return true;
+}
+
+void task_entry() {
+    printf("task entry\n");
+}
+
+void
+rust_task_test::worker::run() {
+    rust_scheduler *scheduler = kernel->get_scheduler();
+    scheduler->root_task->start((uintptr_t)&task_entry, (uintptr_t)NULL);
+    scheduler->start_main_loop(0);
+}
+
+bool
+rust_task_test::run() {
+    rust_srv srv;
+    rust_kernel kernel(&srv);
+
+    array_list<worker *> workers;
+    for (int i = 0; i < DOMAINS; i++) {
+        worker *worker = new rust_task_test::worker (&kernel, this);
+        workers.append(worker);
+        worker->start();
+    }
+
+    sync::random_sleep(1000);
+    return true;
+}
diff --git a/src/rt/test/rust_test_runtime.h b/src/rt/test/rust_test_runtime.h
new file mode 100644
index 00000000000..8d4f38ecb79
--- /dev/null
+++ b/src/rt/test/rust_test_runtime.h
@@ -0,0 +1,51 @@
+#include "../rust_internal.h"
+
+#ifndef RUST_TEST_RUNTIME_H
+#define RUST_TEST_RUNTIME_H
+
+class rust_test_runtime {
+public:
+    rust_test_runtime();
+    virtual ~rust_test_runtime();
+};
+
+
+class rust_domain_test : public rust_test {
+public:
+    class worker : public rust_thread {
+        public:
+        rust_kernel *kernel;
+        worker(rust_kernel *kernel) : kernel(kernel) {
+            // Nop.
+        }
+        void run();
+    };
+    bool run();
+    const char *name() {
+        return "rust_domain_test";
+    }
+};
+
+class rust_task_test : public rust_test {
+public:
+    rust_test_suite *suite;
+    rust_task_test(rust_test_suite *suite) : suite(suite) {
+        // Nop.
+    }
+    class worker : public rust_thread {
+        public:
+        rust_kernel *kernel;
+        rust_task_test *parent;
+        worker(rust_kernel *kernel, rust_task_test *parent) :
+            kernel(kernel), parent(parent) {
+            // Nop.
+        }
+        void run();
+    };
+    bool run();
+    const char *name() {
+        return "rust_task_test";
+    }
+};
+
+#endif /* RUST_TEST_RUNTIME_H */
diff --git a/src/rt/test/rust_test_util.cpp b/src/rt/test/rust_test_util.cpp
new file mode 100644
index 00000000000..2e9d764f69b
--- /dev/null
+++ b/src/rt/test/rust_test_util.cpp
@@ -0,0 +1,78 @@
+#include "../rust_internal.h"
+
+#define COUNT 1000
+#define LARGE_COUNT 10000
+#define THREADS 10
+
+bool
+rust_array_list_test::run() {
+    array_list<int> list;
+
+    for (int i = 0; i < COUNT; i++) {
+        list.append(i);
+    }
+
+    for (int i = 0; i < COUNT; i++) {
+        CHECK (list[i] == i);
+    }
+
+    for (int i = 0; i < COUNT; i++) {
+        CHECK (list.index_of(i) == i);
+    }
+
+    for (int i = 0; i < COUNT; i++) {
+        CHECK (list.replace(i, -i));
+        CHECK (list.replace(-i, i));
+        CHECK (list.index_of(i) == i);
+    }
+
+    for (int i = COUNT - 1; i >= 0; i--) {
+        CHECK (list.pop(NULL));
+    }
+
+    return true;
+}
+
+bool
+rust_synchronized_indexed_list_test::run() {
+    array_list<worker*> workers;
+
+    for (int i = 0; i < THREADS; i++) {
+        worker *worker =
+            new rust_synchronized_indexed_list_test::worker(this);
+        workers.append(worker);
+    }
+
+    for (uint32_t i = 0; i < workers.size(); i++) {
+        workers[i]->start();
+    }
+
+    while(workers.is_empty() == false) {
+        worker *worker;
+        workers.pop(&worker);
+        worker->join();
+        delete worker;
+    }
+
+    long long expected_items = LARGE_COUNT * THREADS;
+
+    CHECK(list.length() == expected_items);
+
+    long long sum = 0;
+    for (size_t i = 0; i < list.length(); i++) {
+        sum += list[i]->value;
+    }
+
+    long long expected_sum = LARGE_COUNT;
+    expected_sum = expected_sum * (expected_sum - 1) / 2 * THREADS;
+    CHECK (sum == expected_sum);
+    return true;
+}
+
+void
+rust_synchronized_indexed_list_test::worker::run() {
+    for (int i = 0; i < LARGE_COUNT; i++) {
+        parent->list.append(new indexed_list_element<int>(i));
+    }
+    return;
+}
diff --git a/src/rt/test/rust_test_util.h b/src/rt/test/rust_test_util.h
new file mode 100644
index 00000000000..41c3579043a
--- /dev/null
+++ b/src/rt/test/rust_test_util.h
@@ -0,0 +1,41 @@
+#ifndef RUST_TEST_UTIL_H
+#define RUST_TEST_UTIL_H
+
+class rust_test_util : public rust_test {
+public:
+
+};
+
+class rust_array_list_test : public rust_test {
+public:
+    bool run();
+    const char *name() {
+        return "rust_array_list_test";
+    }
+};
+
+
+class rust_synchronized_indexed_list_test : public rust_test {
+public:
+    rust_srv srv;
+    synchronized_indexed_list<indexed_list_element<int> > list;
+
+    rust_synchronized_indexed_list_test() {
+        // Nop.
+    }
+
+    class worker : public rust_thread {
+    public:
+        rust_synchronized_indexed_list_test *parent;
+        worker(rust_synchronized_indexed_list_test *parent) : parent(parent) {
+            // Nop.
+        }
+        void run();
+    };
+    bool run();
+    const char *name() {
+        return "rust_synchronized_indexed_list_test";
+    }
+};
+
+#endif /* RUST_TEST_UTIL_H */