feat: testrun

This commit is contained in:
dragonmuffin 2024-08-25 23:09:57 +05:00
parent 858b2e7fd7
commit 6cc4bd0638
6 changed files with 65 additions and 16 deletions

3
.gitmodules vendored
View file

@ -1,6 +1,3 @@
[submodule "proto"] [submodule "proto"]
path = proto path = proto
url = https://git.sch9.ru/new_gate/contracts url = https://git.sch9.ru/new_gate/contracts
[submodule "languages"]
path = languages
url = https://git.sch9.ru/new_gate/languages

9
go.mod
View file

@ -1,14 +1,19 @@
module git.sch9.ru/new_gate/ms-runner module git.sch9.ru/new_gate/ms-runner
go 1.19 go 1.21.3
toolchain go1.23.0
require github.com/containerd/cgroups v1.1.0 require github.com/containerd/cgroups v1.1.0
require ( require (
git.sch9.ru/new_gate/ms-tester v0.0.0 // indirect
github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/docker/go-units v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect
github.com/godbus/dbus/v5 v5.0.4 // indirect github.com/godbus/dbus/v5 v5.0.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34 // indirect go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/sys v0.22.0 // indirect
) )

10
go.sum
View file

@ -1,3 +1,7 @@
git.sch9.ru/new_gate/ms-tester v0.0.0-20240825162014-7b0e1b21f19e h1:QTGa3uw7Lu9HZJymg/FlarlrdofwEdPuzBMXGrILkmU=
git.sch9.ru/new_gate/ms-tester v0.0.0-20240825162014-7b0e1b21f19e/go.mod h1:gqA96jkobHh1HM/bksygv2AnxM+GkCqVAdgmJyC0rE0=
git.sch9.ru/new_gate/ms-tester v0.0.0 h1:ZR5YkHCO9JAY/d1qqEgwu/Dtru6iR1p3sIBqp8tetnA=
git.sch9.ru/new_gate/ms-tester v0.0.0/go.mod h1:gqA96jkobHh1HM/bksygv2AnxM+GkCqVAdgmJyC0rE0=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
@ -14,6 +18,10 @@ github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNia
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -31,6 +39,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34 h1:GkvMjFtXUmahfDtashnc1mnrCtuBVcwse5QV2lUk/tI= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34 h1:GkvMjFtXUmahfDtashnc1mnrCtuBVcwse5QV2lUk/tI=
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

@ -1 +0,0 @@
Subproject commit 8a7e22c121766e865752f492af978f7225b2a95a

View file

