Skip to content

Commit 5b57a0e

Browse files
d
1 parent 5578df7 commit 5b57a0e

File tree

8 files changed

+133
-17
lines changed

8 files changed

+133
-17
lines changed

backend/cmd/compile_user_code.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,11 @@ func CompileUserCode(ctx context.Context, gr types.GradeRequest, tmpDir string)
8080
}
8181

8282
defer func() {
83-
err := cli.ContainerRemove(ctxdl, resp.ID, dockertypes.ContainerRemoveOptions{
83+
err := cli.ContainerRemove(ctx, resp.ID, dockertypes.ContainerRemoveOptions{
8484
Force: true,
8585
})
8686
if err != nil {
8787
log.Panicln("cannot kill and remove container")
88-
panic(err)
8988
}
9089
}()
9190

backend/cmd/exec_user_code.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ import (
2020
const imageExec = "markhuang1212/code-grader/runtime-exec:latest"
2121

2222
type ExecUserCodeResult struct {
23-
Ok bool
24-
MemoryExceed bool
25-
TimeExceed bool
26-
Msg string
23+
Ok bool
24+
WrongAnswer bool
25+
MemoryExceed bool
26+
TimeExceed bool
27+
ExecutionError bool
28+
Duration time.Duration
29+
Msg string
2730
}
2831

2932
func ExecUserCode(ctx context.Context, gr types.GradeRequest, tmpDir string) (*ExecUserCodeResult, error) {
@@ -76,6 +79,7 @@ func ExecUserCode(ctx context.Context, gr types.GradeRequest, tmpDir string) (*E
7679
if err != nil {
7780
return nil, errors.Wrap(err, "cannot start container")
7881
}
82+
startTime := time.Now()
7983

8084
defer func() {
8185
err := cli.ContainerRemove(ctx, resp.ID, dockertypes.ContainerRemoveOptions{
@@ -88,12 +92,14 @@ func ExecUserCode(ctx context.Context, gr types.GradeRequest, tmpDir string) (*E
8892

8993
select {
9094
case status := <-statusCh:
95+
endTime := time.Now()
96+
result.Duration = endTime.Sub(startTime)
9197
switch status.StatusCode {
9298
case 0:
9399
result.Ok = true
94100
result.Msg = "correct answer"
95101
return result, nil
96-
case 1, 2:
102+
case 1:
97103
out, err := cli.ContainerLogs(ctxdl, resp.ID, dockertypes.ContainerLogsOptions{
98104
ShowStderr: true,
99105
ShowStdout: true,
@@ -103,6 +109,20 @@ func ExecUserCode(ctx context.Context, gr types.GradeRequest, tmpDir string) (*E
103109
}
104110
text, _ := io.ReadAll(out)
105111
result.Msg = string(text)
112+
result.WrongAnswer = true
113+
result.Ok = false
114+
return result, nil
115+
case 2:
116+
out, err := cli.ContainerLogs(ctxdl, resp.ID, dockertypes.ContainerLogsOptions{
117+
ShowStderr: true,
118+
ShowStdout: true,
119+
})
120+
if err != nil {
121+
return nil, errors.Wrap(err, "error reading stdout")
122+
}
123+
text, _ := io.ReadAll(out)
124+
result.Msg = string(text)
125+
result.ExecutionError = true
106126
result.Ok = false
107127
return result, nil
108128
case 3:

backend/cmd/exec_user_code_test.go

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"github.com/stretchr/testify/assert"
1212
)
1313

14-
func TestExecUserCode(t *testing.T) {
14+
func TestExecUserCode1(t *testing.T) {
1515

1616
ctx := context.Background()
1717

@@ -36,3 +36,57 @@ func TestExecUserCode(t *testing.T) {
3636
assert.True(t, er.Ok)
3737

3838
}
39+
40+
func TestExecUserCode2(t *testing.T) {
41+
42+
ctx := context.Background()
43+
44+
tmpDir, err := ioutil.TempDir("/tmp", "")
45+
assert.Nil(t, err)
46+
defer os.RemoveAll(tmpDir)
47+
48+
err = os.Chmod(tmpDir, 0777)
49+
assert.Nil(t, err)
50+
51+
gr := types.GradeRequest{
52+
TestCaseName: "example-1",
53+
UserCode: "int main() { return 10; }",
54+
}
55+
56+
cr, err := cmd.CompileUserCode(ctx, gr, tmpDir)
57+
assert.Nil(t, err)
58+
assert.True(t, cr.Ok)
59+
60+
er, err := cmd.ExecUserCode(ctx, gr, tmpDir)
61+
assert.Nil(t, err)
62+
assert.False(t, er.Ok)
63+
assert.True(t, er.ExecutionError)
64+
65+
}
66+
67+
func TestExecUserCode3(t *testing.T) {
68+
69+
ctx := context.Background()
70+
71+
tmpDir, err := ioutil.TempDir("/tmp", "")
72+
assert.Nil(t, err)
73+
defer os.RemoveAll(tmpDir)
74+
75+
err = os.Chmod(tmpDir, 0777)
76+
assert.Nil(t, err)
77+
78+
gr := types.GradeRequest{
79+
TestCaseName: "example-1",
80+
UserCode: "int main() { vector<int> data; while(1) { data.push_back(100); } }",
81+
}
82+
83+
cr, err := cmd.CompileUserCode(ctx, gr, tmpDir)
84+
assert.Nil(t, err)
85+
assert.True(t, cr.Ok)
86+
87+
er, err := cmd.ExecUserCode(ctx, gr, tmpDir)
88+
assert.Nil(t, err)
89+
assert.False(t, er.Ok)
90+
assert.True(t, er.MemoryExceed)
91+
92+
}

backend/cmd/grade_user_code.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,17 @@ func GradeUserCode(ctx context.Context, gr types.GradeRequest) (*types.GradeResu
3737
return nil, errors.Wrap(err, "cannot execute")
3838
}
3939

40+
result.Duration = er.Duration
4041
if !er.Ok {
4142
result.Msg = er.Msg
4243
if er.MemoryExceed {
4344
result.Status = types.GradeResultMemoryExceed
4445
} else if er.TimeExceed {
4546
result.Status = types.GradeResultTimeLimitExceed
46-
} else {
47+
} else if er.WrongAnswer {
4748
result.Status = types.GradeResultWrongAnswer
49+
} else {
50+
return nil, types.ErrInternal
4851
}
4952
return &result, nil
5053
}

backend/cmd/grade_user_code_test.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/stretchr/testify/assert"
1010
)
1111

12+
// success
1213
func TestGradeUserCode1(t *testing.T) {
1314
ctx := context.Background()
1415
gr := types.GradeRequest{
@@ -17,16 +18,41 @@ func TestGradeUserCode1(t *testing.T) {
1718
}
1819
result, err := cmd.GradeUserCode(ctx, gr)
1920
assert.Nil(t, err)
20-
assert.Equal(t, result.Status, types.GradeResultSuccess)
21+
assert.Equal(t, types.GradeResultSuccess, result.Status)
2122
}
2223

24+
// wrong answer
2325
func TestGradeUserCode2(t *testing.T) {
26+
ctx := context.Background()
27+
gr := types.GradeRequest{
28+
TestCaseName: "example-1",
29+
UserCode: "int main() { cout << \"Helloooo\" << endl; }",
30+
}
31+
result, err := cmd.GradeUserCode(ctx, gr)
32+
assert.Nil(t, err)
33+
assert.Equal(t, types.GradeResultWrongAnswer, result.Status)
34+
}
35+
36+
// time limit exceed
37+
func TestGradeUserCode3(t *testing.T) {
2438
ctx := context.Background()
2539
gr := types.GradeRequest{
2640
TestCaseName: "example-1",
2741
UserCode: "int main() { while (1) { } }",
2842
}
2943
result, err := cmd.GradeUserCode(ctx, gr)
3044
assert.Nil(t, err)
31-
assert.Equal(t, result.Status, types.GradeResultTimeLimitExceed)
45+
assert.Equal(t, types.GradeResultTimeLimitExceed, result.Status)
46+
}
47+
48+
// memory limit exceed
49+
func TestGradeUserCode4(t *testing.T) {
50+
ctx := context.Background()
51+
gr := types.GradeRequest{
52+
TestCaseName: "example-1",
53+
UserCode: "int main() { vector<int> data; while (1) { data.push_back(1024); } }",
54+
}
55+
result, err := cmd.GradeUserCode(ctx, gr)
56+
assert.Nil(t, err)
57+
assert.Equal(t, types.GradeResultMemoryExceed, result.Status)
3258
}

backend/types/GradeResult.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
package types
22

3+
import "time"
4+
35
type GradeResultStatus int
46

57
const (
68
GradeResultSuccess GradeResultStatus = iota
79
GradeResultWrongAnswer
10+
GradeResultExecutionError
811
GradeResultInternalError
912
GradeResultCompilationError
1013
GradeResultTimeLimitExceed
1114
GradeResultMemoryExceed
1215
)
1316

1417
type GradeResult struct {
15-
Status GradeResultStatus
16-
Msg string
18+
Status GradeResultStatus
19+
Duration time.Duration
20+
Msg string
1721
}

runtime-exec/run.sh

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,20 @@ then
1515
fi
1616

1717
${DATA_DIR}/a.out < ${TEST_CASE_DIR}/input.txt > ${DATA_DIR}/output.txt 2>&1
18+
STATUS=$?
1819

19-
if [[ $? -ne 0 ]]
20+
if [[ $STATUS -eq 137 ]]
2021
then
21-
cat output.txt
22+
exit 137
23+
fi
24+
25+
if [[ $STATUS -ne 0 ]]
26+
then
27+
echo "program exited with status $STATUS"
28+
if [[ -f output.txt ]];
29+
then
30+
cat output.txt
31+
fi
2232
exit 2
2333
fi
2434

testcases/example-1/testcase.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"RuntimeOptions": {
3-
"MemoryLimit": 512,
4-
"RuntimeLimit": 10
3+
"MemoryLimit": 64,
4+
"RuntimeLimit": 5
55
}
66
}

0 commit comments

Comments
 (0)