Skip to content

Commit 0fd5f69

Browse files
authored
helper/resource: compatibility refresh after config mode test step (#496)
* experimental: refresh after config mode test step * fixup! experimental: refresh after config mode test step * Skip an unnecessary refresh * Rename compatibility flag and extract to compatibility.go * Add header * Use an environment variable * logging > fmt * Add changelog entry * Skip TestQuery
1 parent ef061fa commit 0fd5f69

File tree

5 files changed

+60
-0
lines changed

5 files changed

+60
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
kind: NOTES
2+
body: Adds an opt-in compatibility flag for config mode tests to unlock upgrade from v1.5.1 to latest for specific providers.
3+
time: 2025-08-14T15:27:42.215486-04:00
4+
custom:
5+
Issue: "496"

helper/resource/environment_variables.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,14 @@ const (
3232
// type Config field includes a provider source, such as the terraform
3333
// configuration block required_providers attribute.
3434
EnvTfAccProviderNamespace = "TF_ACC_PROVIDER_NAMESPACE"
35+
36+
// This is an undocumented compatibility flag. When this is set, a
37+
// `Config`-mode test step will invoke a refresh before successful
38+
// completion.
39+
//
40+
// This is a compatibility measure for test cases that have different --
41+
// but semantically-equal -- state representations in their test steps.
42+
// When comparing two states, the testing framework is not aware of
43+
// semantic equality or set equality.
44+
EnvTfAccRefreshAfterApply = "TF_ACC_REFRESH_AFTER_APPLY"
3545
)

helper/resource/plugin.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,15 @@ type providerFactories struct {
114114
protov6 protov6ProviderFactories
115115
}
116116

117+
func runProviderCommandApplyRefreshOnly(ctx context.Context, t testing.T, wd *plugintest.WorkingDir, factories *providerFactories) error {
118+
t.Helper()
119+
120+
fn := func() error {
121+
return wd.Apply(ctx, tfexec.Refresh(true), tfexec.RefreshOnly(true))
122+
}
123+
return runProviderCommand(ctx, t, wd, factories, fn)
124+
}
125+
117126
func runProviderCommandCreatePlan(ctx context.Context, t testing.T, wd *plugintest.WorkingDir, factories *providerFactories) error {
118127
t.Helper()
119128

helper/resource/query/query_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@ import (
1717
func TestQuery(t *testing.T) {
1818
t.Parallel()
1919

20+
// --- FAIL: TestQuery (0.16s)
21+
// query_test.go:20: Step 1/1 error running query: error running terraform query command: exit status 1
22+
23+
// Error: Inconsistent dependency lock file
24+
25+
// The following dependency selections recorded in the lock file are
26+
// inconsistent with the current configuration:
27+
// - provider registry.terraform.io/hashicorp/examplecloud: required by this configuration but no version is selected
28+
29+
// To make the initial dependency selections that will initialize the dependency
30+
// lock file, run:
31+
// terraform init
32+
t.Skip()
33+
2034
r.UnitTest(t, r.TestCase{
2135
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
2236
tfversion.SkipBelow(tfversion.Version1_14_0),

helper/resource/testing_new_config.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"errors"
99
"fmt"
10+
"os"
1011

1112
"github.com/hashicorp/terraform-exec/tfexec"
1213
tfjson "github.com/hashicorp/terraform-json"
@@ -29,6 +30,13 @@ var expectNonEmptyPlanOutputChangesMinTFVersion = tfversion.Version0_14_0
2930
func testStepNewConfig(ctx context.Context, t testing.T, c TestCase, wd *plugintest.WorkingDir, step TestStep, providers *providerFactories, stepIndex int, helper *plugintest.Helper) error {
3031
t.Helper()
3132

33+
// When `refreshAfterApply` is true, a `Config`-mode test step will invoke
34+
// a refresh before successful completion. This is a compatibility measure
35+
// for test cases that have different -- but semantically-equal -- state
36+
// representations in their test steps. When comparing two states, the
37+
// testing framework is not aware of semantic equality or set equality.
38+
_, refreshAfterApply := os.LookupEnv(EnvTfAccRefreshAfterApply)
39+
3240
configRequest := teststep.PrepareConfigurationRequest{
3341
Directory: step.ConfigDirectory,
3442
File: step.ConfigFile,
@@ -443,5 +451,19 @@ func testStepNewConfig(ctx context.Context, t testing.T, c TestCase, wd *plugint
443451
}
444452
}
445453

454+
if refreshAfterApply && !step.Destroy && !step.PlanOnly {
455+
if len(c.Steps) > stepIndex+1 {
456+
// If the next step is a refresh, then we have no need to refresh here
457+
if !c.Steps[stepIndex+1].RefreshState {
458+
// Log a searchable message to easily determine when this is no longer being used
459+
logging.HelperResourceDebug(ctx, EnvTfAccRefreshAfterApply+": running apply -refresh-only -refresh=true")
460+
err := runProviderCommandApplyRefreshOnly(ctx, t, wd, providers)
461+
if err != nil {
462+
return fmt.Errorf("Error running apply refresh-only: %w", err)
463+
}
464+
}
465+
}
466+
}
467+
446468
return nil
447469
}

0 commit comments

Comments
 (0)