@ -5,7 +5,7 @@ import (
) )
func main() { func main() {
runnerService,err := runner.NewRunnerService(); _,err := runner.NewRunnerService();
if(err != nil) { if(err != nil) {
panic(err) panic(err)
} }

View file

@ -1,6 +1,7 @@
package runner package runner
import ( import (
"errors"
"io" "io"
"fmt" "fmt"
"log" "log"
@ -10,7 +11,7 @@ import (
cgroups "github.com/containerd/cgroups" cgroups "github.com/containerd/cgroups"
rand "math/rand" rand "math/rand"
"time" "time"
"git.sch9.ru/new_gate/ms-runner/languages" "git.sch9.ru/new_gate/ms-tester/pkg/models"
) )
const runIdLength = 20 const runIdLength = 20
@ -56,6 +57,15 @@ func copyFile(src string,dst string) error {
return nil return nil
} }
func newRunFolder() (string,error) {
runId := genRunId()
err := os.Mkdir("runs/" + runId, 0777)
if(err!=nil) { return "",err }
err = os.Chmod("runs/" + runId, 0777)
if(err!=nil) { return "",err }
return runId,nil
}
func extractNumbers(s string) (result []int32) { func extractNumbers(s string) (result []int32) {
lastNumber, isNumber := false,false lastNumber, isNumber := false,false
var curNumber int32 = 0 var curNumber int32 = 0
@ -116,12 +126,10 @@ func NewRunnerService() (*RunnerService, error) {
func (runnerService RunnerService) Build(languageId int32, filename string) { func (runnerService RunnerService) Build(languageId int32, filename string) {
core := <-runnerService.CoreFreed core := <-runnerService.CoreFreed
runId := genRunId() runId,err := newRunFolder()
err := os.Mkdir("runs/" + runId, 0777) if(err!=nil) {log.Fatal
if(err!=nil) { log.Fatal(err) }
os.Chmod("runs/" + runId, 0777)
copyFile(filename,"runs/"+runId+"/src") copyFile(filename,"runs/"+runId+"/src")
runnerService.IsolatedRun(languages.Languages[languageId].CompileCmd,"../runs/"+runId,Limits{Processes: 10,Core:core,Memory:BuildMemory,Time:BuildTime}); runnerService.IsolatedRun(models.Languages[languageId].CompileCmd,"../runs/"+runId,Limits{Processes: 10,Core:core,Memory:BuildMemory,Time:BuildTime});
copyFile("runs/"+runId+"/executable","executable") copyFile("runs/"+runId+"/executable","executable")
os.RemoveAll("runs/" + runId) os.RemoveAll("runs/" + runId)
go func() { go func() {
@ -129,13 +137,43 @@ func (runnerService RunnerService) Build(languageId int32, filename string) {
}() }()
} }
func (runnerService RunnerService) IsolatedRun(command []string, sharedFolder string, limits Limits) { func (runnerService RunnerService) RunTest(solutionLanguageId int32, solutionFilename string, inputFilename string, checkerLanguageId int32, checkerFilename string, limits Limits) (models.Result) {
core := <-runnerService.CoreFreed
testRunId,err := newRunFolder()
if(err!=nil) {log.Fatal
copyFile(solutionFilename,"runs/"+testRunId+"/executable")
copyFile(inputFilename,"runs/"+testRunId+"/in")
code,err = runnerService.IsolatedRun(models.Languages[languageId].RunCmd,"../runs/"+testRunId,limits);
defer os.RemoveAll("runs/" + testRunId)
if(err!=nil) {log.Fatal(err);}
if(code!=0) {return models.RuntimeError}
checkRunId,err := newRunFolder()
copyFile("runs/"+testRunId+"/out","runs/"+checkRunId+"/out")
err = runnerService.IsolatedRun(models.Languages[languageId].RunCmd,"../runs/"+checkRunId,Limits{Processes: 10,Core:core,Memory:BuildMemory,Time:BuildTime}); //FIXME add input/output/answer files options
defer os.RemoveAll("runs/" + checkRunId)
if(err!=nil) {log.Fatal(err);}
switch code {
case 0: return models.Accepted //FIXME add model constants
case 1: return models.WrongAnswer
case 2: return models.PresentationError
case 3: return models.SystemFailDuringTesting
}
return models.SystemFailDuringTesting //bad checker result is a system fail
go func() {
runnerService.CoreFreed <- core
}()
}
func (runnerService RunnerService) IsolatedRun(command []string, sharedFolder string, limits Limits) (int32,error) {
args := []string{int32ToString(limits.Processes),int32ToString(limits.Core), int32ToString(limits.Memory), int32ToString(limits.Time), sharedFolder} args := []string{int32ToString(limits.Processes),int32ToString(limits.Core), int32ToString(limits.Memory), int32ToString(limits.Time), sharedFolder}
args = append(args, command...) args = append(args, command...)
log.Println("running isolated process with command:",args) log.Println("running isolated process with command:",args)
cmd := exec.Command("starter/starter", args...) cmd := exec.Command("starter/starter", args...)
err := cmd.Run(); err := cmd.Run();
if err != nil { if errors.Is(err,exec.ExitError) {
log.Println(err) return err.ProcessState.ExitCode,nil
} else if(err!=nil) {
return 0,err
} }
return 0,nil
} }