github.com/adrian-bl/terraform@v0.7.0-rc2.0.20160705220747-de0a34fc3517/terraform/upgrade_state_v1_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"bytes"
     5  	"reflect"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/davecgh/go-spew/spew"
    10  )
    11  
    12  // TestReadUpgradeStateV1toV3 tests the state upgrade process from the V1 state
    13  // to the current version, and needs editing each time. This means it tests the
    14  // entire pipeline of upgrades (which migrate version to version).
    15  func TestReadUpgradeStateV1toV3(t *testing.T) {
    16  	// ReadState should transparently detect the old version but will upgrade
    17  	// it on Write.
    18  	actual, err := ReadState(strings.NewReader(testV1State))
    19  	if err != nil {
    20  		t.Fatalf("err: %s", err)
    21  	}
    22  
    23  	buf := new(bytes.Buffer)
    24  	if err := WriteState(actual, buf); err != nil {
    25  		t.Fatalf("err: %s", err)
    26  	}
    27  
    28  	if actual.Version != 3 {
    29  		t.Fatalf("bad: State version not incremented; is %d", actual.Version)
    30  	}
    31  
    32  	roundTripped, err := ReadState(buf)
    33  	if err != nil {
    34  		t.Fatalf("err: %s", err)
    35  	}
    36  
    37  	if !reflect.DeepEqual(actual, roundTripped) {
    38  		t.Fatalf("bad: %#v", actual)
    39  	}
    40  }
    41  
    42  func TestReadUpgradeStateV1toV3_outputs(t *testing.T) {
    43  	// ReadState should transparently detect the old version but will upgrade
    44  	// it on Write.
    45  	actual, err := ReadState(strings.NewReader(testV1StateWithOutputs))
    46  	if err != nil {
    47  		t.Fatalf("err: %s", err)
    48  	}
    49  
    50  	buf := new(bytes.Buffer)
    51  	if err := WriteState(actual, buf); err != nil {
    52  		t.Fatalf("err: %s", err)
    53  	}
    54  
    55  	if actual.Version != 3 {
    56  		t.Fatalf("bad: State version not incremented; is %d", actual.Version)
    57  	}
    58  
    59  	roundTripped, err := ReadState(buf)
    60  	if err != nil {
    61  		t.Fatalf("err: %s", err)
    62  	}
    63  
    64  	if !reflect.DeepEqual(actual, roundTripped) {
    65  		spew.Config.DisableMethods = true
    66  		t.Fatalf("bad:\n%s\n\nround tripped:\n%s\n", spew.Sdump(actual), spew.Sdump(roundTripped))
    67  		spew.Config.DisableMethods = false
    68  	}
    69  }
    70  
    71  // Upgrading the state should not lose empty module Outputs and Resources maps
    72  // during upgrade. The init for a new module initializes new maps, so we may not
    73  // be expecting to check for a nil map.
    74  func TestReadUpgradeStateV1toV3_emptyState(t *testing.T) {
    75  	// ReadState should transparently detect the old version but will upgrade
    76  	// it on Write.
    77  	orig, err := ReadStateV1([]byte(testV1EmptyState))
    78  	if err != nil {
    79  		t.Fatalf("err: %s", err)
    80  	}
    81  
    82  	stateV2, err := upgradeStateV1ToV2(orig)
    83  	for _, m := range stateV2.Modules {
    84  		if m.Resources == nil {
    85  			t.Fatal("V1 to V2 upgrade lost module.Resources")
    86  		}
    87  		if m.Outputs == nil {
    88  			t.Fatal("V1 to V2 upgrade lost module.Outputs")
    89  		}
    90  	}
    91  
    92  	stateV3, err := upgradeStateV2ToV3(stateV2)
    93  	for _, m := range stateV3.Modules {
    94  		if m.Resources == nil {
    95  			t.Fatal("V2 to V3 upgrade lost module.Resources")
    96  		}
    97  		if m.Outputs == nil {
    98  			t.Fatal("V2 to V3 upgrade lost module.Outputs")
    99  		}
   100  	}
   101  
   102  }
   103  
   104  const testV1EmptyState = `{
   105      "version": 1,
   106      "serial": 0,
   107      "modules": [
   108          {
   109              "path": [
   110                  "root"
   111              ],
   112              "outputs": {},
   113              "resources": {}
   114          }
   115      ]
   116  }
   117  `
   118  
   119  const testV1State = `{
   120      "version": 1,
   121      "serial": 9,
   122      "remote": {
   123          "type": "http",
   124          "config": {
   125              "url": "http://my-cool-server.com/"
   126          }
   127      },
   128      "modules": [
   129          {
   130              "path": [
   131                  "root"
   132              ],
   133              "outputs": null,
   134              "resources": {
   135                  "foo": {
   136                      "type": "",
   137                      "primary": {
   138                          "id": "bar"
   139                      }
   140                  }
   141              },
   142              "depends_on": [
   143                  "aws_instance.bar"
   144              ]
   145          }
   146      ]
   147  }
   148  `
   149  
   150  const testV1StateWithOutputs = `{
   151      "version": 1,
   152      "serial": 9,
   153      "remote": {
   154          "type": "http",
   155          "config": {
   156              "url": "http://my-cool-server.com/"
   157          }
   158      },
   159      "modules": [
   160          {
   161              "path": [
   162                  "root"
   163              ],
   164              "outputs": {
   165              	"foo": "bar",
   166              	"baz": "foo"
   167              },
   168              "resources": {
   169                  "foo": {
   170                      "type": "",
   171                      "primary": {
   172                          "id": "bar"
   173                      }
   174                  }
   175              },
   176              "depends_on": [
   177                  "aws_instance.bar"
   178              ]
   179          }
   180      ]
   181  }
   182  `