From 5a08e9e08a1207851ce4e4cdab333f8a0e1ef47d Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 15 Jun 2016 20:26:35 +0200 Subject: [PATCH] Remove failing blockstore test with context Why is it failing: process is started, cancel() is called, between we satart listening to the channels in select statemnet there is race of three things that can happent: 1. Task can complete 2. Task can start closing <- expected 3. Task already closed This race causes failures of the test. It is basing heavily on race of conditions where the task not closing, nor the task is completed before channels are being listened. It is quite impossible to resolve without adding bunch of timings in there, which we want to avoid, as there is no atomic "send message on channel and select" in Golang License: MIT Signed-off-by: Jakub Sztandera --- blocks/blockstore/blockstore_test.go | 125 ++++++++------------------- 1 file changed, 35 insertions(+), 90 deletions(-) diff --git a/blocks/blockstore/blockstore_test.go b/blocks/blockstore/blockstore_test.go index 2dc828ea238..4a7eb7c7416 100644 --- a/blocks/blockstore/blockstore_test.go +++ b/blocks/blockstore/blockstore_test.go @@ -117,97 +117,42 @@ func TestAllKeysRespectsContext(t *testing.T) { errors <- nil // a nil one to signal break } - // Once without context, to make sure it all works - { - var results dsq.Results - var resultsmu = make(chan struct{}) - resultChan := make(chan dsq.Result) - d.SetFunc(func(q dsq.Query) (dsq.Results, error) { - results = dsq.ResultsWithChan(q, resultChan) - resultsmu <- struct{}{} - return results, nil - }) - - go getKeys(context.Background()) - - // make sure it's waiting. - <-started - <-resultsmu - select { - case <-done: - t.Fatal("sync is wrong") - case <-results.Process().Closing(): - t.Fatal("should not be closing") - case <-results.Process().Closed(): - t.Fatal("should not be closed") - default: - } - - e := dsq.Entry{Key: BlockPrefix.ChildString("foo").String()} - resultChan <- dsq.Result{Entry: e} // let it go. - close(resultChan) - <-done // should be done now. - <-results.Process().Closed() // should be closed now - - // print any errors - for err := range errors { - if err == nil { - break - } - t.Error(err) - } - } - - // Once with - { - var results dsq.Results - var resultsmu = make(chan struct{}) - resultChan := make(chan dsq.Result) - d.SetFunc(func(q dsq.Query) (dsq.Results, error) { - results = dsq.ResultsWithChan(q, resultChan) - resultsmu <- struct{}{} - return results, nil - }) - - ctx, cancel := context.WithCancel(context.Background()) - go getKeys(ctx) - - // make sure it's waiting. - <-started - <-resultsmu - select { - case <-done: - t.Fatal("sync is wrong") - case <-results.Process().Closing(): - t.Fatal("should not be closing") - case <-results.Process().Closed(): - t.Fatal("should not be closed") - default: - } - - cancel() // let it go. - - select { - case <-done: - t.Fatal("sync is wrong") - case <-results.Process().Closed(): - t.Fatal("should not be closed") // should not be closed yet. - case <-results.Process().Closing(): - // should be closing now! - t.Log("closing correctly at this point.") - } - - close(resultChan) - <-done // should be done now. - <-results.Process().Closed() // should be closed now - - // print any errors - for err := range errors { - if err == nil { - break - } - t.Error(err) + var results dsq.Results + var resultsmu = make(chan struct{}) + resultChan := make(chan dsq.Result) + d.SetFunc(func(q dsq.Query) (dsq.Results, error) { + results = dsq.ResultsWithChan(q, resultChan) + resultsmu <- struct{}{} + return results, nil + }) + + go getKeys(context.Background()) + + // make sure it's waiting. + <-started + <-resultsmu + select { + case <-done: + t.Fatal("sync is wrong") + case <-results.Process().Closing(): + t.Fatal("should not be closing") + case <-results.Process().Closed(): + t.Fatal("should not be closed") + default: + } + + e := dsq.Entry{Key: BlockPrefix.ChildString("foo").String()} + resultChan <- dsq.Result{Entry: e} // let it go. + close(resultChan) + <-done // should be done now. + <-results.Process().Closed() // should be closed now + + // print any errors + for err := range errors { + if err == nil { + break } + t.Error(err) } }