feat: diff parser with example
This commit is contained in:
parent
a3deb3d974
commit
ab956f5662
31
README.md
31
README.md
|
@ -13,20 +13,20 @@ go build -o ./build/joj3 ./cmd/joj3
|
|||
+ DIRNAME=./_example/simple
|
||||
+ cd ./_example/simple
|
||||
+ ./../../build/joj3
|
||||
2024/03/04 02:09:42 INFO stage start name=compile
|
||||
2024/03/04 02:09:42 INFO sandbox run cmd="{Args:[/usr/bin/g++ a.cc -o a] Env:[PATH=/usr/bin:/bin] Files:[0xc00007f540 0xc00007f580 0xc00007f5c0] CPULimit:10000000000 RealCPULimit:0 ClockLimit:0 MemoryLimit:104857600 StackLimit:0 ProcLimit:50 CPURateLimit:0 CPUSetLimit: CopyIn:map[] CopyInCached:map[] CopyInCwd:true CopyOut:[stdout stderr] CopyOutCached:[a] CopyOutMax:0 CopyOutDir: TTY:false StrictMemoryLimit:false DataSegmentLimit:false AddressSpaceLimit:false}"
|
||||
2024/03/04 02:09:42 INFO sandbox run copyInCwd=true
|
||||
2024/03/04 02:09:42 INFO sandbox run ret="results:{status:Accepted time:321003000 runTime:321988110 memory:57888768 files:{key:\"stderr\" value:\"\"} files:{key:\"stdout\" value:\"\"} fileIDs:{key:\"a\" value:\"T6BQPS5B\"}}"
|
||||
2024/03/04 02:09:42 INFO executor done result="{Status:Accepted ExitStatus:0 Error: Time:321.003ms RunTime:321.98811ms Memory:55.2 MiB Files:map[stderr:len:0 stdout:len:0] FileIDs:map[a:T6BQPS5B] FileError:[]}"
|
||||
2024/03/04 02:09:42 INFO parser done result="&{Score:100 Comment:compile done, executor status: run time: 321988110 ns, memory: 57888768 bytes}"
|
||||
2024/03/04 02:09:42 INFO stage start name=run
|
||||
2024/03/04 02:09:42 INFO sandbox run cmd="{Args:[./a] Env:[PATH=/usr/bin:/bin] Files:[0xc00007f600 0xc00007f640 0xc00007f680] CPULimit:10000000000 RealCPULimit:0 ClockLimit:0 MemoryLimit:104857600 StackLimit:0 ProcLimit:50 CPURateLimit:0 CPUSetLimit: CopyIn:map[] CopyInCached:map[a:a] CopyInCwd:false CopyOut:[stdout stderr] CopyOutCached:[] CopyOutMax:0 CopyOutDir: TTY:false StrictMemoryLimit:false DataSegmentLimit:false AddressSpaceLimit:false}"
|
||||
2024/03/04 02:09:42 INFO sandbox run ret="results:{status:Accepted time:1446000 runTime:2284978 memory:15384576 files:{key:\"stderr\" value:\"\"} files:{key:\"stdout\" value:\"2\\n\"}}"
|
||||
2024/03/04 02:09:42 INFO executor done result="{Status:Accepted ExitStatus:0 Error: Time:1.446ms RunTime:2.284978ms Memory:14.7 MiB Files:map[stderr:len:0 stdout:len:2] FileIDs:map[] FileError:[]}"
|
||||
2024/03/04 02:09:42 INFO parser done result="&{Score:100 Comment:run done, executor status: run time: 2284978 ns, memory: 15384576 bytes}"
|
||||
2024/03/04 02:09:42 INFO stage result name=compile score=100 comment="compile done, executor status: run time: 321988110 ns, memory: 57888768 bytes"
|
||||
2024/03/04 02:09:42 INFO stage result name=run score=100 comment="run done, executor status: run time: 2284978 ns, memory: 15384576 bytes"
|
||||
2024/03/04 02:09:42 INFO sandbox cleanup
|
||||
2024/03/04 02:57:50 INFO stage start name=compile
|
||||
2024/03/04 02:57:50 INFO sandbox run cmd="{Args:[/usr/bin/g++ a.cc -o a] Env:[PATH=/usr/bin:/bin] Files:[0xc00007f540 0xc00007f580 0xc00007f5c0] CPULimit:10000000000 RealCPULimit:0 ClockLimit:0 MemoryLimit:104857600 StackLimit:0 ProcLimit:50 CPURateLimit:0 CPUSetLimit: CopyIn:map[] CopyInCached:map[] CopyInCwd:true CopyOut:[stdout stderr] CopyOutCached:[a] CopyOutMax:0 CopyOutDir: TTY:false StrictMemoryLimit:false DataSegmentLimit:false AddressSpaceLimit:false}"
|
||||
2024/03/04 02:57:50 INFO sandbox run copyInCwd=true
|
||||
2024/03/04 02:57:50 INFO sandbox run ret="results:{status:Accepted time:298002000 runTime:298694146 memory:57880576 files:{key:\"stderr\" value:\"\"} files:{key:\"stdout\" value:\"\"} fileIDs:{key:\"a\" value:\"DMTRJR3V\"}}"
|
||||
2024/03/04 02:57:50 INFO executor done result="{Status:Accepted ExitStatus:0 Error: Time:298.002ms RunTime:298.694146ms Memory:55.2 MiB Files:map[stderr:len:0 stdout:len:0] FileIDs:map[a:DMTRJR3V] FileError:[]}"
|
||||
2024/03/04 02:57:50 INFO parser done result="&{Score:100 Comment:compile done, executor status: run time: 298694146 ns, memory: 57880576 bytes}"
|
||||
2024/03/04 02:57:50 INFO stage start name=run
|
||||
2024/03/04 02:57:50 INFO sandbox run cmd="{Args:[./a] Env:[PATH=/usr/bin:/bin] Files:[0xc00007f600 0xc00007f640 0xc00007f680] CPULimit:10000000000 RealCPULimit:0 ClockLimit:0 MemoryLimit:104857600 StackLimit:0 ProcLimit:50 CPURateLimit:0 CPUSetLimit: CopyIn:map[] CopyInCached:map[a:a] CopyInCwd:false CopyOut:[stdout stderr] CopyOutCached:[] CopyOutMax:0 CopyOutDir: TTY:false StrictMemoryLimit:false DataSegmentLimit:false AddressSpaceLimit:false}"
|
||||
2024/03/04 02:57:50 INFO sandbox run ret="results:{status:Accepted time:1122000 runTime:1723994 memory:15384576 files:{key:\"stderr\" value:\"\"} files:{key:\"stdout\" value:\"2\\n\"}}"
|
||||
2024/03/04 02:57:50 INFO executor done result="{Status:Accepted ExitStatus:0 Error: Time:1.122ms RunTime:1.723994ms Memory:14.7 MiB Files:map[stderr:len:0 stdout:len:2] FileIDs:map[] FileError:[]}"
|
||||
2024/03/04 02:57:50 INFO parser done result="&{Score:100 Comment:}"
|
||||
2024/03/04 02:57:50 INFO stage result name=compile score=100 comment="compile done, executor status: run time: 298694146 ns, memory: 57880576 bytes"
|
||||
2024/03/04 02:57:50 INFO stage result name=run score=100 comment=""
|
||||
2024/03/04 02:57:50 INFO sandbox cleanup
|
||||
+ cd -
|
||||
```
|
||||
|
||||
|
@ -44,10 +44,11 @@ Parser takes a `ExecutorResult` and its config and returns a `ParserResult`.
|
|||
|
||||
Check `Cmd` in <https://github.com/criyle/go-judge#rest-api-interface>.
|
||||
|
||||
Some extra fields:
|
||||
Some difference:
|
||||
|
||||
- `CopyInCwd bool`: set to `true` to add everything in the current working directory to `CopyIn`.
|
||||
- `CopyInCached map[string]string`: key: file name in sandbox, value: file name used in `CopyOutCached`.
|
||||
- `LocalFile`: now support relative path
|
||||
|
||||
### `ExecutorResult`
|
||||
|
||||
|
|
1
_example/simple/1.stdin
Normal file
1
_example/simple/1.stdin
Normal file
|
@ -0,0 +1 @@
|
|||
1 1
|
1
_example/simple/1.stdout
Normal file
1
_example/simple/1.stdout
Normal file
|
@ -0,0 +1 @@
|
|||
2
|
|
@ -38,7 +38,7 @@ copyOut = ["stdout", "stderr"]
|
|||
[stages.executor.with.copyInCached]
|
||||
a = "a"
|
||||
[[stages.executor.with.files]]
|
||||
content = "1 1"
|
||||
src = "1.stdin"
|
||||
[[stages.executor.with.files]]
|
||||
name = "stdout"
|
||||
max = 4_096
|
||||
|
@ -46,7 +46,7 @@ max = 4_096
|
|||
name = "stderr"
|
||||
max = 4_096
|
||||
[stages.parser]
|
||||
name = "dummy"
|
||||
name = "diff"
|
||||
[stages.parser.with]
|
||||
score = 100
|
||||
comment = "run done"
|
||||
stdoutPath = "1.stdout"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package sandbox
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
|
||||
|
@ -143,3 +144,14 @@ func convertPBFileError(fe []*pb.Response_FileError) []stage.FileError {
|
|||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func convertAbsPath(cmdFile *stage.CmdFile) error {
|
||||
if cmdFile.Src != nil && !filepath.IsAbs(*cmdFile.Src) {
|
||||
absPath, err := filepath.Abs(*cmdFile.Src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmdFile.Src = &absPath
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -46,6 +46,16 @@ func (e *Sandbox) Run(cmd stage.Cmd) (*stage.ExecutorResult, error) {
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
for _, file := range cmd.Files {
|
||||
if err := convertAbsPath(file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for _, file := range cmd.CopyIn {
|
||||
if err := convertAbsPath(&file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
req := &pb.Request{Cmd: convertPBCmd([]stage.Cmd{cmd})}
|
||||
ret, err := e.execClient.Exec(context.TODO(), req)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package parsers
|
||||
|
||||
import (
|
||||
_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff"
|
||||
_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/dummy"
|
||||
)
|
||||
|
||||
|
|
9
internal/parsers/diff/meta.go
Normal file
9
internal/parsers/diff/meta.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package diff
|
||||
|
||||
import "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
|
||||
|
||||
var name = "diff"
|
||||
|
||||
func init() {
|
||||
stage.RegisterParser(name, &Diff{})
|
||||
}
|
36
internal/parsers/diff/parser.go
Normal file
36
internal/parsers/diff/parser.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package diff
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Score int
|
||||
StdoutPath string
|
||||
}
|
||||
|
||||
type Diff struct{}
|
||||
|
||||
func (e *Diff) Run(result *stage.ExecutorResult, configAny any) (
|
||||
*stage.ParserResult, error,
|
||||
) {
|
||||
config, err := stage.DecodeConfig[Config](configAny)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
score := 0
|
||||
stdout, err := os.ReadFile(config.StdoutPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO: more compare strategies
|
||||
if string(stdout) == result.Files["stdout"] {
|
||||
score = config.Score
|
||||
}
|
||||
return &stage.ParserResult{
|
||||
Score: score,
|
||||
Comment: "",
|
||||
}, nil
|
||||
}
|
|
@ -2,10 +2,8 @@ package dummy
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
@ -18,10 +16,8 @@ type Dummy struct{}
|
|||
func (e *Dummy) Run(result *stage.ExecutorResult, configAny any) (
|
||||
*stage.ParserResult, error,
|
||||
) {
|
||||
var config Config
|
||||
err := mapstructure.Decode(configAny, &config)
|
||||
config, err := stage.DecodeConfig[Config](configAny)
|
||||
if err != nil {
|
||||
slog.Error("failed to decode config", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
return &stage.ParserResult{
|
||||
|
|
12
internal/stage/util.go
Normal file
12
internal/stage/util.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package stage
|
||||
|
||||
import "github.com/mitchellh/mapstructure"
|
||||
|
||||
func DecodeConfig[T any](configAny any) (*T, error) {
|
||||
var config T
|
||||
err := mapstructure.Decode(configAny, &config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &config, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user