func compileAndRun()

in sandbox.go [332:379]


func compileAndRun(ctx context.Context, req *request) (*response, error) {
	// TODO(andybons): Add semaphore to limit number of running programs at once.
	tmpDir, err := ioutil.TempDir("", "sandbox")
	if err != nil {
		return nil, fmt.Errorf("error creating temp directory: %v", err)
	}
	defer os.RemoveAll(tmpDir)

	br, err := sandboxBuild(ctx, tmpDir, []byte(req.Body), req.WithVet)
	if err != nil {
		return nil, err
	}
	if br.errorMessage != "" {
		return &response{Errors: br.errorMessage}, nil
	}

	execRes, err := sandboxRun(ctx, br.exePath, br.testParam)
	if err != nil {
		return nil, err
	}
	if execRes.Error != "" {
		return &response{Errors: execRes.Error}, nil
	}

	rec := new(Recorder)
	rec.Stdout().Write(execRes.Stdout)
	rec.Stderr().Write(execRes.Stderr)
	events, err := rec.Events()
	if err != nil {
		log.Printf("error decoding events: %v", err)
		return nil, fmt.Errorf("error decoding events: %v", err)
	}
	var fails int
	if br.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:      execRes.ExitCode,
		IsTest:      br.testParam != "",
		TestsFailed: fails,
		VetErrors:   br.vetOut,
		VetOK:       req.WithVet && br.vetOut == "",
	}, nil
}