github.com/skyscape-cloud-services/terraform@v0.9.2-0.20170609144644-7ece028a1747/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 }