github.com/paultyng/terraform@v0.6.11-0.20180227224804-66ff8f8bed40/command/hook_ui_test.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "regexp" 6 "testing" 7 "time" 8 9 "github.com/hashicorp/terraform/terraform" 10 "github.com/mitchellh/cli" 11 "github.com/mitchellh/colorstring" 12 ) 13 14 func TestUiHookPreApply_periodicTimer(t *testing.T) { 15 ui := cli.NewMockUi() 16 h := &UiHook{ 17 Colorize: &colorstring.Colorize{ 18 Colors: colorstring.DefaultColors, 19 Disable: true, 20 Reset: true, 21 }, 22 Ui: ui, 23 PeriodicUiTimer: 1 * time.Second, 24 } 25 h.init() 26 h.resources = map[string]uiResourceState{ 27 "data.aws_availability_zones.available": uiResourceState{ 28 Op: uiResourceDestroy, 29 Start: time.Now(), 30 }, 31 } 32 33 n := &terraform.InstanceInfo{ 34 Id: "data.aws_availability_zones.available", 35 ModulePath: []string{"root"}, 36 Type: "aws_availability_zones", 37 } 38 39 s := &terraform.InstanceState{ 40 ID: "2017-03-05 10:56:59.298784526 +0000 UTC", 41 Attributes: map[string]string{ 42 "id": "2017-03-05 10:56:59.298784526 +0000 UTC", 43 "names.#": "4", 44 "names.0": "us-east-1a", 45 "names.1": "us-east-1b", 46 "names.2": "us-east-1c", 47 "names.3": "us-east-1d", 48 }, 49 } 50 d := &terraform.InstanceDiff{ 51 Destroy: true, 52 } 53 54 action, err := h.PreApply(n, s, d) 55 if err != nil { 56 t.Fatal(err) 57 } 58 if action != terraform.HookActionContinue { 59 t.Fatalf("Expected hook to continue, given: %#v", action) 60 } 61 62 time.Sleep(3100 * time.Millisecond) 63 64 // stop the background writer 65 uiState := h.resources[n.HumanId()] 66 close(uiState.DoneCh) 67 <-uiState.done 68 69 expectedOutput := `data.aws_availability_zones.available: Destroying... (ID: 2017-03-05 10:56:59.298784526 +0000 UTC) 70 data.aws_availability_zones.available: Still destroying... (ID: 2017-03-05 10:56:59.298784526 +0000 UTC, 1s elapsed) 71 data.aws_availability_zones.available: Still destroying... (ID: 2017-03-05 10:56:59.298784526 +0000 UTC, 2s elapsed) 72 data.aws_availability_zones.available: Still destroying... (ID: 2017-03-05 10:56:59.298784526 +0000 UTC, 3s elapsed) 73 ` 74 output := ui.OutputWriter.String() 75 if output != expectedOutput { 76 t.Fatalf("Output didn't match.\nExpected: %q\nGiven: %q", expectedOutput, output) 77 } 78 79 expectedErrOutput := "" 80 errOutput := ui.ErrorWriter.String() 81 if errOutput != expectedErrOutput { 82 t.Fatalf("Error output didn't match.\nExpected: %q\nGiven: %q", expectedErrOutput, errOutput) 83 } 84 } 85 86 func TestUiHookPreApply_destroy(t *testing.T) { 87 ui := cli.NewMockUi() 88 h := &UiHook{ 89 Colorize: &colorstring.Colorize{ 90 Colors: colorstring.DefaultColors, 91 Disable: true, 92 Reset: true, 93 }, 94 Ui: ui, 95 } 96 h.init() 97 h.resources = map[string]uiResourceState{ 98 "data.aws_availability_zones.available": uiResourceState{ 99 Op: uiResourceDestroy, 100 Start: time.Now(), 101 }, 102 } 103 104 n := &terraform.InstanceInfo{ 105 Id: "data.aws_availability_zones.available", 106 ModulePath: []string{"root"}, 107 Type: "aws_availability_zones", 108 } 109 110 s := &terraform.InstanceState{ 111 ID: "2017-03-05 10:56:59.298784526 +0000 UTC", 112 Attributes: map[string]string{ 113 "id": "2017-03-05 10:56:59.298784526 +0000 UTC", 114 "names.#": "4", 115 "names.0": "us-east-1a", 116 "names.1": "us-east-1b", 117 "names.2": "us-east-1c", 118 "names.3": "us-east-1d", 119 }, 120 } 121 d := &terraform.InstanceDiff{ 122 Destroy: true, 123 } 124 125 action, err := h.PreApply(n, s, d) 126 if err != nil { 127 t.Fatal(err) 128 } 129 if action != terraform.HookActionContinue { 130 t.Fatalf("Expected hook to continue, given: %#v", action) 131 } 132 133 expectedOutput := "data.aws_availability_zones.available: Destroying... (ID: 2017-03-05 10:56:59.298784526 +0000 UTC)\n" 134 output := ui.OutputWriter.String() 135 if output != expectedOutput { 136 t.Fatalf("Output didn't match.\nExpected: %q\nGiven: %q", expectedOutput, output) 137 } 138 139 expectedErrOutput := "" 140 errOutput := ui.ErrorWriter.String() 141 if errOutput != expectedErrOutput { 142 t.Fatalf("Error output didn't match.\nExpected: %q\nGiven: %q", expectedErrOutput, errOutput) 143 } 144 } 145 146 func TestUiHookPostApply_emptyState(t *testing.T) { 147 ui := cli.NewMockUi() 148 h := &UiHook{ 149 Colorize: &colorstring.Colorize{ 150 Colors: colorstring.DefaultColors, 151 Disable: true, 152 Reset: true, 153 }, 154 Ui: ui, 155 } 156 h.init() 157 h.resources = map[string]uiResourceState{ 158 "data.google_compute_zones.available": uiResourceState{ 159 Op: uiResourceDestroy, 160 Start: time.Now(), 161 }, 162 } 163 164 n := &terraform.InstanceInfo{ 165 Id: "data.google_compute_zones.available", 166 ModulePath: []string{"root"}, 167 Type: "google_compute_zones", 168 } 169 action, err := h.PostApply(n, nil, nil) 170 if err != nil { 171 t.Fatal(err) 172 } 173 if action != terraform.HookActionContinue { 174 t.Fatalf("Expected hook to continue, given: %#v", action) 175 } 176 177 expectedRegexp := "^data.google_compute_zones.available: Destruction complete after -?[a-z0-9.]+\n$" 178 output := ui.OutputWriter.String() 179 if matched, _ := regexp.MatchString(expectedRegexp, output); !matched { 180 t.Fatalf("Output didn't match regexp.\nExpected: %q\nGiven: %q", expectedRegexp, output) 181 } 182 183 expectedErrOutput := "" 184 errOutput := ui.ErrorWriter.String() 185 if errOutput != expectedErrOutput { 186 t.Fatalf("Error output didn't match.\nExpected: %q\nGiven: %q", expectedErrOutput, errOutput) 187 } 188 } 189 190 func TestTruncateId(t *testing.T) { 191 testCases := []struct { 192 Input string 193 Expected string 194 MaxLen int 195 }{ 196 { 197 Input: "Hello world", 198 Expected: "H...d", 199 MaxLen: 3, 200 }, 201 { 202 Input: "Hello world", 203 Expected: "H...d", 204 MaxLen: 5, 205 }, 206 { 207 Input: "Hello world", 208 Expected: "He...d", 209 MaxLen: 6, 210 }, 211 { 212 Input: "Hello world", 213 Expected: "He...ld", 214 MaxLen: 7, 215 }, 216 { 217 Input: "Hello world", 218 Expected: "Hel...ld", 219 MaxLen: 8, 220 }, 221 { 222 Input: "Hello world", 223 Expected: "Hel...rld", 224 MaxLen: 9, 225 }, 226 { 227 Input: "Hello world", 228 Expected: "Hell...rld", 229 MaxLen: 10, 230 }, 231 { 232 Input: "Hello world", 233 Expected: "Hello world", 234 MaxLen: 11, 235 }, 236 { 237 Input: "Hello world", 238 Expected: "Hello world", 239 MaxLen: 12, 240 }, 241 } 242 for i, tc := range testCases { 243 testName := fmt.Sprintf("%d", i) 244 t.Run(testName, func(t *testing.T) { 245 out := truncateId(tc.Input, tc.MaxLen) 246 if out != tc.Expected { 247 t.Fatalf("Expected %q to be shortened to %d as %q (given: %q)", 248 tc.Input, tc.MaxLen, tc.Expected, out) 249 } 250 }) 251 } 252 }