github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/terraform/shadow_resource_provisioner_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"reflect"
     7  	"testing"
     8  	"time"
     9  )
    10  
    11  func TestShadowResourceProvisioner_impl(t *testing.T) {
    12  	var _ Shadow = new(shadowResourceProvisionerShadow)
    13  }
    14  
    15  func TestShadowResourceProvisionerValidate(t *testing.T) {
    16  	mock := new(MockResourceProvisioner)
    17  	real, shadow := newShadowResourceProvisioner(mock)
    18  
    19  	// Test values
    20  	config := testResourceConfig(t, map[string]interface{}{
    21  		"foo": "bar",
    22  	})
    23  	returnWarns := []string{"foo"}
    24  	returnErrs := []error{fmt.Errorf("bar")}
    25  
    26  	// Configure the mock
    27  	mock.ValidateReturnWarns = returnWarns
    28  	mock.ValidateReturnErrors = returnErrs
    29  
    30  	// Verify that it blocks until the real func is called
    31  	var warns []string
    32  	var errs []error
    33  	doneCh := make(chan struct{})
    34  	go func() {
    35  		defer close(doneCh)
    36  		warns, errs = shadow.Validate(config)
    37  	}()
    38  
    39  	select {
    40  	case <-doneCh:
    41  		t.Fatal("should block until finished")
    42  	case <-time.After(10 * time.Millisecond):
    43  	}
    44  
    45  	// Call the real func
    46  	realWarns, realErrs := real.Validate(config)
    47  	if !reflect.DeepEqual(realWarns, returnWarns) {
    48  		t.Fatalf("bad: %#v", realWarns)
    49  	}
    50  	if !reflect.DeepEqual(realErrs, returnErrs) {
    51  		t.Fatalf("bad: %#v", realWarns)
    52  	}
    53  
    54  	// The shadow should finish now
    55  	<-doneCh
    56  
    57  	// Verify the shadow returned the same values
    58  	if !reflect.DeepEqual(warns, returnWarns) {
    59  		t.Fatalf("bad: %#v", warns)
    60  	}
    61  	if !reflect.DeepEqual(errs, returnErrs) {
    62  		t.Fatalf("bad: %#v", errs)
    63  	}
    64  
    65  	// Verify we have no errors
    66  	if err := shadow.CloseShadow(); err != nil {
    67  		t.Fatalf("bad: %s", err)
    68  	}
    69  }
    70  
    71  func TestShadowResourceProvisionerValidate_diff(t *testing.T) {
    72  	mock := new(MockResourceProvisioner)
    73  	real, shadow := newShadowResourceProvisioner(mock)
    74  
    75  	// Test values
    76  	config := testResourceConfig(t, map[string]interface{}{
    77  		"foo": "bar",
    78  	})
    79  	returnWarns := []string{"foo"}
    80  	returnErrs := []error{fmt.Errorf("bar")}
    81  
    82  	// Configure the mock
    83  	mock.ValidateReturnWarns = returnWarns
    84  	mock.ValidateReturnErrors = returnErrs
    85  
    86  	// Run a real validation with a config
    87  	real.Validate(testResourceConfig(t, map[string]interface{}{"bar": "baz"}))
    88  
    89  	// Verify that it blocks until the real func is called
    90  	var warns []string
    91  	var errs []error
    92  	doneCh := make(chan struct{})
    93  	go func() {
    94  		defer close(doneCh)
    95  		warns, errs = shadow.Validate(config)
    96  	}()
    97  
    98  	select {
    99  	case <-doneCh:
   100  		t.Fatal("should block until finished")
   101  	case <-time.After(10 * time.Millisecond):
   102  	}
   103  
   104  	// Call the real func
   105  	realWarns, realErrs := real.Validate(config)
   106  	if !reflect.DeepEqual(realWarns, returnWarns) {
   107  		t.Fatalf("bad: %#v", realWarns)
   108  	}
   109  	if !reflect.DeepEqual(realErrs, returnErrs) {
   110  		t.Fatalf("bad: %#v", realWarns)
   111  	}
   112  
   113  	// The shadow should finish now
   114  	<-doneCh
   115  
   116  	// Verify the shadow returned the same values
   117  	if !reflect.DeepEqual(warns, returnWarns) {
   118  		t.Fatalf("bad: %#v", warns)
   119  	}
   120  	if !reflect.DeepEqual(errs, returnErrs) {
   121  		t.Fatalf("bad: %#v", errs)
   122  	}
   123  
   124  	// Verify we have no errors
   125  	if err := shadow.CloseShadow(); err != nil {
   126  		t.Fatalf("bad: %s", err)
   127  	}
   128  }
   129  
   130  func TestShadowResourceProvisionerApply(t *testing.T) {
   131  	mock := new(MockResourceProvisioner)
   132  	real, shadow := newShadowResourceProvisioner(mock)
   133  
   134  	// Test values
   135  	output := new(MockUIOutput)
   136  	state := &InstanceState{ID: "foo"}
   137  	config := testResourceConfig(t, map[string]interface{}{"foo": "bar"})
   138  	mockReturn := errors.New("err")
   139  
   140  	// Configure the mock
   141  	mock.ApplyReturnError = mockReturn
   142  
   143  	// Verify that it blocks until the real func is called
   144  	var err error
   145  	doneCh := make(chan struct{})
   146  	go func() {
   147  		defer close(doneCh)
   148  		err = shadow.Apply(output, state, config)
   149  	}()
   150  
   151  	select {
   152  	case <-doneCh:
   153  		t.Fatal("should block until finished")
   154  	case <-time.After(10 * time.Millisecond):
   155  	}
   156  
   157  	// Call the real func
   158  	realErr := real.Apply(output, state, config)
   159  	if realErr != mockReturn {
   160  		t.Fatalf("bad: %#v", realErr)
   161  	}
   162  
   163  	// The shadow should finish now
   164  	<-doneCh
   165  
   166  	// Verify the shadow returned the same values
   167  	if err != mockReturn {
   168  		t.Errorf("bad: %#v", err)
   169  	}
   170  
   171  	// Verify we have no errors
   172  	if err := shadow.CloseShadow(); err != nil {
   173  		t.Fatalf("bad: %s", err)
   174  	}
   175  	if err := shadow.ShadowError(); err != nil {
   176  		t.Fatalf("bad: %s", err)
   177  	}
   178  }