github.com/trawler/terraform@v0.10.8-0.20171106022149-4b1c7a1d9b48/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.Logf("actual:\n%#v", actual)
    39  		t.Fatalf("roundTripped:\n%#v", roundTripped)
    40  	}
    41  }
    42  
    43  func TestReadUpgradeStateV1toV3_outputs(t *testing.T) {
    44  	// ReadState should transparently detect the old version but will upgrade
    45  	// it on Write.
    46  	actual, err := ReadState(strings.NewReader(testV1StateWithOutputs))
    47  	if err != nil {
    48  		t.Fatalf("err: %s", err)
    49  	}
    50  
    51  	buf := new(bytes.Buffer)
    52  	if err := WriteState(actual, buf); err != nil {
    53  		t.Fatalf("err: %s", err)
    54  	}
    55  
    56  	if actual.Version != 3 {
    57  		t.Fatalf("bad: State version not incremented; is %d", actual.Version)
    58  	}
    59  
    60  	roundTripped, err := ReadState(buf)
    61  	if err != nil {
    62  		t.Fatalf("err: %s", err)
    63  	}
    64  
    65  	if !reflect.DeepEqual(actual, roundTripped) {
    66  		spew.Config.DisableMethods = true
    67  		t.Fatalf("bad:\n%s\n\nround tripped:\n%s\n", spew.Sdump(actual), spew.Sdump(roundTripped))
    68  		spew.Config.DisableMethods = false
    69  	}
    70  }
    71  
    72  // Upgrading the state should not lose empty module Outputs and Resources maps
    73  // during upgrade. The init for a new module initializes new maps, so we may not
    74  // be expecting to check for a nil map.
    75  func TestReadUpgradeStateV1toV3_emptyState(t *testing.T) {
    76  	// ReadState should transparently detect the old version but will upgrade
    77  	// it on Write.
    78  	orig, err := ReadStateV1([]byte(testV1EmptyState))
    79  	if err != nil {
    80  		t.Fatalf("err: %s", err)
    81  	}
    82  
    83  	stateV2, err := upgradeStateV1ToV2(orig)
    84  	if err != nil {
    85  		t.Fatalf("error attempting upgradeStateV1ToV2: %s", err)
    86  	}
    87  
    88  	for _, m := range stateV2.Modules {
    89  		if m.Resources == nil {
    90  			t.Fatal("V1 to V2 upgrade lost module.Resources")
    91  		}
    92  		if m.Outputs == nil {
    93  			t.Fatal("V1 to V2 upgrade lost module.Outputs")
    94  		}
    95  	}
    96  
    97  	stateV3, err := upgradeStateV2ToV3(stateV2)
    98  	if err != nil {
    99  		t.Fatalf("error attempting to upgradeStateV2ToV3: %s", err)
   100  	}
   101  	for _, m := range stateV3.Modules {
   102  		if m.Resources == nil {
   103  			t.Fatal("V2 to V3 upgrade lost module.Resources")
   104  		}
   105  		if m.Outputs == nil {
   106  			t.Fatal("V2 to V3 upgrade lost module.Outputs")
   107  		}
   108  	}
   109  
   110  }
   111  
   112  const testV1EmptyState = `{
   113      "version": 1,
   114      "serial": 0,
   115      "modules": [
   116          {
   117              "path": [
   118                  "root"
   119              ],
   120              "outputs": {},
   121              "resources": {}
   122          }
   123      ]
   124  }
   125  `
   126  
   127  const testV1State = `{
   128      "version": 1,
   129      "serial": 9,
   130      "remote": {
   131          "type": "http",
   132          "config": {
   133              "url": "http://my-cool-server.com/"
   134          }
   135      },
   136      "modules": [
   137          {
   138              "path": [
   139                  "root"
   140              ],
   141              "outputs": null,
   142              "resources": {
   143                  "foo": {
   144                      "type": "",
   145                      "primary": {
   146                          "id": "bar"
   147                      }
   148                  }
   149              },
   150              "depends_on": [
   151                  "aws_instance.bar"
   152              ]
   153          }
   154      ]
   155  }
   156  `
   157  
   158  const testV1StateWithOutputs = `{
   159      "version": 1,
   160      "serial": 9,
   161      "remote": {
   162          "type": "http",
   163          "config": {
   164              "url": "http://my-cool-server.com/"
   165          }
   166      },
   167      "modules": [
   168          {
   169              "path": [
   170                  "root"
   171              ],
   172              "outputs": {
   173              	"foo": "bar",
   174              	"baz": "foo"
   175              },
   176              "resources": {
   177                  "foo": {
   178                      "type": "",
   179                      "primary": {
   180                          "id": "bar"
   181                      }
   182                  }
   183              },
   184              "depends_on": [
   185                  "aws_instance.bar"
   186              ]
   187          }
   188      ]
   189  }
   190  `