var (
cppData, javaData, outData string
- fuzz, superFuzz bool
+ fuzz bool
fuzzFields, fuzzObjects int
)
func init() {
flag.StringVar(&cppData, "cpp_data", "",
- "location of monsterdata_test.bin")
+ "location of monsterdata_test.bin to verify against (required)")
flag.StringVar(&javaData, "java_data", "",
- "location of monsterdata_java_wire.bin")
+ "location of monsterdata_java_wire.bin to verify against (optional)")
flag.StringVar(&outData, "out_data", "",
"location to write generated Go data")
flag.BoolVar(&fuzz, "fuzz", false, "perform fuzzing")
- flag.BoolVar(&superFuzz, "super_fuzz", false,
- "perform fuzzing of 0..fuzz_fields fields")
flag.IntVar(&fuzzFields, "fuzz_fields", 4, "fields per fuzzer object")
flag.IntVar(&fuzzObjects, "fuzz_objects", 10000,
"number of fuzzer objects (higher is slower and more thorough")
flag.Parse()
+
if cppData == "" {
fmt.Fprintf(os.Stderr, "cpp_data argument is required\n")
os.Exit(1)
}
- if javaData == "" {
- fmt.Fprintf(os.Stderr, "java_data argument is required\n")
- os.Exit(1)
- }
}
-// Store specific byte patterns in these variables for the fuzzer.
+// Store specific byte patterns in these variables for the fuzzer. These
+// values are taken verbatim from the C++ function FuzzTest1.
var (
overflowingInt32Val = flatbuffers.GetInt32([]byte{0x83, 0x33, 0x33, 0x33})
overflowingInt64Val = flatbuffers.GetInt64([]byte{0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44})
// TestAll runs all checks, failing if any errors occur.
func TestAll(t *testing.T) {
+ // Verify that the Go FlatBuffers runtime library generates the
+ // expected bytes (does not use any schema):
+ CheckByteLayout(t.Fatalf)
+
+ // Verify that using the generated Go code builds a buffer without
+ // returning errors:
+ generated, off := CheckGeneratedBuild(t.Fatalf)
+
+ // Verify that the buffer generated by Go code is readable by the
+ // generated Go code:
+ CheckReadBuffer(generated, off, t.Fatalf)
+
+ // Verify that the buffer generated by C++ code is readable by the
+ // generated Go code:
monsterDataCpp, err := ioutil.ReadFile(cppData)
if err != nil {
t.Fatal(err)
}
+ CheckReadBuffer(monsterDataCpp, 0, t.Fatalf)
- monsterDataJava, err := ioutil.ReadFile(javaData)
- if err != nil {
- t.Fatalf("run the java test once to generate javaData\n%s", err)
- }
-
- // FIXME: this test is brittle and not maintainable when the test schema changes
- CheckByteLayout(t.Fatalf)
-
- manual, off0 := CheckManualBuild(t.Fatalf)
- helped, off1 := CheckGeneratedBuild(t.Fatalf)
-
- CheckEquality(manual[off0:], monsterDataJava, "manually", t.Fatalf)
- CheckEquality(helped[off1:], monsterDataJava, "helper", t.Fatalf)
+ // Verify that vtables are deduplicated when written:
CheckVtableDeduplication(t.Fatalf)
- CheckInterpretBuffer(monsterDataCpp, 0, t.Fatalf)
- CheckInterpretBuffer(monsterDataJava, 0, t.Fatalf)
-
- CheckDocExample(manual, off0, t.Fatalf)
-
- if superFuzz {
- for i := 0; i <= fuzzFields; i++ {
- checkFuzz(i, fuzzObjects, t.Fatalf)
+ // Verify that the Go code used in FlatBuffers documentation passes
+ // some sanity checks:
+ CheckDocExample(generated, off, t.Fatalf)
+
+ // If the filename of the FlatBuffers file generated by the Java test
+ // is given, check that Go code can read it, and that Go code
+ // generates an identical buffer when used to create the example data:
+ if javaData != "" {
+ monsterDataJava, err := ioutil.ReadFile(javaData)
+ if err != nil {
+ t.Fatal(err)
}
- } else if fuzz {
+ CheckReadBuffer(monsterDataJava, 0, t.Fatalf)
+ CheckByteEquality(generated[off:], monsterDataJava, t.Fatalf)
+ }
+
+ // Verify that various fuzzing scenarios produce a valid FlatBuffer.
+ if fuzz {
checkFuzz(fuzzFields, fuzzObjects, t.Fatalf)
}
- err = ioutil.WriteFile(outData, helped[off1:], os.FileMode(0644))
+ // Write the generated buffer out to a file:
+ err = ioutil.WriteFile(outData, generated[off:], os.FileMode(0644))
if err != nil {
t.Fatal(err)
}
}
-// CheckInterpretBuffer checks that the given buffer is evaluated correctly
+// CheckReadBuffer checks that the given buffer is evaluated correctly
// as the example Monster.
-func CheckInterpretBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
+func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
monster := example.GetRootAsMonster(buf, offset)
if got := monster.Hp(); 80 != got {
return n
}
-// CheckEquality verifies that two byte buffers are the same.
-func CheckEquality(a, b []byte, msg string, fail func(string, ...interface{})) {
+// CheckByteEquality verifies that two byte buffers are the same.
+func CheckByteEquality(a, b []byte, fail func(string, ...interface{})) {
if !bytes.Equal(a, b) {
- fail("%s constructed object does not pass byte equality", msg)
+ fail("objects are not byte-wise equal")
}
}