github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/terraform/context_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  )
     9  
    10  func testContext2(t *testing.T, opts *ContextOpts) *Context {
    11  	return NewContext(opts)
    12  }
    13  
    14  func testApplyFn(
    15  	info *InstanceInfo,
    16  	s *InstanceState,
    17  	d *InstanceDiff) (*InstanceState, error) {
    18  	if d.Destroy {
    19  		return nil, nil
    20  	}
    21  
    22  	id := "foo"
    23  	if idAttr, ok := d.Attributes["id"]; ok && !idAttr.NewComputed {
    24  		id = idAttr.New
    25  	}
    26  
    27  	result := &InstanceState{
    28  		ID:         id,
    29  		Attributes: make(map[string]string),
    30  	}
    31  
    32  	// Copy all the prior attributes
    33  	for k, v := range s.Attributes {
    34  		result.Attributes[k] = v
    35  	}
    36  
    37  	if d != nil {
    38  		result = result.MergeDiff(d)
    39  	}
    40  	return result, nil
    41  }
    42  
    43  func testDiffFn(
    44  	info *InstanceInfo,
    45  	s *InstanceState,
    46  	c *ResourceConfig) (*InstanceDiff, error) {
    47  	var diff InstanceDiff
    48  	diff.Attributes = make(map[string]*ResourceAttrDiff)
    49  
    50  	for k, v := range c.Raw {
    51  		if _, ok := v.(string); !ok {
    52  			continue
    53  		}
    54  
    55  		if k == "nil" {
    56  			return nil, nil
    57  		}
    58  
    59  		// This key is used for other purposes
    60  		if k == "compute_value" {
    61  			continue
    62  		}
    63  
    64  		if k == "compute" {
    65  			attrDiff := &ResourceAttrDiff{
    66  				Old:         "",
    67  				New:         "",
    68  				NewComputed: true,
    69  			}
    70  
    71  			if cv, ok := c.Config["compute_value"]; ok {
    72  				if cv.(string) == "1" {
    73  					attrDiff.NewComputed = false
    74  					attrDiff.New = fmt.Sprintf("computed_%s", v.(string))
    75  				}
    76  			}
    77  
    78  			diff.Attributes[v.(string)] = attrDiff
    79  			continue
    80  		}
    81  
    82  		// If this key is not computed, then look it up in the
    83  		// cleaned config.
    84  		found := false
    85  		for _, ck := range c.ComputedKeys {
    86  			if ck == k {
    87  				found = true
    88  				break
    89  			}
    90  		}
    91  		if !found {
    92  			v = c.Config[k]
    93  		}
    94  
    95  		attrDiff := &ResourceAttrDiff{
    96  			Old: "",
    97  			New: v.(string),
    98  		}
    99  
   100  		if k == "require_new" {
   101  			attrDiff.RequiresNew = true
   102  		}
   103  		diff.Attributes[k] = attrDiff
   104  	}
   105  
   106  	for _, k := range c.ComputedKeys {
   107  		diff.Attributes[k] = &ResourceAttrDiff{
   108  			Old:         "",
   109  			NewComputed: true,
   110  		}
   111  	}
   112  
   113  	for k, v := range diff.Attributes {
   114  		if v.NewComputed {
   115  			continue
   116  		}
   117  
   118  		old, ok := s.Attributes[k]
   119  		if !ok {
   120  			continue
   121  		}
   122  		if old == v.New {
   123  			delete(diff.Attributes, k)
   124  		}
   125  	}
   126  
   127  	if !diff.Empty() {
   128  		diff.Attributes["type"] = &ResourceAttrDiff{
   129  			Old: "",
   130  			New: info.Type,
   131  		}
   132  	}
   133  
   134  	return &diff, nil
   135  }
   136  
   137  func testProvider(prefix string) *MockResourceProvider {
   138  	p := new(MockResourceProvider)
   139  	p.RefreshFn = func(info *InstanceInfo, s *InstanceState) (*InstanceState, error) {
   140  		return s, nil
   141  	}
   142  	p.ResourcesReturn = []ResourceType{
   143  		ResourceType{
   144  			Name: fmt.Sprintf("%s_instance", prefix),
   145  		},
   146  	}
   147  
   148  	return p
   149  }
   150  
   151  func testProvisioner() *MockResourceProvisioner {
   152  	p := new(MockResourceProvisioner)
   153  	return p
   154  }
   155  
   156  func checkStateString(t *testing.T, state *State, expected string) {
   157  	actual := strings.TrimSpace(state.String())
   158  	expected = strings.TrimSpace(expected)
   159  
   160  	if actual != expected {
   161  		t.Fatalf("state does not match! actual:\n%s\n\nexpected:\n%s", actual, expected)
   162  	}
   163  }
   164  
   165  func resourceState(resourceType, resourceID string) *ResourceState {
   166  	return &ResourceState{
   167  		Type: resourceType,
   168  		Primary: &InstanceState{
   169  			ID: resourceID,
   170  		},
   171  	}
   172  }
   173  
   174  // Test helper that gives a function 3 seconds to finish, assumes deadlock and
   175  // fails test if it does not.
   176  func testCheckDeadlock(t *testing.T, f func()) {
   177  	timeout := make(chan bool, 1)
   178  	done := make(chan bool, 1)
   179  	go func() {
   180  		time.Sleep(3 * time.Second)
   181  		timeout <- true
   182  	}()
   183  	go func(f func(), done chan bool) {
   184  		defer func() { done <- true }()
   185  		f()
   186  	}(f, done)
   187  	select {
   188  	case <-timeout:
   189  		t.Fatalf("timed out! probably deadlock")
   190  	case <-done:
   191  		// ok
   192  	}
   193  }
   194  
   195  const testContextGraph = `
   196  root: root
   197  aws_instance.bar
   198    aws_instance.bar -> provider.aws
   199  aws_instance.foo
   200    aws_instance.foo -> provider.aws
   201  provider.aws
   202  root
   203    root -> aws_instance.bar
   204    root -> aws_instance.foo
   205  `
   206  
   207  const testContextRefreshModuleStr = `
   208  aws_instance.web: (1 tainted)
   209    ID = <not created>
   210    Tainted ID 1 = bar
   211  
   212  module.child:
   213    aws_instance.web:
   214      ID = new
   215  `
   216  
   217  const testContextRefreshOutputStr = `
   218  aws_instance.web:
   219    ID = foo
   220    foo = bar
   221  
   222  Outputs:
   223  
   224  foo = bar
   225  `
   226  
   227  const testContextRefreshOutputPartialStr = `
   228  <no state>
   229  `
   230  
   231  const testContextRefreshTaintedStr = `
   232  aws_instance.web: (1 tainted)
   233    ID = <not created>
   234    Tainted ID 1 = foo
   235  `