feat: support golang

This commit is contained in:
Paul Pan 2024-04-27 22:02:14 +08:00
parent 54e83ec63e
commit 0f026aa180
Signed by: Paul
GPG Key ID: D639BDF5BA578AF4
9 changed files with 97 additions and 38 deletions

View File

@ -53,7 +53,7 @@ func (s *service) Compile(meta *JudgeMeta) (*JudgeStatus, e.Status) {
}, },
Runtime: RuntimeArgs{ Runtime: RuntimeArgs{
Rootfs: RootfsFullDir, Rootfs: RootfsFullDir,
Pid: int64(meta.Cfg.Lang.Runtime.Compile.NProcLimit + 2), // bash + make Pid: int64(utils.If(meta.Cfg.Lang.Runtime.Compile.NProcLimit == 0, 0, meta.Cfg.Lang.Runtime.Compile.NProcLimit+2)), // bash + make
Memory: uint64(meta.Cfg.Lang.Runtime.Compile.MemoryLimit * 1024 * 1024), Memory: uint64(meta.Cfg.Lang.Runtime.Compile.MemoryLimit * 1024 * 1024),
Timeout: time.Duration((meta.Cfg.Lang.Runtime.Compile.TimeLimit+1000)/1000) * time.Second, Timeout: time.Duration((meta.Cfg.Lang.Runtime.Compile.TimeLimit+1000)/1000) * time.Second,
}, },

View File

@ -6,6 +6,7 @@ import (
"git.0x7f.app/WOJ/woj-server/pkg/down" "git.0x7f.app/WOJ/woj-server/pkg/down"
"git.0x7f.app/WOJ/woj-server/pkg/file" "git.0x7f.app/WOJ/woj-server/pkg/file"
"git.0x7f.app/WOJ/woj-server/pkg/unzip" "git.0x7f.app/WOJ/woj-server/pkg/unzip"
"git.0x7f.app/WOJ/woj-server/pkg/utils"
"go.uber.org/zap" "go.uber.org/zap"
"os" "os"
"path/filepath" "path/filepath"
@ -58,7 +59,7 @@ func (s *service) PrebuildProblem(meta *JudgeMeta, config *Config, force bool) e
}, },
Runtime: RuntimeArgs{ Runtime: RuntimeArgs{
Rootfs: RootfsFullDir, Rootfs: RootfsFullDir,
Pid: int64(config.Prebuild.NProcLimit + 3), // sh + bash + make Pid: int64(utils.If(config.Prebuild.NProcLimit == 0, 0, config.Prebuild.NProcLimit+3)), // sh + bash + make
Memory: uint64(config.Prebuild.MemoryLimit * 1024 * 1024), Memory: uint64(config.Prebuild.MemoryLimit * 1024 * 1024),
Timeout: time.Duration((config.Prebuild.TimeLimit+1000)/1000) * time.Second, Timeout: time.Duration((config.Prebuild.TimeLimit+1000)/1000) * time.Second,
}, },

View File

