(t *testing.T, fn func() error)
| 564 | } |
| 565 | |
| 566 | func captureOutput(t *testing.T, fn func() error) (string, string) { |
| 567 | t.Helper() |
| 568 | // Do not call this helper from tests using t.Parallel; it manipulates |
| 569 | // process-global stdout/stderr and must be serialized. |
| 570 | captureOutputMu.Lock() |
| 571 | defer captureOutputMu.Unlock() |
| 572 | |
| 573 | stdoutReader, stdoutWriter, err := os.Pipe() |
| 574 | require.NoError(t, err, "should create stdout pipe") |
| 575 | |
| 576 | stderrReader, stderrWriter, err := os.Pipe() |
| 577 | require.NoError(t, err, "should create stderr pipe") |
| 578 | t.Cleanup(func() { |
| 579 | _ = stdoutReader.Close() |
| 580 | _ = stderrReader.Close() |
| 581 | }) |
| 582 | |
| 583 | origStdout := os.Stdout |
| 584 | origStderr := os.Stderr |
| 585 | var runErr error |
| 586 | func() { |
| 587 | os.Stdout = stdoutWriter |
| 588 | os.Stderr = stderrWriter |
| 589 | defer func() { |
| 590 | os.Stdout = origStdout |
| 591 | os.Stderr = origStderr |
| 592 | _ = stdoutWriter.Close() |
| 593 | _ = stderrWriter.Close() |
| 594 | }() |
| 595 | |
| 596 | runErr = fn() |
| 597 | }() |
| 598 | require.NoError(t, runErr, "output function should not return an error") |
| 599 | |
| 600 | var stdoutBuf bytes.Buffer |
| 601 | _, err = io.Copy(&stdoutBuf, stdoutReader) |
| 602 | require.NoError(t, err, "should read stdout output") |
| 603 | |
| 604 | var stderrBuf bytes.Buffer |
| 605 | _, err = io.Copy(&stderrBuf, stderrReader) |
| 606 | require.NoError(t, err, "should read stderr output") |
| 607 | |
| 608 | return stdoutBuf.String(), stderrBuf.String() |
| 609 | } |
no test coverage detected