Пример #1
0
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
}
Пример #2
0
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)
}
Пример #3
0
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
}
Пример #4
0
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)
}
Пример #5
0
func readFromGCS(so model.StoredObject) (io.ReadCloser, error) {
	return util.Load(util.CloudContext(nil), so.Bucket, so.Name)
}