chiark / gitweb /
Infrastructure: Switch testing over to Autotest.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 4 May 2009 00:38:20 +0000 (01:38 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 20 Oct 2012 11:40:09 +0000 (12:40 +0100)
Currently mLib testing is a hopeless mess.  Maybe this will help sort it
out.

Some minor fixing was applied to the data-structure tests:

  * assoc and sym needed fixing to avoid corrupting their internal
    table-size count.  There are now additional assertions that this
    internal count matches the hash table's own count.

  * darray needed fixing to report empty-array on `first' and `last'
    requests.

47 files changed:
.links
Makefile.am
codec/Makefile.am
codec/base32.in [deleted file]
codec/base32.ref [deleted file]
codec/base64.in [deleted file]
codec/base64.ref [deleted file]
codec/hex.in [deleted file]
codec/hex.ref [deleted file]
codec/tests.at [new file with mode: 0644]
configure.ac
debian/changelog
hash/Makefile.am
hash/t/crc32-test.c [new file with mode: 0644]
hash/t/crc32.tests [new file with mode: 0644]
hash/t/unihash-test.c [new file with mode: 0644]
hash/t/unihash-testgen.py [new file with mode: 0644]
hash/tests.at [new file with mode: 0644]
hash/unihash-check.pl [deleted file]
hash/unihash.c
struct/Makefile.am
struct/da-gtest [deleted file]
struct/da-ref [deleted file]
struct/sym-gtest [deleted file]
struct/sym-ref [deleted file]
struct/t/assoc-test.c [moved from struct/assoc-test.c with 86% similarity]
struct/t/da-gtest.py [new file with mode: 0644]
struct/t/da-test.c [moved from struct/da-test.c with 95% similarity]
struct/t/sym-gtest.py [new file with mode: 0644]
struct/t/sym-test.c [moved from struct/sym-test.c with 85% similarity]
struct/tests.at [new file with mode: 0644]
sys/Makefile.am
sys/t/mdup-test.c [moved from sys/mdup-test.c with 100% similarity]
sys/tests.at [new file with mode: 0644]
t/.gitignore [new file with mode: 0644]
t/Makefile.am [new file with mode: 0644]
t/atlocal.in [new file with mode: 0644]
utils/Makefile.am
utils/bits-testgen.c [deleted file]
utils/bits.in [deleted file]
utils/t/bits-test.c [moved from utils/bits.c with 98% similarity]
utils/t/bits-testgen.py [new file with mode: 0644]
utils/t/exc-test.c [moved from utils/exctest.c with 100% similarity]
utils/t/versioncmp-test.c [moved from utils/versioncmp-test.c with 100% similarity]
utils/t/versioncmp.tests [moved from utils/versioncmp.in with 100% similarity]
utils/tests.at [new file with mode: 0644]
vars.am

diff --git a/.links b/.links
index f660b625957a2ea6881673640d072f573e0c3c5f..e3423304487d4a85eabf7aafe57c1f921a850ece 100644 (file)
--- a/.links
+++ b/.links
@@ -3,5 +3,7 @@ config/auto-version
 config/confsubst
 ui/mdwopt.c
 ui/mdwopt.h
+t/autotest.am
+t/testsuite.at
 COPYING
 COPYING.LIB
index 66185ee23f2d754b63acc4265adac104a1cab8af..c50c505d61d1bbccd2871c81af7bf5bd8d72ef22 100644 (file)
@@ -98,6 +98,11 @@ libmLib_la_LIBADD    += test/libtest.la
 SUBDIRS                        += trace
 libmLib_la_LIBADD      += trace/libtrace.la
 
+###--------------------------------------------------------------------------
+### Testing.
+
+SUBDIRS                        += t
+
 ###--------------------------------------------------------------------------
 ### Distribution.
 
index 968ebf9e3a1cffe880b51364557eb95f22fab0e5..a37faecabc8a4a60119a838e43241dd5b2bf7d61 100644 (file)
@@ -60,26 +60,4 @@ bincode_LDADD                += ../mem/libmem.la
 bincode_LDADD          += ../struct/libstruct.la
 bincode_LDADD          += $(UTIL_LIBS)
 
-EXTRA_DIST             += base64.in base32.in hex.in
-EXTRA_DIST             += base64.ref base32.ref hex.ref
-CLEANFILES             += base64.out base32.out hex.out
-
-TEST_CODECS             = base64 base32 hex
-tests:: bincode
-       set -e; \
-       for codec in $(TEST_CODECS); do \
-         case $$codec in \
-           hex) flags=lowerc,ignjunk width=64 ;; \
-           base32) flags=ignjunk width=32 ;; \
-           *) flags=ignjunk width=64 ;; \
-         esac; \
-         ./bincode -e -i'\t' -f$$flags -m$$width -o$$codec.out $$codec \
-                 $(srcdir)/$$codec.in; \
-         cmp $$codec.out $(srcdir)/$$codec.ref; \
-         ./bincode -d -fignjunk -f$$flags -o$$codec.out $$codec \
-                 $(srcdir)/$$codec.ref; \
-         cmp $$codec.out $(srcdir)/$$codec.in; \
-         echo "$$codec OK"; \
-       done
-
 ###----- That's all, folks --------------------------------------------------
