@@ -23,6 +23,8 @@ import (
2323
2424var (
2525 protocol5MinVersion = version .Must (version .NewVersion ("0.12.0" ))
26+
27+ gracefulShutdownMinVersion = version .Must (version .NewVersion ("1.1.0" ))
2628)
2729
2830func TestUnparsedError (t * testing.T ) {
@@ -168,9 +170,47 @@ func TestContext_sleepTimeoutExpired(t *testing.T) {
168170 t .Skip ("the ability to interrupt an apply was added in protocol 5.0 in Terraform 0.12, so test is not valid" )
169171 }
170172
171- // sleep will not react to SIGINT
172- // This ensures that process is killed within the expected time limit.
173- tf .SetWaitDelay (500 * time .Millisecond )
173+ if ! tfv .GreaterThanOrEqual (gracefulShutdownMinVersion ) {
174+ // Versions < 1.1 will not react to SIGINT.
175+ // This ensures the process is killed within the expected time limit.
176+ tf .SetEnableLegacyPipeClosing (true )
177+ tf .SetWaitDelay (500 * time .Millisecond )
178+ }
179+
180+ err := tf .Init (context .Background ())
181+ if err != nil {
182+ t .Fatalf ("err during init: %s" , err )
183+ }
184+
185+ ctx := context .Background ()
186+ ctx , cancel := context .WithTimeout (ctx , 5 * time .Second )
187+ defer cancel ()
188+
189+ errCh := make (chan error )
190+ go func () {
191+ err = tf .Apply (ctx )
192+ if err != nil {
193+ errCh <- err
194+ }
195+ }()
196+
197+ select {
198+ case err := <- errCh :
199+ if ! errors .Is (err , context .DeadlineExceeded ) {
200+ t .Fatalf ("expected context.DeadlineExceeded, got %T %s" , err , err )
201+ }
202+ case <- time .After (time .Second * 10 ):
203+ t .Fatal ("terraform apply should have canceled and returned in ~5s" )
204+ }
205+ })
206+ }
207+
208+ func TestContext_sleepGracefulShutdown (t * testing.T ) {
209+ runTest (t , "sleep" , func (t * testing.T , tfv * version.Version , tf * tfexec.Terraform ) {
210+ // only testing versions that can shut down gracefully
211+ if ! tfv .GreaterThanOrEqual (gracefulShutdownMinVersion ) {
212+ t .Skip ("graceful shutdown was added in Terraform 1.1, so test is not valid" )
213+ }
174214
175215 err := tf .Init (context .Background ())
176216 if err != nil {
@@ -194,6 +234,16 @@ func TestContext_sleepTimeoutExpired(t *testing.T) {
194234 if ! errors .Is (err , context .DeadlineExceeded ) {
195235 t .Fatalf ("expected context.DeadlineExceeded, got %T %s" , err , err )
196236 }
237+ var ee * exec.ExitError
238+ if ! errors .As (err , & ee ) {
239+ t .Fatalf ("expected exec.ExitError, got %T, %s" , err , err )
240+ }
241+ if ! ee .Exited () {
242+ t .Fatalf ("expected process to have exited, but it did not (%s)" , ee .ProcessState .String ())
243+ }
244+ if ee .ExitCode () != 1 {
245+ t .Fatalf ("expected exit code 1, got %d" , ee .ExitCode ())
246+ }
197247 case <- time .After (time .Second * 10 ):
198248 t .Fatal ("terraform apply should have canceled and returned in ~5s" )
199249 }
0 commit comments