playground: make outcome of "Run" clearer
This CL changes the last line displayed after the program was run
to display more detail on what happened.
For more details see CL 141477.
Dockerfile in playground repo needs to be updated
to include x/tools with CL 141477.
Updates golang/go#10590
Updates golang/go#25454
Change-Id: I6bdef66e70d693540e4e7d30478ae9f0bf85d1ba
Reviewed-on: https://go-review.googlesource.com/c/141478
Reviewed-by: Andrew Bonventre <andybons@golang.org>
Run-TryBot: Andrew Bonventre <andybons@golang.org>
diff --git a/sandbox.go b/sandbox.go
index f63c360..9b80f78 100644
--- a/sandbox.go
+++ b/sandbox.go
@@ -28,6 +28,7 @@
"reflect"
"runtime"
"strings"
+ "syscall"
"text/template"
"time"
@@ -49,8 +50,11 @@
}
type response struct {
- Errors string
- Events []Event
+ Errors string
+ Events []Event
+ Status int
+ IsTest bool
+ TestsFailed int
}
// commandHandler returns an http.HandlerFunc.
@@ -276,6 +280,8 @@
}
`))
+var failedTestPattern = "--- FAIL"
+
// compileAndRun tries to build and run a user program.
// The output of successfully ran program is returned in *response.Events.
// If a program cannot be built or has timed out,
@@ -334,19 +340,36 @@
rec := new(Recorder)
cmd.Stdout = rec.Stdout()
cmd.Stderr = rec.Stderr()
+ var status int
if err := cmd.Run(); err != nil {
if ctx.Err() == context.DeadlineExceeded {
- return &response{Errors: "process took too long"}, nil
+ // Send what was captured before the timeout.
+ events, err := rec.Events()
+ if err != nil {
+ return nil, fmt.Errorf("error decoding events: %v", err)
+ }
+ return &response{Errors: "process took too long", Events: events}, nil
}
- if _, ok := err.(*exec.ExitError); !ok {
+ exitErr, ok := err.(*exec.ExitError)
+ if !ok {
return nil, fmt.Errorf("error running sandbox: %v", err)
}
+ if ws, ok := exitErr.Sys().(syscall.WaitStatus); ok {
+ status = ws.ExitStatus()
+ }
}
events, err := rec.Events()
if err != nil {
return nil, fmt.Errorf("error decoding events: %v", err)
}
- return &response{Events: events}, nil
+ var fails int
+ if testParam != "" {
+ // In case of testing the TestsFailed field contains how many tests have failed.
+ for _, e := range events {
+ fails += strings.Count(e.Message, failedTestPattern)
+ }
+ }
+ return &response{Events: events, Status: status, IsTest: testParam != "", TestsFailed: fails}, nil
}
func (s *server) healthCheck() error {