diff --git a/codec/base32.in b/codec/base32.in
deleted file mode 100644 (file)
index a293724..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-Buffy: You're Watchers. Without a Slayer, you're pretty much just
-  watchin' Masterpiece Theater. You can't stop Glory. You can't do
-  anything with the information you have except maybe publish it in
-  the "Everyone Thinks We're Insane-O's Home Journal." So here's how
-  it's gonna work. You're gonna tell me everything you know. Then
-  you're gonna go away. You'll contact me if and when you have any
-  further information about Glory. The magic shop will remain open.
-  Mr. Giles will stay here as my official Watcher, reinstated at full
-  salary...
-Giles: Retroactive.
-Buffy: ...to be paid retroactively from the month he was fired. I
-  will continue my work with the help of my friends...
-Buffy: We're talking about two very powerful witches and a
-  thousand-year-old ex-demon.
-Anya: Willow's a demon?!
-Philip: The boy? No power there.
-Buffy: The boy has clocked more field time than all of you
-  combined. He's part of the unit.
-Willow: That's Riley-speak.
-Xander: I've clocked field time.
-       -- Checkpoint (Buffy the Vampire Slayer, season 5 episode 12)
diff --git a/codec/base32.ref b/codec/base32.ref
deleted file mode 100644 (file)
index 4eb8975..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-       IJ2WMZTZHIQFS33VE5ZGKICXMF2GG2DF
-       OJZS4ICXNF2GQ33VOQQGCICTNRQXSZLS
-       FQQHS33VE5ZGKIDQOJSXI5DZEBWXKY3I
-       EBVHK43UBIQCA53BORRWQ2LOE4QE2YLT
-       ORSXE4DJMVRWKICUNBSWC5DFOIXCAWLP
-       OUQGGYLOE52CA43UN5YCAR3MN5ZHSLRA
-       LFXXKIDDMFXCO5BAMRXQUIBAMFXHS5DI
-       NFXGOIDXNF2GQIDUNBSSA2LOMZXXE3LB
-       ORUW63RAPFXXKIDIMF3GKIDFPBRWK4DU
-       EBWWC6LCMUQHA5LCNRUXG2BANF2CA2LO
-       BIQCA5DIMUQCERLWMVZHS33OMUQFI2DJ
-       NZVXGICXMUTXEZJAJFXHGYLOMUWU6J3T
-       EBEG63LFEBFG65LSNZQWYLRCEBJW6IDI
-       MVZGKJ3TEBUG65YKEAQGS5BHOMQGO33O
-       NZQSA53POJVS4ICZN52SO4TFEBTW63TO
-       MEQHIZLMNQQG2ZJAMV3GK4TZORUGS3TH
-       EB4W65JANNXG65ZOEBKGQZLOBIQCA6LP
-       OUTXEZJAM5XW43TBEBTW6IDBO5QXSLRA
-       LFXXKJ3MNQQGG33OORQWG5BANVSSA2LG
-       EBQW4ZBAO5UGK3RAPFXXKIDIMF3GKIDB
-       NZ4QUIBAMZ2XE5DIMVZCA2LOMZXXE3LB
-       ORUW63RAMFRG65LUEBDWY33SPEXCAVDI
-       MUQG2YLHNFRSA43IN5YCA53JNRWCA4TF
-       NVQWS3RAN5YGK3ROBIQCATLSFYQEO2LM
-       MVZSA53JNRWCA43UMF4SA2DFOJSSAYLT
-       EBWXSIDPMZTGSY3JMFWCAV3BORRWQZLS
-       FQQHEZLJNZZXIYLUMVSCAYLUEBTHK3DM
-       BIQCA43BNRQXE6JOFYXAUR3JNRSXGORA
-       KJSXI4TPMFRXI2LWMUXAUQTVMZTHSORA
-       FYXC45DPEBRGKIDQMFUWIIDSMV2HE33B
-       MN2GS5TFNR4SAZTSN5WSA5DIMUQG233O
-       ORUCA2DFEB3WC4ZAMZUXEZLEFYQESCRA
-       EB3WS3DMEBRW63TUNFXHKZJANV4SA53P
-       OJVSA53JORUCA5DIMUQGQZLMOAQG6ZRA
-       NV4SAZTSNFSW4ZDTFYXC4CSCOVTGM6J2
-       EBLWKJ3SMUQHIYLMNNUW4ZZAMFRG65LU
-       EB2HO3ZAOZSXE6JAOBXXOZLSMZ2WYIDX
-       NF2GG2DFOMQGC3TEEBQQUIBAORUG65LT
-       MFXGILLZMVQXELLPNRSCAZLYFVSGK3LP
-       NYXAUQLOPFQTUICXNFWGY33XE5ZSAYJA
-       MRSW233OH4QQUUDINFWGS4B2EBKGQZJA
-       MJXXSPZAJZXSA4DPO5SXEIDUNBSXEZJO
-       BJBHKZTGPE5CAVDIMUQGE33ZEBUGC4ZA
-       MNWG6Y3LMVSCA3LPOJSSAZTJMVWGIIDU
-       NFWWKIDUNBQW4IDBNRWCA33GEB4W65IK
-       EAQGG33NMJUW4ZLEFYQEQZJHOMQHAYLS
-       OQQG6ZRAORUGKIDVNZUXILQKK5UWY3DP
-       O45CAVDIMF2CO4ZAKJUWYZLZFVZXAZLB
-       NMXAUWDBNZSGK4R2EBESO5TFEBRWY33D
-       NNSWIIDGNFSWYZBAORUW2ZJOBIES2LJA
-       INUGKY3LOBXWS3TUEAUEE5LGMZ4SA5DI
-       MUQFMYLNOBUXEZJAKNWGC6LFOIWCA43F
-       MFZW63RAGUQGK4DJONXWIZJAGEZCSCQ=
diff --git a/codec/base64.in b/codec/base64.in
deleted file mode 100644 (file)
index 359f0e6..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-Buffy: They say how he's gonna kill me? Do you think it'll hurt?
-  Don't touch me! Were you even gonna tell me?
-Giles: I was hoping that I wouldn't have to. That there was... some
-  way around it. I...
-Buffy: I've got a way around it. I quit!
-Angel: It's not that simple.
-Buffy: I'm making it that simple! I quit! I resign, I-I'm fired,
-  you can find someone else to stop the Master from taking over!
-Giles: I'm not sure that anyone else can. All the... the signs
-  indicate...
-Buffy: The signs? READ ME THE SIGNS! TELL ME MY FORTUNE! YOU'RE SO
-  USEFUL SITTING HERE WITH ALL YOUR BOOKS! YOU'RE REALLY A LOTTA
-  HELP!
-Giles: No, I don't suppose I am.
-Angel: I know this is hard.
-Buffy: What do you know about this? You're never gonna die!
-Angel: You think I want anything to happen to you? Do you think I
-  could stand it? We just gotta figure out a way...
-Buffy: I already did. I quit, remember? Pay attention!
-Giles: Buffy, if the Master rises...
-Buffy: I don't care! I don't care. Giles, I'm sixteen years old. I
-  don't wanna die.
-       -- Prophecy Girl
-          (Buffy the Vampire Slayer, season 1 episode 12)
diff --git a/codec/base64.ref b/codec/base64.ref
deleted file mode 100644 (file)
index aa5b87a..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-       QnVmZnk6IFRoZXkgc2F5IGhvdyBoZSdzIGdvbm5hIGtpbGwgbWU/IERvIHlvdSB0
-       aGluayBpdCdsbCBodXJ0PwogIERvbid0IHRvdWNoIG1lISBXZXJlIHlvdSBldmVu
-       IGdvbm5hIHRlbGwgbWU/CkdpbGVzOiBJIHdhcyBob3BpbmcgdGhhdCBJIHdvdWxk
-       bid0IGhhdmUgdG8uIFRoYXQgdGhlcmUgd2FzLi4uIHNvbWUKICB3YXkgYXJvdW5k
-       IGl0LiBJLi4uCkJ1ZmZ5OiBJJ3ZlIGdvdCBhIHdheSBhcm91bmQgaXQuIEkgcXVp
-       dCEKQW5nZWw6IEl0J3Mgbm90IHRoYXQgc2ltcGxlLgpCdWZmeTogSSdtIG1ha2lu
-       ZyBpdCB0aGF0IHNpbXBsZSEgSSBxdWl0ISBJIHJlc2lnbiwgSS1JJ20gZmlyZWQs
-       CiAgeW91IGNhbiBmaW5kIHNvbWVvbmUgZWxzZSB0byBzdG9wIHRoZSBNYXN0ZXIg
-       ZnJvbSB0YWtpbmcgb3ZlciEKR2lsZXM6IEknbSBub3Qgc3VyZSB0aGF0IGFueW9u
-       ZSBlbHNlIGNhbi4gQWxsIHRoZS4uLiB0aGUgc2lnbnMKICBpbmRpY2F0ZS4uLgpC
-       dWZmeTogVGhlIHNpZ25zPyBSRUFEIE1FIFRIRSBTSUdOUyEgVEVMTCBNRSBNWSBG
-       T1JUVU5FISBZT1UnUkUgU08KICBVU0VGVUwgU0lUVElORyBIRVJFIFdJVEggQUxM
-       IFlPVVIgQk9PS1MhIFlPVSdSRSBSRUFMTFkgQSBMT1RUQQogIEhFTFAhCkdpbGVz
-       OiBObywgSSBkb24ndCBzdXBwb3NlIEkgYW0uCkFuZ2VsOiBJIGtub3cgdGhpcyBp
-       cyBoYXJkLgpCdWZmeTogV2hhdCBkbyB5b3Uga25vdyBhYm91dCB0aGlzPyBZb3Un
-       cmUgbmV2ZXIgZ29ubmEgZGllIQpBbmdlbDogWW91IHRoaW5rIEkgd2FudCBhbnl0
-       aGluZyB0byBoYXBwZW4gdG8geW91PyBEbyB5b3UgdGhpbmsgSQogIGNvdWxkIHN0
-       YW5kIGl0PyBXZSBqdXN0IGdvdHRhIGZpZ3VyZSBvdXQgYSB3YXkuLi4KQnVmZnk6
-       IEkgYWxyZWFkeSBkaWQuIEkgcXVpdCwgcmVtZW1iZXI/IFBheSBhdHRlbnRpb24h
-       CkdpbGVzOiBCdWZmeSwgaWYgdGhlIE1hc3RlciByaXNlcy4uLgpCdWZmeTogSSBk
-       b24ndCBjYXJlISBJIGRvbid0IGNhcmUuIEdpbGVzLCBJJ20gc2l4dGVlbiB5ZWFy
-       cyBvbGQuIEkKICBkb24ndCB3YW5uYSBkaWUuCgktLSBQcm9waGVjeSBHaXJsCgkg
-       ICAoQnVmZnkgdGhlIFZhbXBpcmUgU2xheWVyLCBzZWFzb24gMSBlcGlzb2RlIDEy
-       KQo=
diff --git a/codec/hex.in b/codec/hex.in
deleted file mode 100644 (file)
index 4f7322f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-Angel: I saw you before you became the Slayer.
-Buffy: What?
-Angel: I watched you, and I saw you called. It was a bright
-  afternoon out in front of your school. You walked down the steps...
-  and...and I loved you.
-Buffy: Why?
-Angel: 'Cause I could see your heart. You held it before you for
-  everyone to see. And I worried that it would be bruised or torn.
-  And more than anything in my life I wanted to keep it safe... to
-  warm it with my own.
-Buffy: That's beautiful. Or taken literally, incredibly gross.
-Angel: I was just thinking that, too.
-       -- Helpless (Buffy the Vampire Slayer, season 3 episode 12)
diff --git a/codec/hex.ref b/codec/hex.ref
deleted file mode 100644 (file)
index 0176495..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-       416e67656c3a20492073617720796f75206265666f726520796f752062656361
-       6d652074686520536c617965722e0a42756666793a20576861743f0a416e6765
-       6c3a2049207761746368656420796f752c20616e6420492073617720796f7520
-       63616c6c65642e204974207761732061206272696768740a202061667465726e
-       6f6f6e206f757420696e2066726f6e74206f6620796f7572207363686f6f6c2e
-       20596f752077616c6b656420646f776e207468652073746570732e2e2e0a2020
-       616e642e2e2e616e642049206c6f76656420796f752e0a42756666793a205768
-       793f0a416e67656c3a20274361757365204920636f756c642073656520796f75
-       722068656172742e20596f752068656c64206974206265666f726520796f7520
-       666f720a202065766572796f6e6520746f207365652e20416e64204920776f72
-       72696564207468617420697420776f756c642062652062727569736564206f72
-       20746f726e2e0a2020416e64206d6f7265207468616e20616e797468696e6720
-       696e206d79206c69666520492077616e74656420746f206b6565702069742073
-       6166652e2e2e20746f0a20207761726d2069742077697468206d79206f776e2e
-       0a42756666793a205468617427732062656175746966756c2e204f722074616b
-       656e206c69746572616c6c792c20696e6372656469626c792067726f73732e0a
-       416e67656c3a204920776173206a757374207468696e6b696e6720746861742c
-       20746f6f2e0a092d2d2048656c706c6573732028427566667920746865205661
-       6d7069726520536c617965722c20736561736f6e203320657069736f64652031
-       32290a
diff --git a/codec/tests.at b/codec/tests.at
new file mode 100644 (file)
index 0000000..cf51618
--- /dev/null
@@ -0,0 +1,180 @@
+### -*-autotest-*-
+###
+### Test script for utilities
+###
+### (c) 2009 Straylight/Edgeware
+###
+
+###----- Licensing notice ---------------------------------------------------
+###
+### This file is part of the mLib utilities library.
+###
+### mLib is free software; you can redistribute it and/or modify
+### it under the terms of the GNU Library General Public License as
+### published by the Free Software Foundation; either version 2 of the
+### License, or (at your option) any later version.
+###
+### mLib 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 Library General Public License for more details.
+###
+### You should have received a copy of the GNU Library General Public
+### License along with mLib; if not, write to the Free
+### Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+### MA 02111-1307, USA.
+
+###--------------------------------------------------------------------------
+### Useful macros.
+
+m4_define([NEWLINE], [
+])
+
+## CODEC_TESTENCODE(codec, raw-data, encoding, [options])
+##
+## Check that CODEC encodes RAW-DATA as ENCODING, and that it can decode
+## ENCODING as RAW-DATA, using OPTIONS.
+m4_define([CODEC_TESTENCODE], [
+  printf '%s' '$2' >in
+  printf '%s\n' '$3' >expout
+  AT_CHECK([BUILDDIR/bincode $4 $1 in], [0], [expout])
+  mv in expout
+  printf '%s' '$3' >in
+  AT_CHECK([BUILDDIR/bincode -d $4 $1 in], [0], [expout])
+])
+
+## CODEC_TESTDECODE(codec, encoding, [raw-data],
+##                 [options], [exp-status], [exp-stderr])
+##
+## Check that CODEC decodes ENCODING as RAW-DATA, given the OPTIONS, or that
+## it reports EXP-STATUS and produces EXP-STDERR.
+m4_define([CODEC_TESTDECODE], [
+  printf '%s' '$2' >in
+  printf '%s' '$3' >expout
+  AT_CHECK([BUILDDIR/bincode -d $4 $1 in], [$5], [expout],
+          m4_if([$6], [], [], [bincode: decoding error: $6[]NEWLINE]))
+])
+
+###--------------------------------------------------------------------------
+### base64
+AT_SETUP([codec: base64])
+AT_KEYWORDS([codec base64])
+
+## Test vectors from RFC4648.
+CODEC_TESTENCODE([base64],     [],             [])
+CODEC_TESTENCODE([base64],     [f],            [Zg==])
+CODEC_TESTENCODE([base64],     [fo],           [Zm8=])
+CODEC_TESTENCODE([base64],     [foo],          [Zm9v])
+CODEC_TESTENCODE([base64],     [foob],         [Zm9vYg==])
+CODEC_TESTENCODE([base64],     [fooba],        [Zm9vYmE=])
+CODEC_TESTENCODE([base64],     [foobar],       [Zm9vYmFy])
+
+## Test vectors for Base64-URL.
+CODEC_TESTENCODE([base64url],  [fooba],        [Zm9vYmE=])
+CODEC_TESTENCODE([base64],     [fooba?],       [Zm9vYmE/])
+CODEC_TESTENCODE([base64url],  [fooba?],       [Zm9vYmE_])
+CODEC_TESTENCODE([file64],     [fooba?],       [Zm9vYmE%])
+CODEC_TESTENCODE([base64],     [fooba~],       [Zm9vYmF+])
+CODEC_TESTENCODE([base64url],  [fooba~],       [Zm9vYmF-])
+CODEC_TESTENCODE([file64],     [fooba~],       [Zm9vYmF+])
+
+## Some noeqpad tests.
+CODEC_TESTENCODE([base64],     [f],            [Zg],           [-fnoeqpad])
+CODEC_TESTENCODE([base64],     [foo],          [Zm9v],         [-fnoeqpad])
+CODEC_TESTENCODE([base64],     [foob],         [Zm9vYg],       [-fnoeqpad])
+
+## Test for pad-character errors.
+CODEC_TESTDECODE([base64],     [Zg],           [f],            [],
+                [1], [Invalid padding character])
+CODEC_TESTDECODE([base64],     [Zg],           [f],            [-figneqpad])
+CODEC_TESTDECODE([base64],     [Zg=],          [f],            [-figneqpad])
+CODEC_TESTDECODE([base64],     [Zg==],         [f],            [-figneqpad])
+CODEC_TESTDECODE([base64],     [Zg],           [f],            [-fnoeqpad])
+CODEC_TESTDECODE([base64],     [Zg=],          [],             [-fnoeqpad],
+                [1], [Invalid character])
+CODEC_TESTDECODE([base64],     [Zg],           [f],            [-figneqmid])
+CODEC_TESTDECODE([base64],     [Z==g=],        [f],            [-figneqmid])
+
+## Test for other crappy characters.
+CODEC_TESTDECODE([base64],     [Z:g=:=],       [],             [],
+                [1], [Invalid character])
+CODEC_TESTDECODE([base64],     [Z:g=:=],       [f],            [-figninvch])
+CODEC_TESTDECODE([base64],     [Z:g=:==],      [],             [-figninvch],
+                [1], [Invalid padding character])
+
+## Test for incorrect padding bits.
+CODEC_TESTDECODE([base64],     [Zh==],         [],             [],
+                [1], [Nonzero padding bits])
+CODEC_TESTDECODE([base64],     [Zh==],         [f],            [-fignzpad])
+
+## Make sure the case flags are suppressed.
+CODEC_TESTENCODE([base64],     [fooba],        [Zm9vYmE=],     [-flowerc])
+
+## Multiline formatting.
+AT_DATA([bigfile],
+[There are three infallible ways of pleasing an author, and the three form a
+rising scale of compliment: 1, to tell him you have read one of his books; 2,
+to tell him you have read all of his books; 3, to ask him to let you read the
+manuscript of his forthcoming book.  No. 1 admits you to his respect; No. 2
+admits you to his admiration; No. 3 carries you clear into his heart.
+                -- Mark Twain, "Pudd'nhead Wilson's Calendar"
+])
+
+AT_DATA([bigfile.b64],
+[VGhlcmUgYXJlIHRocmVlIGluZmFsbGlibGUgd2F5cyBvZiBwbGVhc2luZyBhbiBh
+dXRob3IsIGFuZCB0aGUgdGhyZWUgZm9ybSBhCnJpc2luZyBzY2FsZSBvZiBjb21w
+bGltZW50OiAxLCB0byB0ZWxsIGhpbSB5b3UgaGF2ZSByZWFkIG9uZSBvZiBoaXMg
+Ym9va3M7IDIsCnRvIHRlbGwgaGltIHlvdSBoYXZlIHJlYWQgYWxsIG9mIGhpcyBi
+b29rczsgMywgdG8gYXNrIGhpbSB0byBsZXQgeW91IHJlYWQgdGhlCm1hbnVzY3Jp
+cHQgb2YgaGlzIGZvcnRoY29taW5nIGJvb2suICBOby4gMSBhZG1pdHMgeW91IHRv
+IGhpcyByZXNwZWN0OyBOby4gMgphZG1pdHMgeW91IHRvIGhpcyBhZG1pcmF0aW9u
+OyBOby4gMyBjYXJyaWVzIHlvdSBjbGVhciBpbnRvIGhpcyBoZWFydC4KICAgICAg
+ICAgICAgICAgIC0tIE1hcmsgVHdhaW4sICJQdWRkJ25oZWFkIFdpbHNvbidzIENh
+bGVuZGFyIgo=
+])
+cp bigfile.b64 expout
+AT_CHECK([BUILDDIR/bincode base64 bigfile], [0], [expout])
+AT_CHECK([BUILDDIR/bincode -f-ignnewl -d base64 bigfile.b64], [1], [ignore],
+        [bincode: decoding error: Invalid character[]NEWLINE])
+cp bigfile expout
+AT_CHECK([BUILDDIR/bincode -d base64 bigfile.b64], [0], [expout])
+
+AT_CLEANUP
+
+## base32
+AT_SETUP([codec: base32])
+AT_KEYWORDS([codec base32])
+
+CODEC_TESTENCODE([base32],     [],             [])
+CODEC_TESTENCODE([base32],     [f],            [MY======])
+CODEC_TESTENCODE([base32],     [fo],           [MZXQ====])
+CODEC_TESTENCODE([base32],     [foo],          [MZXW6===])
+CODEC_TESTENCODE([base32],     [foob],         [MZXW6YQ=])
+CODEC_TESTENCODE([base32],     [fooba],        [MZXW6YTB])
+CODEC_TESTENCODE([base32],     [foobar],       [MZXW6YTBOI======])
+
+CODEC_TESTENCODE([base32hex],  [],             [])
+CODEC_TESTENCODE([base32hex],  [f],            [CO======])
+CODEC_TESTENCODE([base32hex],  [fo],           [CPNG====])
+CODEC_TESTENCODE([base32hex],  [foo],          [CPNMU===])
+CODEC_TESTENCODE([base32hex],  [foob],         [CPNMUOG=])
+CODEC_TESTENCODE([base32hex],  [fooba],        [CPNMUOJ1])
+CODEC_TESTENCODE([base32hex],  [foobar],       [CPNMUOJ1E8======])
+
+AT_CLEANUP
+
+## hex
+AT_SETUP([codec: hex])
+AT_KEYWORDS([codec hex])
+
+CODEC_TESTENCODE([hex],                [],             [])
+CODEC_TESTENCODE([hex],                [f],            [66])
+CODEC_TESTENCODE([hex],                [fo],           [666F])
+CODEC_TESTENCODE([hex],                [foo],          [666F6F])
+CODEC_TESTENCODE([hex],                [foob],         [666F6F62])
+CODEC_TESTENCODE([hex],                [fooba],        [666F6F6261])
+CODEC_TESTENCODE([hex],                [foobar],       [666F6F626172])
+
+AT_CLEANUP
+
+###----- That's all, folks --------------------------------------------------
index 107b49b36832ea368c4f701f7155f067582786b7..2444ac72677c0dccfd663c6c74289634bbc38aca 100644 (file)
@@ -39,6 +39,8 @@ AM_PROG_LIBTOOL
 AX_CFLAGS_WARN_ALL
 mdw_LIBTOOL_VERSION_INFO
 
