summaryrefslogtreecommitdiff
path: root/qa/pmdas
diff options
context:
space:
mode:
Diffstat (limited to 'qa/pmdas')
-rw-r--r--qa/pmdas/GNUmakefile25
-rw-r--r--qa/pmdas/GNUmakefile.install40
-rw-r--r--qa/pmdas/bigun/GNUmakefile32
-rw-r--r--qa/pmdas/bigun/GNUmakefile.install43
-rwxr-xr-xqa/pmdas/bigun/Install24
-rwxr-xr-xqa/pmdas/bigun/Remove11
-rw-r--r--qa/pmdas/bigun/bigun.c71
-rw-r--r--qa/pmdas/bigun/domain.h2
-rw-r--r--qa/pmdas/bigun/help1
-rw-r--r--qa/pmdas/bigun/pmns4
-rw-r--r--qa/pmdas/bigun/root5
-rw-r--r--qa/pmdas/broken/GNUmakefile83
-rw-r--r--qa/pmdas/broken/GNUmakefile.install97
-rwxr-xr-xqa/pmdas/broken/broken_Install30
-rwxr-xr-xqa/pmdas/broken/broken_Remove24
-rw-r--r--qa/pmdas/broken/broken_help39
-rw-r--r--qa/pmdas/broken/broken_pmda.c387
-rw-r--r--qa/pmdas/broken/broken_pmda.v1.c386
-rw-r--r--qa/pmdas/broken/broken_pmns36
-rw-r--r--qa/pmdas/broken/domain.h1
-rw-r--r--qa/pmdas/dynamic/GNUmakefile29
-rw-r--r--qa/pmdas/dynamic/GNUmakefile.install39
-rwxr-xr-xqa/pmdas/dynamic/Install16
-rwxr-xr-xqa/pmdas/dynamic/Remove14
-rw-r--r--qa/pmdas/dynamic/domain.h1
-rw-r--r--qa/pmdas/dynamic/dynamic.c420
-rw-r--r--qa/pmdas/dynamic/help25
-rw-r--r--qa/pmdas/dynamic/pmns18
-rw-r--r--qa/pmdas/dynamic/root5
-rw-r--r--qa/pmdas/slow/GNUmakefile37
-rw-r--r--qa/pmdas/slow/GNUmakefile.install5
-rwxr-xr-xqa/pmdas/slow/Install38
-rwxr-xr-xqa/pmdas/slow/Remove25
-rw-r--r--qa/pmdas/slow/pmdaslow.pl74
-rw-r--r--qa/pmdas/slow_python/GNUmakefile40
-rw-r--r--qa/pmdas/slow_python/GNUmakefile.install5
-rwxr-xr-xqa/pmdas/slow_python/Install38
-rwxr-xr-xqa/pmdas/slow_python/Remove25
-rw-r--r--qa/pmdas/slow_python/pmdaslow_python.python84
39 files changed, 2279 insertions, 0 deletions
diff --git a/qa/pmdas/GNUmakefile b/qa/pmdas/GNUmakefile
new file mode 100644
index 0000000..2a8805b
--- /dev/null
+++ b/qa/pmdas/GNUmakefile
@@ -0,0 +1,25 @@
+#!gmake
+#
+# Copyright (c) 2012 Red Hat.
+# Copyright (c) 2010 Aconex. All Rights Reserved.
+#
+
+TOPDIR = ../..
+include $(TOPDIR)/src/include/builddefs
+
+TESTDIR = $(PCP_VAR_DIR)/testsuite/pmdas
+SUBDIRS = broken bigun dynamic slow slow_python
+LSRCFILES = GNUmakefile.install
+
+default default_pcp: $(SUBDIRS)
+ $(SUBDIRS_MAKERULE)
+
+setup: $(SUBDIRS)
+ $(SUBDIRS_MAKERULE)
+
+install install_pcp: $(SUBDIRS)
+ $(INSTALL) -m 755 -d $(TESTDIR)
+ $(INSTALL) -m 644 GNUmakefile.install $(TESTDIR)/GNUmakefile
+ $(SUBDIRS_MAKERULE)
+
+include $(BUILDRULES)
diff --git a/qa/pmdas/GNUmakefile.install b/qa/pmdas/GNUmakefile.install
new file mode 100644
index 0000000..bd16ec2
--- /dev/null
+++ b/qa/pmdas/GNUmakefile.install
@@ -0,0 +1,40 @@
+#!gmake
+#
+# Copyright (c) 2012 Red Hat.
+# Copyright (c) 2010 Aconex. All Rights Reserved.
+#
+
+ifdef PCP_CONF
+include $(PCP_CONF)
+else
+include $(PCP_DIR)/etc/pcp.conf
+endif
+PATH = $(shell . $(PCP_DIR)/etc/pcp.env; echo $$PATH)
+include $(PCP_INC_DIR)/builddefs
+
+# special variant of SUBDIRS_MAKERULE for running QA in the tree
+#
+SUBDIRS_MAKERULE = \
+ @for d in `echo $^ `; do \
+ if test -d "$$d" ; then \
+ $(ECHO) === $$d ===; \
+ if test -f "$$d/GNUmakefile.install"; then \
+ $(MAKE) -C $$d -f GNUmakefile.install $@ || exit $$?; \
+ else \
+ $(MAKE) -C $$d $@ || exit $$?; \
+ fi; \
+ fi; \
+ done
+
+SUBDIRS = broken bigun dynamic slow slow_python
+
+default default_pcp: $(SUBDIRS)
+ $(SUBDIRS_MAKERULE)
+
+setup: $(SUBDIRS)
+ $(SUBDIRS_MAKERULE)
+
+install install_pcp: $(SUBDIRS)
+ $(SUBDIRS_MAKERULE)
+
+include $(BUILDRULES)
diff --git a/qa/pmdas/bigun/GNUmakefile b/qa/pmdas/bigun/GNUmakefile
new file mode 100644
index 0000000..a4160d9
--- /dev/null
+++ b/qa/pmdas/bigun/GNUmakefile
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2012 Red Hat.
+# Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+#
+
+TOPDIR = ../../..
+include $(TOPDIR)/src/include/builddefs
+
+TESTDIR = $(PCP_VAR_DIR)/testsuite/pmdas/bigun
+
+CFILES = bigun.c
+LIBTARGET = bigun.$(DSOSUFFIX)
+TARGETS = $(LIBTARGET)
+MYFILES = domain.h help pmns root
+MYSCRIPTS = Install Remove
+LSRCFILES = $(MYFILES) $(MYSCRIPTS) GNUmakefile.install
+LDIRT = help.pag help.dir
+
+LLDFLAGS = $(PCP_LIBS)
+LLDLIBS = $(PCP_PMDALIB)
+
+default default_pcp setup: $(TARGETS)
+
+$(LIBTARGET): bigun.o
+
+install install_pcp:
+ $(INSTALL) -m 755 -d $(TESTDIR)
+ $(INSTALL) -m 644 $(CFILES) $(MYFILES) $(TESTDIR)
+ $(INSTALL) -m 755 $(MYSCRIPTS) $(TARGETS) $(TESTDIR)
+ $(INSTALL) -m 644 GNUmakefile.install $(TESTDIR)/GNUmakefile
+
+include $(BUILDRULES)
diff --git a/qa/pmdas/bigun/GNUmakefile.install b/qa/pmdas/bigun/GNUmakefile.install
new file mode 100644
index 0000000..bc8f87e
--- /dev/null
+++ b/qa/pmdas/bigun/GNUmakefile.install
@@ -0,0 +1,43 @@
+#!gmake
+#
+# Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+#
+
+SHELL = sh
+
+ifdef PCP_CONF
+include $(PCP_CONF)
+else
+include $(PCP_DIR)/etc/pcp.conf
+endif
+include $(PCP_INC_DIR)/builddefs
+
+# remove -Lpath and -Ipath options from builddefs CFLAGS value
+#
+PCP_LIBS =
+TMP := $(CFLAGS:-I%=)
+ifdef PCP_DIR
+# put -Ipath and -Lpath back but use paths for run-time environment
+#
+CFLAGS = $(TMP) -I$(PCP_INC_DIR)/..
+LDFLAGS = -L$(PCP_LIB_DIR)
+else
+CFLAGS = $(TMP)
+endif
+
+CFILES = bigun.c
+LIBTARGET = bigun.$(DSOSUFFIX)
+TARGETS = $(LIBTARGET)
+MYFILES = domain.h help pmns root
+MYSCRIPTS = Install Remove
+LDIRT = help.pag help.dir
+
+LLDLIBS = -lpcp_pmda -lpcp $(LIB_FOR_MATH) $(LIB_FOR_DLOPEN) $(LIB_FOR_PTHREADS)
+
+default default_pcp setup: $(TARGETS)
+
+$(LIBTARGET): bigun.o
+
+install install_pcp:
+
+include $(PCP_INC_DIR)/buildrules
diff --git a/qa/pmdas/bigun/Install b/qa/pmdas/bigun/Install
new file mode 100755
index 0000000..4845424
--- /dev/null
+++ b/qa/pmdas/bigun/Install
@@ -0,0 +1,24 @@
+#! /bin/sh
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+if [ -f GNUmakefile.install ]
+then
+ # running within the source tree, not in the 'testsuite' directory
+ #
+ PCP_MAKE_PROG="$PCP_MAKE_PROG -f GNUmakefile.install"
+fi
+
+# Make sure DSO PMDA exists
+make
+
+iam=bigun
+pmda_interface=4
+dso_opt=true
+dso_name=`pwd`/bigun.${dso_suffix}
+daemon_opt=false
+
+pmdaSetup
+pmdaInstall
+exit 0
diff --git a/qa/pmdas/bigun/Remove b/qa/pmdas/bigun/Remove
new file mode 100755
index 0000000..1061fd5
--- /dev/null
+++ b/qa/pmdas/bigun/Remove
@@ -0,0 +1,11 @@
+#! /bin/sh
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=bigun
+
+pmdaSetup
+pmdaRemove
+
+exit 0
diff --git a/qa/pmdas/bigun/bigun.c b/qa/pmdas/bigun/bigun.c
new file mode 100644
index 0000000..735d952
--- /dev/null
+++ b/qa/pmdas/bigun/bigun.c
@@ -0,0 +1,71 @@
+/*
+ * bigun PMDA ... one big value for QA
+ *
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+static pmdaMetric metrics[] = {
+ { NULL,
+ { PMDA_PMID(0,0), PM_TYPE_AGGREGATE_STATIC, PM_INDOM_NULL, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }
+};
+
+#define MYSIZE (1024*1024)
+static pmValueBlock *vbp;
+
+/*
+ * callback provided to pmdaFetch
+ */
+static int
+bigun_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
+{
+ if (pmid_cluster(mdesc->m_desc.pmid) != 0 ||
+ pmid_item(mdesc->m_desc.pmid) != 0)
+ return PM_ERR_PMID;
+ if (inst != PM_IN_NULL)
+ return PM_ERR_INST;
+
+ atom->vbp = vbp;
+ return 1;
+}
+
+/* Initialise the DSO agent */
+void
+bigun_init(pmdaInterface *dp)
+{
+ int i;
+ int sep = __pmPathSeparator();
+ char helppath[MAXPATHLEN];
+
+ /*
+ * Note: helpfile is only available if the PMDA has been installed
+ * from $PCP_VAR_DIR/testsuite/pmdas/bigun ... when the PMDA install
+ * comes from QA run from some other directory, the helpfile may not
+ * be found ... fortunately nothing in QA depends on the helpfile
+ * being available for the bigun PMDA.
+ */
+ snprintf(helppath, sizeof(helppath),
+ "%s%c" "testsuite" "%c" "pmdas" "%c" "bigun" "%c" "help",
+ pmGetConfig("PCP_VAR_DIR"), sep, sep, sep, sep);
+ pmdaDSO(dp, PMDA_INTERFACE_4, "bigun DSO", helppath);
+ if (dp->status != 0)
+ return;
+
+ pmdaSetFetchCallBack(dp, bigun_fetchCallBack);
+ pmdaInit(dp, NULL, 0, metrics, sizeof(metrics)/sizeof(metrics[0]));
+
+ vbp = (pmValueBlock *)malloc(PM_VAL_HDR_SIZE+MYSIZE);
+ if (vbp == NULL) {
+ fprintf(stderr, "bigun_init: malloc failed: %s\n", pmErrStr(-errno));
+ exit(1);
+ }
+ vbp->vtype = PM_TYPE_AGGREGATE_STATIC;
+ vbp->vlen = PM_VAL_HDR_SIZE+MYSIZE;
+ for (i = 0; i < MYSIZE; i += sizeof(int))
+ memcpy((void *)&vbp->vbuf[i], (void *)&i, sizeof(int));
+}
diff --git a/qa/pmdas/bigun/domain.h b/qa/pmdas/bigun/domain.h
new file mode 100644
index 0000000..6f108f2
--- /dev/null
+++ b/qa/pmdas/bigun/domain.h
@@ -0,0 +1,2 @@
+/* reuse the QA BROKEN domain id */
+#define BIGUN 249
diff --git a/qa/pmdas/bigun/help b/qa/pmdas/bigun/help
new file mode 100644
index 0000000..70fd765
--- /dev/null
+++ b/qa/pmdas/bigun/help
@@ -0,0 +1 @@
+@ bigun.sumo one big value
diff --git a/qa/pmdas/bigun/pmns b/qa/pmdas/bigun/pmns
new file mode 100644
index 0000000..8d52234
--- /dev/null
+++ b/qa/pmdas/bigun/pmns
@@ -0,0 +1,4 @@
+bigun {
+ sumo 249:0:0
+}
+
diff --git a/qa/pmdas/bigun/root b/qa/pmdas/bigun/root
new file mode 100644
index 0000000..80ad70e
--- /dev/null
+++ b/qa/pmdas/bigun/root
@@ -0,0 +1,5 @@
+root {
+ bigun
+}
+
+#include "pmns"
diff --git a/qa/pmdas/broken/GNUmakefile b/qa/pmdas/broken/GNUmakefile
new file mode 100644
index 0000000..4834cad
--- /dev/null
+++ b/qa/pmdas/broken/GNUmakefile
@@ -0,0 +1,83 @@
+#
+# Copyright (c) 2012 Red Hat.
+# Copyright (c) 2009-2010 Aconex. All Rights Reserved.
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+TOPDIR = ../../..
+include $(TOPDIR)/src/include/builddefs
+
+STDPMID = $(TOPDIR)/src/pmns/stdpmid
+TESTDIR = $(PCP_VAR_DIR)/testsuite/pmdas/broken
+
+CFILES = broken_pmda.c
+CFILES_TARGETS = $(CFILES)
+
+TARGETS = $(subst broken_pmda,,$(basename $(CFILES_TARGETS))) \
+ broken_pmda_2_0 broken_pmda_2_1 broken_pmda_2_2 \
+ broken_pmda_2_3 broken_pmda_2_4 broken_pmda_2_5
+
+LLDFLAGS = $(PCP_LIBS)
+LLDLIBS = $(PCPLIB)
+
+# all archives, except the ones checked into the source tree,
+# then add executables beyond $(TARGETS)
+#
+LDIRT = *.log help.pag help.dir $(subst .c,.o,$(CFILES)) \
+ broken_pmda_*.c real_broken_pmns broken_v?.dir broken_v?.pag \
+ $(TARGETS)
+
+default default_pcp setup: $(CFILES_TARGETS) $(TARGETS)
+
+MYFILES = broken_help broken_pmns domain.h
+MYSCRIPTS = broken_Install broken_Remove
+LSRCFILES += $(MYFILES) $(MYSCRIPTS) GNUmakefile.install
+
+include $(BUILDRULES)
+
+$(TARGETS):
+
+install install_pcp:
+ $(INSTALL) -m 755 -d $(TESTDIR)
+ $(INSTALL) -m 644 $(CFILES) $(MYFILES) $(TESTDIR)
+ $(INSTALL) -m 755 $(MYSCRIPTS) $(TARGETS) $(TESTDIR)
+ $(INSTALL) -m 644 GNUmakefile.install $(TESTDIR)/GNUmakefile
+
+real_broken_pmns: domain.h broken_pmns
+ cat domain.h >real_broken_pmns
+ echo >>real_broken_pmns
+ echo 'root {' >>real_broken_pmns
+ echo ' broken' >>real_broken_pmns
+ echo '}' >>real_broken_pmns
+ echo >>real_broken_pmns
+ cat broken_pmns >>real_broken_pmns
+
+broken_pmda_2_0: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -o $@ $@.c -lpcp_pmda $(LDLIBS) $(LDFLAGS)
+
+broken_pmda_2_1: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -DBUG_1 -o $@ $@.c -lpcp_pmda $(LDLIBS) $(LDFLAGS)
+
+broken_pmda_2_2: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -DBUG_2 -o $@ $@.c -lpcp_pmda $(LDLIBS) $(LDFLAGS)
+
+broken_pmda_2_3: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -DBUG_3 -o $@ $@.c -lpcp_pmda $(LDLIBS) $(LDFLAGS)
+
+broken_pmda_2_4: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -DBUG_4 -o $@ $@.c -lpcp_pmda $(LDLIBS) $(LDFLAGS)
+
+broken_pmda_2_5: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -DBUG_5 -o $@ $@.c -lpcp_pmda $(LDLIBS) $(LDFLAGS)
diff --git a/qa/pmdas/broken/GNUmakefile.install b/qa/pmdas/broken/GNUmakefile.install
new file mode 100644
index 0000000..44f7722
--- /dev/null
+++ b/qa/pmdas/broken/GNUmakefile.install
@@ -0,0 +1,97 @@
+#!gmake
+#
+# Copyright (c) 2009-2010 Aconex. All Rights Reserved.
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+ifdef PCP_CONF
+include $(PCP_CONF)
+else
+include $(PCP_DIR)/etc/pcp.conf
+endif
+PATH = $(shell . $(PCP_DIR)/etc/pcp.env; echo $$PATH)
+include $(PCP_INC_DIR)/builddefs
+
+STDPMID = $(PCP_VAR_DIR)/pmns/stdpmid
+
+# remove -Lpath and -Ipath options from builddefs CFLAGS value
+#
+PCP_LIBS =
+TMP := $(CFLAGS:-I%=)
+ifdef PCP_DIR
+# put -Ipath and -Lpath back but use paths for run-time environment
+#
+CFLAGS = $(TMP) -I$(PCP_INC_DIR)/.. -L$(PCP_LIB_DIR)
+else
+CFLAGS = $(TMP)
+endif
+CFILES = broken_pmda.c
+CFILES_TARGETS = $(CFILES)
+
+TARGETS = $(subst broken_pmda,,$(basename $(CFILES_TARGETS))) \
+ broken_pmda_2_0 broken_v2.dir broken_pmda_2_1 broken_pmda_2_2 \
+ broken_pmda_2_3 broken_pmda_2_4 broken_pmda_2_5
+
+LLDLIBS = -lpcp $(LIB_FOR_MATH) $(LIB_FOR_DLOPEN) $(LIB_FOR_PTHREADS)
+
+
+# all archives, except the ones checked into the source tree,
+# then add executables beyond $(TARGETS)
+#
+LDIRT = *.log help.pag help.dir $(subst .c,.o,$(CFILES)) \
+ broken_pmda_*.c real_broken_pmns broken_v?.dir broken_v?.pag \
+ $(TARGETS)
+
+default default_pcp setup: $(CFILES_TARGETS) $(TARGETS)
+
+MYFILES = broken_help broken_pmns
+MYSCRIPTS = broken_Install broken_Remove
+
+include $(PCP_INC_DIR)/buildrules
+
+$(TARGETS):
+
+install install_pcp:
+
+broken_v2.dir: broken_help real_broken_pmns
+ rm -f broken_v2.pag broken_v2.dir
+ newhelp -n real_broken_pmns -v 2 -o broken_v2 broken_help
+
+real_broken_pmns: domain.h broken_pmns
+ cat domain.h >real_broken_pmns
+ echo >>real_broken_pmns
+ echo 'root {' >>real_broken_pmns
+ echo ' broken' >>real_broken_pmns
+ echo '}' >>real_broken_pmns
+ echo >>real_broken_pmns
+ cat broken_pmns >>real_broken_pmns
+
+broken_pmda_2_0: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+broken_pmda_2_1: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -DBUG_1 -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+broken_pmda_2_2: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -DBUG_2 -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+broken_pmda_2_3: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -DBUG_3 -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+broken_pmda_2_4: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -DBUG_4 -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+broken_pmda_2_5: broken_pmda.c domain.h
+ rm -f $@ $@.c
+ ln -s broken_pmda.c $@.c
+ $(CCF) $(CDEFS) -DVERSION_2 -DBUG_5 -o $@ $@.c -lpcp_pmda $(LDLIBS)
diff --git a/qa/pmdas/broken/broken_Install b/qa/pmdas/broken/broken_Install
new file mode 100755
index 0000000..32fa109
--- /dev/null
+++ b/qa/pmdas/broken/broken_Install
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# Install the broken PMDA and/or PMNS
+#
+
+# source the PCP configuration environment variables
+. $PCP_DIR/etc/pcp.env
+
+# Get the common procedures and variable assignments
+#
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+# The name of the PMDA
+#
+iam=broken
+
+# Do it
+#
+_setup
+
+dso_opt=false
+daemon_opt=false
+pmns_source=broken_pmns
+help_source=broken_help
+
+_install
+
+exit 0
diff --git a/qa/pmdas/broken/broken_Remove b/qa/pmdas/broken/broken_Remove
new file mode 100755
index 0000000..9d264ff
--- /dev/null
+++ b/qa/pmdas/broken/broken_Remove
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# Remove the broken PMDA
+#
+
+# source the PCP configuration environment variables
+. $PCP_DIR/etc/pcp.env
+
+# Get the common procedures and variable assignments
+#
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+# The name of the PMDA
+#
+iam=broken
+
+# Do it
+#
+_setup
+_remove
+
+exit 0
diff --git a/qa/pmdas/broken/broken_help b/qa/pmdas/broken/broken_help
new file mode 100644
index 0000000..684c4c0
--- /dev/null
+++ b/qa/pmdas/broken/broken_help
@@ -0,0 +1,39 @@
+#
+# broken help file
+# help is provided for all metrics except broken.bad.help
+#
+
+@ broken.valid.one calls to fetch callback
+The number of calls to the PMDA-supplied fetch callback function.
+
+@ broken.valid.two has instance domain
+Valid metric with an instance domain.
+
+@ broken.valid.three has another instance domain
+Valid instance domain with non-sequential serial number.
+
+@ broken.bad.type illegal data type
+Data type in pmDesc is set to PM_TYPE_NOSUPPORT.
+
+@ broken.bad.semantics semantics too high
+Metric semantics set to -1.
+
+@ broken.bad.scale scale too high
+Scale of metrics beyond defined range.
+
+@ broken.bad.indom undefined indom
+The indom is set beyond the bounds of the indom table.
+
+@ broken.no.fetch no fetch method implemented
+The fetch callback does not handle this metric.
+
+@ broken.no.shorthelp
+There is no short help for the metric
+
+@ broken.no.longhelp no long help
+
+@ broken.no.instfetch missing fetch for one instance
+One instance is not supported by fetch callback
+
+@ broken.no.instances empty inst list
+The inst list is empty
diff --git a/qa/pmdas/broken/broken_pmda.c b/qa/pmdas/broken/broken_pmda.c
new file mode 100644
index 0000000..c6c3e43
--- /dev/null
+++ b/qa/pmdas/broken/broken_pmda.c
@@ -0,0 +1,387 @@
+/*
+ * Broken, a PMDA which is broken in several ways
+ *
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+#include "domain.h"
+
+/*
+ * Broken PMDA
+ *
+ * This PMDA is broken in several ways. This is used to test libpcp_pmda
+ * error recovery and messages to the user. Not all the metrics are invalid,
+ * and the metric id's are intentionally sparse to force non-direct mapping.
+ *
+ * The macro BUG_? can be used to turn certain bad things on which may
+ * be fatal.
+ *
+ * BUG Metrics
+ * * broken.valid.one - returns num calls to fetch callback
+ * * broken.valid.two - has instance domain, fixed values
+ * * broken.bad.type - illegal data type
+ * * broken.valid.three - normal, fixed value
+ * * broken.no.fetch - no fetch method implemented for this metric
+ * * broken.no.help - no help text for this metric
+ * * broken.no.shorthelp - no short help on metric
+ * * broken.no.longhelp - no long help on metric
+ * * broken.bad.semantics - illegal semantics
+ * * broken.bad.scale - illegal scale
+ * * broken.no.pmns - not defined in pmns
+ * * broken.no.instfetch - one instance not handled by fetch
+ * * broken.no.instances - instance domain with no instances
+ *
+ * 1 broken.bad.indom - metric with undefined instance
+ * 2 - no instance domain supplied
+ * 3 - no metrics supplied
+ * 4 - bad help file path
+ *
+ * The macro VERSION_? can be used to force this to be a PCP 1.X or 2.0 PMDA
+ *
+ * 1 - use pcp1.X headers and link with compat libs
+ * 2 - use pcp2.o headers and latest libs
+ */
+
+/*
+ * list of instances
+ */
+
+#ifndef BUG_2
+static pmdaInstid _indom0[] = {
+ { 0, "a" }, { 1, "b" }, { 2, "c" }
+};
+#endif
+
+static pmdaInstid _indom1[] = {
+ { 50, "x" }, { 10, "y" }, { 9, "z" }
+};
+
+/*
+ * list of instace domains
+ */
+
+static pmdaIndom indomtab[] = {
+#define INDOM_0 0
+#ifndef BUG_2
+ { INDOM_0, 3, _indom0 },
+#endif
+#define INDOM_1 7
+ { INDOM_1, 3, _indom1 },
+#define INDOM_2 8
+ { INDOM_2, 0, (pmdaInstid *)0 }
+};
+
+
+
+#ifndef BUG_3
+
+/*
+ * all metrics supported in this PMDA - one table entry for each
+ */
+
+static pmdaMetric metrictab[] = {
+/* valid.one */
+ { (void *)0,
+ { PMDA_PMID(0,0), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* valid.two */
+ { (void *)0,
+ { PMDA_PMID(0,1), PM_TYPE_U32, INDOM_0, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* bad.type */
+ { (void *)0,
+ { PMDA_PMID(0,5), PM_TYPE_NOSUPPORT, PM_INDOM_NULL, PM_SEM_COUNTER,
+ { 0, 0, 0, 0, 0, 0 } }, },
+/* valid.three */
+ { (void *)0,
+ { PMDA_PMID(0,7), PM_TYPE_U32, INDOM_1, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* no.fetch */
+ { (void *)0,
+ { PMDA_PMID(0,9), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* no.help */
+ { (void *)0,
+ { PMDA_PMID(0,10), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* no.shorthelp */
+ { (void *)0,
+ { PMDA_PMID(0,11), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* no.longhelp */
+ { (void *)0,
+ { PMDA_PMID(0,12), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* no.isntfetch */
+ { (void *)0,
+ { PMDA_PMID(0,13), PM_TYPE_U32, INDOM_1, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* bad.semantics */
+ { (void *)0,
+ { PMDA_PMID(1,1), PM_TYPE_U32, PM_INDOM_NULL, -1,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* bad.scale */
+ { (void *)0,
+ { PMDA_PMID(1,2), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER,
+ { 1, 0, 0, 10, 0, 0 } }, },
+/* no.pmns */
+ { (void *)0,
+ { PMDA_PMID(1,3), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER,
+ { 1, 0, 0, 10, 0, 0 } }, },
+#ifdef BUG_1
+/* bad.indom */
+ { (void *)0,
+ { PMDA_PMID(1,4), PM_TYPE_U32, 17, PM_SEM_COUNTER,
+ { 1, 0, 0, 10, 0, 0 } }, },
+#endif
+/* no.instances */
+ { (void *)0,
+ { PMDA_PMID(0,14), PM_TYPE_U32, INDOM_2, PM_SEM_COUNTER,
+ { 1, 0, 0, 10, 0, 0 } }, },
+};
+
+#endif
+
+static int _isDSO = 1; /* =0 I am a daemon */
+static char *_logFile = "broken.log";
+#if defined(VERSION_1)
+static char *_helpText = "pmdas/broken/broken_v1";
+#else
+static char *_helpText = "pmdas/broken/broken_v2";
+#endif
+
+/*
+ * callback provided to pmdaFetch
+ */
+
+static int
+broken_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
+{
+ static int count = 0;
+ __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid);
+
+ switch (idp->cluster) {
+ case 0:
+ switch (idp->item) {
+ case 0:
+ atom->l = ++count;
+ break;
+ case 1:
+ switch (inst) {
+ case 0:
+ atom->l = 1;
+ break;
+ case 1:
+ atom->l = 2;
+ break;
+ case 2:
+ atom->l = 3;
+ break;
+ default:
+ return PM_ERR_INST;
+ }
+ break;
+ /* broken.bogus.one: metric not defined in table but is in pmns */
+ case 2:
+ fprintf(stderr,
+ "%s: Fetching metric 0.2 which does not exist\n",
+ pmProgname);
+ atom->l = 42;
+ break;
+ /* metric not defined in table or pmns */
+ case 3:
+ fprintf(stderr,
+ "%s: Fetching metric 0.3 which does not exist\n",
+ pmProgname);
+ atom->l = -1;
+ break;
+ case 5:
+ atom->d = 3.14;
+ break;
+ case 7:
+ switch (inst) {
+ case 50:
+ atom->l = 44;
+ break;
+ case 10:
+ atom->l = 45;
+ break;
+ case 9:
+ atom->l = 46;
+ break;
+ default:
+ return PM_ERR_INST;
+ }
+ break;
+ case 10:
+ atom->l = 55;
+ break;
+ case 11:
+ atom->l = 66;
+ break;
+ case 12:
+ atom->l = 77;
+ break;
+ case 13:
+ switch (inst) {
+ case 50:
+ atom->l = 44;
+ break;
+ case 9:
+ atom->l = 46;
+ break;
+ default:
+ return PM_ERR_INST;
+ }
+ break;
+ case 14:
+ fprintf(stderr, "PMID %s requested with inst = %d\n",
+ pmIDStr(mdesc->m_desc.pmid), inst);
+ return PM_ERR_VALUE;
+ default:
+ return PM_ERR_PMID;
+ }
+ break;
+ case 1:
+ switch (idp->item) {
+ case 1:
+ atom->l = 333;
+ break;
+ case 2:
+ atom->l = 12345;
+ break;
+ case 3:
+ atom->l = 4321;
+ break;
+#ifdef BUG_4
+ case 4:
+ fprintf(stderr, "Eeek! Should not be trying to get PMID %s\n",
+ pmIDStr(mdesc->m_desc.pmid));
+ break;
+#endif
+ default:
+ return PM_ERR_PMID;
+ }
+ break;
+ default:
+ return PM_ERR_PMID;
+ }
+
+ return 0;
+}
+
+/*
+ * Initialise the agent (both daemon and DSO).
+ */
+
+void
+broken_init(pmdaInterface *dp)
+{
+#if defined(BUG_5)
+ if (_isDSO)
+ /*
+ * we don't grok PMDA_INTERFACE_77 ... 77 is arbitrary, just needs
+ * to be bigger than currently validand supported
+ */
+#if defined(VERSION_1)
+ pmdaDSO(dp, 77, "broken DSO", BROKEN, _helpText);
+#else
+ pmdaDSO(dp, 77, "broken DSO", _helpText);
+#endif
+#elif defined(VERSION_1)
+ if (_isDSO)
+ pmdaDSO(dp, PMDA_PROTOCOL_2, "broken DSO", BROKEN, _helpText);
+#else
+ if (_isDSO)
+ pmdaDSO(dp, PMDA_INTERFACE_2, "broken DSO", _helpText);
+#endif
+
+ if (dp->status != 0)
+ return;
+
+ pmdaSetFetchCallBack(dp, broken_fetchCallBack);
+
+#if defined(BUG_2)
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]),
+ metrictab, sizeof(metrictab)/sizeof(metrictab[0]));
+#elif defined(BUG_3)
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]),
+ (pmdaMetric *)0, -1);
+#elif defined(BUG_4)
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]),
+ metrictab, sizeof(metrictab)/sizeof(metrictab[0]));
+#else
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]),
+ metrictab, sizeof(metrictab)/sizeof(metrictab[0]));
+#endif
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s [options]\n\n", pmProgname);
+ fputs("Options:\n"
+ " -d N set pmDebug debugging flag to N\n"
+ " -D domain use domain (numeric) for metrics domain of PMDA\n"
+ " -h helpfile get help text from helpfile rather then default path\n"
+ " -l logfile write log into logfile rather than using default log name\n"
+ "\nExactly one of the following options may appear:\n"
+ " -i port expect PMCD to connect on given inet port (number or name)\n"
+ " -p expect PMCD to supply stdin/stdout (pipe)\n"
+ " -u socket expect PMCD to connect on given unix domain socket\n"
+ " -6 port expect PMCD to connect on given ipv6 port (number or name)\n",
+ stderr);
+ exit(1);
+}
+
+/*
+ * Set up the agent if running as a daemon.
+ */
+
+int
+main(int argc, char **argv)
+{
+ int err = 0;
+ pmdaInterface desc;
+
+ __pmSetProgname(argv[0]);
+ _isDSO = 0;
+
+#if defined(BUG_5)
+ /*
+ * we don't grok PMDA_INTERFACE_77 ... 77 is arbitrary, just needs
+ * to be bigger than currently valid and supported
+ */
+ pmdaDaemon(&desc, 77, pmProgname, BROKEN, _logFile,
+ _helpText);
+#elif defined(VERSION_1)
+ pmdaDaemon(&desc, PMDA_PROTOCOL_2, pmProgname, BROKEN, _logFile,
+ _helpText);
+#else
+ pmdaDaemon(&desc, PMDA_INTERFACE_2, pmProgname, BROKEN, _logFile,
+ _helpText);
+#endif
+
+ if (desc.status != 0) {
+ fprintf(stderr, "pmdaDaemon() failed!\n");
+ exit(1);
+ }
+
+ if (pmdaGetOpt(argc, argv, "D:d:h:i:l:pu:6:", &desc, &err) != EOF)
+ err++;
+
+ if (err)
+ usage();
+
+ pmdaOpenLog(&desc);
+ broken_init(&desc);
+ pmdaConnect(&desc);
+ pmdaMain(&desc);
+
+ exit(0);
+}
diff --git a/qa/pmdas/broken/broken_pmda.v1.c b/qa/pmdas/broken/broken_pmda.v1.c
new file mode 100644
index 0000000..00cda3e
--- /dev/null
+++ b/qa/pmdas/broken/broken_pmda.v1.c
@@ -0,0 +1,386 @@
+/*
+ * Broken, a PMDA which is broken in several ways
+ *
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+#include "domain.h"
+
+/*
+ * Broken PMDA
+ *
+ * This PMDA is broken in several ways. This is used to test libpcp_pmda
+ * error recovery and messages to the user. Not all the metrics are invalid,
+ * and the metric id's are intentionally sparse to force non-direct mapping.
+ *
+ * The macro BUG_? can be used to turn certain bad things on which may
+ * be fatal.
+ *
+ * BUG Metrics
+ * * broken.valid.one - returns num calls to fetch callback
+ * * broken.valid.two - has instance domain, fixed values
+ * * broken.bad.type - illegal data type
+ * * broken.valid.three - normal, fixed value
+ * * broken.no.fetch - no fetch method implemented for this metric
+ * * broken.no.help - no help text for this metric
+ * * broken.no.shorthelp - no short help on metric
+ * * broken.no.longhelp - no long help on metric
+ * * broken.bad.semantics - illegal semantics
+ * * broken.bad.scale - illegal scale
+ * * broken.no.pmns - not defined in pmns
+ * * broken.no.instfetch - one instance not handled by fetch
+ * * broken.no.instances - instance domain with no instances
+ *
+ * 1 broken.bad.indom - metric with undefined instance
+ * 2 - no instance domain supplied
+ * 3 - no metrics supplied
+ * 4 - bad help file path
+ *
+ * The macro VERSION_? can be used to force this to be a PCP 1.X or 2.0 PMDA
+ *
+ * 1 - use pcp1.X headers and link with compat libs
+ * 2 - use pcp2.o headers and latest libs
+ */
+
+#ifndef BUG_2
+
+/*
+ * list of instances
+ */
+
+static pmdaInstid _indom0[] = {
+ { 0, "a" }, { 1, "b" }, { 2, "c" }
+};
+
+static pmdaInstid _indom1[] = {
+ { 50, "x" }, { 10, "y" }, { 9, "z" }
+};
+
+/*
+ * list of instace domains
+ */
+
+static pmdaIndom indomtab[] = {
+#define INDOM_0 0
+ { INDOM_0, 3, _indom0 },
+#define INDOM_1 7
+ { INDOM_1, 3, _indom1 },
+#define INDOM_2 8
+ { INDOM_2, 0, (pmdaInstid *)0 }
+};
+
+#else
+
+#define INDOM_0 0
+#define INDOM_1 7
+#define INDOM_2 8
+
+#endif
+
+
+#ifndef BUG_3
+
+/*
+ * all metrics supported in this PMDA - one table entry for each
+ */
+
+static pmdaMetric metrictab[] = {
+/* valid.one */
+ { (void *)0,
+ { PMDA_PMID(0,0), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* valid.two */
+ { (void *)0,
+ { PMDA_PMID(0,1), PM_TYPE_U32, INDOM_0, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* bad.type */
+ { (void *)0,
+ { PMDA_PMID(0,5), PM_TYPE_NOSUPPORT, PM_INDOM_NULL, PM_SEM_COUNTER,
+ { 0, 0, 0, 0, 0, 0 } }, },
+/* valid.three */
+ { (void *)0,
+ { PMDA_PMID(0,7), PM_TYPE_U32, INDOM_1, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* no.fetch */
+ { (void *)0,
+ { PMDA_PMID(0,9), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* no.help */
+ { (void *)0,
+ { PMDA_PMID(0,10), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* no.shorthelp */
+ { (void *)0,
+ { PMDA_PMID(0,11), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* no.longhelp */
+ { (void *)0,
+ { PMDA_PMID(0,12), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* no.isntfetch */
+ { (void *)0,
+ { PMDA_PMID(0,13), PM_TYPE_U32, INDOM_1, PM_SEM_INSTANT,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* bad.semantics */
+ { (void *)0,
+ { PMDA_PMID(1,1), PM_TYPE_U32, PM_INDOM_NULL, -1,
+ { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
+/* bad.scale */
+ { (void *)0,
+ { PMDA_PMID(1,2), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER,
+ { 1, 0, 0, 10, 0, 0 } }, },
+/* no.pmns */
+ { (void *)0,
+ { PMDA_PMID(1,3), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER,
+ { 1, 0, 0, 10, 0, 0 } }, },
+#ifdef BUG_1
+/* bad.indom */
+ { (void *)0,
+ { PMDA_PMID(1,4), PM_TYPE_U32, 17, PM_SEM_COUNTER,
+ { 1, 0, 0, 10, 0, 0 } }, },
+#endif
+/* no.instances */
+ { (void *)0,
+ { PMDA_PMID(0,14), PM_TYPE_U32, INDOM_2, PM_SEM_COUNTER,
+ { 1, 0, 0, 10, 0, 0 } }, },
+};
+
+#endif
+
+static int _isDSO = 1; /* =0 I am a daemon */
+static char *_logFile = "broken.log";
+#if defined(VERSION_1)
+static char *_helpText = "pmdas/broken/broken_v1";
+#else
+static char *_helpText = "pmdas/broken/broken_v2";
+#endif
+
+/*
+ * callback provided to pmdaFetch
+ */
+
+static int
+broken_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
+{
+ static int count = 0;
+ _pmID_int *idp = (_pmID_int *)&(mdesc->m_desc.pmid);
+
+ switch (idp->cluster) {
+ case 0:
+ switch (idp->item) {
+ case 0:
+ atom->l = ++count;
+ break;
+ case 1:
+ switch (inst) {
+ case 0:
+ atom->l = 1;
+ break;
+ case 1:
+ atom->l = 2;
+ break;
+ case 2:
+ atom->l = 3;
+ break;
+ default:
+ return PM_ERR_INST;
+ }
+ break;
+ /* broken.bogus.one: metric not defined in table but is in pmns */
+ case 2:
+ fprintf(stderr,
+ "%s: Fetching metric 0.2 which does not exist\n",
+ pmProgname);
+ atom->l = 42;
+ break;
+ /* metric not defined in table or pmns */
+ case 3:
+ fprintf(stderr,
+ "%s: Fetching metric 0.3 which does not exist\n",
+ pmProgname);
+ atom->l = -1;
+ break;
+ case 5:
+ atom->d = 3.14;
+ break;
+ case 7:
+ switch (inst) {
+ case 50:
+ atom->l = 44;
+ break;
+ case 10:
+ atom->l = 45;
+ break;
+ case 9:
+ atom->l = 46;
+ break;
+ default:
+ return PM_ERR_INST;
+ }
+ break;
+ case 10:
+ atom->l = 55;
+ break;
+ case 11:
+ atom->l = 66;
+ break;
+ case 12:
+ atom->l = 77;
+ break;
+ case 13:
+ switch (inst) {
+ case 50:
+ atom->l = 44;
+ break;
+ case 9:
+ atom->l = 46;
+ break;
+ default:
+ return PM_ERR_INST;
+ }
+ break;
+ case 14:
+ fprintf(stderr, "PMID %s requested with inst = %d\n",
+ pmIDStr(mdesc->m_desc.pmid), inst);
+ return PM_ERR_VALUE;
+ default:
+ return PM_ERR_PMID;
+ }
+ break;
+ case 1:
+ switch (idp->item) {
+ case 1:
+ atom->l = 333;
+ break;
+ case 2:
+ atom->l = 12345;
+ break;
+ case 3:
+ atom->l = 4321;
+ break;
+#ifdef BUG_4
+ case 4:
+ fprintf(stderr, "Eeek! Should not be trying to get PMID %s\n",
+ pmIDStr(mdesc->m_desc.pmid));
+ break;
+#endif
+ default:
+ return PM_ERR_PMID;
+ }
+ break;
+ default:
+ return PM_ERR_PMID;
+ }
+
+ return 0;
+}
+
+/*
+ * Initialise the agent (both daemon and DSO).
+ */
+
+void
+broken_init(pmdaInterface *dp)
+{
+#if defined(BUG_5)
+ if (_isDSO)
+ /* we don't grok PMDA_INTERFACE_4 ... */
+#if defined(VERSION_1)
+ pmdaDSO(dp, 4, "broken DSO", BROKEN, _helpText);
+#else
+ pmdaDSO(dp, 4, "broken DSO", _helpText);
+#endif
+#elif defined(VERSION_1)
+ if (_isDSO)
+ pmdaDSO(dp, PMDA_PROTOCOL_2, "broken DSO", BROKEN, _helpText);
+#else
+ if (_isDSO)
+ pmdaDSO(dp, PMDA_INTERFACE_2, "broken DSO", _helpText);
+#endif
+
+ if (dp->status != 0)
+ return;
+
+ pmdaSetFetchCallBack(dp, broken_fetchCallBack);
+
+#if defined(BUG_2)
+ pmdaInit(dp, (pmdaIndom *)0, 0, metrictab,
+ sizeof(metrictab)/sizeof(metrictab[0]));
+#elif defined(BUG_3)
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]),
+ (pmdaMetric *)0, -1);
+#elif defined(BUG_4)
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]),
+ metrictab, sizeof(metrictab)/sizeof(metrictab[0]));
+#else
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]),
+ metrictab, sizeof(metrictab)/sizeof(metrictab[0]));
+#endif
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s [options]\n\n", pmProgname);
+ fputs("Options:\n"
+ " -d N set pmDebug debugging flag to N\n"
+ " -D domain use domain (numeric) for metrics domain of PMDA\n"
+ " -h helpfile get help text from helpfile rather then default path\n"
+ " -l logfile write log into logfile rather than using default log name\n"
+ "\nExactly one of the following options may appear:\n"
+ " -i port expect PMCD to connect on given inet port (number or name)\n"
+ " -p expect PMCD to supply stdin/stdout (pipe)\n"
+ " -u socket expect PMCD to connect on given unix domain socket\n"
+ " -6 port expect PMCD to connect on given ipv6 port (number or name)\n",
+ stderr);
+ exit(1);
+}
+
+/*
+ * Set up the agent if running as a daemon.
+ */
+
+int
+main(int argc, char **argv)
+{
+ int err = 0;
+ pmdaInterface desc;
+
+ __pmSetProgname(argv[0]);
+ _isDSO = 0;
+
+#if defined(BUG_5)
+ /* we don't grok PMDA_INTERFACE_4 ... */
+ pmdaDaemon(&desc, 4, pmProgname, BROKEN, _logFile,
+ _helpText);
+#elif defined(VERSION_1)
+ pmdaDaemon(&desc, PMDA_PROTOCOL_2, pmProgname, BROKEN, _logFile,
+ _helpText);
+#else
+ pmdaDaemon(&desc, PMDA_INTERFACE_2, pmProgname, BROKEN, _logFile,
+ _helpText);
+#endif
+
+ if (desc.status != 0) {
+ fprintf(stderr, "pmdaDaemon() failed!\n");
+ exit(1);
+ }
+
+ if (pmdaGetOpt(argc, argv, "D:d:h:i:l:pu:6:", &desc, &err) != EOF)
+ err++;
+
+ if (err)
+ usage();
+
+ pmdaOpenLog(&desc);
+ broken_init(&desc);
+ pmdaConnect(&desc);
+ pmdaMain(&desc);
+
+ exit(0);
+}
diff --git a/qa/pmdas/broken/broken_pmns b/qa/pmdas/broken/broken_pmns
new file mode 100644
index 0000000..926ab3f
--- /dev/null
+++ b/qa/pmdas/broken/broken_pmns
@@ -0,0 +1,36 @@
+/*
+ * Metrics for a broken PMDA
+ */
+
+broken {
+ valid
+ bad
+ no
+ bogus
+}
+
+broken.valid {
+ one BROKEN:0:0
+ two BROKEN:0:1
+ three BROKEN:0:7
+}
+
+broken.bad {
+ type BROKEN:0:5
+ semantics BROKEN:1:1
+ scale BROKEN:1:2
+ indom BROKEN:1:4
+}
+
+broken.no {
+ fetch BROKEN:0:9
+ help BROKEN:0:10
+ shorthelp BROKEN:0:11
+ longhelp BROKEN:0:12
+ instfetch BROKEN:0:13
+ instances BROKEN:0:14
+}
+
+broken.bogus {
+ one BROKEN:0:2
+}
diff --git a/qa/pmdas/broken/domain.h b/qa/pmdas/broken/domain.h
new file mode 100644
index 0000000..3de61ee
--- /dev/null
+++ b/qa/pmdas/broken/domain.h
@@ -0,0 +1 @@
+#define BROKEN 249
diff --git a/qa/pmdas/dynamic/GNUmakefile b/qa/pmdas/dynamic/GNUmakefile
new file mode 100644
index 0000000..ef4e8f4
--- /dev/null
+++ b/qa/pmdas/dynamic/GNUmakefile
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2012 Red Hat.
+#
+
+TOPDIR = ../../..
+include $(TOPDIR)/src/include/builddefs
+
+TESTDIR = $(PCP_VAR_DIR)/testsuite/pmdas/dynamic
+
+CFILES = dynamic.c
+CMDTARGET = pmdadynamic
+TARGETS = $(LIBTARGET) $(CMDTARGET)
+MYFILES = domain.h help pmns root
+MYSCRIPTS = Install Remove
+LSRCFILES = $(MYSCRIPTS) $(MYFILES) GNUmakefile.install
+LDIRT = help.pag help.dir
+
+LLDFLAGS = $(PCP_LIBS)
+LLDLIBS = $(PCP_PMDALIB)
+
+default default_pcp setup: $(TARGETS)
+
+install install_pcp:
+ $(INSTALL) -m 755 -d $(TESTDIR)
+ $(INSTALL) -m 644 $(CFILES) $(MYFILES) $(TESTDIR)
+ $(INSTALL) -m 755 $(MYSCRIPTS) $(TARGETS) $(TESTDIR)
+ $(INSTALL) -m 644 GNUmakefile.install $(TESTDIR)/GNUmakefile
+
+include $(BUILDRULES)
diff --git a/qa/pmdas/dynamic/GNUmakefile.install b/qa/pmdas/dynamic/GNUmakefile.install
new file mode 100644
index 0000000..5606aef
--- /dev/null
+++ b/qa/pmdas/dynamic/GNUmakefile.install
@@ -0,0 +1,39 @@
+#!gmake
+#
+# Copyright (c) 2009 Aconex. All Rights Reserved.
+#
+
+SHELL = sh
+
+ifdef PCP_CONF
+include $(PCP_CONF)
+else
+include $(PCP_DIR)/etc/pcp.conf
+endif
+include $(PCP_INC_DIR)/builddefs
+
+# remove -Lpath and -Ipath options from builddefs CFLAGS value
+#
+PCP_LIBS =
+TMP := $(CFLAGS:-I%=)
+ifdef PCP_DIR
+# put -Ipath and -Lpath back but use paths for run-time environment
+#
+CFLAGS = $(TMP) -I$(PCP_INC_DIR)/..
+LDFLAGS = -L$(PCP_LIB_DIR)
+else
+CFLAGS = $(TMP)
+endif
+
+CFILES = dynamic.c
+CMDTARGET = pmdadynamic
+TARGETS = $(LIBTARGET) $(CMDTARGET)
+LDIRT = *.log help.dir help.pag
+
+LLDLIBS = -lpcp_pmda -lpcp $(LIB_FOR_MATH) $(LIB_FOR_DLOPEN) $(LIB_FOR_PTHREADS)
+
+default default_pcp setup:: $(TARGETS)
+
+install install_pcp:
+
+include $(PCP_INC_DIR)/buildrules
diff --git a/qa/pmdas/dynamic/Install b/qa/pmdas/dynamic/Install
new file mode 100755
index 0000000..17eec23
--- /dev/null
+++ b/qa/pmdas/dynamic/Install
@@ -0,0 +1,16 @@
+#!/bin/sh
+#
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+. /etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+PCP_PMDAS_DIR=${PCP_VAR_DIR}/testsuite/pmdas
+
+iam=dynamic
+dso_opt=false
+pmda_interface=4
+
+pmdaSetup
+pmdaInstall
+exit 0
diff --git a/qa/pmdas/dynamic/Remove b/qa/pmdas/dynamic/Remove
new file mode 100755
index 0000000..c29b0a7
--- /dev/null
+++ b/qa/pmdas/dynamic/Remove
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# Remove the dynamic PMDA
+#
+
+. /etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=dynamic
+pmdaSetup
+pmdaRemove
+exit 0
diff --git a/qa/pmdas/dynamic/domain.h b/qa/pmdas/dynamic/domain.h
new file mode 100644
index 0000000..b17087b
--- /dev/null
+++ b/qa/pmdas/dynamic/domain.h
@@ -0,0 +1 @@
+#define DYNAMIC 247
diff --git a/qa/pmdas/dynamic/dynamic.c b/qa/pmdas/dynamic/dynamic.c
new file mode 100644
index 0000000..05c73ec
--- /dev/null
+++ b/qa/pmdas/dynamic/dynamic.c
@@ -0,0 +1,420 @@
+/*
+ * Dynamic PMDA for testing dynamic indom support
+ *
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdio.h>
+#include <syslog.h>
+#include <errno.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+#include "domain.h"
+
+/*
+ * Dynamic PMDA
+ *
+ * This PMDA has several metrics with a single dynamic indom.
+ * This indom can be controlled by several storable metrics.
+ *
+ * Metrics
+ *
+ * dynamic.numinst - number of instances in the indom right now
+ * dynamic.discrete - discrete metric
+ * dynamic.instant - instantaneous metric
+ * dynamic.counter - counter metric
+ * dynamic.control.add - add an instance
+ * dynamic.control.del - delete an instance
+ *
+ */
+
+/* data and function prototypes for dynamic instance domain handling */
+struct Dynamic {
+ int id;
+ char name[16];
+ unsigned counter;
+};
+
+/*
+ * list of instances
+ */
+
+static struct Dynamic *insts = NULL;
+static pmdaInstid *instids = NULL;
+static unsigned numInsts = 0;
+static unsigned sizeInsts = 0;
+
+/*
+ * list of instance domains
+ */
+
+static pmdaIndom indomtab[] = {
+#define DYNAMIC_INDOM 0
+ { DYNAMIC_INDOM, 0, NULL }
+};
+
+/*
+ * all metrics supported in this PMDA - one table entry for each
+ */
+
+static pmdaMetric metrictab[] = {
+/* numinsts */
+ { NULL,
+ { PMDA_PMID(0,0), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) }, },
+/* discrete */
+ { NULL,
+ { PMDA_PMID(0,1), PM_TYPE_STRING, DYNAMIC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) }, },
+/* instant */
+ { NULL,
+ { PMDA_PMID(0,2), PM_TYPE_U32, DYNAMIC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+/* counter */
+ { NULL,
+ { PMDA_PMID(0,3), PM_TYPE_U32, DYNAMIC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+/* control.add */
+ { NULL,
+ { PMDA_PMID(1,4), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) }, },
+/* control.del */
+ { NULL,
+ { PMDA_PMID(1,5), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) }, },
+};
+
+/*
+ * callback provided to pmdaFetch
+ */
+static int
+dynamic_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
+{
+ __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid);
+
+ if (inst != PM_IN_NULL &&
+ !(idp->cluster == 0 && idp->item >= 1 && idp->item <= 3))
+ return PM_ERR_INST;
+
+ __pmNotifyErr(LOG_DEBUG, "dynamic_fetch: %d.%d[%d]\n",
+ idp->cluster, idp->item, inst);
+
+ if (idp->cluster == 0) {
+ switch (idp->item) {
+ case 0: /* numinst */
+ atom->ul = numInsts;
+ break;
+
+ case 1: /* discrete */
+ if (inst < sizeInsts)
+ if (insts[inst].id >= 0)
+ atom->cp = insts[inst].name;
+ else
+ return PM_ERR_INST;
+ else
+ return PM_ERR_INST;
+ break;
+
+ case 2: /* instant */
+ if (inst < sizeInsts)
+ if (insts[inst].id >= 0)
+ atom->ul = insts[inst].counter;
+ else
+ return PM_ERR_INST;
+ else
+ return PM_ERR_INST;
+ break;
+
+ case 3: /* counter */
+ if (inst < sizeInsts)
+ if (insts[inst].id >= 0)
+ atom->ul = insts[inst].counter;
+ else
+ return PM_ERR_INST;
+ else
+ return PM_ERR_INST;
+ break;
+
+ default:
+ return PM_ERR_PMID;
+ }
+ }
+ else if (idp->cluster == 1) { /* dynamic.control */
+ switch(idp->item) {
+ case 4: /* add */
+ atom->ul = sizeInsts;
+ break;
+
+ case 5: /* del */
+ atom->ul = sizeInsts - numInsts;
+ break;
+
+ default:
+ return PM_ERR_PMID;
+ }
+ }
+ else
+ return PM_ERR_PMID;
+
+ return 1;
+}
+
+/*
+ * wrapper for pmdaFetch which increments the counters for each instance
+ */
+static int
+dynamic_fetch(int numpmid, pmID pmidlist[], pmResult **resp, pmdaExt *pmda)
+{
+ int i;
+
+ for (i = 0; i < sizeInsts; i++)
+ if (insts[i].id >= 0)
+ insts[i].counter += insts[i].id;
+
+ return pmdaFetch(numpmid, pmidlist, resp, pmda);
+}
+
+/*
+ * add or delete an instance
+ */
+/*ARGSUSED*/
+static int
+dynamic_store(pmResult *result, pmdaExt *pmda)
+{
+ int i;
+ int j;
+ int changed = 0;
+ int sts = 0;
+ int val;
+ pmValueSet *vsp = NULL;
+ __pmID_int *pmidp = NULL;
+
+ for (i = 0; i < result->numpmid; i++) {
+ vsp = result->vset[i];
+ pmidp = (__pmID_int *)&vsp->pmid;
+
+ if (pmidp->cluster == 1) { /* all storable metrics are cluster 1 */
+
+ switch (pmidp->item) {
+ case 4: /* add */
+
+ val = vsp->vlist[0].value.lval;
+ if (val < 0) {
+ sts = PM_ERR_SIGN;
+ }
+ else if (val < sizeInsts) {
+ if (insts[val].id >= 0) {
+ sts = PM_ERR_INST;
+ }
+ else {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: Adding instance %d (size = %d)\n",
+ val, sizeInsts);
+#endif
+
+ insts[val].id = val;
+ insts[val].counter = 0;
+ numInsts++;
+ changed = 1;
+ }
+ }
+ else {
+ insts = (struct Dynamic*)realloc(insts, (val + 1) * sizeof(struct Dynamic));
+ if (insts == NULL) {
+ __pmNotifyErr(LOG_ERR,
+ "dynamic_store: Unable to realloc %d bytes\n",
+ (int)(val * sizeof(struct Dynamic)));
+ sizeInsts = 0;
+ numInsts = 0;
+ changed = 1;
+ sts = PM_ERR_TOOBIG;
+ }
+ else {
+ for (i = sizeInsts; i <= val; i++) {
+ insts[i].id = -1;
+ sprintf(insts[i].name, "%d", i);
+ insts[i].counter = 0;
+ }
+ insts[val].id = val;
+ changed = 1;
+ sizeInsts = val + 1;
+ numInsts++;
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: Adding instance %d (size = %d)\n",
+ val, sizeInsts);
+#endif
+ }
+ }
+ break;
+
+ case 5: /* del */
+ val = vsp->vlist[0].value.lval;
+ if (val < 0) { /* delete all */
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: Removing all instances\n");
+#endif
+
+ for (i = 0; i < sizeInsts; i++) {
+ insts[i].id = -1;
+ insts[i].counter = 0;
+ }
+ numInsts = 0;
+ changed = 1;
+ }
+ else if (val < sizeInsts) {
+ if (insts[val].id < 0) {
+ sts = PM_ERR_INST;
+ }
+ else {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: Removing instance %d\n",
+ val);
+#endif
+ insts[val].id = -1;
+ insts[val].counter = 0;
+ changed = 1;
+ numInsts--;
+ }
+ }
+ else
+ sts = PM_ERR_INST;
+ break;
+
+ default:
+ sts = PM_ERR_PMID;
+ break;
+ }
+ }
+ else if (pmidp->cluster == 0 && pmidp->item <= 3) {
+ sts = -EACCES;
+ break;
+ }
+ else {
+ sts = PM_ERR_PMID;
+ break;
+ }
+ }
+
+ if (changed) {
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: Resizing to %d instances\n",
+ numInsts);
+#endif
+
+ if (numInsts > 0) {
+ instids = (pmdaInstid *)realloc(instids,
+ numInsts * sizeof(pmdaInstid));
+ if (instids == NULL) {
+ __pmNotifyErr(LOG_ERR,
+ "dynamic_store: Could not realloc %d bytes\n",
+ (int)(numInsts * sizeof(pmdaInstid)));
+ sts = PM_ERR_TOOBIG;
+ }
+ else {
+ for (i = 0, j = 0; i < sizeInsts; i++) {
+ if (insts[i].id >= 0) {
+ instids[j].i_inst = insts[i].id;
+ instids[j].i_name = insts[i].name;
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: [%d] %d \"%s\"\n",
+ j, instids[j].i_inst,
+ instids[j].i_name);
+#endif
+
+ j++;
+ }
+ }
+ indomtab[DYNAMIC_INDOM].it_numinst = numInsts;
+ indomtab[DYNAMIC_INDOM].it_set = instids;
+ }
+ }
+ else {
+ indomtab[DYNAMIC_INDOM].it_numinst = 0;
+ indomtab[DYNAMIC_INDOM].it_set = NULL;
+ }
+ }
+
+ return sts;
+}
+
+/*
+ * Initialise the agent (both daemon and DSO).
+ */
+void
+dynamic_init(pmdaInterface *dp)
+{
+ if (dp->status != 0)
+ return;
+
+ dp->version.two.fetch = dynamic_fetch;
+ dp->version.two.store = dynamic_store;
+
+ pmdaSetFetchCallBack(dp, dynamic_fetchCallBack);
+
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]), metrictab,
+ sizeof(metrictab)/sizeof(metrictab[0]));
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s [options]\n\n", pmProgname);
+ fputs("Options:\n"
+ " -d domain use domain (numeric) for metrics domain of PMDA\n"
+ " -l logfile write log into logfile rather than using default log name\n"
+ "\nExactly one of the following options may appear:\n"
+ " -i port expect PMCD to connect on given inet port (number or name)\n"
+ " -p expect PMCD to supply stdin/stdout (pipe)\n"
+ " -u socket expect PMCD to connect on given unix domain socket\n"
+ " -6 port expect PMCD to connect on given ipv6 port (number or name)\n",
+ stderr);
+ exit(1);
+}
+
+/*
+ * Set up the agent if running as a daemon.
+ */
+int
+main(int argc, char **argv)
+{
+ int sep = __pmPathSeparator();
+ int err = 0;
+ pmdaInterface dispatch;
+ char helppath[MAXPATHLEN];
+
+ __pmSetProgname(argv[0]);
+ snprintf(helppath, sizeof(helppath),
+ "%s%c" "testsuite" "%c" "pmdas" "%c" "dynamic" "%c" "help",
+ pmGetConfig("PCP_VAR_DIR"), sep, sep, sep, sep);
+ pmdaDaemon(&dispatch, PMDA_INTERFACE_4, pmProgname, DYNAMIC,
+ "dynamic.log", helppath);
+
+ if (pmdaGetOpt(argc, argv, "D:d:h:i:l:pu:6:?", &dispatch, &err) != EOF)
+ err++;
+
+ if (err)
+ usage();
+
+ pmdaOpenLog(&dispatch);
+ dynamic_init(&dispatch);
+ pmdaConnect(&dispatch);
+ pmdaMain(&dispatch);
+
+ exit(0);
+}
diff --git a/qa/pmdas/dynamic/help b/qa/pmdas/dynamic/help
new file mode 100644
index 0000000..110151e
--- /dev/null
+++ b/qa/pmdas/dynamic/help
@@ -0,0 +1,25 @@
+#
+# dynamic help file
+#
+
+@ dynamic.numinsts number of instances
+The number of instances currently being exported
+
+@ dynamic.discrete instance id as a string
+The instance identifier exported as a string
+
+@ dynamic.instant counter as a instaneous value
+The counter for the instance exported as an instaneous value
+
+@ dynamic.counter counter as a counter
+The counter for the instance exported as a counter
+
+@ dynamic.control.add add an instance
+Storing the instance id of an instance not currently exported
+will all that instance to the indom.
+
+@ dynamic.control.del delete an instance
+Storing the instance id of an instance that is currently being
+exported will remove that instance from the indom. Storing a negative
+number will cause all instances to be removed.
+
diff --git a/qa/pmdas/dynamic/pmns b/qa/pmdas/dynamic/pmns
new file mode 100644
index 0000000..aa81933
--- /dev/null
+++ b/qa/pmdas/dynamic/pmns
@@ -0,0 +1,18 @@
+/*
+ * Metrics for a dynamic PMDA
+ */
+
+#include <stdpmid>
+
+dynamic {
+ numinsts DYNAMIC:0:0
+ discrete DYNAMIC:0:1
+ instant DYNAMIC:0:2
+ counter DYNAMIC:0:3
+ control
+}
+
+dynamic.control {
+ add DYNAMIC:1:4
+ del DYNAMIC:1:5
+}
diff --git a/qa/pmdas/dynamic/root b/qa/pmdas/dynamic/root
new file mode 100644
index 0000000..22fccee
--- /dev/null
+++ b/qa/pmdas/dynamic/root
@@ -0,0 +1,5 @@
+root {
+ dynamic
+}
+
+#include "pmns"
diff --git a/qa/pmdas/slow/GNUmakefile b/qa/pmdas/slow/GNUmakefile
new file mode 100644
index 0000000..32e93dd
--- /dev/null
+++ b/qa/pmdas/slow/GNUmakefile
@@ -0,0 +1,37 @@
+#!gmake
+#
+# Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+#
+# This program 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.
+#
+# This program 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.
+#
+
+TOPDIR = ../../..
+include $(TOPDIR)/src/include/builddefs
+
+IAM = slow
+TESTDIR = $(PCP_VAR_DIR)/testsuite/pmdas/$(IAM)
+LSRCFILES = Install Remove pmda$(IAM).pl GNUmakefile.install
+LDIRT = domain.h root pmns *.log
+
+default default_pcp setup: check_domain
+
+include $(BUILDRULES)
+
+install: default
+ $(INSTALL) -m 755 -d $(TESTDIR)
+ $(INSTALL) -m 755 Install Remove $(TESTDIR)
+ $(INSTALL) -m 644 pmda$(IAM).pl $(TESTDIR)/pmda$(IAM).pl
+ $(INSTALL) -m 644 GNUmakefile.install $(TESTDIR)/GNUmakefile
+
+install_pcp: install
+
+check_domain: $(TOPDIR)/src/pmns/stdpmid
+ $(DOMAIN_PERLRULE)
diff --git a/qa/pmdas/slow/GNUmakefile.install b/qa/pmdas/slow/GNUmakefile.install
new file mode 100644
index 0000000..8340ba8
--- /dev/null
+++ b/qa/pmdas/slow/GNUmakefile.install
@@ -0,0 +1,5 @@
+default default_pcp setup:
+
+clobber clean:
+ rm -f domain.h domain.h.perl domain.h.save
+ rm -f pmns pmns.perl pmns.save
diff --git a/qa/pmdas/slow/Install b/qa/pmdas/slow/Install
new file mode 100755
index 0000000..6ef6ec9
--- /dev/null
+++ b/qa/pmdas/slow/Install
@@ -0,0 +1,38 @@
+#! /bin/sh
+#
+# Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+#
+# This program 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.
+#
+# This program 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.
+#
+# Install the slow PMDA
+#
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=slow
+perl_opt=true
+daemon_opt=false
+forced_restart=false
+
+pmdaSetup
+$PCP_ECHO_PROG $PCP_ECHO_N "Startup delay (secs) [0]? $PCP_ECHO_C"
+read x
+[ -z "$x" ] && x=0
+$PCP_ECHO_PROG $PCP_ECHO_N "Fetch delay (secs) [0]? $PCP_ECHO_C"
+read y
+[ -z "$y" ] && y=0
+perl_args="$perl_args $x $y"
+[ "$x" -lt 0 ] && check_delay=`expr -1 \* $x + 2`
+[ "$x" -gt 0 ] && check_delay=`expr $x + 2`
+
+pmdaInstall
+exit 0
diff --git a/qa/pmdas/slow/Remove b/qa/pmdas/slow/Remove
new file mode 100755
index 0000000..5641c52
--- /dev/null
+++ b/qa/pmdas/slow/Remove
@@ -0,0 +1,25 @@
+#! /bin/sh
+#
+# Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+#
+# This program 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.
+#
+# This program 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.
+#
+# Remove the slow PMDA
+#
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=slow
+
+pmdaSetup
+pmdaRemove
+exit 0
diff --git a/qa/pmdas/slow/pmdaslow.pl b/qa/pmdas/slow/pmdaslow.pl
new file mode 100644
index 0000000..7d8311f
--- /dev/null
+++ b/qa/pmdas/slow/pmdaslow.pl
@@ -0,0 +1,74 @@
+#
+# Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+#
+# This program 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.
+#
+# This program 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.
+#
+
+use strict;
+use warnings;
+use PCP::PMDA;
+
+use vars qw( $pmda $start_delay $fetch_delay );
+
+sub slow_fetch_callback
+{
+ my ($cluster, $item, $inst) = @_;
+ my $metric_name = pmda_pmid_name($cluster, $item);
+
+ if ($fetch_delay > 0) {
+ sleep($fetch_delay);
+ }
+
+ $pmda->log("slow_fetch_callback $metric_name $cluster:$item ($inst)\n");
+
+ if ($inst != PM_IN_NULL) { return (PM_ERR_INST, 0); }
+ if (!defined($metric_name)) { return (PM_ERR_PMID, 0); }
+
+ return (17, 1);
+}
+
+# Usage: pmdaslow [startdelay [fetchdelay]]
+#
+$start_delay = 0;
+$start_delay = $ARGV[0] unless !defined($ARGV[0]);
+$fetch_delay = 0;
+$fetch_delay = $ARGV[1] unless !defined($ARGV[1]);
+
+#debug# print 'start delay: ',$start_delay,' sec\n';
+#debug# print 'fetch delay: ',$fetch_delay,' sec\n';
+
+$pmda = PCP::PMDA->new('slow', 243);
+$pmda->connect_pmcd unless $start_delay < 0;
+
+if ($start_delay < 0) {
+ sleep(-$start_delay);
+}
+if ($start_delay > 0) {
+ sleep($start_delay);
+}
+
+$pmda->add_metric(pmda_pmid(0,0), PM_TYPE_U32, PM_INDOM_NULL,
+ PM_SEM_INSTANT, pmda_units(0,0,0,0,0,0),
+ 'slow.seventeen', '', '');
+
+$pmda->set_fetch_callback(\&slow_fetch_callback);
+$pmda->set_user('pcp');
+$pmda->run;
+
+=pod
+
+=head1 NAME
+
+pmdaslow - QA PMDA
+
+=head1 DESCRIPTION
+
+DO NOT INSTALL THIS PMDA.
diff --git a/qa/pmdas/slow_python/GNUmakefile b/qa/pmdas/slow_python/GNUmakefile
new file mode 100644
index 0000000..20ffe63
--- /dev/null
+++ b/qa/pmdas/slow_python/GNUmakefile
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+#
+# This program 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.
+#
+# This program 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.
+#
+
+TOPDIR = ../../..
+include $(TOPDIR)/src/include/builddefs
+
+IAM = slow_python
+TESTDIR = $(PCP_VAR_DIR)/testsuite/pmdas/$(IAM)
+PYSCRIPT = pmda$(IAM).python
+LSRCFILES = Install Remove $(PYSCRIPT) GNUmakefile.install
+
+# Uses some domain as slow PMDA (QA never installs both together)
+#
+DOMAIN = SLOW
+
+LDIRT = domain.h $(IAM).log pmns.python
+
+default default_pcp setup: check_domain
+
+include $(BUILDRULES)
+
+install_pcp install: default
+ $(INSTALL) -m 755 -d $(TESTDIR)
+ $(INSTALL) -m 755 Install Remove $(TESTDIR)
+ $(INSTALL) -m 644 $(PYSCRIPT) $(TESTDIR)/$(PYSCRIPT)
+ $(INSTALL) -m 644 GNUmakefile.install $(TESTDIR)/GNUmakefile
+
+check_domain: $(TOPDIR)/src/pmns/stdpmid
+ $(DOMAIN_PYTHONRULE)
diff --git a/qa/pmdas/slow_python/GNUmakefile.install b/qa/pmdas/slow_python/GNUmakefile.install
new file mode 100644
index 0000000..62a9c73
--- /dev/null
+++ b/qa/pmdas/slow_python/GNUmakefile.install
@@ -0,0 +1,5 @@
+default default_pcp setup:
+
+clobber clean:
+ rm -f domain.h domain.h.python domain.h.save
+ rm -f pmns pmns.python pmns.save
diff --git a/qa/pmdas/slow_python/Install b/qa/pmdas/slow_python/Install
new file mode 100755
index 0000000..ab05eb8
--- /dev/null
+++ b/qa/pmdas/slow_python/Install
@@ -0,0 +1,38 @@
+#! /bin/sh
+#
+# Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+#
+# This program 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.
+#
+# This program 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.
+#
+# Install the slow PMDA
+#
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=slow_python
+python_opt=true
+daemon_opt=false
+forced_restart=false
+
+pmdaSetup
+$PCP_ECHO_PROG $PCP_ECHO_N "Startup delay (secs) [0]? $PCP_ECHO_C"
+read x
+[ -z "$x" ] && x=0
+$PCP_ECHO_PROG $PCP_ECHO_N "Fetch delay (secs) [0]? $PCP_ECHO_C"
+read y
+[ -z "$y" ] && y=0
+python_args="$python_args $x $y"
+[ "$x" -lt 0 ] && check_delay=`expr -1 \* $x + 2`
+[ "$x" -gt 0 ] && check_delay=`expr $x + 2`
+
+pmdaInstall
+exit 0
diff --git a/qa/pmdas/slow_python/Remove b/qa/pmdas/slow_python/Remove
new file mode 100755
index 0000000..c3cbda8
--- /dev/null
+++ b/qa/pmdas/slow_python/Remove
@@ -0,0 +1,25 @@
+#! /bin/sh
+#
+# Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+#
+# This program 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.
+#
+# This program 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.
+#
+# Remove the slow PMDA
+#
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=slow_python
+
+pmdaSetup
+pmdaRemove
+exit 0
diff --git a/qa/pmdas/slow_python/pmdaslow_python.python b/qa/pmdas/slow_python/pmdaslow_python.python
new file mode 100644
index 0000000..c1da8e8
--- /dev/null
+++ b/qa/pmdas/slow_python/pmdaslow_python.python
@@ -0,0 +1,84 @@
+'''
+Python implementation of the "slow_python" Performance Metrics Domain Agent.
+'''
+#
+# Copyright (c) 2013 Red Hat.
+# Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+#
+# This program 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.
+#
+# This program 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.
+#
+
+import sys
+import os
+import time
+import ctypes
+from ctypes import c_int, POINTER, cast
+import cpmapi as c_api
+from pcp.pmda import PMDA, pmdaMetric
+from pcp.pmapi import pmUnits, pmContext as PCP
+
+class SlowPMDA(PMDA):
+ '''
+ A slow Performance Metrics Domain Agent.
+ DO NOT INSTALL - for QA ONLY.
+ '''
+
+ def slow_fetch_callback(self, cluster, item, inst):
+ global fetch_delay
+
+ if int(fetch_delay) < 0:
+ time.sleep(-1*int(fetch_delay))
+
+ if int(fetch_delay) > 0:
+ time.sleep(int(fetch_delay))
+
+ if cluster == 0 and item == 0:
+ return [13, 1]
+ return [c_api.PM_ERR_PMID, 0]
+
+ def __init__(self, name, domain):
+ global start_delay
+
+ PMDA.__init__(self, name, domain)
+
+ self.configfile = PCP.pmGetConfig('PCP_PMDAS_DIR')
+ self.configfile += '/' + name + '/' + name + '.conf'
+
+ if int(start_delay) > 0:
+ self.connect_pmcd()
+
+ if int(start_delay) < 0:
+ time.sleep(-1*int(start_delay))
+ if int(start_delay) > 0:
+ time.sleep(int(start_delay))
+
+ self.add_metric(name + '.thirteen', pmdaMetric(self.pmid(0, 0),
+ c_api.PM_TYPE_32, c_api.PM_INDOM_NULL, c_api.PM_SEM_INSTANT,
+ pmUnits(0, 0, 0, 0, 0, 0)))
+
+ self.set_fetch_callback(self.slow_fetch_callback)
+ self.set_user(PCP.pmGetConfig('PCP_USER'))
+
+# Usage: pmdaslow [startdelay [fetchdelay]]
+#
+start_delay = 0
+if len(sys.argv) >= 2:
+ start_delay = sys.argv[1]
+fetch_delay = 0
+if len(sys.argv) >= 3:
+ fetch_delay = sys.argv[2]
+
+#debug# print 'start delay: ', start_delay, ' sec'
+#debug# print 'fetch delay: ', fetch_delay, ' sec'
+
+if __name__ == '__main__':
+ SlowPMDA('slow_python', 242).run()
+