Description
Unit tests in cmd/middleware (and occasionally adjacent packages) intermittently report FAIL (unknown) even though the test itself passes. The tool first-run middleware creates its spinners via uxlib.NewSpinner without a Writer, which defaults to os.Stdout. On start/stop the spinner emits cursor escape codes (\033[?25l / \033[?25h) directly to stdout. Under go test -json, those raw bytes corrupt the event stream, so the runner misattributes a passing test as a failure - sometimes onto an unrelated test that ran concurrently.
Symptom
=== FAIL: cmd/middleware TestToolFirstRunMiddleware_OfferInstall_PromptError (unknown)
25h--- PASS: TestToolFirstRunMiddleware_OfferInstall_PromptError (0.00s)
The 25h prefix is the tail of the show-cursor escape \033[?25h.
Root cause
SpinnerOptions.Writer defaults to os.Stdout (cli/azd/pkg/ux/spinner.go).
- The detect/install spinners in
cli/azd/cmd/middleware/tool_first_run.go do not set Writer.
forbidigo only guards os.Stdout writes in *_test.go, so it does not catch this production-code path.
Expected
Spinners exercised by tests should write to the console handle (io.Discard under MockConsole), keeping the go test -json stream clean. Related to #8385.
Description
Unit tests in
cmd/middleware(and occasionally adjacent packages) intermittently reportFAIL (unknown)even though the test itself passes. The tool first-run middleware creates its spinners viauxlib.NewSpinnerwithout aWriter, which defaults toos.Stdout. On start/stop the spinner emits cursor escape codes (\033[?25l/\033[?25h) directly to stdout. Undergo test -json, those raw bytes corrupt the event stream, so the runner misattributes a passing test as a failure - sometimes onto an unrelated test that ran concurrently.Symptom
The
25hprefix is the tail of the show-cursor escape\033[?25h.Root cause
SpinnerOptions.Writerdefaults toos.Stdout(cli/azd/pkg/ux/spinner.go).cli/azd/cmd/middleware/tool_first_run.godo not setWriter.forbidigoonly guardsos.Stdoutwrites in*_test.go, so it does not catch this production-code path.Expected
Spinners exercised by tests should write to the console handle (
io.DiscardunderMockConsole), keeping thego test -jsonstream clean. Related to #8385.