+AC_CHECK_PROGS([AUTOM4TE], [autom4te])
+
 mdw_MANEXT
 
 AC_DEFINE_UNQUOTED([SRCDIR], ["$(cd $srcdir && pwd)"],
@@ -96,10 +98,16 @@ case $want_adns,$have_adns in
 esac
 AM_CONDITIONAL([WITH_ADNS], [test "$use_adns" = yes])
 
+dnl--------------------------------------------------------------------------
+dnl Python (used for testing).
+
+AM_PATH_PYTHON([2.4],, [:])
+
 dnl--------------------------------------------------------------------------
 dnl Output.
 
 AC_CONFIG_HEADER([config/config.h])
+AC_CONFIG_TESTDIR([t])
 
 AC_CONFIG_FILES(
   [Makefile]
@@ -113,7 +121,8 @@ AC_CONFIG_FILES(
   [test/Makefile]
   [trace/Makefile]
   [ui/Makefile]
-  [utils/Makefile])
+  [utils/Makefile]
+  [t/Makefile t/atlocal])
 AC_OUTPUT
 
 dnl ----- That's all, folks -------------------------------------------------
index 6c72744772df1d99421c4fd418b9667549f99b56..a8c83df6289742c90d7a25c06c8d0224af9735f7 100644 (file)
@@ -6,8 +6,9 @@ mlib (2.2.0~pre1) experimental; urgency=low
   * Overhaul of binary-to-text coding: now has better error handling, and
     a single unified engine.  Also provides a program, bincode(1), for
     exercising the system.
+  * Replace random ad-hoc testing by a system based on GNU Autotest.
 
- -- Mark Wooding <mdw@distorted.org.uk>  Sun, 03 May 2009 01:43:57 +0100
+ -- Mark Wooding <mdw@distorted.org.uk>  Sun, 03 May 2009 01:44:45 +0100
 
 mlib (2.1.1) experimental; urgency=low
 
index c6167a66c07bccde639a5dae8e4da8e0d4b5fdf4..4ab562c8cd3ebc210026bffdf7791763d61ddb4f 100644 (file)
@@ -56,6 +56,13 @@ $(precomp)/crc32-tab.c:
        mv $@.new $@
 endif
 
+check_PROGRAMS         += t/crc32.t
+t_crc32_t_SOURCES       = t/crc32-test.c
+t_crc32_t_CPPFLAGS      = $(TEST_CPPFLAGS)
+t_crc32_t_LDFLAGS       = -static
+
+EXTRA_DIST             += t/crc32.tests
+
 ## Universal hashing.
 pkginclude_HEADERS     += unihash.h
 noinst_LTLIBRARIES     += libunihash.la
@@ -79,18 +86,11 @@ $(precomp)/unihash-global.c:
                mv $@.new $@
 endif
 
-check_PROGRAMS         += unihash.t
-unihash_t_SOURCES       = unihash.c
-unihash_t_CPPFLAGS      = $(TEST_CPPFLAGS)
-unihash_t_LDFLAGS       = -static
-
-tests:: unihash.t unihash.in
-       ./unihash.t -f unihash.in
-
-EXTRA_DIST             += unihash-check.pl
-CLEANFILES             += unihash.in
-unihash.in: unihash-check.pl
-       perl $(srcdir)/unihash-check.pl >$@.new && mv $@.new $@
+check_PROGRAMS         += t/unihash.t
+t_unihash_t_SOURCES     = t/unihash-test.c
+t_unihash_t_CPPFLAGS    = $(TEST_CPPFLAGS)
+t_unihash_t_LDFLAGS     = -static
 
+EXTRA_DIST             += t/unihash-testgen.py
 
 ###----- That's all, folks --------------------------------------------------
diff --git a/hash/t/crc32-test.c b/hash/t/crc32-test.c
new file mode 100644 (file)
index 0000000..8e6d820
--- /dev/null
@@ -0,0 +1,91 @@
+/* -*-c-*-
+ *
+ * Test driver for CRC
+ *
+ * (c) 2009 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the mLib utilities library.
+ *
+ * mLib is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * mLib 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with mLib; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+
+#include "crc32.h"
+#include "testrig.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+static int verify(dstr *v)
+{
+  uint32 h, hh;
+  size_t n;
+  int i, c;
+  const char *p;
+  int ok = 1;
+
+  static const int step[] = { 0, 1, 5, 6, 7, 8, 23, -1 };
+
+  /* --- Set up for using this key --- */
+
+  h = *(uint32 *)v[1].buf;
+
+  /* --- Hash the data a lot --- */
+
+  for (i = 0; step[i] >= 0; i++) {
+    c = step[i];
+    if (!c)
+      hh = crc32(0, v[0].buf, v[0].len);
+    else {
+      hh = 0;
+      p = v[0].buf;
+      n = v[0].len;
+      while (n) {
+       if (c > n) c = n;
+       hh = crc32(hh, p, c);
+       p += c;
+       n -= c;
+      }
+    }
+    if (h != hh) {
+      ok = 0;
+      fprintf(stderr, "\ncrc32 failed\n");
+      fprintf(stderr, "         data = %s\n", v[0].buf);
+      fprintf(stderr, "         step = %d\n", step[i]);
+      fprintf(stderr, "         expected = %08lx\n", (unsigned long)h);
+      fprintf(stderr, "         computed = %08lx\n", (unsigned long)hh);
+    }
+  }
+  return (ok);
+}
+
+static const test_chunk tests[] = {
+  { "hash", verify, { &type_string, &type_uint32 } },
+  { 0, 0, { 0 } }
+};
+
+int main(int argc, char *argv[])
+{
+  test_run(argc, argv, tests, "crc32.in");
+  return (0);
+}
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/hash/t/crc32.tests b/hash/t/crc32.tests
new file mode 100644 (file)
index 0000000..9fb2baf
--- /dev/null
@@ -0,0 +1,11 @@
+### -*-conf-*-
+### crc32 tests
+
+hash {
+  ""                                                           0;
+  "foo"                                                                0x8c736521;
+  "anything you like"                                          0x2c090211;
+  "an exaple test string"                                      0x686a05aa;
+  "The quick brown fox jumps over the lazy dog."               0x519025e9;
+  "A man, a plan, a canal: Panama!"                            0x27f3faee;
+}
diff --git a/hash/t/unihash-test.c b/hash/t/unihash-test.c
new file mode 100644 (file)
index 0000000..3e56f10
--- /dev/null
@@ -0,0 +1,96 @@
+/* -*-c-*-
+ *
+ * Test driver for universal hashing
+ *
+ * (c) 2009 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the mLib utilities library.
+ *
+ * mLib is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * mLib 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with mLib; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+
+#include "unihash.h"
+#include "testrig.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+static int verify(dstr *v)
+{
+  unihash_info ui;
+  uint32 k;
+  uint32 h, hh;
+  size_t n;
+  int i, c;
+  const char *p;
+  int ok = 1;
+
+  static const int step[] = { 0, 1, 5, 6, 7, 8, 23, -1 };
+
+  /* --- Set up for using this key --- */
+
+  k = *(uint32 *)v[0].buf;
+  h = *(uint32 *)v[2].buf;
+  unihash_setkey(&ui, k);
+
+  /* --- Hash the data a lot --- */
+
+  for (i = 0; step[i] >= 0; i++) {
+    c = step[i];
+    if (!c)
+      hh = unihash(&ui, v[1].buf, v[1].len);
+    else {
+      hh = UNIHASH_INIT(&ui);
+      p = v[1].buf;
+      n = v[1].len;
+      while (n) {
+       if (c > n) c = n;
+       hh = unihash_hash(&ui, hh, p, c);
+       p += c;
+       n -= c;
+      }
+    }
+    if (h != hh) {
+      ok = 0;
+      fprintf(stderr, "\nunihash failed\n");
+      fprintf(stderr, "         key = %08lx\n", (unsigned long)k);
+      fprintf(stderr, "         data = %s\n", v[1].buf);
+      fprintf(stderr, "         step = %d\n", step[i]);
+      fprintf(stderr, "         expected = %08lx\n", (unsigned long)h);
+      fprintf(stderr, "         computed = %08lx\n", (unsigned long)hh);
+    }
+  }
+  return (ok);
+}
+
+static const test_chunk tests[] = {
+  { "hash", verify, { &type_uint32, &type_string, &type_uint32 } },
+  { 0, 0, { 0 } }
+};
+
+int main(int argc, char *argv[])
+{
+  test_run(argc, argv, tests, "unihash.in");
+  return (0);
+}
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/hash/t/unihash-testgen.py b/hash/t/unihash-testgen.py
new file mode 100644 (file)
index 0000000..2fe8982
--- /dev/null
@@ -0,0 +1,39 @@
+#! /usr/bin/python
+### -*-python-*-
+###
+### Generate test vectors for universal hashing.
+
+MOD = 0x104c11db7
+
+def gfmul(x, y):
+  a = 0
+  while y > 0:
+    if y & 1: a ^= x
+    if x & 0x80000000: x = (x << 1) ^ MOD
+    else: x <<= 1
+    y >>= 1
+  return a
+
+def hashtest(k, m):
+  h = k
+  for ch in m: h = gfmul(h ^ ord(ch), k)
+  print '  0x%08x "%s" 0x%08x;' % (k, m, h)
+
+print '''\
+### Test vectors for universal hashing
+###   [generated]
+
+hash {'''
+
+for k, m in [(0x00000000, 'anything you like'),
+             (0x12345678, 'an exaple test string'),
+             (0xb8a171f0, 'The quick brown fox jumps over the lazy dog.'),
+             (0x2940521b, 'A man, a plan, a canal: Panama!')]:
+  hashtest(k, m)
+
+k, m = 0x94b22a73, 0xbb7b1fef
+for i in xrange(48):
+  hashtest(k, "If we don't succeed, we run the risk of failure.")
+  k = gfmul(k, m)
+
+print '}'
diff --git a/hash/tests.at b/hash/tests.at
new file mode 100644 (file)
index 0000000..65456d8
--- /dev/null
@@ -0,0 +1,49 @@
+### -*-autotest-*-
+###
+### Test script for hashing
+###
+### (c) 2009 Straylight/Edgeware
+###
+
+###----- Licensing notice ---------------------------------------------------
+###
+### This file is part of the mLib utilities library.
+###
+### mLib is free software; you can redistribute it and/or modify
+### it under the terms of the GNU Library General Public License as
+### published by the Free Software Foundation; either version 2 of the
+### License, or (at your option) any later version.
+###
+### mLib 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 Library General Public License for more details.
+###
+### You should have received a copy of the GNU Library General Public
+### License along with mLib; if not, write to the Free
+### Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+### MA 02111-1307, USA.
+
+###--------------------------------------------------------------------------
+### Tests.
+
+## crc32
+AT_SETUP([hash: crc32])
+AT_KEYWORDS([hash crc32])
+
+AT_CHECK([BUILDDIR/t/crc32.t -f SRCDIR/t/crc32.tests],
+        [0], [ignore], [ignore])
+
+AT_CLEANUP
+
+## unihash
+AT_SETUP([hash: unihash])
+AT_KEYWORDS([hash unihash])
+
+$PYTHON SRCDIR/t/unihash-testgen.py >unihash.tests
+AT_CHECK([BUILDDIR/t/unihash.t -f unihash.tests],
+        [0], [ignore], [ignore])
+
+AT_CLEANUP
+
+###----- That's all, folks --------------------------------------------------
diff --git a/hash/unihash-check.pl b/hash/unihash-check.pl
deleted file mode 100644 (file)
index f7041f8..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#! /usr/bin/perl
-
-my $MOD = 0x04c11db7;
-
-sub gfmul {
-  my ($x, $y) = @_;
-  my $a = 0;
-
-  while ($y) {
-    if ($y & 1) { $a ^= $x };
-    if ($x & 0x80000000) { $x <<= 1; $x &= 0xffffffff; $x ^= $MOD; }
-    else { $x <<= 1; }
-    $y >>= 1;
-  }
-  return $a;
-}
-
-sub hash {
-  my ($k, $msg) = @_;
-  my $h = $k;
-  for (my $i = 0; $i < length $msg; $i++) {
-    my $m = ord(substr($msg, $i, 1));
-    $h = gfmul($h ^ $m, $k);
-  }
-  printf "  0x%08x \"%s\" 0x%08x;\n", $k, $msg, $h;
-}
-
-print <<EOF;
-# test vectors for unihash
-
-hash {
-EOF
-hash(0x00000000, "anything you like");
-hash(0x12345678, "an exaple test string");
-hash(0xb8a171f0, "The quick brown fox jumps over the lazy dog.");
-hash(0x2940521b, "A man, a plan, a canal: Panama!");
-
-my $k = 0x94b22a73;
-my $m = 0xbb7b1fef;
-for (my $i = 0; $i < 48; $i++) {
-  hash($k, "If we don't succeed, we run the risk of failure.");
-  $k = gfmul($k, $m);
-}
-
-print <<EOF;
-}
-EOF
index 2997e4fac50ec9f1364d1a4de852d0c2834c3806..a6f9ae2a51c0247a5e68c14c82b39b693425b537 100644 (file)
@@ -143,75 +143,6 @@ uint32 unihash_hash(const unihash_info *i, uint32 a,
  */
 
 uint32 unihash(const unihash_info *i, const void *p, size_t sz)
-{
-  return (UNIHASH(i, p, sz));
-}
-
-/*----- Test rig ----------------------------------------------------------*/
-
-#ifdef TEST_RIG
-
-#include "testrig.h"
-
-static int verify(dstr *v)
-{
-  unihash_info ui;
-  uint32 k;
-  uint32 h, hh;
-  size_t n;
-  int i, c;
-  const char *p;
-  int ok = 1;
-
-  static const int step[] = { 0, 1, 5, 6, 7, 8, 23, -1 };
-
-  /* --- Set up for using this key --- */
-
-  k = *(uint32 *)v[0].buf;
-  h = *(uint32 *)v[2].buf;
-  unihash_setkey(&ui, k);
-
-  /* --- Hash the data a lot --- */
-
-  for (i = 0; step[i] >= 0; i++) {
-    c = step[i];
-    if (!c)
-      hh = unihash(&ui, v[1].buf, v[1].len);
-    else {
-      hh = UNIHASH_INIT(&ui);
-      p = v[1].buf;
-      n = v[1].len;
-      while (n) {
-       if (c > n) c = n;
-       hh = unihash_hash(&ui, hh, p, c);
-       p += c;
-       n -= c;
-      }
-    }
-    if (h != hh) {
-      ok = 0;
-      fprintf(stderr, "\nunihash failed\n");
-      fprintf(stderr, "         key = %08lx\n", (unsigned long)k);
-      fprintf(stderr, "         data = %s\n", v[1].buf);
-      fprintf(stderr, "         step = %d\n", step[i]);
-      fprintf(stderr, "         expected = %08lx\n", (unsigned long)h);
-      fprintf(stderr, "         computed = %08lx\n", (unsigned long)hh);
-    }
-  }
-  return (ok);
-}
-
-static const test_chunk tests[] = {
-  { "hash", verify, { &type_uint32, &type_string, &type_uint32 } },
-  { 0, 0, { 0 } }
-};
-
-int main(int argc, char *argv[])
-{
-  test_run(argc, argv, tests, "unihash.in");
-  return (0);
-}
-
-#endif
+  { return (UNIHASH(i, p, sz)); }
 
 /*----- That's all, folks -------------------------------------------------*/
index 280e52d171c38c1a6a1f71221dab251edb0ae0f3..a718c09e73506d03e4f9c709b3282539ad0391a0 100644 (file)
@@ -47,26 +47,12 @@ pkginclude_HEADERS  += darray.h
 libstruct_la_SOURCES   += darray.c
 LIBMANS                        += darray.3
 
-CLEANFILES             += da.out
-tests:: darray.t da.in da.ref
-       ./darray.t <da.in >da.out
-       cmp da.out da.ref
-       @echo "darray OK"
-
-check_PROGRAMS         += darray.t
-darray_t_SOURCES        = da-test.c
-darray_t_CPPFLAGS       = $(TEST_CPPFLAGS)
-darray_t_LDFLAGS        = -static
-
-EXTRA_DIST             += da-gtest
-CLEANFILES             += da.in
-da.in: da-gtest
-       perl $(srcdir)/da-gtest 10000 >$@.new && mv $@.new $@
-
-EXTRA_DIST             += da-ref
-CLEANFILES             += da.ref
-da.ref: da-ref da.in
-       perl $(srcdir)/da-ref <da.in >$@.new && mv $@.new $@
+check_PROGRAMS         += t/darray.t
+t_darray_t_SOURCES      = t/da-test.c
+t_darray_t_CPPFLAGS     = $(TEST_CPPFLAGS)
+t_darray_t_LDFLAGS      = -static
+
+EXTRA_DIST             += t/da-gtest.py
 
 ## Hash tables.
 pkginclude_HEADERS     += hash.h
@@ -78,26 +64,12 @@ pkginclude_HEADERS  += sym.h
 libstruct_la_SOURCES   += sym.c
 LIBMANS                        += sym.3
 
-CLEANFILES             += sym.out
-tests:: sym.t sym.in sym.ref
-       ./sym.t <sym.in >sym.out
-       cmp sym.out sym.ref
-       @echo "sym OK"
-
-check_PROGRAMS         += sym.t
-sym_t_SOURCES           = sym-test.c
-sym_t_CPPFLAGS          = $(TEST_CPPFLAGS)
-sym_t_LDFLAGS           = -static
+check_PROGRAMS         += t/sym.t
+t_sym_t_SOURCES                 = t/sym-test.c
+t_sym_t_CPPFLAGS        = $(TEST_CPPFLAGS)
+t_sym_t_LDFLAGS                 = -static
 
-EXTRA_DIST             += sym-gtest
-CLEANFILES             += sym.in
-sym.in: sym-gtest
-       perl $(srcdir)/sym-gtest 10000 >$@.new && mv $@.new $@
-
-EXTRA_DIST             += sym-ref
-CLEANFILES             += sym.ref
-sym.ref: sym-ref sym.in
-       perl $(srcdir)/sym-ref <sym.in >$@.new && mv $@.new $@
+EXTRA_DIST             += t/sym-gtest.py
 
 ## Atoms.
 pkginclude_HEADERS     += atom.h
@@ -109,15 +81,9 @@ pkginclude_HEADERS  += assoc.h
 libstruct_la_SOURCES   += assoc.c
 LIBMANS                        += assoc.3
 
-CLEANFILES             += assoc.out
-tests:: assoc.t sym.in sym.ref
-       ./assoc.t <sym.in >assoc.out
-       cmp assoc.out sym.ref
-       @echo "sym OK"
-
-check_PROGRAMS         += assoc.t
-assoc_t_SOURCES                 = assoc-test.c
-assoc_t_CPPFLAGS        = $(TEST_CPPFLAGS)
-assoc_t_LDFLAGS                 = -static
+check_PROGRAMS         += t/assoc.t
+t_assoc_t_SOURCES       = t/assoc-test.c
+t_assoc_t_CPPFLAGS      = $(TEST_CPPFLAGS)
+t_assoc_t_LDFLAGS       = -static
 
 ###----- That's all, folks --------------------------------------------------
diff --git a/struct/da-gtest b/struct/da-gtest
deleted file mode 100755 (executable)
index 0348833..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#! /usr/bin/perl
-#
-# Generate a random test file for dynamic array testing.
-#
-# Syntax reference:
-#
-#   push n, pop, shift, unshift n -- normal stack ops (pop and shift print)
-#   insert x y z ... -- insert items at beginning
-#   append x y z ... -- append items at end
-#   delete n -- remove n items from beginning
-#   reduce n -- remove n items from end
-#   set i n -- assign item at index i to be n
-#   get i -- display item at index i
-#   first, last -- show first or last item
-#   show -- write entire array to stdout, space separated on one line
-
-sub random ($) {
-  my $lim = shift;
-  return int(rand($lim));
-}
-
-$lines = shift || 100;
-$max = 0; # Estimate of size of array
-$serial = 1;
-while ($lines) {
-  $what = random(21);
-  if ($what < 8) {
-    my $op = (qw(push pop shift unshift))[$what % 4];
-    if ($op eq "push" || $op eq "unshift") {
-      my $n = $serial++;
-      $max++;
-      print "$op $n\n";
-    } elsif ($max > 0) {
-      $max--;
-      print "$op\n";
-    }
-  } elsif ($what < 10) {
-    my @n = ($serial++);
-    my $op = (qw(insert append))[$what % 2];
-    push(@n, $serial++) while random(4) < 3;
-    print "$op ", join(" ", @n), "\n";
-    $max += @n;
-  } elsif ($what < 12) {
-    if ($max < 10000) { next; }
-    my $n = 1;
-    my $op = (qw(delete reduce))[$what % 2];
-    $n++ while random(4) < 3;
-    print "$op $n\n";
-    $max -= $n;
-    if ($max < 0) {
-      $max = 0;
-    }
-  } elsif ($what < 16) {
-    my $i = random($max);
-    $i++ while random(4) < 2;
-    if ($what % 2 == 0) {
-      my $n = $serial++;
-      print "set $i $n\n";
-      if ($i >= $max) {
-       $max = $i + 1;
-      }
-    } else {
-      print "get $i\n";
-    }
-  } elsif ($what < 20) {
-    my $op = (qw(first last))[$what % 2];
-    print "$op\n" if $max;
-  } elsif (random(10) == 0) {
-    print "show\n";
-  } else { next; }
-  $lines--;
-}
-
-print "show\n";
diff --git a/struct/da-ref b/struct/da-ref
deleted file mode 100755 (executable)
index aed94a4..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#! /usr/bin/perl
-#
-# Reference implementation for dynamic array testing.
-
-@a = ();
-while (<>) {
-  chomp();
-  # print "$_\n";
-  @F = split();
-  if ($F[0] eq "push") {
-    push(@a, $F[1]);
-  } elsif ($F[0] eq "unshift") {
-    unshift(@a, $F[1]);
-  } elsif ($F[0] eq "pop") {
-    if (@a == 0) {
-      print "*UFLOW*\n";
-    } else {
-      my $n = int(pop(@a));
-      print "$n\n";
-    }
-  } elsif ($F[0] eq "shift") {
-    if (@a == 0) {
-      print "*UFLOW*\n";
-    } else {
-      my $n = int(shift(@a));
-      print "$n\n";
-    }
-  } elsif ($F[0] eq "insert") {
-    shift(@F);
-    unshift(@a, @F);
-  } elsif ($F[0] eq "append") {
-    shift(@F);
-    push(@a, @F);
-  } elsif ($F[0] eq "delete") {
-    if ($F[1] > @a) {
-      # @a = ();
-      print "*UFLOW*\n";
-    } else {
-      splice(@a, 0, $F[1]);
-    }
-  } elsif ($F[0] eq "reduce") {
-    if ($F[1] > @a) {
-      # @a = ();
-      print "*UFLOW*\n";
-    } else {
-      $#a -= $F[1];
-    }
-  } elsif ($F[0] eq "set") {
-    if ($F[1] > @a) {
-      for (my $i = @a; $i < $F[1]; $i++) { $a[$i] = -1; }
-    }
-    $a[$F[1]] = int($F[2]);
-  } elsif ($F[0] eq "get") {
-    if ($F[1] >= @a) {
-      print "*RANGE*\n";
-    } else {
-      print int($a[$F[1]]), "\n";
-    }
-  } elsif ($F[0] eq "first") {
-    print int($a[0]), "\n";
-  } elsif ($F[0] eq "last") {
-    print int($a[$#a]), "\n";
-  } elsif ($F[0] eq "show") {
-    if (@a) {
-      print join(" ", map int, @a), "\n";
-    } else {
-      print "*EMPTY*\n";
-    }
-  } else {
-    print "*BAD*\n";
-  }
-}
diff --git a/struct/sym-gtest b/struct/sym-gtest
deleted file mode 100755 (executable)
index ac5bcaf..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#! /usr/bin/perl
-#
-# Generate a random test file for symbol table testing.
-#
-# Syntax reference:
-#
-#  set k v -- assign (textual) key k the (integer) value i
-#  get k -- display value at key k
-#  del k -- remove key k
-#  count -- show number of items
-#  show -- dump out the entire table, in alphabetical key order
-
-sub random ($) {
-  my $lim = shift;
-  return int(rand($lim));
-}
-
-$words = "/usr/dict/words";
--r $words or $words = "/usr/share/dict/words";
-open(DICT, $words) or die("open($words): $!");
-@w = grep /./, <DICT>;
-chomp(@w);
-close(DICT);
-
-%a = ();
-
-$lines = shift || 100;
-$serial = 1;
-while ($lines) {
-  $what = random(4);
-  if ($what == 0) {
-    my $k = $w[random(@w)];
-    my $i = $serial++;
-    print "set $k $i\n";
-    $a{$k} = $i;
-  } elsif ($what == 1) {
-    my $k = $w[random(@w)];
-    if (!exists($a{$w}) && random(8) != 0) { next; }
-    print "get $k\n";
-  } elsif ($what == 2) {
-    my $k = $w[random(@w)];
-    if (!exists($a{$w}) && random(8) != 0) { next; }
-    print "del $k\n";
-    delete($w{$k});
-  } elsif (random(5) == 0) {
-    print "count\n";
-  } else { next; }
-  $lines--;
-}
-
-print "show\n";
diff --git a/struct/sym-ref b/struct/sym-ref
deleted file mode 100755 (executable)
index c0a4622..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#! /usr/bin/perl
-#
-# Reference implementation for symbol table testing.
-
-%a = ();
-while (<>) {
-  chomp();
-  @F = split();
-  if ($F[0] eq "set") {
-    $a{$F[1]} = $F[2];
-  } elsif ($F[0] eq "get") {
-    if (exists($a{$F[1]})) {
-      print "$a{$F[1]}\n";
-    } else {
-      print "*MISSING*\n";
-    }
-  } elsif ($F[0] eq "del") {
-    if (exists($a{$F[1]})) {
-      delete($a{$F[1]});
-    } else {
-      print "*MISSING*\n";
-    }
-  } elsif ($F[0] eq "count") {
-    print int(keys(%a)), "\n";
-  } elsif ($F[0] eq "show") {
-    if (!%a) {
-      print "*EMPTY*\n";
-    } else {
-      my $s = "";
-      foreach $k (sort(keys(%a))) {
-       print "$s$k:$a{$k}";
-       $s = " ";
-      }
-      print "\n";
-    }
-  } else {
-    print "*BAD*\n";
-  }
-}
-
similarity index 86%
rename from struct/assoc-test.c
rename to struct/t/assoc-test.c
index 59498577b6ab33565554fe41498026ea7691f443..05a05d96199c9d5e51b06dc59e7fdbe35d78cd3b 100644 (file)
@@ -1,3 +1,4 @@
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -23,14 +24,14 @@ int main(void)
   char *p;
   atom_table at;
   assoc_table t;
-  size_t n = 0;
+  size_t n = 0, j;
 
   atom_createtable(&at);
   assoc_create(&t);
 
   while (fgets(buf, sizeof(buf), stdin)) {
+/*     printf("+++ %s", buf); */
     buf[strlen(buf) - 1] = 0;
-/*     printf("# %s\n", buf); */
     p = strtok(buf, " ");
 
     if (strcmp(p, "set") == 0) {
@@ -71,17 +72,23 @@ int main(void)
          puts("*NOMEM*");
          continue;
        }
-       for (vv = v, assoc_mkiter(&i, &t); (w = assoc_next(&i)) != 0; vv++)
+       for (vv = v, assoc_mkiter(&i, &t), j = 0;
+            (w = assoc_next(&i)) != 0;
+            vv++, j++) {
+         assert(j < n);
          *vv = w;
+       }
+       assert(j == n);
        qsort(v, n, sizeof(*v), cmp);
        printf("%s:%i", ATOM_NAME(ASSOC_ATOM(*v)), (*v)->i);
-       for (vv = v + 1; --n; vv++)
+       for (vv = v + 1; --j; vv++)
          printf(" %s:%i", ATOM_NAME(ASSOC_ATOM(*vv)), (*vv)->i);
        free(v);
        putchar('\n');
       }
     } else
       puts("*BAD*");
+/*     printf("--- %d\n", n); */
   }
 
   assoc_destroy(&t);
diff --git a/struct/t/da-gtest.py b/struct/t/da-gtest.py
new file mode 100644 (file)
index 0000000..14bc0cc
--- /dev/null
@@ -0,0 +1,180 @@
+#! /usr/bin/python
+### -*-python-*-
+###
+### Generate input script and expected output for dynamic array testing.
+
+import sys as SYS
+import random as R
+
+###--------------------------------------------------------------------------
+### Command-line parsing.
+
+SYS.argv[0:1] = []
+def arg(default = None):
+  if len(SYS.argv):
+    r = SYS.argv[0]
+    SYS.argv[0:1] = []
+    return r
+  else:
+    return default
+
+R.seed(None)
+SEED = int(arg(str(R.randrange(0, 1 << 32))), 0)
+R.seed(SEED)
+
+LINES = int(arg(1000))
+
+###--------------------------------------------------------------------------
+### Initialization.
+
+SERIAL = 1
+ARRAY = []
+
+SCRIPT = open('da.script', 'w')
+WIN = open('expout', 'w')
+
+###--------------------------------------------------------------------------
+### Utility functions.
+
+OPS = []
+def op(weight):
+  """
+  Operation decorator.  Add the following function to the operations table,
+  with the given probability WEIGHT.  This works as follows: if TOTAL is the
+  total of all the WEIGHTs, then this operation has a probability of
+  WEIGHT/TOTAL of being selected.
+  """
+  def _(cls):
+    OPS.append((weight, cls))
+    return cls
+  return _
+
+def serial():
+  """Return the next number in a simple sequence."""
+  global SERIAL
+  SERIAL += 1
+  return SERIAL - 1
+
+def mkseq():
+  """Return a short list of stuff to be added to the array."""
+  seq = [serial()]
+  while R.randrange(0, 4) < 3: seq.append(serial())
+  return seq
+
+def mkseqlen():
+  """Return a length of stuff to be removed from the array."""
+  n = 1
+  while R.randrange(0, 4) < 3: n += 1
+  return n
+
+###--------------------------------------------------------------------------
+### The actual operations.
+
+@op(20)
+def op_push():
+  n = serial()
+  SCRIPT.write('push %d\n' % n)
+  ARRAY.append(n)
+@op(20)
+def op_pop():
+  SCRIPT.write('pop\n')
+  if not ARRAY:
+    WIN.write('*UFLOW*\n')
+  else:
+    n, = ARRAY[-1:]
+    ARRAY[-1:] = []
+    WIN.write('%d\n' % n)
+@op(20)
+def op_unshift():
+  n = serial()
+  SCRIPT.write('unshift %d\n' % n)
+  ARRAY[0:0] = [n]
+@op(20)
+def op_shift():
+  SCRIPT.write('shift\n')
+  if not ARRAY:
+    WIN.write('*UFLOW*\n')
+  else:
+    n = ARRAY[0]
+    ARRAY[0:1] = []
+    WIN.write('%d\n' % n)
+
+@op(10)
+def op_insert():
+  stuff = mkseq()
+  SCRIPT.write('insert ' + ' '.join(['%d' % i for i in stuff]) + '\n')
+  ARRAY[0:0] = stuff
+@op(10)
+def op_append():
+  global ARRAY                          # += is a binding occurrence
+  stuff = mkseq()
+  SCRIPT.write('append ' + ' '.join(['%d' % i for i in stuff]) + '\n')
+  ARRAY += stuff
+
+@op(20)
+def op_delete():
+  if len(ARRAY) < LINES/10: return
+  n = mkseqlen()
+  SCRIPT.write('delete %d\n' % n)
+  if n > len(ARRAY): WIN.write('*UFLOW*\n')
+  else: ARRAY[0:n] = []
+@op(20)
+def op_reduce():
+  if len(ARRAY) < LINES/10: return
+  n = mkseqlen()
+  SCRIPT.write('reduce %d\n' % n)
+  if n > len(ARRAY): WIN.write('*UFLOW*\n')
+  else: ARRAY[-n:] = []
+
+def mkindex():
+  if not ARRAY: ix = 0
+  else: ix = R.randrange(0, len(ARRAY))
+  while R.randrange(0, 2) < 1: ix += 1
+  return ix
+
+@op(20)
+def op_set():
+  global ARRAY                          # += is a binding occurrence
+  ix, x = mkindex(), serial()
+  SCRIPT.write('set %d %d\n' % (ix, x))
+  if ix >= len(ARRAY): ARRAY += [-1] * (ix - len(ARRAY) + 1)
+  ARRAY[ix] = x
+@op(20)
+def op_get():
+  ix = mkindex()
+  SCRIPT.write('get %d\n' % ix)
+  if ix >= len(ARRAY): WIN.write('*RANGE*\n')
+  else: WIN.write('%d\n' % ARRAY[ix])
+
+@op(10)
+def op_first():
+  SCRIPT.write('first\n')
+  if len(ARRAY): WIN.write('%d\n' % ARRAY[0])
+  else: WIN.write('*RANGE*\n')
+@op(10)
+def op_last():
+  SCRIPT.write('last\n')
+  if len(ARRAY): WIN.write('%d\n' % ARRAY[-1])
+  else: WIN.write('*RANGE*\n')
+
+@op(1)
+def op_show():
+  SCRIPT.write('show\n')
+  if not ARRAY: WIN.write('*EMPTY*\n')
+  else: WIN.write(' '.join(['%d' % i for i in ARRAY]) + '\n')
+
+###--------------------------------------------------------------------------
+### Generate the output.
+
+OPTAB = []
+for p, func in OPS:
+  OPTAB += [func] * p
+for i in xrange(LINES):
+  OPTAB[R.randrange(0, len(OPTAB))]()
+op_show()
+
+SCRIPT.close()
+WIN.close()
+open('da.seed', 'w').write('da-gtest seed = %08x\n' % SEED)
+
+###----- That's all, folks --------------------------------------------------
similarity index 95%
rename from struct/da-test.c
rename to struct/t/da-test.c
index 38b6055c52e8510b535a779c53f1b47d00825e88..0f3e6253c071d823397de7516da3265916eef334 100644 (file)
@@ -104,9 +104,15 @@ int main(void)
        else
          printf("%i\n", DA(&v)[i]);
       } else if (strcmp(p, "first") == 0) {
-       printf("%i\n", DA_FIRST(&v));
+       if (DA_LEN(&v))
+         printf("%i\n", DA_FIRST(&v));
+       else
+         puts("*RANGE*");
       } else if (strcmp(p, "last") == 0) {
-       printf("%i\n", DA_LAST(&v));
+       if (DA_LEN(&v))
+         printf("%i\n", DA_LAST(&v));
+       else
+         puts("*RANGE*");
       } else if (strcmp(p, "show") == 0) {
        if (DA_LEN(&v) == 0)
          puts("*EMPTY*");
diff --git a/struct/t/sym-gtest.py b/struct/t/sym-gtest.py
new file mode 100644 (file)
index 0000000..ea69034
--- /dev/null
@@ -0,0 +1,137 @@
+#! /usr/bin/python
+### -*-python-*-
+###
+### Generate input script and expected output for hash tables.
+
+import sys as SYS
+import random as R
+
+###--------------------------------------------------------------------------
+### Command-line parsing.
+
+SYS.argv[0:1] = []
+def arg(default = None):
+  if len(SYS.argv):
+    r = SYS.argv[0]
+    SYS.argv[0:1] = []
+    return r
+  else:
+    return default
+
+R.seed(None)
+SEED = int(arg(str(R.randrange(0, 1 << 32))), 0)
+R.seed(SEED)
+
+LINES = int(arg(1000))
+
+###--------------------------------------------------------------------------
+### Word list.
+
+def word():
+  def char(): return 'abcdefghijklmnopqrstuvwxyz'[R.randrange(0, 26)]
+  word = char() + char() + char()
+  while R.randrange(0, 6) != 0: word += char()
+  return word
+
+## for i in ['/usr/share/dict/words', '/usr/dict/words']:
+##   try:
+##     WORDS = [line[:-1] for line in open(i)]
+##     raise Exception
+##   except:
+##     pass
+##   else:
+##     def word():
+##       return WORDS[R.randrange(0, len(WORDS))]
+##     break
+
+###--------------------------------------------------------------------------
+### Initialization.
+
+SERIAL = 1
+MAP = {}
+
+SCRIPT = open('sym.script', 'w')
+WIN = open('expout', 'w')
+
+###--------------------------------------------------------------------------
+### Utility functions.
+
+OPS = []
+def op(weight):
+  """
+  Operation decorator.  Add the following function to the operations table,
+  with the given probability WEIGHT.  This works as follows: if TOTAL is the
+  total of all the WEIGHTs, then this operation has a probability of
+  WEIGHT/TOTAL of being selected.
+  """
+  def _(cls):
+    OPS.append((weight, cls))
+    return cls
+  return _
+
+def serial():
+  """Return the next number in a simple sequence."""
+  global SERIAL
+  SERIAL += 1
+  return SERIAL - 1
+
+###--------------------------------------------------------------------------
+### The actual operations.
+
+@op(10)
+def op_set():
+  w = word()
+  n = serial()
+  SCRIPT.write('set %s %d\n' % (w, n))
+  MAP[w] = n
+
+@op(10)
+def op_get():
+  w = word()
+  try:
+    WIN.write('%d\n' % MAP[w])
+  except KeyError:
+    if R.randrange(8): return
+    WIN.write('*MISSING*\n')
+  SCRIPT.write('get %s\n' % (w))
+
+@op(10)
+def op_del():
+  w = word()
+  try:
+    del MAP[w]
+  except KeyError:
+    if R.randrange(8): return
+    WIN.write('*MISSING*\n')
+  SCRIPT.write('del %s\n' % (w))
+
+@op(4)
+def op_count():
+  SCRIPT.write('count\n')
+  WIN.write('%d\n' % len(MAP))
+
+@op(1)
+def op_show():
+  SCRIPT.write('show\n')
+  if not MAP:
+    WIN.write('*EMPTY*\n')
+  else:
+    kk = MAP.keys()
+    kk.sort()
+    WIN.write(' '.join(['%s:%d' % (k, MAP[k]) for k in kk]) + '\n')
+
+###--------------------------------------------------------------------------
+### Generate the output.
+
+OPTAB = []
+for p, func in OPS:
+  OPTAB += [func] * p
+for i in xrange(LINES):
+  OPTAB[R.randrange(0, len(OPTAB))]()
+op_show()
+
+SCRIPT.close()
+WIN.close()
+open('sym.seed', 'w').write('sym-gtest seed = %08x\n' % SEED)
+
+###----- That's all, folks --------------------------------------------------
similarity index 85%
rename from struct/sym-test.c
rename to struct/t/sym-test.c
index 18e984167d6d1329b5e4ac4bafbb48104d6c6b6e..264d6a957f25e73db6eaac27a8a2eb3b4343f137 100644 (file)
@@ -1,3 +1,4 @@
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -21,13 +22,13 @@ int main(void)
   char buf[256];
   char *p;
   sym_table t;
-  size_t n = 0;
+  size_t n = 0, j;
 
   sym_create(&t);
 
   while (fgets(buf, sizeof(buf), stdin)) {
+/*     printf("+++ %s", buf); */
     buf[strlen(buf) - 1] = 0;
-/*     printf("# %s\n", buf); */
     p = strtok(buf, " ");
 
     if (strcmp(p, "set") == 0) {
@@ -68,17 +69,23 @@ int main(void)
          puts("*NOMEM*");
          continue;
        }
-       for (vv = v, sym_mkiter(&i, &t); (w = sym_next(&i)) != 0; vv++)
+       for (vv = v, sym_mkiter(&i, &t), j = 0;
+            (w = sym_next(&i)) != 0;
+            vv++, j++) {
+         assert(j < n);
          *vv = w;
+       }
+       assert(j == n);
        qsort(v, n, sizeof(*v), cmp);
        printf("%s:%i", SYM_NAME(*v), (*v)->i);
-       for (vv = v + 1; --n; vv++)
+       for (vv = v + 1; --j; vv++)
          printf(" %s:%i", SYM_NAME(*vv), (*vv)->i);
        free(v);
        putchar('\n');
       }
     } else
       puts("*BAD*");
