File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 44 "errors"
55 "fmt"
66 "sort"
7+ "sync"
78
89 "github.com/hashicorp/go-multierror"
910 "github.com/hashicorp/terraform/terraform"
@@ -49,6 +50,10 @@ type Provider struct {
4950 ConfigureFunc ConfigureFunc
5051
5152 meta interface {}
53+
54+ stopCh chan struct {} // stopCh is closed when Stop is called
55+ stopped bool // set to true once stopped to avoid double close of stopCh
56+ stopLock sync.Mutex
5257}
5358
5459// ConfigureFunc is the function used to configure a Provider.
@@ -104,6 +109,45 @@ func (p *Provider) SetMeta(v interface{}) {
104109 p .meta = v
105110}
106111
112+ // Stopped reports whether the provider has been stopped or not.
113+ func (p * Provider ) Stopped () bool {
114+ p .stopLock .Lock ()
115+ defer p .stopLock .Unlock ()
116+ return p .stopped
117+ }
118+
119+ // StopCh returns a channel that is closed once the provider is stopped.
120+ func (p * Provider ) StopCh () <- chan struct {} {
121+ p .stopLock .Lock ()
122+ defer p .stopLock .Unlock ()
123+
124+ if p .stopCh == nil {
125+ p .stopCh = make (chan struct {})
126+ }
127+
128+ return p .stopCh
129+ }
130+
131+ // Stop implementation of terraform.ResourceProvider interface.
132+ func (p * Provider ) Stop () error {
133+ p .stopLock .Lock ()
134+ defer p .stopLock .Unlock ()
135+
136+ // Close the stop channel and mark as stopped if we haven't
137+ if ! p .stopped {
138+ // Initialize the stop channel so future calls to StopCh work
139+ if p .stopCh == nil {
140+ p .stopCh = make (chan struct {})
141+ }
142+
143+ // Close and mark
144+ close (p .stopCh )
145+ p .stopped = true
146+ }
147+
148+ return nil
149+ }
150+
107151// Input implementation of terraform.ResourceProvider interface.
108152func (p * Provider ) Input (
109153 input terraform.UIInput ,
Original file line number Diff line number Diff line change 44 "fmt"
55 "reflect"
66 "testing"
7+ "time"
78
89 "github.com/hashicorp/terraform/config"
910 "github.com/hashicorp/terraform/terraform"
@@ -328,3 +329,55 @@ func TestProviderMeta(t *testing.T) {
328329 t .Fatalf ("bad: %#v" , v )
329330 }
330331}
332+
333+ func TestProviderStop (t * testing.T ) {
334+ var p Provider
335+
336+ if p .Stopped () {
337+ t .Fatal ("should not be stopped" )
338+ }
339+
340+ // Verify stopch blocks
341+ ch := p .StopCh ()
342+ select {
343+ case <- ch :
344+ t .Fatal ("should not be stopped" )
345+ case <- time .After (10 * time .Millisecond ):
346+ }
347+
348+ // Stop it
349+ if err := p .Stop (); err != nil {
350+ t .Fatalf ("err: %s" , err )
351+ }
352+
353+ // Verify
354+ if ! p .Stopped () {
355+ t .Fatal ("should be stopped" )
356+ }
357+
358+ select {
359+ case <- ch :
360+ case <- time .After (10 * time .Millisecond ):
361+ t .Fatal ("should be stopped" )
362+ }
363+ }
364+
365+ func TestProviderStop_stopFirst (t * testing.T ) {
366+ var p Provider
367+
368+ // Stop it
369+ if err := p .Stop (); err != nil {
370+ t .Fatalf ("err: %s" , err )
371+ }
372+
373+ // Verify
374+ if ! p .Stopped () {
375+ t .Fatal ("should be stopped" )
376+ }
377+
378+ select {
379+ case <- p .StopCh ():
380+ case <- time .After (10 * time .Millisecond ):
381+ t .Fatal ("should be stopped" )
382+ }
383+ }
You can’t perform that action at this time.
0 commit comments