eval

package
v0.0.0-...-5733806 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 10, 2023 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const MAGIC_REPLACE = "<REPLACE>"

Variables

View Source
var Langs = map[string]Language{
	"c": {
		Extensions:    []string{".c"},
		Compiled:      true,
		PrintableName: "C",
		InternalName:  "c",

		CompileCommand: []string{"gcc", "-fuse-ld=mold", "-std=c11", "-O2", "-s", "-static", "-DKNOVA", "-DONLINE_JUDGE", MAGIC_REPLACE, "-o", "/box/output"},
		RunCommand:     []string{"/box/output"},
		SourceName:     "/box/main.c",
		CompiledName:   "/box/output",

		Mounts: []Directory{{In: "/etc"}},
	},
	"cpp": {
		Extensions:    []string{".cpp", ".c++", ".cc", ".cxx", ".cpp11"},
		Compiled:      true,
		PrintableName: "C++11",
		InternalName:  "cpp",

		CompileCommand: []string{"g++", "-fuse-ld=mold", "-std=c++11", "-O2", "-s", "-static", "-DKNOVA", "-DONLINE_JUDGE", MAGIC_REPLACE, "-o", "/box/output"},
		RunCommand:     []string{"/box/output"},
		SourceName:     "/box/main.cpp",
		CompiledName:   "/box/output",

		Mounts: []Directory{{In: "/etc"}},
	},
	"cpp14": {
		Extensions:    []string{".cpp", ".c++", ".cc", ".cxx", ".cpp14"},
		Compiled:      true,
		PrintableName: "C++14",
		InternalName:  "cpp14",

		CompileCommand: []string{"g++", "-fuse-ld=mold", "-std=c++14", "-O2", "-s", "-static", "-DKNOVA", "-DONLINE_JUDGE", MAGIC_REPLACE, "-o", "/box/output"},
		RunCommand:     []string{"/box/output"},
		SourceName:     "/box/main.cpp",
		CompiledName:   "/box/output",

		Mounts: []Directory{{In: "/etc"}},
	},
	"cpp17": {
		Extensions:    []string{".cpp", ".c++", ".cc", ".cxx", ".cpp17"},
		Compiled:      true,
		PrintableName: "C++17",
		InternalName:  "cpp17",

		CompileCommand: []string{"g++", "-fuse-ld=mold", "-std=c++17", "-O2", "-s", "-static", "-DKNOVA", "-DONLINE_JUDGE", MAGIC_REPLACE, "-o", "/box/output"},
		RunCommand:     []string{"/box/output"},
		SourceName:     "/box/main.cpp",
		CompiledName:   "/box/output",

		Mounts: []Directory{{In: "/etc"}},
	},
	"cpp20": {
		Extensions:    []string{".cpp", ".c++", ".cc", ".cxx", ".cpp20"},
		Compiled:      true,
		PrintableName: "C++20",
		InternalName:  "cpp20",

		CompileCommand: []string{"g++", "-fuse-ld=mold", "-std=c++20", "-O2", "-s", "-static", "-DKNOVA", "-DONLINE_JUDGE", MAGIC_REPLACE, "-o", "/box/output"},
		RunCommand:     []string{"/box/output"},
		SourceName:     "/box/main.cpp",
		CompiledName:   "/box/output",

		Mounts: []Directory{{In: "/etc"}},
	},
	"pascal": {

		Extensions:    []string{".pas"},
		Compiled:      true,
		PrintableName: "Pascal",
		InternalName:  "pascal",

		CompileCommand: []string{"fpc", "-O2", "-XSst", "-Mobjfpc", "-vw", "-dKNOVA", "-dONLINE_JUDGE", MAGIC_REPLACE, "-o/box/output"},
		RunCommand:     []string{"/box/output"},
		SourceName:     "/box/main.pas",
		CompiledName:   "/box/output",

		Mounts: []Directory{{In: "/etc"}},
	},
	"golang": {

		Extensions:    []string{".go"},
		Compiled:      true,
		PrintableName: "Go",
		InternalName:  "golang",

		CompileCommand: []string{"/usr/bin/go", "build", MAGIC_REPLACE},
		RunCommand:     []string{"/box/main"},
		SourceName:     "/box/main.go",
		CompiledName:   "/box/main",

		BuildEnv:  map[string]string{"CGO_ENABLED": "0", "GOCACHE": "/go/cache", "GOPATH": "/box", "GO111MODULE": "off"},
		CommonEnv: map[string]string{"GOMAXPROCS": "1"},

		Mounts: []Directory{{In: "/go", Opts: "tmp", Verbatim: true}},
	},
	"haskell": {
		Disabled:      true,
		Extensions:    []string{".hs", ".lhs"},
		Compiled:      true,
		PrintableName: "Haskell",
		InternalName:  "haskell",

		CompileCommand: []string{"ghc", "-o", "/box/output", MAGIC_REPLACE},
		RunCommand:     []string{"/box/output"},
		SourceName:     "/box/main.hs",
		CompiledName:   "/box/output",
	},
	"java": {
		Disabled:      true,
		Extensions:    []string{".java"},
		Compiled:      true,
		PrintableName: "Java",
		InternalName:  "java",

		CompileCommand: []string{"javac", MAGIC_REPLACE},
		RunCommand:     []string{"java", "Main"},
		SourceName:     "/Main.java",
		CompiledName:   "/Main.class",

		Mounts: []Directory{{In: "/etc"}},
	},
	"python3": {
		Extensions:    []string{".py", ".py3"},
		Compiled:      false,
		PrintableName: "Python 3",
		InternalName:  "python3",

		RunCommand:   []string{"python3", "/box/main.py"},
		SourceName:   "/box/main.py",
		CompiledName: "/box/main.py",
	},
	"outputOnly": {
		Extensions:    []string{".output_only"},
		Compiled:      false,
		PrintableName: "Output Only",
		InternalName:  "outputOnly",

		RunCommand:   []string{"cat", "/box/output"},
		SourceName:   "/box/output_src",
		CompiledName: "/box/output",
	},
}