+/*     printf("--- %d\n", n); */
   }
 
   sym_destroy(&t);
diff --git a/struct/tests.at b/struct/tests.at
new file mode 100644 (file)
index 0000000..3ae7199
--- /dev/null
@@ -0,0 +1,57 @@
+### -*-autotest-*-
+###
+### Test script for data structures
+###
+### (c) 2009 Straylight/Edgeware
+###
+
+###----- Licensing notice ---------------------------------------------------
+###
+### This file is part of the mLib utilities library.
+###
+### mLib is free software; you can redistribute it and/or modify
+### it under the terms of the GNU Library General Public License as
+### published by the Free Software Foundation; either version 2 of the
+### License, or (at your option) any later version.
+###
+### mLib 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 Library General Public License for more details.
+###
+### You should have received a copy of the GNU Library General Public
+### License along with mLib; if not, write to the Free
+### Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+### MA 02111-1307, USA.
+
+###--------------------------------------------------------------------------
+### Tests.
+
+## assoc
+AT_SETUP([struct: assoc])
+AT_KEYWORDS([struct assoc])
+for seed in 0x58677213 0xdfcc2ff4 ""; do
+  $PYTHON SRCDIR/t/sym-gtest.py $seed
+  AT_CHECK([BUILDDIR/t/assoc.t <sym.script], [0], [expout])
+done
+AT_CLEANUP
+
+## darray
+AT_SETUP([struct: darray])
+AT_KEYWORDS([struct darray])
+for seed in 0x0394946c 0xe8991664 ""; do
+  $PYTHON SRCDIR/t/da-gtest.py $seed
+  AT_CHECK([BUILDDIR/t/darray.t <da.script], [0], [expout])
+done
+AT_CLEANUP
+
+## sym
+AT_SETUP([struct: sym])
+AT_KEYWORDS([struct sym])
+for seed in 0xdc0f64a3 0xd0b9fad0 ""; do
+  $PYTHON SRCDIR/t/sym-gtest.py $seed
+  AT_CHECK([BUILDDIR/t/sym.t <sym.script], [0], [expout])
+done
+AT_CLEANUP
+
+###----- That's all, folks --------------------------------------------------
index 5a0adb7c2facd9337a26a7ea148ea46dcf6b448d..d2d861c91dd064824df07a78668e6e5651b89475 100644 (file)
@@ -67,15 +67,10 @@ pkginclude_HEADERS  += mdup.h
 libsys_la_SOURCES      += mdup.c
 LIBMANS                        += mdup.3
 
