// FinallyCoverage provides coverage for the Finally function. func (t *RSuite) FinallyCoverage() async.R { expected := fmt.Errorf("some error") didRun := false r, s := async.NewR() s.Fail(expected) w := async.Finally(r, func() { didRun = true }) // Verify that the value was round-tripped. return async.When(w, func(val interface{}, err error) async.R { if !didRun { return async.NewErrorf("Expected finally to run. Got: false, Want: true") } if err != expected { return async.NewErrorf("Expected error. Got: %v, Want: %v", err, expected) } if val != nil { return async.NewErrorf("Expected error. Got: %v, Want: nil", val) } return async.Done() }) }
// AsyncTurn verifies that a parallel turn executed by a Source does run, and that its resolution is // reflected correctly on the main turn queue. func (t *TurnSourceSuite) AsyncTurn() async.R { src := turns.NewTurnSource() syncPoint1 := make(chan struct{}, 0) syncPoint2 := make(chan struct{}, 0) // Create a truly parallel turn. r := src.New(func() error { t.Infof("Beginning async turn.") // produce sync point 1. close(syncPoint1) // wait for sync point 2. <-syncPoint2 return nil }) // Create a coop-turn to provide the sync point. async.New(func() async.R { t.Infof("Beginning coop turn that provides sync point.") // Wait for both parallel and coop turns to have started. <-syncPoint1 // Completed the parallel turn. close(syncPoint2) return async.Done() }) // Cleanup the source. return async.Finally(r, func() { // Destroy the TurnSource since we don't need it anymore. src.Close() }) }