2013-03-24 17:31:18 -04:00
|
|
|
package packer
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2013-12-16 23:48:39 -05:00
|
|
|
"os"
|
2013-08-11 22:05:07 -04:00
|
|
|
"strings"
|
2013-03-24 17:47:59 -04:00
|
|
|
"testing"
|
2020-11-20 13:21:29 -05:00
|
|
|
|
2020-12-17 16:29:25 -05:00
|
|
|
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
2013-03-24 17:31:18 -04:00
|
|
|
)
|
|
|
|
|
2014-02-21 21:29:15 -05:00
|
|
|
// This reads the output from the bytes.Buffer in our test object
|
|
|
|
// and then resets the buffer.
|
2020-11-20 13:21:29 -05:00
|
|
|
func readWriter(ui *packersdk.BasicUi) (result string) {
|
2014-02-21 21:29:15 -05:00
|
|
|
buffer := ui.Writer.(*bytes.Buffer)
|
|
|
|
result = buffer.String()
|
|
|
|
buffer.Reset()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-01-29 09:10:14 -05:00
|
|
|
// Reset the input Reader than add some input to it.
|
2020-11-20 13:21:29 -05:00
|
|
|
func writeReader(ui *packersdk.BasicUi, input string) {
|
2017-01-29 09:10:14 -05:00
|
|
|
buffer := ui.Reader.(*bytes.Buffer)
|
|
|
|
buffer.WriteString(input)
|
|
|
|
}
|
|
|
|
|
2020-11-20 13:21:29 -05:00
|
|
|
func readErrorWriter(ui *packersdk.BasicUi) (result string) {
|
2014-02-21 21:29:15 -05:00
|
|
|
buffer := ui.ErrorWriter.(*bytes.Buffer)
|
|
|
|
result = buffer.String()
|
|
|
|
buffer.Reset()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-11-20 13:21:29 -05:00
|
|
|
func testUi() *packersdk.BasicUi {
|
|
|
|
return &packersdk.BasicUi{
|
2014-02-21 23:02:55 -05:00
|
|
|
Reader: new(bytes.Buffer),
|
|
|
|
Writer: new(bytes.Buffer),
|
2014-02-21 21:29:15 -05:00
|
|
|
ErrorWriter: new(bytes.Buffer),
|
2019-03-06 09:54:10 -05:00
|
|
|
TTY: new(testTTY),
|
2013-04-20 21:55:02 -04:00
|
|
|
}
|
|
|
|
}
|
2013-03-24 17:31:18 -04:00
|
|
|
|
2019-02-28 08:40:55 -05:00
|
|
|
type testTTY struct {
|
|
|
|
say string
|
|
|
|
}
|
|
|
|
|
2019-03-15 06:10:30 -04:00
|
|
|
func (tty *testTTY) Close() error { return nil }
|
2019-03-06 09:54:10 -05:00
|
|
|
func (tty *testTTY) ReadString() (string, error) {
|
|
|
|
return tty.say, nil
|
2019-02-28 08:40:55 -05:00
|
|
|
}
|
|
|
|
|
2013-06-03 16:35:43 -04:00
|
|
|
func TestColoredUi(t *testing.T) {
|
|
|
|
bufferUi := testUi()
|
2020-09-23 14:33:51 -04:00
|
|
|
ui := &ColoredUi{UiColorYellow, UiColorRed, bufferUi, &UiProgressBar{}}
|
2013-06-03 16:35:43 -04:00
|
|
|
|
2015-04-07 14:33:58 -04:00
|
|
|
if !ui.supportsColors() {
|
|
|
|
t.Skip("skipping for ui without color support")
|
|
|
|
}
|
|
|
|
|
2013-06-03 16:35:43 -04:00
|
|
|
ui.Say("foo")
|
2013-06-12 13:41:58 -04:00
|
|
|
result := readWriter(bufferUi)
|
2013-11-20 00:31:54 -05:00
|
|
|
if result != "\033[1;33mfoo\033[0m\n" {
|
2013-06-12 13:41:58 -04:00
|
|
|
t.Fatalf("invalid output: %s", result)
|
|
|
|
}
|
|
|
|
|
|
|
|
ui.Message("foo")
|
|
|
|
result = readWriter(bufferUi)
|
2013-11-20 00:31:54 -05:00
|
|
|
if result != "\033[0;33mfoo\033[0m\n" {
|
2013-06-12 13:41:58 -04:00
|
|
|
t.Fatalf("invalid output: %s", result)
|
|
|
|
}
|
|
|
|
|
|
|
|
ui.Error("foo")
|
|
|
|
result = readWriter(bufferUi)
|
2014-02-21 21:29:15 -05:00
|
|
|
if result != "" {
|
|
|
|
t.Fatalf("invalid output: %s", result)
|
|
|
|
}
|
|
|
|
|
|
|
|
result = readErrorWriter(bufferUi)
|
2013-11-20 00:31:54 -05:00
|
|
|
if result != "\033[1;31mfoo\033[0m\n" {
|
2013-06-12 13:41:58 -04:00
|
|
|
t.Fatalf("invalid output: %s", result)
|
|
|
|
}
|
2013-06-03 16:35:43 -04:00
|
|
|
}
|
|
|
|
|
2013-12-16 23:48:39 -05:00
|
|
|
func TestColoredUi_noColorEnv(t *testing.T) {
|
|
|
|
bufferUi := testUi()
|
2020-09-23 14:33:51 -04:00
|
|
|
ui := &ColoredUi{UiColorYellow, UiColorRed, bufferUi, &UiProgressBar{}}
|
2013-12-16 23:48:39 -05:00
|
|
|
|
|
|
|
// Set the env var to get rid of the color
|
|
|
|
oldenv := os.Getenv("PACKER_NO_COLOR")
|
|
|
|
os.Setenv("PACKER_NO_COLOR", "1")
|
|
|
|
defer os.Setenv("PACKER_NO_COLOR", oldenv)
|
|
|
|
|
|
|
|
ui.Say("foo")
|
|
|
|
result := readWriter(bufferUi)
|
|
|
|
if result != "foo\n" {
|
|
|
|
t.Fatalf("invalid output: %s", result)
|
|
|
|
}
|
|
|
|
|
|
|
|
ui.Message("foo")
|
|
|
|
result = readWriter(bufferUi)
|
|
|
|
if result != "foo\n" {
|
|
|
|
t.Fatalf("invalid output: %s", result)
|
|
|
|
}
|
|
|
|
|
|
|
|
ui.Error("foo")
|
2014-02-21 21:29:15 -05:00
|
|
|
result = readErrorWriter(bufferUi)
|
2013-12-16 23:48:39 -05:00
|
|
|
if result != "foo\n" {
|
|
|
|
t.Fatalf("invalid output: %s", result)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-29 15:44:42 -04:00
|
|
|
func TestTargetedUI(t *testing.T) {
|
2013-05-21 16:20:51 -04:00
|
|
|
bufferUi := testUi()
|
2018-03-13 23:24:39 -04:00
|
|
|
targetedUi := &TargetedUI{
|
2013-08-11 21:31:28 -04:00
|
|
|
Target: "foo",
|
|
|
|
Ui: bufferUi,
|
|
|
|
}
|
2013-05-21 16:20:51 -04:00
|
|
|
|
2013-10-17 03:09:27 -04:00
|
|
|
var actual, expected string
|
2018-03-13 23:24:39 -04:00
|
|
|
targetedUi.Say("foo")
|
2013-10-17 03:09:27 -04:00
|
|
|
actual = readWriter(bufferUi)
|
|
|
|
expected = "==> foo: foo\n"
|
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("bad: %#v", actual)
|
|
|
|
}
|
2013-05-21 16:20:51 -04:00
|
|
|
|
2018-03-13 23:24:39 -04:00
|
|
|
targetedUi.Message("foo")
|
2013-10-17 03:09:27 -04:00
|
|
|
actual = readWriter(bufferUi)
|
|
|
|
expected = " foo: foo\n"
|
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("bad: %#v", actual)
|
|
|
|
}
|
2013-06-03 14:30:38 -04:00
|
|
|
|
2018-03-13 23:24:39 -04:00
|
|
|
targetedUi.Error("bar")
|
2014-02-21 21:29:15 -05:00
|
|
|
actual = readErrorWriter(bufferUi)
|
2013-10-17 03:09:27 -04:00
|
|
|
expected = "==> foo: bar\n"
|
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("bad: %#v", actual)
|
|
|
|
}
|
2013-07-02 15:28:25 -04:00
|
|
|
|
2018-03-13 23:24:39 -04:00
|
|
|
targetedUi.Say("foo\nbar")
|
2013-10-17 03:09:27 -04:00
|
|
|
actual = readWriter(bufferUi)
|
|
|
|
expected = "==> foo: foo\n==> foo: bar\n"
|
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("bad: %#v", actual)
|
|
|
|
}
|
2013-05-21 16:20:51 -04:00
|
|
|
}
|
|
|
|
|
2013-06-03 16:35:43 -04:00
|
|
|
func TestColoredUi_ImplUi(t *testing.T) {
|
|
|
|
var raw interface{}
|
|
|
|
raw = &ColoredUi{}
|
2020-11-20 13:21:29 -05:00
|
|
|
if _, ok := raw.(packersdk.Ui); !ok {
|
2013-06-03 16:35:43 -04:00
|
|
|
t.Fatalf("ColoredUi must implement Ui")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-29 15:44:42 -04:00
|
|
|
func TestTargetedUI_ImplUi(t *testing.T) {
|
2013-05-21 16:20:51 -04:00
|
|
|
var raw interface{}
|
2017-03-29 15:44:42 -04:00
|
|
|
raw = &TargetedUI{}
|
2020-11-20 13:21:29 -05:00
|
|
|
if _, ok := raw.(packersdk.Ui); !ok {
|
2017-03-29 15:44:42 -04:00
|
|
|
t.Fatalf("TargetedUI must implement Ui")
|
2013-05-21 16:20:51 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-11 21:20:27 -04:00
|
|
|
func TestBasicUi_ImplUi(t *testing.T) {
|
2013-05-21 16:20:51 -04:00
|
|
|
var raw interface{}
|
2020-11-20 13:21:29 -05:00
|
|
|
raw = &packersdk.BasicUi{}
|
|
|
|
if _, ok := raw.(packersdk.Ui); !ok {
|
2013-08-11 21:20:27 -04:00
|
|
|
t.Fatalf("BasicUi must implement Ui")
|
2013-05-21 16:20:51 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-11 21:20:27 -04:00
|
|
|
func TestBasicUi_Error(t *testing.T) {
|
2013-05-08 18:12:48 -04:00
|
|
|
bufferUi := testUi()
|
|
|
|
|
2013-10-17 03:09:27 -04:00
|
|
|
var actual, expected string
|
2013-05-08 18:12:48 -04:00
|
|
|
bufferUi.Error("foo")
|
2014-02-21 21:29:15 -05:00
|
|
|
actual = readErrorWriter(bufferUi)
|
2013-10-17 03:09:27 -04:00
|
|
|
expected = "foo\n"
|
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("bad: %#v", actual)
|
|
|
|
}
|
2013-05-08 18:12:48 -04:00
|
|
|
|
2014-02-21 21:29:15 -05:00
|
|
|
bufferUi.ErrorWriter = nil
|
2013-05-27 18:12:48 -04:00
|
|
|
bufferUi.Error("5")
|
2013-10-17 03:09:27 -04:00
|
|
|
actual = readWriter(bufferUi)
|
|
|
|
expected = "5\n"
|
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("bad: %#v", actual)
|
|
|
|
}
|
2013-05-08 18:12:48 -04:00
|
|
|
}
|
|
|
|
|
2013-08-11 21:20:27 -04:00
|
|
|
func TestBasicUi_Say(t *testing.T) {
|
2013-04-20 21:55:02 -04:00
|
|
|
bufferUi := testUi()
|
|
|
|
|
2013-10-17 03:09:27 -04:00
|
|
|
var actual, expected string
|
|
|
|
|
2013-03-24 17:31:18 -04:00
|
|
|
bufferUi.Say("foo")
|
2013-10-17 03:09:27 -04:00
|
|
|
actual = readWriter(bufferUi)
|
|
|
|
expected = "foo\n"
|
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("bad: %#v", actual)
|
|
|
|
}
|
2013-03-24 17:31:18 -04:00
|
|
|
|
2013-05-27 18:12:48 -04:00
|
|
|
bufferUi.Say("5")
|
2013-10-17 03:09:27 -04:00
|
|
|
actual = readWriter(bufferUi)
|
|
|
|
expected = "5\n"
|
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("bad: %#v", actual)
|
|
|
|
}
|
2013-03-24 17:31:18 -04:00
|
|
|
}
|
|
|
|
|
2017-01-29 09:10:14 -05:00
|
|
|
func TestBasicUi_Ask(t *testing.T) {
|
|
|
|
|
|
|
|
var actual, expected string
|
|
|
|
var err error
|
|
|
|
|
|
|
|
var testCases = []struct {
|
|
|
|
Prompt, Input, Answer string
|
|
|
|
}{
|
|
|
|
{"[c]ontinue or [a]bort", "c\n", "c"},
|
|
|
|
{"[c]ontinue or [a]bort", "c", "c"},
|
|
|
|
// Empty input shouldn't give an error
|
|
|
|
{"Name", "Joe Bloggs\n", "Joe Bloggs"},
|
|
|
|
{"Name", "Joe Bloggs", "Joe Bloggs"},
|
|
|
|
{"Name", "\n", ""},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, testCase := range testCases {
|
2018-03-13 03:40:52 -04:00
|
|
|
// Because of the internal bufio we can't easily reset the input, so create a new one each time
|
2017-01-29 09:10:14 -05:00
|
|
|
bufferUi := testUi()
|
2019-03-06 09:54:10 -05:00
|
|
|
bufferUi.TTY = &testTTY{testCase.Input}
|
2017-01-29 09:10:14 -05:00
|
|
|
|
|
|
|
actual, err = bufferUi.Ask(testCase.Prompt)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if actual != testCase.Answer {
|
|
|
|
t.Fatalf("bad answer: %#v", actual)
|
|
|
|
}
|
|
|
|
|
|
|
|
actual = readWriter(bufferUi)
|
|
|
|
expected = testCase.Prompt + " "
|
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("bad prompt: %#v", actual)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-08-11 22:05:07 -04:00
|
|
|
func TestMachineReadableUi_ImplUi(t *testing.T) {
|
|
|
|
var raw interface{}
|
|
|
|
raw = &MachineReadableUi{}
|
2020-11-20 13:21:29 -05:00
|
|
|
if _, ok := raw.(packersdk.Ui); !ok {
|
2013-08-11 22:05:07 -04:00
|
|
|
t.Fatalf("MachineReadableUi must implement Ui")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMachineReadableUi(t *testing.T) {
|
|
|
|
var data, expected string
|
|
|
|
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
ui := &MachineReadableUi{Writer: buf}
|
|
|
|
|
2013-08-12 02:18:14 -04:00
|
|
|
// No target
|
2013-08-11 22:05:07 -04:00
|
|
|
ui.Machine("foo", "bar", "baz")
|
|
|
|
data = strings.SplitN(buf.String(), ",", 2)[1]
|
2013-08-12 02:18:14 -04:00
|
|
|
expected = ",foo,bar,baz\n"
|
2013-08-11 22:05:07 -04:00
|
|
|
if data != expected {
|
|
|
|
t.Fatalf("bad: %s", data)
|
|
|
|
}
|
|
|
|
|
2013-08-12 02:18:14 -04:00
|
|
|
// Target
|
2013-08-11 22:05:07 -04:00
|
|
|
buf.Reset()
|
|
|
|
ui.Machine("mitchellh,foo", "bar", "baz")
|
|
|
|
data = strings.SplitN(buf.String(), ",", 2)[1]
|
2013-08-12 02:18:14 -04:00
|
|
|
expected = "mitchellh,foo,bar,baz\n"
|
2013-08-11 22:05:07 -04:00
|
|
|
if data != expected {
|
|
|
|
t.Fatalf("bad: %s", data)
|
|
|
|
}
|
|
|
|
|
2013-08-12 02:18:14 -04:00
|
|
|
// Commas
|
2013-08-11 22:05:07 -04:00
|
|
|
buf.Reset()
|
|
|
|
ui.Machine("foo", "foo,bar")
|
|
|
|
data = strings.SplitN(buf.String(), ",", 2)[1]
|
2013-08-12 02:18:14 -04:00
|
|
|
expected = ",foo,foo%!(PACKER_COMMA)bar\n"
|
2013-08-11 22:05:07 -04:00
|
|
|
if data != expected {
|
|
|
|
t.Fatalf("bad: %s", data)
|
|
|
|
}
|
2013-08-12 02:18:14 -04:00
|
|
|
|
|
|
|
// New lines
|
|
|
|
buf.Reset()
|
|
|
|
ui.Machine("foo", "foo\n")
|
|
|
|
data = strings.SplitN(buf.String(), ",", 2)[1]
|
|
|
|
expected = ",foo,foo\\n\n"
|
|
|
|
if data != expected {
|
|
|
|
t.Fatalf("bad: %#v", data)
|
|
|
|
}
|
2013-08-11 22:05:07 -04:00
|
|
|
}
|