diff options
-rw-r--r-- | test/ChangeLog | 10 | ||||
-rw-r--r-- | test/Makefile.am | 4 | ||||
-rw-r--r-- | test/Makefile.in | 4 | ||||
-rw-r--r-- | test/strftime.awk | 34 |
4 files changed, 38 insertions, 14 deletions
diff --git a/test/ChangeLog b/test/ChangeLog index b5ff6e64..95f8fe17 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,13 @@ +2014-01-16 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * Makefile.am (strftime): Remove comment about the race condition, since + this should be fixed. And gawk now calls date inside the script. + * strftime.awk: Based on an idea from Pat Ranking, fix the race + condition by looping repeatedly over strftime/date/strftime until + the before and after strftime results match. That should fix + the race condition where the seconds field might increment between + invocations. + 2014-01-14 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am (split_after_fpat): New test. diff --git a/test/Makefile.am b/test/Makefile.am index e6dfea17..cb9bdc83 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1252,12 +1252,10 @@ nonl:: @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ strftime:: - @echo This test could fail on slow machines or on a minute boundary, - @echo so if it does, double check the actual results: @echo $@ @GAWKLOCALE=C; export GAWKLOCALE; \ TZ=GMT0; export TZ; \ - (LC_ALL=C date) | $(AWK) -v OUTPUT=_$@ -f "$(srcdir)"/strftime.awk + $(AWK) -v OUTPUT=_$@ -f "$(srcdir)"/strftime.awk @-$(CMP) strftime.ok _$@ && rm -f _$@ strftime.ok || exit 0 litoct:: diff --git a/test/Makefile.in b/test/Makefile.in index 8fe395ef..fa0f6345 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1676,12 +1676,10 @@ nonl:: @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ strftime:: - @echo This test could fail on slow machines or on a minute boundary, - @echo so if it does, double check the actual results: @echo $@ @GAWKLOCALE=C; export GAWKLOCALE; \ TZ=GMT0; export TZ; \ - (LC_ALL=C date) | $(AWK) -v OUTPUT=_$@ -f "$(srcdir)"/strftime.awk + $(AWK) -v OUTPUT=_$@ -f "$(srcdir)"/strftime.awk @-$(CMP) strftime.ok _$@ && rm -f _$@ strftime.ok || exit 0 litoct:: diff --git a/test/strftime.awk b/test/strftime.awk index 775cd4e5..a52957f0 100644 --- a/test/strftime.awk +++ b/test/strftime.awk @@ -2,18 +2,36 @@ # # input is the output of `date', see Makefile.in # -# The mucking about with $0 and $N is to avoid problems +# The mucking about with $0 and $NF is to avoid problems # on cygwin, where the timezone field is empty and there # are two consecutive blanks. -# Additional mucking about to lop off the seconds field; -# helps decrease chance of difference due to a second boundary +BEGIN { + maxtries = 10 + datecmd = "date" + fmt = "%a %b %d %H:%M:%S %Z %Y" -{ - $3 = sprintf("%02d", $3 + 0) - $4 = substr($4, 1, 5) - print > "strftime.ok" - $0 = strftime("%a %b %d %H:%M %Z %Y") + # loop until before equals after, thereby protecting + # against a race condition where the seconds field might have + # incremented between running date and strftime + i = 0 + while (1) { + if (++i > maxtries) { + printf "Warning: this system is so slow that after %d attempts, we could never get two sequential invocations of strftime to give the same result!\n", maxtries > "/dev/stderr" + break + } + before = strftime(fmt) + datecmd | getline sd + after = strftime(fmt) + close(datecmd) + if (before == after) { + if (i > 1) + printf "Notice: it took %d loops to get the before and after strftime values to match\n", i > "/dev/stderr" + break + } + } + print sd > "strftime.ok" + $0 = after $NF = $NF print > OUTPUT } |