From 706f6a7ec4a59f98108a6f3fd8f34fcbfd81f596 Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Wed, 30 Jan 2008 22:28:37 -0500 Subject: [PATCH] More work on the testsuite. I'm not sure exactly what tests I will have the patience to write, but at least the infrastructure is all there. --- .gitignore | 1 + Makefile | 9 ++---- run-testsuite | 27 ++++++++++++++++ testsuite.cc | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 119 insertions(+), 8 deletions(-) create mode 100755 run-testsuite diff --git a/.gitignore b/.gitignore index 9cad653..4467edc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ sample testsuite testsuite.expected testsuite.out +testsuite.err diff --git a/Makefile b/Makefile index 68e7a00..450681e 100644 --- a/Makefile +++ b/Makefile @@ -34,16 +34,11 @@ testsuite: testsuite.o $(library-objects) g++ $^ -o $@ # Extract the expected output from the testsuite source. testsuite.expected: testsuite.cc - sed -nre 's,^.*//,,p' $< >$@ + sed -nre 's,^.*//([^ ]),\1,p' $< >$@ # Run the testsuite. .PHONY: test test: testsuite testsuite.expected - ./testsuite >testsuite.out - @if diff -u testsuite.expected testsuite.out; then\ - echo 'All tests passed.';\ - else\ - echo >&2 'At least one test failed!'; exit 1;\ - fi + ./run-testsuite # The rules below build a program that uses the library. They are preset to # build ``sample'' from ``sample.cc''. You can change the name(s) of the diff --git a/run-testsuite b/run-testsuite new file mode 100755 index 0000000..0c563c2 --- /dev/null +++ b/run-testsuite @@ -0,0 +1,27 @@ +#!/bin/bash + +bad= + +set -o pipefail +if ! valgrind --error-exitcode=1 --leak-check=full \ + ./testsuite 2>&1 >testsuite.out | tee testsuite.err; then + echo >&2 'Memory errors!' + bad=1 +fi + +if grep 'LEAK SUMMARY' testsuite.err >/dev/null; then + echo >&2 'Memory leaks!' + bad=1 +fi + +if ! diff -u testsuite.expected testsuite.out; then + echo >&2 'Output is incorrect!' + bad=1 +fi + +if [ $bad ]; then + echo >&2 'Test suite failed!' + exit 1 +else + echo 'Test suite succeeded.' +fi diff --git a/testsuite.cc b/testsuite.cc index c91c8ad..3796b99 100644 --- a/testsuite.cc +++ b/testsuite.cc @@ -8,10 +8,98 @@ #include using namespace std; +const BigUnsigned &check(const BigUnsigned &x) { + unsigned int l = x.getLength(); + if (l != 0 && x.getBlock(l-1) == 0) + cout << "Unzapped number!" << endl; + if (l > x.getCapacity()) + cout << "Capacity inconsistent with length!" << endl; + return x; +} + +const BigInteger &check(const BigInteger &x) { + if (x.getSign() == 0 && !x.getMagnitude().isZero()) + cout << "Sign should not be zero!" << endl; + if (x.getSign() != 0 && x.getMagnitude().isZero()) + cout << "Sign should be zero!" << endl; + check(x.getMagnitude()); + return x; +} + +#define THROWY(x) try {x; cout << "Expected error not thrown!" << endl; } catch (const char *err) {} + int main() { - + +try { + BigUnsigned z(0), one(1), ten(10); cout << z << ',' << one << ',' << ten << endl; //0,1,10 +// TODO: Comprehensively test the general and special cases of each function. + +// Addition +cout << check(BigUnsigned(0) + 0) << endl; //0 +cout << check(BigUnsigned(0) + 1) << endl; //1 +cout << check(BigUnsigned(0xFFFFFFFFU) + 1) << endl; //4294967296 + +// Negative BigUnsigneds +THROWY(BigUnsigned(-1)); +THROWY(BigUnsigned(5) - BigUnsigned(6)); +cout << check(BigUnsigned(5) - BigUnsigned(5)) << endl; //0 + +// Multiplication and division +BigUnsigned a = check(BigUnsigned(314159265) * 358979323); +cout << a << ',' << (a / 123) << ',' << (a % 123) << endl; +//112776680263877595,916883579381118,81 +THROWY(BigUnsigned(5) / 0); + +{ + /* Test that BigInteger division sets the sign to zero. + * Bug reported by David Allen. */ + BigInteger num(3), denom(5), quotient; + num.divideWithRemainder(denom, quotient); + check(quotient); + num = 5; + num.divideWithRemainder(denom, quotient); + check(num); +} + +{ + /* Test that BigInteger subtraction sets the sign properly. + * Bug reported by Samuel Larkin. */ + BigInteger zero(0), three(3), ans; + ans = zero - three; + cout << check(ans).getSign() << endl; //-1 +} + +{ + /* Test that BigInteger multiplication shifts bits properly on systems + * where long is bigger than int. (Obviously, this would only catch the + * bug when run on such a system.) + * Bug reported by Mohand Mezmaz. */ + BigInteger f=4; f*=3; + cout<