github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/worker/dependency/util_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package dependency_test 5 6 import ( 7 "time" 8 9 gc "gopkg.in/check.v1" 10 "launchpad.net/tomb" 11 12 coretesting "github.com/juju/juju/testing" 13 "github.com/juju/juju/worker" 14 "github.com/juju/juju/worker/dependency" 15 ) 16 17 type manifoldHarness struct { 18 inputs []string 19 errors chan error 20 starts chan struct{} 21 ignoreExternalKill bool 22 } 23 24 func newManifoldHarness(inputs ...string) *manifoldHarness { 25 return &manifoldHarness{ 26 inputs: inputs, 27 errors: make(chan error, 1000), 28 starts: make(chan struct{}, 1000), 29 ignoreExternalKill: false, 30 } 31 } 32 33 // newErrorIgnoringManifoldHarness starts a minimal worker that ignores 34 // fatal errors - and will never die. 35 // This is potentially nasty, but it's useful in tests where we want 36 // to generate fatal errors but not race on which one the engine see first. 37 func newErrorIgnoringManifoldHarness(inputs ...string) *manifoldHarness { 38 return &manifoldHarness{ 39 inputs: inputs, 40 errors: make(chan error, 1000), 41 starts: make(chan struct{}, 1000), 42 ignoreExternalKill: true, 43 } 44 } 45 46 func (ews *manifoldHarness) Manifold() dependency.Manifold { 47 return dependency.Manifold{ 48 Inputs: ews.inputs, 49 Start: ews.start, 50 } 51 } 52 func (ews *manifoldHarness) start(getResource dependency.GetResourceFunc) (worker.Worker, error) { 53 for _, resourceName := range ews.inputs { 54 if err := getResource(resourceName, nil); err != nil { 55 return nil, err 56 } 57 } 58 w := &minimalWorker{tomb.Tomb{}, ews.ignoreExternalKill} 59 go func() { 60 defer w.tomb.Done() 61 ews.starts <- struct{}{} 62 select { 63 case <-w.tombDying(): 64 case err := <-ews.errors: 65 w.tomb.Kill(err) 66 } 67 }() 68 return w, nil 69 } 70 71 func (ews *manifoldHarness) AssertOneStart(c *gc.C) { 72 ews.AssertStart(c) 73 ews.AssertNoStart(c) 74 } 75 76 func (ews *manifoldHarness) AssertStart(c *gc.C) { 77 select { 78 case <-ews.starts: 79 case <-time.After(coretesting.LongWait): 80 c.Fatalf("never started") 81 } 82 } 83 84 func (ews *manifoldHarness) AssertNoStart(c *gc.C) { 85 select { 86 case <-time.After(coretesting.ShortWait): 87 case <-ews.starts: 88 c.Fatalf("started unexpectedly") 89 } 90 } 91 92 func (ews *manifoldHarness) InjectError(c *gc.C, err error) { 93 select { 94 case ews.errors <- err: 95 case <-time.After(coretesting.LongWait): 96 c.Fatalf("never sent") 97 } 98 } 99 100 type minimalWorker struct { 101 tomb tomb.Tomb 102 ignoreExternalKill bool 103 } 104 105 func (w *minimalWorker) tombDying() <-chan struct{} { 106 if w.ignoreExternalKill { 107 return nil 108 } 109 return w.tomb.Dying() 110 } 111 112 func (w *minimalWorker) Kill() { 113 w.tomb.Kill(nil) 114 } 115 116 func (w *minimalWorker) Wait() error { 117 return w.tomb.Wait() 118 } 119 120 func startMinimalWorker(_ dependency.GetResourceFunc) (worker.Worker, error) { 121 w := &minimalWorker{} 122 go func() { 123 <-w.tomb.Dying() 124 w.tomb.Done() 125 }() 126 return w, nil 127 } 128 129 func nothingFatal(_ error) bool { 130 return false 131 }