From 3d0b335b0fa5fcde7562a6c4c8c4ae84e70a81f0 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Fri, 22 May 2026 22:22:13 -0400 Subject: [PATCH 1/4] GODRIVER-3868 Update extended bson cases. --- bson/benchmark_test.go | 116 +++++++++++++---------- internal/cmd/benchmark/benchmark_test.go | 52 +++++++++- testdata/extended_bson/deep_bson.json.gz | Bin 616 -> 0 bytes testdata/extended_bson/flat_bson.json.gz | Bin 5078 -> 0 bytes testdata/extended_bson/full_bson.json.gz | Bin 3345 -> 0 bytes 5 files changed, 118 insertions(+), 50 deletions(-) delete mode 100644 testdata/extended_bson/deep_bson.json.gz delete mode 100644 testdata/extended_bson/flat_bson.json.gz delete mode 100644 testdata/extended_bson/full_bson.json.gz diff --git a/bson/benchmark_test.go b/bson/benchmark_test.go index 991714eb65..ebb437f96d 100644 --- a/bson/benchmark_test.go +++ b/bson/benchmark_test.go @@ -7,14 +7,14 @@ package bson import ( + "archive/tar" "bytes" "compress/gzip" "encoding/json" + "errors" "fmt" "io" - "io/ioutil" "os" - "path" "sync" "testing" ) @@ -144,54 +144,74 @@ var nestedInstance = nestedtest1{ }, } -const extendedBSONDir = "../testdata/extended_bson" +const extendedBSONTGZ = "../testdata/specifications/source/benchmarking/data/extended_bson.tgz" var ( extJSONFiles map[string]map[string]any extJSONFilesMu sync.Mutex ) -// readExtJSONFile reads the GZIP-compressed extended JSON document from the given filename in the -// "extended BSON" test data directory (../testdata/extended_bson) and returns it as a -// map[string]any. It panics on any errors. -func readExtJSONFile(filename string) map[string]any { +// readExtJSONFile reads the named JSON file from the extended_bson.tgz archive and returns it as a +// map[string]any. The first call decompresses the archive and caches all entries; subsequent calls +// only look up the cache. It calls b.Fatal on any errors. +func readExtJSONFile(b *testing.B, filename string) map[string]any { + b.Helper() extJSONFilesMu.Lock() defer extJSONFilesMu.Unlock() - if v, ok := extJSONFiles[filename]; ok { - return v - } - filePath := path.Join(extendedBSONDir, filename) - file, err := os.Open(filePath) - if err != nil { - panic(fmt.Sprintf("error opening file %q: %s", filePath, err)) - } - defer func() { - _ = file.Close() - }() - gz, err := gzip.NewReader(file) - if err != nil { - panic(fmt.Sprintf("error creating GZIP reader: %s", err)) - } - defer func() { - _ = gz.Close() - }() + if extJSONFiles == nil { + file, err := os.Open(extendedBSONTGZ) + if err != nil { + b.Fatalf("error opening %q: %s", extendedBSONTGZ, err) + return nil + } + defer func() { + _ = file.Close() + }() + + gz, err := gzip.NewReader(file) + if err != nil { + b.Fatalf("error creating gzip reader: %s", err) + return nil + } + defer func() { + _ = gz.Close() + }() - data, err := ioutil.ReadAll(gz) - if err != nil { - panic(fmt.Sprintf("error reading GZIP contents of file: %s", err)) - } + extJSONFiles = make(map[string]map[string]any) - var v map[string]any - err = UnmarshalExtJSON(data, false, &v) - if err != nil { - panic(fmt.Sprintf("error unmarshalling extended JSON: %s", err)) + tr := tar.NewReader(gz) + for { + hdr, err := tr.Next() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + b.Fatalf("error reading tar: %s", err) + return nil + } + if hdr.Typeflag != tar.TypeReg { + continue + } + data, err := io.ReadAll(tr) + if err != nil { + b.Fatalf("error reading tar entry %q: %s", hdr.Name, err) + return nil + } + var v map[string]any + if err = UnmarshalExtJSON(data, false, &v); err != nil { + b.Fatalf("error unmarshalling %q: %s", hdr.Name, err) + return nil + } + extJSONFiles[hdr.Name] = v + } } - if extJSONFiles == nil { - extJSONFiles = make(map[string]map[string]any) + v, ok := extJSONFiles["extended_bson/"+filename] + if !ok { + b.Fatalf("file %q not found in %q", filename, extendedBSONTGZ) + return nil } - extJSONFiles[filename] = v return v } @@ -213,16 +233,16 @@ func BenchmarkMarshal(b *testing.B) { value: encodetestBsonD, }, { - desc: "deep_bson.json.gz", - value: readExtJSONFile("deep_bson.json.gz"), + desc: "deep_bson.json", + value: readExtJSONFile(b, "deep_bson.json"), }, { - desc: "flat_bson.json.gz", - value: readExtJSONFile("flat_bson.json.gz"), + desc: "flat_bson.json", + value: readExtJSONFile(b, "flat_bson.json"), }, { - desc: "full_bson.json.gz", - value: readExtJSONFile("full_bson.json.gz"), + desc: "full_bson.json", + value: readExtJSONFile(b, "full_bson.json"), }, } @@ -314,16 +334,16 @@ func BenchmarkUnmarshal(b *testing.B) { value: nestedInstance, }, { - name: "deep_bson.json.gz", - value: readExtJSONFile("deep_bson.json.gz"), + name: "deep_bson.json", + value: readExtJSONFile(b, "deep_bson.json"), }, { - name: "flat_bson.json.gz", - value: readExtJSONFile("flat_bson.json.gz"), + name: "flat_bson.json", + value: readExtJSONFile(b, "flat_bson.json"), }, { - name: "full_bson.json.gz", - value: readExtJSONFile("full_bson.json.gz"), + name: "full_bson.json", + value: readExtJSONFile(b, "full_bson.json"), }, } diff --git a/internal/cmd/benchmark/benchmark_test.go b/internal/cmd/benchmark/benchmark_test.go index 3e0ba80dce..cfd6d40b7d 100644 --- a/internal/cmd/benchmark/benchmark_test.go +++ b/internal/cmd/benchmark/benchmark_test.go @@ -209,8 +209,56 @@ func loadSourceDocument(b *testing.B, canonicalOnly bool, pathParts ...string) b return doc } +func loadBSONExtJSONFile(b *testing.B, canonicalOnly bool, source string) bson.D { + b.Helper() + + tgzPath := filepath.Join(testdataDir(b), "specifications", "source", "benchmarking", "data", "extended_bson.tgz") + + file, err := os.Open(tgzPath) + require.NoError(b, err, "failed to open %q", tgzPath) + defer file.Close() + + gz, err := gzip.NewReader(file) + require.NoError(b, err, "failed to create gzip reader") + defer gz.Close() + + tr := tar.NewReader(gz) + for { + hdr, err := tr.Next() + if errors.Is(err, io.EOF) { + break + } + + require.NoError(b, err, "failed to read tar") + + if hdr.Typeflag != tar.TypeReg { + continue + } + + if hdr.Name != bsonDataDir+"/"+source { + continue + } + + data, err := io.ReadAll(tr) + require.NoError(b, err, "failed to read tar entry %q", hdr.Name) + + var doc bson.D + + err = bson.UnmarshalExtJSON(data, canonicalOnly, &doc) + require.NoError(b, err, "failed to unmarshal extended JSON from %q", hdr.Name) + + require.NotEmpty(b, doc) + + return doc + } + + b.Fatalf("file %q not found in %q", bsonDataDir+"/"+source, tgzPath) + + return nil +} + func benchmarkBSONEncoding(b *testing.B, canonicalOnly bool, source string) { - doc := loadSourceDocument(b, canonicalOnly, testdataPerfDir(b), bsonDataDir, source) + doc := loadBSONExtJSONFile(b, canonicalOnly, source) b.ResetTimer() @@ -229,7 +277,7 @@ func benchmarkBSONEncoding(b *testing.B, canonicalOnly bool, source string) { } func benchmarkBSONDecoding(b *testing.B, canonicalOnly bool, source string) { - doc := loadSourceDocument(b, canonicalOnly, testdataPerfDir(b), bsonDataDir, source) + doc := loadBSONExtJSONFile(b, canonicalOnly, source) raw, err := bson.Marshal(doc) require.NoError(b, err, "failed to encode bson data") diff --git a/testdata/extended_bson/deep_bson.json.gz b/testdata/extended_bson/deep_bson.json.gz deleted file mode 100644 index e2588ef533a525d215b0dd604e087565f68fb53d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 616 zcmV-u0+;zAqc9kS_kD^I>pns67-Is4 zUcU0BbEAWp!yrLC4s^*SaZ&Cpf-x5w557+EWBG^;hd~n?3+(5NJ zIedtdRhzRsIGaAhu=j6|C0;ZVX?D<0I^bVwvQQVPyYSSs2ut8xMqglf;|u70$DFB} zUkxZLnSC5~ueOMvwSfwI=PTKeSxddn!kUc|^<|od8jL4J`n%N6AHM;Afz-dO2LJ$6 Ccq|nF diff --git a/testdata/extended_bson/flat_bson.json.gz b/testdata/extended_bson/flat_bson.json.gz deleted file mode 100644 index 124148bf67162d2a58f75312a92121a8aa304230..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5078 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 b&|k&j3SE!K Date: Mon, 1 Jun 2026 23:18:28 -0400 Subject: [PATCH 2/4] rewrite with sync.Once --- bson/benchmark_test.go | 141 ++++++++++++++++++++++------------------- 1 file changed, 75 insertions(+), 66 deletions(-) diff --git a/bson/benchmark_test.go b/bson/benchmark_test.go index ebb437f96d..0f4f887839 100644 --- a/bson/benchmark_test.go +++ b/bson/benchmark_test.go @@ -17,6 +17,8 @@ import ( "os" "sync" "testing" + + "go.mongodb.org/mongo-driver/v2/internal/require" ) var encodetestBsonD D @@ -144,76 +146,83 @@ var nestedInstance = nestedtest1{ }, } -const extendedBSONTGZ = "../testdata/specifications/source/benchmarking/data/extended_bson.tgz" +// loadExtendedBSON is a function that returns the extended BSON data for a given filename in the +// extended_bson.tgz archive. The first call to loadExtendedBSON will decompress all the JSON files +// in the archive and cache all entries; subsequent calls will only return the cache. Caller must +// not mutate the returned value. +var loadExtendedBSON = func() func(tb testing.TB, filename string) map[string]any { + const extendedBSONTGZ = "../testdata/specifications/source/benchmarking/data/extended_bson.tgz" -var ( - extJSONFiles map[string]map[string]any - extJSONFilesMu sync.Mutex -) + var once sync.Once + var onceErr error + entryErr := make(map[string]error) + results := make(map[string]map[string]any) -// readExtJSONFile reads the named JSON file from the extended_bson.tgz archive and returns it as a -// map[string]any. The first call decompresses the archive and caches all entries; subsequent calls -// only look up the cache. It calls b.Fatal on any errors. -func readExtJSONFile(b *testing.B, filename string) map[string]any { - b.Helper() - extJSONFilesMu.Lock() - defer extJSONFilesMu.Unlock() - - if extJSONFiles == nil { - file, err := os.Open(extendedBSONTGZ) - if err != nil { - b.Fatalf("error opening %q: %s", extendedBSONTGZ, err) - return nil - } - defer func() { - _ = file.Close() - }() - - gz, err := gzip.NewReader(file) - if err != nil { - b.Fatalf("error creating gzip reader: %s", err) - return nil - } - defer func() { - _ = gz.Close() - }() - - extJSONFiles = make(map[string]map[string]any) + return func(tb testing.TB, filename string) map[string]any { + tb.Helper() - tr := tar.NewReader(gz) - for { - hdr, err := tr.Next() - if errors.Is(err, io.EOF) { - break - } + once.Do(func() { + file, err := os.Open(extendedBSONTGZ) if err != nil { - b.Fatalf("error reading tar: %s", err) - return nil - } - if hdr.Typeflag != tar.TypeReg { - continue + onceErr = fmt.Errorf("error opening %q: %v", extendedBSONTGZ, err) + return } - data, err := io.ReadAll(tr) + defer func() { + _ = file.Close() + }() + + gz, err := gzip.NewReader(file) if err != nil { - b.Fatalf("error reading tar entry %q: %s", hdr.Name, err) - return nil + onceErr = fmt.Errorf("error creating gzip reader: %v", err) + return + } + defer func() { + _ = gz.Close() + }() + + tr := tar.NewReader(gz) + for { + hdr, err := tr.Next() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + onceErr = fmt.Errorf("error reading tar header: %v", err) + return + } + if hdr.Typeflag != tar.TypeReg { + continue + } + data, err := io.ReadAll(tr) + if err != nil { + entryErr[hdr.Name] = fmt.Errorf("error reading tar entry: %v", err) + continue + } + + var v map[string]any + err = UnmarshalExtJSON(data, false, &v) + if err != nil { + entryErr[hdr.Name] = fmt.Errorf("error unmarshalling: %v", err) + continue + } + results[hdr.Name] = v } - var v map[string]any - if err = UnmarshalExtJSON(data, false, &v); err != nil { - b.Fatalf("error unmarshalling %q: %s", hdr.Name, err) - return nil + }) + entry := "extended_bson/" + filename + if err, ok := entryErr[entry]; ok { + require.FailNowf(tb, "failed to load benchmark data", "error loading file %q from %q: %v", filename, extendedBSONTGZ, err) + } + v, ok := results[entry] + if !ok { + if onceErr != nil { + require.FailNowf(tb, "failed to load benchmark data", "error loading file %q from %q: %v", filename, extendedBSONTGZ, onceErr) + } else { + require.FailNowf(tb, "failed to load benchmark data", "error loading file %q from %q: not found", filename, extendedBSONTGZ) } - extJSONFiles[hdr.Name] = v } + return v } - - v, ok := extJSONFiles["extended_bson/"+filename] - if !ok { - b.Fatalf("file %q not found in %q", filename, extendedBSONTGZ) - return nil - } - return v -} +}() func BenchmarkMarshal(b *testing.B) { cases := []struct { @@ -234,15 +243,15 @@ func BenchmarkMarshal(b *testing.B) { }, { desc: "deep_bson.json", - value: readExtJSONFile(b, "deep_bson.json"), + value: loadExtendedBSON(b, "deep_bson.json"), }, { desc: "flat_bson.json", - value: readExtJSONFile(b, "flat_bson.json"), + value: loadExtendedBSON(b, "flat_bson.json"), }, { desc: "full_bson.json", - value: readExtJSONFile(b, "full_bson.json"), + value: loadExtendedBSON(b, "full_bson.json"), }, } @@ -335,15 +344,15 @@ func BenchmarkUnmarshal(b *testing.B) { }, { name: "deep_bson.json", - value: readExtJSONFile(b, "deep_bson.json"), + value: loadExtendedBSON(b, "deep_bson.json"), }, { name: "flat_bson.json", - value: readExtJSONFile(b, "flat_bson.json"), + value: loadExtendedBSON(b, "flat_bson.json"), }, { name: "full_bson.json", - value: readExtJSONFile(b, "full_bson.json"), + value: loadExtendedBSON(b, "full_bson.json"), }, } From b17879b752faedac8ce9a8f33ef99381406effca Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Mon, 1 Jun 2026 23:26:03 -0400 Subject: [PATCH 3/4] revert changes in internal/cmd/benchmark/benchmark_test.go --- internal/cmd/benchmark/benchmark_test.go | 52 +----------------------- 1 file changed, 2 insertions(+), 50 deletions(-) diff --git a/internal/cmd/benchmark/benchmark_test.go b/internal/cmd/benchmark/benchmark_test.go index cfd6d40b7d..3e0ba80dce 100644 --- a/internal/cmd/benchmark/benchmark_test.go +++ b/internal/cmd/benchmark/benchmark_test.go @@ -209,56 +209,8 @@ func loadSourceDocument(b *testing.B, canonicalOnly bool, pathParts ...string) b return doc } -func loadBSONExtJSONFile(b *testing.B, canonicalOnly bool, source string) bson.D { - b.Helper() - - tgzPath := filepath.Join(testdataDir(b), "specifications", "source", "benchmarking", "data", "extended_bson.tgz") - - file, err := os.Open(tgzPath) - require.NoError(b, err, "failed to open %q", tgzPath) - defer file.Close() - - gz, err := gzip.NewReader(file) - require.NoError(b, err, "failed to create gzip reader") - defer gz.Close() - - tr := tar.NewReader(gz) - for { - hdr, err := tr.Next() - if errors.Is(err, io.EOF) { - break - } - - require.NoError(b, err, "failed to read tar") - - if hdr.Typeflag != tar.TypeReg { - continue - } - - if hdr.Name != bsonDataDir+"/"+source { - continue - } - - data, err := io.ReadAll(tr) - require.NoError(b, err, "failed to read tar entry %q", hdr.Name) - - var doc bson.D - - err = bson.UnmarshalExtJSON(data, canonicalOnly, &doc) - require.NoError(b, err, "failed to unmarshal extended JSON from %q", hdr.Name) - - require.NotEmpty(b, doc) - - return doc - } - - b.Fatalf("file %q not found in %q", bsonDataDir+"/"+source, tgzPath) - - return nil -} - func benchmarkBSONEncoding(b *testing.B, canonicalOnly bool, source string) { - doc := loadBSONExtJSONFile(b, canonicalOnly, source) + doc := loadSourceDocument(b, canonicalOnly, testdataPerfDir(b), bsonDataDir, source) b.ResetTimer() @@ -277,7 +229,7 @@ func benchmarkBSONEncoding(b *testing.B, canonicalOnly bool, source string) { } func benchmarkBSONDecoding(b *testing.B, canonicalOnly bool, source string) { - doc := loadBSONExtJSONFile(b, canonicalOnly, source) + doc := loadSourceDocument(b, canonicalOnly, testdataPerfDir(b), bsonDataDir, source) raw, err := bson.Marshal(doc) require.NoError(b, err, "failed to encode bson data") From 9b37a70c7ed1b4931ce8d0cb037caed3220b6e58 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Wed, 3 Jun 2026 15:53:42 -0400 Subject: [PATCH 4/4] Use global variables to replace closure. --- bson/benchmark_test.go | 121 +++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/bson/benchmark_test.go b/bson/benchmark_test.go index 0f4f887839..045cc5f558 100644 --- a/bson/benchmark_test.go +++ b/bson/benchmark_test.go @@ -146,83 +146,86 @@ var nestedInstance = nestedtest1{ }, } +var ( + loadExtendedBSONOnce sync.Once + loadExtendedBSONErr error + loadExtendedBSONEntries map[string]map[string]any + loadExtendedBSONEntryErrs map[string]error +) + // loadExtendedBSON is a function that returns the extended BSON data for a given filename in the // extended_bson.tgz archive. The first call to loadExtendedBSON will decompress all the JSON files // in the archive and cache all entries; subsequent calls will only return the cache. Caller must // not mutate the returned value. -var loadExtendedBSON = func() func(tb testing.TB, filename string) map[string]any { +func loadExtendedBSON(tb testing.TB, filename string) map[string]any { + tb.Helper() + const extendedBSONTGZ = "../testdata/specifications/source/benchmarking/data/extended_bson.tgz" - var once sync.Once - var onceErr error - entryErr := make(map[string]error) - results := make(map[string]map[string]any) + loadExtendedBSONOnce.Do(func() { + file, err := os.Open(extendedBSONTGZ) + if err != nil { + loadExtendedBSONErr = fmt.Errorf("error opening %q: %v", extendedBSONTGZ, err) + return + } + defer func() { + _ = file.Close() + }() + + gz, err := gzip.NewReader(file) + if err != nil { + loadExtendedBSONErr = fmt.Errorf("error creating gzip reader: %v", err) + return + } + defer func() { + _ = gz.Close() + }() - return func(tb testing.TB, filename string) map[string]any { - tb.Helper() + loadExtendedBSONEntries = make(map[string]map[string]any) + loadExtendedBSONEntryErrs = make(map[string]error) - once.Do(func() { - file, err := os.Open(extendedBSONTGZ) + tr := tar.NewReader(gz) + for { + hdr, err := tr.Next() + if errors.Is(err, io.EOF) { + break + } if err != nil { - onceErr = fmt.Errorf("error opening %q: %v", extendedBSONTGZ, err) + loadExtendedBSONErr = fmt.Errorf("error reading tar header: %v", err) return } - defer func() { - _ = file.Close() - }() - - gz, err := gzip.NewReader(file) + if hdr.Typeflag != tar.TypeReg { + continue + } + data, err := io.ReadAll(tr) if err != nil { - onceErr = fmt.Errorf("error creating gzip reader: %v", err) - return + loadExtendedBSONEntryErrs[hdr.Name] = fmt.Errorf("error reading tar entry: %v", err) + continue } - defer func() { - _ = gz.Close() - }() - - tr := tar.NewReader(gz) - for { - hdr, err := tr.Next() - if errors.Is(err, io.EOF) { - break - } - if err != nil { - onceErr = fmt.Errorf("error reading tar header: %v", err) - return - } - if hdr.Typeflag != tar.TypeReg { - continue - } - data, err := io.ReadAll(tr) - if err != nil { - entryErr[hdr.Name] = fmt.Errorf("error reading tar entry: %v", err) - continue - } - var v map[string]any - err = UnmarshalExtJSON(data, false, &v) - if err != nil { - entryErr[hdr.Name] = fmt.Errorf("error unmarshalling: %v", err) - continue - } - results[hdr.Name] = v + var v map[string]any + err = UnmarshalExtJSON(data, false, &v) + if err != nil { + loadExtendedBSONEntryErrs[hdr.Name] = fmt.Errorf("error unmarshalling: %v", err) + continue } - }) - entry := "extended_bson/" + filename - if err, ok := entryErr[entry]; ok { - require.FailNowf(tb, "failed to load benchmark data", "error loading file %q from %q: %v", filename, extendedBSONTGZ, err) + loadExtendedBSONEntries[hdr.Name] = v } - v, ok := results[entry] - if !ok { - if onceErr != nil { - require.FailNowf(tb, "failed to load benchmark data", "error loading file %q from %q: %v", filename, extendedBSONTGZ, onceErr) - } else { - require.FailNowf(tb, "failed to load benchmark data", "error loading file %q from %q: not found", filename, extendedBSONTGZ) - } + }) + entry := "extended_bson/" + filename + if err, ok := loadExtendedBSONEntryErrs[entry]; ok { + require.FailNowf(tb, "failed to load benchmark data", "error loading file %q from %q: %v", filename, extendedBSONTGZ, err) + } + v, ok := loadExtendedBSONEntries[entry] + if !ok { + if loadExtendedBSONErr != nil { + require.FailNowf(tb, "failed to load benchmark data", "error loading file %q from %q: %v", filename, extendedBSONTGZ, loadExtendedBSONErr) + } else { + require.FailNowf(tb, "failed to load benchmark data", "error loading file %q from %q: not found", filename, extendedBSONTGZ) } - return v } -}() + return v +} func BenchmarkMarshal(b *testing.B) { cases := []struct {