feat: unify argument passing and errors in runner

This commit is contained in:
Paul Pan 2024-01-29 21:15:39 +08:00
parent 81b42f782e
commit bb53ae280f
Signed by: Paul
GPG Key ID: D639BDF5BA578AF4
9 changed files with 152 additions and 129 deletions

View File

@ -19,7 +19,7 @@ func (h *handler) Build(_ context.Context, t *asynq.Task) error {
}
h.log.Debug("build", zap.Any("payload", p))
meta := runner.JudgeMeta{Version: p.ProblemVersionID}
meta := runner.JudgeMeta{Run: runner.JudgeMetaRun{Version: p.ProblemVersionID}}
status, ctx := func() (e.Status, string) {
url, status := h.storageService.Get(p.StorageKey, time.Second*60*5)

View File

@ -15,6 +15,14 @@ import (
"time"
)
var (
statusSystemError = runner.JudgeStatus{
Message: "System Error",
CompileMessage: "",
Tasks: []runner.TaskStatus{{Verdict: runner.VerdictSystemError, Message: "System Error"}},
}
)
func (h *handler) Judge(_ context.Context, t *asynq.Task) error {
var p model.SubmitJudgePayload
if err := json.Unmarshal(t.Payload(), &p); err != nil {
@ -23,45 +31,59 @@ func (h *handler) Judge(_ context.Context, t *asynq.Task) error {
user := utils.RandomString(16)
h.log.Debug("judge", zap.Any("payload", p), zap.String("user", user))
meta := runner.JudgeMeta{Version: p.ProblemVersionID, User: user, Lang: p.Submission.Language}
SystemError := &runner.JudgeStatus{
Message: "System Error",
Tasks: []runner.TaskStatus{{Verdict: runner.VerdictSystemError, Message: "API Error"}},
meta := runner.JudgeMeta{
Run: runner.JudgeMetaRun{
Version: p.ProblemVersionID,
User: user,
Lang: p.Submission.Language,
},
}
status, point, ctx := func() (e.Status, int32, *runner.JudgeStatus) {
// 1. write user code
userCode := filepath.Join(runner.UserDir, user, fmt.Sprintf("%s.%s", user, p.Submission.Language))
if !file.Touch(userCode) {
return e.InternalError, 0, SystemError
return e.InternalError, 0, &statusSystemError
}
err := file.Write(userCode, []byte(p.Submission.Code))
if err != nil {
return e.InternalError, 0, SystemError
return e.InternalError, 0, &statusSystemError
}
// 2. check problem
if !h.runnerService.ProblemExists(&meta) {
url, status := h.storageService.Get(p.StorageKey, time.Second*60*5)
if status != e.Success {
return status, 0, SystemError
return status, 0, &statusSystemError
}
_, status = h.runnerService.NewProblem(&meta, url, false)
if status != e.Success {
return status, 0, SystemError
return status, 0, &statusSystemError
}
}
// 3. compile
// 3. validate
if ret, status := h.runnerService.ValidatePath(&meta); status != e.Success {
return status, 0, ret
}
// 4. extract config
if status := h.runnerService.GetConfig(&meta, true); status != e.Success {
return e.RunnerProblemParseFailed, 0, &runner.JudgeStatus{
Message: fmt.Sprintf("System Error: Problem Malformed (%d:%s)", status, status.String()),
CompileMessage: "",
Tasks: []runner.TaskStatus{{Verdict: runner.VerdictSystemError, Message: "System Error"}},
}
}
// 5. compile
compileResult, status := h.runnerService.Compile(&meta)
if status != e.Success {
return status, 0, compileResult
}
// 4. run and judge
// 6. run and judge
result, point, status := h.runnerService.RunAndJudge(&meta)
return status, point, result
}()

View File

@ -22,10 +22,20 @@ const (
ContainerImageRun = "git.0x7f.app/woj/ubuntu-run:latest"
)
type JudgeMetaRun struct {
Version uint // problem version id
User string // user id
Lang string // language
}
type JudgeMetaConfig struct {
All *Config
Lang *ConfigLanguage
}
type JudgeMeta struct {
Version uint
User string
Lang string
Run JudgeMetaRun
Cfg JudgeMetaConfig
}
func init() {
@ -41,33 +51,47 @@ func init() {
}
func (s *service) ProblemExists(meta *JudgeMeta) bool {
problemPath := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version))
problemPath := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version))
return file.Exist(problemPath)
}
func (s *service) ValidatePath(meta *JudgeMeta) e.Status {
func (s *service) ValidatePath(meta *JudgeMeta) (*JudgeStatus, e.Status) {
gen := func(status e.Status) (*JudgeStatus, e.Status) {
return &JudgeStatus{
Message: fmt.Sprintf("System Error: Problem/User Files Not Found (%d:%s)", status, status.String()),
CompileMessage: "",
Tasks: []TaskStatus{{Verdict: VerdictSystemError, Message: "System Error"}},
}, status
}
if !s.ProblemExists(meta) {
s.log.Info("problem not exists", zap.Uint("version", meta.Version))
return e.RunnerProblemNotExist
s.log.Error("problem not exists", zap.Uint("version", meta.Run.Version))
return gen(e.RunnerProblemNotExist)
}
userPath := filepath.Join(UserDir, meta.User, fmt.Sprintf("%s.%s", meta.User, meta.Lang))
userPath := filepath.Join(UserDir, meta.Run.User, fmt.Sprintf("%s.%s", meta.Run.User, meta.Run.Lang))
if !file.Exist(userPath) {
s.log.Info("user program not exists", zap.String("user", meta.User), zap.String("lang", meta.Lang))
return e.RunnerUserNotExist
s.log.Error("user program not exists", zap.String("user", meta.Run.User), zap.String("lang", meta.Run.Lang))
return gen(e.RunnerUserNotExist)
}
return e.Success
return nil, e.Success
}
func (s *service) GetConfig(meta *JudgeMeta, skipCheck bool) (*Config, *ConfigLanguage, e.Status) {
func (s *service) GetConfig(meta *JudgeMeta, skipCheck bool) e.Status {
config, err := s.ParseConfig(meta, skipCheck)
if err != nil {
return nil, nil, e.RunnerProblemParseFailed
return e.RunnerProblemParseFailed
}
cLang, ok := config.FilterLanguage(meta.Lang)
lang, ok := config.FilterLanguage(meta.Run.Lang)
if !ok {
return nil, nil, e.RunnerLanguageNotSupported
return e.RunnerLanguageNotSupported
}
return config, cLang, e.Success
meta.Cfg = JudgeMetaConfig{
All: config,
Lang: lang,
}
return e.Success
}

View File

@ -14,62 +14,44 @@ import (
)
func (s *service) Compile(meta *JudgeMeta) (*JudgeStatus, e.Status) {
// 1. ensure problem/user exists
status := s.ValidatePath(meta)
if status != e.Success {
return &JudgeStatus{Message: "check failed"}, status
}
// 1. prepare judge environment
workDir := filepath.Join(UserDir, meta.Run.User)
judgeDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version), "judge")
config, cLang, status := s.GetConfig(meta, true)
if status != e.Success {
s.log.Error("[compile] parse config failed", zap.Any("meta", *meta))
return &JudgeStatus{
Message: "parse config failed",
Tasks: []TaskStatus{{Verdict: VerdictSystemError, Message: "parse config failed"}},
}, e.RunnerProblemParseFailed
}
sourceFile := filepath.Join(workDir, fmt.Sprintf("%s.%s", meta.Run.User, meta.Run.Lang))
targetFile := filepath.Join(workDir, fmt.Sprintf("%s.out", meta.Run.User))
// 2. prepare judge environment
workDir := filepath.Join(UserDir, meta.User)
judgeDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), "judge")
sourceFile := filepath.Join(workDir, fmt.Sprintf("%s.%s", meta.User, meta.Lang))
targetFile := filepath.Join(workDir, fmt.Sprintf("%s.out", meta.User))
logFile := filepath.Join(workDir, fmt.Sprintf("%s.compile.log", meta.User))
logFile := filepath.Join(workDir, fmt.Sprintf("%s.compile.log", meta.Run.User))
log, err := os.Create(logFile)
if err != nil {
s.log.Error("[compile] create log file failed", zap.Error(err))
return &JudgeStatus{
Message: "create log file failed",
Tasks: []TaskStatus{{Verdict: VerdictSystemError, Message: "create log file failed"}},
Message: "System Error: Unable to create log file",
CompileMessage: "",
Tasks: []TaskStatus{{Verdict: VerdictSystemError, Message: "System Error"}},
}, e.RunnerUserCompileFailed
}
defer func(log *os.File) {
_ = log.Close()
}(log)
// 3. compile
// 2. compile
err = utils.NewMust().
DoAny(func() error { return os.Remove(targetFile) }).
Do(func() error { return file.TouchErr(targetFile) }).
Do(func() error {
l, ok := config.FilterLanguage(meta.Lang)
if !ok {
return e.RunnerProblemParseFailed.AsError()
}
script := l.JudgeScript()
script := meta.Cfg.Lang.JudgeScript()
args := &RunArgs{
Program: ProgramArgs{
Args: []string{"sh", "-c", fmt.Sprintf("cd /woj/user && make -f %s compile", script)},
Env: []string{fmt.Sprintf("USER_PROG=%s", meta.User), fmt.Sprintf("LANG=%s", meta.Lang)},
Env: []string{fmt.Sprintf("USER_PROG=%s", meta.Run.User), fmt.Sprintf("LANG=%s", meta.Run.Lang)},
},
Runtime: RuntimeArgs{
Image: ContainerImageFull,
Pid: int64(cLang.Runtime.Compile.NProcLimit + 2), // bash + make
Memory: uint64(cLang.Runtime.Compile.MemoryLimit * 1024 * 1024),
Timeout: time.Duration((cLang.Runtime.Compile.TimeLimit+1000)/1000) * time.Second,
Pid: int64(meta.Cfg.Lang.Runtime.Compile.NProcLimit + 2), // bash + make
Memory: uint64(meta.Cfg.Lang.Runtime.Compile.MemoryLimit * 1024 * 1024),
Timeout: time.Duration((meta.Cfg.Lang.Runtime.Compile.TimeLimit+1000)/1000) * time.Second,
},
IO: IOArgs{
Output: log,
@ -85,13 +67,13 @@ func (s *service) Compile(meta *JudgeMeta) (*JudgeStatus, e.Status) {
},
{
Source: sourceFile,
Destination: fmt.Sprintf("/woj/user/%s.%s", meta.User, meta.Lang),
Destination: fmt.Sprintf("/woj/user/%s.%s", meta.Run.User, meta.Run.Lang),
Type: "bind",
Options: []string{"rbind", "ro"},
},
{
Source: targetFile,
Destination: fmt.Sprintf("/woj/user/%s.out", meta.User),
Destination: fmt.Sprintf("/woj/user/%s.out", meta.Run.User),
Type: "bind",
Options: []string{"rbind"},
},
@ -102,6 +84,7 @@ func (s *service) Compile(meta *JudgeMeta) (*JudgeStatus, e.Status) {
}).
Done()
status := e.Success
if err != nil {
s.log.Info("[compile] compile failed", zap.Error(err), zap.Any("meta", *meta))
status = e.RunnerUserCompileFailed
@ -115,8 +98,9 @@ func (s *service) Compile(meta *JudgeMeta) (*JudgeStatus, e.Status) {
if !file.Exist(targetFile) || file.Empty(targetFile) {
return &JudgeStatus{
Message: "compile failed",
Tasks: []TaskStatus{{Verdict: VerdictCompileError, Message: msgText}}},
Message: "Compile Failed",
CompileMessage: msgText,
Tasks: []TaskStatus{{Verdict: VerdictCompileError, Message: msgText}}},
utils.If(status == e.Success, e.RunnerUserCompileFailed, status)
}

View File

@ -181,7 +181,7 @@ func (c *Config) FilterLanguage(lang string) (*ConfigLanguage, bool) {
}
func (s *service) ParseConfig(meta *JudgeMeta, skipCheck bool) (*Config, error) {
base := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version))
base := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version))
file := filepath.Join(base, "config.json")
data, err := os.ReadFile(file)

View File

@ -14,8 +14,8 @@ import (
)
func (s *service) DownloadProblem(meta *JudgeMeta, url string) e.Status {
zipPath := filepath.Join(TmpDir, fmt.Sprintf("%d.zip", meta.Version))
problemPath := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version))
zipPath := filepath.Join(TmpDir, fmt.Sprintf("%d.zip", meta.Run.Version))
problemPath := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version))
err := down.Down(zipPath, url)
if err != nil {
@ -37,21 +37,21 @@ func (s *service) PrebuildProblem(meta *JudgeMeta, config *Config, force bool) e
return e.RunnerProblemNotExist
}
mark := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), ".mark.prebuild")
mark := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version), ".mark.prebuild")
if force {
_ = os.Remove(mark)
} else if file.Exist(mark) {
return e.Success
}
prebuildScript := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), "judge", "prebuild.Makefile")
prebuildScript := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version), "judge", "prebuild.Makefile")
if !file.Exist(prebuildScript) {
s.log.Info("[new] prebuild script not found", zap.String("path", prebuildScript), zap.Uint("version", meta.Version))
s.log.Info("[new] prebuild script not found", zap.String("path", prebuildScript), zap.Uint("version", meta.Run.Version))
return e.Success
}
dataDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), "data")
judgeDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), "judge")
dataDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version), "data")
judgeDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version), "judge")
args := &RunArgs{
Program: ProgramArgs{
@ -83,7 +83,7 @@ func (s *service) PrebuildProblem(meta *JudgeMeta, config *Config, force bool) e
err := s.pool.WaitForTask(id)
if err != nil {
s.log.Warn("[new] prebuild problem failed", zap.Error(err), zap.Uint("version", meta.Version))
s.log.Warn("[new] prebuild problem failed", zap.Error(err), zap.Uint("version", meta.Run.Version))
return e.RunnerProblemPrebuildFailed
}
@ -92,7 +92,7 @@ func (s *service) PrebuildProblem(meta *JudgeMeta, config *Config, force bool) e
func (s *service) NewProblem(meta *JudgeMeta, url string, force bool) (*Config, e.Status) {
if force {
problemPath := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version))
problemPath := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version))
_ = os.RemoveAll(problemPath)
}
@ -105,7 +105,7 @@ func (s *service) NewProblem(meta *JudgeMeta, url string, force bool) (*Config,
cfg, err := s.ParseConfig(meta, false)
if err != nil {
s.log.Info("[new] parse problem failed", zap.Error(err), zap.Uint("version", meta.Version))
s.log.Info("[new] parse problem failed", zap.Error(err), zap.Uint("version", meta.Run.Version))
return &Config{}, e.RunnerProblemParseFailed
}

View File

@ -13,43 +13,43 @@ import (
"time"
)
func (s *service) SandboxArgsBuilder(meta *JudgeMeta, cLang *ConfigLanguage, id int) string {
func (s *service) SandboxArgsBuilder(meta *JudgeMeta, id int) string {
var args []string
args = append(args, fmt.Sprintf("--memory_limit=%d", cLang.Runtime.Run.MemoryLimit))
args = append(args, fmt.Sprintf("--nproc_limit=%d", cLang.Runtime.Run.NProcLimit))
args = append(args, fmt.Sprintf("--time_limit=%d", cLang.Runtime.Run.TimeLimit))
args = append(args, fmt.Sprintf("--sandbox_template=%s", cLang.Lang))
args = append(args, fmt.Sprintf("--memory_limit=%d", meta.Cfg.Lang.Runtime.Run.MemoryLimit))
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("--sandbox_template=%s", meta.Cfg.Lang.Lang))
args = append(args, fmt.Sprintf("--sandbox_action=ret"))
args = append(args, fmt.Sprintf("--uid=1000"))
args = append(args, fmt.Sprintf("--gid=1000"))
args = append(args, fmt.Sprintf("--file_input=/woj/problem/data/input/%d.input", id))
args = append(args, fmt.Sprintf("--file_output=/woj/user/%d.out.usr", id))
args = append(args, fmt.Sprintf("--file_info=/woj/user/%d.info", id))
args = append(args, fmt.Sprintf("--program=/woj/user/%s.out", meta.User))
args = append(args, fmt.Sprintf("--program=/woj/user/%s.out", meta.Run.User))
return strings.Join(args, " ")
}
func (s *service) ProblemRun(meta *JudgeMeta, config *Config, cLang *ConfigLanguage) {
workDir := filepath.Join(UserDir, meta.User)
dataDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), "data", "input")
func (s *service) ProblemRun(meta *JudgeMeta) {
workDir := filepath.Join(UserDir, meta.Run.User)
dataDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version), "data", "input")
runtimeArgs := RuntimeArgs{
Image: ContainerImageRun,
// sh, woj_launcher:program, woj_launcher:killer, woj_launcher:stat
Pid: int64(cLang.Runtime.Run.NProcLimit + 4),
Memory: uint64(cLang.Runtime.Run.MemoryLimit * 1024 * 1024),
Pid: int64(meta.Cfg.Lang.Runtime.Run.NProcLimit + 4),
Memory: uint64(meta.Cfg.Lang.Runtime.Run.MemoryLimit * 1024 * 1024),
// woj-sandbox killer will add 1 more second, here we add 1 also
Timeout: time.Duration((cLang.Runtime.Run.TimeLimit+1000)/1000+1+1) * time.Second,
Timeout: time.Duration((meta.Cfg.Lang.Runtime.Run.TimeLimit+1000)/1000+1+1) * time.Second,
}
ids := make([]int, 0)
for _, task := range config.Tasks {
for _, task := range meta.Cfg.All.Tasks {
f := func(id int) func() error {
return func() error {
testCase := filepath.Join(dataDir, fmt.Sprintf("%d.input", id))
targetFile := filepath.Join(workDir, fmt.Sprintf("%s.out", meta.User))
targetFile := filepath.Join(workDir, fmt.Sprintf("%s.out", meta.Run.User))
ansFile := filepath.Join(workDir, fmt.Sprintf("%d.out.usr", id))
ifoFile := filepath.Join(workDir, fmt.Sprintf("%d.info", id))
@ -58,7 +58,7 @@ func (s *service) ProblemRun(meta *JudgeMeta, config *Config, cLang *ConfigLangu
Args: []string{
"sh", "-c",
"cd /woj/user && /woj/framework/scripts/woj_launcher " +
s.SandboxArgsBuilder(meta, cLang, id),
s.SandboxArgsBuilder(meta, id),
},
},
Runtime: runtimeArgs,
@ -72,7 +72,7 @@ func (s *service) ProblemRun(meta *JudgeMeta, config *Config, cLang *ConfigLangu
},
{
Source: targetFile,
Destination: fmt.Sprintf("/woj/user/%s.out", meta.User),
Destination: fmt.Sprintf("/woj/user/%s.out", meta.Run.User),
Type: "bind",
Options: []string{"rbind", "ro"},
},
@ -114,21 +114,21 @@ func (s *service) ProblemRun(meta *JudgeMeta, config *Config, cLang *ConfigLangu
}
}
func (s *service) ProblemJudge(meta *JudgeMeta, config *Config, cLang *ConfigLanguage) {
workDir := filepath.Join(UserDir, meta.User)
dataDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), "data")
judgeDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), "judge")
script := cLang.JudgeScript()
func (s *service) ProblemJudge(meta *JudgeMeta) {
workDir := filepath.Join(UserDir, meta.Run.User)
dataDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version), "data")
judgeDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version), "judge")
script := meta.Cfg.Lang.JudgeScript()
runtimeArgs := RuntimeArgs{
Image: ContainerImageFull,
Pid: int64(cLang.Runtime.Check.NProcLimit + 2), // bash + make
Memory: uint64(cLang.Runtime.Check.MemoryLimit * 1024 * 1024),
Timeout: time.Duration((cLang.Runtime.Check.TimeLimit+1000)/1000) * time.Second,
Pid: int64(meta.Cfg.Lang.Runtime.Check.NProcLimit + 2), // bash + make
Memory: uint64(meta.Cfg.Lang.Runtime.Check.MemoryLimit * 1024 * 1024),
Timeout: time.Duration((meta.Cfg.Lang.Runtime.Check.TimeLimit+1000)/1000) * time.Second,
}
ids := make([]int, 0)
for _, task := range config.Tasks {
for _, task := range meta.Cfg.All.Tasks {
f := func(id int) func() error {
return func() error {
ansFile := filepath.Join(workDir, fmt.Sprintf("%d.out.usr", id))
@ -142,7 +142,7 @@ func (s *service) ProblemJudge(meta *JudgeMeta, config *Config, cLang *ConfigLan
},
Env: []string{
fmt.Sprintf("TEST_NUM=%d", id),
fmt.Sprintf("CMP=%s", cLang.Judge.Cmp),
fmt.Sprintf("CMP=%s", meta.Cfg.Lang.Judge.Cmp),
},
},
Runtime: runtimeArgs,
@ -197,26 +197,14 @@ func (s *service) ProblemJudge(meta *JudgeMeta, config *Config, cLang *ConfigLan
}
func (s *service) RunAndJudge(meta *JudgeMeta) (*JudgeStatus, int32, e.Status) {
// 1. ensure problem/user exists
status := s.ValidatePath(meta)
if status != e.Success {
return &JudgeStatus{Message: "check failed"}, 0, status
}
// 1. run user program
s.ProblemRun(meta)
// 2. config
config, cLang, status := s.GetConfig(meta, true)
if status != e.Success {
return &JudgeStatus{Message: status.String()}, 0, status
}
// 2. run judge
s.ProblemJudge(meta)
// 3. run user program
s.ProblemRun(meta, config, cLang)
// 4. run judge
s.ProblemJudge(meta, config, cLang)
// 5. check result
result, pts := s.CheckResults(meta, config, cLang)
// 3. check result
result, pts := s.CheckResults(meta)
return result, pts, e.Success
}

View File

@ -32,6 +32,10 @@ type Service interface {
ParseConfig(meta *JudgeMeta, skipCheck bool) (*Config, error)
// ProblemExists check if problem exists
ProblemExists(meta *JudgeMeta) bool
// ValidatePath check if problem/user exists
ValidatePath(meta *JudgeMeta) (*JudgeStatus, e.Status)
// GetConfig return config and filter language config, will fill result to meta.Config
GetConfig(meta *JudgeMeta, skipCheck bool) e.Status
HealthCheck() error
Shutdown() error

View File

@ -47,8 +47,9 @@ type TaskStatus struct {
}
type JudgeStatus struct {
Message string `json:"message"`
Tasks []TaskStatus `json:"tasks"`
Message string `json:"message"`
CompileMessage string `json:"compile_message"`
Tasks []TaskStatus `json:"tasks"`
}
func (t *TaskStatus) getInfoText(infoFile string) *TaskStatus {
@ -193,19 +194,19 @@ func (t *TaskStatus) checkJudge(pts *map[int]int32) *TaskStatus {
return t
}
func (s *service) CheckResults(meta *JudgeMeta, config *Config, cLang *ConfigLanguage) (*JudgeStatus, int32) {
func (s *service) CheckResults(meta *JudgeMeta) (*JudgeStatus, int32) {
// CE will be processed in phase compile
pts := map[int]int32{}
for _, task := range config.Tasks {
for _, task := range meta.Cfg.All.Tasks {
pts[task.Id] = task.Points
}
var results []TaskStatus
dir := filepath.Join(UserDir, meta.User)
dir := filepath.Join(UserDir, meta.Run.User)
var sum int32 = 0
for i := 1; i <= len(config.Tasks); i++ {
for i := 1; i <= len(meta.Cfg.All.Tasks); i++ {
result := TaskStatus{Id: i, Verdict: VerdictAccepted, Points: 0}
info := filepath.Join(dir, fmt.Sprintf("%d.info", i))
@ -213,8 +214,8 @@ func (s *service) CheckResults(meta *JudgeMeta, config *Config, cLang *ConfigLan
result.getInfoText(info).
getInfo().
checkTime(cLang).
checkMemory(cLang).
checkTime(meta.Cfg.Lang).
checkMemory(meta.Cfg.Lang).
checkExit().
getJudgeText(judge).
getJudge().