Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/tests/lib Add tests for semaphores. Note: the "unlink" one ...



details:   https://anonhg.NetBSD.org/src/rev/51925a187ff3
branches:  trunk
changeset: 755595:51925a187ff3
user:      pooka <pooka%NetBSD.org@localhost>
date:      Thu Jun 10 22:03:43 2010 +0000

description:
Add tests for semaphores.  Note: the "unlink" one fails because our
implementation is broken.  I'll file a PR shortly.

diffstat:

 tests/lib/Makefile                      |    4 +-
 tests/lib/semaphore/Atffile             |    6 +
 tests/lib/semaphore/Makefile            |    9 +
 tests/lib/semaphore/pthread/Atffile     |    6 +
 tests/lib/semaphore/pthread/Makefile    |   15 +
 tests/lib/semaphore/pthread/t_sem_pth.c |   16 +
 tests/lib/semaphore/sem.c               |  299 ++++++++++++++++++++++++++++++++
 7 files changed, 353 insertions(+), 2 deletions(-)

diffs (truncated from 389 to 300 lines):

diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/Makefile
--- a/tests/lib/Makefile        Thu Jun 10 22:00:02 2010 +0000
+++ b/tests/lib/Makefile        Thu Jun 10 22:03:43 2010 +0000
@@ -1,8 +1,8 @@
-# $NetBSD: Makefile,v 1.2 2009/11/02 10:15:45 plunky Exp $
+# $NetBSD: Makefile,v 1.3 2010/06/10 22:03:43 pooka Exp $
 
 .include <bsd.own.mk>
 
