github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/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  	for _, m := range stateV2.Modules {
    85  		if m.Resources == nil {
    86  			t.Fatal("V1 to V2 upgrade lost module.Resources")
    87  		}
    88  		if m.Outputs == nil {
    89  			t.Fatal("V1 to V2 upgrade lost module.Outputs")
    90  		}
    91  	}
    92  
    93  	stateV3, err := upgradeStateV2ToV3(stateV2)
    94  	for _, m := range stateV3.Modules {
    95  		if m.Resources == nil {
    96  			t.Fatal("V2 to V3 upgrade lost module.Resources")
    97  		}
    98  		if m.Outputs == nil {
    99  			t.Fatal("V2 to V3 upgrade lost module.Outputs")
   100  		}
   101  	}
   102  
   103  }
   104  
   105  const testV1EmptyState = `{
   106      "version": 1,
   107      "serial": 0,
   108      "modules": [
   109          {
   110              "path": [
   111                  "root"
   112              ],
   113              "outputs": {},
   114              "resources": {}
   115          }
   116      ]
   117  }
   118  `
   119  
   120  const testV1State = `{
   121      "version": 1,
   122      "serial": 9,
   123      "remote": {
   124          "type": "http",
   125          "config": {
   126              "url": "http://my-cool-server.com/"
   127          }
   128      },
   129      "modules": [
   130          {
   131              "path": [
   132                  "root"
   133              ],
   134              "outputs": null,
   135              "resources": {
   136                  "foo": {
   137                      "type": "",
   138                      "primary": {
   139                          "id": "bar"
   140                      }
   141                  }
   142              },
   143              "depends_on": [
   144                  "aws_instance.bar"
   145              ]
   146          }
   147      ]
   148  }
   149  `
   150  
   151  const testV1StateWithOutputs = `{
   152      "version": 1,
   153      "serial": 9,
   154      "remote": {
   155          "type": "http",
   156          "config": {
   157              "url": "http://my-cool-server.com/"
   158          }
   159      },
   160      "modules": [
   161          {
   162              "path": [
   163                  "root"
   164              ],
   165              "outputs": {
   166              	"foo": "bar",
   167              	"baz": "foo"
   168              },
   169              "resources": {
   170                  "foo": {
   171                      "type": "",
   172                      "primary": {
   173                          "id": "bar"
   174                      }
   175                  }
   176              },
   177              "depends_on": [
   178                  "aws_instance.bar"
   179              ]
   180          }
   181      ]
   182  }
   183  `