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/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();
+}
+`)
+
+}