Add malloc test support to unit tests.
Currently far from passing and I haven't even tried with a leak checker yet.
Also bn_test is slow.
Change-Id: I4fe2783aa5f7897839ca846062ae7e4a367d2469
Reviewed-on: https://boringssl-review.googlesource.com/4794
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt
index 7430b62..6858cbb 100644
--- a/crypto/CMakeLists.txt
+++ b/crypto/CMakeLists.txt
@@ -207,6 +207,8 @@
constant_time_test
constant_time_test.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(constant_time_test crypto)
@@ -215,6 +217,8 @@
thread_test
thread_test.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(thread_test crypto)
diff --git a/crypto/base64/CMakeLists.txt b/crypto/base64/CMakeLists.txt
index 8bc531a..42037a5 100644
--- a/crypto/base64/CMakeLists.txt
+++ b/crypto/base64/CMakeLists.txt
@@ -12,6 +12,8 @@
base64_test
base64_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(base64_test crypto)
diff --git a/crypto/bio/CMakeLists.txt b/crypto/bio/CMakeLists.txt
index f4122c4..dbf5951 100644
--- a/crypto/bio/CMakeLists.txt
+++ b/crypto/bio/CMakeLists.txt
@@ -22,6 +22,8 @@
bio_test
bio_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(bio_test crypto)
diff --git a/crypto/bn/CMakeLists.txt b/crypto/bn/CMakeLists.txt
index 4a33f7e..2e0cb45 100644
--- a/crypto/bn/CMakeLists.txt
+++ b/crypto/bn/CMakeLists.txt
@@ -70,6 +70,8 @@
bn_test
bn_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(bn_test crypto)
diff --git a/crypto/bytestring/CMakeLists.txt b/crypto/bytestring/CMakeLists.txt
index d1f0441..cbbacf2 100644
--- a/crypto/bytestring/CMakeLists.txt
+++ b/crypto/bytestring/CMakeLists.txt
@@ -14,6 +14,8 @@
bytestring_test
bytestring_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(bytestring_test crypto)
diff --git a/crypto/dh/CMakeLists.txt b/crypto/dh/CMakeLists.txt
index 9e487d5..d0c1da7 100644
--- a/crypto/dh/CMakeLists.txt
+++ b/crypto/dh/CMakeLists.txt
@@ -16,6 +16,8 @@
dh_test
dh_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(dh_test crypto)
diff --git a/crypto/digest/CMakeLists.txt b/crypto/digest/CMakeLists.txt
index 8cab46a..816d116 100644
--- a/crypto/digest/CMakeLists.txt
+++ b/crypto/digest/CMakeLists.txt
@@ -13,6 +13,8 @@
digest_test
digest_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(digest_test crypto)
diff --git a/crypto/dsa/CMakeLists.txt b/crypto/dsa/CMakeLists.txt
index dab2c4c..1bb8b63 100644
--- a/crypto/dsa/CMakeLists.txt
+++ b/crypto/dsa/CMakeLists.txt
@@ -14,6 +14,8 @@
dsa_test
dsa_test.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(dsa_test crypto)
diff --git a/crypto/ec/CMakeLists.txt b/crypto/ec/CMakeLists.txt
index a218c0d..b5ebefa 100644
--- a/crypto/ec/CMakeLists.txt
+++ b/crypto/ec/CMakeLists.txt
@@ -20,12 +20,16 @@
example_mul
example_mul.c
+
+ $<TARGET_OBJECTS:test_support>
)
add_executable(
ec_test
ec_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(example_mul crypto)
diff --git a/crypto/ecdsa/CMakeLists.txt b/crypto/ecdsa/CMakeLists.txt
index c8645d1..f431e59 100644
--- a/crypto/ecdsa/CMakeLists.txt
+++ b/crypto/ecdsa/CMakeLists.txt
@@ -14,6 +14,8 @@
ecdsa_test
ecdsa_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(ecdsa_test crypto)
diff --git a/crypto/err/CMakeLists.txt b/crypto/err/CMakeLists.txt
index 89f96bd..5215eec 100644
--- a/crypto/err/CMakeLists.txt
+++ b/crypto/err/CMakeLists.txt
@@ -44,6 +44,8 @@
err_test
err_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(err_test crypto)
diff --git a/crypto/evp/CMakeLists.txt b/crypto/evp/CMakeLists.txt
index 6db9752..5769fa4 100644
--- a/crypto/evp/CMakeLists.txt
+++ b/crypto/evp/CMakeLists.txt
@@ -26,12 +26,15 @@
evp_extra_test
evp_extra_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
add_executable(
evp_test
evp_test.cc
+
$<TARGET_OBJECTS:test_support>
)
@@ -39,6 +42,8 @@
pbkdf_test
pbkdf_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(evp_extra_test crypto)
diff --git a/crypto/hkdf/CMakeLists.txt b/crypto/hkdf/CMakeLists.txt
index f8dd748..66d680a 100644
--- a/crypto/hkdf/CMakeLists.txt
+++ b/crypto/hkdf/CMakeLists.txt
@@ -12,6 +12,8 @@
hkdf_test
hkdf_test.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(hkdf_test crypto)
diff --git a/crypto/hmac/CMakeLists.txt b/crypto/hmac/CMakeLists.txt
index 1a08c55..11d267f 100644
--- a/crypto/hmac/CMakeLists.txt
+++ b/crypto/hmac/CMakeLists.txt
@@ -13,6 +13,7 @@
hmac_test
hmac_test.cc
+
$<TARGET_OBJECTS:test_support>
)
diff --git a/crypto/lhash/CMakeLists.txt b/crypto/lhash/CMakeLists.txt
index 0eaabed..c71b8a1 100644
--- a/crypto/lhash/CMakeLists.txt
+++ b/crypto/lhash/CMakeLists.txt
@@ -12,6 +12,8 @@
lhash_test
lhash_test.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(lhash_test crypto)
diff --git a/crypto/modes/CMakeLists.txt b/crypto/modes/CMakeLists.txt
index d50e97b..ffb29b6 100644
--- a/crypto/modes/CMakeLists.txt
+++ b/crypto/modes/CMakeLists.txt
@@ -58,6 +58,8 @@
gcm_test
gcm_test.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(gcm_test crypto)
diff --git a/crypto/pkcs8/CMakeLists.txt b/crypto/pkcs8/CMakeLists.txt
index c0f2746..4426f1e 100644
--- a/crypto/pkcs8/CMakeLists.txt
+++ b/crypto/pkcs8/CMakeLists.txt
@@ -15,6 +15,8 @@
pkcs12_test
pkcs12_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(pkcs12_test crypto)
diff --git a/crypto/rsa/CMakeLists.txt b/crypto/rsa/CMakeLists.txt
index c438e1d..0ea12c8 100644
--- a/crypto/rsa/CMakeLists.txt
+++ b/crypto/rsa/CMakeLists.txt
@@ -16,6 +16,8 @@
rsa_test
rsa_test.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(rsa_test crypto)
diff --git a/crypto/test/CMakeLists.txt b/crypto/test/CMakeLists.txt
index 0d5ca81..84a6174 100644
--- a/crypto/test/CMakeLists.txt
+++ b/crypto/test/CMakeLists.txt
@@ -4,4 +4,5 @@
OBJECT
file_test.cc
+ malloc.cc
)
diff --git a/ssl/test/malloc.cc b/crypto/test/malloc.cc
similarity index 100%
rename from ssl/test/malloc.cc
rename to crypto/test/malloc.cc
diff --git a/crypto/x509/CMakeLists.txt b/crypto/x509/CMakeLists.txt
index 96cf35c..3bb5704 100644
--- a/crypto/x509/CMakeLists.txt
+++ b/crypto/x509/CMakeLists.txt
@@ -59,6 +59,8 @@
pkcs7_test
pkcs7_test.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(pkcs7_test crypto)
diff --git a/crypto/x509v3/CMakeLists.txt b/crypto/x509v3/CMakeLists.txt
index ffa5a4a..c7e6054 100644
--- a/crypto/x509v3/CMakeLists.txt
+++ b/crypto/x509v3/CMakeLists.txt
@@ -47,6 +47,8 @@
v3name_test
v3nametest.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(v3name_test crypto)
@@ -55,6 +57,8 @@
tab_test
tabtest.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(tab_test crypto)
diff --git a/ssl/CMakeLists.txt b/ssl/CMakeLists.txt
index f016046..cf5a29d 100644
--- a/ssl/CMakeLists.txt
+++ b/ssl/CMakeLists.txt
@@ -40,6 +40,8 @@
ssl_test
ssl_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(ssl_test ssl crypto)
diff --git a/ssl/pqueue/CMakeLists.txt b/ssl/pqueue/CMakeLists.txt
index 9f14020..53d2a8b 100644
--- a/ssl/pqueue/CMakeLists.txt
+++ b/ssl/pqueue/CMakeLists.txt
@@ -12,6 +12,8 @@
pqueue_test
pqueue_test.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(pqueue_test ssl crypto)
diff --git a/ssl/test/CMakeLists.txt b/ssl/test/CMakeLists.txt
index a0d7a5e..3b07903 100644
--- a/ssl/test/CMakeLists.txt
+++ b/ssl/test/CMakeLists.txt
@@ -5,9 +5,10 @@
async_bio.cc
bssl_shim.cc
- malloc.cc
packeted_bio.cc
test_config.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(bssl_shim ssl crypto)
diff --git a/util/all_tests.go b/util/all_tests.go
index 5b6dd88..49954df 100644
--- a/util/all_tests.go
+++ b/util/all_tests.go
@@ -22,16 +22,21 @@
"os"
"os/exec"
"path"
+ "strconv"
"strings"
+ "syscall"
"time"
)
// TODO(davidben): Link tests with the malloc shim and port -malloc-test to this runner.
var (
- useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
- buildDir = flag.String("build-dir", "build", "The build directory to run the tests from.")
- jsonOutput = flag.String("json-output", "", "The file to output JSON results to.")
+ useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
+ useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb")
+ buildDir = flag.String("build-dir", "build", "The build directory to run the tests from.")
+ jsonOutput = flag.String("json-output", "", "The file to output JSON results to.")
+ mallocTest = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.")
+ mallocTestDebug = flag.Bool("malloc-test-debug", false, "If true, ask each test to abort rather than fail a malloc. This can be used with a specific value for --malloc-test to identity the malloc failing that is causing problems.")
)
type test []string
@@ -157,25 +162,59 @@
return exec.Command("valgrind", valgrindArgs...)
}
-func runTest(test test) (passed bool, err error) {
+func gdbOf(path string, args ...string) *exec.Cmd {
+ xtermArgs := []string{"-e", "gdb", "--args"}
+ xtermArgs = append(xtermArgs, path)
+ xtermArgs = append(xtermArgs, args...)
+
+ return exec.Command("xterm", xtermArgs...)
+}
+
+type moreMallocsError struct{}
+
+func (moreMallocsError) Error() string {
+ return "child process did not exhaust all allocation calls"
+}
+
+var errMoreMallocs = moreMallocsError{}
+
+func runTestOnce(test test, mallocNumToFail int64) (passed bool, err error) {
prog := path.Join(*buildDir, test[0])
args := test[1:]
var cmd *exec.Cmd
if *useValgrind {
cmd = valgrindOf(false, prog, args...)
+ } else if *useGDB {
+ cmd = gdbOf(prog, args...)
} else {
cmd = exec.Command(prog, args...)
}
var stdoutBuf bytes.Buffer
+ var stderrBuf bytes.Buffer
cmd.Stdout = &stdoutBuf
- cmd.Stderr = os.Stderr
+ cmd.Stderr = &stderrBuf
+ if mallocNumToFail >= 0 {
+ cmd.Env = os.Environ()
+ cmd.Env = append(cmd.Env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10))
+ if *mallocTestDebug {
+ cmd.Env = append(cmd.Env, "MALLOC_ABORT_ON_FAIL=1")
+ }
+ cmd.Env = append(cmd.Env, "_MALLOC_CHECK=1")
+ }
if err := cmd.Start(); err != nil {
return false, err
}
if err := cmd.Wait(); err != nil {
+ if exitError, ok := err.(*exec.ExitError); ok {
+ if exitError.Sys().(syscall.WaitStatus).ExitStatus() == 88 {
+ return false, errMoreMallocs
+ }
+ }
+ fmt.Print(string(stderrBuf.Bytes()))
return false, err
}
+ fmt.Print(string(stderrBuf.Bytes()))
// Account for Windows line-endings.
stdout := bytes.Replace(stdoutBuf.Bytes(), []byte("\r\n"), []byte("\n"), -1)
@@ -187,6 +226,21 @@
return false, nil
}
+func runTest(test test) (bool, error) {
+ if *mallocTest < 0 {
+ return runTestOnce(test, -1)
+ }
+
+ for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ {
+ if passed, err := runTestOnce(test, mallocNumToFail); err != errMoreMallocs {
+ if err != nil {
+ err = fmt.Errorf("at malloc %d: %s", mallocNumToFail, err)
+ }
+ return passed, err
+ }
+ }
+}
+
// shortTestName returns the short name of a test. Except for evp_test, it
// assumes that any argument which ends in .txt is a path to a data file and not
// relevant to the test's uniqueness.