NOTE: Last extension MUST be unique (for proper detection of submissions in problem archives)

Functions

func CleanCompilation

func CleanCompilation(subid int) error

func CompileFile

func CompileFile(ctx context.Context, box Sandbox, files map[string][]byte, compiledFiles []string, language Language) (string, error)

CompileFile compiles a file that has the corresponding language

func CopyInBox

func CopyInBox(b Sandbox, p1 string, p2 string) error

func GetLangByFilename

func GetLangByFilename(filename string) string

func Initialize

func Initialize() error

Initialize should be called after reading the flags, but before manager.New

func MakeGoodCommand

func MakeGoodCommand(command []string) ([]string, error)

makeGoodCommand makes sure it's a full path (with no symlinks) for the command. Some languages (like java) are hidden pretty deep in symlinks, and we don't want a hardcoded path that could be different on other platforms.

func MakeGoodCompileCommand

func MakeGoodCompileCommand(command []string, files []string) ([]string, error)

func RunTask

func RunTask[req, resp any](ctx context.Context, mgr BoxScheduler, memQuota int64, r *req, t Task[req, resp]) (*resp, error)

TODO: Can this be done any nicer? Unfortunately it can't be a member of a struct/interface since Go type parameters are very restrictive regarding this

Types

type BoxScheduler

type BoxScheduler interface {
	GetBox(ctx context.Context, memQuota int64) (Sandbox, error)
	ReleaseBox(Sandbox)
	Close(context.Context) error
}

type Checker

type Checker interface {
	Prepare(context.Context) (string, error)
	Cleanup(context.Context) error

	// RunChecker returns a comment and a decimal number [0, 100] signifying the percentage of correctness of the subtest
	RunChecker(ctx context.Context, programOut, correctInput, correctOut io.Reader) (string, decimal.Decimal)
}

Checker is an interface for a function that statelessly tries to evaluate a subtest from a submission

type CompileRequest

type CompileRequest struct {
	ID          int
	CodeFiles   map[string][]byte
	HeaderFiles map[string][]byte
	Lang        string
}

type CompileResponse

type CompileResponse struct {
	Output  string
	Success bool
	Other   string
}

type Directory

type Directory struct {
	In      string `toml:"in"`
	Out     string `toml:"out"`
	Opts    string `toml:"opts"`
	Removes bool   `toml:"removes"`

	// Verbatim doesn't set Out to In implicitly if it isn't set
	Verbatim bool `toml:"verbatim"`
}

Directory represents a directory rule

type ExecRequest

type ExecRequest struct {
	SubID       int
	SubtestID   int
	Filename    string
	MemoryLimit int
	TimeLimit   float64
	Lang        string
	TestInput   io.Reader
}

type ExecResponse

type ExecResponse struct {
	Time       float64
	Memory     int
	ExitStatus int
	Comments   string
}

type Language

type Language struct {
	Disabled bool

	// Useful to categorize by file upload
	Extensions []string
	Compiled   bool

	PrintableName string
	InternalName  string

	CompileCommand []string `toml:"compile_command"`
	RunCommand     []string `toml:"run_command"`

	BuildEnv map[string]string `toml:"build_env"`
	RunEnv   map[string]string `toml:"run_env"`
	// CommonEnv will be added at both compile-time and runtime, and can be replaced by BuildEnv/RunEnv
	CommonEnv map[string]string `toml:"common_env"`

	// Mounts represents all directories to be mounted
	Mounts     []Directory `toml:"mounts"`
	SourceName string      `toml:"source_name"`

	CompiledName string `toml:"compiled_name"`
}

Language is the data available for a language

type Limits

type Limits struct {
	// seconds
	TimeLimit float64
	// kilobytes
	MemoryLimit int
}

Limits stores the constraints that need to be respected by a submission

type RunConfig

type RunConfig struct {
	StderrToStdout bool

	InputPath  string
	OutputPath string
	StderrPath string

	MemoryLimit int

	TimeLimit     float64
	WallTimeLimit float64

	MaxProcs int

	InheritEnv   bool
	EnvToInherit []string
	EnvToSet     map[string]string

	Directories []Directory
}

type RunStats

type RunStats struct {
	Memory int `json:"memory"`

	ExitCode   int  `json:"exit_code"`
	ExitSignal int  `json:"exit_signal"`
	Killed     bool `json:"killed"`

	Message string `json:"message"`
	Status  string `json:"status"`

	Time     float64 `json:"time"`
	WallTime float64 `json:"wall_time"`
}

func RunSubmission

func RunSubmission(ctx context.Context, box Sandbox, language Language, constraints Limits, consoleInput bool) (*RunStats, error)

RunSubmission runs a program, following the language conventions filenames contains the names for input and output, used if consoleInput is true

type Sandbox

type Sandbox interface {
	// ReadFile reads contents of path from sandbox and pipes them to the given writer
	ReadFile(path string, w io.Writer) error
	WriteFile(path string, r io.Reader, mode fs.FileMode) error
	// RemoveFile(path string) error
	FileExists(path string) bool

	// For debugging that god forsaken no output file found bug
	ReadDir(path string) ([]string, error)

	GetID() int
	MemoryQuota() int64

	// if stdout == stderr, then it will act like exec.CombinedOutput()
	RunCommand(ctx context.Context, cmd []string, conf *RunConfig) (*RunStats, error)

	io.Closer
}

type Task

type Task[Req, Resp any] func(context.Context, Sandbox, *Req) (*Resp, error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL