command: Add tests for UiHook (#12447)
This commit is contained in:
parent
e15ba7e595
commit
4d6242dfe0
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue