Commit 1aa5b47c authored by Gari Singh's avatar Gari Singh Committed by Gerrit Code Review
Browse files

Merge "Fix error processing for runProgram"

parents 8a15ac6a c184b3f2
......@@ -18,7 +18,7 @@ package golang
import (
"bytes"
"errors"
"context"
"fmt"
"os/exec"
"strings"
......@@ -30,35 +30,30 @@ func runProgram(env Env, timeout time.Duration, pgm string, args ...string) ([]b
if env == nil {
return nil, fmt.Errorf("<%s, %v>: nil env provided", pgm, args)
}
var stdOut bytes.Buffer
var stdErr bytes.Buffer
cmd := exec.Command(pgm, args...)
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
cmd := exec.CommandContext(ctx, pgm, args...)
cmd.Env = flattenEnv(env)
cmd.Stdout = &stdOut
cmd.Stderr = &stdErr
err := cmd.Start()
stdErr := &bytes.Buffer{}
cmd.Stderr = stdErr
// Create a go routine that will wait for the command to finish
done := make(chan error, 1)
go func() {
done <- cmd.Wait()
}()
out, err := cmd.Output()
select {
case <-time.After(timeout):
if err = cmd.Process.Kill(); err != nil {
return nil, fmt.Errorf("<%s, %v>: failed to kill: %s", pgm, args, err)
} else {
return nil, errors.New(fmt.Sprintf("<%s, %v>: timeout(%d msecs)", pgm, args, timeout/time.Millisecond))
}
case err = <-done:
if err != nil {
return nil, fmt.Errorf("<%s, %v>: failed with error: \"%s\"\n%s", pgm, args, err, string(stdErr.Bytes()))
}
if ctx.Err() == context.DeadlineExceeded {
err = fmt.Errorf("timed out after %s", timeout)
}
return stdOut.Bytes(), nil
if err != nil {
return nil,
fmt.Errorf(
"command <%s %s>: failed with error: \"%s\"\n%s",
pgm,
strings.Join(args, " "),
err,
string(stdErr.Bytes()))
}
return out, nil
}
// Logic inspired by: https://dave.cheney.net/2014/09/14/go-list-your-swiss-army-knife
......
......@@ -16,7 +16,12 @@ limitations under the License.
package golang
import "testing"
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func Test_listDeps(t *testing.T) {
_, err := listDeps(nil, "github.com/hyperledger/fabric/peer")
......@@ -24,3 +29,22 @@ func Test_listDeps(t *testing.T) {
t.Errorf("list failed: %s", err)
}
}
func Test_runProgram(t *testing.T) {
_, err := runProgram(
getEnv(),
10*time.Millisecond,
"go",
"build",
"github.com/hyperledger/fabric/peer",
)
assert.Contains(t, err.Error(), "timed out")
_, err = runProgram(
getEnv(),
1*time.Second,
"go",
"cmddoesnotexist",
)
assert.Contains(t, err.Error(), "unknown command")
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment