fix: healthcheck & update teapot poststage
This commit is contained in:
		
							parent
							
								
									47c46755e6
								
							
						
					
					
						commit
						c67dd32cf2
					
				|  | @ -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 | ||||
| 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