From 774a99d6de1affd25ae49186c3735091827b4b47 Mon Sep 17 00:00:00 2001 From: Rahul Gurnani Date: Tue, 3 Nov 2020 05:09:09 +0530 Subject: [PATCH] feat(tests): Run tests in parallel (#1572) Run tests in parallel. Break up the tests into 3 functions: manual, packages and root. Run those via GNU parallel. Moved some expensive tests to manual mode. With these changes, the badger tests can now run in under 6 minutes on a fast machine. Co-authored-by: Manish R Jain --- db_test.go | 11 +++++++- iterator_test.go | 8 +++--- merge_test.go | 4 +-- stream_test.go | 6 ++-- test.sh | 72 +++++++++++++++++++++++++++++++----------------- 5 files changed, 66 insertions(+), 35 deletions(-) diff --git a/db_test.go b/db_test.go index baaa07658..1373ff722 100644 --- a/db_test.go +++ b/db_test.go @@ -70,7 +70,8 @@ func getTestOptions(dir string) Options { WithMemTableSize(1 << 15). WithBaseTableSize(1 << 15). // Force more compaction. WithBaseLevelSize(4 << 15). // Force more compaction. - WithSyncWrites(false) + WithSyncWrites(false). + WithLoggingLevel(WARNING) return opt } @@ -910,6 +911,10 @@ func TestIterateDeleted(t *testing.T) { } func TestIterateParallel(t *testing.T) { + if !*manual { + t.Skip("Skipping test meant to be run manually.") + return + } key := func(account int) []byte { var b [4]byte binary.BigEndian.PutUint32(b[:], uint32(account)) @@ -1816,6 +1821,10 @@ func TestMinReadTs(t *testing.T) { } func TestGoroutineLeak(t *testing.T) { + if !*manual { + t.Skip("Skipping test meant to be run manually.") + return + } test := func(t *testing.T, opt *Options) { time.Sleep(1 * time.Second) before := runtime.NumGoroutine() diff --git a/iterator_test.go b/iterator_test.go index 28ff3fd74..d52c56d81 100644 --- a/iterator_test.go +++ b/iterator_test.go @@ -123,6 +123,10 @@ func TestPickSortTables(t *testing.T) { } func TestIteratePrefix(t *testing.T) { + if !*manual { + t.Skip("Skipping test meant to be run manually.") + return + } testIteratorPrefix := func(t *testing.T, db *DB) { bkey := func(i int) []byte { return []byte(fmt.Sprintf("%04d", i)) @@ -199,14 +203,12 @@ func TestIteratePrefix(t *testing.T) { } t.Run("With Default options", func(t *testing.T) { - t.Parallel() runBadgerTest(t, nil, func(t *testing.T, db *DB) { testIteratorPrefix(t, db) }) }) t.Run("With Block Offsets in Cache", func(t *testing.T) { - t.Parallel() opts := getTestOptions("") opts.IndexCacheSize = 100 << 20 runBadgerTest(t, &opts, func(t *testing.T, db *DB) { @@ -215,7 +217,6 @@ func TestIteratePrefix(t *testing.T) { }) t.Run("With Block Offsets and Blocks in Cache", func(t *testing.T) { - t.Parallel() opts := getTestOptions("") opts.BlockCacheSize = 100 << 20 opts.IndexCacheSize = 100 << 20 @@ -225,7 +226,6 @@ func TestIteratePrefix(t *testing.T) { }) t.Run("With Blocks in Cache", func(t *testing.T) { - t.Parallel() opts := getTestOptions("") opts.BlockCacheSize = 100 << 20 runBadgerTest(t, &opts, func(t *testing.T, db *DB) { diff --git a/merge_test.go b/merge_test.go index 2b22ea9ea..23e028081 100644 --- a/merge_test.go +++ b/merge_test.go @@ -164,6 +164,6 @@ func bytesToUint64(b []byte) uint64 { } // Merge function to add two uint64 numbers -func add(existing, new []byte) []byte { - return uint64ToBytes(bytesToUint64(existing) + bytesToUint64(new)) +func add(existing, latest []byte) []byte { + return uint64ToBytes(bytesToUint64(existing) + bytesToUint64(latest)) } diff --git a/stream_test.go b/stream_test.go index f0bd8bd0c..d6bd5e568 100644 --- a/stream_test.go +++ b/stream_test.go @@ -27,7 +27,6 @@ import ( bpb "github.com/dgraph-io/badger/v2/pb" "github.com/dgraph-io/badger/v2/y" - "github.com/dgraph-io/ristretto/z" "github.com/golang/protobuf/proto" "github.com/stretchr/testify/require" ) @@ -164,7 +163,6 @@ func TestStream(t *testing.T) { require.Equal(t, 50, count, "Count mismatch for pred: %s", pred) } require.NoError(t, db.Close()) - require.Equal(t, int64(0), z.NumAllocBytes()) } func TestStreamWithThreadId(t *testing.T) { @@ -214,6 +212,10 @@ func TestStreamWithThreadId(t *testing.T) { } func TestBigStream(t *testing.T) { + if !*manual { + t.Skip("Skipping test meant to be run manually.") + return + } // Set the maxStreamSize to 1MB for the duration of the test so that the it can use a smaller // dataset than it would otherwise need. originalMaxStreamSize := maxStreamSize diff --git a/test.sh b/test.sh index f7ea5606d..3665504b5 100755 --- a/test.sh +++ b/test.sh @@ -4,7 +4,6 @@ set -e go version -packages=$(go list ./... | grep github.com/dgraph-io/badger/v2/) if [[ ! -z "$TEAMCITY_VERSION" ]]; then export GOFLAGS="-json" @@ -38,32 +37,53 @@ pushd badger go build -v . popd -# tags="-tags=jemalloc" -tags="" +tags="-tags=jemalloc" +# tags="" +InstallJemalloc # Run the memory intensive tests first. -go test -v $tags -run='TestBigKeyValuePairs$' --manual=true -go test -v $tags -run='TestPushValueLogLimit' --manual=true +manual() { + echo "==> Running manual tests" + # Run the special Truncate test. + rm -rf p + go test -v $tags -run='TestTruncateVlogNoClose$' --manual=true + truncate --size=4096 p/000000.vlog + go test -v $tags -run='TestTruncateVlogNoClose2$' --manual=true + go test -v $tags -run='TestTruncateVlogNoClose3$' --manual=true + rm -rf p -# Run the special Truncate test. -rm -rf p -go test -v $tags -run='TestTruncateVlogNoClose$' --manual=true -truncate --size=4096 p/000000.vlog -go test -v $tags -run='TestTruncateVlogNoClose2$' --manual=true -go test -v $tags -run='TestTruncateVlogNoClose3$' --manual=true -rm -rf p + go test -v $tags -run='TestBigKeyValuePairs$' --manual=true + go test -v $tags -run='TestPushValueLogLimit' --manual=true + go test -v $tags -run='TestKeyCount' --manual=true + go test -v $tags -run='TestIteratePrefix' --manual=true + go test -v $tags -run='TestIterateParallel' --manual=true + go test -v $tags -run='TestBigStream' --manual=true + go test -v $tags -run='TestGoroutineLeak' --manual=true -InstallJemalloc -# Run the key count test for stream writer. -go test -v -tags jemalloc -run='TestKeyCount' --manual=true - -# Run the normal tests. -echo "==> Starting tests.. " -# go test -timeout=25m -v -race github.com/dgraph-io/badger/v2/... -for pkg in $packages; do - echo "===> Testing $pkg" - go test $tags -timeout=25m -v -race $pkg -done - -echo "===> Testing root level" -go test $tags -timeout=25m -v . -race + echo "==> DONE manual tests" +} + +pkgs() { + packages=$(go list ./... | grep github.com/dgraph-io/badger/v2/) + echo "==> Running package tests for $packages" + for pkg in $packages; do + echo "===> Testing $pkg" + go test $tags -timeout=25m -v -race $pkg -parallel 16 + done + echo "==> DONE package tests" +} + +root() { + # Run the normal tests. + # go test -timeout=25m -v -race github.com/dgraph-io/badger/v2/... + + echo "==> Running root level tests." + go test $tags -timeout=25m -v . -race -parallel 16 + echo "==> DONE root level tests" +} + +export -f manual +export -f pkgs +export -f root + +parallel --progress --line-buffer ::: manual pkgs root