Skip to content

Commit eb7249d

Browse files
mildwonkeypselle
authored andcommitted
Mildwonkey/tests (#24548)
* helper/resource: remove provider resolver test * repl tests passing * helper/resource: add some extra shimming to ShimLegacyState Some of the tests in helper/resource have to shim between legacy and modern states. Terraform expects modern states to have the Provider set for each resource (and not be a legacy provider). This PR adds a wrapper around terraform.ShimLegacyState which iterates through the resources in the state (after the shim) and adds the provider FQN.
1 parent 1fc24e3 commit eb7249d

File tree

7 files changed

+147
-92
lines changed

7 files changed

+147
-92
lines changed

helper/resource/state_shim.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func shimNewState(newState *states.State, providers map[string]terraform.Resourc
5555
for key, i := range res.Instances {
5656
resState := &terraform.ResourceState{
5757
Type: resType,
58-
Provider: res.ProviderConfig.LegacyString(),
58+
Provider: legacyProviderConfigString(res.ProviderConfig),
5959
}
6060

6161
// We should always have a Current instance here, but be safe about checking.
@@ -186,3 +186,37 @@ func shimmedAttributes(instance *states.ResourceInstanceObjectSrc, res *schema.R
186186

187187
return instanceState.Attributes, nil
188188
}
189+
190+
func shimLegacyState(legacy *terraform.State) (*states.State, error) {
191+
state, err := terraform.ShimLegacyState(legacy)
192+
if err != nil {
193+
return nil, err
194+
}
195+
196+
if state.HasResources() {
197+
for _, module := range state.Modules {
198+
for name, resource := range module.Resources {
199+
module.Resources[name].ProviderConfig.Provider = addrs.ImpliedProviderForUnqualifiedType(resource.Addr.Resource.ImpliedProvider())
200+
}
201+
}
202+
}
203+
return state, err
204+
}
205+
206+
// legacyProviderConfigString was copied from addrs.Provider.LegacyString() to
207+
// create a legacy-style string from a non-legacy provider. This is only
208+
// necessary as this package shims back and forth between legacy and modern
209+
// state, neither of which encode the addrs.Provider for a resource.
210+
func legacyProviderConfigString(pc addrs.AbsProviderConfig) string {
211+
if pc.Alias != "" {
212+
if len(pc.Module) == 0 {
213+
return fmt.Sprintf("%s.%s.%s", "provider", pc.Provider.Type, pc.Alias)
214+
} else {
215+
return fmt.Sprintf("%s.%s.%s.%s", pc.Module.String(), "provider", pc.Provider.LegacyString(), pc.Alias)
216+
}
217+
}
218+
if len(pc.Module) == 0 {
219+
return fmt.Sprintf("%s.%s", "provider", pc.Provider.Type)
220+
}
221+
return fmt.Sprintf("%s.%s.%s", pc.Module.String(), "provider", pc.Provider.Type)
222+
}

helper/resource/state_shim_test.go

Lines changed: 97 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func TestStateShim(t *testing.T) {
4242
},
4343
},
4444
addrs.AbsProviderConfig{
45-
Provider: addrs.NewLegacyProvider("test"),
45+
Provider: addrs.NewDefaultProvider("test"),
4646
Module: addrs.RootModule,
4747
},
4848
)
@@ -58,7 +58,7 @@ func TestStateShim(t *testing.T) {
5858
DependsOn: []addrs.Referenceable{},
5959
},
6060
addrs.AbsProviderConfig{
61-
Provider: addrs.NewLegacyProvider("test"),
61+
Provider: addrs.NewDefaultProvider("test"),
6262
Module: addrs.RootModule,
6363
},
6464
)
@@ -77,7 +77,7 @@ func TestStateShim(t *testing.T) {
7777
DependsOn: []addrs.Referenceable{},
7878
},
7979
addrs.AbsProviderConfig{
80-
Provider: addrs.NewLegacyProvider("test"),
80+
Provider: addrs.NewDefaultProvider("test"),
8181
Module: childInstance.Module(),
8282
},
8383
)
@@ -101,7 +101,7 @@ func TestStateShim(t *testing.T) {
101101
},
102102
},
103103
addrs.AbsProviderConfig{
104-
Provider: addrs.NewLegacyProvider("test"),
104+
Provider: addrs.NewDefaultProvider("test"),
105105
Module: childInstance.Module(),
106106
},
107107
)
@@ -127,7 +127,7 @@ func TestStateShim(t *testing.T) {
127127
},
128128
},
129129
addrs.AbsProviderConfig{
130-
Provider: addrs.NewLegacyProvider("test"),
130+
Provider: addrs.NewDefaultProvider("test"),
131131
Module: childInstance.Module(),
132132
},
133133
)
@@ -144,7 +144,7 @@ func TestStateShim(t *testing.T) {
144144
DependsOn: []addrs.Referenceable{},
145145
},
146146
addrs.AbsProviderConfig{
147-
Provider: addrs.NewLegacyProvider("test"),
147+
Provider: addrs.NewDefaultProvider("test"),
148148
Module: childInstance.Module(),
149149
},
150150
)
@@ -160,7 +160,7 @@ func TestStateShim(t *testing.T) {
160160
DependsOn: []addrs.Referenceable{},
161161
},
162162
addrs.AbsProviderConfig{
163-
Provider: addrs.NewLegacyProvider("test"),
163+
Provider: addrs.NewDefaultProvider("test"),
164164
Module: childInstance.Module(),
165165
},
166166
)
@@ -177,7 +177,7 @@ func TestStateShim(t *testing.T) {
177177
DependsOn: []addrs.Referenceable{},
178178
},
179179
addrs.AbsProviderConfig{
180-
Provider: addrs.NewLegacyProvider("test"),
180+
Provider: addrs.NewDefaultProvider("test"),
181181
Module: childInstance.Module(),
182182
},
183183
)
@@ -332,3 +332,92 @@ func TestStateShim(t *testing.T) {
332332
t.Fatalf("wrong result state\ngot:\n%s\n\nwant:\n%s", shimmed, expected)
333333
}
334334
}
335+
336+
// TestShimLegacyState only checks the functionality unique to this func: adding
337+
// the implied provider FQN
338+
func TestShimLegacyState(t *testing.T) {
339+
340+
input := &terraform.State{
341+
Version: 3,
342+
Modules: []*terraform.ModuleState{
343+
&terraform.ModuleState{
344+
Path: []string{"root"},
345+
Resources: map[string]*terraform.ResourceState{
346+
"test_thing.baz": &terraform.ResourceState{
347+
Type: "test_thing",
348+
Provider: "provider.test",
349+
Primary: &terraform.InstanceState{
350+
ID: "baz",
351+
Attributes: map[string]string{
352+
"id": "baz",
353+
"bazzle": "dazzle",
354+
},
355+
},
356+
},
357+
},
358+
},
359+
&terraform.ModuleState{
360+
Path: []string{"root", "child"},
361+
Resources: map[string]*terraform.ResourceState{
362+
"test_thing.bar": &terraform.ResourceState{
363+
Type: "test_thing",
364+
Provider: "module.child.provider.test",
365+
Primary: &terraform.InstanceState{
366+
ID: "bar",
367+
Attributes: map[string]string{
368+
"id": "bar",
369+
"fizzle": "wizzle",
370+
},
371+
},
372+
},
373+
},
374+
},
375+
},
376+
}
377+
378+
expected := states.NewState()
379+
root := expected.EnsureModule(addrs.RootModuleInstance)
380+
root.SetResourceInstanceCurrent(
381+
addrs.Resource{
382+
Mode: addrs.ManagedResourceMode,
383+
Type: "test_thing",
384+
Name: "baz",
385+
}.Instance(addrs.NoKey),
386+
&states.ResourceInstanceObjectSrc{
387+
Status: states.ObjectReady,
388+
AttrsFlat: map[string]string{"id": "baz", "bazzle": "dazzle"},
389+
DependsOn: []addrs.Referenceable{},
390+
Dependencies: []addrs.ConfigResource{},
391+
},
392+
addrs.AbsProviderConfig{
393+
Provider: addrs.NewDefaultProvider("test"),
394+
Module: addrs.RootModule,
395+
},
396+
)
397+
child := expected.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey))
398+
child.SetResourceInstanceCurrent(
399+
addrs.Resource{
400+
Mode: addrs.ManagedResourceMode,
401+
Type: "test_thing",
402+
Name: "bar",
403+
}.Instance(addrs.NoKey),
404+
&states.ResourceInstanceObjectSrc{
405+
Status: states.ObjectReady,
406+
AttrsFlat: map[string]string{"id": "bar", "fizzle": "wizzle"},
407+
DependsOn: []addrs.Referenceable{},
408+
Dependencies: []addrs.ConfigResource{},
409+
},
410+
addrs.AbsProviderConfig{
411+
Provider: addrs.NewDefaultProvider("test"),
412+
Module: child.Addr.Module(),
413+
},
414+
)
415+
416+
got, err := shimLegacyState(input)
417+
if err != nil {
418+
t.Fatalf("unexpected error: %s", err)
419+
}
420+
if !got.Equal(expected) {
421+
t.Fatal("wrong result")
422+
}
423+
}

