diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
commit | 47e6e7c84f008a53061e661f31ae96629bc694ef (patch) | |
tree | 648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /qa/src/torture_pmns.c | |
download | pcp-debian/3.9.10.tar.gz |
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'qa/src/torture_pmns.c')
-rw-r--r-- | qa/src/torture_pmns.c | 495 |
1 files changed, 495 insertions, 0 deletions
diff --git a/qa/src/torture_pmns.c b/qa/src/torture_pmns.c new file mode 100644 index 0000000..17e986c --- /dev/null +++ b/qa/src/torture_pmns.c @@ -0,0 +1,495 @@ +/* + * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2009 Ken McDonell. All Rights Reserved. + * + * Exercise just the PMNS functions ... intended for dynamic PMNS testing + * ... this is really torture_api re-tweaked + */ + +#include <pcp/pmapi.h> +#include <pcp/impl.h> + +static int vflag; +static char *context_name = "localhost"; +static int context_type = 0; /* archive, host or local */ +static char *namespace = PM_NS_DEFAULT; +static int all_children = 1; /* do the children of "" test */ +static int root_children; /* only do the children of "" test */ +static int dump_metrics; /* just dump the metrics and exit */ +/* + * pmns_style == 1 => do PMNS style loading the old way + * pmns_style == 2 => try to use the distributed PMNS + */ +static int pmns_style = 2; + +static int numpmid = 0; +static char **namelist; /* The list of metrics to test out */ +static pmID *midlist; + +typedef struct name_status { + char *name; + int status; +}name_status; + +#define REPORT(str, sts) \ +printf("%s() returns %d", str, sts);\ +if (sts < 0) printf(" (%s)", pmErrStr(sts));\ +putchar('\n'); + +static int +compar_str(const void *a, const void *b) +{ + char **ca = (char **)a; + char **cb = (char **)b; + return strcmp(*ca, *cb); +} + +static int +compar_name_status(const void *a, const void *b) +{ + name_status *ca = (name_status*)a; + name_status *cb = (name_status*)b; + return strcmp(ca->name, cb->name); +} + +void +do_chn(char *name) +{ + int n; + int j; + char **enfants = NULL; + name_status *ns_table = NULL; + int has_children = 0; + + n = pmGetChildren(name, &enfants); + REPORT("pmGetChildren", n); + if (n > 0) { + qsort(enfants, n, sizeof(enfants[0]), compar_str); + has_children = 1; + } + + /* test out pmGetChildrenStatus */ + { + char **s_enfants = NULL; + int *status = NULL; + + n = pmGetChildrenStatus(name, &s_enfants, &status); + REPORT("pmGetChildrenStatus", n); + if (n > 0) { + /* create a ns_table for sorting */ + ns_table = (name_status*)malloc(sizeof(name_status)*n); + if (ns_table == 0) { + printf("Malloc failed\n"); + exit(1); + } + for(j = 0; j < n; j++) { + ns_table[j].name = s_enfants[j]; + ns_table[j].status = status[j]; + } + + qsort(ns_table, n, sizeof(ns_table[0]), compar_name_status); + + for (j = 0; j < n; j++) { + if (strcmp(ns_table[j].name, enfants[j]) != 0) { + printf("pmGetChildrenStatus mismatch: \"%s\" vs \"%s\"\n", + enfants[j], ns_table[j].name); + } + }/*for*/ + }/*if*/ + if (s_enfants) free(s_enfants); + if (status) free(status); + } + + if (has_children && vflag) { + printf("children of \"%s\" ...\n", name); + for (j = 0; j < n; j++) { + + printf(" %-20s", enfants[j]); + if (ns_table) + printf("<s = %d>", ns_table[j].status); + printf("\n"); + } + } + + if (enfants) free(enfants); + if (ns_table) free(ns_table); + +} + +void +parse_args(int argc, char **argv) +{ + extern char *optarg; + extern int optind; + int errflag = 0; + int c; + static char *usage = "[-bcLmvx] [-a archive] [-h host] [-n namespace] [-s 1|2] metricname ..."; + char *endnum; + int sts; +#ifdef PCP_DEBUG + static char *debug = "[-D <dbg>]"; +#else + static char *debug = ""; +#endif + + __pmSetProgname(argv[0]); + + while ((c = getopt(argc, argv, "a:bcD:h:iLmn:s:vx")) != EOF) { + switch (c) { + case 'a': /* archive name for context */ + if (context_type != 0) { + fprintf(stderr, "%s: at most one of -a, -h, -L and -x allowed\n", + pmProgname); + errflag++; + } + context_type = PM_CONTEXT_ARCHIVE; + context_name = optarg; + break; + + case 'b': /* dont do the children of "" test */ + all_children = 0; + break; + + case 'c': /* only do the children of "" test */ + root_children = 1; + break; + + case 'D': /* debug flag */ + sts = __pmParseDebug(optarg); + if (sts < 0) { + fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n", + pmProgname, optarg); + errflag++; + } + else + pmDebug |= sts; + break; + + case 'h': /* context_namename for live context */ + if (context_type != 0) { + fprintf(stderr, "%s: at most one of -a, -h, -L and -x allowed\n", + pmProgname); + errflag++; + } + context_type = PM_CONTEXT_HOST; + context_name = optarg; + break; + + case 'i': /* non-IRIX names (always true now) */ + break; + + case 'L': /* LOCAL context */ + if (context_type != 0) { + fprintf(stderr, "%s: at most one of -a, -h, -L and -x allowed\n", + pmProgname); + errflag++; + } + context_type = PM_CONTEXT_LOCAL; + context_name = NULL; + break; + + case 'm': /* dump out the list of metrics to be tested */ + dump_metrics = 1; + break; + + case 'n': /* alternative name space file */ + namespace = optarg; + break; + + case 'v': /* verbose */ + vflag++; + break; + + case 'x': /* NO context */ + if (context_type != 0) { + fprintf(stderr, "%s: at most one of -a, -h, -L and -x allowed\n", + pmProgname); + errflag++; + } + context_type = -1; + context_name = NULL; + break; + + case 's': /* pmns style */ + pmns_style = (int)strtol(optarg, &endnum, 10); + if (*endnum != '\0') { + printf("%s: -s requires numeric argument\n", pmProgname); + errflag++; + } + break; + + case '?': + default: + errflag++; + break; + } + } + + if (context_type == 0) context_type = PM_CONTEXT_HOST; + + numpmid = argc - optind; + if (numpmid < 1) { + errflag++; + } + else { + int i; + if ((midlist = (pmID *)malloc(numpmid*sizeof(pmID))) == NULL) { + fprintf(stderr, "malloc failed for midlist[]: %s\n", strerror(errno)); + exit(1); + } + if ((namelist = (char **)malloc(numpmid*sizeof(char *))) == NULL) { + fprintf(stderr, "malloc failed for namelist[]: %s\n", strerror(errno)); + exit(1); + } + for (i = 0; i < numpmid; i++) + namelist[i] = argv[optind+i]; + } + + if (errflag) { + printf("Usage: %s %s%s\n", pmProgname, debug, usage); + exit(1); + } +} + +void +load_namespace(char *namespace) +{ + struct timeval now, then; + int sts; + + gettimeofday(&then, (struct timezone *)0); + if ((sts = pmLoadNameSpace(namespace)) < 0) { + printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts)); + exit(1); + } + gettimeofday(&now, (struct timezone *)0); + printf("Name space load: %.2f msec\n", __pmtimevalSub(&now, &then)*1000); +} + +void +test_api(void) +{ + int sts; + int i; + int *instlist; + char **inamelist; + char **allnames; + int n; + char *back; + pmResult *resp; + pmDesc desc; + + if (context_type != -1) { + if (context_type == 0) { + char local[MAXHOSTNAMELEN]; + context_type = PM_CONTEXT_HOST; + gethostname(local, sizeof(local)); + context_name = local; + } + + if ((sts = pmNewContext(context_type, context_name)) < 0) { + printf("%s: Error in creating %s context for \"%s\": %s\n", + pmProgname, + context_type == PM_CONTEXT_HOST ? "host" : + context_type == PM_CONTEXT_ARCHIVE ? "archive" : + "local", + context_name, + pmErrStr(sts)); + } + } + + if (vflag > 1) { + __pmDumpNameSpace(stdout, 1); + } + + n = pmLookupName(numpmid, namelist, midlist); + REPORT("pmLookupName", n); + + for (i = 0; i < numpmid; i++) { + printf("%s: id[%d] = %s\n", namelist[i], i, pmIDStr(midlist[i])); + } + + /* Set mode for archive so that an indom can be retrieved + * if necessary. + * Getting an indom is done based on current time. + * If we try and get an indom from the start then we may not + * have one yet. + */ + if (context_type == PM_CONTEXT_ARCHIVE) { + struct timeval when; + + n = pmGetArchiveEnd(&when); + REPORT("pmGetArchiveEnd", n); + + n = pmSetMode(PM_MODE_BACK, &when, 1000); + REPORT("pmSetMode", n); + } + + for (i = 0; i < numpmid && !root_children; i++) { + putchar('\n'); + if (vflag) { + printf("=== metric %d === name: %s pmid %s\n", i, namelist[i], pmIDStr(midlist[i])); + } + if (midlist[i] != PM_ID_NULL) { + n = pmNameID(midlist[i], &back); + REPORT("pmNameID", n); + if (n >= 0) { + if (vflag) { + printf("pmid: %s ", pmIDStr(midlist[i])); + printf(" name: %s\n", back); + } + if (strcmp(namelist[i], back) != 0) { + printf("pmNameID botch: expected \"%s\", got \"%s\"\n", + namelist[i], back); + } + free(back); + } + n = pmNameAll(midlist[i], &allnames); + REPORT("pmNameAll", n); + if (n >= 0) { + int j; + for (j = 0; j < n; j++) { + if (vflag) { + printf("pmid: %s ", pmIDStr(midlist[i])); + printf(" name: %s\n", allnames[j]); + } + if (strcmp(namelist[i], allnames[j]) != 0) { + printf("pmNameAll info: expected \"%s\", got \"%s\"\n", + namelist[i], allnames[j]); + } + } + free(allnames); + } + if (context_type != -1) { + n = pmLookupDesc(midlist[i], &desc); + REPORT("pmLookupDesc", n); + if (n >= 0) { + if (vflag > 1) { + const char *u = pmUnitsStr(&desc.units); + printf("desc: type=%d indom=0x%x sem=%d units=%s\n", + desc.type, desc.indom, desc.sem, + *u == '\0' ? "none" : u); + } + if (desc.indom == PM_INDOM_NULL) + continue; + n = pmGetInDom(desc.indom, &instlist, &inamelist); + REPORT("pmGetInDom", n); + if (n >= 0) { + int j; + int numinst = n; + char *name; + for (j = 0; j < numinst; j++) { + if (vflag > 1) + printf(" instance id: 0x%x\n", instlist[j]); + n = pmNameInDom(desc.indom, instlist[j], &name); + REPORT("pmNameInDom", n); + if (n >= 0) { + if (vflag > 1) + printf(" %s (== %s?)\n", name, inamelist[j]); + n = pmLookupInDom(desc.indom, name); + REPORT("pmLookupInDom", n); + if (n >= 0) { + if (n != instlist[j]) { + printf("botch: pmLookupInDom returns 0x%x, expected 0x%x\n", + n, instlist[j]); + } + } + free(name); + } + } + free(instlist); + free(inamelist); + } + } + } + } + do_chn(namelist[i]); + } /* for each named metric */ + + if (all_children || root_children) { + /* root check */ + /* + * This is only useful in a namspace where irix has not been stripped from the + * names. Once irix is stripped from the names, the list returned becomes + * to variable to do a QA in this manner. + * Test #568 using pmns_xlate tests the root. + */ + printf("\n"); + do_chn(""); + } + + if (context_type == PM_CONTEXT_ARCHIVE) { + struct timeval when; + + when.tv_sec = 0; + when.tv_usec = 0; + + if (vflag) + printf("\nArchive result ...\n"); + for (i = 0; i < numpmid; i++) { + if (midlist[i] == PM_ID_NULL) + continue; + if ((n = pmSetMode(PM_MODE_FORW, &when, 0)) < 0) { + printf("pmSetMode(PM_MODE_FORW): %s\n", pmErrStr(n)); + } + else { + if (vflag) + printf("Fetch of %s:\n", namelist[i]); + if ((n = pmFetch(1, &midlist[i], &resp)) < 0) { + printf("Archive pmFetch: %s\n", pmErrStr(n)); + } + else { + if (vflag) + __pmDumpResult(stdout, resp); + pmFreeResult(resp); + } + } + }/*for*/ + } + + else if (context_type == PM_CONTEXT_HOST) { + if ((n = pmSetMode(PM_MODE_LIVE, (struct timeval *)0, 0)) < 0) { + printf("pmSetMode(PM_MODE_LIVE): %s\n", pmErrStr(n)); + } + else { + if ((n = pmFetch(numpmid, midlist, &resp)) < 0) { + printf("real-time pmFetch: %s\n", pmErrStr(n)); + } + else { + if (vflag) { + printf("\nReal-time result ...\n"); + __pmDumpResult(stdout, resp); + } + pmFreeResult(resp); + } + } + } + +} + +int +main(int argc, char **argv) +{ + parse_args(argc, argv); + + if (dump_metrics == 1) { + int i; + for(i = 0; i < numpmid; i++) { + printf("%s\n", namelist[i]); + } + exit(0); + } + + if (pmns_style == 2) { + /* test it the new way with distributed namespace */ + /* i.e. no client loaded namespace */ + test_api(); + } + else { + /* test it the old way with namespace file */ + load_namespace(namespace); + test_api(); + } + + exit(0); +} |