From 06fbaba15b519c965b6eeca167313e6fbbb27bff Mon Sep 17 00:00:00 2001 From: Jarek Kowalski Date: Sun, 15 Mar 2020 23:44:21 -0700 Subject: [PATCH] testing: ensure cleanup of content managers, fixes #356 --- repo/content/content_index_recovery_test.go | 5 ++ repo/content/content_manager_test.go | 84 +++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/repo/content/content_index_recovery_test.go b/repo/content/content_index_recovery_test.go index 17d785aaa..767bfb0a4 100644 --- a/repo/content/content_index_recovery_test.go +++ b/repo/content/content_index_recovery_test.go @@ -14,6 +14,7 @@ func TestContentIndexRecovery(t *testing.T) { data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} bm := newTestContentManager(t, data, keyTime, nil) + content1 := writeContentAndVerify(ctx, t, bm, seededRandomData(10, 100)) content2 := writeContentAndVerify(ctx, t, bm, seededRandomData(11, 100)) content3 := writeContentAndVerify(ctx, t, bm, seededRandomData(12, 100)) @@ -28,8 +29,12 @@ func TestContentIndexRecovery(t *testing.T) { return bm.st.DeleteBlob(ctx, bi.BlobID) })) + bm.Close(ctx) + // now with index blobs gone, all contents appear to not be found bm = newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) + verifyContentNotFound(ctx, t, bm, content1) verifyContentNotFound(ctx, t, bm, content2) verifyContentNotFound(ctx, t, bm, content3) diff --git a/repo/content/content_manager_test.go b/repo/content/content_manager_test.go index 3f1bcde57..c0065f653 100644 --- a/repo/content/content_manager_test.go +++ b/repo/content/content_manager_test.go @@ -37,6 +37,8 @@ func TestContentManagerEmptyFlush(t *testing.T) { data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} bm := newTestContentManager(t, data, keyTime, nil) + + defer bm.Close(ctx) bm.Flush(ctx) if got, want := len(data), 0; got != want { @@ -49,6 +51,8 @@ func TestContentZeroBytes1(t *testing.T) { data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} bm := newTestContentManager(t, data, keyTime, nil) + + defer bm.Close(ctx) contentID := writeContentAndVerify(ctx, t, bm, []byte{}) bm.Flush(ctx) @@ -58,6 +62,9 @@ func TestContentZeroBytes1(t *testing.T) { dumpContentManagerData(ctx, t, data) bm = newTestContentManager(t, data, keyTime, nil) + + defer bm.Close(ctx) + verifyContent(ctx, t, bm, contentID, []byte{}) } @@ -66,6 +73,9 @@ func TestContentZeroBytes2(t *testing.T) { data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} bm := newTestContentManager(t, data, keyTime, nil) + + defer bm.Close(ctx) + writeContentAndVerify(ctx, t, bm, seededRandomData(10, 10)) writeContentAndVerify(ctx, t, bm, []byte{}) bm.Flush(ctx) @@ -82,6 +92,8 @@ func TestContentManagerSmallContentWrites(t *testing.T) { keyTime := map[blob.ID]time.Time{} bm := newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) + for i := 0; i < 100; i++ { writeContentAndVerify(ctx, t, bm, seededRandomData(i, 10)) } @@ -103,6 +115,8 @@ func TestContentManagerDedupesPendingContents(t *testing.T) { keyTime := map[blob.ID]time.Time{} bm := newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) + for i := 0; i < 100; i++ { writeContentAndVerify(ctx, t, bm, seededRandomData(0, 999)) } @@ -124,6 +138,8 @@ func TestContentManagerDedupesPendingAndUncommittedContents(t *testing.T) { keyTime := map[blob.ID]time.Time{} bm := newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) + // no writes here, all data fits in a single pack. writeContentAndVerify(ctx, t, bm, seededRandomData(0, 950)) writeContentAndVerify(ctx, t, bm, seededRandomData(1, 950)) @@ -157,6 +173,8 @@ func TestContentManagerEmpty(t *testing.T) { keyTime := map[blob.ID]time.Time{} bm := newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) + noSuchContentID := ID(hashValue([]byte("foo"))) b, err := bm.GetContent(ctx, noSuchContentID) @@ -193,6 +211,8 @@ func TestContentManagerInternalFlush(t *testing.T) { keyTime := map[blob.ID]time.Time{} bm := newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) + for i := 0; i < 100; i++ { b := make([]byte, 25) cryptorand.Read(b) //nolint:errcheck @@ -230,7 +250,9 @@ func TestContentManagerWriteMultiple(t *testing.T) { data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} timeFunc := faketime.AutoAdvance(fakeTime, 1*time.Second) + bm := newTestContentManager(t, data, keyTime, timeFunc) + defer bm.Close(ctx) var contentIDs []ID @@ -256,6 +278,7 @@ func TestContentManagerWriteMultiple(t *testing.T) { } bm = newTestContentManager(t, data, keyTime, timeFunc) + defer bm.Close(ctx) } pos := rand.Intn(len(contentIDs)) @@ -314,14 +337,23 @@ func TestContentManagerConcurrency(t *testing.T) { ctx := testlogging.Context(t) data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} + bm := newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) + preexistingContent := writeContentAndVerify(ctx, t, bm, seededRandomData(10, 100)) bm.Flush(ctx) dumpContentManagerData(ctx, t, data) + bm1 := newTestContentManager(t, data, keyTime, nil) + defer bm1.Close(ctx) + bm2 := newTestContentManager(t, data, keyTime, nil) + defer bm2.Close(ctx) + bm3 := newTestContentManager(t, data, keyTime, faketime.AutoAdvance(fakeTime.Add(1), 1*time.Second)) + defer bm3.Close(ctx) // all bm* can see pre-existing content verifyContent(ctx, t, bm1, preexistingContent, seededRandomData(10, 100)) @@ -359,6 +391,8 @@ func TestContentManagerConcurrency(t *testing.T) { // new content manager at this point can see all data. bm4 := newTestContentManager(t, data, keyTime, nil) + defer bm4.Close(ctx) + verifyContent(ctx, t, bm4, preexistingContent, seededRandomData(10, 100)) verifyContent(ctx, t, bm4, sharedContent, seededRandomData(20, 100)) verifyContent(ctx, t, bm4, bm1content, seededRandomData(31, 100)) @@ -379,6 +413,8 @@ func TestContentManagerConcurrency(t *testing.T) { // new content manager at this point can see all data. bm5 := newTestContentManager(t, data, keyTime, nil) + defer bm5.Close(ctx) + verifyContent(ctx, t, bm5, preexistingContent, seededRandomData(10, 100)) verifyContent(ctx, t, bm5, sharedContent, seededRandomData(20, 100)) verifyContent(ctx, t, bm5, bm1content, seededRandomData(31, 100)) @@ -394,7 +430,9 @@ func TestDeleteContent(t *testing.T) { ctx := testlogging.Context(t) data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} + bm := newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) content1 := writeContentAndVerify(ctx, t, bm, seededRandomData(10, 100)) @@ -426,6 +464,7 @@ func TestDeleteContent(t *testing.T) { log(ctx).Debugf("-----------") bm = newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) verifyContentNotFound(ctx, t, bm, content1) verifyContentNotFound(ctx, t, bm, content2) } @@ -457,6 +496,8 @@ func TestParallelWrites(t *testing.T) { var workerLock sync.RWMutex bm := newTestContentManagerWithStorage(t, fs, nil) + defer bm.Close(ctx) + numWorkers := 8 closeWorkers := make(chan bool) @@ -564,6 +605,7 @@ func TestFlushResumesWriters(t *testing.T) { } bm := newTestContentManagerWithStorage(t, fs, nil) + defer bm.Close(ctx) first := writeContentAndVerify(ctx, t, bm, []byte{1, 2, 3}) var second ID @@ -605,6 +647,7 @@ func TestFlushResumesWriters(t *testing.T) { func verifyAllDataPresent(ctx context.Context, t *testing.T, data map[blob.ID][]byte, contentIDs map[ID]bool) { bm := newTestContentManager(t, data, nil, nil) + defer bm.Close(ctx) _ = bm.IterateContents(ctx, IterateOptions{}, func(ci Info) error { delete(contentIDs, ci.ID) return nil @@ -674,6 +717,8 @@ func TestHandleWriteErrors(t *testing.T) { } bm := newTestContentManagerWithStorage(t, fs, nil) + defer bm.Close(ctx) + writeRetries := 0 var cids []ID for i := 0; i < tc.numContents; i++ { @@ -687,7 +732,10 @@ func TestHandleWriteErrors(t *testing.T) { if got, want := writeRetries, tc.expectedWriteRetries; got != want { t.Errorf("invalid # of write retries %v, wanted %v", got, want) } + bm2 := newTestContentManagerWithStorage(t, st, nil) + defer bm2.Close(ctx) + for i, cid := range cids { verifyContent(ctx, t, bm2, cid, seededRandomData(i, tc.contentSize)) } @@ -711,6 +759,7 @@ func TestRewriteNonDeleted(t *testing.T) { keyTime := map[blob.ID]time.Time{} fakeNow := faketime.AutoAdvance(fakeTime, 1*time.Second) bm := newTestContentManager(t, data, keyTime, fakeNow) + defer bm.Close(ctx) applyStep := func(action int) { switch action { @@ -718,6 +767,7 @@ func TestRewriteNonDeleted(t *testing.T) { t.Logf("flushing and reopening") bm.Flush(ctx) bm = newTestContentManager(t, data, keyTime, fakeNow) + defer bm.Close(ctx) case 1: t.Logf("flushing") bm.Flush(ctx) @@ -741,7 +791,10 @@ func TestDisableFlush(t *testing.T) { ctx := testlogging.Context(t) data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} + bm := newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) + bm.DisableIndexFlush(ctx) bm.DisableIndexFlush(ctx) @@ -777,6 +830,7 @@ func TestRewriteDeleted(t *testing.T) { keyTime := map[blob.ID]time.Time{} fakeNow := faketime.AutoAdvance(fakeTime, 1*time.Second) bm := newTestContentManager(t, data, keyTime, fakeNow) + defer bm.Close(ctx) applyStep := func(action int) { switch action { @@ -784,6 +838,7 @@ func TestRewriteDeleted(t *testing.T) { t.Logf("flushing and reopening") bm.Flush(ctx) bm = newTestContentManager(t, data, keyTime, fakeNow) + defer bm.Close(ctx) case 1: t.Logf("flushing") bm.Flush(ctx) @@ -827,22 +882,31 @@ func TestDeleteAndRecreate(t *testing.T) { // write a content data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} + bm := newTestContentManager(t, data, keyTime, faketime.Frozen(fakeTime)) + defer bm.Close(ctx) + content1 := writeContentAndVerify(ctx, t, bm, seededRandomData(10, 100)) bm.Flush(ctx) // delete but at given timestamp but don't commit yet. bm0 := newTestContentManager(t, data, keyTime, faketime.AutoAdvance(tc.deletionTime, 1*time.Second)) + defer bm0.Close(ctx) + assertNoError(t, bm0.DeleteContent(ctx, content1)) // delete it at t0+10 bm1 := newTestContentManager(t, data, keyTime, faketime.AutoAdvance(fakeTime.Add(10*time.Second), 1*time.Second)) + defer bm1.Close(ctx) + verifyContent(ctx, t, bm1, content1, seededRandomData(10, 100)) assertNoError(t, bm1.DeleteContent(ctx, content1)) bm1.Flush(ctx) // recreate at t0+20 bm2 := newTestContentManager(t, data, keyTime, faketime.AutoAdvance(fakeTime.Add(20*time.Second), 1*time.Second)) + defer bm2.Close(ctx) + content2 := writeContentAndVerify(ctx, t, bm2, seededRandomData(10, 100)) bm2.Flush(ctx) @@ -854,6 +918,8 @@ func TestDeleteAndRecreate(t *testing.T) { } bm3 := newTestContentManager(t, data, keyTime, nil) + defer bm3.Close(ctx) + dumpContentManagerData(ctx, t, data) if tc.isVisible { verifyContent(ctx, t, bm3, content1, seededRandomData(10, 100)) @@ -869,7 +935,10 @@ func TestIterateContents(t *testing.T) { ctx := testlogging.Context(t) data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} + bm := newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) + // flushed, non-deleted contentID1 := writeContentAndVerify(ctx, t, bm, seededRandomData(10, 100)) @@ -1003,7 +1072,10 @@ func TestFindUnreferencedBlobs(t *testing.T) { ctx := testlogging.Context(t) data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} + bm := newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) + verifyUnreferencedBlobsCount(ctx, t, bm, 0) contentID := writeContentAndVerify(ctx, t, bm, seededRandomData(10, 100)) @@ -1050,7 +1122,10 @@ func TestFindUnreferencedBlobs2(t *testing.T) { ctx := testlogging.Context(t) data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} + bm := newTestContentManager(t, data, keyTime, nil) + defer bm.Close(ctx) + verifyUnreferencedBlobsCount(ctx, t, bm, 0) contentID := writeContentAndVerify(ctx, t, bm, seededRandomData(10, 100)) writeContentAndVerify(ctx, t, bm, seededRandomData(11, 100)) @@ -1122,7 +1197,9 @@ func TestContentWriteAliasing(t *testing.T) { ctx := testlogging.Context(t) data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} + bm := newTestContentManager(t, data, keyTime, faketime.Frozen(fakeTime)) + defer bm.Close(ctx) contentData := []byte{100, 0, 0} id1 := writeContentAndVerify(ctx, t, bm, contentData) @@ -1148,7 +1225,9 @@ func TestContentReadAliasing(t *testing.T) { ctx := testlogging.Context(t) data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} + bm := newTestContentManager(t, data, keyTime, faketime.Frozen(fakeTime)) + defer bm.Close(ctx) contentData := []byte{100, 0, 0} id1 := writeContentAndVerify(ctx, t, bm, contentData) @@ -1180,7 +1259,10 @@ func verifyVersionCompat(t *testing.T, writeVersion int) { // create content manager that writes 'writeVersion' and reads all versions >= minSupportedReadVersion data := blobtesting.DataMap{} keyTime := map[blob.ID]time.Time{} + mgr := newTestContentManager(t, data, keyTime, nil) + defer mgr.Close(ctx) + mgr.writeFormatVersion = int32(writeVersion) dataSet := map[ID][]byte{} @@ -1218,6 +1300,7 @@ func verifyVersionCompat(t *testing.T, writeVersion int) { // create new manager that reads and writes using new version. mgr = newTestContentManager(t, data, keyTime, nil) + defer mgr.Close(ctx) // make sure we can read everything verifyContentManagerDataSet(ctx, t, mgr, dataSet) @@ -1234,6 +1317,7 @@ func verifyVersionCompat(t *testing.T, writeVersion int) { // now open one more manager mgr = newTestContentManager(t, data, keyTime, nil) + defer mgr.Close(ctx) verifyContentManagerDataSet(ctx, t, mgr, dataSet) }