github.com/lamielle/terraform@v0.3.2-0.20141121070651-81f008ba53d5/helper/schema/resource_test.go (about)

     1  package schema
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/terraform/terraform"
     9  )
    10  
    11  func TestResourceApply_create(t *testing.T) {
    12  	r := &Resource{
    13  		Schema: map[string]*Schema{
    14  			"foo": &Schema{
    15  				Type:     TypeInt,
    16  				Optional: true,
    17  			},
    18  		},
    19  	}
    20  
    21  	called := false
    22  	r.Create = func(d *ResourceData, m interface{}) error {
    23  		called = true
    24  		d.SetId("foo")
    25  		return nil
    26  	}
    27  
    28  	var s *terraform.InstanceState = nil
    29  
    30  	d := &terraform.InstanceDiff{
    31  		Attributes: map[string]*terraform.ResourceAttrDiff{
    32  			"foo": &terraform.ResourceAttrDiff{
    33  				New: "42",
    34  			},
    35  		},
    36  	}
    37  
    38  	actual, err := r.Apply(s, d, nil)
    39  	if err != nil {
    40  		t.Fatalf("err: %s", err)
    41  	}
    42  
    43  	if !called {
    44  		t.Fatal("not called")
    45  	}
    46  
    47  	expected := &terraform.InstanceState{
    48  		ID: "foo",
    49  		Attributes: map[string]string{
    50  			"id":  "foo",
    51  			"foo": "42",
    52  		},
    53  	}
    54  
    55  	if !reflect.DeepEqual(actual, expected) {
    56  		t.Fatalf("bad: %#v", actual)
    57  	}
    58  }
    59  
    60  func TestResourceApply_destroy(t *testing.T) {
    61  	r := &Resource{
    62  		Schema: map[string]*Schema{
    63  			"foo": &Schema{
    64  				Type:     TypeInt,
    65  				Optional: true,
    66  			},
    67  		},
    68  	}
    69  
    70  	called := false
    71  	r.Delete = func(d *ResourceData, m interface{}) error {
    72  		called = true
    73  		return nil
    74  	}
    75  
    76  	s := &terraform.InstanceState{
    77  		ID: "bar",
    78  	}
    79  
    80  	d := &terraform.InstanceDiff{
    81  		Destroy: true,
    82  	}
    83  
    84  	actual, err := r.Apply(s, d, nil)
    85  	if err != nil {
    86  		t.Fatalf("err: %s", err)
    87  	}
    88  
    89  	if !called {
    90  		t.Fatal("delete not called")
    91  	}
    92  
    93  	if actual != nil {
    94  		t.Fatalf("bad: %#v", actual)
    95  	}
    96  }
    97  
    98  func TestResourceApply_destroyCreate(t *testing.T) {
    99  	r := &Resource{
   100  		Schema: map[string]*Schema{
   101  			"foo": &Schema{
   102  				Type:     TypeInt,
   103  				Optional: true,
   104  			},
   105  
   106  			"tags": &Schema{
   107  				Type:     TypeMap,
   108  				Optional: true,
   109  				Computed: true,
   110  			},
   111  		},
   112  	}
   113  
   114  	change := false
   115  	r.Create = func(d *ResourceData, m interface{}) error {
   116  		change = d.HasChange("tags")
   117  		d.SetId("foo")
   118  		return nil
   119  	}
   120  	r.Delete = func(d *ResourceData, m interface{}) error {
   121  		return nil
   122  	}
   123  
   124  	var s *terraform.InstanceState = &terraform.InstanceState{
   125  		ID: "bar",
   126  		Attributes: map[string]string{
   127  			"foo":       "bar",
   128  			"tags.Name": "foo",
   129  		},
   130  	}
   131  
   132  	d := &terraform.InstanceDiff{
   133  		Attributes: map[string]*terraform.ResourceAttrDiff{
   134  			"foo": &terraform.ResourceAttrDiff{
   135  				New:         "42",
   136  				RequiresNew: true,
   137  			},
   138  			"tags.Name": &terraform.ResourceAttrDiff{
   139  				Old:         "foo",
   140  				New:         "foo",
   141  				RequiresNew: true,
   142  			},
   143  		},
   144  	}
   145  
   146  	actual, err := r.Apply(s, d, nil)
   147  	if err != nil {
   148  		t.Fatalf("err: %s", err)
   149  	}
   150  
   151  	if !change {
   152  		t.Fatal("should have change")
   153  	}
   154  
   155  	expected := &terraform.InstanceState{
   156  		ID: "foo",
   157  		Attributes: map[string]string{
   158  			"id":        "foo",
   159  			"foo":       "42",
   160  			"tags.Name": "foo",
   161  		},
   162  	}
   163  
   164  	if !reflect.DeepEqual(actual, expected) {
   165  		t.Fatalf("bad: %#v", actual)
   166  	}
   167  }
   168  
   169  func TestResourceApply_destroyPartial(t *testing.T) {
   170  	r := &Resource{
   171  		Schema: map[string]*Schema{
   172  			"foo": &Schema{
   173  				Type:     TypeInt,
   174  				Optional: true,
   175  			},
   176  		},
   177  	}
   178  
   179  	r.Delete = func(d *ResourceData, m interface{}) error {
   180  		d.Set("foo", 42)
   181  		return fmt.Errorf("some error")
   182  	}
   183  
   184  	s := &terraform.InstanceState{
   185  		ID: "bar",
   186  		Attributes: map[string]string{
   187  			"foo": "12",
   188  		},
   189  	}
   190  
   191  	d := &terraform.InstanceDiff{
   192  		Destroy: true,
   193  	}
   194  
   195  	actual, err := r.Apply(s, d, nil)
   196  	if err == nil {
   197  		t.Fatal("should error")
   198  	}
   199  
   200  	expected := &terraform.InstanceState{
   201  		ID: "bar",
   202  		Attributes: map[string]string{
   203  			"id":  "bar",
   204  			"foo": "42",
   205  		},
   206  	}
   207  
   208  	if !reflect.DeepEqual(actual, expected) {
   209  		t.Fatalf("bad: %#v", actual)
   210  	}
   211  }
   212  
   213  func TestResourceApply_update(t *testing.T) {
   214  	r := &Resource{
   215  		Schema: map[string]*Schema{
   216  			"foo": &Schema{
   217  				Type:     TypeInt,
   218  				Optional: true,
   219  			},
   220  		},
   221  	}
   222  
   223  	r.Update = func(d *ResourceData, m interface{}) error {
   224  		d.Set("foo", 42)
   225  		return nil
   226  	}
   227  
   228  	s := &terraform.InstanceState{
   229  		ID: "foo",
   230  		Attributes: map[string]string{
   231  			"foo": "12",
   232  		},
   233  	}
   234  
   235  	d := &terraform.InstanceDiff{
   236  		Attributes: map[string]*terraform.ResourceAttrDiff{
   237  			"foo": &terraform.ResourceAttrDiff{
   238  				New: "13",
   239  			},
   240  		},
   241  	}
   242  
   243  	actual, err := r.Apply(s, d, nil)
   244  	if err != nil {
   245  		t.Fatalf("err: %s", err)
   246  	}
   247  
   248  	expected := &terraform.InstanceState{
   249  		ID: "foo",
   250  		Attributes: map[string]string{
   251  			"id":  "foo",
   252  			"foo": "42",
   253  		},
   254  	}
   255  
   256  	if !reflect.DeepEqual(actual, expected) {
   257  		t.Fatalf("bad: %#v", actual)
   258  	}
   259  }
   260  
   261  func TestResourceApply_updateNoCallback(t *testing.T) {
   262  	r := &Resource{
   263  		Schema: map[string]*Schema{
   264  			"foo": &Schema{
   265  				Type:     TypeInt,
   266  				Optional: true,
   267  			},
   268  		},
   269  	}
   270  
   271  	r.Update = nil
   272  
   273  	s := &terraform.InstanceState{
   274  		ID: "foo",
   275  		Attributes: map[string]string{
   276  			"foo": "12",
   277  		},
   278  	}
   279  
   280  	d := &terraform.InstanceDiff{
   281  		Attributes: map[string]*terraform.ResourceAttrDiff{
   282  			"foo": &terraform.ResourceAttrDiff{
   283  				New: "13",
   284  			},
   285  		},
   286  	}
   287  
   288  	actual, err := r.Apply(s, d, nil)
   289  	if err == nil {
   290  		t.Fatal("should error")
   291  	}
   292  
   293  	expected := &terraform.InstanceState{
   294  		ID: "foo",
   295  		Attributes: map[string]string{
   296  			"foo": "12",
   297  		},
   298  	}
   299  
   300  	if !reflect.DeepEqual(actual, expected) {
   301  		t.Fatalf("bad: %#v", actual)
   302  	}
   303  }
   304  
   305  func TestResourceInternalValidate(t *testing.T) {
   306  	cases := []struct {
   307  		In  *Resource
   308  		Err bool
   309  	}{
   310  		{
   311  			nil,
   312  			true,
   313  		},
   314  
   315  		// No optional and no required
   316  		{
   317  			&Resource{
   318  				Schema: map[string]*Schema{
   319  					"foo": &Schema{
   320  						Type:     TypeInt,
   321  						Optional: true,
   322  						Required: true,
   323  					},
   324  				},
   325  			},
   326  			true,
   327  		},
   328  	}
   329  
   330  	for i, tc := range cases {
   331  		err := tc.In.InternalValidate()
   332  		if (err != nil) != tc.Err {
   333  			t.Fatalf("%d: bad: %s", i, err)
   334  		}
   335  	}
   336  }
   337  
   338  func TestResourceRefresh(t *testing.T) {
   339  	r := &Resource{
   340  		Schema: map[string]*Schema{
   341  			"foo": &Schema{
   342  				Type:     TypeInt,
   343  				Optional: true,
   344  			},
   345  		},
   346  	}
   347  
   348  	r.Read = func(d *ResourceData, m interface{}) error {
   349  		if m != 42 {
   350  			return fmt.Errorf("meta not passed")
   351  		}
   352  
   353  		return d.Set("foo", d.Get("foo").(int)+1)
   354  	}
   355  
   356  	s := &terraform.InstanceState{
   357  		ID: "bar",
   358  		Attributes: map[string]string{
   359  			"foo": "12",
   360  		},
   361  	}
   362  
   363  	expected := &terraform.InstanceState{
   364  		ID: "bar",
   365  		Attributes: map[string]string{
   366  			"id":  "bar",
   367  			"foo": "13",
   368  		},
   369  	}
   370  
   371  	actual, err := r.Refresh(s, 42)
   372  	if err != nil {
   373  		t.Fatalf("err: %s", err)
   374  	}
   375  
   376  	if !reflect.DeepEqual(actual, expected) {
   377  		t.Fatalf("bad: %#v", actual)
   378  	}
   379  }
   380  
   381  func TestResourceRefresh_delete(t *testing.T) {
   382  	r := &Resource{
   383  		Schema: map[string]*Schema{
   384  			"foo": &Schema{
   385  				Type:     TypeInt,
   386  				Optional: true,
   387  			},
   388  		},
   389  	}
   390  
   391  	r.Read = func(d *ResourceData, m interface{}) error {
   392  		d.SetId("")
   393  		return nil
   394  	}
   395  
   396  	s := &terraform.InstanceState{
   397  		ID: "bar",
   398  		Attributes: map[string]string{
   399  			"foo": "12",
   400  		},
   401  	}
   402  
   403  	actual, err := r.Refresh(s, 42)
   404  	if err != nil {
   405  		t.Fatalf("err: %s", err)
   406  	}
   407  
   408  	if actual != nil {
   409  		t.Fatalf("bad: %#v", actual)
   410  	}
   411  }