Commit c184b3f2 authored by Gari Singh's avatar Gari Singh
Browse files

Fix error processing for runProgram



runProgram was not returning the proper error
when the 60 sec timeout is reached.

FAB-12168 #done

Change-Id: Ie955c4f402fab942a5430c75f774feac13bbc975
Signed-off-by: default avatarGari Singh <gari.r.singh@gmail.com>
parent 7851d469
......@@ -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