From 202cc3eab48643f5b0535f2173d642b20b3aacd6 Mon Sep 17 00:00:00 2001 From: Geoffrey Challen Date: Mon, 11 Jan 2016 20:08:39 -0500 Subject: [PATCH] Accidentally checked in patch. --- automation_testing | 509 --------------------------------------------- 1 file changed, 509 deletions(-) delete mode 100644 automation_testing diff --git a/automation_testing b/automation_testing deleted file mode 100644 index bd9525e..0000000 --- a/automation_testing +++ /dev/null @@ -1,509 +0,0 @@ -diff --git a/kern/conf/conf.kern b/kern/conf/conf.kern -index 2a29022..3fa5742 100644 ---- a/kern/conf/conf.kern -+++ b/kern/conf/conf.kern -@@ -461,3 +461,6 @@ defoption synchprobs - optfile synchprobs synchprobs/whalemating.c - optfile synchprobs synchprobs/stoplight.c - optfile synchprobs test/synchprobs.c -+ -+defoption automationtest -+optfile automationtest test/automationtest.c -diff --git a/kern/include/lib.h b/kern/include/lib.h -index d1ae75d..a5aca71 100644 ---- a/kern/include/lib.h -+++ b/kern/include/lib.h -@@ -201,9 +201,10 @@ void random_spinner(uint32_t); - /* - * Testing variants of kprintf. tprintf is silent during automated testing. - * sprintf prefixes the kernel secret to kprintf messages during automated -- * testing. -+ * testing. nprintf is not silent during automated testing. - */ - - int tkprintf(const char *format, ...) __PF(1,2); -+int nkprintf(const char *format, ...) __PF(1,2); - - #endif /* _LIB_H_ */ -diff --git a/kern/include/test.h b/kern/include/test.h -index a2458a2..260e515 100644 ---- a/kern/include/test.h -+++ b/kern/include/test.h -@@ -31,6 +31,7 @@ - #define _TEST_H_ - - #include "opt-synchprobs.h" -+#include "opt-automationtest.h" - - /* - * Declarations for test code and other miscellaneous high-level -@@ -133,4 +134,14 @@ int stoplight(int, char **); - - #endif - -+/* -+ * Automation tests for detecting kernel deadlocks and livelocks. -+ */ -+ -+#if OPT_AUTOMATIONTEST -+int dltest(int, char **); -+int ll1test(int, char **); -+int ll16test(int, char **); -+#endif -+ - #endif /* _TEST_H_ */ -diff --git a/kern/lib/kprintf.c b/kern/lib/kprintf.c -index c8a3baa..0a6fe90 100644 ---- a/kern/lib/kprintf.c -+++ b/kern/lib/kprintf.c -@@ -159,6 +159,25 @@ tkprintf(const char *fmt, ...) - - return chars; - } -+/* -+ * kprintf variant that is quiet during non-automated testing -+ */ -+int -+nkprintf(const char *fmt, ...) -+{ -+ int chars; -+ va_list ap; -+ -+ if (strcmp(KERNEL_SECRET, "") == 0) { -+ return 0; -+ } -+ -+ va_start(ap, fmt); -+ chars = vkprintf(fmt, ap); -+ va_end(ap); -+ -+ return chars; -+} - - /* - * panic() is for fatal errors. It prints the printf arguments it's -diff --git a/kern/main/menu.c b/kern/main/menu.c -index d0ed255..abb99cb 100644 ---- a/kern/main/menu.c -+++ b/kern/main/menu.c -@@ -48,6 +48,7 @@ - #include "opt-sfs.h" - #include "opt-net.h" - #include "opt-synchprobs.h" -+#include "opt-automationtest.h" - - /* - * In-kernel menu and command dispatcher. -@@ -530,6 +531,29 @@ cmd_testmenu(int n, char **a) - return 0; - } - -+#if OPT_AUTOMATIONTEST -+static const char *automationmenu[] = { -+ "[dl] Deadlock test (*) ", -+ "[ll1] Livelock test (1 thread) ", -+ "[ll16] Livelock test (16 threads) ", -+ NULL -+}; -+ -+static -+int -+cmd_automationmenu(int n, char **a) -+{ -+ (void)n; -+ (void)a; -+ -+ showmenu("OS/161 automation tests menu", automationmenu); -+ kprintf(" (*) These tests require locks.\n"); -+ kprintf("\n"); -+ -+ return 0; -+} -+#endif -+ - static const char *mainmenu[] = { - "[?o] Operations menu ", - "[?t] Tests menu ", -@@ -566,6 +590,9 @@ static struct { - { "help", cmd_mainmenu }, - { "?o", cmd_opsmenu }, - { "?t", cmd_testmenu }, -+#if OPT_AUTOMATIONTEST -+ { "?a", cmd_automationmenu }, -+#endif - - /* operations */ - { "s", cmd_shell }, -@@ -654,6 +681,13 @@ static struct { - { "fs4", writestress2 }, - { "fs5", longstress }, - { "fs6", createstress }, -+ -+#if OPT_AUTOMATIONTEST -+ /* automation tests */ -+ { "dl", dltest }, -+ { "ll1", ll1test }, -+ { "ll16", ll16test }, -+#endif - - { NULL, NULL } - }; -diff --git a/kern/test/automationtest.c b/kern/test/automationtest.c -new file mode 100644 -index 0000000..2dce056 ---- /dev/null -+++ b/kern/test/automationtest.c -@@ -0,0 +1,175 @@ -+/* -+ * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 -+ * The President and Fellows of Harvard College. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ */ -+ -+/* -+ * Automation test code for creating (and detecting) kernel dead and livelocks. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_SPINNERS 16 -+ -+static struct lock *deadlock_locks[2]; -+static struct semaphore *deadlock_sem; -+ -+struct spinlock spinners_lock[MAX_SPINNERS]; -+ -+static -+void -+inititems(void) -+{ -+ int i; -+ -+ for (i = 0; i < 2; i++) { -+ deadlock_locks[i] = lock_create("deadlock lock"); -+ if (deadlock_locks[i] == NULL) { -+ panic("automationtest: lock_create failed\n"); -+ } -+ } -+ deadlock_sem = sem_create("deadlock sem", 0); -+ if (deadlock_sem == NULL) { -+ panic("automationtest: sem_create failed\n"); -+ } -+ -+ for (i = 0; i < MAX_SPINNERS; i++) { -+ spinlock_init(&(spinners_lock[i])); -+ } -+} -+ -+static -+void -+dltestthread(void *junk1, unsigned long junk2) -+{ -+ (void)junk1; -+ (void)junk2; -+ -+ lock_acquire(deadlock_locks[1]); -+ V(deadlock_sem); -+ lock_acquire(deadlock_locks[0]); -+} -+ -+int -+dltest(int nargs, char **args) -+{ -+ int result; -+ -+ (void)nargs; -+ (void)args; -+ -+ inititems(); -+ -+ lock_acquire(deadlock_locks[0]); -+ -+ result = thread_fork("dltest", NULL, dltestthread, NULL, (unsigned long)0); -+ if (result) { -+ panic("dltest: thread_fork failed: %s\n", strerror(result)); -+ } -+ -+ P(deadlock_sem); -+ lock_acquire(deadlock_locks[1]); -+ -+ panic("dltest: didn't create deadlock (locks probably don't work)\n"); -+ -+ // 09 Jan 2015 : GWA : Shouldn't return. -+ return 0; -+} -+ -+inline -+static -+void -+infinite_spinner(unsigned long i) -+{ -+ (void)i; -+ volatile int j; -+ -+ for (j=0; j<10000000; j++); -+ -+ spinlock_acquire(&(spinners_lock[i])); -+ -+ for (j=0; j<=1000; j++) { -+ if (j == 1000) { -+ j = 0; -+ } -+ } -+ panic("ll1test: infinite spin loop completed\n"); -+} -+ -+int -+ll1test(int nargs, char **args) -+{ -+ (void)nargs; -+ (void)args; -+ -+ inititems(); -+ -+ infinite_spinner((unsigned long) 0); -+ -+ // 09 Jan 2015 : GWA : Shouldn't return. -+ return 0; -+} -+ -+ -+static -+void -+ll16testthread(void *junk1, unsigned long i) -+{ -+ (void)junk1; -+ -+ infinite_spinner(i); -+} -+ -+int -+ll16test(int nargs, char **args) -+{ -+ int i, result; -+ -+ inititems(); -+ -+ (void)nargs; -+ (void)args; -+ -+ for (i=1; i<16; i++) { -+ result = thread_fork("ll16testthread", NULL, ll16testthread, NULL, (unsigned long)i); -+ if (result) { -+ panic("ll16test: thread_fork failed: %s\n", strerror(result)); -+ } -+ } -+ infinite_spinner(0); -+ -+ // 09 Jan 2015 : GWA : Shouldn't return. -+ return 0; -+} -diff --git a/userland/include/stdio.h b/userland/include/stdio.h -index 440a822..772277f 100644 ---- a/userland/include/stdio.h -+++ b/userland/include/stdio.h -@@ -59,6 +59,7 @@ int vsnprintf(char *buf, size_t len, const char *fmt, __va_list ap); - /* Automated testing extensions. */ - - int tprintf(const char *fmt, ...); -+int nprintf(const char *fmt, ...); - int printsf(const char *fmt, ...); - - /* Print the argument string and then a newline. Returns 0 or -1 on error. */ -diff --git a/userland/lib/libc/stdio/printf.c b/userland/lib/libc/stdio/printf.c -index 52a8161..30d923d 100644 ---- a/userland/lib/libc/stdio/printf.c -+++ b/userland/lib/libc/stdio/printf.c -@@ -97,6 +97,24 @@ tprintf(const char *fmt, ...) - return chars; - } - -+/* printf variant that is loud during automated testing */ -+int -+nprintf(const char *fmt, ...) -+{ -+ int chars; -+ va_list ap; -+ -+ if (strcmp(KERNEL_SECRET, "") == 0) { -+ return 0; -+ } -+ -+ va_start(ap, fmt); -+ chars = vprintf(fmt, ap); -+ va_end(ap); -+ -+ return chars; -+} -+ - /* printf variant that prepends the kernel secret */ - int - printsf(const char *fmt, ...) -diff --git a/userland/testbin/Makefile b/userland/testbin/Makefile -index e5cf502..3e16de0 100644 ---- a/userland/testbin/Makefile -+++ b/userland/testbin/Makefile -@@ -10,8 +10,8 @@ SUBDIRS=add argtest badcall bigexec bigfile bigfork bigseek bloat conman \ - filetest forkbomb forktest frack guzzle hash hog huge kitchen \ - malloctest matmult multiexec palin parallelvm poisondisk psort \ - quinthuge quintmat quintsort randcall redirect rmdirtest rmtest \ -- sbrktest schedpong sink sort sparsefile sty tail tictac triplehuge \ -- triplemat triplesort usemtest zero -+ sbrktest schedpong sink sort sparsefile spinner sty tail tictac \ -+ triplehuge triplemat triplesort usemtest waiter zero - - # But not: - # userthreads (no support in kernel API in base system) -diff --git a/userland/testbin/spinner/Makefile b/userland/testbin/spinner/Makefile -new file mode 100644 -index 0000000..2eaac72 ---- /dev/null -+++ b/userland/testbin/spinner/Makefile -@@ -0,0 +1,11 @@ -+# Makefile for spinner -+ -+TOP=../../.. -+.include "$(TOP)/mk/os161.config.mk" -+ -+PROG=spinner -+SRCS=spinner.c -+BINDIR=/testbin -+ -+.include "$(TOP)/mk/os161.prog.mk" -+ -diff --git a/userland/testbin/spinner/spinner.c b/userland/testbin/spinner/spinner.c -new file mode 100644 -index 0000000..cffb3aa ---- /dev/null -+++ b/userland/testbin/spinner/spinner.c -@@ -0,0 +1,47 @@ -+/* -+ * spinner.c -+ * -+ * Spins as hard as it can, forking multiple processes as needed. Intended to -+ * test our ability to detect stuck processes in userspace. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+static -+void -+spin(void) -+{ -+ volatile int i; -+ -+ for (i=0; i <= 1000; i++) { -+ if (i == 1000) { -+ i = 0; -+ } -+ } -+} -+ -+int -+main(int argc, char **argv) -+{ -+ int i, count, pid; -+ -+ if (argc != 2) { -+ errx(1, "Usage: spinner "); -+ } -+ count = atoi(argv[1]); -+ -+ for (i = 1; i < count; i++) { -+ pid = fork(); -+ if (pid != 0) { -+ spin(); -+ } -+ } -+ spin(); -+ errx(2, "spinner: spin returned"); -+ -+ // 09 Jan 2015 : GWA : Shouldn't get here. -+ return 0; -+} -diff --git a/userland/testbin/waiter/Makefile b/userland/testbin/waiter/Makefile -new file mode 100644 -index 0000000..fdad038 ---- /dev/null -+++ b/userland/testbin/waiter/Makefile -@@ -0,0 +1,11 @@ -+# Makefile for waiter -+ -+TOP=../../.. -+.include "$(TOP)/mk/os161.config.mk" -+ -+PROG=waiter -+SRCS=waiter.c -+BINDIR=/testbin -+ -+.include "$(TOP)/mk/os161.prog.mk" -+ -diff --git a/userland/testbin/waiter/waiter.c b/userland/testbin/waiter/waiter.c -new file mode 100644 -index 0000000..575d631 ---- /dev/null -+++ b/userland/testbin/waiter/waiter.c -@@ -0,0 +1,29 @@ -+/* -+ * waiter.c -+ * -+ * Just sits there without doing anything. We use the read system call just to -+ * provide a way to wait. Intended to test our ability to detect stuck -+ * processes in userspace. -+ */ -+ -+#include -+#include -+ -+int -+main(void) -+{ -+ char ch=0; -+ int len; -+ -+ while (ch!='q') { -+ len = read(STDIN_FILENO, &ch, 1); -+ if (len < 0) { -+ err(1, "stdin: read"); -+ } -+ if (len==0) { -+ /* EOF */ -+ break; -+ } -+ } -+ return 0; -+}