From 94ffafbb4095fb242f5d05274815a29667d51d03 Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Sun, 11 Sep 2016 21:36:42 -0400 Subject: [PATCH] Add contrib/pwmd-stress-test.c. --- Makefile.am | 2 +- configure.ac | 5 +- contrib/Makefile.am | 7 ++ contrib/pwmd-stress-test.c | 220 +++++++++++++++++++++++++++++++++++++++++++++ src/Makefile.am | 3 +- 5 files changed, 232 insertions(+), 5 deletions(-) create mode 100644 contrib/Makefile.am create mode 100644 contrib/pwmd-stress-test.c diff --git a/Makefile.am b/Makefile.am index f8645ef8..7958979d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ EXTRA_DIST = TODO ChangeLog INSTALL NEWS debian ABOUT-NLS libpwmd-8.0.pc.in -SUBDIRS = doc src po +SUBDIRS = doc src po contrib ACLOCAL_AMFLAGS = -I m4 install-data-hook: diff --git a/configure.ac b/configure.ac index d0bb08f1..02a8f98c 100644 --- a/configure.ac +++ b/configure.ac @@ -272,8 +272,9 @@ if test "x$WITH_QUALITY" = "xyes"; then fi AM_CONDITIONAL(WITH_QUALITY, [test "x$WITH_QUALITY" = "xyes"]) -AC_CONFIG_FILES([Makefile libpwmd-8.0.pc doc/Makefile doc/doxygen.conf.in \ - doc/pwmc.1 src/Makefile src/libpwmd.h po/Makefile.in]) +AC_CONFIG_FILES([Makefile libpwmd-8.0.pc doc/Makefile contrib/Makefile \ + doc/doxygen.conf.in doc/pwmc.1 src/Makefile src/libpwmd.h \ + po/Makefile.in]) AC_OUTPUT echo echo "Features:" diff --git a/contrib/Makefile.am b/contrib/Makefile.am new file mode 100644 index 00000000..67a10385 --- /dev/null +++ b/contrib/Makefile.am @@ -0,0 +1,7 @@ +DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(top_builddir)/src + +noinst_PROGRAMS = pwmd-stress-test +pwmd_stress_test_SOURCES = pwmd-stress-test.c +pwmd_stress_test_CFLAGS = @GPG_ERROR_CFLAGS@ +pwmd_stress_test_LDFLAGS = @GPG_ERROR_LIBS@ +pwmd_stress_test_LDADD = $(top_builddir)/src/libpwmd.la diff --git a/contrib/pwmd-stress-test.c b/contrib/pwmd-stress-test.c new file mode 100644 index 00000000..2ce16d1c --- /dev/null +++ b/contrib/pwmd-stress-test.c @@ -0,0 +1,220 @@ +/* + Copyright (C) 2016 + Ben Kibbey + + This file is part of libpwmd. + + Libpwmd is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Libpwmd 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Libpwmd. If not, see . +*/ +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include + +static char *socket, *file, *cmd; +static int remaining; +static pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER; +static int lock; +static int states; +static int lock_timeout; +static int quiet; + +static gpg_error_t +status_cb (void *data, const char *line) +{ + pthread_t tid = pthread_self (); + + if (quiet < 1) + fprintf(stdout, "STATUS: %p: %s\n", (pthread_t *)tid, line); + return 0; +} + +void * +start (void *data) +{ + pwm_t *pwm = NULL; + gpg_error_t rc; + pthread_t tid = pthread_self (); + char *result; + + if (quiet < 2) + fprintf(stdout, "START: %p\n", (pthread_t *)tid); + rc = pwmd_new ("test-client", &pwm); + if (rc) + goto fail; + + pwmd_setopt (pwm, PWMD_OPTION_LOCK_ON_OPEN, lock); + pwmd_setopt (pwm, PWMD_OPTION_STATUS_CB, status_cb); + + rc = pwmd_connect (pwm, socket, NULL); + if (rc) + goto fail; + + if (lock_timeout) + { + rc = pwmd_command (pwm, NULL, NULL, NULL, NULL, "OPTION lock-timeout=%i", + lock_timeout); + if (rc) + goto fail; + } + + if (states) + { + rc = pwmd_command (pwm, NULL, NULL, NULL, NULL, "OPTION client-state=%i", + states); + if (rc) + goto fail; + } + + rc = pwmd_process (pwm); + if (rc) + goto fail; + + if (file) + { + rc = pwmd_open (pwm, file, NULL, NULL); + if (rc) + goto fail; + } + + rc = pwmd_process (pwm); + if (rc) + goto fail; + + rc = pwmd_command (pwm, &result, NULL, NULL, NULL, cmd); + if (rc) + goto fail; + + if (quiet < 1) + fprintf(stdout, "RESULT: %p: '%s'\n", (pthread_t *) tid, result); + pwmd_free (result); + rc = pwmd_process (pwm); + +fail: + pwmd_close (pwm); + + if (rc && quiet < 3) + fprintf(stdout, "ERROR: %p: %u: %s\n", (pthread_t *)tid, rc, + gpg_strerror(rc)); + + pthread_mutex_lock (&count_mutex); + remaining--; + pthread_mutex_unlock (&count_mutex); + if (quiet < 2) + fprintf(stdout, "END: %p\n", (pthread_t *)tid); + pthread_exit (NULL); + return NULL; +} + +static void +usage (const char *pn, int status) +{ + fprintf(status == EXIT_SUCCESS ? stdout : stderr, + "Usage: %s [-hsnq] [-l N] [] ''\n", pn); + fprintf(status == EXIT_SUCCESS ? stdout : stderr, + " -n don't lock data file mutex\n" + " -l N lock timeout in tenths of a second\n" + " -q quiet (can be used more than once)\n" + " -s receive client state status messages\n" + " -h this help text\n"); + exit (status); +} + +int main(int argc, char **argv) +{ + int i; + pthread_attr_t attr; + unsigned nclients; + int opt; + + lock = 1; + + while ((opt = getopt (argc, argv, "hnsl:q")) != -1) + { + switch (opt) + { + case 'q': + quiet++; + break; + case 'l': + lock_timeout = atoi (optarg); + break; + case 'n': + lock = 0; + break; + case 's': + states = 1; + break; + case 'h': + usage (argv[0], EXIT_SUCCESS); + break; + } + } + + if (argc - optind < 3) + usage (argv[0], EXIT_FAILURE); + + nclients = atoi (argv[optind++]); + socket = strdup (argv[optind++]); + + if ((argc-optind) > 1) + file = strdup (argv[optind++]); + + cmd = strdup (argv[optind++]); + if (quiet < 2) + fprintf(stdout, "Doing: '%s'\n", cmd); + pwmd_init (); + pthread_attr_init (&attr); + pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + + for (i = 0; i < nclients; i++) + { + pthread_t tid; + int e = pthread_create (&tid, NULL, start, NULL); + + if (e) + { + if (quiet < 3) + fprintf(stdout, "%s\n", strerror (e)); + continue; + } + + pthread_mutex_lock (&count_mutex); + remaining++; + pthread_mutex_unlock (&count_mutex); + } + + pthread_attr_destroy (&attr); + + for (; remaining;) + { + int n; + + pthread_mutex_lock (&count_mutex); + n = remaining; + pthread_mutex_unlock (&count_mutex); + + if (quiet < 2) + fprintf(stdout, "%i clients remain ...\n", n); + usleep (100000); + } + + pwmd_deinit (); + exit (EXIT_SUCCESS); +} diff --git a/src/Makefile.am b/src/Makefile.am index 9990501b..52419cbe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,8 +40,7 @@ endif pwmc_CFLAGS = -DLOCALEDIR=\"${prefix}/share/locale\" @GPG_ERROR_CFLAGS@ \ @GNUTLS_CFLAGS@ @libssh2_CFLAGS@ @LIBASSUAN_CFLAGS@ pwmc_LDFLAGS = @GPG_ERROR_LIBS@ @LIBASSUAN_LIBS@ @GNUTLS_LIBS@ @libssh2_LIBS@ -pwmc_LDADD= -lpwmd -pwmc_DEPENDENCIES= libpwmd.la +pwmc_LDADD = libpwmd.la if WITH_READLINE pwmc_LDFLAGS += @READLINE_LIBS@ -- 2.11.4.GIT