command: Add tests for UiHook (#12447)

This commit is contained in:
Radek Simko 2017-03-13 20:09:25 +00:00 committed by GitHub
parent e15ba7e595
commit 4d6242dfe0
2 changed files with 197 additions and 4 deletions

View File

@ -15,14 +15,15 @@ import (
"github.com/mitchellh/colorstring" "github.com/mitchellh/colorstring"
) )
const periodicUiTimer = 10 * time.Second const defaultPeriodicUiTimer = 10 * time.Second
const maxIdLen = 20 const maxIdLen = 20
type UiHook struct { type UiHook struct {
terraform.NilHook terraform.NilHook
Colorize *colorstring.Colorize Colorize *colorstring.Colorize
Ui cli.Ui Ui cli.Ui
PeriodicUiTimer time.Duration
l sync.Mutex l sync.Mutex
once sync.Once once sync.Once
@ -163,7 +164,7 @@ func (h *UiHook) stillApplying(state uiResourceState) {
case <-state.DoneCh: case <-state.DoneCh:
return return
case <-time.After(periodicUiTimer): case <-time.After(h.PeriodicUiTimer):
// Timer up, show status // Timer up, show status
} }
@ -330,6 +331,9 @@ func (h *UiHook) init() {
if h.Colorize == nil { if h.Colorize == nil {
panic("colorize not given") panic("colorize not given")
} }
if h.PeriodicUiTimer == 0 {
h.PeriodicUiTimer = defaultPeriodicUiTimer
}
h.resources = make(map[string]uiResourceState) h.resources = make(map[string]uiResourceState)

View File

@ -1,10 +1,199 @@
package command package command
import ( import (
"bytes"
"fmt" "fmt"
"testing" "testing"
"time"
"github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/cli"
"github.com/mitchellh/colorstring"
) )
func TestUiHookPreApply_periodicTimer(t *testing.T) {
ui := &cli.MockUi{
InputReader: bytes.NewReader([]byte{}),
ErrorWriter: bytes.NewBuffer([]byte{}),
OutputWriter: bytes.NewBuffer([]byte{}),
}
h := &UiHook{
Colorize: &colorstring.Colorize{
Colors: colorstring.DefaultColors,
Disable: true,
Reset: true,
},
Ui: ui,
PeriodicUiTimer: 1 * time.Second,
}
h.init()
h.resources = map[string]uiResourceState{
"data.aws_availability_zones.available": uiResourceState{
Op: uiResourceDestroy,
Start: time.Now(),
},
}
n := &terraform.InstanceInfo{
Id: "data.aws_availability_zones.available",
ModulePath: []string{"root"},
Type: "aws_availability_zones",
}
s := &terraform.InstanceState{
ID: "2017-03-05 10:56:59.298784526 +0000 UTC",
Attributes: map[string]string{
"id": "2017-03-05 10:56:59.298784526 +0000 UTC",
"names.#": "4",
"names.0": "us-east-1a",
"names.1": "us-east-1b",
"names.2": "us-east-1c",
"names.3": "us-east-1d",
},
}
d := &terraform.InstanceDiff{
Destroy: true,
}
action, err := h.PreApply(n, s, d)
if err != nil {
t.Fatal(err)
}
if action != terraform.HookActionContinue {
t.Fatalf("Expected hook to continue, given: %#v", action)
}
time.Sleep(3100 * time.Millisecond)
expectedOutput := `data.aws_availability_zones.available: Destroying... (ID: 2017-03-0...0000 UTC)
data.aws_availability_zones.available: Still destroying... (ID: 2017-03-0...0000 UTC, 1s elapsed)
data.aws_availability_zones.available: Still destroying... (ID: 2017-03-0...0000 UTC, 2s elapsed)
data.aws_availability_zones.available: Still destroying... (ID: 2017-03-0...0000 UTC, 3s elapsed)
`
output := ui.OutputWriter.String()
if output != expectedOutput {
t.Fatalf("Output didn't match.\nExpected: %q\nGiven: %q", expectedOutput, output)
}
expectedErrOutput := ""
errOutput := ui.ErrorWriter.String()
if errOutput != expectedErrOutput {
t.Fatalf("Error output didn't match.\nExpected: %q\nGiven: %q", expectedErrOutput, errOutput)
}
}
func TestUiHookPreApply_destroy(t *testing.T) {
ui := &cli.MockUi{
InputReader: bytes.NewReader([]byte{}),
ErrorWriter: bytes.NewBuffer([]byte{}),
OutputWriter: bytes.NewBuffer([]byte{}),
}
h := &UiHook{
Colorize: &colorstring.Colorize{
Colors: colorstring.DefaultColors,
Disable: true,
Reset: true,
},
Ui: ui,
}
h.init()
h.resources = map[string]uiResourceState{
"data.aws_availability_zones.available": uiResourceState{
Op: uiResourceDestroy,
Start: time.Now(),
},
}
n := &terraform.InstanceInfo{
Id: "data.aws_availability_zones.available",
ModulePath: []string{"root"},
Type: "aws_availability_zones",
}
s := &terraform.InstanceState{
ID: "2017-03-05 10:56:59.298784526 +0000 UTC",
Attributes: map[string]string{
"id": "2017-03-05 10:56:59.298784526 +0000 UTC",
"names.#": "4",
"names.0": "us-east-1a",
"names.1": "us-east-1b",
"names.2": "us-east-1c",
"names.3": "us-east-1d",
},
}
d := &terraform.InstanceDiff{
Destroy: true,
}
action, err := h.PreApply(n, s, d)
if err != nil {
t.Fatal(err)
}
if action != terraform.HookActionContinue {
t.Fatalf("Expected hook to continue, given: %#v", action)
}
expectedOutput := "data.aws_availability_zones.available: Destroying... (ID: 2017-03-0...0000 UTC)\n"
output := ui.OutputWriter.String()
if output != expectedOutput {
t.Fatalf("Output didn't match.\nExpected: %q\nGiven: %q", expectedOutput, output)
}
expectedErrOutput := ""
errOutput := ui.ErrorWriter.String()
if errOutput != expectedErrOutput {
t.Fatalf("Error output didn't match.\nExpected: %q\nGiven: %q", expectedErrOutput, errOutput)
}
}
func TestUiHookPostApply_emptyState(t *testing.T) {
ui := &cli.MockUi{
InputReader: bytes.NewReader([]byte{}),
ErrorWriter: bytes.NewBuffer([]byte{}),
OutputWriter: bytes.NewBuffer([]byte{}),
}
h := &UiHook{
Colorize: &colorstring.Colorize{
Colors: colorstring.DefaultColors,
Disable: true,
Reset: true,
},
Ui: ui,
}
h.init()
h.resources = map[string]uiResourceState{
"data.google_compute_zones.available": uiResourceState{
Op: uiResourceDestroy,
Start: time.Now(),
},
}
n := &terraform.InstanceInfo{
Id: "data.google_compute_zones.available",
ModulePath: []string{"root"},
Type: "google_compute_zones",
}
action, err := h.PostApply(n, nil, nil)
if err != nil {
t.Fatal(err)
}
if action != terraform.HookActionContinue {
t.Fatalf("Expected hook to continue, given: %#v", action)
}
expectedOutput := "data.google_compute_zones.available: Destruction complete\n"
output := ui.OutputWriter.String()
if output != expectedOutput {
t.Fatalf("Output didn't match.\nExpected: %q\nGiven: %q", expectedOutput, output)
}
expectedErrOutput := ""
errOutput := ui.ErrorWriter.String()
if errOutput != expectedErrOutput {
t.Fatalf("Error output didn't match.\nExpected: %q\nGiven: %q", expectedErrOutput, errOutput)
}
}
func TestTruncateId(t *testing.T) { func TestTruncateId(t *testing.T) {
testCases := []struct { testCases := []struct {
Input string Input string