diff --git a/command/operator_api.go b/command/operator_api.go index b7812aad2ef1..36dd375b241b 100644 --- a/command/operator_api.go +++ b/command/operator_api.go @@ -18,6 +18,10 @@ import ( "github.com/posener/complete" ) +// Stdin represents the system's standard input, but it's declared as a +// variable here to allow tests to override it with a regular file. +var Stdin = os.Stdin + type OperatorAPICommand struct { Meta @@ -141,13 +145,13 @@ func (c *OperatorAPICommand) Run(args []string) int { // Opportunistically read from stdin and POST unless method has been // explicitly set. - stat, _ := os.Stdin.Stat() + stat, _ := Stdin.Stat() if (stat.Mode() & os.ModeCharDevice) == 0 { verbose("* Reading request body from stdin.") // Load stdin into a *bytes.Reader so that http.NewRequest can set the // correct Content-Length value. - b, err := ioutil.ReadAll(os.Stdin) + b, err := ioutil.ReadAll(Stdin) if err != nil { c.Ui.Error(fmt.Sprintf("Error reading stdin: %v", err)) return 1 diff --git a/command/operator_api_test.go b/command/operator_api_test.go index 9a17d31bd619..b71e65787f07 100644 --- a/command/operator_api_test.go +++ b/command/operator_api_test.go @@ -2,7 +2,6 @@ package command import ( "bytes" - "io/ioutil" "net/http" "net/http/httptest" "net/url" @@ -176,7 +175,7 @@ func Test_pathToURL(t *testing.T) { // TestOperatorAPICommand_ContentLength tests that requests have the proper // ContentLength set. // -// Don't run in parallel since it messes with os.Stdin. +// Don't run it in parallel as it modifies the package's Stdin variable. func TestOperatorAPICommand_ContentLength(t *testing.T) { contentLength := make(chan int, 1) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -184,23 +183,20 @@ func TestOperatorAPICommand_ContentLength(t *testing.T) { })) defer ts.Close() - // Setup os.Stdin to a known value. - // The command stats stdin, so we can't mock it as another io.Reader. - // https://stackoverflow.com/a/46365584 + // Setup a temp file to act as stdin. input := []byte("test-input") - tmpfile, err := ioutil.TempFile("", "example") + fakeStdin, err := os.CreateTemp("", "fake-stdin") require.NoError(t, err) - defer os.Remove(tmpfile.Name()) + defer os.Remove(fakeStdin.Name()) - _, err = tmpfile.Write(input) + _, err = fakeStdin.Write(input) require.NoError(t, err) - _, err = tmpfile.Seek(0, 0) + _, err = fakeStdin.Seek(0, 0) require.NoError(t, err) - oldStdin := os.Stdin - defer func() { os.Stdin = oldStdin }() - - os.Stdin = tmpfile + // Override the package's Stdin variable for testing. + Stdin = fakeStdin + defer func() { Stdin = os.Stdin }() // Setup command. buf := bytes.NewBuffer(nil)