Drop unnecessary prefix in test output since we rely on go's testing to do the right thing
This commit is contained in:
parent
84d1505807
commit
302f869dc5
|
@ -619,16 +619,6 @@ func ProgramTestManualLifeCycle(t *testing.T, opts *ProgramTestOptions) *Program
|
||||||
return pt
|
return pt
|
||||||
}
|
}
|
||||||
|
|
||||||
// fprintf works like fmt.FPrintf, except it explicitly drops the return values. This keeps the linters happy, since
|
|
||||||
// they don't like to see errors dropped on the floor. It is possible that our call to fmt.Fprintf will fail, even
|
|
||||||
// for "standard" streams like `stdout` and `stderr`, if they have been set to non-blocking by an external process.
|
|
||||||
// In that case, we just drop the error on the floor and continue. We see this behavior in Travis when we try to write
|
|
||||||
// a lot of messages quickly (as we do when logging test failures)
|
|
||||||
func fprintf(w io.Writer, format string, a ...interface{}) {
|
|
||||||
_, err := fmt.Fprintf(w, format, a...)
|
|
||||||
contract.IgnoreError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProgramTester contains state associated with running a single test pass.
|
// ProgramTester contains state associated with running a single test pass.
|
||||||
type ProgramTester struct {
|
type ProgramTester struct {
|
||||||
t *testing.T // the Go tester for this run.
|
t *testing.T // the Go tester for this run.
|
||||||
|
@ -880,8 +870,8 @@ func (pt *ProgramTester) runVirtualEnvCommand(name string, args []string, wd str
|
||||||
}
|
}
|
||||||
|
|
||||||
if pt.opts.Verbose {
|
if pt.opts.Verbose {
|
||||||
fprintf(pt.opts.Stdout, "acquired pip install lock\n")
|
pt.t.Log("acquired pip install lock")
|
||||||
defer fprintf(pt.opts.Stdout, "released pip install lock\n")
|
defer pt.t.Log("released pip install lock")
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := pipMutex.Unlock(); err != nil {
|
if err := pipMutex.Unlock(); err != nil {
|
||||||
|
@ -931,8 +921,8 @@ func (pt *ProgramTester) runPipenvCommand(name string, args []string, wd string)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pt.opts.Verbose {
|
if pt.opts.Verbose {
|
||||||
fprintf(pt.opts.Stdout, "acquired pip install lock\n")
|
pt.t.Log("acquired pip install lock")
|
||||||
defer fprintf(pt.opts.Stdout, "released pip install lock\n")
|
defer pt.t.Log("released pip install lock")
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := pipMutex.Unlock(); err != nil {
|
if err := pipMutex.Unlock(); err != nil {
|
||||||
|
@ -1062,7 +1052,7 @@ func (pt *ProgramTester) TestLifeCycleInitialize() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure all links are present, the stack is created, and all configs are applied.
|
// Ensure all links are present, the stack is created, and all configs are applied.
|
||||||
fprintf(pt.opts.Stdout, "Initializing project (dir %s; stack %s)\n", dir, stackName)
|
pt.t.Logf("Initializing project (dir %s; stack %s)", dir, stackName)
|
||||||
|
|
||||||
// Login as needed.
|
// Login as needed.
|
||||||
stackInitName := string(pt.opts.GetStackNameWithOwner())
|
stackInitName := string(pt.opts.GetStackNameWithOwner())
|
||||||
|
@ -1130,7 +1120,7 @@ func (pt *ProgramTester) TestLifeCycleInitialize() error {
|
||||||
func (pt *ProgramTester) TestLifeCycleDestroy() error {
|
func (pt *ProgramTester) TestLifeCycleDestroy() error {
|
||||||
if pt.projdir != "" {
|
if pt.projdir != "" {
|
||||||
// Destroy and remove the stack.
|
// Destroy and remove the stack.
|
||||||
fprintf(pt.opts.Stdout, "Destroying stack\n")
|
pt.t.Log("Destroying stack")
|
||||||
destroy := []string{"destroy", "--non-interactive", "--yes", "--skip-preview"}
|
destroy := []string{"destroy", "--non-interactive", "--yes", "--skip-preview"}
|
||||||
if pt.opts.GetDebugUpdates() {
|
if pt.opts.GetDebugUpdates() {
|
||||||
destroy = append(destroy, "-d")
|
destroy = append(destroy, "-d")
|
||||||
|
@ -1140,7 +1130,7 @@ func (pt *ProgramTester) TestLifeCycleDestroy() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if pt.t.Failed() {
|
if pt.t.Failed() {
|
||||||
fprintf(pt.opts.Stdout, "Test failed, retaining stack '%s'\n", pt.opts.GetStackNameWithOwner())
|
pt.t.Logf("Test failed, retaining stack '%s'", pt.opts.GetStackNameWithOwner())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1155,7 +1145,7 @@ func (pt *ProgramTester) TestLifeCycleDestroy() error {
|
||||||
func (pt *ProgramTester) TestPreviewUpdateAndEdits() error {
|
func (pt *ProgramTester) TestPreviewUpdateAndEdits() error {
|
||||||
dir := pt.projdir
|
dir := pt.projdir
|
||||||
// Now preview and update the real changes.
|
// Now preview and update the real changes.
|
||||||
fprintf(pt.opts.Stdout, "Performing primary preview and update\n")
|
pt.t.Log("Performing primary preview and update")
|
||||||
initErr := pt.PreviewAndUpdate(dir, "initial", pt.opts.ExpectFailure, false, false)
|
initErr := pt.PreviewAndUpdate(dir, "initial", pt.opts.ExpectFailure, false, false)
|
||||||
|
|
||||||
// If the initial preview/update failed, just exit without trying the rest (but make sure to destroy).
|
// If the initial preview/update failed, just exit without trying the rest (but make sure to destroy).
|
||||||
|
@ -1165,7 +1155,7 @@ func (pt *ProgramTester) TestPreviewUpdateAndEdits() error {
|
||||||
|
|
||||||
// Perform an empty preview and update; nothing is expected to happen here.
|
// Perform an empty preview and update; nothing is expected to happen here.
|
||||||
if !pt.opts.SkipExportImport {
|
if !pt.opts.SkipExportImport {
|
||||||
fprintf(pt.opts.Stdout, "Roundtripping checkpoint via stack export and stack import\n")
|
pt.t.Log("Roundtripping checkpoint via stack export and stack import")
|
||||||
|
|
||||||
if err := pt.exportImport(dir); err != nil {
|
if err := pt.exportImport(dir); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1177,7 +1167,7 @@ func (pt *ProgramTester) TestPreviewUpdateAndEdits() error {
|
||||||
if !pt.opts.AllowEmptyUpdateChanges {
|
if !pt.opts.AllowEmptyUpdateChanges {
|
||||||
msg = "(no changes expected)"
|
msg = "(no changes expected)"
|
||||||
}
|
}
|
||||||
fprintf(pt.opts.Stdout, "Performing empty preview and update%s\n", msg)
|
pt.t.Logf("Performing empty preview and update%s", msg)
|
||||||
if err := pt.PreviewAndUpdate(
|
if err := pt.PreviewAndUpdate(
|
||||||
dir, "empty", false, !pt.opts.AllowEmptyPreviewChanges, !pt.opts.AllowEmptyUpdateChanges); err != nil {
|
dir, "empty", false, !pt.opts.AllowEmptyPreviewChanges, !pt.opts.AllowEmptyUpdateChanges); err != nil {
|
||||||
|
|
||||||
|
@ -1250,7 +1240,7 @@ func (pt *ProgramTester) PreviewAndUpdate(dir string, name string, shouldFail, e
|
||||||
if !pt.opts.SkipPreview {
|
if !pt.opts.SkipPreview {
|
||||||
if err := pt.runPulumiCommand("pulumi-preview-"+name, preview, dir, shouldFail); err != nil {
|
if err := pt.runPulumiCommand("pulumi-preview-"+name, preview, dir, shouldFail); err != nil {
|
||||||
if shouldFail {
|
if shouldFail {
|
||||||
fprintf(pt.opts.Stdout, "Permitting failure (ExpectFailure=true for this preview)\n")
|
pt.t.Log("Permitting failure (ExpectFailure=true for this preview)")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
@ -1261,7 +1251,7 @@ func (pt *ProgramTester) PreviewAndUpdate(dir string, name string, shouldFail, e
|
||||||
if !pt.opts.SkipUpdate {
|
if !pt.opts.SkipUpdate {
|
||||||
if err := pt.runPulumiCommand("pulumi-update-"+name, update, dir, shouldFail); err != nil {
|
if err := pt.runPulumiCommand("pulumi-update-"+name, update, dir, shouldFail); err != nil {
|
||||||
if shouldFail {
|
if shouldFail {
|
||||||
fprintf(pt.opts.Stdout, "Permitting failure (ExpectFailure=true for this update)\n")
|
pt.t.Log("Permitting failure (ExpectFailure=true for this update)")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
@ -1289,7 +1279,7 @@ func (pt *ProgramTester) query(dir string, name string, shouldFail bool) error {
|
||||||
// Now run a query.
|
// Now run a query.
|
||||||
if err := pt.runPulumiCommand("pulumi-query-"+name, query, dir, shouldFail); err != nil {
|
if err := pt.runPulumiCommand("pulumi-query-"+name, query, dir, shouldFail); err != nil {
|
||||||
if shouldFail {
|
if shouldFail {
|
||||||
fprintf(pt.opts.Stdout, "Permitting failure (ExpectFailure=true for this update)\n")
|
pt.t.Log("Permitting failure (ExpectFailure=true for this update)")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
@ -1314,7 +1304,7 @@ func (pt *ProgramTester) testEdits(dir string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pt *ProgramTester) testEdit(dir string, i int, edit EditDir) error {
|
func (pt *ProgramTester) testEdit(dir string, i int, edit EditDir) error {
|
||||||
fprintf(pt.opts.Stdout, "Applying edit '%v' and rerunning preview and update\n", edit.Dir)
|
pt.t.Logf("Applying edit '%v' and rerunning preview and update", edit.Dir)
|
||||||
|
|
||||||
if edit.Additive {
|
if edit.Additive {
|
||||||
// Just copy new files into dir
|
// Just copy new files into dir
|
||||||
|
@ -1498,9 +1488,9 @@ func (pt *ProgramTester) performExtraRuntimeValidation(
|
||||||
Events: events,
|
Events: events,
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(pt.opts.Stdout, "Performing extra runtime validation.\n")
|
pt.t.Log("Performing extra runtime validation.")
|
||||||
extraRuntimeValidation(pt.t, stackInfo)
|
extraRuntimeValidation(pt.t, stackInfo)
|
||||||
fprintf(pt.opts.Stdout, "Extra runtime validation complete.\n")
|
pt.t.Log("Extra runtime validation complete.")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1513,31 +1503,19 @@ func (pt *ProgramTester) copyTestToTemporaryDirectory() (string, string, error)
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up a prefix so that all output has the test directory name in it. This is important for debugging
|
if pt.opts.Stdout == nil {
|
||||||
// because we run tests in parallel, and so all output will be interleaved and difficult to follow otherwise.
|
pt.opts.Stdout = os.Stdout
|
||||||
var prefix string
|
|
||||||
if len(sourceDir) <= 30 {
|
|
||||||
prefix = fmt.Sprintf("[ %30.30s ] ", sourceDir)
|
|
||||||
} else {
|
|
||||||
prefix = fmt.Sprintf("[ %30.30s ] ", sourceDir[len(sourceDir)-30:])
|
|
||||||
}
|
}
|
||||||
stdout := pt.opts.Stdout
|
if pt.opts.Stderr == nil {
|
||||||
if stdout == nil {
|
pt.opts.Stderr = os.Stderr
|
||||||
stdout = newPrefixer(os.Stdout, prefix)
|
|
||||||
pt.opts.Stdout = stdout
|
|
||||||
}
|
|
||||||
stderr := pt.opts.Stderr
|
|
||||||
if stderr == nil {
|
|
||||||
stderr = newPrefixer(os.Stderr, prefix)
|
|
||||||
pt.opts.Stderr = stderr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(pt.opts.Stdout, "sample: %v\n", sourceDir)
|
pt.t.Logf("sample: %v", sourceDir)
|
||||||
bin, err := pt.getBin()
|
bin, err := pt.getBin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
fprintf(pt.opts.Stdout, "pulumi: %v\n", bin)
|
pt.t.Logf("pulumi: %v\n", bin)
|
||||||
|
|
||||||
stackName := string(pt.opts.GetStackName())
|
stackName := string(pt.opts.GetStackName())
|
||||||
|
|
||||||
|
@ -1600,7 +1578,7 @@ func (pt *ProgramTester) copyTestToTemporaryDirectory() (string, string, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stdout, "projdir: %v\n", projdir)
|
pt.t.Logf("projdir: %v", projdir)
|
||||||
return tmpdir, projdir, nil
|
return tmpdir, projdir, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1675,7 +1653,7 @@ func (pt *ProgramTester) prepareNodeJSProject(projinfo *engine.Projinfo) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(pt.opts.Stdout, "adding resolution for %s to version %s\n", packageName, packageVersion)
|
pt.t.Logf("adding resolution for %s to version %s", packageName, packageVersion)
|
||||||
resolutions["**/"+packageName] = packageVersion
|
resolutions["**/"+packageName] = packageVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
@ -27,15 +26,6 @@ import (
|
||||||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/contract"
|
"github.com/pulumi/pulumi/sdk/v2/go/common/util/contract"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPrefixer(t *testing.T) {
|
|
||||||
byts := make([]byte, 0, 1000)
|
|
||||||
buf := bytes.NewBuffer(byts)
|
|
||||||
prefixer := newPrefixer(buf, "OK: ")
|
|
||||||
_, err := prefixer.Write([]byte("\nsadsada\n\nasdsadsa\nasdsadsa\n"))
|
|
||||||
contract.AssertNoError(err)
|
|
||||||
assert.Equal(t, []byte("OK: \nOK: sadsada\nOK: \nOK: asdsadsa\nOK: asdsadsa\n"), buf.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that RunCommand writes the command's output to a log file.
|
// Test that RunCommand writes the command's output to a log file.
|
||||||
func TestRunCommandLog(t *testing.T) {
|
func TestRunCommandLog(t *testing.T) {
|
||||||
// Try to find node on the path. We need a program to run, and node is probably
|
// Try to find node on the path. We need a program to run, and node is probably
|
||||||
|
@ -55,7 +45,7 @@ func TestRunCommandLog(t *testing.T) {
|
||||||
defer os.RemoveAll(tempdir)
|
defer os.RemoveAll(tempdir)
|
||||||
|
|
||||||
args := []string{node, "-e", "console.log('output from node');"}
|
args := []string{node, "-e", "console.log('output from node');"}
|
||||||
err = RunCommand(nil, "node", args, tempdir, opts)
|
err = RunCommand(t, "node", args, tempdir, opts)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
matches, err := filepath.Glob(filepath.Join(tempdir, commandOutputFolderName, "node.*"))
|
matches, err := filepath.Glob(filepath.Join(tempdir, commandOutputFolderName, "node.*"))
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -105,38 +104,6 @@ func writeCommandOutput(commandName, runDir string, output []byte) (string, erro
|
||||||
return logFile, nil
|
return logFile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type prefixer struct {
|
|
||||||
writer io.Writer
|
|
||||||
prefix []byte
|
|
||||||
anyOutput bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// newPrefixer wraps an io.Writer, prepending a fixed prefix after each \n emitting on the wrapped writer
|
|
||||||
func newPrefixer(writer io.Writer, prefix string) *prefixer {
|
|
||||||
return &prefixer{writer, []byte(prefix), false}
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ io.Writer = (*prefixer)(nil)
|
|
||||||
|
|
||||||
func (prefixer *prefixer) Write(p []byte) (int, error) {
|
|
||||||
n := 0
|
|
||||||
lines := bytes.SplitAfter(p, []byte{'\n'})
|
|
||||||
for _, line := range lines {
|
|
||||||
if len(line) > 0 {
|
|
||||||
_, err := prefixer.writer.Write(prefixer.prefix)
|
|
||||||
if err != nil {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m, err := prefixer.writer.Write(line)
|
|
||||||
n += m
|
|
||||||
if err != nil {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyFile copies a single file from src to dst
|
// CopyFile copies a single file from src to dst
|
||||||
// From https://blog.depado.eu/post/copy-files-and-directories-in-go
|
// From https://blog.depado.eu/post/copy-files-and-directories-in-go
|
||||||
func CopyFile(src, dst string) error {
|
func CopyFile(src, dst string) error {
|
||||||
|
|
|
@ -394,7 +394,7 @@ func TestRuntimeErrorPython(t *testing.T) {
|
||||||
|
|
||||||
_, err = s.Up(ctx)
|
_, err = s.Up(ctx)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
assert.True(t, IsRuntimeError(err))
|
assert.True(t, IsRuntimeError(err), "%+v", err)
|
||||||
|
|
||||||
// -- pulumi destroy --
|
// -- pulumi destroy --
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue