func processDiffResults(ctx context.Context, sub model.KeyedSubmission, tr model.DiffTestResult, bucket, testFile string, test *datastore.Key) (ts model.TestStats, err error) { var want io.ReadCloser want, err = util.Load(util.CloudContext(ctx), bucket, testFile) if err != nil { return } defer want.Close() have := strings.NewReader(tr.Stdout) diffLines, ok, err := compare(want, have) if err != nil { return } tr.DiffLines = diffLines tr.Failed = !ok ts = model.TestStats{ Stdout: tr.Stdout, Stderr: tr.Stderr, Test: test, Failed: !ok, } _, err = tr.PutWithParent(ctx, sub.Key) return }
func robot(ctx context.Context, t model.KeyedTest, sub model.KeyedSubmission, ball io.Reader) (err error) { log.Debugf(ctx, "Executing robot tester") var testMap io.ReadCloser if testMap, err = util.Load(util.CloudContext(ctx), util.TemplateBucket, t.Params["tests"]); err != nil { return } defer testMap.Close() var testMapBytes, stdinBytes []byte tr := tar.NewReader(ball) if _, err = tr.Next(); err != nil { return err } if stdinBytes, err = ioutil.ReadAll(tr); err != nil { return err } if testMapBytes, err = ioutil.ReadAll(testMap); err != nil { return } var m Map if err = json.Unmarshal(testMapBytes, &m); err != nil { return } moves, err := testRobot(m, string(stdinBytes)) if err != nil { // TODO(victorbalan): Pass the error to the ws so the client knows what he's doing wrong return } var body []byte if body, err = json.Marshal(moves); err != nil { return } return ws.Write(sub.Key.Parent(), body) }
func stream(ctx context.Context, file model.StoredObject) io.ReadCloser { pr, pw := io.Pipe() go func() { defer pw.Close() rc, err := util.Load(ctx, file.Bucket, file.Name) if err != nil { return } defer rc.Close() buf, err := ioutil.ReadAll(rc) if err != nil { return } w := tar.NewWriter(pw) defer w.Close() w.WriteHeader(&tar.Header{ Name: path.Base(file.Name), Mode: 0600, Size: int64(len(buf)), }) w.Write(buf) }() return pr }
func IODiffRun(ctx context.Context, t model.KeyedTest, sub model.KeyedSubmission, ball io.Reader) (ts model.TestStats, err error) { image := newImage(sub.Language) if err = prepareImage(image); err != nil { return } var c *docker.Container c, err = dc.CreateContainer(docker.CreateContainerOptions{ Config: &docker.Config{ Image: image, OpenStdin: true, StdinOnce: true, }, HostConfig: &docker.HostConfig{ Privileged: false, Memory: 0, // TODO(flowlo): Limit memory }, }) if err != nil { return } err = dc.UploadToContainer(c.ID, docker.UploadToContainerOptions{ Path: "/run", InputStream: ball, }) if err != nil { return } var stdin io.ReadCloser stdin, err = util.Load(util.CloudContext(ctx), util.TestsBucket, t.Params["input"]) if err != nil { return } defer stdin.Close() start := time.Now() if err = dc.StartContainer(c.ID, c.HostConfig); err != nil { return } err = dc.AttachToContainer(docker.AttachToContainerOptions{ Container: c.ID, InputStream: stdin, Stdin: true, Stream: true, }) if err != nil { return } if err = waitForContainer(c.ID); err != nil { return } end := time.Now() stdout, stderr := new(bytes.Buffer), new(bytes.Buffer) if stdout, stderr, err = getLogs(c.ID); err != nil { return } tr := model.DiffTestResult{ SimpleTestResult: model.SimpleTestResult{ Stdout: stdout.String(), Stderr: stderr.String(), Start: start, End: end, }, Endpoint: "diff-result", } return processDiffResults(ctx, sub, tr, util.TestsBucket, t.Params["output"], t.Key) }
func readFromGCS(so model.StoredObject) (io.ReadCloser, error) { return util.Load(util.CloudContext(nil), so.Bucket, so.Name) }