WIP: dev #6
| 
						 | 
				
			
			@ -5,10 +5,10 @@ from typing import Any, List
 | 
			
		|||
import rtoml
 | 
			
		||||
 | 
			
		||||
from joj3_config_generator.models import joj1, repo, result, task
 | 
			
		||||
from joj3_config_generator.processers.repo import (
 | 
			
		||||
from joj3_config_generator.processers.repo import (  # get_teapotcheck_config,
 | 
			
		||||
    get_healthcheck_config,
 | 
			
		||||
    get_teapot_config,
 | 
			
		||||
    get_teapotcheck_config,
 | 
			
		||||
    get_teapot_stage,
 | 
			
		||||
)
 | 
			
		||||
from joj3_config_generator.processers.task import (
 | 
			
		||||
    fix_diff,
 | 
			
		||||
| 
						 | 
				
			
			@ -34,13 +34,17 @@ def convert(repo_conf: repo.Config, task_conf: task.Config) -> result.Config:
 | 
			
		|||
        ),
 | 
			
		||||
        # FIXME: don't hardcode
 | 
			
		||||
        actor_csv_path="/home/tt/.config/joj/students.csv",
 | 
			
		||||
        stage=result.Stage(stages=[], sandbox_token=repo_conf.sandbox_token),
 | 
			
		||||
        stage=result.Stage(
 | 
			
		||||
            stages=[],
 | 
			
		||||
            sandbox_token=repo_conf.sandbox_token,
 | 
			
		||||
            poststages=[get_teapot_stage(repo_conf)],
 | 
			
		||||
        ),
 | 
			
		||||
        teapot=get_teapot_config(repo_conf, task_conf),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # Construct healthcheck stage
 | 
			
		||||
    healthcheck_stage = get_healthcheck_config(repo_conf)
 | 
			
		||||
    teapotcheck_stage = get_teapotcheck_config(repo_conf, task_conf)
 | 
			
		||||
    # teapotcheck_stage = get_teapotcheck_config(repo_conf, task_conf)
 | 
			
		||||
    result_conf.stage.stages.append(healthcheck_stage)
 | 
			
		||||
    cached: List[str] = []
 | 
			
		||||
    # Convert each stage in the task configuration
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +69,7 @@ def convert_joj1(joj1_conf: joj1.Config) -> task.Config:
 | 
			
		|||
        # You can define a command based on language properties
 | 
			
		||||
        command = f"run {language.language}"
 | 
			
		||||
        # Assuming we don't have explicit files, we will set empty ones or default behavior
 | 
			
		||||
        files = task.Files(import_=[], export=[])
 | 
			
		||||
        files = task.Files(import_=[], export=[])  # type: ignore
 | 
			
		||||
        # Score can be derived from the first case or set to a default
 | 
			
		||||
        score = 0
 | 
			
		||||
        parsers: List[str] = []  # Define parsers if applicable
 | 
			
		||||
| 
						 | 
				
			
			@ -121,4 +125,3 @@ def distribute_json(folder_path: str, repo_obj: Any) -> None:
 | 
			
		|||
                    assert os.path.exists(
 | 
			
		||||
                        json_file_path
 | 
			
		||||
                    ), f"Failed to convert {toml_file_path} into json!"
 | 
			
		||||
    return 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,9 +15,7 @@ class Group(BaseModel):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class Config(BaseModel):
 | 
			
		||||
    teaching_team: List[str]
 | 
			
		||||
    max_size: float = Field(..., ge=0)
 | 
			
		||||
    release_tags: List[str]
 | 
			
		||||
    files: Files
 | 
			
		||||
    sandbox_token: str
 | 
			
		||||
    max_total_score: int = Field(100)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,8 +16,8 @@ class CmdFile(BaseModel):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class Cmd(BaseModel):
 | 
			
		||||
    args: list[str]
 | 
			
		||||
    env: list[str] = ["PATH=/usr/bin:/bin:/usr/local/bin"]
 | 
			
		||||
    args: Optional[List[str]] = None
 | 
			
		||||
    env: Optional[List[str]] = ["PATH=/usr/bin:/bin:/usr/local/bin"]
 | 
			
		||||
| 
					
	
	
	
	
	
	
	
	 | 
			||||
    stdin: Optional[CmdFile] = CmdFile(content="")
 | 
			
		||||
    stdout: Optional[CmdFile] = CmdFile(name="stdout", max=4 * 1024)
 | 
			
		||||
    stderr: Optional[CmdFile] = CmdFile(name="stderr", max=4 * 1024)
 | 
			
		||||
| 
						 | 
				
			
			@ -27,12 +27,12 @@ class Cmd(BaseModel):
 | 
			
		|||
    memory_limit: int = Field(800 * 1024 * 1024, serialization_alias="memoryLimit")
 | 
			
		||||
    stack_limit: int = Field(0, serialization_alias="stackLimit")
 | 
			
		||||
    proc_limit: int = Field(50, serialization_alias="procLimit")
 | 
			
		||||
    proc_limit: int = Field(50, serialization_alias="procLimit")
 | 
			
		||||
    cpu_rate_limit: int = Field(0, serialization_alias="cpuRateLimit")
 | 
			
		||||
    cpu_set_limit: str = Field("", serialization_alias="cpuSetLimit")
 | 
			
		||||
    copy_in: Dict[str, CmdFile] = Field({}, serialization_alias="copyIn")
 | 
			
		||||
    copy_in_cached: Dict[str, str] = Field({}, serialization_alias="copyInCached")
 | 
			
		||||
    copy_in_dir: str = Field(".", serialization_alias="copyInDir")
 | 
			
		||||
    # reconsider this default situation
 | 
			
		||||
    copy_out: List[str] = Field(["stdout", "stderr"], serialization_alias="copyOut")
 | 
			
		||||
    copy_out_cached: List[str] = Field([], serialization_alias="copyOutCached")
 | 
			
		||||
    copy_out_max: int = Field(0, serialization_alias="copyOutMax")
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +46,6 @@ class Cmd(BaseModel):
 | 
			
		|||
class OptionalCmd(BaseModel):
 | 
			
		||||
    args: Optional[list[str]] = None
 | 
			
		||||
    env: Optional[list[str]] = ["PATH=/usr/bin:/bin:/usr/local/bin"]
 | 
			
		||||
    env: Optional[list[str]] = ["PATH=/usr/bin:/bin:/usr/local/bin"]
 | 
			
		||||
    stdin: Optional[CmdFile] = None
 | 
			
		||||
    stdout: Optional[CmdFile] = None
 | 
			
		||||
    stderr: Optional[CmdFile] = None
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +59,6 @@ class OptionalCmd(BaseModel):
 | 
			
		|||
    )
 | 
			
		||||
    stack_limit: Optional[int] = Field(None, serialization_alias="stackLimit")
 | 
			
		||||
    proc_limit: Optional[int] = Field(50, serialization_alias="procLimit")
 | 
			
		||||
    proc_limit: Optional[int] = Field(50, serialization_alias="procLimit")
 | 
			
		||||
    cpu_rate_limit: Optional[int] = Field(None, serialization_alias="cpuRateLimit")
 | 
			
		||||
    cpu_set_limit: Optional[str] = Field(None, serialization_alias="cpuSetLimit")
 | 
			
		||||
    copy_in: Optional[Dict[str, CmdFile]] = Field(None, serialization_alias="copyIn")
 | 
			
		||||
