Re: [libvirt] PATCH: 4/4: Test the event loop impl

2009-05-12 Thread Daniel Veillard
On Mon, May 11, 2009 at 12:25:08PM +0100, Daniel P. Berrange wrote:
 This patch adds a new test case to validate the various wierd scenarios that
 can occur when adding/removing/updating watches  timers in the event loop.
 In particular it checks
 
  - Handling of watches marked as deleted before virEventRunOnce 
  - Handling of watches marked as deleted during dispatch of poll() results
  - Correct interrupt of main thread if watches change during poll() sleep
 
 These are the 3 problems we've been hitting with all these issues. I've
 tested they all fail prior to this patch
 
   http://www.redhat.com/archives/libvir-list/2009-March/msg00246.html
 
 and now all 3 pass

  Okay, it would be great to have a slightly more generic framework
for event tesing using for example scenarios files, but that's a good
first step,

  ACK !

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] PATCH: 4/4: Test the event loop impl

2009-05-11 Thread Daniel P. Berrange
This patch adds a new test case to validate the various wierd scenarios that
can occur when adding/removing/updating watches  timers in the event loop.
In particular it checks

 - Handling of watches marked as deleted before virEventRunOnce 
 - Handling of watches marked as deleted during dispatch of poll() results
 - Correct interrupt of main thread if watches change during poll() sleep

These are the 3 problems we've been hitting with all these issues. I've
tested they all fail prior to this patch

  http://www.redhat.com/archives/libvir-list/2009-March/msg00246.html

and now all 3 pass

Daniel

diff -r d5dc15adcbea tests/.cvsignore
--- a/tests/.cvsignore  Fri May 08 11:58:19 2009 +0100
+++ b/tests/.cvsignore  Fri May 08 15:51:11 2009 +0100
@@ -16,6 +16,7 @@ nodeinfotest
 statstest
 qparamtest
 seclabeltest
+eventtest
 *.gcda
 *.gcno
 *.exe
diff -r d5dc15adcbea tests/Makefile.am
--- a/tests/Makefile.am Fri May 08 11:58:19 2009 +0100
+++ b/tests/Makefile.am Fri May 08 15:51:11 2009 +0100
@@ -125,6 +125,11 @@ if WITH_SECDRIVER_SELINUX
 TESTS += seclabeltest
 endif
 
+if WITH_LIBVIRTD
+noinst_PROGRAMS += eventtest
+TESTS += eventtest
+endif
+
 TESTS += nodedevxml2xmltest
 
 path_add = $$abs_top_builddir/src$(PATH_SEPARATOR)$$abs_top_builddir/qemud
@@ -226,4 +231,10 @@ qparamtest_SOURCES = \
qparamtest.c testutils.h testutils.c
 qparamtest_LDADD = $(LDADDS)
 
+if WITH_LIBVIRTD
+eventtest_SOURCES = \
+   eventtest.c testutils.h testutils.c ../qemud/event.c
+eventtest_LDADD = -lrt $(LDADDS)
+endif
+
 CLEANFILES = *.cov *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda
diff -r d5dc15adcbea tests/eventtest.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/tests/eventtest.c Fri May 08 15:51:11 2009 +0100
@@ -0,0 +1,444 @@
+/*
+ * eventtest.c: Test the libvirtd event loop impl
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Daniel P. Berrange berra...@redhat.com
+ */
+
+#include config.h
+
+#include stdlib.h
+#include signal.h
+#include time.h
+
+#include testutils.h
+#include internal.h
+#include threads.h
+#include logging.h
+#include ../qemud/event.h
+
+#define NUM_FDS 5
+#define NUM_TIME 5
+
+static struct handleInfo {
+int pipeFD[2];
+int fired;
+int watch;
+int error;
+int delete;
+} handles[NUM_FDS];
+
+static struct timerInfo {
+int timeout;
+int timer;
+int fired;
+int error;
+int delete;
+} timers[NUM_TIME];
+
+enum {
+EV_ERROR_NONE,
+EV_ERROR_WATCH,
+EV_ERROR_FD,
+EV_ERROR_EVENT,
+EV_ERROR_DATA,
+};
+
+static void
+testPipeReader(int watch, int fd, int events, void *data)
+{
+struct handleInfo *info = data;
+char one;
+
+info-fired = 1;
+
+if (watch != info-watch) {
+info-error = EV_ERROR_WATCH;
+return;
+}
+
+if (fd != info-pipeFD[0]) {
+info-error = EV_ERROR_FD;
+return;
+}
+
+if (!(events  VIR_EVENT_HANDLE_READABLE)) {
+info-error = EV_ERROR_EVENT;
+return;
+}
+if (read(fd, one, 1) != 1) {
+info-error = EV_ERROR_DATA;
+return;
+}
+info-error = EV_ERROR_NONE;
+
+if (info-delete != -1)
+virEventRemoveHandleImpl(info-delete);
+}
+
+
+static void
+testTimer(int timer, void *data)
+{
+struct timerInfo *info = data;
+
+info-fired = 1;
+
+if (timer != info-timer) {
+info-error = EV_ERROR_WATCH;
+return;
+}
+
+info-error = EV_ERROR_NONE;
+
+if (info-delete != -1)
+virEventRemoveTimeoutImpl(info-delete);
+}
+
+static pthread_mutex_t eventThreadMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t eventThreadRunCond = PTHREAD_COND_INITIALIZER;
+static int eventThreadRunOnce = 0;
+static pthread_cond_t eventThreadJobCond = PTHREAD_COND_INITIALIZER;
+static int eventThreadJobDone = 0;
+
+
+static void *eventThreadLoop(void *data ATTRIBUTE_UNUSED) {
+while (1) {
+pthread_mutex_lock(eventThreadMutex);
+while (!eventThreadRunOnce) {
+pthread_cond_wait(eventThreadRunCond, eventThreadMutex);
+}
+eventThreadRunOnce = 0;
+pthread_mutex_unlock(eventThreadMutex);
+
+virEventRunOnce();
+
+pthread_mutex_lock(eventThreadMutex);
+eventThreadJobDone = 1;