Skip to content

Commit ca0c0bc

Browse files
bindings/go: Add memory usage test for streaming parser (#181)
1 parent 335e0fa commit ca0c0bc

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
This package should only have a single test
2+
so that we can use SetMemoryLimit without
3+
affecting other tests running in different
4+
goroutines in the same process.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package memtest
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"os"
7+
"runtime"
8+
"runtime/debug"
9+
"strings"
10+
"testing"
11+
12+
"github.com/stretchr/testify/require"
13+
"google.golang.org/protobuf/proto"
14+
15+
"github.com/sourcegraph/scip/bindings/go/scip"
16+
)
17+
18+
// Do not add any other tests in this sub-package, so that the
19+
// SetMemoryLimit call doesn't interfere with other running tests
20+
21+
func TestLowMemoryParsing(t *testing.T) {
22+
tmpFile, err := os.CreateTemp(t.TempDir(), "very-large-index.scip")
23+
require.NoError(t, err)
24+
defer os.RemoveAll(tmpFile.Name())
25+
26+
// Total index size will be about (textSize + ε) * docCount ~= 128 MB
27+
const textSize = 128 * 1024
28+
const docCount = 1000
29+
{
30+
largeIndex := scip.Index{}
31+
for i := 0; i < docCount; i++ {
32+
doc := scip.Document{}
33+
doc.Text = strings.Repeat(fmt.Sprintf("%d", i), textSize)
34+
largeIndex.Documents = append(largeIndex.Documents, &doc)
35+
}
36+
indexBytes, err := proto.Marshal(&largeIndex)
37+
require.NoError(t, err)
38+
_, err = tmpFile.Write(indexBytes)
39+
require.NoError(t, err)
40+
41+
_, err = tmpFile.Seek(0, io.SeekStart)
42+
require.NoError(t, err)
43+
44+
runtime.GC()
45+
}
46+
47+
require.Greater(t, docCount, 100)
48+
const maxDocsInMemory = docCount / 100
49+
debug.SetMemoryLimit(textSize * maxDocsInMemory)
50+
51+
curDoc := &scip.Document{}
52+
indexVisitor := scip.IndexVisitor{VisitDocument: func(d *scip.Document) {
53+
curDoc = d
54+
}}
55+
56+
// No OOM
57+
err = indexVisitor.ParseStreaming(tmpFile)
58+
_ = curDoc
59+
require.NoError(t, err)
60+
}
61+
62+
// Do not add any other tests in this sub-package, so that the
63+
// SetMemoryLimit call doesn't interfere with other running tests

0 commit comments

Comments
 (0)