-check_PROGRAMS         += mdup.t
-mdup_t_SOURCES          = mdup-test.c
-mdup_t_CPPFLAGS                 = $(TEST_CPPFLAGS)
-mdup_t_LDFLAGS          = -static
-
-EXTRA_DIST             += mdup-test.sh
-CLEANFILES             += mdup.[0-9]*.out mdup.[0-9]*.err
-tests:: mdup.t mdup-test.sh
-       $(srcdir)/mdup-test.sh
+check_PROGRAMS         += t/mdup.t
+t_mdup_t_SOURCES        = t/mdup-test.c
+t_mdup_t_CPPFLAGS       = $(TEST_CPPFLAGS)
+t_mdup_t_LDFLAGS        = -static
 
 ## Time arithmetic.
 pkginclude_HEADERS     += tv.h
similarity index 100%
rename from sys/mdup-test.c
rename to sys/t/mdup-test.c
diff --git a/sys/tests.at b/sys/tests.at
new file mode 100644 (file)
index 0000000..ac0774e
--- /dev/null
@@ -0,0 +1,52 @@
+### -*-autotest-*-
+###
+### Test script for system features
+###
+### (c) 2009 Straylight/Edgeware
+###
+
+###----- Licensing notice ---------------------------------------------------
+###
+### This file is part of the mLib utilities library.
+###
+### mLib is free software; you can redistribute it and/or modify
+### it under the terms of the GNU Library General Public License as
+### published by the Free Software Foundation; either version 2 of the
+### License, or (at your option) any later version.
+###
+### mLib 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 Library General Public License for more details.
+###
+### You should have received a copy of the GNU Library General Public
+### License along with mLib; if not, write to the Free
+### Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+### MA 02111-1307, USA.
+
+###--------------------------------------------------------------------------
+### mdup
+
+AT_SETUP([sys: mdup])
+AT_KEYWORDS([sys mdup])
+
+mdup=BUILDDIR/t/mdup-test
+
+## Very simple cases.
+$mdup 3:4
+$mdup 4:3
+
+## Overlapping sources and destinations
+$mdup 4:3 3:5 5:6
+
+## Repeated sources
+$mdup 3:4 3:3 3:-1
+$mdup 5:8 3:4 3:5 4:6
+
+## Cycles
+$mdup 5:7 3:4 3:5 4:6 5:3
+$mdup 5:8 3:4 3:5 4:6 5:3
+
+AT_CLEANUP
+
+###----- That's all, folks --------------------------------------------------
diff --git a/t/.gitignore b/t/.gitignore
new file mode 100644 (file)
index 0000000..8392db0
--- /dev/null
@@ -0,0 +1,5 @@
+autotest.am
+package.m4
+testsuite.at
+testsuite
+tests.m4
diff --git a/t/Makefile.am b/t/Makefile.am
new file mode 100644 (file)
index 0000000..617af72
--- /dev/null
@@ -0,0 +1,48 @@
+### -*-makefile-*-
+###
+### Build script for test infrastructure
+###
+### (c) 2009 Straylight/Edgeware
+###
+
+###----- Licensing notice ---------------------------------------------------
+###
+### This file is part of the mLib utilities library.
+###
+### mLib is free software; you can redistribute it and/or modify
+### it under the terms of the GNU Library General Public License as
+### published by the Free Software Foundation; either version 2 of the
+### License, or (at your option) any later version.
+###
+### mLib 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 Library General Public License for more details.
+###
+### You should have received a copy of the GNU Library General Public
+### License along with mLib; if not, write to the Free
+### Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+### MA 02111-1307, USA.
+
+include autotest.am
+
+autotest_TESTS          =
+
+###--------------------------------------------------------------------------
+### Make sure everything is built.
+
+check-local: check-build
+check-build:
+       $(MAKE) -C $(top_builddir) all
+.PHONY: check-build
+
+###--------------------------------------------------------------------------
+### Test directories.
+
+autotest_TESTS         += $(top_srcdir)/codec/tests.at
+autotest_TESTS         += $(top_srcdir)/hash/tests.at
+autotest_TESTS         += $(top_srcdir)/struct/tests.at
+autotest_TESTS         += $(top_srcdir)/sys/tests.at
+autotest_TESTS         += $(top_srcdir)/utils/tests.at
+
+###----- That's all, folks --------------------------------------------------
diff --git a/t/atlocal.in b/t/atlocal.in
new file mode 100644 (file)
index 0000000..1a4a661
--- /dev/null
@@ -0,0 +1,29 @@
+### -*-sh-*-
+###
+### Configuration variables interesting to the test suite
+###
+### (c) 2009 Straylight/Edgeware
+###
+
+###----- Licensing notice ---------------------------------------------------
+###
+### This file is part of the mLib utilities library.
+###
+### mLib is free software; you can redistribute it and/or modify
+### it under the terms of the GNU Library General Public License as
+### published by the Free Software Foundation; either version 2 of the
+### License, or (at your option) any later version.
+###
+### mLib 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 Library General Public License for more details.
+###
+### You should have received a copy of the GNU Library General Public
+### License along with mLib; if not, write to the Free
+### Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+### MA 02111-1307, USA.
+
+PYTHON=@PYTHON@
+
+###----- That's all, folks --------------------------------------------------
index 226e86a0a45448e2f3b58869516ddc6b685a571d..b52e7f69e418335c69993653e1fed58cbdd84e01 100644 (file)
@@ -44,20 +44,21 @@ LIBMANS                     += align.3
 pkginclude_HEADERS     += bits.h
 LIBMANS                        += bits.3
 
