diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/all_tests.go | 65 | ||||
-rw-r--r-- | src/util/bot/toolchain_vs2013.hash | 1 | ||||
-rw-r--r-- | src/util/bot/vs_toolchain.py | 15 | ||||
-rw-r--r-- | src/util/doc.go | 14 | ||||
-rw-r--r-- | src/util/generate_build_files.py | 22 |
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()) |