diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 16:28:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 16:28:20 +0000 |
commit | dcc721a95bef6f0d8e6d8775b8efe33e5aecd562 (patch) | |
tree | 66a2774cd0ee294d019efd71d2544c70f42b2842 /tests/chkseq.c | |
parent | Initial commit. (diff) | |
download | rsyslog-dcc721a95bef6f0d8e6d8775b8efe33e5aecd562.tar.xz rsyslog-dcc721a95bef6f0d8e6d8775b8efe33e5aecd562.zip |
Adding upstream version 8.2402.0.upstream/8.2402.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/chkseq.c')
-rw-r--r-- | tests/chkseq.c | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/tests/chkseq.c b/tests/chkseq.c new file mode 100644 index 0000000..00674e9 --- /dev/null +++ b/tests/chkseq.c @@ -0,0 +1,249 @@ +/* Checks if a file consists of line of strictly monotonically + * increasing numbers. An expected start and end number may + * be set. + * + * Params + * -f<filename> file to process, if not given stdin is processed. + * -s<starting number> -e<ending number> + * default for s is 0. -e should be given (else it is also 0) + * -d may be specified, in which case duplicate messages are permitted. + * -m number of messages permitted to be missing without triggering a + * failure. This is necessary for some failover tests, where it is + * impossible to totally guard against messagt loss. By default, NO + * message is permitted to be lost. + * -T anticipate truncation (which means specified payload length may be + * more than actual payload (which may have been truncated) + * -i increment between messages (default: 1). Can be used for tests which + * intentionally leave consistent gaps in the message numbering. + * + * Part of the testbench for rsyslog. + * + * Copyright 2009-2018 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog 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 3 of the License, or + * (at your option) any later version. + * + * Rsyslog 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 Rsyslog. If not, see <http://www.gnu.org/licenses/>. + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if defined(_AIX) + #include <unistd.h> +#else + #include <getopt.h> +#endif + +int main(int argc, char *argv[]) +{ + FILE *fp; + int val; + int i; + int ret = 0; + int scanfOK; + int verbose = 0; + int bHaveExtraData = 0; + int bAnticipateTruncation = 0; + int dupsPermitted = 0; + int start = 0, end = 0; + int opt; + int lostok = 0; /* how many messages are OK to be lost? */ + int nDups = 0; + int increment = 1; + int reachedEOF; + int edLen; /* length of extra data */ + static char edBuf[500*1024]; /* buffer for extra data (pretty large to be on the save side...) */ + static char ioBuf[sizeof(edBuf)+1024]; + char *file = NULL; + + while((opt = getopt(argc, argv, "i:e:f:ds:vm:ET")) != EOF) { + switch((char)opt) { + case 'f': + file = optarg; + break; + case 'd': + dupsPermitted = 1; + break; + case 'i': + increment = atoi(optarg); + break; + case 'e': + end = atoi(optarg); + break; + case 's': + start = atoi(optarg); + break; + case 'v': + ++verbose; + break; + case 'm': + lostok = atoi(optarg); + break; + case 'E': + bHaveExtraData = 1; + break; + case 'T': + bAnticipateTruncation = 1; + break; + default:printf("Invalid call of chkseq, optchar='%c'\n", opt); + printf("Usage: chkseq file -sstart -eend -d -E\n"); + exit(1); + } + } + + if(start > end) { + printf("start must be less than or equal end!\n"); + exit(1); + } + + if(verbose) { + printf("chkseq: start %d, end %d\n", start, end); + } + + /* read file */ + if(file == NULL) { + fp = stdin; + } else { + fp = fopen(file, "r"); + } + if(fp == NULL) { + printf("error opening file '%s'\n", file); + perror(file); + exit(1); + } + + for(i = start ; i <= end ; i += increment) { + if(bHaveExtraData) { + if(fgets(ioBuf, sizeof(ioBuf), fp) == NULL) { + scanfOK = 0; + } else { + scanfOK = sscanf(ioBuf, "%d,%d,%s\n", &val, &edLen, edBuf) == 3 ? 1 : 0; + } + if(edLen != (int) strlen(edBuf)) { + if (bAnticipateTruncation == 1) { + if (edLen < (int) strlen(edBuf)) { + printf("extra data length specified %d, but actually is %ld in" + " record %d (truncation was anticipated, but payload should" + " have been smaller than data-length, not larger)\n", + edLen, (long) strlen(edBuf), i); + exit(1); + } + } else { + printf("extra data length specified %d, but actually is %ld in record %d\n", + edLen, (long) strlen(edBuf), i); + exit(1); + } + } + } else { + if(fgets(ioBuf, sizeof(ioBuf), fp) == NULL) { + scanfOK = 0; + } else { + scanfOK = sscanf(ioBuf, "%d\n", &val) == 1 ? 1 : 0; + } + } + if(!scanfOK) { + printf("scanf error in index i=%d\n", i); + exit(1); + } + while(val > i && lostok > 0) { + --lostok; + printf("message %d missing (ok due to -m [now %d])\n", i, lostok); + ++i; + } + if(val != i) { + if(val == i - increment && dupsPermitted) { + --i; + ++nDups; + } else { + printf("read value %d, but expected value %d\n", val, i); + exit(1); + } + } + } + + if(i - increment != end) { + printf("lastrecord does not match. file: %d, expected %d\n", i - increment, end); + exit(1); + } + + int c = getc(fp); + if(c == EOF) { + reachedEOF = 1; + } else { + ungetc(c, fp); + /* if duplicates are permitted, we need to do a final check if we have duplicates at the + * end of file. + */ + if(dupsPermitted) { + i = end; + while(!feof(fp)) { + if(bHaveExtraData) { + if(fgets(ioBuf, sizeof(ioBuf), fp) == NULL) { + scanfOK = 0; + } else { + scanfOK = sscanf(ioBuf, "%d,%d,%s\n", &val, + &edLen, edBuf) == 3 ? 1 : 0; + } + if(edLen != (int) strlen(edBuf)) { + if (bAnticipateTruncation == 1) { + if (edLen < (int) strlen(edBuf)) { + printf("extra data length specified %d, but " + "actually is %ld in record %d (truncation was" + " anticipated, but payload should have been " + "smaller than data-length, not larger)\n", + edLen, (long) strlen(edBuf), i); + exit(1); + } + } else { + printf("extra data length specified %d, but actually " + "is %ld in record %d\n", + edLen, (long) strlen(edBuf), i); + exit(1); + } + } + } else { + if(fgets(ioBuf, sizeof(ioBuf), fp) == NULL) { + scanfOK = 0; + } else { + scanfOK = sscanf(ioBuf, "%d\n", &val) == 1 ? 1 : 0; + } + } + + if(val != i) { + reachedEOF = 0; + goto breakIF; + } + } + reachedEOF = feof(fp) ? 1 : 0; + } else { + reachedEOF = 0; + } + } + +breakIF: + if(nDups != 0) + printf("info: had %d duplicates (this is no error)\n", nDups); + + if(!reachedEOF) { + printf("end of processing, but NOT end of file! First line of extra data is:\n"); + for(c = fgetc(fp) ; c != '\n' && c != EOF ; c = fgetc(fp)) + putchar(c); + putchar('\n'); + exit(1); + } + + exit(ret); +} |