@ -15,15 +15,17 @@ var (
}{ }{
"c": {""}, "c": {""},
"cpp": {""}, "cpp": {""},
"rust": {""}, "go": {""},
"python3": {"/usr/bin/python3"}, "python3": {"/usr/bin/python3"},
"pypy3": {"/usr/bin/pypy3"}, "pypy3": {"/usr/bin/pypy3"},
"rust": {""},
} }
) )
type ConfigRuntime struct { type ConfigRuntime struct {
TimeLimit int `json:"TimeLimit"` // in ms TimeLimit int `json:"TimeLimit"` // in ms
MemoryLimit int `json:"MemoryLimit"` // in mb MemoryLimit int `json:"MemoryLimit"` // in mb
SoftMemoryLimit int `json:"SoftMemoryLimit"` // in mb
NProcLimit int `json:"NProcLimit"` NProcLimit int `json:"NProcLimit"`
WriteFileLimit int `json:"WriteFileLimit"` // in mb WriteFileLimit int `json:"WriteFileLimit"` // in mb
} }
@ -32,18 +34,21 @@ var (
DefaultPrebuildRuntime = ConfigRuntime{ DefaultPrebuildRuntime = ConfigRuntime{
TimeLimit: 300000, TimeLimit: 300000,
MemoryLimit: 256, MemoryLimit: 256,
SoftMemoryLimit: 256,
NProcLimit: 64, NProcLimit: 64,
WriteFileLimit: 1, WriteFileLimit: 1024,
} }
DefaultCompileRuntime = ConfigRuntime{ DefaultCompileRuntime = ConfigRuntime{
TimeLimit: 60000, TimeLimit: 60000,
MemoryLimit: 256, MemoryLimit: 256,
SoftMemoryLimit: 256,
NProcLimit: 64, NProcLimit: 64,
WriteFileLimit: 64, WriteFileLimit: 64,
} }
DefaultCheckRuntime = ConfigRuntime{ DefaultCheckRuntime = ConfigRuntime{
TimeLimit: 60000, TimeLimit: 60000,
MemoryLimit: 128, MemoryLimit: 128,
SoftMemoryLimit: 128,
NProcLimit: 64, NProcLimit: 64,
WriteFileLimit: 16, WriteFileLimit: 16,
} }
@ -56,11 +61,16 @@ func (c *ConfigRuntime) Validate() error {
if c.MemoryLimit <= 0 { if c.MemoryLimit <= 0 {
return errors.New("memory limit <= 0") return errors.New("memory limit <= 0")
} }
if c.SoftMemoryLimit <= 0 {
// default to memory limit
c.SoftMemoryLimit = c.MemoryLimit
}
if c.NProcLimit <= 0 { if c.NProcLimit <= 0 {
return errors.New("nproc limit <= 0") c.NProcLimit = 0
} }
if c.WriteFileLimit <= 0 { if c.WriteFileLimit <= 0 {
return errors.New("write file limit <= 0") // default to 1mb
c.WriteFileLimit = 1
} }
return nil return nil
} }

View File

