Convert aes_test to GTest. This introduces machinery to start embedding the test data files into the crypto_test binary. Figuring out every CI's test data story is more trouble than is worth it. The GTest FileTest runner is considerably different from the old one: - It returns void and expects failures to use the GTest EXPECT_* and ASSERT_* macros, rather than ExpectBytesEqual. This is more monkey work to convert, but ultimately less work to add new tests. I think it's also valuable for our FileTest and normal test patterns to align as much as possible. The line number is emitted via SCOPED_TRACE. - I've intentionally omitted the Error attribute handling, since that doesn't work very well with the new callback. This means evp_test.cc will take a little more work to convert, but this is again to keep our two test patterns aligned. - The callback takes a std::function rather than a C-style void pointer. This means we can go nuts with lambdas. It also places the path first so clang-format doesn't go nuts. BUG=129 Change-Id: I0d1920a342b00e64043e3ea05f5f5af57bfe77b3 Reviewed-on: https://boringssl-review.googlesource.com/16507 Reviewed-by: Adam Langley <agl@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt index 9abb82b..d5f9ed9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -9,6 +9,8 @@ set(CMAKE_GENERATOR_CC cl) endif() +include(sources.cmake) + enable_language(C) enable_language(CXX) @@ -265,6 +267,15 @@ # themselves as dependencies next to the target definition. add_custom_target(all_tests) +add_custom_command( + OUTPUT crypto_test_data.cc + COMMAND ${GO_EXECUTABLE} run util/embed_test_data.go ${CRYPTO_TEST_DATA} > + ${CMAKE_CURRENT_BINARY_DIR}/crypto_test_data.cc + DEPENDS util/embed_test_data.go ${CRYPTO_TEST_DATA} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(crypto_test_data OBJECT crypto_test_data.cc) + add_subdirectory(crypto) add_subdirectory(ssl) add_subdirectory(ssl/test)
diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index ba6ae07..3a2e802 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt
@@ -251,10 +251,13 @@ dsa/dsa_test.cc err/err_test.cc evp/evp_extra_test.cc + fipsmodule/aes/aes_test.cc fipsmodule/ec/ec_test.cc fipsmodule/rand/ctrdrbg_test.cc + test/file_test_gtest.cc rsa_extra/rsa_test.cc + $<TARGET_OBJECTS:crypto_test_data> $<TARGET_OBJECTS:gtest_main> $<TARGET_OBJECTS:test_support> )
diff --git a/crypto/fipsmodule/CMakeLists.txt b/crypto/fipsmodule/CMakeLists.txt index 4bcaf47..ab95fd6 100644 --- a/crypto/fipsmodule/CMakeLists.txt +++ b/crypto/fipsmodule/CMakeLists.txt
@@ -199,16 +199,6 @@ endif() add_executable( - aes_test - - aes/aes_test.cc - $<TARGET_OBJECTS:test_support> -) - -target_link_libraries(aes_test crypto) -add_dependencies(all_tests aes_test) - -add_executable( bn_test bn/bn_test.cc
diff --git a/crypto/fipsmodule/aes/aes_test.cc b/crypto/fipsmodule/aes/aes_test.cc index e1e9ca6..73ae255 100644 --- a/crypto/fipsmodule/aes/aes_test.cc +++ b/crypto/fipsmodule/aes/aes_test.cc
@@ -18,77 +18,50 @@ #include <memory> #include <vector> +#include <gtest/gtest.h> + #include <openssl/aes.h> -#include <openssl/crypto.h> #include "../../internal.h" #include "../../test/file_test.h" +#include "../../test/test_util.h" -static bool TestRaw(FileTest *t) { +static void TestRaw(FileTest *t) { std::vector<uint8_t> key, plaintext, ciphertext; - if (!t->GetBytes(&key, "Key") || - !t->GetBytes(&plaintext, "Plaintext") || - !t->GetBytes(&ciphertext, "Ciphertext")) { - return false; - } + ASSERT_TRUE(t->GetBytes(&key, "Key")); + ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext")); + ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext")); - if (plaintext.size() != AES_BLOCK_SIZE || - ciphertext.size() != AES_BLOCK_SIZE) { - t->PrintLine("Plaintext or Ciphertext not a block size."); - return false; - } + ASSERT_EQ(static_cast<unsigned>(AES_BLOCK_SIZE), plaintext.size()); + ASSERT_EQ(static_cast<unsigned>(AES_BLOCK_SIZE), ciphertext.size()); AES_KEY aes_key; - if (AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key) != 0) { - t->PrintLine("AES_set_encrypt_key failed."); - return false; - } + ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key)); // Test encryption. uint8_t block[AES_BLOCK_SIZE]; AES_encrypt(plaintext.data(), block, &aes_key); - if (!t->ExpectBytesEqual(block, AES_BLOCK_SIZE, ciphertext.data(), - ciphertext.size())) { - t->PrintLine("AES_encrypt gave the wrong output."); - return false; - } + EXPECT_EQ(Bytes(ciphertext), Bytes(block)); // Test in-place encryption. OPENSSL_memcpy(block, plaintext.data(), AES_BLOCK_SIZE); AES_encrypt(block, block, &aes_key); - if (!t->ExpectBytesEqual(block, AES_BLOCK_SIZE, ciphertext.data(), - ciphertext.size())) { - t->PrintLine("In-place AES_encrypt gave the wrong output."); - return false; - } + EXPECT_EQ(Bytes(ciphertext), Bytes(block)); - if (AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key) != 0) { - t->PrintLine("AES_set_decrypt_key failed."); - return false; - } + ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key)); // Test decryption. AES_decrypt(ciphertext.data(), block, &aes_key); - if (!t->ExpectBytesEqual(block, AES_BLOCK_SIZE, plaintext.data(), - plaintext.size())) { - t->PrintLine("AES_decrypt gave the wrong output."); - return false; - } + EXPECT_EQ(Bytes(plaintext), Bytes(block)); // Test in-place decryption. OPENSSL_memcpy(block, ciphertext.data(), AES_BLOCK_SIZE); AES_decrypt(block, block, &aes_key); - if (!t->ExpectBytesEqual(block, AES_BLOCK_SIZE, plaintext.data(), - plaintext.size())) { - t->PrintLine("In-place AES_decrypt gave the wrong output."); - return false; - } - - return true; + EXPECT_EQ(Bytes(plaintext), Bytes(block)); } -static bool TestKeyWrap(FileTest *t) { +static void TestKeyWrap(FileTest *t) { // All test vectors use the default IV, so test both with implicit and // explicit IV. // @@ -98,93 +71,61 @@ }; std::vector<uint8_t> key, plaintext, ciphertext; - if (!t->GetBytes(&key, "Key") || - !t->GetBytes(&plaintext, "Plaintext") || - !t->GetBytes(&ciphertext, "Ciphertext")) { - return false; - } + ASSERT_TRUE(t->GetBytes(&key, "Key")); + ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext")); + ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext")); - if (plaintext.size() + 8 != ciphertext.size()) { - t->PrintLine("Invalid Plaintext and Ciphertext lengths."); - return false; - } + ASSERT_EQ(plaintext.size() + 8, ciphertext.size()) + << "Invalid Plaintext and Ciphertext lengths."; + // Test encryption. AES_KEY aes_key; - if (AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key) != 0) { - t->PrintLine("AES_set_encrypt_key failed."); - return false; - } + ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key)); + // Test with implicit IV. std::unique_ptr<uint8_t[]> buf(new uint8_t[ciphertext.size()]); - if (AES_wrap_key(&aes_key, nullptr /* iv */, buf.get(), plaintext.data(), - plaintext.size()) != static_cast<int>(ciphertext.size()) || - !t->ExpectBytesEqual(buf.get(), ciphertext.size(), ciphertext.data(), - ciphertext.size())) { - t->PrintLine("AES_wrap_key with implicit IV failed."); - return false; - } + int len = AES_wrap_key(&aes_key, nullptr /* iv */, buf.get(), + plaintext.data(), plaintext.size()); + ASSERT_GE(len, 0); + EXPECT_EQ(Bytes(ciphertext), Bytes(buf.get(), static_cast<size_t>(len))); + // Test with explicit IV. OPENSSL_memset(buf.get(), 0, ciphertext.size()); - if (AES_wrap_key(&aes_key, kDefaultIV, buf.get(), plaintext.data(), - plaintext.size()) != static_cast<int>(ciphertext.size()) || - !t->ExpectBytesEqual(buf.get(), ciphertext.size(), ciphertext.data(), - ciphertext.size())) { - t->PrintLine("AES_wrap_key with explicit IV failed."); - return false; - } + len = AES_wrap_key(&aes_key, kDefaultIV, buf.get(), plaintext.data(), + plaintext.size()); + ASSERT_GE(len, 0); + EXPECT_EQ(Bytes(ciphertext), Bytes(buf.get(), static_cast<size_t>(len))); - if (AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key) != 0) { - t->PrintLine("AES_set_decrypt_key failed."); - return false; - } + // Test decryption. + ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key)); + // Test with implicit IV. buf.reset(new uint8_t[plaintext.size()]); - if (AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(), ciphertext.data(), - ciphertext.size()) != static_cast<int>(plaintext.size()) || - !t->ExpectBytesEqual(buf.get(), plaintext.size(), plaintext.data(), - plaintext.size())) { - t->PrintLine("AES_unwrap_key with implicit IV failed."); - return false; - } + len = AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(), ciphertext.data(), + ciphertext.size()); + ASSERT_GE(len, 0); + EXPECT_EQ(Bytes(plaintext), Bytes(buf.get(), static_cast<size_t>(len))); + // Test with explicit IV. OPENSSL_memset(buf.get(), 0, plaintext.size()); - if (AES_unwrap_key(&aes_key, kDefaultIV, buf.get(), ciphertext.data(), - ciphertext.size()) != static_cast<int>(plaintext.size()) || - !t->ExpectBytesEqual(buf.get(), plaintext.size(), plaintext.data(), - plaintext.size())) { - t->PrintLine("AES_unwrap_key with explicit IV failed."); - return false; - } + len = AES_unwrap_key(&aes_key, kDefaultIV, buf.get(), ciphertext.data(), + ciphertext.size()); + ASSERT_GE(len, 0); + // Test corrupted ciphertext. ciphertext[0] ^= 1; - if (AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(), ciphertext.data(), - ciphertext.size()) != -1) { - t->PrintLine("AES_unwrap_key with bad input unexpectedly succeeded."); - return false; - } - - return true; + EXPECT_EQ(-1, AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(), + ciphertext.data(), ciphertext.size())); } -static bool TestAES(FileTest *t, void *arg) { - if (t->GetParameter() == "Raw") { - return TestRaw(t); - } - if (t->GetParameter() == "KeyWrap") { - return TestKeyWrap(t); - } - - t->PrintLine("Unknown mode '%s'.", t->GetParameter().c_str()); - return false; -} - -int main(int argc, char **argv) { - CRYPTO_library_init(); - - if (argc != 2) { - fprintf(stderr, "%s <test file.txt>\n", argv[0]); - return 1; - } - - return FileTestMain(TestAES, nullptr, argv[1]); +TEST(AESTest, TestVectors) { + FileTestGTest("crypto/fipsmodule/aes/aes_tests.txt", [](FileTest *t) { + if (t->GetParameter() == "Raw") { + TestRaw(t); + } else if (t->GetParameter() == "KeyWrap") { + TestKeyWrap(t); + } else { + ADD_FAILURE() << "Unknown mode " << t->GetParameter(); + } + }); }
diff --git a/crypto/test/file_test.h b/crypto/test/file_test.h index 2c03f90..70629f3 100644 --- a/crypto/test/file_test.h +++ b/crypto/test/file_test.h
@@ -22,6 +22,7 @@ OPENSSL_MSVC_PRAGMA(warning(push)) OPENSSL_MSVC_PRAGMA(warning(disable : 4702)) +#include <functional> #include <map> #include <memory> #include <set> @@ -219,4 +220,8 @@ // FAIL/PASS message to stdout. int FileTestMainSilent(FileTestFunc run_test, void *arg, const char *path); +// FileTestGTest behaves like FileTestMain, but for GTest. |path| must be the +// name of a test file embedded in the test binary. +void FileTestGTest(const char *path, std::function<void(FileTest *)> run_test); + #endif /* OPENSSL_HEADER_CRYPTO_TEST_FILE_TEST_H */
diff --git a/crypto/test/file_test_gtest.cc b/crypto/test/file_test_gtest.cc new file mode 100644 index 0000000..90d12bf --- /dev/null +++ b/crypto/test/file_test_gtest.cc
@@ -0,0 +1,85 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "file_test.h" + +#include <assert.h> +#include <string.h> + +#include <memory> +#include <string> +#include <utility> + +#include <gtest/gtest.h> + + +std::string GetTestData(const char *path); + +class StringLineReader : public FileTest::LineReader { + public: + explicit StringLineReader(const std::string &data) + : data_(data), offset_(0) {} + + FileTest::ReadResult ReadLine(char *out, size_t len) override { + assert(len > 0); + if (offset_ == data_.size()) { + return FileTest::kReadEOF; + } + + size_t idx = data_.find('\n', offset_); + if (idx == std::string::npos) { + idx = data_.size(); + } else { + idx++; // Include the newline. + } + + if (idx - offset_ > len - 1) { + ADD_FAILURE() << "Line too long."; + return FileTest::kReadError; + } + + memcpy(out, data_.data() + offset_, idx - offset_); + out[idx - offset_] = '\0'; + offset_ = idx; + return FileTest::kReadSuccess; + } + + private: + std::string data_; + size_t offset_; + + StringLineReader(const StringLineReader &) = delete; + StringLineReader &operator=(const StringLineReader &) = delete; +}; + +void FileTestGTest(const char *path, std::function<void(FileTest *)> run_test) { + std::unique_ptr<StringLineReader> reader( + new StringLineReader(GetTestData(path))); + FileTest t(std::move(reader)); + + while (true) { + switch (t.ReadNext()) { + case FileTest::kReadError: + ADD_FAILURE() << "Error reading test."; + return; + case FileTest::kReadEOF: + return; + case FileTest::kReadSuccess: + break; + } + + SCOPED_TRACE(testing::Message() << path << ", line " << t.start_line()); + run_test(&t); + } +}
diff --git a/crypto/test/test_util.h b/crypto/test/test_util.h index e03bff4..3bf41ab 100644 --- a/crypto/test/test_util.h +++ b/crypto/test/test_util.h
@@ -22,6 +22,7 @@ #include <iosfwd> #include <string> +#include <vector> #include "../internal.h" @@ -42,6 +43,8 @@ : data(reinterpret_cast<const uint8_t *>(str)), len(strlen(str)) {} explicit Bytes(const std::string &str) : data(reinterpret_cast<const uint8_t *>(str.data())), len(str.size()) {} + explicit Bytes(const std::vector<uint8_t> &vec) + : data(vec.data()), len(vec.size()) {} template <size_t N> explicit Bytes(const uint8_t (&array)[N]) : data(array), len(N) {}
diff --git a/sources.cmake b/sources.cmake new file mode 100644 index 0000000..185e961 --- /dev/null +++ b/sources.cmake
@@ -0,0 +1,10 @@ +# This file contains source lists that are also consumed by +# generate_build_files.py. +# +# TODO(davidben): Move the other source lists into this file. + +set( + CRYPTO_TEST_DATA + + crypto/fipsmodule/aes/aes_tests.txt +)
diff --git a/util/all_tests.json b/util/all_tests.json index 49cb428..f926d07 100644 --- a/util/all_tests.json +++ b/util/all_tests.json
@@ -36,7 +36,6 @@ ["crypto/ecdh/ecdh_test", "crypto/ecdh/ecdh_tests.txt"], ["crypto/evp/evp_test", "crypto/evp/evp_tests.txt"], ["crypto/evp/pbkdf_test"], - ["crypto/fipsmodule/aes_test", "crypto/fipsmodule/aes/aes_tests.txt"], ["crypto/fipsmodule/bn_test", "crypto/fipsmodule/bn/bn_tests.txt"], ["crypto/fipsmodule/ctrdrbg_vector_test", "crypto/fipsmodule/rand/ctrdrbg_vectors.txt"], ["crypto/fipsmodule/ecdsa_sign_test", "crypto/fipsmodule/ecdsa/ecdsa_sign_tests.txt"],
diff --git a/util/embed_test_data.go b/util/embed_test_data.go new file mode 100644 index 0000000..0819530 --- /dev/null +++ b/util/embed_test_data.go
@@ -0,0 +1,140 @@ +// Copyright (c) 2017, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// embed_test_data generates a C++ source file which exports a function, +// GetTestData, which looks up the specified data files. +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "unicode" +) + +func quote(in []byte) string { + var buf bytes.Buffer + buf.WriteByte('"') + for _, b := range in { + switch b { + case '\a': + buf.WriteString(`\a`) + case '\b': + buf.WriteString(`\b`) + case '\f': + buf.WriteString(`\f`) + case '\n': + buf.WriteString(`\n`) + case '\r': + buf.WriteString(`\r`) + case '\t': + buf.WriteString(`\t`) + case '\v': + buf.WriteString(`\v`) + case '"': + buf.WriteString(`\"`) + default: + if unicode.IsPrint(rune(b)) { + buf.WriteByte(b) + } else { + fmt.Fprintf(&buf, "\\x%02x", b) + } + } + } + buf.WriteByte('"') + return buf.String() +} + +func main() { + fmt.Printf(`/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This file is generated by: +`) + fmt.Printf(" * go run util/embed_test_data.go") + for _, arg := range os.Args[1:] { + fmt.Printf(" \\\n * %s", arg) + } + fmt.Printf(" */\n") + + fmt.Printf(` +#include <stdlib.h> +#include <string.h> + +#include <algorithm> +#include <string> + + +`) + + // MSVC limits the length of string constants, so we emit an array of + // them and concatenate at runtime. We could also use a single array + // literal, but this is less compact. + const chunkSize = 8192 + + for i, arg := range os.Args[1:] { + data, err := ioutil.ReadFile(arg) + if err != nil { + fmt.Fprintf(os.Stderr, "Error reading %s: %s.\n", data, err) + os.Exit(1) + } + fmt.Printf("static const char *kData%d[] = {\n", i) + for i := 0; i < len(data); i += chunkSize { + chunk := chunkSize + if chunk > len(data)-i { + chunk = len(data) - i + } + fmt.Printf(" %s,\n", quote(data[i:i+chunk])) + } + fmt.Printf("};\n") + fmt.Printf("static const size_t kLen%d = %d;\n\n", i, len(data)) + } + + fmt.Printf(`static std::string AssembleString(const char **data, size_t len) { + std::string ret; + for (size_t i = 0; i < len; i += %d) { + size_t chunk = std::min(static_cast<size_t>(%d), len - i); + ret.append(data[i / %d], chunk); + } + return ret; +} + +/* Silence -Wmissing-declarations. */ +std::string GetTestData(const char *path); + +std::string GetTestData(const char *path) { +`, chunkSize, chunkSize, chunkSize) + for i, arg := range os.Args[1:] { + fmt.Printf(" if (strcmp(path, %s) == 0) {\n", quote([]byte(arg))) + fmt.Printf(" return AssembleString(kData%d, kLen%d);\n", i, i) + fmt.Printf(" }\n") + } + fmt.Printf(` fprintf(stderr, "File not embedded: %%s.\n", path); + abort(); +} +`) + +}
diff --git a/util/generate_build_files.py b/util/generate_build_files.py index a10d275..0b1be0b 100644 --- a/util/generate_build_files.py +++ b/util/generate_build_files.py
@@ -486,8 +486,8 @@ return not is_dir or dent != 'runner' -def NotGTestMain(path, dent, is_dir): - return dent != 'gtest_main.cc' +def NotGTestSupport(path, dent, is_dir): + return 'gtest' not in dent def SSLHeaderFiles(path, dent, is_dir): @@ -630,12 +630,42 @@ return asmfiles +def ExtractVariablesFromCMakeFile(cmakefile): + """Parses the contents of the CMakeLists.txt file passed as an argument and + returns a dictionary of exported source lists.""" + variables = {} + in_set_command = False + set_command = [] + with open(cmakefile) as f: + for line in f: + if '#' in line: + line = line[:line.index('#')] + line = line.strip() + + if not in_set_command: + if line.startswith('set('): + in_set_command = True + set_command = [] + elif line == ')': + in_set_command = False + if not set_command: + raise ValueError('Empty set command') + variables[set_command[0]] = set_command[1:] + else: + set_command.extend([c for c in line.split(' ') if c]) + + if in_set_command: + raise ValueError('Unfinished set command') + return variables + + def IsGTest(path): with open(path) as f: return "#include <gtest/gtest.h>" in f.read() def main(platforms): + cmake = ExtractVariablesFromCMakeFile(os.path.join('src', 'sources.cmake')) crypto_c_files = FindCFiles(os.path.join('src', 'crypto'), NoTestsNorFIPSFragments) fips_fragments = FindCFiles(os.path.join('src', 'crypto', 'fipsmodule'), OnlyFIPSFragments) ssl_source_files = FindCFiles(os.path.join('src', 'ssl'), NoTests) @@ -650,13 +680,24 @@ crypto_c_files.append('err_data.c') test_support_c_files = FindCFiles(os.path.join('src', 'crypto', 'test'), - NotGTestMain) + NotGTestSupport) test_support_h_files = ( FindHeaderFiles(os.path.join('src', 'crypto', 'test'), AllFiles) + FindHeaderFiles(os.path.join('src', 'ssl', 'test'), NoTestRunnerFiles)) + # Generate crypto_test_data.cc + with open('crypto_test_data.cc', 'w+') as out: + subprocess.check_call( + ['go', 'run', 'util/embed_test_data.go'] + cmake['CRYPTO_TEST_DATA'], + cwd='src', + stdout=out) + test_c_files = [] - crypto_test_files = ['src/crypto/test/gtest_main.cc'] + crypto_test_files = [ + 'crypto_test_data.cc', + 'src/crypto/test/file_test_gtest.cc', + 'src/crypto/test/gtest_main.cc', + ] # TODO(davidben): Remove this loop once all tests are converted. for path in FindCFiles(os.path.join('src', 'crypto'), OnlyTests): if IsGTest(path):