summaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/all_tests.go65
-rw-r--r--src/util/bot/toolchain_vs2013.hash1
-rw-r--r--src/util/bot/vs_toolchain.py15
-rw-r--r--src/util/doc.go14
-rw-r--r--src/util/generate_build_files.py22
5 files changed, 98 insertions, 19 deletions
diff --git a/src/util/all_tests.go b/src/util/all_tests.go
index 91822d1..49954df 100644
--- a/src/util/all_tests.go
+++ b/src/util/all_tests.go
@@ -22,16 +22,21 @@ import (
"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
@@ -83,6 +88,7 @@ var tests = []test{
{"crypto/lhash/lhash_test"},
{"crypto/modes/gcm_test"},
{"crypto/pkcs8/pkcs12_test"},
+ {"crypto/refcount_test"},
{"crypto/rsa/rsa_test"},
{"crypto/thread_test"},
{"crypto/x509/pkcs7_test"},
@@ -156,25 +162,59 @@ func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd {
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)
@@ -186,6 +226,21 @@ func runTest(test test) (passed bool, err error) {
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.
diff --git a/src/util/bot/toolchain_vs2013.hash b/src/util/bot/toolchain_vs2013.hash
deleted file mode 100644
index 4ed8816..0000000
--- a/src/util/bot/toolchain_vs2013.hash
+++ /dev/null
@@ -1 +0,0 @@
-ee7d718ec60c2dc5d255bbe325909c2021a7efef
diff --git a/src/util/bot/vs_toolchain.py b/src/util/bot/vs_toolchain.py
index fd76f39..2a54b9e 100644
--- a/src/util/bot/vs_toolchain.py
+++ b/src/util/bot/vs_toolchain.py
@@ -34,8 +34,9 @@ def SetEnvironmentAndGetRuntimeDllDirs():
toolchain = toolchain_data['path']
version = toolchain_data['version']
- version_is_pro = version[-1] != 'e'
- win8sdk = toolchain_data['win8sdk']
+ win_sdk = toolchain_data.get('win_sdk')
+ if not win_sdk:
+ win_sdk = toolchain_data['win8sdk']
wdk = toolchain_data['wdk']
# TODO(scottmg): The order unfortunately matters in these. They should be
# split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call
@@ -49,10 +50,10 @@ def SetEnvironmentAndGetRuntimeDllDirs():
# otheroptions.express
# values there.
gyp_defines_dict = gyp.NameValueListToDict(gyp.ShlexEnv('GYP_DEFINES'))
- gyp_defines_dict['windows_sdk_path'] = win8sdk
+ gyp_defines_dict['windows_sdk_path'] = win_sdk
os.environ['GYP_DEFINES'] = ' '.join('%s=%s' % (k, pipes.quote(str(v)))
for k, v in gyp_defines_dict.iteritems())
- os.environ['WINDOWSSDKDIR'] = win8sdk
+ os.environ['WINDOWSSDKDIR'] = win_sdk
os.environ['WDK_DIR'] = wdk
# Include the VS runtime in the PATH in case it's not machine-installed.
runtime_path = ';'.join(vs2013_runtime_dll_dirs)
@@ -63,9 +64,8 @@ def SetEnvironmentAndGetRuntimeDllDirs():
def _GetDesiredVsToolchainHashes():
"""Load a list of SHA1s corresponding to the toolchains that we want installed
to build with."""
- sha1path = os.path.join(script_dir, 'toolchain_vs2013.hash')
- with open(sha1path, 'rb') as f:
- return f.read().strip().splitlines()
+ # Use Chromium's VS2013.
+ return ['ee7d718ec60c2dc5d255bbe325909c2021a7efef']
def FindDepotTools():
@@ -85,7 +85,6 @@ def Update():
bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain:
depot_tools_path = FindDepotTools()
- json_data_file = os.path.join(script_dir, 'win_toolchain.json')
get_toolchain_args = [
sys.executable,
os.path.join(depot_tools_path,
diff --git a/src/util/doc.go b/src/util/doc.go
index 20feae5..540d6ca 100644
--- a/src/util/doc.go
+++ b/src/util/doc.go
@@ -209,12 +209,24 @@ func skipLine(s string) string {
}
func getNameFromDecl(decl string) (string, bool) {
- for strings.HasPrefix(decl, "#if") {
+ for strings.HasPrefix(decl, "#if") || strings.HasPrefix(decl, "#elif") {
decl = skipLine(decl)
}
if strings.HasPrefix(decl, "struct ") {
return "", false
}
+ if strings.HasPrefix(decl, "#define ") {
+ // This is a preprocessor #define. The name is the next symbol.
+ decl = strings.TrimPrefix(decl, "#define ")
+ for len(decl) > 0 && decl[0] == ' ' {
+ decl = decl[1:]
+ }
+ i := strings.IndexAny(decl, "( ")
+ if i < 0 {
+ return "", false
+ }
+ return decl[:i], true
+ }
decl = skipPast(decl, "STACK_OF(")
decl = skipPast(decl, "LHASH_OF(")
i := strings.Index(decl, "(")
diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py
index 94de546..e534a56 100644
--- a/src/util/generate_build_files.py
+++ b/src/util/generate_build_files.py
@@ -90,6 +90,7 @@ class Chromium(object):
],
'sources': [
'%s',
+ '<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
@@ -99,9 +100,12 @@ class Chromium(object):
test_names.sort()
- test_gypi.write(""" ],
- 'variables': {
- 'boringssl_test_targets': [\n""")
+ test_gypi.write(' ],\n \'variables\': {\n')
+
+ self.PrintVariableSection(
+ test_gypi, 'boringssl_test_support_sources', files['test_support'])
+
+ test_gypi.write(' \'boringssl_test_targets\': [\n')
for test in test_names:
test_gypi.write(""" '%s',\n""" % test)
@@ -174,10 +178,16 @@ def OnlyTests(dent, is_dir):
"""Filter function that can be passed to FindCFiles in order to remove
non-test sources."""
if is_dir:
- return True
+ return dent != 'test'
return '_test.' in dent or dent.startswith('example_')
+def AllFiles(dent, is_dir):
+ """Filter function that can be passed to FindCFiles in order to include all
+ sources."""
+ return True
+
+
def FindCFiles(directory, filter_func):
"""Recurses through directory and returns a list of paths to all the C source
files that pass filter_func."""
@@ -304,6 +314,9 @@ def main(platform):
stdout=err_data)
crypto_c_files.append('err_data.c')
+ test_support_cc_files = FindCFiles(os.path.join('src', 'crypto', 'test'),
+ AllFiles)
+
test_c_files = FindCFiles(os.path.join('src', 'crypto'), OnlyTests)
test_c_files += FindCFiles(os.path.join('src', 'ssl'), OnlyTests)
@@ -312,6 +325,7 @@ def main(platform):
'ssl': ssl_c_files,
'tool': tool_cc_files,
'test': test_c_files,
+ 'test_support': test_support_cc_files,
}
asm_outputs = sorted(WriteAsmFiles(ReadPerlAsmOperations()).iteritems())