read+write the new dependencies in the statefile

The test fixture did not like having modules when using the generic json
map, so read and compare the states in the final *File datastructure.
This commit is contained in:
James Bardin 2019-10-15 18:10:54 -04:00
parent 2c3c011f20
commit 5a0a0020a0
9 changed files with 169 additions and 24 deletions

View File

@ -88,6 +88,7 @@ func (os *ResourceInstanceObjectSrc) Decode(ty cty.Type) (*ResourceInstanceObjec
Value: val,
Status: os.Status,
Dependencies: os.Dependencies,
DependsOn: os.DependsOn,
Private: os.Private,
}, nil
}

View File

@ -172,6 +172,7 @@ func (obj *ResourceInstanceObjectSrc) DeepCopy() *ResourceInstanceObjectSrc {
AttrsFlat: attrsFlat,
AttrsJSON: attrsJSON,
Dependencies: dependencies,
DependsOn: dependsOn,
}
}

View File

@ -2,7 +2,6 @@ package statefile
import (
"bytes"
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
@ -11,8 +10,6 @@ import (
"testing"
"github.com/go-test/deep"
tfversion "github.com/hashicorp/terraform/version"
)
func TestRoundtrip(t *testing.T) {
@ -22,8 +19,6 @@ func TestRoundtrip(t *testing.T) {
t.Fatal(err)
}
currentVersion := tfversion.Version
for _, info := range entries {
const inSuffix = ".in.tfstate"
const outSuffix = ".out.tfstate"
@ -39,14 +34,20 @@ func TestRoundtrip(t *testing.T) {
outName := name + outSuffix
t.Run(name, func(t *testing.T) {
ir, err := os.Open(filepath.Join(dir, inName))
if err != nil {
t.Fatal(err)
}
oSrcWant, err := ioutil.ReadFile(filepath.Join(dir, outName))
if err != nil {
t.Fatal(err)
}
oWant, diags := readStateV4(oSrcWant)
if diags.HasErrors() {
t.Fatal(diags.Err())
}
ir, err := os.Open(filepath.Join(dir, inName))
if err != nil {
t.Fatal(err)
}
defer ir.Close()
f, err := Read(ir)
if err != nil {
@ -58,20 +59,12 @@ func TestRoundtrip(t *testing.T) {
if err != nil {
t.Fatal(err)
}
oSrcGot := buf.Bytes()
oSrcWritten := buf.Bytes()
var oGot, oWant map[string]interface{}
err = json.Unmarshal(oSrcGot, &oGot)
if err != nil {
t.Fatalf("result isn't JSON: %s", err)
oGot, diags := readStateV4(oSrcWritten)
if diags.HasErrors() {
t.Fatal(diags.Err())
}
err = json.Unmarshal(oSrcWant, &oWant)
if err != nil {
t.Fatalf("wanted result isn't JSON: %s", err)
}
// A newly written state should always reflect the current terraform version.
oWant["terraform_version"] = currentVersion
problems := deep.Equal(oGot, oWant)
sort.Strings(problems)

View File

@ -0,0 +1,36 @@
{
"version": 4,
"serial": 0,
"lineage": "f2968801-fa14-41ab-a044-224f3a4adf04",
"terraform_version": "0.12.0",
"outputs": {
"numbers": {
"type": "string",
"value": "0,1"
}
},
"resources": [
{
"module": "module.modA",
"mode": "managed",
"type": "null_resource",
"name": "resource",
"provider": "provider.null",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "4639265839606265182",
"triggers": {
"input": "test"
}
},
"private": "bnVsbA==",
"depends_on": [
"var.input"
]
}
]
}
]
}

View File

@ -0,0 +1 @@
v4-foreach.in.tfstate

View File

@ -0,0 +1,88 @@
{
"version": 4,
"terraform_version": "0.12.0",
"serial": 0,
"lineage": "f2968801-fa14-41ab-a044-224f3a4adf04",
"outputs": {
"numbers": {
"value": "0,1",
"type": "string"
}
},
"resources": [
{
"mode": "managed",
"type": "null_resource",
"name": "bar",
"provider": "provider.null",
"instances": [
{
"schema_version": 0,
"attributes_flat": {
"id": "5388490630832483079",
"triggers.%": "1",
"triggers.whaaat": "0,1"
},
"depends_on": [
"null_resource.foo"
]
}
]
},
{
"module": "module.modB",
"mode": "managed",
"type": "null_resource",
"name": "bar",
"each": "map",
"provider": "provider.null",
"instances": [
{
"index_key": "a",
"schema_version": 0,
"attributes_flat": {
"id": "8212585058302700791"
},
"dependencies": [
"module.modA.null_resource.resource"
]
},
{
"index_key": "b",
"schema_version": 0,
"attributes_flat": {
"id": "1523897709610803586"
},
"dependencies": [
"module.modA.null_resource.resource"
]
}
]
},
{
"module": "module.modA",
"mode": "managed",
"type": "null_resource",
"name": "resource",
"provider": "provider.null",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "4639265839606265182",
"triggers": {
"input": "test"
}
},
"private": "bnVsbA==",
"dependencies": [
"null_resource.bar"
],
"depends_on": [
"var.input"
]
}
]
}
]
}

View File

@ -0,0 +1 @@
v4-modules.in.tfstate

View File

@ -313,7 +313,7 @@ func upgradeInstanceObjectV3ToV4(rsOld *resourceStateV2, isOld *instanceStateV2,
Status: status,
Deposed: string(deposedKey),
AttributesFlat: attributes,
Dependencies: dependencies,
DependsOn: dependencies,
SchemaVersion: schemaVersion,
PrivateRaw: privateJSON,
}, nil

View File

@ -181,7 +181,10 @@ func prepareStateV4(sV4 *stateV4) (*File, tfdiags.Diagnostics) {
}
{
depsRaw := isV4.Dependencies
// Allow both the deprecated `depends_on` and new
// `dependencies` to coexist for now so resources can be
// upgraded as they are refreshed.
depsRaw := isV4.DependsOn
deps := make([]addrs.Referenceable, 0, len(depsRaw))
for _, depRaw := range depsRaw {
ref, refDiags := addrs.ParseRefStr(depRaw)
@ -202,6 +205,20 @@ func prepareStateV4(sV4 *stateV4) (*File, tfdiags.Diagnostics) {
}
deps = append(deps, ref.Subject)
}
obj.DependsOn = deps
}
{
depsRaw := isV4.Dependencies
deps := make([]addrs.AbsResource, 0, len(depsRaw))
for _, depRaw := range depsRaw {
addr, addrDiags := addrs.ParseAbsResourceStr(depRaw)
diags = diags.Append(addrDiags)
if addrDiags.HasErrors() {
continue
}
deps = append(deps, addr)
}
obj.Dependencies = deps
}
@ -466,6 +483,11 @@ func appendInstanceObjectStateV4(rs *states.Resource, is *states.ResourceInstanc
deps[i] = depAddr.String()
}
depOn := make([]string, len(obj.DependsOn))
for i, depAddr := range obj.DependsOn {
depOn[i] = depAddr.String()
}
var rawKey interface{}
switch tk := key.(type) {
case addrs.IntKey:
@ -491,6 +513,7 @@ func appendInstanceObjectStateV4(rs *states.Resource, is *states.ResourceInstanc
AttributesRaw: obj.AttrsJSON,
PrivateRaw: privateRaw,
Dependencies: deps,
DependsOn: depOn,
}), diags
}
@ -540,7 +563,8 @@ type instanceObjectStateV4 struct {
PrivateRaw []byte `json:"private,omitempty"`
Dependencies []string `json:"depends_on,omitempty"`
Dependencies []string `json:"dependencies,omitempty"`
DependsOn []string `json:"depends_on,omitempty"`
}
// stateVersionV4 is a weird special type we use to produce our hard-coded