On Fri, Sep 04, 2020 at 11:24:39PM +0200, Peter Eisentraut wrote: > According to the POSIX standard, atoi() is not required to do any error > checking, and if you want error checking, you should use strtol(). > > And if you do that, you might as well change the variables to unsigned and > use strtoul(), and then drop the checks for <=0.
Switching to unsigned makes sense, indeed. > I would allow 0. It's not > very useful, but it's not harmful and could be applicable in testing. Hmm, OK. For pg_test_fsync, 0 means infinity, and for pg_test_timing that means stopping immediately (we currently don't allow that). How does this apply to testing? For pg_test_fsync, using 0 would mean to just remain stuck in the first fsync() pattern, while for pg_test_fsync this means doing no test loops at all, generating a useless log once done. Or do you mean to change the logic of pg_test_fsync so as --secs-per-test=0 means doing one single write? That's something I thought about for this thread, but I am not sure that the extra regression test gain is worth more complexity in this code. -- Michael
diff --git a/src/bin/pg_test_fsync/.gitignore b/src/bin/pg_test_fsync/.gitignore index f3b5932498..5eb5085f45 100644 --- a/src/bin/pg_test_fsync/.gitignore +++ b/src/bin/pg_test_fsync/.gitignore @@ -1 +1,3 @@ /pg_test_fsync + +/tmp_check/ diff --git a/src/bin/pg_test_fsync/Makefile b/src/bin/pg_test_fsync/Makefile index 7632c94eb7..c4f9ae0664 100644 --- a/src/bin/pg_test_fsync/Makefile +++ b/src/bin/pg_test_fsync/Makefile @@ -22,6 +22,12 @@ install: all installdirs installdirs: $(MKDIR_P) '$(DESTDIR)$(bindir)' +check: + $(prove_check) + +installcheck: + $(prove_installcheck) + uninstall: rm -f '$(DESTDIR)$(bindir)/pg_test_fsync$(X)' diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c index 6e47293123..db96986684 100644 --- a/src/bin/pg_test_fsync/pg_test_fsync.c +++ b/src/bin/pg_test_fsync/pg_test_fsync.c @@ -62,7 +62,7 @@ do { \ static const char *progname; -static int secs_per_test = 5; +static uint32 secs_per_test = 5; static int needs_unlink = 0; static char full_buf[DEFAULT_XLOG_SEG_SIZE], *buf, @@ -148,6 +148,7 @@ handle_args(int argc, char *argv[]) int option; /* Command line option */ int optindex = 0; /* used by getopt_long */ + char *endptr; if (argc > 1) { @@ -173,7 +174,19 @@ handle_args(int argc, char *argv[]) break; case 's': - secs_per_test = atoi(optarg); + secs_per_test = strtoul(optarg, &endptr, 10); + + if (endptr == optarg || *endptr != '\0') + { + pg_log_error("invalid argument for option %s", "--secs-per-test"); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); + } + if (secs_per_test == 0) + { + pg_log_error("%s must not be 0", "--secs-per-test"); + exit(1); + } break; default: diff --git a/src/bin/pg_test_fsync/t/001_basic.pl b/src/bin/pg_test_fsync/t/001_basic.pl new file mode 100644 index 0000000000..3fdb4d07fc --- /dev/null +++ b/src/bin/pg_test_fsync/t/001_basic.pl @@ -0,0 +1,25 @@ +use strict; +use warnings; + +use Config; +use TestLib; +use Test::More tests => 12; + +######################################### +# Basic checks + +program_help_ok('pg_test_fsync'); +program_version_ok('pg_test_fsync'); +program_options_handling_ok('pg_test_fsync'); + +######################################### +# Test invalid option combinations + +command_fails_like( + [ 'pg_test_fsync', '--secs-per-test', 'a' ], + qr/\Qpg_test_fsync: error: invalid argument for option --secs-per-test\E/, + 'pg_test_fsync: invalid argument for option --secs-per-test'); +command_fails_like( + [ 'pg_test_fsync', '--secs-per-test', '0' ], + qr/\Qpg_test_fsync: error: --secs-per-test must not be 0\E/, + 'pg_test_fsync: --secs-per-test must not be 0'); diff --git a/src/bin/pg_test_timing/.gitignore b/src/bin/pg_test_timing/.gitignore index f6c664c765..e5aac2ab12 100644 --- a/src/bin/pg_test_timing/.gitignore +++ b/src/bin/pg_test_timing/.gitignore @@ -1 +1,3 @@ /pg_test_timing + +/tmp_check/ diff --git a/src/bin/pg_test_timing/Makefile b/src/bin/pg_test_timing/Makefile index 334d6ff5c0..52994b4103 100644 --- a/src/bin/pg_test_timing/Makefile +++ b/src/bin/pg_test_timing/Makefile @@ -22,6 +22,12 @@ install: all installdirs installdirs: $(MKDIR_P) '$(DESTDIR)$(bindir)' +check: + $(prove_check) + +installcheck: + $(prove_installcheck) + uninstall: rm -f '$(DESTDIR)$(bindir)/pg_test_timing$(X)' diff --git a/src/bin/pg_test_timing/pg_test_timing.c b/src/bin/pg_test_timing/pg_test_timing.c index e14802372b..229c2f27b6 100644 --- a/src/bin/pg_test_timing/pg_test_timing.c +++ b/src/bin/pg_test_timing/pg_test_timing.c @@ -11,10 +11,10 @@ static const char *progname; -static int32 test_duration = 3; +static uint32 test_duration = 3; static void handle_args(int argc, char *argv[]); -static uint64 test_timing(int32); +static uint64 test_timing(uint32 duration); static void output(uint64 loop_count); /* record duration in powers of 2 microseconds */ @@ -47,6 +47,7 @@ handle_args(int argc, char *argv[]) int option; /* Command line option */ int optindex = 0; /* used by getopt_long */ + char *endptr; if (argc > 1) { @@ -68,7 +69,21 @@ handle_args(int argc, char *argv[]) switch (option) { case 'd': - test_duration = atoi(optarg); + test_duration = strtoul(optarg, &endptr, 10); + + if (endptr == optarg || *endptr != '\0') + { + fprintf(stderr, _("%s: invalid argument for option %s\n"), + progname, "--duration"); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); + } + if (test_duration == 0) + { + fprintf(stderr, _("%s: %s must not be 0\n"), progname, + "--duration"); + exit(1); + } break; default: @@ -89,26 +104,15 @@ handle_args(int argc, char *argv[]) exit(1); } - if (test_duration > 0) - { - printf(ngettext("Testing timing overhead for %d second.\n", - "Testing timing overhead for %d seconds.\n", - test_duration), - test_duration); - } - else - { - fprintf(stderr, - _("%s: duration must be a positive integer (duration is \"%d\")\n"), - progname, test_duration); - fprintf(stderr, _("Try \"%s --help\" for more information.\n"), - progname); - exit(1); - } + + printf(ngettext("Testing timing overhead for %d second.\n", + "Testing timing overhead for %d seconds.\n", + test_duration), + test_duration); } static uint64 -test_timing(int32 duration) +test_timing(uint32 duration) { uint64 total_time; int64 time_elapsed = 0; diff --git a/src/bin/pg_test_timing/t/001_basic.pl b/src/bin/pg_test_timing/t/001_basic.pl new file mode 100644 index 0000000000..d194ad04ea --- /dev/null +++ b/src/bin/pg_test_timing/t/001_basic.pl @@ -0,0 +1,25 @@ +use strict; +use warnings; + +use Config; +use TestLib; +use Test::More tests => 12; + +######################################### +# Basic checks + +program_help_ok('pg_test_timing'); +program_version_ok('pg_test_timing'); +program_options_handling_ok('pg_test_timing'); + +######################################### +# Test invalid option combinations + +command_fails_like( + [ 'pg_test_timing', '--duration', 'a' ], + qr/\Qpg_test_timing: invalid argument for option --duration\E/, + 'pg_test_timing: invalid argument for option --duration'); +command_fails_like( + [ 'pg_test_timing', '--duration', '0' ], + qr/\Qpg_test_timing: --duration must not be 0\E/, + 'pg_test_timing: --duration must not be 0');
signature.asc
Description: PGP signature