Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Terraform Test: Allow skipping cleanup of entire test file or individual run blocks #36729

Open
wants to merge 3 commits into
base: f-controlling-destroys
Choose a base branch
from

Conversation

dsa0x
Copy link
Member

@dsa0x dsa0x commented Mar 20, 2025

Implements skip_cleanup, which allows skipping the cleanup of individual run blocks or the entire test file. This simply ensures that the cleanup stage for the state is an apply of the run requesting the skip, instead of the normal destroy

Target Release

1.12.x

CHANGELOG entry

  • This change is user-facing and I added a changelog entry.
  • This change is not user-facing.

@dsa0x dsa0x added the no-changelog-needed Add this to your PR if the change does not require a changelog entry label Mar 20, 2025
@dsa0x dsa0x force-pushed the sams/test_skip_cleanup branch from 88896d6 to 7f4cb14 Compare March 20, 2025 16:50
@dsa0x dsa0x marked this pull request as ready for review March 20, 2025 17:37
@dsa0x dsa0x requested a review from a team as a code owner March 20, 2025 17:37
Comment on lines +2317 to +2336
stateGetter := func(stateKey string) (*states.State, error) {
backend := local.New()
dir := filepath.Dir(stateKey)
backendConfig := cty.ObjectVal(map[string]cty.Value{
"path": cty.StringVal(stateKey),
"workspace_dir": cty.StringVal(dir),
})
diags := backend.Configure(backendConfig)
if diags.HasErrors() {
return nil, fmt.Errorf("failed to configure backend: %s", diags)
}

mgr, err := backend.StateMgr("default")
if err != nil {
return nil, fmt.Errorf("failed to create state manager: %s", err)
}
if err := mgr.RefreshState(); err != nil {
return nil, fmt.Errorf("failed to refresh state: %s", err)
}
return mgr.State(), nil
Copy link
Member

@SarahFrench SarahFrench Mar 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been learning about the state packages recently, and an easier way to implement code that does this is using a statemgr.Filesystem:

// stateKey is value like ".terraform/test/TpQOqtev.tfstate"
sm := statemgr.NewFilesystem(stateKey)
err := sm.RefreshState()
if err != nil {
    return nil, fmt.Errorf("error when reading state file: %w", err)
}
return sm.State(), err

Alternatively, I think your helper can be replaced with the pre-existing testStateRead function! I've just been refactoring some code to remove my own implementation of this helper also, and it looks like there are a number of helpers like this in the codebase 😂

@SarahFrench SarahFrench requested a review from a team March 25, 2025 15:12
Copy link
Member

@SarahFrench SarahFrench left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few comments:

  • Some nit-like comments about how terminal output could make it clearer about whether cleanup is being skipped, and why.
  • A comment about some scenarios with conflicting skip_cleanup instructions that it might be useful to add tests for.

In the case of conflicting skip_cleanup instructions from run blocks versus the test block, should that cause a parsing error or should the test run and during cleanup users see a warning about the conflicting instructions?

Comment on lines +2278 to +2282
run "test_three"... pass
run "test_four"... pass
run "test_five"... pass
main.tftest.hcl... tearing down
main.tftest.hcl... pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the happy path (i.e. when the warning isn't present in the terminal output) would it be beneficial to indicate that the tearing down process is affected by skip_cleanup?

E.g.

  run "test_five"... pass
main.tftest.hcl... tearing down
+    cleanup stopped at run "test_three" due to use of skip_cleanup
main.tftest.hcl... pass

Comment on lines +2560 to +2562
run "test_five"... pass
main.tftest.hcl... tearing down
main.tftest.hcl... pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If teardown is prevented for the entire file through the test block, is that information available early enough to affect this terminal output? A user seeing that output might think that the skip_clean up wasn't working, until they check state.

E.g.

- main.tftest.hcl... tearing down
+ main.tftest.hcl... tear down skipped for this file
main.tftest.hcl... pass

or

main.tftest.hcl... tearing down
+    clean up is skipped for this file
main.tftest.hcl... pass

@@ -2214,6 +2214,373 @@ Success! 5 passed, 0 failed.
}
}

func TestTest_SkipCleanup(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the expected behaviour when a user sets skip_cleanup = true in the test block and also in an individual run block?

Similarly, what's the expected behaviour when a user sets skip_cleanup = false in the test block and skip_cleanup = true in an individual run block? Does the user receive a warning from these two conflicting instructions?

@SarahFrench SarahFrench requested a review from a team March 25, 2025 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-changelog-needed Add this to your PR if the change does not require a changelog entry
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants