terraform/helper/schema/resource_test.go

481 lines
7.8 KiB
Go

package schema
import (
"fmt"
"reflect"
"testing"
"github.com/hashicorp/terraform/terraform"
)
func TestResourceApply_create(t *testing.T) {
r := &Resource{
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeInt,
Optional: true,
},
},
}
called := false
r.Create = func(d *ResourceData, m interface{}) error {
called = true
d.SetId("foo")
return nil
}
var s *terraform.InstanceState = nil
d := &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{
New: "42",
},
},
}
actual, err := r.Apply(s, d, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
if !called {
t.Fatal("not called")
}
expected := &terraform.InstanceState{
ID: "foo",
Attributes: map[string]string{
"id": "foo",
"foo": "42",
},
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func TestResourceApply_destroy(t *testing.T) {
r := &Resource{
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeInt,
Optional: true,
},
},
}
called := false
r.Delete = func(d *ResourceData, m interface{}) error {
called = true
return nil
}
s := &terraform.InstanceState{
ID: "bar",
}
d := &terraform.InstanceDiff{
Destroy: true,
}
actual, err := r.Apply(s, d, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
if !called {
t.Fatal("delete not called")
}
if actual != nil {
t.Fatalf("bad: %#v", actual)
}
}
func TestResourceApply_destroyCreate(t *testing.T) {
r := &Resource{
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeInt,
Optional: true,
},
"tags": &Schema{
Type: TypeMap,
Optional: true,
Computed: true,
},
},
}
change := false
r.Create = func(d *ResourceData, m interface{}) error {
change = d.HasChange("tags")
d.SetId("foo")
return nil
}
r.Delete = func(d *ResourceData, m interface{}) error {
return nil
}
var s *terraform.InstanceState = &terraform.InstanceState{
ID: "bar",
Attributes: map[string]string{
"foo": "bar",
"tags.Name": "foo",
},
}
d := &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{
New: "42",
RequiresNew: true,
},
"tags.Name": &terraform.ResourceAttrDiff{
Old: "foo",
New: "foo",
RequiresNew: true,
},
},
}
actual, err := r.Apply(s, d, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
if !change {
t.Fatal("should have change")
}
expected := &terraform.InstanceState{
ID: "foo",
Attributes: map[string]string{
"id": "foo",
"foo": "42",
"tags.#": "1",
"tags.Name": "foo",
},
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func TestResourceApply_destroyPartial(t *testing.T) {
r := &Resource{
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeInt,
Optional: true,
},
},
}
r.Delete = func(d *ResourceData, m interface{}) error {
d.Set("foo", 42)
return fmt.Errorf("some error")
}
s := &terraform.InstanceState{
ID: "bar",
Attributes: map[string]string{
"foo": "12",
},
}
d := &terraform.InstanceDiff{
Destroy: true,
}
actual, err := r.Apply(s, d, nil)
if err == nil {
t.Fatal("should error")
}
expected := &terraform.InstanceState{
ID: "bar",
Attributes: map[string]string{
"id": "bar",
"foo": "42",
},
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func TestResourceApply_update(t *testing.T) {
r := &Resource{
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeInt,
Optional: true,
},
},
}
r.Update = func(d *ResourceData, m interface{}) error {
d.Set("foo", 42)
return nil
}
s := &terraform.InstanceState{
ID: "foo",
Attributes: map[string]string{
"foo": "12",
},
}
d := &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{
New: "13",
},
},
}
actual, err := r.Apply(s, d, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
expected := &terraform.InstanceState{
ID: "foo",
Attributes: map[string]string{
"id": "foo",
"foo": "42",
},
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func TestResourceApply_updateNoCallback(t *testing.T) {
r := &Resource{
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeInt,
Optional: true,
},
},
}
r.Update = nil
s := &terraform.InstanceState{
ID: "foo",
Attributes: map[string]string{
"foo": "12",
},
}
d := &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{
New: "13",
},
},
}
actual, err := r.Apply(s, d, nil)
if err == nil {
t.Fatal("should error")
}
expected := &terraform.InstanceState{
ID: "foo",
Attributes: map[string]string{
"foo": "12",
},
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func TestResourceInternalValidate(t *testing.T) {
cases := []struct {
In *Resource
Err bool
}{
{
nil,
true,
},
// No optional and no required
{
&Resource{
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeInt,
Optional: true,
Required: true,
},
},
},
true,
},
}
for i, tc := range cases {
err := tc.In.InternalValidate()
if (err != nil) != tc.Err {
t.Fatalf("%d: bad: %s", i, err)
}
}
}
func TestResourceRefresh(t *testing.T) {
r := &Resource{
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeInt,
Optional: true,
},
},
}
r.Read = func(d *ResourceData, m interface{}) error {
if m != 42 {
return fmt.Errorf("meta not passed")
}
return d.Set("foo", d.Get("foo").(int)+1)
}
s := &terraform.InstanceState{
ID: "bar",
Attributes: map[string]string{
"foo": "12",
},
}
expected := &terraform.InstanceState{
ID: "bar",
Attributes: map[string]string{
"id": "bar",
"foo": "13",
},
}
actual, err := r.Refresh(s, 42)
if err != nil {
t.Fatalf("err: %s", err)
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func TestResourceRefresh_delete(t *testing.T) {
r := &Resource{
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeInt,
Optional: true,
},
},
}
r.Read = func(d *ResourceData, m interface{}) error {
d.SetId("")
return nil
}
s := &terraform.InstanceState{
ID: "bar",
Attributes: map[string]string{
"foo": "12",
},
}
actual, err := r.Refresh(s, 42)
if err != nil {
t.Fatalf("err: %s", err)
}
if actual != nil {
t.Fatalf("bad: %#v", actual)
}
}
func TestResourceRefresh_existsError(t *testing.T) {
r := &Resource{
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeInt,
Optional: true,
},
},
}
r.Exists = func(*ResourceData, interface{}) (bool, error) {
return false, fmt.Errorf("error")
}
r.Read = func(d *ResourceData, m interface{}) error {
panic("shouldn't be called")
}
s := &terraform.InstanceState{
ID: "bar",
Attributes: map[string]string{
"foo": "12",
},
}
actual, err := r.Refresh(s, 42)
if err == nil {
t.Fatalf("should error")
}
if !reflect.DeepEqual(actual, s) {
t.Fatalf("bad: %#v", actual)
}
}
func TestResourceRefresh_noExists(t *testing.T) {
r := &Resource{
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeInt,
Optional: true,
},
},
}
r.Exists = func(*ResourceData, interface{}) (bool, error) {
return false, nil
}
r.Read = func(d *ResourceData, m interface{}) error {
panic("shouldn't be called")
}
s := &terraform.InstanceState{
ID: "bar",
Attributes: map[string]string{
"foo": "12",
},
}
actual, err := r.Refresh(s, 42)
if err != nil {
t.Fatalf("err: %s", err)
}
if actual != nil {
t.Fatalf("should have no state")
}
}