| 
						 | 
				
			
			@ -88,14 +86,7 @@ class OptionalCmd(BaseModel):
 | 
			
		|||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Stage(BaseModel):
 | 
			
		||||
    name: str
 | 
			
		||||
    group: Optional[str] = None
 | 
			
		||||
    executor: "ExecutorConfig"
 | 
			
		||||
    parsers: list["ParserConfig"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ExecutorWithConfig(BaseModel):
 | 
			
		||||
class ExecutorWith(BaseModel):
 | 
			
		||||
    default: Cmd
 | 
			
		||||
    cases: List[OptionalCmd]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +96,7 @@ class Executor(BaseModel):
 | 
			
		|||
    with_: ExecutorWith = Field(..., serialization_alias="with")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Parser(BaseModel):
 | 
			
		||||
class ParserConfig(BaseModel):
 | 
			
		||||
    name: str
 | 
			
		||||
    with_: Dict[str, Any] = Field(..., serialization_alias="with")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -114,7 +105,7 @@ class StageDetail(BaseModel):
 | 
			
		|||
    name: str
 | 
			
		||||
    group: Optional[str] = ""
 | 
			
		||||
    executor: Executor
 | 
			
		||||
    parsers: List[Parser]
 | 
			
		||||
    parsers: List[ParserConfig]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Stage(BaseModel):
 | 
			
		||||
| 
						 | 
				
			
			@ -126,6 +117,8 @@ class Stage(BaseModel):
 | 
			
		|||
        "/tmp/joj3_result.json", serialization_alias="outputPath"
 | 
			
		||||
    )  # nosec: B108
 | 
			
		||||
    stages: List[StageDetail]
 | 
			
		||||
    prestages: Optional[List[StageDetail]] = None
 | 
			
		||||
    poststages: List[StageDetail]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Teapot(BaseModel):
 | 
			
		||||
| 
						 | 
				
			
			@ -147,9 +140,10 @@ class Teapot(BaseModel):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class Config(BaseModel):
 | 
			
		||||
    name: str = "unknown"
 | 
			
		||||
    name: str = ""
 | 
			
		||||
    log_path: str = Field("", serialization_alias="logPath")
 | 
			
		||||
    expire_unix_timestamp: int = Field(-1, serialization_alias="expireUnixTimestamp")
 | 
			
		||||
    actor_csv_path: str = Field("", serialization_alias="actorCsvPath")
 | 
			
		||||
    actor_csv_path: str = Field("", serialization_alias="actorpostStagesCsvPath")
 | 
			
		||||
    max_total_score: int = Field(100, serialization_alias="maxTotalScore")
 | 
			
		||||
    stage: Stage
 | 
			
		||||
    teapot: Teapot
 | 
			
		||||
    teapot: Teapot  # FIXME: remove this
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
from datetime import datetime
 | 
			
		||||
from typing import Any, Dict, Optional, Type
 | 
			
		||||
from typing import Any, Dict, List, Optional, Type
 | 
			
		||||
 | 
			
		||||
from pydantic import BaseModel, Field, root_validator
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +13,13 @@ class ParserResultDetail(BaseModel):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class ParserFile(BaseModel):
 | 
			
		||||
    name: str = None
 | 
			
		||||
    name: Optional[str] = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ParserLog(BaseModel):
 | 
			
		||||
    fileName: Optional[str] = None
 | 
			
		||||
    msg: Optional[str] = None
 | 
			
		||||
    level: Optional[str] = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ParserDummy(BaseModel):
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +60,7 @@ class Stage(BaseModel):
 | 
			
		|||
    name: Optional[str] = None  # Stage name
 | 
			
		||||
    group: Optional[str] = None  # TODO: may need to formulate this
 | 
			
		||||
    path: Optional[str] = None  # FIXME: this is highly possible to be removed in future
 | 
			
		||||
    env: Optional[list[str]] = None
 | 
			
		||||
    command: Optional[str] = None  # Command to run
 | 
			
		||||
    files: Optional[Files] = None
 | 
			
		||||
    in_: Optional[str] = Field(None, alias="in")
 | 
			
		||||
| 
						 | 
				
			
			@ -72,8 +79,9 @@ class Stage(BaseModel):
 | 
			
		|||
    )
 | 
			
		||||
    file: Optional[ParserFile] = ParserFile()
 | 
			
		||||
    skip: Optional[list[str]] = []
 | 
			
		||||
    diff: Optional[ParserDiff] = ParserDiff()
 | 
			
		||||
    # cases related
 | 
			
		||||
    cases: Optional[Dict[str, "Stage"]] = {}
 | 
			
		||||
    diff: Optional[ParserDiff] = ParserDiff()
 | 
			
		||||
 | 
			
		||||
    class Config:
 | 
			
		||||
        extra = "allow"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
import hashlib
 | 
			
		||||
import shlex
 | 
			
		||||
import socket
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
 | 
			
		||||
from joj3_config_generator.models import repo, result, task
 | 
			
		||||
| 
						 | 
				
			
			@ -7,8 +8,8 @@ from joj3_config_generator.models import repo, result, task
 | 
			
		|||
 | 
			
		||||
def get_grading_repo_name() -> str:
 | 
			
		||||
    # FIXME: uncomment back when everything is ready!
 | 
			
		||||
    host_name = "engr151"
 | 
			
		||||
    # host_name = socket.gethostname()
 | 
			
		||||
    # host_name = "engr151"
 | 
			
		||||
    host_name = socket.gethostname()
 | 
			
		||||
    return f"{host_name.split('-')[0]}-joj"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +51,33 @@ def get_teapot_config(repo_conf: repo.Config, task_conf: task.Config) -> result.
 | 
			
		|||
    return teapot
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_healthcheck_cmd(repo_conf: repo.Config) -> result.Cmd:
 | 
			
		||||
