opentofu/terraform/shadow_resource_provisioner_test.go
2016-10-11 22:17:30 +08:00

179 lines
4.0 KiB
Go

package terraform
import (
"errors"
"fmt"
"reflect"
"testing"
"time"
)
func TestShadowResourceProvisioner_impl(t *testing.T) {
var _ Shadow = new(shadowResourceProvisionerShadow)
}
func TestShadowResourceProvisionerValidate(t *testing.T) {
mock := new(MockResourceProvisioner)
real, shadow := newShadowResourceProvisioner(mock)
// Test values
config := testResourceConfig(t, map[string]interface{}{
"foo": "bar",
})
returnWarns := []string{"foo"}
returnErrs := []error{fmt.Errorf("bar")}
// Configure the mock
mock.ValidateReturnWarns = returnWarns
mock.ValidateReturnErrors = returnErrs
// Verify that it blocks until the real func is called
var warns []string
var errs []error
doneCh := make(chan struct{})
go func() {
defer close(doneCh)
warns, errs = shadow.Validate(config)
}()
select {
case <-doneCh:
t.Fatal("should block until finished")
case <-time.After(10 * time.Millisecond):
}
// Call the real func
realWarns, realErrs := real.Validate(config)
if !reflect.DeepEqual(realWarns, returnWarns) {
t.Fatalf("bad: %#v", realWarns)
}
if !reflect.DeepEqual(realErrs, returnErrs) {
t.Fatalf("bad: %#v", realWarns)
}
// The shadow should finish now
<-doneCh
// Verify the shadow returned the same values
if !reflect.DeepEqual(warns, returnWarns) {
t.Fatalf("bad: %#v", warns)
}
if !reflect.DeepEqual(errs, returnErrs) {
t.Fatalf("bad: %#v", errs)
}
// Verify we have no errors
if err := shadow.CloseShadow(); err != nil {
t.Fatalf("bad: %s", err)
}
}
func TestShadowResourceProvisionerValidate_diff(t *testing.T) {
mock := new(MockResourceProvisioner)
real, shadow := newShadowResourceProvisioner(mock)
// Test values
config := testResourceConfig(t, map[string]interface{}{
"foo": "bar",
})
returnWarns := []string{"foo"}
returnErrs := []error{fmt.Errorf("bar")}
// Configure the mock
mock.ValidateReturnWarns = returnWarns
mock.ValidateReturnErrors = returnErrs
// Run a real validation with a config
real.Validate(testResourceConfig(t, map[string]interface{}{"bar": "baz"}))
// Verify that it blocks until the real func is called
var warns []string
var errs []error
doneCh := make(chan struct{})
go func() {
defer close(doneCh)
warns, errs = shadow.Validate(config)
}()
select {
case <-doneCh:
t.Fatal("should block until finished")
case <-time.After(10 * time.Millisecond):
}
// Call the real func
realWarns, realErrs := real.Validate(config)
if !reflect.DeepEqual(realWarns, returnWarns) {
t.Fatalf("bad: %#v", realWarns)
}
if !reflect.DeepEqual(realErrs, returnErrs) {
t.Fatalf("bad: %#v", realWarns)
}
// The shadow should finish now
<-doneCh
// Verify the shadow returned the same values
if !reflect.DeepEqual(warns, returnWarns) {
t.Fatalf("bad: %#v", warns)
}
if !reflect.DeepEqual(errs, returnErrs) {
t.Fatalf("bad: %#v", errs)
}
// Verify we have no errors
if err := shadow.CloseShadow(); err != nil {
t.Fatalf("bad: %s", err)
}
}
func TestShadowResourceProvisionerApply(t *testing.T) {
mock := new(MockResourceProvisioner)
real, shadow := newShadowResourceProvisioner(mock)
// Test values
output := new(MockUIOutput)
state := &InstanceState{ID: "foo"}
config := testResourceConfig(t, map[string]interface{}{"foo": "bar"})
mockReturn := errors.New("err")
// Configure the mock
mock.ApplyReturnError = mockReturn
// Verify that it blocks until the real func is called
var err error
doneCh := make(chan struct{})
go func() {
defer close(doneCh)
err = shadow.Apply(output, state, config)
}()
select {
case <-doneCh:
t.Fatal("should block until finished")
case <-time.After(10 * time.Millisecond):
}
// Call the real func
realErr := real.Apply(output, state, config)
if realErr != mockReturn {
t.Fatalf("bad: %#v", realErr)
}
// The shadow should finish now
<-doneCh
// Verify the shadow returned the same values
if err != mockReturn {
t.Errorf("bad: %#v", err)
}
// Verify we have no errors
if err := shadow.CloseShadow(); err != nil {
t.Fatalf("bad: %s", err)
}
if err := shadow.ShadowError(); err != nil {
t.Fatalf("bad: %s", err)
}
}