github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/terraform/eval_state_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  )
     7  
     8  func TestEvalRequireState(t *testing.T) {
     9  	ctx := new(MockEvalContext)
    10  
    11  	cases := []struct {
    12  		State *InstanceState
    13  		Exit  bool
    14  	}{
    15  		{
    16  			nil,
    17  			true,
    18  		},
    19  		{
    20  			&InstanceState{},
    21  			true,
    22  		},
    23  		{
    24  			&InstanceState{ID: "foo"},
    25  			false,
    26  		},
    27  	}
    28  
    29  	var exitVal EvalEarlyExitError
    30  	for _, tc := range cases {
    31  		node := &EvalRequireState{State: &tc.State}
    32  		_, err := node.Eval(ctx)
    33  		if tc.Exit {
    34  			if err != exitVal {
    35  				t.Fatalf("should've exited: %#v", tc.State)
    36  			}
    37  
    38  			continue
    39  		}
    40  		if !tc.Exit && err != nil {
    41  			t.Fatalf("shouldn't exit: %#v", tc.State)
    42  		}
    43  		if err != nil {
    44  			t.Fatalf("err: %s", err)
    45  		}
    46  	}
    47  }
    48  
    49  func TestEvalUpdateStateHook(t *testing.T) {
    50  	mockHook := new(MockHook)
    51  
    52  	ctx := new(MockEvalContext)
    53  	ctx.HookHook = mockHook
    54  	ctx.StateState = &State{Serial: 42}
    55  	ctx.StateLock = new(sync.RWMutex)
    56  
    57  	node := &EvalUpdateStateHook{}
    58  	if _, err := node.Eval(ctx); err != nil {
    59  		t.Fatalf("err: %s", err)
    60  	}
    61  
    62  	if !mockHook.PostStateUpdateCalled {
    63  		t.Fatal("should call PostStateUpdate")
    64  	}
    65  	if mockHook.PostStateUpdateState.Serial != 42 {
    66  		t.Fatalf("bad: %#v", mockHook.PostStateUpdateState)
    67  	}
    68  }
    69  
    70  func TestEvalReadState(t *testing.T) {
    71  	var output *InstanceState
    72  	cases := map[string]struct {
    73  		Resources          map[string]*ResourceState
    74  		Node               EvalNode
    75  		ExpectedInstanceId string
    76  	}{
    77  		"ReadState gets primary instance state": {
    78  			Resources: map[string]*ResourceState{
    79  				"aws_instance.bar": &ResourceState{
    80  					Primary: &InstanceState{
    81  						ID: "i-abc123",
    82  					},
    83  				},
    84  			},
    85  			Node: &EvalReadState{
    86  				Name:   "aws_instance.bar",
    87  				Output: &output,
    88  			},
    89  			ExpectedInstanceId: "i-abc123",
    90  		},
    91  		"ReadStateDeposed gets deposed instance": {
    92  			Resources: map[string]*ResourceState{
    93  				"aws_instance.bar": &ResourceState{
    94  					Deposed: []*InstanceState{
    95  						&InstanceState{ID: "i-abc123"},
    96  					},
    97  				},
    98  			},
    99  			Node: &EvalReadStateDeposed{
   100  				Name:   "aws_instance.bar",
   101  				Output: &output,
   102  				Index:  0,
   103  			},
   104  			ExpectedInstanceId: "i-abc123",
   105  		},
   106  	}
   107  
   108  	for k, c := range cases {
   109  		ctx := new(MockEvalContext)
   110  		ctx.StateState = &State{
   111  			Modules: []*ModuleState{
   112  				&ModuleState{
   113  					Path:      rootModulePath,
   114  					Resources: c.Resources,
   115  				},
   116  			},
   117  		}
   118  		ctx.StateLock = new(sync.RWMutex)
   119  		ctx.PathPath = rootModulePath
   120  
   121  		result, err := c.Node.Eval(ctx)
   122  		if err != nil {
   123  			t.Fatalf("[%s] Got err: %#v", k, err)
   124  		}
   125  
   126  		expected := c.ExpectedInstanceId
   127  		if !(result != nil && result.(*InstanceState).ID == expected) {
   128  			t.Fatalf("[%s] Expected return with ID %#v, got: %#v", k, expected, result)
   129  		}
   130  
   131  		if !(output != nil && output.ID == expected) {
   132  			t.Fatalf("[%s] Expected output with ID %#v, got: %#v", k, expected, output)
   133  		}
   134  
   135  		output = nil
   136  	}
   137  }
   138  
   139  func TestEvalWriteState(t *testing.T) {
   140  	state := &State{}
   141  	ctx := new(MockEvalContext)
   142  	ctx.StateState = state
   143  	ctx.StateLock = new(sync.RWMutex)
   144  	ctx.PathPath = rootModulePath
   145  
   146  	is := &InstanceState{ID: "i-abc123"}
   147  	node := &EvalWriteState{
   148  		Name:         "restype.resname",
   149  		ResourceType: "restype",
   150  		State:        &is,
   151  	}
   152  	_, err := node.Eval(ctx)
   153  	if err != nil {
   154  		t.Fatalf("Got err: %#v", err)
   155  	}
   156  
   157  	checkStateString(t, state, `
   158  restype.resname:
   159    ID = i-abc123
   160  	`)
   161  }
   162  
   163  func TestEvalWriteStateDeposed(t *testing.T) {
   164  	state := &State{}
   165  	ctx := new(MockEvalContext)
   166  	ctx.StateState = state
   167  	ctx.StateLock = new(sync.RWMutex)
   168  	ctx.PathPath = rootModulePath
   169  
   170  	is := &InstanceState{ID: "i-abc123"}
   171  	node := &EvalWriteStateDeposed{
   172  		Name:         "restype.resname",
   173  		ResourceType: "restype",
   174  		State:        &is,
   175  		Index:        -1,
   176  	}
   177  	_, err := node.Eval(ctx)
   178  	if err != nil {
   179  		t.Fatalf("Got err: %#v", err)
   180  	}
   181  
   182  	checkStateString(t, state, `
   183  restype.resname: (1 deposed)
   184    ID = <not created>
   185    Deposed ID 1 = i-abc123
   186  	`)
   187  }