def get_teapot_stage(repo_conf: repo.Config) -> result.StageDetail:
 | 
			
		||||
    args_ = ""
 | 
			
		||||
    args_ = (
 | 
			
		||||
        args_
 | 
			
		||||
        + f"/usr/local/bin/joint-teapot joj3-all-env /home/tt/.config/teapot/teapot.env --grading-repo-name {get_grading_repo_name()} --max-total-score {repo_conf.max_total_score}"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    stage_conf = result.StageDetail(
 | 
			
		||||
        name="teapot",
 | 
			
		||||
        executor=result.Executor(
 | 
			
		||||
            name="local",
 | 
			
		||||
            with_=result.ExecutorWith(
 | 
			
		||||
                default=result.Cmd(
 | 
			
		||||
                    args=shlex.split(args_),
 | 
			
		||||
                    env=[
 | 
			
		||||
                        "LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"
 | 
			
		||||
                    ],  # TODO: fix it according to the task name
 | 
			
		||||
                ),
 | 
			
		||||
                cases=[],
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        parsers=[result.ParserConfig(name="log", with_={"msg": "joj3 summary"})],
 | 
			
		||||
    )
 | 
			
		||||
    return stage_conf
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_healthcheck_args(repo_conf: repo.Config) -> str:
 | 
			
		||||
    repoSize = repo_conf.max_size
 | 
			
		||||
    immutable = repo_conf.files.immutable
 | 
			
		||||
    repo_size = f"-repoSize={str(repoSize)} "
 | 
			
		||||
| 
						 | 
				
			
			@ -59,13 +86,13 @@ def get_healthcheck_cmd(repo_conf: repo.Config) -> result.Cmd:
 | 
			
		|||
    for i, meta in enumerate(required_files):
 | 
			
		||||
        required_files[i] = f"-meta={meta} "
 | 
			
		||||
 | 
			
		||||
    immutable_files = f"-checkFileNameList="
 | 
			
		||||
    immutable_files = "-checkFileNameList="
 | 
			
		||||
    for i, name in enumerate(immutable):
 | 
			
		||||
        if i == len(immutable) - 1:
 | 
			
		||||
            immutable_files = immutable_files + name + " "
 | 
			
		||||
        else:
 | 
			
		||||
            immutable_files = immutable_files + name + ","
 | 
			
		||||
    chore = f"/tmp/repo-health-checker -root=. "
 | 
			
		||||
    chore = "/usr/local/bin/repo-health-checker -root=. "
 | 
			
		||||
    args = ""
 | 
			
		||||
    args = args + chore
 | 
			
		||||
    args = args + repo_size
 | 
			
		||||
| 
						 | 
				
			
			@ -76,26 +103,25 @@ def get_healthcheck_cmd(repo_conf: repo.Config) -> result.Cmd:
 | 
			
		|||
 | 
			
		||||
    args = args + immutable_files
 | 
			
		||||
 | 
			
		||||
    cmd = result.Cmd(
 | 
			
		||||
        args=shlex.split(args),
 | 
			
		||||
        copy_in={
 | 
			
		||||
            # This path is hardcoded
 | 
			
		||||
            f"/tmp/repo-health-checker": result.CmdFile(
 | 
			
		||||
                src="/usr/local/bin/repo-health-checker"
 | 
			
		||||
            )
 | 
			
		||||
        },
 | 
			
		||||
    return args
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_debug_args(repo_conf: repo.Config) -> str:
 | 
			
		||||
    args = ""
 | 
			
		||||
    args = (
 | 
			
		||||
        args
 | 
			
		||||
        + f"/usr/local/bin/joint-teapot joj3-check-env /home/tt/.config/teapot/teapot.env --grading-repo-name {get_grading_repo_name()} --group-config"
 | 
			
		||||
    )
 | 
			
		||||
    return cmd
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_teapotcheck_cmd(repo_conf: repo.Config, task_conf: task.Config) -> result.Cmd:
 | 
			
		||||
    return 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_teapotcheck_config(
 | 
			
		||||
    repo_conf: repo.Config, task_conf: task.Config
 | 
			
		||||
) -> result.StageDetail:
 | 
			
		||||
    return 0
 | 
			
		||||
    group_config = ""
 | 
			
		||||
    for i, name in enumerate(repo_conf.groups.name):
 | 
			
		||||
        group_config = (
 | 
			
		||||
            group_config
 | 
			
		||||
            + f"{name}={repo_conf.groups.max_count[i]}:{repo_conf.groups.time_period_hour[i]},"
 | 
			
		||||
        )
 | 
			
		||||
    # default value hardcoded
 | 
			
		||||
    group_config = group_config + "=100:24"
 | 
			
		||||
    args = args + group_config
 | 
			
		||||
    return args
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_healthcheck_config(repo_conf: repo.Config) -> result.StageDetail:
 | 
			
		||||
| 
						 | 
				
			
			@ -103,10 +129,24 @@ def get_healthcheck_config(repo_conf: repo.Config) -> result.StageDetail:
 | 
			
		|||
        name="healthcheck",
 | 
			
		||||
        group="",
 | 
			
		||||
        executor=result.Executor(
 | 
			
		||||
            name="sandbox",
 | 
			
		||||
            with_=result.ExecutorWith(default=get_healthcheck_cmd(repo_conf), cases=[]),
 | 
			
		||||
            name="local",
 | 
			
		||||
            with_=result.ExecutorWith(
 | 
			
		||||
                default=result.Cmd(),
 | 
			
		||||
                cases=[
 | 
			
		||||
                    result.OptionalCmd(
 | 
			
		||||
                        args=shlex.split(get_healthcheck_args(repo_conf)),
 | 
			
		||||
                    ),
 | 
			
		||||
                    result.OptionalCmd(
 | 
			
		||||
                        args=shlex.split(get_debug_args(repo_conf)),
 | 
			
		||||
                        env=["LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"],
 | 
			
		||||
                    ),
 | 
			
		||||
                ],
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        parsers=[ParserConfig(name="healthcheck", with_={"score": 0, "comment": ""})],
 | 
			
		||||
        parsers=[
 | 
			
		||||
            result.ParserConfig(name="healthcheck", with_={"score": 1}),
 | 
			
		||||
            result.ParserConfig(name="debug", with_={"score": 1}),
 | 
			
		||||
        ],
 | 
			
		||||
    )
 | 
			
		||||
    return healthcheck_stage
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -124,9 +164,6 @@ def get_hash(immutable_files: list[str]) -> str:  # input should be a list
 | 
			
		|||
    current_file_path = Path(__file__).resolve()
 | 
			
		||||
    project_root = current_file_path.parents[2]
 | 
			
		||||
    file_path = f"{project_root}/tests/immutable_p3-test/"
 | 
			
		||||
    # file_path = f"{project_root}/tests/immutable_hteam/"
 | 
			
		||||
    # file_path = f"{project_root}/tests/immutable_hteam-test/"
 | 
			
		||||
    # file_path = f"{project_root}/tests/immutable_p3/"
 | 
			
		||||
    immutable_hash = []
 | 
			
		||||
    for i, file in enumerate(immutable_files):
 | 
			
		||||
        immutable_files[i] = file_path + file.rsplit("/", 1)[-1]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,10 @@ def get_conf_stage(
 | 
			
		|||
            with_=executor_with_config,
 | 
			
		||||
        ),
 | 
			
		||||
        parsers=(
 | 
			
		||||
            [result.Parser(name=parser, with_={}) for parser in task_stage.parsers]
 | 
			
		||||
            [
 | 
			
		||||
                result.ParserConfig(name=parser, with_={})
 | 
			
		||||
                for parser in task_stage.parsers
 | 
			
		||||
            ]
 | 
			
		||||
            if task_stage.parsers is not None
 | 
			
		||||
            else []
 | 
			
		||||
        ),
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +72,12 @@ def get_executorWithConfig(
 | 
			
		|||
                for file in copy_in_files
 | 
			
		||||
            },
 | 
			
		||||
            stdin=(
 | 
			
		||||
                result.CmdFile(content="") if "diff" not in task_stage.parsers else None
 | 
			
		||||
                result.CmdFile(content="")
 | 
			
		||||
                if (
 | 
			
		||||
                    (task_stage.parsers is not None)
 | 
			
		||||
                    and ("diff" not in task_stage.parsers)
 | 
			
		||||
                )
 | 
			
		||||
                else None
 | 
			
		||||
            ),
 | 
			
		||||
            copy_out=copy_out_files,
 | 
			
		||||
            copy_in_cached={file: file for file in cached},
 | 
			
		||||
| 
						 | 
				
			
			@ -274,9 +282,7 @@ def fix_diff(
 | 
			
		|||
                        src=f"/home/tt/.config/joj/{task_conf.task.type_}/{stdin}"
 | 
			
		||||
                        # src=f"/home/tt/.config/joj/{task_stage.path}/{stdin}"
 | 
			
		||||
                    ),
 | 
			
		||||
                    args=(
 | 
			
		||||
                        shlex.split(case_stage.command) if command is not None else None
 | 
			
		||||
                    ),
 | 
			
		||||
                    args=(shlex.split(command) if command is not None else None),
 | 
			
		||||
                    cpu_limit=cpu_limit,
 | 
			
		||||
                    clock_limit=clock_limit,
 | 
			
		||||
                    memory_limit=memory_limit,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,23 +1,15 @@
 | 
			
		|||
teaching_team = ["prof_john", "ta_alice", "ta_bob"]
 | 
			
		||||
max_size = 50.5
 | 
			
		||||
release_tags = ["v1.0", "v2.0", "final"]
 | 
			
		||||
sandbox_token = "test"
 | 
			
		||||
 | 
			
		||||
# reconfigure later
 | 
			
		||||
max_total_score = 100
 | 
			
		||||
 | 
			
		||||
# for projects
 | 
			
		||||
#groups.name = ["build", "run"]
 | 
			
		||||
#groups.max_count = [8, 5]
 | 
			
		||||
#groups.time_period_hour = [24, 24]
 | 
			
		||||
 | 
			
		||||
max_size = 50.5
 | 
			
		||||
 | 
			
		||||
# for tests
 | 
			
		||||
groups.name = ["joj", "run"]
 | 
			
		||||
groups.max_count = [1000, 1000]
 | 
			
		||||
groups.time_period_hour = [24, 24]
 | 
			
		||||
[groups]
 | 
			
		||||
name = ["joj", "run"]
 | 
			
		||||
max_count = [1000, 1000]
 | 
			
		||||
time_period_hour = [24, 24]
 | 
			
		||||
 | 
			
		||||
[files]
 | 
			
		||||
# projects
 | 
			
		||||
# required = ["README.md", "Changelog.md"]
 | 
			
		||||
required = ["README.md"]
 | 
			
		||||
immutable = [".gitignore", ".gitattributes",".gitea/workflows/push.yaml", ".gitea/workflows/release.yaml" ]
 | 
			
		||||
required = ["README.md", "Changelog.md"]
 | 
			
		||||
immutable = [".gitignore", ".gitattributes",".gitea/workflows/push.yaml", ".gitea/workflows/release.yaml"]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,22 +1,460 @@
 | 
			
		|||
# general task configuration
 | 
			
		||||
| 
					
	
	
	
	
	
	
	
	 
				
					
						张泊明518370910136
						commented  
			
		make this basic test as simple as possible, and create new test cases for each kind of stage make this basic test as simple as possible, and create new test cases for each kind of stage 
			
			
		 | 
			||||
task.name = "e2" # task name
 | 
			
		||||
task.type = "exam/e2"
 | 
			
		||||
task.name = "hw7 ex2" # task name
 | 
			
		||||
task.type = "homework/h7/e2"
 | 
			
		||||
 | 
			
		||||
release.deadline = 2024-12-30 23:59:59+08:00
 | 
			
		||||
release.stages = [ "compile" ]
 | 
			
		||||
 | 
			
		||||
[[stages]]
 | 
			
		||||
name = "[cq] Compilation"
 | 
			
		||||
command = "./tools/compile" # eg. script running cmake commands
 | 
			
		||||
files.import = [ "tools/compile", "h6/build/ex3-main.c", "h6/build/ex4-main.c", "h6/build/ex5-main.c", "h6/build/ex7-main.c" ]
 | 
			
		||||
files.export = [ "h6/build/ex2", "h6/build/ex2-asan", "h6/build/ex2-ubsan", "h6/build/ex2-msan", "h6/build/ex3", "h6/build/ex3-asan", "h6/build/ex3-ubsan", "h6/build/ex3-msan", "h6/build/ex4", "h6/build/ex4-asan", "h6/build/ex4-ubsan", "h6/build/ex4-msan", "h6/build/ex5", "h6/build/ex5-asan", "h6/build/ex5-ubsan", "h6/build/ex5-msan", "h6/build/ex6", "h6/build/ex6-asan", "h6/build/ex6-ubsan", "h6/build/ex6-msan", "h6/build/ex7", "h6/build/ex7-asan", "h6/build/ex7-ubsan", "h6/build/ex7-msan", "h6/build/ex3-main.c", "h6/build/ex4-main.c", "h6/build/ex5-main.c", "h6/build/ex7-main.c", "h6/build/compile_commands.json" ]
 | 
			
		||||
name = "healthcheck"
 | 
			
		||||
score = 1
 | 
			
		||||
 | 
			
		||||
# compile parsers ex
 | 
			
		||||
parsers = [ "result-detail", "result-status", "file" ]
 | 
			
		||||
# healthcheck parsers
 | 
			
		||||
parsers = ["healthcheck", "debug"]
 | 
			
		||||
cases0.command = "/usr/local/bin/repo-health-checker -repoSize=100"
 | 
			
		||||
case1.command = """/usr/local/bin/joint-teapot
 | 
			
		||||
                  joj3-check-env
 | 
			
		||||
                  /home/tt/.config/teapot/teapot.env"
 | 
			
		||||
                  --grading-repo-name
 | 
			
		||||
                  JOJ3-actions-examples
 | 
			
		||||
                  --group-config
 | 
			
		||||
                  joj=50:24,=100:24"""
 | 
			
		||||
case1.env = ["LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"]
 | 
			
		||||
 | 
			
		||||
[[stages]]
 | 
			
		||||
name = "Compilation"
 | 
			
		||||
command = "./tools/compile" # eg. script running cmake commands
 | 
			
		||||
files.import = [ "tools/compile" ]
 | 
			
		||||
files.export = [ "h7/build/ex2", "h7/build/ex2-asan", "h7/build/ex2-ubsan", "h7/build/ex2-msan", "h7/build/compile_commands.json" ]
 | 
			
		||||
score = 1
 | 
			
		||||
 | 
			
		||||
# compile parsers
 | 
			
		||||
parsers = [ "result-detail", "result-status" ]
 | 
			
		||||
result-status.comment = "Congratulations! Your code compiled successfully."
 | 
			
		||||
result-detail.exitstatus = true
 | 
			
		||||
result-detail.stderr = true
 | 
			
		||||
result-detail.time = false
 | 
			
		||||
result-detail.mem = false
 | 
			
		||||
result-status.forcequit = true
 | 
			
		||||
file.name = "stdout"
 | 
			
		||||
 | 
			
		||||
[[stages]]
 | 
			
		||||
name = "[cq] Filelength"
 | 
			
		||||
command = "./tools/filelength 400 300 *.cpp *.h"
 | 
			
		||||
files.import = [ "tools/filelength" ]
 | 
			
		||||
 | 
			
		||||
parsers = [ "keyword", "result-detail" ]
 | 
			
		||||
keyword.keyword = [ "max", "recommended"]
 | 
			
		||||
keyword.weight = [ 20, 10 ]
 | 
			
		||||
result-detail.exitstatus = true
 | 
			
		||||
result-detail.stdout = true
 | 
			
		||||
result-detail.time = false
 | 
			
		||||
result-detail.mem = false
 | 
			
		||||
 | 
			
		||||
[[stages]]
 | 
			
		||||
name = "[cq] Clang-tidy"
 | 
			
		||||
command = "run-clang-tidy-18 -header-filter=.* -quiet -load=/usr/local/lib/libcodequality.so -p h7/build h7/ex2.cpp"
 | 
			
		||||
files.import = [ "tests/homework/h7/.clang-tidy", "h7/build/compile_commands.json" ]
 | 
			
		||||
limit.stdout = 65
 | 
			
		||||
 | 
			
		||||
parsers = [ "clangtidy", "result-detail" ]
 | 
			
		||||
clangtidy.keyword = [ "codequality-unchecked-malloc-result", "codequality-no-global-variables", "codequality-no-header-guard", "codequality-no-fflush-stdin", "readability-function-size", "readability-duplicate-include", "readability-identifier-naming", "readability-redundant", "readability-misleading-indentation", "readability-misplaced-array-index", "cppcoreguidelines-init-variables", "bugprone-suspicious-string-compare", "google-global-names-in-headers", "clang-diagnostic", "clang-analyzer", "misc", "performance", "portability" ]
 | 
			
		||||
clangtidy.weight = [ 5, 20, 20, 20, 10, 5, 5, 5, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5]
 | 
			
		||||
result-detail.exitstatus = true
 | 
			
		||||
result-detail.stdout = true
 | 
			
		||||
result-detail.time = false
 | 
			
		||||
result-detail.mem = false
 | 
			
		||||
 | 
			
		||||
[[stages]]
 | 
			
		||||
name = "[cq] Cppcheck"
 | 
			
		||||
command = "cppcheck --template='{\"file\":\"{file}\",\"line\":{line}, \"column\":{column}, \"severity\":\"{severity}\", \"message\":\"{message}\", \"id\":\"{id}\"}' --force --enable=all --suppress=missingIncludeSystem  --quiet h7/ex2.cpp"
 | 
			
		||||
limit.stderr = 65
 | 
			
		||||
 | 
			
		||||
parsers = [ "cppcheck", "result-detail" ]
 | 
			
		||||
cppcheck.keyword = ["error", "warning", "portability", "performance", "style"]
 | 
			
		||||
cppcheck.weight = [15, 5, 5, 5, 5]
 | 
			
		||||
result-detail.exitstatus = true
 | 
			
		||||
result-detail.stderr = true
 | 
			
		||||
result-detail.time = false
 | 
			
		||||
result-detail.mem = false
 | 
			
		||||
 | 
			
		||||
[[stages]]
 | 
			
		||||
name = "[cq] Cpplint"
 | 
			
		||||
command = "cpplint --linelength=120 --filter=-legal,-readability/casting,-whitespace,-runtime/printf,-runtime/threadsafe_fn,-runtime/int,-readability/todo,-build/include_subdir,-build/header_guard,-build/include_what_you_use --recursive --exclude=build h7/ex2.cpp"
 | 
			
		||||
limit.stdout = 65
 | 
			
		||||
 | 
			
		||||
parsers = [ "cpplint", "result-detail" ]
 | 
			
		||||
cpplint.keyword = [ "runtime", "readability", "build" ]
 | 
			
		||||
cpplint.weight = [ 5, 20, 10]
 | 
			
		||||
result-detail.exitstatus = true
 | 
			
		||||
result-detail.stderr = true
 | 
			
		||||
result-detail.time = false
 | 
			
		||||
result-detail.mem = false
 | 
			
		||||
 | 
			
		||||
[[stages]]
 | 
			
		||||
name = "[joj] ex2-asan"
 | 
			
		||||
group = "run"
 | 
			
		||||
command="./h7/build/ex2-asan -a"
 | 
			
		||||
files.import = [ "h7/build/ex2-asan" ]
 | 
			
		||||
limit.mem = 91224961
 | 
			
		||||
 | 
			
		||||
parsers = [ "diff", "result-detail" ]
 | 
			
		||||
result-detail.exitstatus = true
 | 
			
		||||
result-detail.stderr = true
 | 
			
		||||
 | 
			
		||||
# will be removed as long as the name is fixed
 | 
			
		||||
case0.diff.output.score = 5
 | 
			
		||||
case0.limit.cpu = 1
 | 
			
		||||
case0.limit.mem = 91224961
 | 
			
		||||
case0.diff.output.ignorespaces = true
 | 
			
		||||
#case0.limit.stdout = 8
 | 
			
		||||
#case0.command = "./h7/build/ex2"
 | 
			
		||||
case0.in = "case0.in"
 | 
			
		||||
 | 
			
		||||
case1.diff.output.score = 5
 | 
			
		||||
case1.limit.cpu = 1
 | 
			
		||||
case1.limit.mem = 91224961
 | 
			
		||||
case1.diff.output.ignorespaces = true
 | 
			
		||||
#case1.limit.stdout = 8
 | 
			
		||||
#case1.command = "./h7/build/ex2"
 | 
			
		||||
case1.in = "case1.in"
 | 
			
		||||
 | 
			
		||||
case2.diff.output.score = 5
 | 
			
		||||
case2.limit.cpu = 1
 | 
			
		||||
case2.limit.mem = 91224961
 | 
			
		||||
case2.diff.output.ignorespaces = true
 | 
			
		||||
#case2.limit.stdout = 8
 | 
			
		||||
#case2.command = "./h7/build/ex2"
 | 
			
		||||
case2.in = "case2.in"
 | 
			
		||||
 | 
			
		||||
case3.diff.output.score = 5
 | 
			
		||||
case3.limit.cpu = 1
 | 
			
		||||
case3.limit.mem = 91224961
 | 
			
		||||
case3.diff.output.ignorespaces = true
 | 
			
		||||
#case3.limit.stdout = 8
 | 
			
		||||
#case3.command = "./h7/build/ex2"
 | 
			
		||||
case3.in = "case3.in"
 | 
			
		||||
 | 
			
		||||
case4.diff.output.score = 10
 | 
			
		||||
case4.limit.cpu = 1
 | 
			
		||||
case4.limit.mem = 91224961
 | 
			
		||||
case4.diff.output.ignorespaces = true
 | 
			
		||||
#case4.limit.stdout = 8
 | 
			
		||||
#case4.command = "./h7/build/ex2"
 | 
			
		||||
case4.in = "case4.in"
 | 
			
		||||
 | 
			
		||||
case5.diff.output.score = 10
 | 
			
		||||
case5.limit.cpu = 1
 | 
			
		||||
case5.limit.mem = 91224961
 | 
			
		||||
case5.diff.output.ignorespaces = true
 | 
			
		||||
#case5.limit.stdout = 8
 | 
			
		||||
#case5.command = "./h7/build/ex2"
 | 
			
		||||
case5.in = "case5.in"
 | 
			
		||||
 | 
			
		||||
case6.diff.output.score = 15
 | 
			
		||||
case6.limit.cpu = 1
 | 
			
		||||
case6.limit.mem = 91224961
 | 
			
		||||
case6.diff.output.ignorespaces = true
 | 
			
		||||
#case6.limit.stdout = 8
 | 
			
		||||
#case6.command = "./h7/build/ex2"
 | 
			
		||||
case6.in = "case6.in"
 | 
			
		||||
 | 
			
		||||
case7.diff.output.score = 15
 | 
			
		||||
case7.limit.cpu = 1
 | 
			
		||||
case7.limit.mem = 91224961
 | 
			
		||||
case7.diff.output.ignorespaces = true
 | 
			
		||||
#case7.limit.stdout = 8
 | 
			
		||||
#case7.command = "./h7/build/ex2"
 | 
			
		||||
case7.in = "case7.in"
 | 
			
		||||
 | 
			
		||||
case8.diff.output.score = 15
 | 
			
		||||
case8.limit.cpu = 1
 | 
			
		||||
case8.limit.mem = 91224961
 | 
			
		||||
case8.diff.output.ignorespaces = true
 | 
			
		||||
#case8.limit.stdout = 8
 | 
			
		||||
#case8.command = "./h7/build/ex2"
 | 
			
		||||
case8.in = "case8.in"
 | 
			
		||||
 | 
			
		||||
case9.diff.output.score = 15
 | 
			
		||||
case9.limit.cpu = 1
 | 
			
		||||
case9.limit.mem = 91224961
 | 
			
		||||
case9.diff.output.ignorespaces = true
 | 
			
		||||
#case9.limit.stdout = 8
 | 
			
		||||
#case9.command = "./h7/build/ex2"
 | 
			
		||||
case9.in = "case9.in"
 | 
			
		||||
 | 
			
		||||
[[stages]]
 | 
			
		||||
name = "[joj] ex2-msan"
 | 
			
		||||
group = "joj"
 | 
			
		||||
command="./h7/build/ex2-msan -a"
 | 
			
		||||
files.import = [ "h7/build/ex2-msan" ]
 | 
			
		||||
limit.mem = 91224961
 | 
			
		||||
 | 
			
		||||
parsers = [ "diff", "result-detail" ]
 | 
			
		||||
result-detail.exitstatus = true
 | 
			
		||||
result-detail.stderr = true
 | 
			
		||||
 | 
			
		||||
# will be removed as long as the name is fixed
 | 
			
		||||
case0.diff.output.score = 5
 | 
			
		||||
case0.limit.cpu = 1
 | 
			
		||||
case0.limit.mem = 91224961
 | 
			
		||||
case0.diff.output.ignorespaces = true
 | 
			
		||||
#case0.limit.stdout = 8
 | 
			
		||||
#case0.command = "./h7/build/ex2"
 | 
			
		||||
case0.in = "case0.in"
 | 
			
		||||
 | 
			
		||||
case1.diff.output.score = 5
 | 
			
		||||
case1.limit.cpu = 1
 | 
			
		||||
case1.limit.mem = 91224961
 | 
			
		||||
case1.diff.output.ignorespaces = true
 | 
			
		||||
#case1.limit.stdout = 8
 | 
			
		||||
#case1.command = "./h7/build/ex2"
 | 
			
		||||
case1.in = "case1.in"
 | 
			
		||||
 | 
			
		||||
case2.diff.output.score = 5
 | 
			
		||||
case2.limit.cpu = 1
 | 
			
		||||
case2.limit.mem = 91224961
 | 
			
		||||
case2.diff.output.ignorespaces = true
 | 
			
		||||
#case2.limit.stdout = 8
 | 
			
		||||
#case2.command = "./h7/build/ex2"
 | 
			
		||||
case2.in = "case2.in"
 | 
			
		||||
 | 
			
		||||
case3.diff.output.score = 5
 | 
			
		||||
case3.limit.cpu = 1
 | 
			
		||||
case3.limit.mem = 91224961
 | 
			
		||||
case3.diff.output.ignorespaces = true
 | 
			
		||||
#case3.limit.stdout = 8
 | 
			
		||||
#case3.command = "./h7/build/ex2"
 | 
			
		||||
case3.in = "case3.in"
 | 
			
		||||
 | 
			
		||||
case4.diff.output.score = 10
 | 
			
		||||
case4.limit.cpu = 1
 | 
			
		||||
case4.limit.mem = 91224961
 | 
			
		||||
case4.diff.output.ignorespaces = true
 | 
			
		||||
#case4.limit.stdout = 8
 | 
			
		||||
#case4.command = "./h7/build/ex2"
 | 
			
		||||
case4.in = "case4.in"
 | 
			
		||||
 | 
			
		||||
case5.diff.output.score = 10
 | 
			
		||||
case5.limit.cpu = 1
 | 
			
		||||
case5.limit.mem = 91224961
 | 
			
		||||
case5.diff.output.ignorespaces = true
 | 
			
		||||
#case5.limit.stdout = 8
 | 
			
		||||
#case5.command = "./h7/build/ex2"
 | 
			
		||||
case5.in = "case5.in"
 | 
			
		||||
 | 
			
		||||
case6.diff.output.score = 15
 | 
			
		||||
case6.limit.cpu = 1
 | 
			
		||||
case6.limit.mem = 91224961
 | 
			
		||||
case6.diff.output.ignorespaces = true
 | 
			
		||||
#case6.limit.stdout = 8
 | 
			
		||||
#case6.command = "./h7/build/ex2"
 | 
			
		||||
case6.in = "case6.in"
 | 
			
		||||
 | 
			
		||||
case7.diff.output.score = 15
 | 
			
		||||
case7.limit.cpu = 1
 | 
			
		||||
case7.limit.mem = 91224961
 | 
			
		||||
case7.diff.output.ignorespaces = true
 | 
			
		||||
#case7.limit.stdout = 8
 | 
			
		||||
#case7.command = "./h7/build/ex2"
 | 
			
		||||
case7.in = "case7.in"
 | 
			
		||||
 | 
			
		||||
case8.diff.output.score = 15
 | 
			
		||||
case8.limit.cpu = 1
 | 
			
		||||
case8.limit.mem = 91224961
 | 
			
		||||
case8.diff.output.ignorespaces = true
 | 
			
		||||
#case8.limit.stdout = 8
 | 
			
		||||
#case8.command = "./h7/build/ex2"
 | 
			
		||||
case8.in = "case8.in"
 | 
			
		||||
 | 
			
		||||
case9.diff.output.score = 15
 | 
			
		||||
case9.limit.cpu = 1
 | 
			
		||||
case9.limit.mem = 91224961
 | 
			
		||||
case9.diff.output.ignorespaces = true
 | 
			
		||||
#case9.limit.stdout = 8
 | 
			
		||||
#case9.command = "./h7/build/ex2"
 | 
			
		||||
case9.in = "case9.in"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[[stages]]
 | 
			
		||||
name = "[joj] ex2-ubsan"
 | 
			
		||||
command="./h7/build/ex2-ubsan -a"
 | 
			
		||||
files.import = [ "h7/build/ex2-ubsan" ]
 | 
			
		||||
 | 
			
		||||
parsers = [ "diff", "result-detail" ]
 | 
			
		||||
result-detail.exitstatus = true
 | 
			
		||||
result-detail.stderr = true
 | 
			
		||||
 | 
			
		||||
# will be removed as long as the name is fixed
 | 
			
		||||
case0.diff.output.score = 5
 | 
			
		||||
case0.limit.cpu = 1
 | 
			
		||||
case0.limit.mem = 91224961
 | 
			
		||||
case0.diff.output.ignorespaces = true
 | 
			
		||||
#case0.limit.stdout = 8
 | 
			
		||||
#case0.command = "./h7/build/ex2"
 | 
			
		||||
case0.in = "case0.in"
 | 
			
		||||
 | 
			
		||||
case1.diff.output.score = 5
 | 
			
		||||
case1.limit.cpu = 1
 | 
			
		||||
case1.limit.mem = 91224961
 | 
			
		||||
case1.diff.output.ignorespaces = true
 | 
			
		||||
#case1.limit.stdout = 8
 | 
			
		||||
#case1.command = "./h7/build/ex2"
 | 
			
		||||
case1.in = "case1.in"
 | 
			
		||||
 | 
			
		||||
case2.diff.output.score = 5
 | 
			
		||||
case2.limit.cpu = 1
 | 
			
		||||
case2.limit.mem = 91224961
 | 
			
		||||
case2.diff.output.ignorespaces = true
 | 
			
		||||
#case2.limit.stdout = 8
 | 
			
		||||
#case2.command = "./h7/build/ex2"
 | 
			
		||||
case2.in = "case2.in"
 | 
			
		||||
 | 
			
		||||
case3.diff.output.score = 5
 | 
			
		||||
case3.limit.cpu = 1
 | 
			
		||||
case3.limit.mem = 91224961
 | 
			
		||||
case3.diff.output.ignorespaces = true
 | 
			
		||||
#case3.limit.stdout = 8
 | 
			
		||||
#case3.command = "./h7/build/ex2"
 | 
			
		||||
case3.in = "case3.in"
 | 
			
		||||
 | 
			
		||||
case4.diff.output.score = 10
 | 
			
		||||
case4.limit.cpu = 1
 | 
			
		||||
case4.limit.mem = 91224961
 | 
			
		||||
case4.diff.output.ignorespaces = true
 | 
			
		||||
#case4.limit.stdout = 8
 | 
			
		||||
#case4.command = "./h7/build/ex2"
 | 
			
		||||
case4.in = "case4.in"
 | 
			
		||||
 | 
			
		||||
case5.diff.output.score = 10
 | 
			
		||||
case5.limit.cpu = 1
 | 
			
		||||
case5.limit.mem = 91224961
 | 
			
		||||
case5.diff.output.ignorespaces = true
 | 
			
		||||
#case5.limit.stdout = 8
 | 
			
		||||
#case5.command = "./h7/build/ex2"
 | 
			
		||||
case5.in = "case5.in"
 | 
			
		||||
 | 
			
		||||
case6.diff.output.score = 15
 | 
			
		||||
case6.limit.cpu = 1
 | 
			
		||||
case6.limit.mem = 91224961
 | 
			
		||||
case6.diff.output.ignorespaces = true
 | 
			
		||||
#case6.limit.stdout = 8
 | 
			
		||||
#case6.command = "./h7/build/ex2"
 | 
			
		||||
case6.in = "case6.in"
 | 
			
		||||
 | 
			
		||||
case7.diff.output.score = 15
 | 
			
		||||
case7.limit.cpu = 1
 | 
			
		||||
case7.limit.mem = 91224961
 | 
			
		||||
case7.diff.output.ignorespaces = true
 | 
			
		||||
#case7.limit.stdout = 8
 | 
			
		||||
#case7.command = "./h7/build/ex2"
 | 
			
		||||
case7.in = "case7.in"
 | 
			
		||||
 | 
			
		||||
case8.diff.output.score = 15
 | 
			
		||||
case8.limit.cpu = 1
 | 
			
		||||
case8.limit.mem = 91224961
 | 
			
		||||
case8.diff.output.ignorespaces = true
 | 
			
		||||
#case8.limit.stdout = 8
 | 
			
		||||
#case8.command = "./h7/build/ex2"
 | 
			
		||||
case8.in = "case8.in"
 | 
			
		||||
 | 
			
		||||
case9.diff.output.score = 15
 | 
			
		||||
case9.limit.cpu = 1
 | 
			
		||||
case9.limit.mem = 91224961
 | 
			
		||||
case9.diff.output.ignorespaces = true
 | 
			
		||||
#case9.limit.stdout = 8
 | 
			
		||||
#case9.command = "./h7/build/ex2"
 | 
			
		||||
case9.in = "case9.in"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[[stages]]
 | 
			
		||||
name = "[joj] ex2"
 | 
			
		||||
group = "joj"
 | 
			
		||||
command="./h7/build/ex2"
 | 
			
		||||
files.import = [ "h7/build/ex2" ]
 | 
			
		||||
score = 10
 | 
			
		||||
 | 
			
		||||
parsers = [ "diff", "result-detail" ]
 | 
			
		||||
result-detail.exitstatus = true
 | 
			
		||||
result-detail.stderr = true
 | 
			
		||||
result-status.forcequit = true
 | 
			
		||||
 | 
			
		||||
# will be removed as long as the name is fixed
 | 
			
		||||
case0.diff.output.score = 5
 | 
			
		||||
case0.limit.cpu = 1
 | 
			
		||||
case0.limit.mem = 91224961
 | 
			
		||||
case0.diff.output.ignorespaces = true
 | 
			
		||||
#case0.limit.stdout = 8
 | 
			
		||||
#case0.command = "./h7/build/ex2"
 | 
			
		||||
case0.in = "case0.in"
 | 
			
		||||
 | 
			
		||||
case1.diff.output.score = 5
 | 
			
		||||
case1.limit.cpu = 1
 | 
			
		||||
case1.limit.mem = 91224961
 | 
			
		||||
case1.diff.output.ignorespaces = true
 | 
			
		||||
#case1.limit.stdout = 8
 | 
			
		||||
#case1.command = "./h7/build/ex2"
 | 
			
		||||
case1.in = "case1.in"
 | 
			
		||||
 | 
			
		||||
case2.diff.output.score = 5
 | 
			
		||||
case2.limit.cpu = 1
 | 
			
		||||
case2.limit.mem = 91224961
 | 
			
		||||
case2.diff.output.ignorespaces = true
 | 
			
		||||
#case2.limit.stdout = 8
 | 
			
		||||
#case2.command = "./h7/build/ex2"
 | 
			
		||||
case2.in = "case2.in"
 | 
			
		||||
 | 
			
		||||
case3.diff.output.score = 5
 | 
			
		||||
case3.limit.cpu = 1
 | 
			
		||||
case3.limit.mem = 91224961
 | 
			
		||||
case3.diff.output.ignorespaces = true
 | 
			
		||||
#case3.limit.stdout = 8
 | 
			
		||||
#case3.command = "./h7/build/ex2"
 | 
			
		||||
case3.in = "case3.in"
 | 
			
		||||
 | 
			
		||||
case4.diff.output.score = 10
 | 
			
		||||
case4.limit.cpu = 1
 | 
			
		||||
case4.limit.mem = 91224961
 | 
			
		||||
case4.diff.output.ignorespaces = true
 | 
			
		||||
#case4.limit.stdout = 8
 | 
			
		||||
#case4.command = "./h7/build/ex2"
 | 
			
		||||
case4.in = "case4.in"
 | 
			
		||||
 | 
			
		||||
case5.diff.output.score = 10
 | 
			
		||||
case5.limit.cpu = 1
 | 
			
		||||
case5.limit.mem = 91224961
 | 
			
		||||
case5.diff.output.ignorespaces = true
 | 
			
		||||
#case5.limit.stdout = 8
 | 
			
		||||
#case5.command = "./h7/build/ex2"
 | 
			
		||||
case5.in = "case5.in"
 | 
			
		||||
 | 
			
		||||
case6.diff.output.score = 15
 | 
			
		||||
case6.limit.cpu = 1
 | 
			
		||||
case6.limit.mem = 91224961
 | 
			
		||||
case6.diff.output.ignorespaces = true
 | 
			
		||||
#case6.limit.stdout = 8
 | 
			
		||||
#case6.command = "./h7/build/ex2"
 | 
			
		||||
case6.in = "case6.in"
 | 
			
		||||
 | 
			
		||||
case7.diff.output.score = 15
 | 
			
		||||
case7.limit.cpu = 1
 | 
			
		||||
case7.limit.mem = 91224961
 | 
			
		||||
case7.diff.output.ignorespaces = true
 | 
			
		||||
#case7.limit.stdout = 8
 | 
			
		||||
#case7.command = "./h7/build/ex2"
 | 
			
		||||
case7.in = "case7.in"
 | 
			
		||||
 | 
			
		||||
case8.diff.output.score = 15
 | 
			
		||||
case8.limit.cpu = 1
 | 
			
		||||
case8.limit.mem = 91224961
 | 
			
		||||
case8.diff.output.ignorespaces = true
 | 
			
		||||
#case8.limit.stdout = 8
 | 
			
		||||
#case8.command = "./h7/build/ex2"
 | 
			
		||||
case8.in = "case8.in"
 | 
			
		||||
 | 
			
		||||
case9.diff.output.score = 15
 | 
			
		||||
case9.limit.cpu = 1
 | 
			
		||||
case9.limit.mem = 91224961
 | 
			
		||||
case9.diff.output.ignorespaces = true
 | 
			
		||||
#case9.limit.stdout = 8
 | 
			
		||||
#case9.command = "./h7/build/ex2"
 | 
			
		||||
case9.in = "case9.in"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,4 +16,4 @@ jobs:
 | 
			
		|||
          fetch-depth: 0
 | 
			
		||||
      - name: run joj3
 | 
			
		||||
        run: |
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/homework                    
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/homework
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,4 +18,4 @@ jobs:
 | 
			
		|||
          fetch-depth: 0
 | 
			
		||||
      - name: run joj3
 | 
			
		||||
        run: |
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/homework" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"          
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/homework" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,4 +16,4 @@ jobs:
 | 
			
		|||
          fetch-depth: 0
 | 
			
		||||
      - name: run joj3
 | 
			
		||||
        run: |
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/homework          
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/homework
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,5 +16,4 @@ jobs:
 | 
			
		|||
          fetch-depth: 0
 | 
			
		||||
      - name: run joj3
 | 
			
		||||
        run: |
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/projects/p3                              
 | 
			
		||||
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/projects/p3
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,5 +18,4 @@ jobs:
 | 
			
		|||
          fetch-depth: 0
 | 
			
		||||
      - name: run joj3
 | 
			
		||||
        run: |
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/projects/p3" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"                    
 | 
			
		||||
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/projects/p3" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,5 +16,4 @@ jobs:
 | 
			
		|||
          fetch-depth: 0
 | 
			
		||||
      - name: run joj3
 | 
			
		||||
        run: |
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/projects/p3                              
 | 
			
		||||
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/projects/p3
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,5 +18,4 @@ jobs:
 | 
			
		|||
          fetch-depth: 0
 | 
			
		||||
      - name: run joj3
 | 
			
		||||
        run: |
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/projects/p3" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"                    
 | 
			
		||||
 | 
			
		||||
          sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/projects/p3" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user
	
Unify the use of
listorListeverywhere as we only support Python >=3.9 now.ok