github.com/skyscape-cloud-services/terraform@v0.9.2-0.20170609144644-7ece028a1747/terraform/upgrade_state_v2_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"bytes"
     5  	"strings"
     6  	"testing"
     7  )
     8  
     9  // TestReadUpgradeStateV2toV3 tests the state upgrade process from the V2 state
    10  // to the current version, and needs editing each time. This means it tests the
    11  // entire pipeline of upgrades (which migrate version to version).
    12  func TestReadUpgradeStateV2toV3(t *testing.T) {
    13  	// ReadState should transparently detect the old version but will upgrade
    14  	// it on Write.
    15  	upgraded, err := ReadState(strings.NewReader(testV2State))
    16  	if err != nil {
    17  		t.Fatalf("err: %s", err)
    18  	}
    19  
    20  	buf := new(bytes.Buffer)
    21  	if err := WriteState(upgraded, buf); err != nil {
    22  		t.Fatalf("err: %s", err)
    23  	}
    24  
    25  	if upgraded.Version != 3 {
    26  		t.Fatalf("bad: State version not incremented; is %d", upgraded.Version)
    27  	}
    28  
    29  	// For this test we cannot assert that we match the round trip because an
    30  	// empty map has been removed from state. Instead we make assertions against
    31  	// some of the key fields in the _upgraded_ state.
    32  	instanceState, ok := upgraded.RootModule().Resources["test_resource.main"]
    33  	if !ok {
    34  		t.Fatalf("Instance state for test_resource.main was removed from state during upgrade")
    35  	}
    36  
    37  	primary := instanceState.Primary
    38  	if primary == nil {
    39  		t.Fatalf("Primary instance was removed from state for test_resource.main")
    40  	}
    41  
    42  	// Non-empty computed map is moved from .# to .%
    43  	if _, ok := primary.Attributes["computed_map.#"]; ok {
    44  		t.Fatalf("Count was not upgraded from .# to .%% for computed_map")
    45  	}
    46  	if count, ok := primary.Attributes["computed_map.%"]; !ok || count != "1" {
    47  		t.Fatalf("Count was not in .%% or was not 2 for computed_map")
    48  	}
    49  
    50  	// list_of_map top level retains .#
    51  	if count, ok := primary.Attributes["list_of_map.#"]; !ok || count != "2" {
    52  		t.Fatal("Count for list_of_map was migrated incorrectly")
    53  	}
    54  
    55  	// list_of_map.0 is moved from .# to .%
    56  	if _, ok := primary.Attributes["list_of_map.0.#"]; ok {
    57  		t.Fatalf("Count was not upgraded from .# to .%% for list_of_map.0")
    58  	}
    59  	if count, ok := primary.Attributes["list_of_map.0.%"]; !ok || count != "2" {
    60  		t.Fatalf("Count was not in .%% or was not 2 for list_of_map.0")
    61  	}
    62  
    63  	// list_of_map.1 is moved from .# to .%
    64  	if _, ok := primary.Attributes["list_of_map.1.#"]; ok {
    65  		t.Fatalf("Count was not upgraded from .# to .%% for list_of_map.1")
    66  	}
    67  	if count, ok := primary.Attributes["list_of_map.1.%"]; !ok || count != "2" {
    68  		t.Fatalf("Count was not in .%% or was not 2 for list_of_map.1")
    69  	}
    70  
    71  	// map is moved from .# to .%
    72  	if _, ok := primary.Attributes["map.#"]; ok {
    73  		t.Fatalf("Count was not upgraded from .# to .%% for map")
    74  	}
    75  	if count, ok := primary.Attributes["map.%"]; !ok || count != "2" {
    76  		t.Fatalf("Count was not in .%% or was not 2 for map")
    77  	}
    78  
    79  	// optional_computed_map should be removed from state
    80  	if _, ok := primary.Attributes["optional_computed_map"]; ok {
    81  		t.Fatal("optional_computed_map was not removed from state")
    82  	}
    83  
    84  	// required_map is moved from .# to .%
    85  	if _, ok := primary.Attributes["required_map.#"]; ok {
    86  		t.Fatalf("Count was not upgraded from .# to .%% for required_map")
    87  	}
    88  	if count, ok := primary.Attributes["required_map.%"]; !ok || count != "3" {
    89  		t.Fatalf("Count was not in .%% or was not 3 for map")
    90  	}
    91  
    92  	// computed_list keeps .#
    93  	if count, ok := primary.Attributes["computed_list.#"]; !ok || count != "2" {
    94  		t.Fatal("Count was migrated incorrectly for computed_list")
    95  	}
    96  
    97  	// computed_set keeps .#
    98  	if count, ok := primary.Attributes["computed_set.#"]; !ok || count != "2" {
    99  		t.Fatal("Count was migrated incorrectly for computed_set")
   100  	}
   101  	if val, ok := primary.Attributes["computed_set.2337322984"]; !ok || val != "setval1" {
   102  		t.Fatal("Set item for computed_set.2337322984 changed or moved")
   103  	}
   104  	if val, ok := primary.Attributes["computed_set.307881554"]; !ok || val != "setval2" {
   105  		t.Fatal("Set item for computed_set.307881554 changed or moved")
   106  	}
   107  
   108  	// string properties are unaffected
   109  	if val, ok := primary.Attributes["id"]; !ok || val != "testId" {
   110  		t.Fatal("id was not set correctly after migration")
   111  	}
   112  }
   113  
   114  const testV2State = `{
   115      "version": 2,
   116      "terraform_version": "0.7.0",
   117      "serial": 2,
   118      "modules": [
   119          {
   120              "path": [
   121                  "root"
   122              ],
   123              "outputs": {
   124                  "computed_map": {
   125                      "sensitive": false,
   126                      "type": "map",
   127                      "value": {
   128                          "key1": "value1"
   129                      }
   130                  },
   131                  "computed_set": {
   132                      "sensitive": false,
   133                      "type": "list",
   134                      "value": [
   135                          "setval1",
   136                          "setval2"
   137                      ]
   138                  },
   139                  "map": {
   140                      "sensitive": false,
   141                      "type": "map",
   142                      "value": {
   143                          "key": "test",
   144                          "test": "test"
   145                      }
   146                  },
   147                  "set": {
   148                      "sensitive": false,
   149                      "type": "list",
   150                      "value": [
   151                          "test1",
   152                          "test2"
   153                      ]
   154                  }
   155              },
   156              "resources": {
   157                  "test_resource.main": {
   158                      "type": "test_resource",
   159                      "primary": {
   160                          "id": "testId",
   161                          "attributes": {
   162                              "computed_list.#": "2",
   163                              "computed_list.0": "listval1",
   164                              "computed_list.1": "listval2",
   165                              "computed_map.#": "1",
   166                              "computed_map.key1": "value1",
   167                              "computed_read_only": "value_from_api",
   168                              "computed_read_only_force_new": "value_from_api",
   169                              "computed_set.#": "2",
   170                              "computed_set.2337322984": "setval1",
   171                              "computed_set.307881554": "setval2",
   172                              "id": "testId",
   173                              "list_of_map.#": "2",
   174                              "list_of_map.0.#": "2",
   175                              "list_of_map.0.key1": "value1",
   176                              "list_of_map.0.key2": "value2",
   177                              "list_of_map.1.#": "2",
   178                              "list_of_map.1.key3": "value3",
   179                              "list_of_map.1.key4": "value4",
   180                              "map.#": "2",
   181                              "map.key": "test",
   182                              "map.test": "test",
   183                              "map_that_look_like_set.#": "2",
   184                              "map_that_look_like_set.12352223": "hello",
   185                              "map_that_look_like_set.36234341": "world",
   186                              "optional_computed_map.#": "0",
   187                              "required": "Hello World",
   188                              "required_map.#": "3",
   189                              "required_map.key1": "value1",
   190                              "required_map.key2": "value2",
   191                              "required_map.key3": "value3",
   192                              "set.#": "2",
   193                              "set.2326977762": "test1",
   194                              "set.331058520": "test2"
   195                          }
   196                      }
   197                  }
   198              }
   199          }
   200      ]
   201  }
   202  `