// WhenErrorReturnCoverage provides coverage for the When function. func (t *RSuite) WhenErrorReturnCoverage() async.R { expected := fmt.Errorf("some error") w := async.When(async.Done(), func() async.R { r, s := async.NewR() s.Fail(expected) return r }) w1 := async.When(w, func(err error) (interface{}, error) { if err != expected { return nil, fmt.Errorf("Expected executed w. Got: %v, Want: %v", err, expected) } return nil, err }) w2 := async.When(w1, func(err error) error { if err != expected { return fmt.Errorf("Expected executed w1. Got: %v, Want: %v", err, expected) } return err }) return async.When(w2, func(err error) async.R { if err != expected { return async.NewErrorf("Expected executed w2. Got: %v, Want: %v", err, expected) } return async.Done() }) }
// NewResultForward tests Resolver.Forward(). func (t *TurnRunnerSuite) NewResultForward() async.R { expected := fmt.Errorf("some error") r, s := async.NewR() async.When(async.Done(), func() { s.Forward(async.NewError(expected)) }) return async.When(r, func(err error) error { if err != expected { return fmt.Errorf("Got: %v, Want: %v", err, expected) } return nil }) }
func (t *TurnRunnerSuite) NewResultSuccess() async.R { r, s := async.NewR() async.When(async.Done(), func() { s.Complete() }) return r }
// RunUntil runs turns in the manager until main becomes resolved. If main fails, then its error // is returned, otherwise returns nil. func (m *Manager) RunUntil(main async.R) error { var mainExited error m.NewTurn("RunUntil", func() { async.When(main, func(err error) error { if err != nil { mainExited = err } else { mainExited = errSuccess } return err }) }) // Loop around until the main result has been resolved. Block efficiently on I/O (so that we // don't spin on select) if we run out of local work to do. for mainExited == nil { // Flush the main queue. m.runOneLoop() // If there is no work to do then block on I/O. if m.turns.IsEmpty() && (mainExited == nil) { e := m.sources.Wait() assert.True(m.turns.IsEmpty(), "Only blocked on I/O if there was no work to do.") assert.True(mainExited == nil, "Only blocked on I/O if the program not exited.") assert.True(e != nil, "LIVE LOCK: no progress can be made because there are no I/O "+ "sources, no local turns, and the program has not yet exited.") e.Signal() // force Select in next loop to see this source again. } } if mainExited != errSuccess { return mainExited } return nil }
// RunActor starts a contained environment with a turn manager that runs to completion. // main is the initial turn to be executed and the manager continues execution until main's return // value is resolved. func RunActor(root async.Func) error { done := make(chan error, 1) go func() { manager := turns.NewManager(turns.NewUniqueIDGenerator()) runner := turns.NewTurnRunner(manager) tlsRelease := async.SetAmbientRunner(runner) defer tlsRelease() // Allocate a resolver to track the completion of the "main" function. r, s := async.NewR() // Queue to main routine for execution. manager.NewTurn("Main", func() { async.When(root(), func(err error) { log.Infof("Actor Completed with status: %v", err) s.Resolve(err) }) }) err := manager.RunUntil(r) done <- err close(done) }() err := <-done return err }
// NewErrorfCoverage tests Runner.Errorf(). func (t *TurnRunnerSuite) NewErrorfCoverage() async.R { e := async.NewErrorf("some %s %d", "error", 1) return async.When(e, func(err error) error { if err.Error() != "some error 1" { return fmt.Errorf("Got: %v, Want: %v", err, "some error 1") } return nil }) }
// ResolveCoverage tests Resolver.Resolve(). func (t *TurnRunnerSuite) ResolveCoverage() async.R { r, s := async.NewR() async.When(async.Done(), func() { s.Resolve(nil) }) expected := fmt.Errorf("some error") r2, s2 := async.NewR() async.When(r, func() { s2.Resolve(expected) }) return async.When(r2, func(err error) error { if err != expected { return fmt.Errorf("Got: %v, Want: %v", err, expected) } return nil }) }
func (t *TurnRunnerSuite) DoneWhen() async.R { done := async.Done() return async.When(done, func(err error) async.R { if err != nil { t.Errorf("Expected Done() to succeeed. Got: %v, Want: nil", err) } return async.Done() }) }
// NewErrorfCoverage provides coverage for the NewErrorf function. func (t *RSuite) NewErrorfCoverage() async.R { expected := fmt.Errorf("some error") r := async.NewErrorf("%v", expected) return async.When(r, func(val interface{}, err error) async.R { if err.Error() != expected.Error() { return async.NewErrorf("Expected error. Got: %v, Want: %v", err, expected) } return async.Done() }) }
// NewCoverage provides coverage for the New function. func (t *RSuite) NewCoverage() async.R { r, s := async.NewR() s.Complete() return async.When(r, func(val interface{}, err error) async.R { if err != nil { return async.NewErrorf("Expected successful completion. Got: %v, Want: nil", err) } return async.Done() }) }
// NewErrorfCoverage provides coverage for the NewErrorf function. func (t *StringRSuite) NewErrorfCoverage() async.R { expected := fmt.Errorf("some error") r := async.NewStringErrorf("%v", expected) return async.When(r, func(err error) error { if err.Error() != expected.Error() { return fmt.Errorf("Expected error. Got: %v, Want: %v", err, expected) } return nil }) }
// WhenErrorCoverage provides coverage for the When function. func (t *RSuite) WhenErrorCoverage() async.R { expected := fmt.Errorf("some error") w := async.When(async.Done(), func() async.R { r, s := async.NewR() s.Fail(expected) return r }) w1 := async.When(w, func(_ interface{}, err error) async.R { if err != expected { return async.NewErrorf("Expected executed w. Got: %v, Want: %v", err, expected) } return w }) w2 := async.When(w1, func(interface{}) async.R { return async.NewErrorf("Expected not executed w1") }) w3 := async.When(w2, func(_ interface{}, err error) async.R { if err != expected { return async.NewErrorf("Expected executed w. Got: %v, Want: %v", err, expected) } return w2 }) w4 := async.When(w3, func() async.R { return async.NewErrorf("Expected not executed w3") }) return async.When(w4, func(_ interface{}, err error) async.R { if err != expected { return async.NewErrorf("Expected executed w. Got: %v, Want: %v", err, expected) } return async.Done() }) }
// NewResultForwarded tests a When on a forwarded result resolves correctly. func (t *TurnRunnerSuite) NewResultForwarded() async.R { expected := fmt.Errorf("some error") r, s := async.NewR() // Forward the result synchronously causing the When to be directly enqueued on the error. s.Forward(async.NewError(expected)) return async.When(r, func(err error) error { if err != expected { return fmt.Errorf("Got: %v, Want: %v", err, expected) } return nil }) }
// NewCoverage provides coverage for the New function. func (t *StringRSuite) NewCoverage() async.R { expected := "a test string" r, s := async.NewStringR() s.Complete(expected) return async.When(r, func(val string, err error) error { if err != nil { return fmt.Errorf("Expected success. Got: %v, Want: nil", err) } if val != expected { return fmt.Errorf("Expected success. Got: %v, Want: %v", val, expected) } return nil }) }
// WhenReturnCoverage provides coverage for the When function. func (t *RSuite) WhenReturnCoverage() async.R { w := async.When(async.Done(), func() async.R { r, s := async.NewR() s.Complete() return r }) w1 := async.When(w, func() (interface{}, error) { return nil, nil }) w2 := async.When(w1, func() error { return nil }) w3 := async.When(w2, func() interface{} { return nil }) w4 := async.When(w3, func() { }) return w4 }
// WhenCoverage provides coverage for the When function. func (t *StringRSuite) WhenCoverage() async.R { expected := "a test string" w := async.WhenString(async.Done(), func() async.StringR { r, s := async.NewStringR() s.Complete(expected) return r }) // Verify that the value was round-tripped. return async.When(w, func(val string, err error) error { if err != nil { return fmt.Errorf("Expected success. Got: %v, Want: nil", err) } if val != expected { return fmt.Errorf("Expected value. Got: %v, Want: %v", val, expected) } return nil }) }
// WhenCoverage provides coverage for the When function. func (t *RSuite) WhenCoverage() async.R { w := async.When(async.Done(), func(val interface{}, err error) async.R { r, s := async.NewR() s.Complete() return r }) // Verify full signature. expected := interface{}(nil) w1 := async.When(w, func(val interface{}, err error) async.R { if err != nil { return async.NewErrorf("Expected success w1. Got: %v, Want: nil", err) } if val != expected { return async.NewErrorf("Expected value w1. Got: %v, Want: %v", val, expected) } return w }) // Verify just error. w2 := async.When(w1, func(err error) async.R { if err != nil { return async.NewErrorf("Expected success w2. Got: %v, Want: nil", err) } return w1 }) // Verify just value. w3 := async.When(w2, func(val interface{}) async.R { if val != expected { return async.NewErrorf("Expected value w3. Got: %v, Want: %v", val, expected) } return w2 }) // Verify neither value nor error. didRun := false w4 := async.When(w3, func() async.R { didRun = true return w3 }) return async.When(w4, func() async.R { if !didRun { return async.NewErrorf("Expected executed w4. Got: %v, Want: true", didRun) } return w4 }) }
// FinallyCoverage provides coverage for the Finally function. func (t *StringRSuite) FinallyCoverage() async.R { expected := "a test string" didRun := false r, s := async.NewStringR() s.Complete(expected) w := async.FinallyString(r, func() { didRun = true }) // Verify that the value was round-tripped. return async.When(w, func(val string, err error) error { if !didRun { return fmt.Errorf("Expected finally to run. Got: false, Want: true") } if err != nil { return fmt.Errorf("Expected success. Got: %v, Want: nil", err) } if val != expected { return fmt.Errorf("Expected success. Got: %v, Want: %v", val, expected) } return nil }) }
// 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() }) }
// ForwardCoverage provides coverage for the Forward function. func (t *StringRSuite) ForwardCoverage() async.R { expected := "a test string" resolved, s0 := async.NewStringR() s0.Complete(expected) // Instead of resolving the return result, forward it to an already resolved value. w := async.WhenString(async.Done(), func() async.StringR { r, s := async.NewStringR() s.Forward(resolved) return r }) // Verify that the value was round-tripped. return async.When(w, func(val string, err error) error { if err != nil { return fmt.Errorf("Expected success. Got: %v, Want: nil", err) } if val != expected { return fmt.Errorf("Expected value. Got: %v, Want: %v", val, expected) } return nil }) }