-EXTRA_DIST             += bits.in bits-testgen.c
-tests:: bits.t bits.in
-       ./bits.t -f $(srcdir)/bits.in
-
-check_PROGRAMS         += bits.t
-bits_t_SOURCES          = bits.c
-bits_t_CPPFLAGS                 = $(TEST_CPPFLAGS)
-bits_t_LDFLAGS          = -static
+check_PROGRAMS         += t/bits.t
+t_bits_t_SOURCES        = t/bits-test.c
+t_bits_t_CPPFLAGS       = $(TEST_CPPFLAGS)
+t_bits_t_LDFLAGS        = -static
+EXTRA_DIST             += t/bits-testgen.py
 
 ## Exceptions.
 pkginclude_HEADERS     += exc.h
 libutils_la_SOURCES    += exc.c
 LIBMANS                        += exc.3
 
+check_PROGRAMS         += t/exc.t
+t_exc_t_SOURCES                 = t/exc-test.c
+t_exc_t_LDFLAGS                 = -static
+
 ## String handling.
 pkginclude_HEADERS     += str.h
 libutils_la_SOURCES    += str.c
@@ -68,13 +69,10 @@ pkginclude_HEADERS  += versioncmp.h
 libutils_la_SOURCES    += versioncmp.c
 LIBMANS                        += versioncmp.3
 
-EXTRA_DIST             += versioncmp.in
-tests:: versioncmp.t versioncmp.in
-       ./versioncmp.t -f $(srcdir)/versioncmp.in
-
-check_PROGRAMS         += versioncmp.t
-versioncmp_t_SOURCES    = versioncmp-test.c
-versioncmp_t_CPPFLAGS   = $(TEST_CPPFLAGS)
-versioncmp_t_LDFLAGS    = -static
+check_PROGRAMS         += t/versioncmp.t
+t_versioncmp_t_SOURCES  = t/versioncmp-test.c
+t_versioncmp_t_CPPFLAGS         = $(TEST_CPPFLAGS)
+t_versioncmp_t_LDFLAGS  = -static
+EXTRA_DIST             += t/versioncmp.tests
 
 ###----- That's all, folks --------------------------------------------------