-SUBDIR=                libc libevent
+SUBDIR=                libc libevent semaphore
 
 TESTSDIR=      ${TESTSBASE}/lib
 
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/Atffile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/Atffile       Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,6 @@
+Content-Type: application/X-atf-atffile; version="1"
+X-NetBSD-Id: "$NetBSD: Atffile,v 1.1 2010/06/10 22:03:43 pooka Exp $"
+
+prop: test-suite = "NetBSD"
+
+tp: pthread
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/Makefile      Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,9 @@
+#      $NetBSD: Makefile,v 1.1 2010/06/10 22:03:43 pooka Exp $
+#
+
+SUBDIR=                pthread
+
+TESTSDIR=      ${TESTSBASE}/lib/semaphore
+
+.include <bsd.test.mk>
+.include <bsd.subdir.mk>
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/pthread/Atffile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/pthread/Atffile       Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,6 @@
+Content-Type: application/X-atf-atffile; version="1"
+X-NetBSD-Id: "$NetBSD: Atffile,v 1.1 2010/06/10 22:03:43 pooka Exp $"
+
+prop: test-suite = "NetBSD"
+
+tp-glob: t_*
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/pthread/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/pthread/Makefile      Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,15 @@
+# $NetBSD: Makefile,v 1.1 2010/06/10 22:03:43 pooka Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR=      ${TESTSBASE}/lib/semaphore/pthread
+
+TESTS_C=       t_sem_pth
+
+CPPFLAGS+=     -I${.CURDIR}/..
+
+LDADD+=                -lrumpkern_ksem -lrump -lrumpuser -lpthread
+
+WARNS= 4
+
+.include <bsd.test.mk>
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/pthread/t_sem_pth.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/pthread/t_sem_pth.c   Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,16 @@
+#define LIBNAME "pthread"
+#include "sem.c"
+
+ATF_TP_ADD_TCS(tp)
+{
+
+       ATF_TP_ADD_TC(tp, postwait);
+       ATF_TP_ADD_TC(tp, initvalue);
+       ATF_TP_ADD_TC(tp, destroy);
+       ATF_TP_ADD_TC(tp, busydestroy);
+       ATF_TP_ADD_TC(tp, blockwait);
+       ATF_TP_ADD_TC(tp, named);
+       ATF_TP_ADD_TC(tp, unlink);
+
+       return atf_no_error();
+}
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/sem.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/sem.c Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,299 @@
+/*     $NetBSD: sem.c,v 1.1 2010/06/10 22:03:43 pooka Exp $    */
+
+/*
+ * Common code for semaphore tests.  This can be included both into
+ * programs using librt and libpthread.
+ */
+
+#include <sys/types.h>
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../../h_macros.h"
+
+ATF_TC(postwait);
+ATF_TC_HEAD(postwait, tc)
+{
+
+       atf_tc_set_md_var(tc, "descr", "tests post and wait from a "
+           "single thread (%s)", LIBNAME);
+}
+
+ATF_TC_BODY(postwait, tc)
+{
+       sem_t sem;
+       int rv;
+
+       rump_init();
+
+       ATF_REQUIRE_EQ(sem_init(&sem, 1, 0), 0);
+
+       sem_post(&sem);
+       sem_post(&sem);
+
+       sem_wait(&sem);
+       sem_wait(&sem);
+       rv = sem_trywait(&sem);
+       ATF_REQUIRE(errno == EAGAIN);
+       ATF_REQUIRE(rv == -1);
+}
+
+ATF_TC(initvalue);
+ATF_TC_HEAD(initvalue, tc)
+{
+
+       atf_tc_set_md_var(tc, "descr", "tests initialization with a non-zero "
+           "value (%s)", LIBNAME);
+}
+
+ATF_TC_BODY(initvalue, tc)
+{
+       sem_t sem;
+
+       rump_init();
+       sem_init(&sem, 1, 4);
+
+       ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+       ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+       ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+       ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+       ATF_REQUIRE_EQ(sem_trywait(&sem), -1);
+}
+
+ATF_TC(destroy);
+ATF_TC_HEAD(destroy, tc)
+{
+
+       atf_tc_set_md_var(tc, "descr", "tests sem_destroy works (%s)", LIBNAME);
+}
+
+ATF_TC_BODY(destroy, tc)
+{
+       sem_t sem;
+       int rv, i;
+
+       rump_init();
+       for (i = 0; i < 2; i++) {
+               sem_init(&sem, 1, 1);
+
+               ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+               ATF_REQUIRE_EQ(sem_trywait(&sem), -1);
+               ATF_REQUIRE_EQ(sem_destroy(&sem), 0);
+               rv = sem_trywait(&sem);
+               ATF_REQUIRE_EQ(errno, EINVAL);
+               ATF_REQUIRE_EQ(rv, -1);
+       }
+}
+
+ATF_TC(busydestroy);
+ATF_TC_HEAD(busydestroy, tc)
+{
+
+       atf_tc_set_md_var(tc, "descr", "tests sem_destroy report EBUSY for "
+           "a busy semaphore (%s)", LIBNAME);
+}
+
+static void *
+hthread(void *arg)
+{
+       sem_t *semmarit = arg;
+
+       for (;;) {
+               sem_post(&semmarit[2]);
+               sem_wait(&semmarit[1]);
+               sem_wait(&semmarit[0]);
+       }
+}
+
+ATF_TC_BODY(busydestroy, tc)
+{
+       sem_t semmarit[3];
+       pthread_t pt;
+       int i;
+
+       /* use a unicpu rump kernel.  this means less chance for race */
+       setenv("RUMP_NCPU", "1", 1);
+
+       rump_init();
+       sem_init(&semmarit[0], 1, 0);
+       sem_init(&semmarit[1], 1, 0);
+       sem_init(&semmarit[2], 1, 0);
+
+       pthread_create(&pt, NULL, hthread, semmarit);
+
+       /*
+        * Make a best-effort to catch the other thread with its pants down.
+        * We can't do this for sure, can we?  Although, we could reach
+        * inside the rump kernel and inquire about the thread's sleep
+        * status.
+        */
+       for (i = 0; i < 1000; i++) {
+               sem_wait(&semmarit[2]);
+               usleep(1);
+               if (sem_destroy(&semmarit[1]) == -1)
+                       if (errno == EBUSY)
+                               break;
+
+               /*
+                * Didn't catch it?  ok, recreate and post to make the
+                * other thread run
+                */
+               sem_init(&semmarit[1], 1, 0);
+               sem_post(&semmarit[0]);
+               sem_post(&semmarit[1]);
+
+       }
+       if (i == 1000)
+               atf_tc_fail("sem destroy not reporting EBUSY");
+}
+
+ATF_TC(blockwait);
+ATF_TC_HEAD(blockwait, tc)
+{
+
+       atf_tc_set_md_var(tc, "descr", "tests sem_wait can handle blocking "
+           "(%s)", LIBNAME);
+}
+
+ATF_TC_BODY(blockwait, tc)
+{
+       sem_t semmarit[3];
+       pthread_t pt;
+       int i;
+
+       rump_init();
+       sem_init(&semmarit[0], 1, 0);
+       sem_init(&semmarit[1], 1, 0);
+       sem_init(&semmarit[2], 1, 0);
+
+       pthread_create(&pt, NULL, hthread, semmarit);
+
+       /*
+        * Make a best-effort.  Unless we're extremely unlucky, we should
+        * at least one blocking wait.
+        */
+       for (i = 0; i < 10; i++) {
+               sem_wait(&semmarit[2]);
+               usleep(1);
+               sem_post(&semmarit[0]);
+               sem_post(&semmarit[1]);
+
+       }
+       if (i == 1000)
+               atf_tc_fail("sem destroy not reporting EBUSY");
+}
+
+ATF_TC(named);
+ATF_TC_HEAD(named, tc)
+{
+
+       atf_tc_set_md_var(tc, "descr", "tests named semaphores (%s)", LIBNAME);
+}
+
+/*
+ * Wow, easy naming rules.  it's these times i'm really happy i can
+ * single-step into the kernel.
+ */
+#define SEM1 "/my_precious_sem"
+#define SEM2 "/justsem"



Home | Main Index | Thread Index | Old Index