@ -22,7 +22,7 @@ type ProblemRunResults map[int]*ProblemRunResult
func (s *service) SandboxArgsBuilder(meta *JudgeMeta, id int) string { func (s *service) SandboxArgsBuilder(meta *JudgeMeta, id int) string {
var args []string var args []string
args = append(args, fmt.Sprintf("--memory_limit=%d", meta.Cfg.Lang.Runtime.Run.MemoryLimit)) args = append(args, fmt.Sprintf("--memory_limit=%d", meta.Cfg.Lang.Runtime.Run.SoftMemoryLimit))
args = append(args, fmt.Sprintf("--nproc_limit=%d", meta.Cfg.Lang.Runtime.Run.NProcLimit)) args = append(args, fmt.Sprintf("--nproc_limit=%d", meta.Cfg.Lang.Runtime.Run.NProcLimit))
args = append(args, fmt.Sprintf("--time_limit=%d", meta.Cfg.Lang.Runtime.Run.TimeLimit)) args = append(args, fmt.Sprintf("--time_limit=%d", meta.Cfg.Lang.Runtime.Run.TimeLimit))
args = append(args, fmt.Sprintf("--fsize_limit=%d", meta.Cfg.Lang.Runtime.Run.WriteFileLimit)) args = append(args, fmt.Sprintf("--fsize_limit=%d", meta.Cfg.Lang.Runtime.Run.WriteFileLimit))
@ -55,8 +55,9 @@ func (s *service) ProblemRun(meta *JudgeMeta) ProblemRunResults {
runtimeArgs := RuntimeArgs{ runtimeArgs := RuntimeArgs{
Rootfs: RootfsRunDir, Rootfs: RootfsRunDir,
// sh, woj_launcher:program, woj_launcher:killer, woj_launcher:stat // sh, woj_launcher:program, woj_launcher:killer, woj_launcher:stat
Pid: int64(meta.Cfg.Lang.Runtime.Run.NProcLimit + 4), Pid: int64(utils.If(meta.Cfg.Lang.Runtime.Run.NProcLimit == 0, 0, meta.Cfg.Lang.Runtime.Run.NProcLimit+4)),
Memory: uint64(meta.Cfg.Lang.Runtime.Run.MemoryLimit * 1024 * 1024), // use SoftMemoryLimit when run, judge with MemoryLimit
Memory: uint64(meta.Cfg.Lang.Runtime.Run.SoftMemoryLimit * 1024 * 1024),
// woj-sandbox killer will add 1 more second, here we add 1 also // woj-sandbox killer will add 1 more second, here we add 1 also
Timeout: time.Duration((meta.Cfg.Lang.Runtime.Run.TimeLimit+1000)/1000+1+1) * time.Second, Timeout: time.Duration((meta.Cfg.Lang.Runtime.Run.TimeLimit+1000)/1000+1+1) * time.Second,
} }

View File

@ -1,7 +1,7 @@
include ${TEMPLATE}/go.mk ${TEMPLATE}/Judger.mk include ${TEMPLATE}/go.mk ${TEMPLATE}/Judger.mk
compile: compile:
@$(GO) build $(GO_BUILD_FLAGS) -o $(PREFIX)/user/$(USER_PROG).out $(PREFIX)/user/$(USER_PROG).$(LANG) @env GOCACHE=$(GOCACHE) $(GO) build $(GO_BUILD_FLAGS) -o $(PREFIX)/user/$(USER_PROG).out $(PREFIX)/user/$(USER_PROG).$(LANG)
judge: judge:
$($(CMP)) $(PREFIX)/problem/data/input/$(TEST_NUM).input $(PREFIX)/user/$(TEST_NUM).out.usr $(PREFIX)/problem/data/output/$(TEST_NUM).output $(PREFIX)/user/$(TEST_NUM).judge -appes $($(CMP)) $(PREFIX)/problem/data/input/$(TEST_NUM).input $(PREFIX)/user/$(TEST_NUM).out.usr $(PREFIX)/problem/data/output/$(TEST_NUM).output $(PREFIX)/user/$(TEST_NUM).judge -appes

View File

@ -1,2 +1,3 @@
GO=/usr/bin/go GO=/usr/bin/go
GO_BUILD_FLAGS=-trimpath GO_BUILD_FLAGS=-trimpath
GOCACHE=/tmp/go-build

View File

@ -34,12 +34,28 @@
"Judge" : {"Type": "custom", "Script": "custom.Makefile", "Cmp": ""}, "Judge" : {"Type": "custom", "Script": "custom.Makefile", "Cmp": ""},
// 运行时配置:时间(ms) 内存(MB) 进/线程数目 // 运行时配置:时间(ms) 内存(MB) 进/线程数目
"Runtime": { "Runtime": {
// 编译阶段,可选,默认值见下 // 编译阶段,可选,若缺失整个字段则替换为如下默认值
"Compile": {"TimeLimit": 60000, "MemoryLimit": 256, "NProcLimit": 64}, "Compile": {
"TimeLimit" : 60000,
"MemoryLimit" : 256,
// NProcLimit 为可选字段,不填默认为 0
"NProcLimit" : 64,
// WriteFileLimit 为可选字段,不填默认为 1
"WriteFileLimit": 64
},
// 运行阶段,必选 // 运行阶段,必选
"Run" : {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}, "Run" : {
// 答案检查阶段,可选,默认值见下 "TimeLimit" : 1000,
"Check" : {"TimeLimit": 60000, "MemoryLimit": 128, "NProcLimit": 64} "MemoryLimit" : 16,
// SoftMemoryLimit 为可选字段,不填默认为 MemoryLimit
// SoftMemoryLimit 仅适用于运行时沙箱设置,实际判断内存超标时使用 MemoryLimit
"SoftMemoryLimit": 16,
"NProcLimit" : 1,
// WriteFileLimit 为可选字段,不填默认为 1
"WriteFileLimit" : 1
},
// 答案检查阶段,可选,规则与 Compile 相同
"Check" : {"TimeLimit": 60000, "MemoryLimit": 128, "NProcLimit": 64, "WriteFileLimit": 16}
} }
}, },
{ {
@ -73,10 +89,18 @@
"Runtime": { "Runtime": {
"Run": {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1} "Run": {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}
} }
},
{
"Lang" : "go",
"Judge" : {"Type": "default", "Script": "", "Cmp": "NCMP"},
"Runtime": {
// Go 运行时会申请大量内存与线程
"Run": {"TimeLimit": 1000, "MemoryLimit": 16, "SoftMemoryLimit": 1024, "NProcLimit": 0}
}
} }
], ],
// 题目构建阶段,用于生成测试数据等,可选,默认值见下 // 题目构建阶段,用于生成测试数据等,可选,规则与 Compile 相同
"Prebuild" : {"TimeLimit": 300000, "MemoryLimit": 256, "NProcLimit": 64}, "Prebuild" : {"TimeLimit": 300000, "MemoryLimit": 256, "NProcLimit": 64, "WriteFileLimit": 1024},
// 评测点信息,总分应当为 100 分 // 评测点信息,总分应当为 100 分
"Tasks" : [ "Tasks" : [
// 第一个评测点,分值 10 分,使用 ./data/{input,output}/1.{input,output} 为测试数据 // 第一个评测点,分值 10 分,使用 ./data/{input,output}/1.{input,output} 为测试数据

View File

@ -4,9 +4,15 @@
"Lang" : "c", "Lang" : "c",
"Judge" : {"Type": "custom", "Script": "custom.Makefile", "Cmp": ""}, "Judge" : {"Type": "custom", "Script": "custom.Makefile", "Cmp": ""},
"Runtime": { "Runtime": {
"Compile": {"TimeLimit": 60000, "MemoryLimit": 256, "NProcLimit": 64}, "Compile": {"TimeLimit": 60000, "MemoryLimit": 256, "NProcLimit": 64, "WriteFileLimit": 64},
"Run" : {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}, "Run" : {
"Check" : {"TimeLimit": 60000, "MemoryLimit": 128, "NProcLimit": 64} "TimeLimit" : 1000,
"MemoryLimit" : 16,
"SoftMemoryLimit": 16,
"NProcLimit" : 1,
"WriteFileLimit" : 1
},
"Check" : {"TimeLimit": 60000, "MemoryLimit": 128, "NProcLimit": 64, "WriteFileLimit": 16}
} }
}, },
{ {
@ -27,7 +33,7 @@
"Lang" : "pypy3", "Lang" : "pypy3",
"Judge" : {"Type": "default", "Script": "", "Cmp": "NCMP"}, "Judge" : {"Type": "default", "Script": "", "Cmp": "NCMP"},
"Runtime": { "Runtime": {
"Run": {"TimeLimit": 1000, "MemoryLimit": 70, "NProcLimit": 1} "Run": {"TimeLimit": 1000, "MemoryLimit": 80, "NProcLimit": 1}
} }
}, },
{ {
@ -36,9 +42,16 @@
"Runtime": { "Runtime": {
"Run": {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1} "Run": {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}
} }
},
{
"Lang" : "go",
"Judge" : {"Type": "default", "Script": "", "Cmp": "NCMP"},
"Runtime": {
"Run": {"TimeLimit": 1000, "MemoryLimit": 16, "SoftMemoryLimit": 1024, "NProcLimit": 0}
}
} }
], ],
"Prebuild" : {"TimeLimit": 300000, "MemoryLimit": 256, "NProcLimit": 64}, "Prebuild" : {"TimeLimit": 300000, "MemoryLimit": 256, "NProcLimit": 64, "WriteFileLimit": 1024},
"Tasks" : [ "Tasks" : [
{"Id": 1, "Points": 10}, {"Id": 1, "Points": 10},
{"Id": 2, "Points": 20}, {"Id": 2, "Points": 20},

View File

@ -0,0 +1,9 @@
package main
import "fmt"
func main() {
a, b := 0, 0
_, _ = fmt.Scan(&a, &b)
fmt.Println(a + b)
}