diff --git a/utils/bits-testgen.c b/utils/bits-testgen.c
deleted file mode 100644 (file)
index bd52b30..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Generate random test vectors for 64-bit operations.
- *
- * As an independent reference, we use the Catacomb multiprecision integer
- * library.
- */
-
-#include <stdio.h>
-
-#include <catacomb/mp.h>
-#include <catacomb/mprand.h>
-#include <catacomb/fibrand.h>
-
-static mp *m64;
-static grand *r;
-
-#define NVEC 64
-
-static mp *mp_rol(mp *d, mp *x, unsigned s)
-{
-  mp *l = mp_lsl(MP_NEW, x, s);
-  mp *r = mp_lsr(MP_NEW, x, 64 - s);
-  d = mp_add(d, l, r);
-  mp_drop(l);
-  mp_drop(r);
-  return (d);
-}
-
-static mp *mp_ror(mp *d, mp *x, unsigned s)
-{
-  mp *l = mp_lsl(MP_NEW, x, 64 - s);
-  mp *r = mp_lsr(MP_NEW, x, s);
-  d = mp_add(d, l, r);
-  mp_drop(l);
-  mp_drop(r);
-  return (d);
-}
-
-static void putmp(mp *x)
-{
-  octet buf[8];
-  unsigned i;
-  fputc(' ', stdout);
-  mp_storeb(x, buf, sizeof(buf));
-  for (i = 0; i < sizeof(buf); i++)
-    printf("%02x", buf[i]);
-}
-
-#define GEN_SHIFT(op)                                                  \
-                                                                       \
-static void gen_##op(void)                                             \
-{                                                                      \
-  unsigned i;                                                          \
-  fputs("\n" #op "64 {\n", stdout);                                    \
-  for (i = 0; i < NVEC; i++) {                                         \
-    mp *x = mprand_range(MP_NEW, m64, r, 0);                           \
-    unsigned s = r->ops->range(r, 70), ss = s & 63;                    \
-    mp *y = mp_##op(MP_NEW, x, ss);                                    \
-    mp_div(0, &y, y, m64);                                             \
-                                                                       \
-    fputs(" ", stdout);                                                        \
-    putmp(x); printf(" %2u", s); putmp(y);                             \
-    fputs(";\n", stdout);                                              \
-    mp_drop(x); mp_drop(y);                                            \
-  }                                                                    \
-  for (i = 0; i < 4; i++) {                                            \
-    mp *x = mprand_range(MP_NEW, m64, r, 0);                           \
-    mp *y = mp_##op(MP_NEW, x, 32);                                    \
-    mp_div(0, &y, y, m64);                                             \
-                                                                       \
-    fputs(" ", stdout);                                                        \
-    putmp(x); printf(" 32"); putmp(y);                                 \
-    fputs(";\n", stdout);                                              \
-    mp_drop(x); mp_drop(y);                                            \
-  }                                                                    \
-  fputs("}\n", stdout);                                                        \
-}
-
-#define GEN_ARITH(op)                                                  \
-                                                                       \
-static void gen_##op(void)                                             \
-{                                                                      \
-  unsigned i;                                                          \
-  fputs("\n" #op "64 {\n", stdout);                                    \
-  for (i = 0; i < NVEC; i++) {                                         \
-    mp *x = mprand_range(MP_NEW, m64, r, 0);                           \
-    mp *y = mprand_range(MP_NEW, m64, r, 0);                           \
-    mp *z = mp_##op(MP_NEW, x, y);                                     \
-    mp_div(0, &z, z, m64);                                             \
-                                                                       \
-    fputs(" ", stdout);                                                        \
-    putmp(x); putmp(y); putmp(z);                                      \
-    fputs(";\n", stdout);                                              \
-    mp_drop(x); mp_drop(y); mp_drop(z);                                        \
-  }                                                                    \
-  fputs("}\n", stdout);                                                        \
-}
-
-GEN_SHIFT(lsl)
-GEN_SHIFT(lsr)
-GEN_SHIFT(rol)
-GEN_SHIFT(ror)
-GEN_ARITH(add)
-GEN_ARITH(sub)
-
-int main(void)
-{
-  m64 = mp_lsl(MP_NEW, MP_ONE, 64);
-  r = fibrand_create(0);
-  fputs("# Test vectors for 64-bit operations [generated]\n", stdout);
-
-  gen_lsl();
-  gen_lsr();
-  gen_rol();
-  gen_ror();
-  gen_add();
-  gen_sub();
-  return (0);
-}
diff --git a/utils/bits.in b/utils/bits.in
deleted file mode 100644 (file)
index fcf7275..0000000
+++ /dev/null
@@ -1,419 +0,0 @@
-# Test vectors for 64-bit operations [generated]
-
-lsl64 {
-  22907dd1dff7dac5  7 483ee8effbed6280;
-  1d26d0c6eb14ad56 13 da18dd6295aac000;
-  edd1dc9268eeee53 56 5300000000000000;
-  7130c9f137120634 41 240c680000000000;
-  3d1f337f29549e6b 53 cd60000000000000;
-  512061f7080cc07d 66 448187dc203301f4;
-  cde8e160ad10997a  5 bd1c2c15a2132f40;
-  6057acc87638f508 64 6057acc87638f508;
-  49ae1d50c38201a8 20 d50c38201a800000;
-  2cde52ebfda19d0c 66 b3794baff6867430;
-  0f215eb57bb3a4f3 25 6af76749e6000000;
-  370c33d090c54215  1 6e1867a1218a842a;
-  b3ad54efc9a38378 35 4d1c1bc000000000;
-  b03fb648e27fff63 66 c0fed92389fffd8c;
-  9829b94586306fed 10 a6e51618c1bfb400;
-  00157846b710ee72 22 11adc43b9c800000;
-  2219bfb474fd71d8 17 7f68e9fae3b00000;
-  4bb65d1563259f9e 61 c000000000000000;
-  8b77dba189196d1e 23 d0c48cb68f000000;
-  3f768281e040a9b9 54 6e40000000000000;
-  bd689aef66f5306c 51 8360000000000000;
-  6b08ac8b0a22260c  1 d611591614444c18;
-  5cfb0bad7d95214a 36 d95214a000000000;
-  6794c18b5337685a 16 c18b5337685a0000;
-  1e72d7b97e23e6ea 39 11f3750000000000;
-  12e4713df4679563 62 c000000000000000;
-  49377d20a8f08345 33 51e1068a00000000;
-  3e4ee1315f3c8f2a 47 4795000000000000;
-  921451dcd1af5813 29 9a35eb0260000000;
-  798391805da08da3 40 a08da30000000000;
-  5f8584b7c5e61766 54 d980000000000000;
-  d1ecdf3d264a7f16 15 6f9e93253f8b0000;
-  c2e815f422cdf0c8 53 1900000000000000;
-  147ed12ca986981a  9 fda259530d303400;
-  98ad0abef8bc4fcb 36 8bc4fcb000000000;
-  7e98ef1f0446b42f 45 d685e00000000000;
-  d44b6d00f06dc188 14 db403c1b70620000;
-  a784e0c6f21195a3  5 f09c18de4232b460;
-  ae985511265febd1 34 997faf4400000000;
-  4720eef9eb1c8dd0 24 f9eb1c8dd0000000;
-  eb0cfa9138ddc399 54 e640000000000000;
-  5608fe95e81c2533 31 f40e129980000000;
-  9c1a9851bc2810d8 26 46f0a04360000000;
-  a089c3f9099c5ffb 28 9099c5ffb0000000;
-  69f6a9f2c0945ffd 58 f400000000000000;
-  03cc0cae9ce021a5 39 7010d28000000000;
-  4ffa91544485f1a1 21 2a8890be34200000;
-  1770a18cbfe6effd 67 bb850c65ff377fe8;
-  778554acf1270485 20 4acf127048500000;
-  827b480aa3a4c84c 33 4749909800000000;
-  f6c9b53bf8f957f4 10 26d4efe3e55fd000;
-  f43e89957f9a3e81 46 8fa0400000000000;
-  743d16687b7bb8de 33 f6f771bc00000000;
-  dad9e9a79b1abf91 18 a69e6c6afe440000;
-  42c2ecccb44d65ba 65 8585d999689acb74;
-  b0ef5746ea8fdccc  0 b0ef5746ea8fdccc;
-  957eb6d6699e6b7e 14 adb59a679adf8000;
-  5cb2dac07ecde957 69 965b580fd9bd2ae0;
-  46fee6dda7abc8ad 62 4000000000000000;
-  ac90cfe22d2f1f29  0 ac90cfe22d2f1f29;
-  42fa8b669ed3bb35  6 bea2d9a7b4eecd40;
-  5e51881e99027b8a 47 3dc5000000000000;
-  a3ccf860b0009740 14 3e182c0025d00000;
-  1c1b9fc214e9ca21  4 c1b9fc214e9ca210;
-  308ba60076817523 32 7681752300000000;
-  9c2835076a23faac 32 6a23faac00000000;
-  dd67771cc667a833 32 c667a83300000000;
-  06148f302c3973ac 32 2c3973ac00000000;
-}
-
-lsr64 {
-  2352fd61e4fa8fec 55 0000000000000046;
-  c861a8b33779f09e 38 00000000032186a2;
-  fc02a8f48afa3080 12 000fc02a8f48afa3;
-  7c486315799dc875 61 0000000000000003;
-  2b5b0677da1ac273 19 0000056b60cefb43;
-  893232a9f81d1451 47 0000000000011264;
-  e475f6b94a43a67b 29 0000000723afb5ca;
-  0d2f9aaafe2dd721 36 0000000000d2f9aa;
-  ba8095ffab1eaadf 40 0000000000ba8095;
-  1f813e28a1397a79 54 000000000000007e;
-  2941feeffdc2eb44 60 0000000000000002;
-  0d5e8f444f7f4e0c 65 06af47a227bfa706;
-  0013e5150686d230 35 0000000000027ca2;
-  49e2414ebf47970e 34 0000000012789053;
-  75cff206877de691 32 0000000075cff206;
-  c3ab6cf8556b7aa7 12 000c3ab6cf8556b7;
-  5948d1b8834df219 28 00000005948d1b88;
-  ec1718dcdeee0d52 41 0000000000760b8c;
-  e4758a386a9943e9  3 1c8eb1470d53287d;
-  b9a80f34c0fde11c 46 000000000002e6a0;
-  9e544e0c536ca1e0 18 00002795138314db;
-  8485290a4d87d13b 11 001090a52149b0fa;
-  1cccada8c1a0a9aa 11 00039995b5183415;
-  4e3c3554f8fb1ef6 36 0000000004e3c355;
-  c270295dfc0ca655 26 000000309c0a577f;
-  bdb75359f91cb9d9 35 0000000017b6ea6b;
-  ce6c0b396179d31f 12 000ce6c0b396179d;
-  1da1ae8f4ae480cd 11 0003b435d1e95c90;
-  d6cf2bacf6f9fd3f 38 00000000035b3cae;
-  01325eb855323665  4 001325eb85532366;
-  788d73d192ee53b3  7 00f11ae7a325dca7;
-  5de25b1593b70f86 61 0000000000000002;
-  2d90a9b59ed034a8 23 0000005b21536b3d;
-  2d25d54756fa5c47 23 0000005a4baa8ead;
-  33922a22d9fd8815 57 0000000000000019;
-  5eb9d85197a21cc3 40 00000000005eb9d8;
-  d5ae7be8dbf98e4f 28 0000000d5ae7be8d;
-  cf6b1372a5aa47b5 65 67b589b952d523da;
-  c783443d64f2ed6a 61 0000000000000006;
-  f86b799e2a168116 42 00000000003e1ade;
-  56445a09898eaa96 47 000000000000ac88;
-  8eedb969ffe07669 16 00008eedb969ffe0;
-  bb7a24c69f13d099 18 00002ede8931a7c4;
-  ffc1ba78c70dda7a 50 0000000000003ff0;
-  a25e771702fb1901  6 028979dc5c0bec64;
-  8a959cb8e75079bb 53 0000000000000454;
-  cc8c54f31b450e88 28 0000000cc8c54f31;
-  cb0f58a1e34c8b15 57 0000000000000065;
-  1986c251f5b70be2 64 1986c251f5b70be2;
-  8995e6c932a17eab 47 000000000001132b;
-  ddb8e4ba463c6630 69 06edc725d231e331;
-  ae8a7a899e4279d5 49 0000000000005745;
-  8d5be74088e4097e 43 000000000011ab7c;
-  6c9e4fba61339d6d 56 000000000000006c;
-  ab7707ca48ff5ba1 10 002addc1f2923fd6;
-  1addf5748729720a 36 0000000001addf57;
-  079c0a2535ded561 48 000000000000079c;
-  e3d33dcf7c71cd7d 19 00001c7a67b9ef8e;
-  71e554a6850d5588 21 0000038f2aa53428;
-  7ae6994fc8528bd1  6 01eb9a653f214a2f;
-  4a2404a059f7f99c 14 00012890128167df;
-  9ce757b3e7a1d075 55 0000000000000139;
-  6d94238ab56d738e  0 6d94238ab56d738e;
-  7de6496247060e7b 65 3ef324b12383073d;
-  6a0c897031ad09a5 32 000000006a0c8970;
-  fa687ec3bad8e18d 32 00000000fa687ec3;
-  ad361f1e226e7887 32 00000000ad361f1e;
-  d35f86c639733c5c 32 00000000d35f86c6;
-}
-
-rol64 {
-  4aed8aaebabb7e0f  0 4aed8aaebabb7e0f;
-  a37fc5cc09f7f62f 36 9f7f62fa37fc5cc0;
-  23fcd2dec5de24d2 66 8ff34b7b17789348;
-  c839839c1b06319f 24 9c1b06319fc83983;
-  b54bdd13c17ef292 58 4ad52f744f05fbca;
-  d3caeb5e57fd21df 60 fd3caeb5e57fd21d;
-  6186265ee6ea4590 51 2c830c3132f73752;
-  cb822fb2ef953aea 63 65c117d977ca9d75;
-  03e0fce2e1b9511b 69 7c1f9c5c372a2360;
-  c86e67f123377a8f 24 f123377a8fc86e67;
-  b8dcc73ae1b3c6cd 31 70d9e366dc6e639d;
-  4e3cb24284cfed17 65 9c796485099fda2e;
-  66b0a6689cf0969c 68 6b0a6689cf0969c6;
-  8fca80e322a4b1bf 41 49637f1f9501c645;
-  1220450433efb6b6 40 efb6b61220450433;
-  d820cf27a64b9d47 24 27a64b9d47d820cf;
-  845dac557bb3e75f 66 1176b155eecf9d7e;
-  fb8e173416867fcd 12 e173416867fcdfb8;
-  d58b10f91d07a037  5 b1621f23a0f406fa;
-  b96e83c4bf2fb5b2 33 7e5f6b6572dd0789;
-  d663cb3884b2a0a8 55 546b31e59c425950;
-  5df752423f3179bf 55 dfaefba9211f98bc;
-  3564672e370ffc37 26 b8dc3ff0dcd5919c;
-  a31e8aac1d426ce1 11 f45560ea13670d18;
-  4780e974a8a2a0e7 39 515073a3c074ba54;
-  0fd0d7f69fa658ab 67 7e86bfb4fd32c558;
-  40d304128719b541 27 9438cdaa0a069820;
-  322b3bf7d02cec05 39 16760299159dfbe8;
-  96cec07591ada462 17 80eb235b48c52d9d;
-  ba3037235e19a394 48 a394ba3037235e19;
-  56b4cfc5555e925e 58 795ad33f15557a49;
-  d39040e632d56264 52 264d39040e632d56;
-  e6a427b99a5dc266 50 099b9a909ee66977;
-  cc034b9f099f0467 28 f099f0467cc034b9;
-  9da898b39324cd30 31 c99266984ed44c59;
-  51014f6796f9c488 59 42880a7b3cb7ce24;
-  dd678d490c2f320f 46 cc83f759e352430b;
-  3c484fb34bd52239 33 97aa447278909f66;
-  2cb8ecf4f64e3298 16 ecf4f64e32982cb8;
-  73be257a753b3820 33 ea767040e77c4af4;
-  3f94a079bde2dd98 60 83f94a079bde2dd9;
-  702db2ba11927589 63 b816d95d08c93ac4;
-  340af7b91f9632fc  2 d02bdee47e58cbf0;
-  761ca16434a9935e 28 434a9935e761ca16;
-  11c1cb072f32a59c 27 3979952ce08e0e58;
-  97d9a7b0556463ff 27 82ab231ffcbecd3d;
-  ebc43263391424d0 31 9c8a126875e21931;
-  c897a8a484313243 34 10c4c90f225ea292;
-  1b5302ccd501b538  3 da981666a80da9c0;
-  0764ee4ce1d3fc04 38 74ff0101d93b9338;
-  4f7d8c0c48ad7d6f 20 c0c48ad7d6f4f7d8;
-  d5c8d92dbd873a8f 23 96dec39d47eae46c;
-  63aae01a2a199d3a 61 4c755c03454333a7;
-  30a6d917fa0c1a23 32 fa0c1a2330a6d917;
-  bc8a4cba45b20543 25 748b640a87791499;
-  fc1b9dbce078b87a 65 f8373b79c0f170f5;
-  acf03897b95a3f37  0 acf03897b95a3f37;
-  d0544b5151db0a16 57 2da0a896a2a3b614;
-  9e8f2fc12c7f839f 49 073f3d1e5f8258ff;
-  9a0056284a697ffd 27 42534bffecd002b1;
-  dead83f5a356e910 55 886f56c1fad1ab74;
-  260ea9379cc72321 24 379cc72321260ea9;
-  17158fee8ca42e75  1 2e2b1fdd19485cea;
-  4f497b3734be301d 55 0ea7a4bd9b9a5f18;
-  5fe692629db57311 32 9db573115fe69262;
-  22f3a1573f9e0553 32 3f9e055322f3a157;
-  3e96265e4326fa53 32 4326fa533e96265e;
-  de3d4eb23cacdf6e 32 3cacdf6ede3d4eb2;
-}
-
-ror64 {
-  ad8ca13187eba153 37 8c3f5d0a9d6c6509;
-  ba31582b3793b05f 42 0acde4ec17ee8c56;
-  9f80c5814b91f4d3  5 9cfc062c0a5c8fa6;
-  9943307fa4ef095e 62 650cc1fe93bc257a;
-  7c9351366ef8e98e 26 be3a639f24d44d9b;
-  b48aa989dbb8d0f1 56 8aa989dbb8d0f1b4;
-  b2dab2863e574842 58 b6aca18f95d210ac;
-  97782f16c5816270 17 b1384bbc178b62c0;
-  8f4bdbd6ebdfbafb 41 eb75efdd7dc7a5ed;
-  f5427dbee5f95b53 68 3f5427dbee5f95b5;
-  cb6d7c128b79f465 38 4a2de7d1972db5f0;
-  0f20d40224baac3a 40 0224baac3a0f20d4;
-  63c1f3f00f301cc9 46 cfc03cc073258f07;
-  bfea6d561ab5aea5  6 96ffa9b5586ad6ba;
-  5c7a8d2fc4feef99 47 1a5f89fddf32b8f5;
-  b6c86db981143082 35 3022861056d90db7;
-  6473a86a5da3d2e8 13 9743239d4352ed1e;
-  602ebbaf08bf9315 27 17f262ac05d775e1;
-  38a1c33beb408771 47 8677d6810ee27143;
-  a3f63408d3b27df5 35 1a764fbeb47ec681;
-  ed5537bfb0162f05 41 dfd80b1782f6aa9b;
-  d1b2c36ceec1dc40  6 0346cb0db3bb0771;
-  3aed7667c6342c83 35 f8c68590675daecc;
-  eef301f2c93fda30 14 68c3bbcc07cb24ff;
-  f7987116dba62d93 21 316c9fbcc388b6dd;
-  70274ffe5a6506e4  7 c8e04e9ffcb4ca0d;
-  6bcedb015be40bfb 24 e40bfb6bcedb015b;
-  68d7d2ce372a8a38 44 2ce372a8a3868d7d;
-  569863bbd3ad4290 53 c31dde9d6a1482b4;
-  776ee19eb0a86714 64 776ee19eb0a86714;
-  3292af9ac5ff48a0 14 2280ca4abe6b17fd;
-  e0136f6237637451 54 4dbd88dd8dd14780;
-  45b31f52265dfa0f 27 cbbf41e8b663ea44;
-  0392ea7314124aeb 55 25d4e6282495d607;
-  c7319c116207607f 27 40ec0ff8e633822c;
-  3bfa119be8284f3a 42 66fa0a13ce8efe84;
-  e760886e4d3bf414 46 21b934efd0539d82;
-  b27749f2665a9537 32 665a9537b27749f2;
-  a8c06832398b5a70 68 0a8c06832398b5a7;
-  c1f9a7aba24b5516 25 25aa8b60fcd3d5d1;
-  1e51aaeb95e1e511 56 51aaeb95e1e5111e;
-  b3874faad48effe1 26 23bff86ce1d3eab5;
-  2dccf08b113a1f9e 52 cf08b113a1f9e2dc;
-  bb25b47f8968a082 17 50415d92da3fc4b4;
-  ab4008222c8c03df 48 08222c8c03dfab40;
-  213ba7e1412f9995 49 d3f0a097ccca909d;
-  c8123ef89b66074e 52 23ef89b66074ec81;
-  b502e2eacd8d74c2 45 17566c6ba615a817;
-  26887b8c874ad75e 26 d2b5d789a21ee321;
-  872a6e980a11947c 46 ba60284651f21ca9;
-  33b6ba72a81cf590 61 9db5d39540e7ac81;
-  faada6fe97c73242 65 7d56d37f4be39921;
-  24b1b85fe682cd1d 27 d059a3a496370bfc;
-  b833126cf9876424 66 2e0cc49b3e61d909;
-  c612844fb428dbc6 38 3ed0a36f1b184a11;
-  95238cb43653d3f5 16 d3f595238cb43653;
-  2aa1effa03c4cc3a 57 50f7fd01e2661d15;
-  fb97bbbf521b5864 41 dfa90dac327dcbdd;
-  baa395b5c7a7aa80 27 f4f550175472b6b8;
-  dfdb0984dc12ba2c 66 37f6c2613704ae8b;
-  11b39e4d85729892 13 c4908d9cf26c2b94;
-  2d986c78a311033b 49 363c5188819d96cc;
-  ba444d46e7503fd1  8 d1ba444d46e7503f;
-  686b7d7922fcf56b 47 faf245f9ead6d0d6;
-  b001ddd542907641 32 42907641b001ddd5;
-  3a327c960cf48973 32 0cf489733a327c96;
-  09ecc63d88b79c61 32 88b79c6109ecc63d;
-  f240e09c02002d31 32 02002d31f240e09c;
-}
-
-add64 {
-  ffa31bbb318ee6c9 77886da9ed9bf217 772b89651f2ad8e0;
-  2503beebdc863e7a 5aec57d94fd2f508 7ff016c52c593382;
-  677d70bb3b80e18c 7251e6454c970deb d9cf57008817ef77;
-  f1c65a62b1b9026f 15719acbd61c7704 0737f52e87d57973;
-  960ba55948d612e3 d3486d5d49202d18 695412b691f63ffb;
-  99399c6c45e8c599 40dbf36af241f761 da158fd7382abcfa;
-  fb9eed6a0cd0f0f3 632d1f45b7754396 5ecc0cafc4463489;
-  e39647f1cfee6040 330d58d6cd78a424 16a3a0c89d670464;
-  7db21330002cb386 d4bca40e62371c6d 526eb73e6263cff3;
-  e1c7031eb74dfa95 b66359d2cbf149ff 982a5cf1833f4494;
-  2e45cd635e2fcf27 d2e59db3ca1e8e7b 012b6b17284e5da2;
-  ad63ea4c6925e11b 301c6631d719e7bd dd80507e403fc8d8;
-  9f0657cc8e6619ec c046ef1f44c964bb 5f4d46ebd32f7ea7;
-  69a9fe8470acbd94 b63bc903388de527 1fe5c787a93aa2bb;
-  50b83682b43c0cbe e5d7933cf398b6d1 368fc9bfa7d4c38f;
-  a67482fbdd55f104 dece9659b7ecb778 854319559542a87c;
-  492cab8935ed33bf dc821a09459bfb4a 25aec5927b892f09;
-  323a1a40e6201389 19236991a37cd95a 4b5d83d2899cece3;
-  2b7ffef363020062 d0acc63ba6d05b12 fc2cc52f09d25b74;
-  1db43d975099d082 f03fe29725e17c84 0df4202e767b4d06;
-  8801d09bbe4e85f7 c131099b7d08a054 4932da373b57264b;
-  ffb5584821a24134 d4e7b794483c13c3 d49d0fdc69de54f7;
-  dc096d1c5e1099ac 44430283fb5a02df 204c6fa0596a9c8b;
-  0184be162ac48b75 ec32f75040808056 edb7b5666b450bcb;
-  1e2f6b50326ca98c b15e551d75529eaf cf8dc06da7bf483b;
-  7365630d71159148 c7bef83555794918 3b245b42c68eda60;
-  f67af3372a5cbc05 96df32153c93ed4e 8d5a254c66f0a953;
-  430351e583fc19a9 5431a75d8cdbe2df 9734f94310d7fc88;
-  2519db4bbebb8ec9 36ea3d9c821c7ccd 5c0418e840d80b96;
-  1065e01360db5f60 1b7df81e5c04ed9a 2be3d831bce04cfa;
-  6c99a594ea6f81c4 a73fb16638a957bf 13d956fb2318d983;
-  3169420dd13fb427 f93dd859bb958ddd 2aa71a678cd54204;
-  916cbddf29aca294 151f8b3b6e14b136 a68c491a97c153ca;
-  c6110822a062efdc 48ccc81cf9eaef85 0eddd03f9a4ddf61;
-  bab5817a17ce5c7d 7db952939d68ad41 386ed40db53709be;
-  f3e534755d5253ad e8fe934c07a834ff dce3c7c164fa88ac;
-  145953602245c141 a5706669ba7fc566 b9c9b9c9dcc586a7;
-  8d0422a0a55011b9 2c57299ba1dbf17e b95b4c3c472c0337;
-  b53b86b676485d4e aec47d6ed6c1cfdb 640004254d0a2d29;
-  33abdb685054013e e42476b3652ffeed 17d0521bb584002b;
-  74e814305e87098f 012790b9c7b63825 760fa4ea263d41b4;
-  22fb3116e5d4261e 38f3bbc7aca807d9 5beeecde927c2df7;
-  7cc9f89cd170b899 ea665723ac1ebffc 67304fc07d8f7895;
-  a9adcf9792573201 792b40b628469eed 22d9104dba9dd0ee;
-  f672a26fdff77589 377176c791d6d05d 2de4193771ce45e6;
-  e40d2c2eedce7389 12e8a01a4a099c70 f6f5cc4937d80ff9;
-  43dc1e358b162ef4 96013eadfd569906 d9dd5ce3886cc7fa;
-  74abbe06e79609e2 a5ff7e7b394634e5 1aab3c8220dc3ec7;
-  0fd32f5d53cb1a59 d86f31434c46b912 e84260a0a011d36b;
-  a5c776d85f896e78 23af6c42d02bf636 c976e31b2fb564ae;
-  e86e5c9dd566720b d965d3bb8ace6968 c1d430596034db73;
-  6d143e937ce97f11 4c7870a4590fe308 b98caf37d5f96219;
-  69c015fc03df474a ef039a618bad49da 58c3b05d8f8c9124;
-  c4e978b498b30f5b df9e8f05bd0da330 a48807ba55c0b28b;
-  3087b6a9bc6e194b b83e25210ff7ff77 e8c5dbcacc6618c2;
-  b3093e95f655c4ce a7ee958e7c34c023 5af7d424728a84f1;
-  8551c621019d03f8 05eb84dfbc033b4f 8b3d4b00bda03f47;
-  aa87ba7cefdec2ce 866a37ad34319550 30f1f22a2410581e;
-  86e9a1e9b538b043 09b50be0769ab77e 909eadca2bd367c1;
-  8e1192fa83d9fad8 0f63d3d397206f04 9d7566ce1afa69dc;
-  bda0d57ae405c719 9d821e8c88b126fe 5b22f4076cb6ee17;
-  1bb5139aaaf14309 68a929926b06207c 845e3d2d15f76385;
-  8c47736195bb45e9 458ca5c5dfbeb93f d1d419277579ff28;
-  83b0705883ec36cf f87381fd47cfa1b0 7c23f255cbbbd87f;
-}
-
-sub64 {
-  840f33a93043b3b8 3f8c5b4675f8dc37 4482d862ba4ad781;
-  01d52c8258029c24 f46d6b5d3447d076 0d67c12523bacbae;
-  9b76805d62cddc3c 95780d2a4333b49e 05fe73331f9a279e;
-  e45991918d826254 21765e775ed435ec c2e3331a2eae2c68;
-  0cb384f3ea92338e 1c406099f48452f3 f0732459f60de09b;
-  05fe731bdaf80c62 7c3c6e37f7280c06 89c204e3e3d0005c;
-  12aa89841e7cf25f 8d11297468360e6f 8599600fb646e3f0;
-  4f13686c9fca96fc 50237a657a0c851d feefee0725be11df;
-  3b8cb60ea1a95b2b 488d12ee7745ee29 f2ffa3202a636d02;
-  8af1ccd5901a5412 bcaac1ee8639e9db ce470ae709e06a37;
-  42ae568070a2f527 0c06e9aedbeea1a7 36a76cd194b45380;
-  e9db048fe53412d0 115b14082a737f4f d87ff087bac09381;
-  57a1ded3be8d6228 0b7c9162889ab350 4c254d7135f2aed8;
-  9400e5e98eb4e953 a25ec65e79b8c991 f1a21f8b14fc1fc2;
-  15b3c653aee0aa03 794ed82d5120ee49 9c64ee265dbfbbba;
-  5c76f984993259f8 0edc054bd7c3d63f 4d9af438c16e83b9;
-  fa34e470ca2462ed dbbb8ecbab916c5c 1e7955a51e92f691;
-  56d8006738fa669a b5322e4a0abbf298 a1a5d21d2e3e7402;
-  e437f41bd175469e c26093f2ff5936b5 21d76028d21c0fe9;
-  ba02725ec00e044e 7ffc5de81723faa9 3a061476a8ea09a5;
-  f5ae1def086a31fa 66d1256c07ec03b2 8edcf883007e2e48;
-  e282a1f1abdd0bd3 720053262c99ce85 70824ecb7f433d4e;
-  abefa13cc1b083ee f34d3455c4e73e21 b8a26ce6fcc945cd;
-  e36fd6df5d3e80da 8e7468fdecd51cf7 54fb6de1706963e3;
-  53508bb42f9fb12d bbbf874db4fc1d93 979104667aa3939a;
-  a08c4fff0cb126cd db33a2d5b6244f85 c558ad29568cd748;
-  60342f111b96e944 da0d834e0981f0fb 8626abc31214f849;
-  29bb2238436d3d5c 0cc0d6c0d7dc0122 1cfa4b776b913c3a;
-  d4e4b492d0144d0a 216312d86999de02 b381a1ba667a6f08;
-  62aa21d058b04793 ca967ac4e15d8ea0 9813a70b7752b8f3;
-  7c7559b4c2d33eab 6ba7002f0cdb3b17 10ce5985b5f80394;
-  cee3365083ac9b0a f78716ffb3dc1bee d75c1f50cfd07f1c;
-  beff21f4be58cac5 39468a2ba0e2993a 85b897c91d76318b;
-  f68c3b001544ee50 45e03f4db3071561 b0abfbb2623dd8ef;
-  be6bb80aef13d9b7 d6d3430f44d09daa e79874fbaa433c0d;
-  0ef5bc1d106176a2 5e285963e24cb86c b0cd62b92e14be36;
-  2f5541b5ef1f653d dba0b770766c5a13 53b48a4578b30b2a;
-  12398a5bca95d24f 0687b4560a76287f 0bb1d605c01fa9d0;
-  6772fa6d8e350eea 0194bcc240fb19ad 65de3dab4d39f53d;
-  6169ae1bacec540e c6af706b81647983 9aba3db02b87da8b;
-  fea76d131a869677 0c4f71cd9468c166 f257fb45861dd511;
-  b2e08ee794cb1de9 631b1a5239d80768 4fc574955af31681;
-  c5f5d16f81d09e34 c95a7a8d545dc794 fc9b56e22d72d6a0;
-  078d1f0f0130311b b1063d557b31dd54 5686e1b985fe53c7;
-  50de5365dd81df94 4a91eea0b3722175 064c64c52a0fbe1f;
-  3792c2eafa6233cc c658e0b8768dcb70 7139e23283d4685c;
-  27e0384677309813 5beba6be23ed8205 cbf491885343160e;
-  8f94e209fdbf838c aa4a6aa7696b7c16 e54a776294540776;
-  4e4853557845c317 c2cdc5fb5ad60d9d 8b7a8d5a1d6fb57a;
-  479e93740c3b0dcb fa6a10a7b62fd2c7 4d3482cc560b3b04;
-  26118c18862e3577 c1e1c80cbba574c1 642fc40bca88c0b6;
-  880bbe893abbc412 a0876b0c6551dbc0 e784537cd569e852;
-  02685dcb638d3852 cd78ce98851931c5 34ef8f32de74068d;
-  783ed0fbfb0514b9 cc25a09cd136eac6 ac19305f29ce29f3;
-  0edd1bbe299d0576 74a19f3cc23ebb6a 9a3b7c81675e4a0c;
-  8fc2889d6cfd2702 f57ada42c026133f 9a47ae5aacd713c3;
-  add9376cee2976e5 62724f7364acd2a1 4b66e7f9897ca444;
-  224fe89bdc5eaa00 e9d1d88442f98f77 387e101799651a89;
-  e41daa2fabef0312 68145366042b11c2 7c0956c9a7c3f150;
-  0bfb4f1a4bec61a3 08e848bbf1ee1264 0313065e59fe4f3f;
-  26b7ab0259e30390 93b750a91adc862a 93005a593f067d66;
-  3d21201fb7e0e828 a8e8b735f372e772 943868e9c46e00b6;
-  8cfc5c2cbf62304b 2868e4e22d000239 6493774a92622e12;
-  d4fc83506a7d0850 49f4d713dad4992d 8b07ac3c8fa86f23;
-}
similarity index 98%
rename from utils/bits.c
rename to utils/t/bits-test.c
index db983313c49db3d74859c1eb87056df072ec9a80..0d0f66cdf15a0d091dd61a1ce28ae3e501ee3019 100644 (file)
@@ -95,7 +95,7 @@ static test_chunk tests[] = {
 
 int main(int argc, char *argv[])
 {
-  test_run(argc, argv, tests, SRCDIR "/bits.in");
+  test_run(argc, argv, tests, SRCDIR "/t/bits.tests");
   return (0);
 }
 
diff --git a/utils/t/bits-testgen.py b/utils/t/bits-testgen.py
new file mode 100644 (file)
index 0000000..6bb9f88
--- /dev/null
@@ -0,0 +1,55 @@
+#! /usr/bin/python
+### -*-python-*-
+###
+### Generate input script and expected output for bit manipulation,
+### particularly 64-bit arithmetic.
+
+import sys as SYS
+import random as R
+
+NVEC = 64
+WD = 64
+LIMIT = 1 << WD
+MASK = LIMIT - 1
+
+SYS.argv.pop()
+def arg(default = None):
+  if len(SYS.argv):
+    return SYS.argv.pop()
+  else:
+    return default
+
+R.seed(None)
+SEED = int(arg(R.randrange(0, 1 << 32)))
+R.seed(SEED)
+
+print '### Test vectors for 64-bit arithmetic macros'
+print '###   [generated; seed = 0x%08x]' % SEED
+
+def rol(x, n): return ((x << n) | (x >> (WD - n))) & MASK
+def ror(x, n): return ((x >> n) | (x << (WD - n))) & MASK
+def put(x): return '%0*x' % (WD/4, x)
+
+for name, func in [('lsl', lambda x, n: x << n),
+                   ('lsr', lambda x, n: x >> n),
+                   ('rol', rol),
+                   ('ror', ror)]:
+  print '\n%s64 {' % name
+  for i in xrange(NVEC):
+    x = R.randrange(LIMIT)
+    sh = R.randrange(0, 70) & 63
+    print '  %s %2d %s;' % (put(x), sh, put(func(x, sh) & MASK))
+  for i in xrange(4):
+    x = R.randrange(LIMIT)
+    sh = 32
+    print '  %s %2d %s;' % (put(x), sh, put(func(x, sh) & MASK))
+  print '}'
+
+for name, func in [('add', lambda x, y: x + y),
+                   ('sub', lambda x, y: x - y)]:
+  print '\n%s64 {' % name
+  for i in xrange(NVEC):
+    x = R.randrange(LIMIT)
+    y = R.randrange(LIMIT)
+    print '  %s %s %s;' % (put(x), put(y), put(func(x, y) & MASK))
+  print '}'
similarity index 100%
rename from utils/exctest.c
rename to utils/t/exc-test.c
similarity index 100%
rename from utils/versioncmp.in
rename to utils/t/versioncmp.tests
diff --git a/utils/tests.at b/utils/tests.at
new file mode 100644 (file)
index 0000000..3b216fc
--- /dev/null
@@ -0,0 +1,62 @@
+### -*-autotest-*-
+###
+### Test script for utilities
+###
+### (c) 2009 Straylight/Edgeware
+###
+
+###----- Licensing notice ---------------------------------------------------
+###
+### This file is part of the mLib utilities library.
+###
+### mLib is free software; you can redistribute it and/or modify
+### it under the terms of the GNU Library General Public License as
+### published by the Free Software Foundation; either version 2 of the
+### License, or (at your option) any later version.
+###
+### mLib 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 Library General Public License for more details.
+###
+### You should have received a copy of the GNU Library General Public
+### License along with mLib; if not, write to the Free
+### Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+### MA 02111-1307, USA.
+
+###--------------------------------------------------------------------------
+### Tests.
+
+## bits
+AT_SETUP([utilities: bits])
+AT_KEYWORDS([utils bits])
+for seed in 0xaca98e08 0x0b6e95fb ""; do
+  $PYTHON SRCDIR/t/bits-testgen.py $seed >bits.tests
+  AT_CHECK([BUILDDIR/t/bits.t -f bits.tests], [0], [ignore], [ignore])
+done
+AT_CLEANUP
+
+## exc
+AT_SETUP([utilities: exc])
+AT_KEYWORDS([utils exc])
+AT_DATA([expout],
+[apple
+banana
+cabbage
+dibble
+exc type 2 (excession)
+fennel
+65 exception (val = 53)
+hello! __exc_list = (nil)
+])
+AT_CHECK([BUILDDIR/t/exc.t], [0], [expout])
+AT_CLEANUP
+
+## versioncmp
+AT_SETUP([utilities: versioncmp])
+AT_KEYWORDS([utils versioncmp])
+AT_CHECK([BUILDDIR/t/versioncmp.t -f SRCDIR/t/versioncmp.tests],
+        [0], [ignore], [ignore])
+AT_CLEANUP
+
+###----- That's all, folks --------------------------------------------------
diff --git a/vars.am b/vars.am
index a35014d4c5afd5de3a15a457d79d9dfd11a3fab9..3c653704eec7a520455e322f961da4aa5441b41f 100644 (file)
--- a/vars.am
+++ b/vars.am
@@ -99,6 +99,9 @@ LDADD                  = $(top_builddir)/libmLib.la
 check: tests
 .PHONY: check tests
 
+tests::;
+.PHONY: tests
+
 ###--------------------------------------------------------------------------
 ### Manual.