helper/resource/testing.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ func testProviderFactories(c TestCase) (map[addrs.Provider]providers.Factory, er
689689
newProviders := make(map[addrs.Provider]providers.Factory)
690690
for legacyName, pf := range ctxProviders {
691691
factory := pf // must copy to ensure each closure sees its own value
692-
newProviders[addrs.NewLegacyProvider(legacyName)] = func() (providers.Interface, error) {
692+
newProviders[addrs.NewDefaultProvider(legacyName)] = func() (providers.Interface, error) {
693693
p, err := factory()
694694
if err != nil {
695695
return nil, err

helper/resource/testing_config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func testStep(opts terraform.ContextOpts, state *terraform.State, step TestStep)
4343

4444
// Build the context
4545
opts.Config = cfg
46-
opts.State, err = terraform.ShimLegacyState(state)
46+
opts.State, err = shimLegacyState(state)
4747
if err != nil {
4848
return nil, err
4949
}

helper/resource/testing_test.go

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ import (
1414
"testing"
1515

1616
"github.com/hashicorp/go-multierror"
17-
"github.com/hashicorp/terraform/addrs"
18-
"github.com/hashicorp/terraform/helper/schema"
19-
"github.com/hashicorp/terraform/plugin/discovery"
2017
"github.com/hashicorp/terraform/terraform"
2118
)
2219

@@ -1036,77 +1033,6 @@ func TestTest_Taint(t *testing.T) {
10361033
}
10371034
}
10381035

1039-
func TestTestProviderResolver(t *testing.T) {
1040-
stubProvider := func(name string) terraform.ResourceProvider {
1041-
return &schema.Provider{
1042-
Schema: map[string]*schema.Schema{
1043-
name: &schema.Schema{
1044-
Type: schema.TypeString,
1045-
Required: true,
1046-
},
1047-
},
1048-
}
1049-
}
1050-
1051-
c := TestCase{
1052-
ProviderFactories: map[string]terraform.ResourceProviderFactory{
1053-
"foo": terraform.ResourceProviderFactoryFixed(stubProvider("foo")),
1054-
"bar": terraform.ResourceProviderFactoryFixed(stubProvider("bar")),
1055-
},
1056-
Providers: map[string]terraform.ResourceProvider{
1057-
"baz": stubProvider("baz"),
1058-
"bop": stubProvider("bop"),
1059-
},
1060-
}
1061-
1062-
resolver, err := testProviderResolver(c)
1063-
if err != nil {
1064-
t.Fatal(err)
1065-
}
1066-
1067-
reqd := discovery.PluginRequirements{
1068-
"foo": &discovery.PluginConstraints{},
1069-
"bar": &discovery.PluginConstraints{},
1070-
"baz": &discovery.PluginConstraints{},
1071-
"bop": &discovery.PluginConstraints{},
1072-
}
1073-
1074-
factories, errs := resolver.ResolveProviders(reqd)
1075-
if len(errs) != 0 {
1076-
for _, err := range errs {
1077-
t.Error(err)
1078-
}
1079-
t.Fatal("unexpected errors")
1080-
}
1081-
1082-
for name := range reqd {
1083-
t.Run(name, func(t *testing.T) {
1084-
pf, ok := factories[addrs.NewLegacyProvider(name)]
1085-
if !ok {
1086-
t.Fatalf("no factory for %q", name)
1087-
}
1088-
p, err := pf()
1089-
if err != nil {
1090-
t.Fatal(err)
1091-
}
1092-
resp := p.GetSchema()
1093-
_, ok = resp.Provider.Block.Attributes[name]
1094-
if !ok {
1095-
var has string
1096-
for k := range resp.Provider.Block.Attributes {
1097-
has = k
1098-
break
1099-
}
1100-
if has != "" {
1101-
t.Errorf("provider %q does not have the expected schema attribute %q (but has %q)", name, name, has)
1102-
} else {
1103-
t.Errorf("provider %q does not have the expected schema attribute %q", name, name)
1104-
}
1105-
}
1106-
})
1107-
}
1108-
}
1109-
11101036
const testConfigStr = `
11111037
resource "test_instance" "foo" {}
11121038
`

repl/session_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestSession_basicState(t *testing.T) {
4646
AttrsJSON: []byte(`{"id":"bar"}`),
4747
},
4848
addrs.AbsProviderConfig{
49-
Provider: addrs.NewLegacyProvider("test"),
49+
Provider: addrs.NewDefaultProvider("test"),
5050
Module: addrs.RootModule,
5151
},
5252
)
@@ -61,7 +61,7 @@ func TestSession_basicState(t *testing.T) {
6161
AttrsJSON: []byte(`{"id":"bar"}`),
6262
},
6363
addrs.AbsProviderConfig{
64-
Provider: addrs.NewLegacyProvider("test"),
64+
Provider: addrs.NewDefaultProvider("test"),
6565
Module: addrs.RootModule,
6666
},
6767
)
@@ -213,9 +213,9 @@ func testSession(t *testing.T, test testSessionTest) {
213213
// Build the TF context
214214
ctx, diags := terraform.NewContext(&terraform.ContextOpts{
215215
State: test.State,
216-
ProviderResolver: providers.ResolverFixed(map[addrs.Provider]providers.Factory{
217-
addrs.NewLegacyProvider("test"): providers.FactoryFixed(p),
218-
}),
216+
Providers: map[addrs.Provider]providers.Factory{
217+
addrs.NewDefaultProvider("test"): providers.FactoryFixed(p),
218+
},
219219
Config: config,
220220
})
221221
if diags.HasErrors() {

states/statefile/version3_upgrade.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,19 @@ func upgradeStateV3ToV4(old *stateV3) (*stateV4, error) {
136136
return nil, fmt.Errorf("invalid legacy provider config reference %q for %s: %s", oldProviderAddr, instAddr, diags.Err())
137137
}
138138
providerAddr = addrs.AbsProviderConfig{
139-
Module: moduleAddr.Module(),
139+
Module: moduleAddr.Module(),
140+
// We use NewLegacyProvider here so we can use
141+
// LegacyString() below to get the appropriate
142+
// legacy-style provider string.
140143
Provider: addrs.NewLegacyProvider(localAddr.LocalName),
141144
Alias: localAddr.Alias,
142145
}
143146
} else {
144147
providerAddr = addrs.AbsProviderConfig{
145-
Module: moduleAddr.Module(),
148+
Module: moduleAddr.Module(),
149+
// We use NewLegacyProvider here so we can use
150+
// LegacyString() below to get the appropriate
151+
// legacy-style provider string.
146152
Provider: addrs.NewLegacyProvider(resAddr.ImpliedProvider()),
147153
}
148154
}

0 commit comments

Comments
 (0)