dev #10
							
								
								
									
										22
									
								
								README.md
									
									
									
									
									
								
							
							
						
						|  | @ -16,3 +16,25 @@ | ||||||
| 4. Install deps by `pdm install && pdm run pre-commit install` | 4. Install deps by `pdm install && pdm run pre-commit install` | ||||||
| 5. Run the cli app by `pdm run app --help` | 5. Run the cli app by `pdm run app --help` | ||||||
| 6. Check other commands or scripts with `pdm run --list` | 6. Check other commands or scripts with `pdm run --list` | ||||||
|  | 
 | ||||||
|  | ## How to use? | ||||||
|  | 
 | ||||||
|  | - `joj3-config-generator convert` function is now supported, currently support one argument as input, it indicates the **convert root** | ||||||
|  |   - default value on the server can be given as `/home/tt/.config/joj` | ||||||
|  |   - **NOTE:** the user should ensure that the ideal `repo.toml` file is in the sub-directory of the **convert root** | ||||||
|  |   - the intended immutable files should be placed at a sub-directory named `immutable_files` at same position as the `repo.toml` file | ||||||
|  | 
 | ||||||
|  | ```shell | ||||||
|  | $ tree . | ||||||
|  | . | ||||||
|  | |- immutable_files | ||||||
|  | | |-- push.yaml | ||||||
|  | | |-- release.yaml | ||||||
|  | |-- repo.toml | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | - sample command on the server | ||||||
|  | 
 | ||||||
|  | ```shell | ||||||
|  | joj3-config-generator convert /home/tt/.config/joj | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | @ -1,93 +1,41 @@ | ||||||
| from typing import List | import os | ||||||
|  | from typing import Dict | ||||||
| 
 | 
 | ||||||
| from joj3_config_generator.models import joj1, repo, result, task | from joj3_config_generator.models import joj1, repo, result, task | ||||||
|  | from joj3_config_generator.models.const import CACHE_ROOT, JOJ3_CONFIG_ROOT | ||||||
|  | from joj3_config_generator.processers.repo import ( | ||||||
|  |     get_health_check_stage, | ||||||
|  |     get_teapot_stage, | ||||||
|  | ) | ||||||
|  | from joj3_config_generator.processers.task import get_conf_stage | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # FIXME: LLM generated convert function, only for demostration |  | ||||||
| def convert(repo_conf: repo.Config, task_conf: task.Config) -> result.Config: | def convert(repo_conf: repo.Config, task_conf: task.Config) -> result.Config: | ||||||
|     # Create the base ResultConf object |     # Create the base ResultConf object | ||||||
|     result_conf = result.Config( |     result_conf = result.Config( | ||||||
|         name=task_conf.task, |         name=task_conf.task.name, | ||||||
|         log_path=f"{task_conf.task.replace(' ', '_')}.log", |         # exact folder difference specified by type | ||||||
|         expire_unix_timestamp=( |         log_path=str(CACHE_ROOT / "joj3" / f"{task_conf.task.type_}.log"), | ||||||
|             int(task_conf.release.deadline.timestamp()) |         expire_unix_timestamp=int(task_conf.release.end_time.timestamp()), | ||||||
|             if task_conf.release.deadline |         effective_unix_timestamp=int(task_conf.release.begin_time.timestamp()), | ||||||
|             else -1 |         actor_csv_path=str(JOJ3_CONFIG_ROOT / "students.csv"),  # students.csv position | ||||||
|         ), |         max_total_score=repo_conf.max_total_score, | ||||||
|         stage=result.Stage(stages=[], sandbox_token=repo_conf.sandbox_token), |         stage=result.Stage(sandbox_token=repo_conf.sandbox_token), | ||||||
|         teapot=result.Teapot(), |  | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|  |     current_test = os.environ.get("PYTEST_CURRENT_TEST") is not None | ||||||
|  |     # Construct health check stage | ||||||
|  |     if not repo_conf.force_skip_health_check_on_test or not current_test: | ||||||
|  |         result_conf.stage.stages.append(get_health_check_stage(repo_conf)) | ||||||
|  |     cached: Dict[str, None] = {} | ||||||
|     # Convert each stage in the task configuration |     # Convert each stage in the task configuration | ||||||
|     for task_stage in task_conf.stages: |     for task_stage in task_conf.stages: | ||||||
|         executor_with_config = result.ExecutorWith( |         result_conf.stage.stages.append(get_conf_stage(task_conf, task_stage, cached)) | ||||||
|             default=result.Cmd( |     if not repo_conf.force_skip_teapot_on_test or not current_test: | ||||||
|                 args=task_stage.command.split(), |         result_conf.stage.post_stages.append(get_teapot_stage(repo_conf)) | ||||||
|                 copy_in={ |  | ||||||
|                     file: result.LocalFile(src=file) |  | ||||||
|                     for file in task_stage.files.import_ |  | ||||||
|                 }, |  | ||||||
|                 copy_out_cached=task_stage.files.export, |  | ||||||
|             ), |  | ||||||
|             cases=[],  # You can add cases if needed |  | ||||||
|         ) |  | ||||||
|         conf_stage = result.StageDetail( |  | ||||||
|             name=task_stage.name, |  | ||||||
|             group=task_conf.task, |  | ||||||
|             executor=result.Executor( |  | ||||||
|                 name="sandbox", |  | ||||||
|                 with_=executor_with_config, |  | ||||||
|             ), |  | ||||||
|             parsers=[ |  | ||||||
|                 result.Parser(name=parser, with_={}) for parser in task_stage.parsers |  | ||||||
|             ], |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
|         if "result-detail" in task_stage.parsers: |  | ||||||
|             result_detail_parser = next( |  | ||||||
|                 p for p in conf_stage.parsers if p.name == "result-detail" |  | ||||||
|             ) |  | ||||||
|             result_detail_parser.with_.update(task_stage.result_detail) |  | ||||||
| 
 |  | ||||||
|         result_conf.stage.stages.append(conf_stage) |  | ||||||
| 
 | 
 | ||||||
|     return result_conf |     return result_conf | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # FIXME: LLM generated convert function, only for demostration |  | ||||||
| def convert_joj1(joj1_conf: joj1.Config) -> task.Config: | def convert_joj1(joj1_conf: joj1.Config) -> task.Config: | ||||||
|     stages = [] |     return task.Config() | ||||||
|     for language in joj1_conf.languages: |  | ||||||
|         # Here you might want to create a stage for each language |  | ||||||
|         # 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=[]) |  | ||||||
|         # Score can be derived from the first case or set to a default |  | ||||||
|         score = 0 |  | ||||||
|         parsers: List[str] = []  # Define parsers if applicable |  | ||||||
|         if joj1_conf.cases: |  | ||||||
|             score = sum( |  | ||||||
|                 case.score for case in joj1_conf.cases |  | ||||||
|             )  # Sum scores for all cases |  | ||||||
|         # Creating a stage for each language |  | ||||||
|         stages.append( |  | ||||||
|             task.Stage( |  | ||||||
|                 name=language.language, |  | ||||||
|                 command=command, |  | ||||||
|                 files=files, |  | ||||||
|                 score=score, |  | ||||||
|                 parsers=parsers, |  | ||||||
|                 result_detail=task.ParserResultDetail(),  # You can customize this further if needed |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|     # Assuming no deadline is provided in `joj1`, you can set it accordingly |  | ||||||
|     release_deadline = ( |  | ||||||
|         None  # Placeholder for future implementation if deadlines are defined |  | ||||||
|     ) |  | ||||||
| 
 |  | ||||||
|     return task.Config( |  | ||||||
|         task=joj1_conf.languages[0].language if joj1_conf.languages else "Unnamed Task", |  | ||||||
|         release=task.Release(deadline=release_deadline), |  | ||||||
|         stages=stages, |  | ||||||
|     ) |  | ||||||
|  |  | ||||||
							
								
								
									
										39
									
								
								joj3_config_generator/load.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,39 @@ | ||||||
|  | from pathlib import Path | ||||||
|  | from typing import Dict, Tuple | ||||||
|  | 
 | ||||||
|  | import inquirer | ||||||
|  | import rtoml | ||||||
|  | import yaml | ||||||
|  | 
 | ||||||
|  | from joj3_config_generator.models import joj1, repo, task | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def load_joj3_toml_answers() -> Dict[str, str]: | ||||||
|  |     questions = [ | ||||||
|  |         inquirer.List( | ||||||
|  |             "size", | ||||||
|  |             message="What size do you need?", | ||||||
|  |             choices=["Jumbo", "Large", "Standard", "Medium", "Small", "Micro"], | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
|  |     answers = inquirer.prompt(questions) | ||||||
|  |     return answers | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def load_joj1_yaml(yaml_path: Path) -> joj1.Config: | ||||||
|  |     joj1_obj = yaml.safe_load(yaml_path.read_text()) | ||||||
|  |     return joj1.Config(**joj1_obj) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def load_joj3_toml( | ||||||
|  |     root_path: Path, repo_toml_path: Path, task_toml_path: Path | ||||||
|  | ) -> Tuple[repo.Config, task.Config]: | ||||||
|  |     repo_obj = rtoml.loads(repo_toml_path.read_text()) | ||||||
|  |     task_obj = rtoml.loads(task_toml_path.read_text()) | ||||||
|  |     repo_conf = repo.Config(**repo_obj) | ||||||
|  |     repo_conf.root = root_path | ||||||
|  |     repo_conf.path = repo_toml_path.relative_to(root_path) | ||||||
|  |     task_conf = task.Config(**task_obj) | ||||||
|  |     task_conf.root = root_path | ||||||
|  |     task_conf.path = task_toml_path.relative_to(root_path) | ||||||
|  |     return repo_conf, task_conf | ||||||
|  | @ -1,48 +1,44 @@ | ||||||
| import json | import json | ||||||
| 
					
					jon-lee marked this conversation as resolved
					
				 | |||||||
| from pathlib import Path | from pathlib import Path | ||||||
| 
 | 
 | ||||||
| import inquirer |  | ||||||
| import rtoml | import rtoml | ||||||
| import typer | import typer | ||||||
| import yaml |  | ||||||
| from typing_extensions import Annotated | from typing_extensions import Annotated | ||||||
| 
 | 
 | ||||||
| from joj3_config_generator.convert import convert as convert_conf | from joj3_config_generator.convert import convert as convert_conf | ||||||
| from joj3_config_generator.convert import convert_joj1 as convert_joj1_conf | from joj3_config_generator.convert import convert_joj1 as convert_joj1_conf | ||||||
| from joj3_config_generator.models import joj1, repo, task | from joj3_config_generator.load import ( | ||||||
|  |     load_joj1_yaml, | ||||||
|  |     load_joj3_toml, | ||||||
|  |     load_joj3_toml_answers, | ||||||
|  | ) | ||||||
|  | from joj3_config_generator.models.const import JOJ3_CONFIG_ROOT | ||||||
| from joj3_config_generator.utils.logger import logger | from joj3_config_generator.utils.logger import logger | ||||||
| 
 | 
 | ||||||
| app = typer.Typer(add_completion=False) | app = typer.Typer(add_completion=False) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @app.command() | @app.command() | ||||||
| def create(toml: typer.FileTextWrite) -> None: | def create(toml_path: Path) -> None: | ||||||
|     """ |     """ | ||||||
|     Create a new JOJ3 toml config file |     Create a new JOJ3 toml config file | ||||||
|     """ |     """ | ||||||
|     logger.info("Creating") |     logger.info(f"Creating toml file {toml_path}") | ||||||
|     questions = [ |     answers = load_joj3_toml_answers() | ||||||
|         inquirer.List( |     logger.debug(f"Got answers: {answers}") | ||||||
|             "size", |     toml_path.write_text(rtoml.dumps({})) | ||||||
|             message="What size do you need?", |  | ||||||
|             choices=["Jumbo", "Large", "Standard", "Medium", "Small", "Micro"], |  | ||||||
|         ), |  | ||||||
|     ] |  | ||||||
|     answers = inquirer.prompt(questions) |  | ||||||
|     logger.info(answers) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @app.command() | @app.command() | ||||||
| def convert_joj1(yaml_file: typer.FileText, toml_file: typer.FileTextWrite) -> None: | def convert_joj1(yaml_path: Path, toml_path: Path) -> None: | ||||||
|     """ |     """ | ||||||
|     Convert a JOJ1 yaml config file to JOJ3 toml config file |     Convert a JOJ1 yaml config file to JOJ3 toml config file | ||||||
|     """ |     """ | ||||||
|     logger.info(f"Converting yaml file {yaml_file}") |     logger.info(f"Converting yaml file {yaml_path}") | ||||||
|     joj1_obj = yaml.safe_load(yaml_file.read()) |     joj1_model = load_joj1_yaml(yaml_path) | ||||||
|     joj1_model = joj1.Config(**joj1_obj) |  | ||||||
|     task_model = convert_joj1_conf(joj1_model) |     task_model = convert_joj1_conf(joj1_model) | ||||||
|     result_dict = task_model.model_dump(by_alias=True) |     result_dict = task_model.model_dump(mode="json", by_alias=True, exclude_none=True) | ||||||
|     toml_file.write(rtoml.dumps(result_dict)) |     toml_path.write_text(rtoml.dumps(result_dict)) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @app.command() | @app.command() | ||||||
|  | @ -50,8 +46,7 @@ def convert( | ||||||
|     root: Annotated[ |     root: Annotated[ | ||||||
|         Path, |         Path, | ||||||
|         typer.Argument( |         typer.Argument( | ||||||
|             help="root directory of config files, " |             help=f"root directory of config files, located at {JOJ3_CONFIG_ROOT} in JTC" | ||||||
|             "located at /home/tt/.config/joj in JTC" |  | ||||||
|         ), |         ), | ||||||
|     ] = Path(".") |     ] = Path(".") | ||||||
| ) -> None: | ) -> None: | ||||||
|  | @ -60,9 +55,7 @@ def convert( | ||||||
|     """ |     """ | ||||||
|     logger.info(f"Converting files in {root.absolute()}") |     logger.info(f"Converting files in {root.absolute()}") | ||||||
|     for repo_toml_path in root.glob("**/repo.toml"): |     for repo_toml_path in root.glob("**/repo.toml"): | ||||||
|         repo_path = repo_toml_path.parent |         for task_toml_path in repo_toml_path.parent.glob("**/*.toml"): | ||||||
|         repo_obj = rtoml.loads(repo_toml_path.read_text()) |  | ||||||
|         for task_toml_path in repo_path.glob("**/*.toml"): |  | ||||||
|             if repo_toml_path == task_toml_path: |             if repo_toml_path == task_toml_path: | ||||||
|                 continue |                 continue | ||||||
|             toml_name = task_toml_path.name.removesuffix(".toml") |             toml_name = task_toml_path.name.removesuffix(".toml") | ||||||
|  | @ -70,15 +63,11 @@ def convert( | ||||||
|             logger.info( |             logger.info( | ||||||
|                 f"Converting {repo_toml_path} & {task_toml_path} to {result_json_path}" |                 f"Converting {repo_toml_path} & {task_toml_path} to {result_json_path}" | ||||||
|             ) |             ) | ||||||
|             task_obj = rtoml.loads(task_toml_path.read_text()) |             repo_conf, task_conf = load_joj3_toml(root, repo_toml_path, task_toml_path) | ||||||
|             repo_conf = repo.Config(**repo_obj) |  | ||||||
|             repo_conf.root = root |  | ||||||
|             repo_conf.path = repo_toml_path.relative_to(root) |  | ||||||
|             task_conf = task.Config(**task_obj) |  | ||||||
|             task_conf.root = root |  | ||||||
|             task_conf.path = task_toml_path.relative_to(root) |  | ||||||
|             result_model = convert_conf(repo_conf, task_conf) |             result_model = convert_conf(repo_conf, task_conf) | ||||||
|             result_dict = result_model.model_dump(by_alias=True, exclude_none=True) |             result_dict = result_model.model_dump( | ||||||
|  |                 mode="json", by_alias=True, exclude_none=True | ||||||
|  |             ) | ||||||
|             with result_json_path.open("w") as result_file: |             with result_json_path.open("w") as result_file: | ||||||
|                 json.dump(result_dict, result_file, ensure_ascii=False, indent=4) |                 json.dump(result_dict, result_file, ensure_ascii=False, indent=4) | ||||||
|                 result_file.write("\n") |                 result_file.write("\n") | ||||||
|  |  | ||||||
							
								
								
									
										19
									
								
								joj3_config_generator/models/common.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,19 @@ | ||||||
|  | from typing import Union | ||||||
|  | 
 | ||||||
|  | import humanfriendly | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Memory(int): | ||||||
|  |     def __new__(cls, value: Union[str, int]) -> "Memory": | ||||||
|  |         if isinstance(value, str): | ||||||
|  |             parsed = humanfriendly.parse_size(value, binary=True) | ||||||
|  |             return super().__new__(cls, parsed) | ||||||
|  |         return super().__new__(cls, value) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Time(int): | ||||||
|  |     def __new__(cls, value: Union[str, int]) -> "Time": | ||||||
|  |         if isinstance(value, str): | ||||||
|  |             parsed = humanfriendly.parse_timespan(value) * 1_000_000_000  # ns | ||||||
|  |             return super().__new__(cls, round(parsed)) | ||||||
|  |         return super().__new__(cls, value) | ||||||
							
								
								
									
										11
									
								
								joj3_config_generator/models/const.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,11 @@ | ||||||
|  | from pathlib import Path | ||||||
|  | 
 | ||||||
|  | from joj3_config_generator.models.common import Memory, Time | ||||||
|  | 
 | ||||||
|  | DEFAULT_CPU_LIMIT = Time("1s") | ||||||
|  | DEFAULT_MEMORY_LIMIT = Memory("128m") | ||||||
|  | DEFAULT_FILE_LIMIT = Memory("32m") | ||||||
|  | 
 | ||||||
|  | JOJ3_CONFIG_ROOT = Path("/home/tt/.config/joj") | ||||||
|  | TEAPOT_CONFIG_ROOT = Path("/home/tt/.config/teapot") | ||||||
|  | CACHE_ROOT = Path("/home/tt/.cache") | ||||||
|  | @ -1,21 +1,29 @@ | ||||||
|  | import socket | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
| from typing import List, Optional | from typing import List | ||||||
| 
 | 
 | ||||||
| from pydantic import BaseModel, Field | from pydantic import BaseModel, Field | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Files(BaseModel): | class Files(BaseModel): | ||||||
|     whitelist_patterns: List[str] |     required: List[str] = [] | ||||||
|     whitelist_file: Optional[str] |     immutable: List[str] = [] | ||||||
|     required: List[str] | 
 | ||||||
|     immutable: List[str] | 
 | ||||||
|  | class Groups(BaseModel): | ||||||
|  |     name: List[str] = [] | ||||||
|  |     max_count: List[int] = [] | ||||||
|  |     time_period_hour: List[int] = [] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Config(BaseModel): | class Config(BaseModel): | ||||||
|  |     max_size: float = Field(10, ge=0) | ||||||
|  |     files: Files = Files() | ||||||
|  |     sandbox_token: str = Field("") | ||||||
|  |     max_total_score: int = Field(100) | ||||||
|  |     force_skip_health_check_on_test: bool = False | ||||||
|  |     force_skip_teapot_on_test: bool = False | ||||||
|  |     groups: Groups = Groups() | ||||||
|     root: Path = Path(".") |     root: Path = Path(".") | ||||||
|     path: Path = Path("repo.toml") |     path: Path = Path("repo.toml") | ||||||
|     teaching_team: List[str] |     grading_repo_name: str = f"{socket.gethostname().split('-')[0]}-joj" | ||||||
|     max_size: float = Field(..., ge=0) |  | ||||||
|     release_tags: List[str] |  | ||||||
|     files: Files |  | ||||||
|     sandbox_token: str |  | ||||||
|  |  | ||||||
|  | @ -1,6 +1,12 @@ | ||||||
| from typing import Any, Dict, List, Optional, Union | from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union | ||||||
| 
 | 
 | ||||||
| from pydantic import BaseModel, Field | from pydantic import BaseModel, ConfigDict, Field, field_validator | ||||||
|  | 
 | ||||||
|  | from joj3_config_generator.models.const import ( | ||||||
|  |     DEFAULT_CPU_LIMIT, | ||||||
|  |     DEFAULT_FILE_LIMIT, | ||||||
|  |     DEFAULT_MEMORY_LIMIT, | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class LocalFile(BaseModel): | class LocalFile(BaseModel): | ||||||
|  | @ -17,7 +23,7 @@ class PreparedFile(BaseModel): | ||||||
| 
 | 
 | ||||||
| class Collector(BaseModel): | class Collector(BaseModel): | ||||||
|     name: str |     name: str | ||||||
|     max: int |     max: int = DEFAULT_FILE_LIMIT | ||||||
|     pipe: bool = True |     pipe: bool = True | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -33,27 +39,26 @@ class StreamOut(BaseModel): | ||||||
|     stream_out: bool = Field(..., alias="streamOut") |     stream_out: bool = Field(..., alias="streamOut") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| InputFile = Union[LocalFile | MemoryFile | PreparedFile | Symlink] | InputFile = Union[LocalFile, MemoryFile, PreparedFile, Symlink] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Cmd(BaseModel): | class Cmd(BaseModel): | ||||||
|     args: List[str] |     args: List[str] = [] | ||||||
|     env: List[str] = [] |     env: List[str] = [] | ||||||
|     stdin: Optional[Union[InputFile | StreamIn]] = None |     stdin: Union[InputFile, StreamIn] = MemoryFile(content="") | ||||||
|     stdout: Optional[Union[Collector | StreamOut]] = None |     stdout: Union[Collector, StreamOut] = Collector(name="stdout") | ||||||
|     stderr: Optional[Union[Collector | StreamOut]] = None |     stderr: Union[Collector, StreamOut] = Collector(name="stderr") | ||||||
|     cpu_limit: int = Field(0, serialization_alias="cpuLimit") |     cpu_limit: int = Field(DEFAULT_CPU_LIMIT, serialization_alias="cpuLimit") | ||||||
|     real_cpu_limit: int = Field(0, serialization_alias="realCpuLimit") |     clock_limit: int = Field(2 * DEFAULT_CPU_LIMIT, serialization_alias="clockLimit") | ||||||
|     clock_limit: int = Field(0, serialization_alias="clockLimit") |     memory_limit: int = Field(DEFAULT_MEMORY_LIMIT, serialization_alias="memoryLimit") | ||||||
|     memory_limit: int = Field(0, serialization_alias="memoryLimit") |  | ||||||
|     stack_limit: int = Field(0, serialization_alias="stackLimit") |     stack_limit: int = Field(0, serialization_alias="stackLimit") | ||||||
|     proc_limit: int = Field(0, serialization_alias="procLimit") |     proc_limit: int = Field(50, serialization_alias="procLimit") | ||||||
|     cpu_rate_limit: int = Field(0, serialization_alias="cpuRateLimit") |     cpu_rate_limit: int = Field(0, serialization_alias="cpuRateLimit") | ||||||
|     cpu_set_limit: str = Field("", serialization_alias="cpuSetLimit") |     cpu_set_limit: str = Field("", serialization_alias="cpuSetLimit") | ||||||
|     copy_in: Dict[str, InputFile] = Field({}, serialization_alias="copyIn") |     copy_in: Dict[str, InputFile] = Field({}, serialization_alias="copyIn") | ||||||
|     copy_in_cached: Dict[str, str] = Field({}, serialization_alias="copyInCached") |     copy_in_cached: Dict[str, str] = Field({}, serialization_alias="copyInCached") | ||||||
|     copy_in_dir: str = Field(".", serialization_alias="copyInDir") |     copy_in_dir: str = Field(".", serialization_alias="copyInDir") | ||||||
|     copy_out: List[str] = Field([], serialization_alias="copyOut") |     copy_out: List[str] = Field(["stdout", "stderr"], serialization_alias="copyOut") | ||||||
|     copy_out_cached: List[str] = Field([], serialization_alias="copyOutCached") |     copy_out_cached: List[str] = Field([], serialization_alias="copyOutCached") | ||||||
|     copy_out_max: int = Field(0, serialization_alias="copyOutMax") |     copy_out_max: int = Field(0, serialization_alias="copyOutMax") | ||||||
|     copy_out_dir: str = Field("", serialization_alias="copyOutDir") |     copy_out_dir: str = Field("", serialization_alias="copyOutDir") | ||||||
|  | @ -66,11 +71,10 @@ class Cmd(BaseModel): | ||||||
| class OptionalCmd(BaseModel): | class OptionalCmd(BaseModel): | ||||||
|     args: Optional[List[str]] = None |     args: Optional[List[str]] = None | ||||||
|     env: Optional[List[str]] = None |     env: Optional[List[str]] = None | ||||||
|     stdin: Optional[Union[InputFile | StreamIn]] = None |     stdin: Optional[Union[InputFile, StreamIn]] = None | ||||||
|     stdout: Optional[Union[Collector | StreamOut]] = None |     stdout: Optional[Union[Collector, StreamOut]] = None | ||||||
|     stderr: Optional[Union[Collector | StreamOut]] = None |     stderr: Optional[Union[Collector, StreamOut]] = None | ||||||
|     cpu_limit: Optional[int] = Field(None, serialization_alias="cpuLimit") |     cpu_limit: Optional[int] = Field(None, serialization_alias="cpuLimit") | ||||||
|     real_cpu_limit: Optional[int] = Field(None, serialization_alias="realCpuLimit") |  | ||||||
|     clock_limit: Optional[int] = Field(None, serialization_alias="clockLimit") |     clock_limit: Optional[int] = Field(None, serialization_alias="clockLimit") | ||||||
|     memory_limit: Optional[int] = Field(None, serialization_alias="memoryLimit") |     memory_limit: Optional[int] = Field(None, serialization_alias="memoryLimit") | ||||||
|     stack_limit: Optional[int] = Field(None, serialization_alias="stackLimit") |     stack_limit: Optional[int] = Field(None, serialization_alias="stackLimit") | ||||||
|  | @ -101,23 +105,39 @@ class OptionalCmd(BaseModel): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ExecutorWith(BaseModel): | class ExecutorWith(BaseModel): | ||||||
|     default: Cmd |     default: Cmd = Cmd() | ||||||
|     cases: List[OptionalCmd] |     cases: List[OptionalCmd] = [] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Executor(BaseModel): | class Executor(BaseModel): | ||||||
|     name: str |     name: str | ||||||
|     with_: ExecutorWith = Field(..., serialization_alias="with") |     with_: ExecutorWith = Field(ExecutorWith(), serialization_alias="with") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Parser(BaseModel): | class Parser(BaseModel): | ||||||
|     name: str |     name: str | ||||||
|     with_: Dict[str, Any] = Field(..., serialization_alias="with") |     if TYPE_CHECKING: | ||||||
|  | 
 | ||||||
|  |         class Empty(BaseModel): | ||||||
|  |             pass | ||||||
|  | 
 | ||||||
|  |         with_: BaseModel = Field(Empty(), serialization_alias="with") | ||||||
|  |     else: | ||||||
|  |         with_: Dict[str, Any] = Field({}, serialization_alias="with") | ||||||
|  | 
 | ||||||
|  |     model_config = ConfigDict(validate_assignment=True) | ||||||
|  | 
 | ||||||
|  |     @field_validator("with_", mode="before") | ||||||
|  |     @classmethod | ||||||
|  |     def validate_with(cls, v: Any) -> Dict[str, Any]: | ||||||
|  |         if isinstance(v, BaseModel): | ||||||
|  |             return v.model_dump(by_alias=True) | ||||||
|  |         raise ValueError("Must be a BaseModel instance") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class StageDetail(BaseModel): | class StageDetail(BaseModel): | ||||||
|     name: str |     name: str | ||||||
|     group: str |     group: str = "" | ||||||
|     executor: Executor |     executor: Executor | ||||||
|     parsers: List[Parser] |     parsers: List[Parser] | ||||||
| 
 | 
 | ||||||
|  | @ -130,26 +150,74 @@ class Stage(BaseModel): | ||||||
|     output_path: str = Field( |     output_path: str = Field( | ||||||
|         "/tmp/joj3_result.json", serialization_alias="outputPath" |         "/tmp/joj3_result.json", serialization_alias="outputPath" | ||||||
|     )  # nosec: B108 |     )  # nosec: B108 | ||||||
|     stages: List[StageDetail] |     stages: List[StageDetail] = [] | ||||||
| 
 |     pre_stages: List[StageDetail] = Field([], serialization_alias="preStages") | ||||||
| 
 |     post_stages: List[StageDetail] = Field([], serialization_alias="postStages") | ||||||
| class Teapot(BaseModel): |  | ||||||
|     log_path: str = Field( |  | ||||||
|         "/home/tt/.cache/joint-teapot-debug.log", serialization_alias="logPath" |  | ||||||
|     ) |  | ||||||
|     scoreboard_path: str = Field("scoreboard.csv", serialization_alias="scoreboardPath") |  | ||||||
|     failed_table_path: str = Field( |  | ||||||
|         "failed-table.md", serialization_alias="failedTablePath" |  | ||||||
|     ) |  | ||||||
|     grading_repo_name: str = Field("", serialization_alias="gradingRepoName") |  | ||||||
|     skip_issue: bool = Field(False, serialization_alias="skipIssue") |  | ||||||
|     skip_scoreboard: bool = Field(False, serialization_alias="skipScoreboard") |  | ||||||
|     skip_failed_table: bool = Field(False, serialization_alias="skipFailedTable") |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Config(BaseModel): | class Config(BaseModel): | ||||||
|     name: str = "unknown" |     name: str = "" | ||||||
|     log_path: str = Field("", serialization_alias="logPath") |     log_path: str = Field("", serialization_alias="logPath") | ||||||
|     expire_unix_timestamp: int = Field(-1, serialization_alias="expireUnixTimestamp") |     expire_unix_timestamp: int = Field(-1, serialization_alias="expireUnixTimestamp") | ||||||
|  |     effective_unix_timestamp: int = Field( | ||||||
|  |         -1, serialization_alias="effectiveUnixTimestamp" | ||||||
|  |     ) | ||||||
|  |     actor_csv_path: str = Field("", serialization_alias="actorCsvPath") | ||||||
|  |     max_total_score: int = Field(100, serialization_alias="maxTotalScore") | ||||||
|     stage: Stage |     stage: Stage | ||||||
|     teapot: Teapot | 
 | ||||||
|  | 
 | ||||||
|  | class DummyConfig(BaseModel): | ||||||
|  |     score: int = 0 | ||||||
|  |     comment: Optional[str] = None | ||||||
|  |     force_quit_on_not_accepted: Optional[bool] = Field( | ||||||
|  |         False, serialization_alias="forceQuitOnNotAccepted" | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DiffOutputConfig(BaseModel): | ||||||
| 
					
					jon-lee marked this conversation as resolved
					
				 
				
					
						张泊明518370910136
						commented  also these  also these `Optional`? 
				
					
						李衍志523370910113
						commented  I guess some of the field have default within JOJ3, so I choose optional just to reduce the length of json previously I guess some of the field have default within JOJ3, so I choose optional just to reduce the length of json previously 
				
					
						张泊明518370910136
						commented  better put all defaults here then we only need to check the code here better put all defaults here then we only need to check the code here 
				
					
						李衍志523370910113
						commented  indeed. indeed. | |||||||
|  |     score: int = 100 | ||||||
|  |     file_name: str = Field("", serialization_alias="fileName") | ||||||
|  |     answer_path: str = Field("", serialization_alias="answerPath") | ||||||
|  |     force_quit_on_diff: bool = Field(False, serialization_alias="forceQuitOnDiff") | ||||||
|  |     always_hide: bool = Field(False, serialization_alias="alwaysHide") | ||||||
|  |     compare_space: bool = Field(False, serialization_alias="compareSpace") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ResultDetailConfig(BaseModel): | ||||||
|  |     score: int = 0 | ||||||
|  |     comment: str = "" | ||||||
|  |     show_files: List[str] = Field([], serialization_alias="showFiles") | ||||||
|  |     show_exit_status: bool = Field(True, serialization_alias="showExitStatus") | ||||||
|  |     show_runtime: bool = Field(True, serialization_alias="showRuntime") | ||||||
|  |     show_memory: bool = Field(False, serialization_alias="showMemory") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class KeywordConfig(BaseModel): | ||||||
|  |     keywords: List[str] = [] | ||||||
|  |     score: int = 0 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class KeywordMatchConfig(BaseModel): | ||||||
|  |     matches: List[KeywordConfig] = [] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class FileConfig(BaseModel): | ||||||
|  |     name: str = "" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DiffCasesConfig(BaseModel): | ||||||
|  |     outputs: List[DiffOutputConfig] = [] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DiffConfig(BaseModel): | ||||||
| 
					
					jon-lee marked this conversation as resolved
					
				 
				
					
						张泊明518370910136
						commented  what needs to be refined? what needs to be refined? 
				
					
						李衍志523370910113
						commented  just feels bit waste since this outputs only have one field before I coded the logic, I wrote that comment without checking the details of diff parser. But it should be the best strategy to show the structures as well as give flexiblity for extension now. just feels bit waste since this outputs only have one field before I coded the logic, I wrote that comment without checking the details of diff parser. But it should be the best strategy to show the structures as well as give flexiblity for extension now. | |||||||
|  |     name: str = "diff" | ||||||
|  |     cases: List[DiffCasesConfig] = [] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class MsgConfig(BaseModel): | ||||||
|  |     msg: str = "" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ScoreConfig(BaseModel): | ||||||
|  |     score: int = 0 | ||||||
|  |  | ||||||
|  | @ -1,8 +1,16 @@ | ||||||
| from datetime import datetime | from datetime import datetime, timedelta | ||||||
|  | from enum import Enum | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
| from typing import List, Optional | from typing import Any, Dict, List, Type | ||||||
| 
 | 
 | ||||||
| from pydantic import BaseModel, Field | from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator | ||||||
|  | 
 | ||||||
|  | from joj3_config_generator.models.common import Memory, Time | ||||||
|  | from joj3_config_generator.models.const import ( | ||||||
|  |     DEFAULT_CPU_LIMIT, | ||||||
|  |     DEFAULT_FILE_LIMIT, | ||||||
|  |     DEFAULT_MEMORY_LIMIT, | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ParserResultDetail(BaseModel): | class ParserResultDetail(BaseModel): | ||||||
|  | @ -10,31 +18,136 @@ class ParserResultDetail(BaseModel): | ||||||
|     mem: bool = True  # Display memory usage |     mem: bool = True  # Display memory usage | ||||||
|     stdout: bool = False  # Display stdout messages |     stdout: bool = False  # Display stdout messages | ||||||
|     stderr: bool = False  # Display stderr messages |     stderr: bool = False  # Display stderr messages | ||||||
|  |     exit_status: bool = True | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ParserFile(BaseModel): | ||||||
|  |     name: str = "" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ParserLog(BaseModel): | ||||||
|  |     filename: str | ||||||
|  |     msg: str = "" | ||||||
|  |     level: str = "" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ParserDummy(BaseModel): | ||||||
|  |     comment: str = "" | ||||||
|  |     score: int = 0 | ||||||
|  |     force_quit: bool = False | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ParserKeyword(BaseModel): | ||||||
|  |     keyword: List[str] = [] | ||||||
|  |     weight: List[int] = [] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Outputs(BaseModel): | ||||||
|  |     score: int = 0 | ||||||
|  |     ignore_spaces: bool = True | ||||||
|  |     hide: bool = False | ||||||
|  |     force_quit: bool = False | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ParserDiff(BaseModel): | ||||||
|  |     output: Outputs = Outputs() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Files(BaseModel): | class Files(BaseModel): | ||||||
|     import_: List[str] = Field(serialization_alias="import", validation_alias="import") |     import_: List[str] = Field([], alias="import") | ||||||
|     export: List[str] |     export: List[str] = [] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Limit(BaseModel): | ||||||
|  |     mem: int = DEFAULT_MEMORY_LIMIT | ||||||
|  |     cpu: int = DEFAULT_CPU_LIMIT | ||||||
|  |     stdout: int = DEFAULT_FILE_LIMIT | ||||||
|  |     stderr: int = DEFAULT_FILE_LIMIT | ||||||
|  | 
 | ||||||
|  |     model_config = ConfigDict(validate_assignment=True) | ||||||
|  | 
 | ||||||
|  |     @field_validator("cpu", mode="before") | ||||||
|  |     @classmethod | ||||||
|  |     def ensure_time(cls, v: Any) -> Time: | ||||||
|  |         if isinstance(v, str): | ||||||
|  |             return Time(v) | ||||||
|  |         raise ValueError("Must be a string") | ||||||
|  | 
 | ||||||
|  |     @field_validator("mem", "stdout", "stderr", mode="before") | ||||||
|  |     @classmethod | ||||||
|  |     def ensure_mem(cls, v: Any) -> Memory: | ||||||
|  |         if isinstance(v, str): | ||||||
|  |             return Memory(v) | ||||||
|  |         raise ValueError("Must be a string") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Parser(str, Enum): | ||||||
|  |     CLANG_TIDY = "clangtidy" | ||||||
|  |     CPPCHECK = "cppcheck" | ||||||
|  |     CPPLINT = "cpplint" | ||||||
|  |     KEYWORD = "keyword" | ||||||
|  |     RESULT_STATUS = "result-status" | ||||||
|  |     RESULT_DETAIL = "result-detail" | ||||||
|  |     DUMMY = "dummy" | ||||||
|  |     FILE = "file" | ||||||
|  |     DIFF = "diff" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Stage(BaseModel): | class Stage(BaseModel): | ||||||
|     name: str  # Stage name |     name: str = ""  # Stage name | ||||||
|     command: str  # Command to run |     env: List[str] = [] | ||||||
|     files: Files  # Files to import and export |     command: str = ""  # Command to run | ||||||
|     score: int  # Score for the task |     files: Files = Files() | ||||||
|     parsers: List[str]  # list of parsers |     in_: str = Field("", alias="in") | ||||||
|     result_detail: ParserResultDetail = ( |     out_: str = Field("", alias="out") | ||||||
|         ParserResultDetail() |     score: int = 0 | ||||||
|     )  #  for result-detail parser |     parsers: List[Parser] = []  # list of parsers | ||||||
|  |     limit: Limit = Limit() | ||||||
|  |     dummy: ParserDummy = ParserDummy() | ||||||
|  |     result_status: ParserDummy = Field(ParserDummy(), alias="result-status") | ||||||
|  |     keyword: ParserKeyword = ParserKeyword() | ||||||
|  |     clangtidy: ParserKeyword = ParserKeyword() | ||||||
|  |     cppcheck: ParserKeyword = ParserKeyword() | ||||||
|  |     cpplint: ParserKeyword = ParserKeyword() | ||||||
|  |     result_detail: ParserResultDetail = Field( | ||||||
|  |         ParserResultDetail(), alias="result-detail" | ||||||
|  |     ) | ||||||
|  |     file: ParserFile = ParserFile() | ||||||
|  |     skip: List[str] = [] | ||||||
|  | 
 | ||||||
|  |     # cases related | ||||||
|  |     cases: Dict[str, "Stage"] = {} | ||||||
|  |     diff: ParserDiff = ParserDiff() | ||||||
|  | 
 | ||||||
|  |     model_config = ConfigDict(extra="allow") | ||||||
|  | 
 | ||||||
|  |     @model_validator(mode="before") | ||||||
|  |     @classmethod | ||||||
|  |     def gather_cases(cls: Type["Stage"], values: Dict[str, Any]) -> Dict[str, Any]: | ||||||
|  |         cases = {k: v for k, v in values.items() if k.startswith("case")} | ||||||
|  |         for key in cases: | ||||||
|  |             values.pop(key) | ||||||
|  |         values["cases"] = {k: v for k, v in cases.items()} | ||||||
|  |         return values | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Release(BaseModel): | class Release(BaseModel): | ||||||
|     deadline: Optional[datetime]  # RFC 3339 formatted date-time with offset |     end_time: datetime = datetime.now() + timedelta( | ||||||
|  |         days=365 | ||||||
|  |     )  # RFC 3339 formatted date-time with offset | ||||||
|  |     begin_time: datetime = datetime.fromtimestamp( | ||||||
|  |         0 | ||||||
|  |     )  # RFC 3339 formatted date-time with offset | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Task(BaseModel): | ||||||
|  |     type_: str = Field("unknown", serialization_alias="type", validation_alias="type") | ||||||
|  |     name: str = "unknown" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Config(BaseModel): | class Config(BaseModel): | ||||||
|     root: Path = Path(".") |     root: Path = Path(".") | ||||||
|     path: Path = Path("task.toml") |     path: Path = Path("task.toml") | ||||||
|     task: str  # Task name (e.g., hw3 ex5) |     task: Task = Task()  # Task name (e.g., hw3 ex5) | ||||||
|     release: Release  # Release configuration |     release: Release = Release()  # Release configuration | ||||||
|     stages: List[Stage]  # list of stage configurations |     stages: List[Stage] = []  # list of stage configurations | ||||||
|  |  | ||||||
							
								
								
									
										0
									
								
								joj3_config_generator/processers/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										108
									
								
								joj3_config_generator/processers/repo.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,108 @@ | ||||||
|  | import hashlib | ||||||
|  | from pathlib import Path | ||||||
|  | from typing import List | ||||||
|  | 
 | ||||||
|  | from joj3_config_generator.models import repo, result | ||||||
|  | from joj3_config_generator.models.const import CACHE_ROOT, TEAPOT_CONFIG_ROOT | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_teapot_stage(repo_conf: repo.Config) -> result.StageDetail: | ||||||
|  |     args = [ | ||||||
|  |         "/usr/local/bin/joint-teapot", | ||||||
|  |         "joj3-all-env", | ||||||
|  |         str(TEAPOT_CONFIG_ROOT / "teapot.env"), | ||||||
|  |         "--grading-repo-name", | ||||||
|  |         repo_conf.grading_repo_name, | ||||||
|  |         "--max-total-score", | ||||||
|  |         str(repo_conf.max_total_score), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     stage_conf = result.StageDetail( | ||||||
|  |         name="teapot", | ||||||
|  |         executor=result.Executor( | ||||||
|  |             name="local", | ||||||
|  |             with_=result.ExecutorWith( | ||||||
|  |                 default=result.Cmd( | ||||||
|  |                     args=args, | ||||||
|  |                     env=[f"LOG_FILE_PATH={CACHE_ROOT}/joint-teapot-debug.log"], | ||||||
|  |                 ), | ||||||
|  |                 cases=[], | ||||||
|  |             ), | ||||||
|  |         ), | ||||||
|  |         parsers=[result.Parser(name="log", with_=result.MsgConfig(msg="joj3 summary"))], | ||||||
|  |     ) | ||||||
|  |     return stage_conf | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_health_check_args(repo_conf: repo.Config) -> List[str]: | ||||||
|  |     return [ | ||||||
|  |         "/usr/local/bin/repo-health-checker", | ||||||
|  |         "-root=.", | ||||||
|  |         f"-repoSize={str(repo_conf.max_size)}", | ||||||
|  |         *[f"-meta={meta}" for meta in repo_conf.files.required], | ||||||
|  |         f"-checkFileSumList={','.join(get_hashs(repo_conf))}", | ||||||
|  |         f"-checkFileNameList={','.join(repo_conf.files.immutable)}", | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_teapot_check_args(repo_conf: repo.Config) -> List[str]: | ||||||
|  |     return [ | ||||||
|  |         "/usr/local/bin/joint-teapot", | ||||||
|  |         "joj3-check-env", | ||||||
|  |         str(TEAPOT_CONFIG_ROOT / "teapot.env"), | ||||||
|  |         "--grading-repo-name", | ||||||
|  |         repo_conf.grading_repo_name, | ||||||
|  |         "--group-config", | ||||||
|  |         ",".join( | ||||||
|  |             f"{name}={max_count}:{time_period}" | ||||||
|  |             for name, max_count, time_period in zip( | ||||||
|  |                 repo_conf.groups.name, | ||||||
|  |                 repo_conf.groups.max_count, | ||||||
|  |                 repo_conf.groups.time_period_hour, | ||||||
|  |             ) | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_health_check_stage(repo_conf: repo.Config) -> result.StageDetail: | ||||||
|  |     health_check_stage = result.StageDetail( | ||||||
|  |         name="Health Check", | ||||||
|  |         group="", | ||||||
|  |         executor=result.Executor( | ||||||
|  |             name="local", | ||||||
|  |             with_=result.ExecutorWith( | ||||||
|  |                 default=result.Cmd(), | ||||||
|  |                 cases=[ | ||||||
|  |                     result.OptionalCmd( | ||||||
|  |                         args=get_health_check_args(repo_conf), | ||||||
|  |                     ), | ||||||
|  |                     result.OptionalCmd( | ||||||
|  |                         args=get_teapot_check_args(repo_conf), | ||||||
|  |                         env=[f"LOG_FILE_PATH={CACHE_ROOT}/joint-teapot-debug.log"], | ||||||
|  |                     ), | ||||||
|  |                 ], | ||||||
|  |             ), | ||||||
|  |         ), | ||||||
|  |         parsers=[ | ||||||
|  |             result.Parser(name="healthcheck", with_=result.ScoreConfig(score=1)), | ||||||
|  |             result.Parser(name="debug", with_=result.ScoreConfig(score=0)), | ||||||
|  |         ], | ||||||
|  |     ) | ||||||
|  |     return health_check_stage | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def calc_sha256sum(file_path: Path) -> str: | ||||||
|  |     sha256_hash = hashlib.sha256() | ||||||
|  |     with open(file_path, "rb") as f: | ||||||
|  |         for byte_block in iter(lambda: f.read(64 * 1024), b""): | ||||||
|  |             sha256_hash.update(byte_block) | ||||||
|  |     return sha256_hash.hexdigest() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_hashs(repo_conf: repo.Config) -> List[str]: | ||||||
|  |     base_dir = (repo_conf.root / repo_conf.path).parent | ||||||
|  |     immutable_dir = base_dir / "immutable_files" | ||||||
|  |     immutable_files = [ | ||||||
|  |         immutable_dir / Path(file).name for file in repo_conf.files.immutable | ||||||
|  |     ] | ||||||
|  |     return [calc_sha256sum(file) for file in immutable_files] | ||||||
							
								
								
									
										206
									
								
								joj3_config_generator/processers/task.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,206 @@ | ||||||
|  | import re | ||||||
| 
					
					jon-lee marked this conversation as resolved
					
				 
				
					
						张泊明518370910136
						commented  Path should not be relative to  Path should not be relative to `JOJ3_CONFIG_ROOT` in this file, should be relative to `task.toml` dir 
				
					
						李衍志523370910113
						commented  I reckon you said things is relative to  I reckon you said things is relative to `JOJ3_CONFIG_ROOT` in JTC before. we have a `task.type` in `task.toml` to mend the path 
				
					
						张泊明518370910136
						commented  
 `config.path` is relative to `JOJ3_CONFIG_ROOT`. 
				
					
						李衍志523370910113
						commented  could you explain further? I m not quite sure my understanding is clear. could you explain further? I m not quite sure my understanding is clear. 
				
					
						张泊明518370910136
						commented  In  In `joj3_config_generator/models/task.py`, `Config.path` is relative to `JOJ3_CONFIG_ROOT`, so `task.toml` will located at `JOJ3_CONFIG_ROOT / task_conf.path` in JTC. | |||||||
|  | import shlex | ||||||
| 
					
					jon-lee marked this conversation as resolved
					
				 
				
					
						张泊明518370910136
						commented  Some  Some `with_.update` is still using raw dict, not model with `model_dump`. | |||||||
|  | from pathlib import Path | ||||||
|  | from typing import Any, Callable, Dict, List, Tuple | ||||||
|  | 
 | ||||||
|  | from joj3_config_generator.models import result, task | ||||||
|  | from joj3_config_generator.models.common import Memory, Time | ||||||
|  | from joj3_config_generator.models.const import JOJ3_CONFIG_ROOT | ||||||
|  | from joj3_config_generator.models.task import Parser as ParserEnum | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_conf_stage( | ||||||
|  |     task_conf: task.Config, | ||||||
|  |     task_stage: task.Stage, | ||||||
|  |     cached: Dict[str, None], | ||||||
|  | ) -> result.StageDetail: | ||||||
|  |     conf_stage = result.StageDetail( | ||||||
|  |         name=task_stage.name, | ||||||
|  |         # group is determined by adding between "[]" in the name of the task | ||||||
|  |         group=( | ||||||
|  |             match.group(1) | ||||||
|  |             if (match := re.search(r"\[([^\[\]]+)\]", task_stage.name or "")) | ||||||
|  |             else "" | ||||||
|  |         ), | ||||||
|  |         executor=result.Executor( | ||||||
|  |             name="sandbox", | ||||||
|  |             with_=get_executor_with(task_stage, cached), | ||||||
|  |         ), | ||||||
|  |         parsers=([result.Parser(name=parser) for parser in task_stage.parsers]), | ||||||
|  |     ) | ||||||
|  |     processed_dict = get_processed_dict(task_stage) | ||||||
|  |     for idx, parser in enumerate(task_stage.parsers): | ||||||
|  |         if parser in processed_dict: | ||||||
|  |             fn, parser_model = processed_dict[parser] | ||||||
|  |             fn(parser_model, conf_stage.parsers[idx]) | ||||||
|  |         elif parser == ParserEnum.DIFF: | ||||||
|  |             fix_diff( | ||||||
|  |                 task_stage, | ||||||
|  |                 conf_stage.parsers[idx], | ||||||
|  |                 conf_stage.executor, | ||||||
|  |                 JOJ3_CONFIG_ROOT / task_conf.path.parent, | ||||||
|  |             ) | ||||||
|  |         else: | ||||||
|  |             continue | ||||||
|  |     return conf_stage | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_processed_dict( | ||||||
|  |     task_stage: task.Stage, | ||||||
|  | ) -> Dict[ParserEnum, Tuple[Callable[[Any, result.Parser], None], Any]]: | ||||||
|  |     processed_dict: Dict[ | ||||||
|  |         ParserEnum, Tuple[Callable[[Any, result.Parser], None], Any] | ||||||
|  |     ] = { | ||||||
|  |         ParserEnum.CLANG_TIDY: (fix_keyword, task_stage.clangtidy), | ||||||
|  |         ParserEnum.KEYWORD: (fix_keyword, task_stage.keyword), | ||||||
|  |         ParserEnum.CPPCHECK: (fix_keyword, task_stage.cppcheck), | ||||||
|  |         ParserEnum.CPPLINT: (fix_keyword, task_stage.cpplint), | ||||||
|  |         ParserEnum.RESULT_DETAIL: (fix_result_detail, task_stage.result_detail), | ||||||
|  |         ParserEnum.DUMMY: (fix_dummy, task_stage.dummy), | ||||||
|  |         ParserEnum.RESULT_STATUS: (fix_dummy, task_stage.result_status), | ||||||
|  |         ParserEnum.FILE: (fix_file, task_stage.file), | ||||||
|  |     } | ||||||
|  |     return processed_dict | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_executor_with( | ||||||
|  |     task_stage: task.Stage, cached: Dict[str, None] | ||||||
|  | ) -> result.ExecutorWith: | ||||||
|  |     file_import = task_stage.files.import_ | ||||||
|  |     copy_in_files = (file for file in file_import if file not in cached) | ||||||
|  |     file_export = task_stage.files.export | ||||||
|  |     copy_out_files = ["stdout", "stderr"] | ||||||
|  |     executor_with_config = result.ExecutorWith( | ||||||
|  |         default=result.Cmd( | ||||||
|  |             args=shlex.split(task_stage.command), | ||||||
|  |             copy_in={ | ||||||
|  |                 file: result.LocalFile(src=str(JOJ3_CONFIG_ROOT / file)) | ||||||
|  |                 # all copyin files store in this tools folder | ||||||
|  |                 # TODO: are there any corner cases? | ||||||
|  |                 for file in copy_in_files | ||||||
|  |             }, | ||||||
|  |             copy_out=copy_out_files, | ||||||
|  |             copy_in_cached={file: file for file in cached}, | ||||||
|  |             copy_out_cached=file_export, | ||||||
|  |             cpu_limit=Time(task_stage.limit.cpu), | ||||||
|  |             clock_limit=2 * Time(task_stage.limit.cpu), | ||||||
|  |             memory_limit=Memory(task_stage.limit.mem), | ||||||
|  |             stderr=result.Collector( | ||||||
|  |                 name="stderr", pipe=True, max=Memory(task_stage.limit.stderr) | ||||||
|  |             ), | ||||||
|  |             stdout=result.Collector( | ||||||
|  |                 name="stdout", pipe=True, max=Memory(task_stage.limit.stdout) | ||||||
|  |             ), | ||||||
|  |         ), | ||||||
|  |         cases=[], | ||||||
|  |     ) | ||||||
|  |     for file in file_export: | ||||||
|  |         cached[file] = None | ||||||
|  |     return executor_with_config | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def fix_keyword( | ||||||
|  |     keyword_config: task.ParserKeyword, keyword_parser: result.Parser | ||||||
|  | ) -> None: | ||||||
|  |     if len(keyword_config.keyword) != len(keyword_config.weight): | ||||||
|  |         raise ValueError("Keywords and weights must have the same length") | ||||||
|  |     score_groups: Dict[int, List[str]] = {} | ||||||
|  |     for keyword, score in zip(keyword_config.keyword, keyword_config.weight): | ||||||
|  |         score_groups.setdefault(score, []).append(keyword) | ||||||
|  |     keyword_parser.with_ = result.KeywordMatchConfig( | ||||||
|  |         matches=[ | ||||||
|  |             result.KeywordConfig(keywords=keywords, score=score) | ||||||
|  |             for score, keywords in score_groups.items() | ||||||
|  |         ] | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def fix_result_detail( | ||||||
|  |     result_detail_parser_config: task.ParserResultDetail, | ||||||
|  |     result_detail_parser: result.Parser, | ||||||
|  | ) -> None: | ||||||
|  |     show_files = [] | ||||||
|  |     if result_detail_parser_config.stdout: | ||||||
|  |         show_files.append("stdout") | ||||||
|  |     if result_detail_parser_config.stderr: | ||||||
|  |         show_files.append("stderr") | ||||||
|  |     result_detail_parser.with_ = result.ResultDetailConfig( | ||||||
|  |         score=0, | ||||||
|  |         comment="", | ||||||
|  |         show_files=show_files, | ||||||
|  |         show_exit_status=result_detail_parser_config.exit_status, | ||||||
|  |         show_runtime=result_detail_parser_config.time, | ||||||
|  |         show_memory=result_detail_parser_config.mem, | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def fix_dummy( | ||||||
|  |     dummy_parser_config: task.ParserDummy, dummy_parser: result.Parser | ||||||
|  | ) -> None: | ||||||
|  |     # we don't use dummy parser in real application | ||||||
|  |     dummy_parser.with_ = result.DummyConfig( | ||||||
|  |         score=dummy_parser_config.score, | ||||||
|  |         comment=dummy_parser_config.comment, | ||||||
|  |         force_quit_on_not_accepted=dummy_parser_config.force_quit, | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def fix_file(file_parser_config: task.ParserFile, file_parser: result.Parser) -> None: | ||||||
|  |     file_parser.with_ = result.FileConfig(name=file_parser_config.name) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def fix_diff( | ||||||
|  |     task_stage: task.Stage, | ||||||
|  |     diff_parser_config: result.Parser, | ||||||
|  |     diff_executor: result.Executor, | ||||||
|  |     base_dir: Path, | ||||||
|  | ) -> None: | ||||||
|  |     skip = task_stage.skip | ||||||
|  |     cases = task_stage.cases | ||||||
|  |     finalized_cases = [case for case in cases if case not in skip] | ||||||
|  | 
 | ||||||
|  |     stage_cases = [] | ||||||
|  |     parser_cases = [] | ||||||
|  | 
 | ||||||
|  |     for case in finalized_cases: | ||||||
|  |         case_stage = task_stage.cases.get(case) if task_stage.cases else None | ||||||
|  |         if not case_stage: | ||||||
|  |             continue | ||||||
|  | 
 | ||||||
|  |         cpu_limit = case_stage.limit.cpu | ||||||
|  |         clock_limit = 2 * case_stage.limit.cpu | ||||||
|  |         memory_limit = case_stage.limit.mem | ||||||
|  |         command = case_stage.command | ||||||
|  |         stdin = case_stage.in_ if case_stage.in_ != "" else f"{case}.in" | ||||||
|  |         stdout = case_stage.out_ if case_stage.out_ != "" else f"{case}.out" | ||||||
|  | 
 | ||||||
|  |         stage_cases.append( | ||||||
|  |             result.OptionalCmd( | ||||||
|  |                 stdin=result.LocalFile( | ||||||
|  |                     src=str(base_dir / stdin), | ||||||
|  |                 ), | ||||||
|  |                 args=shlex.split(command) if command else None, | ||||||
|  |                 cpu_limit=cpu_limit, | ||||||
|  |                 clock_limit=clock_limit, | ||||||
|  |                 memory_limit=memory_limit, | ||||||
|  |                 proc_limit=50, | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  |         diff_output = case_stage.diff.output | ||||||
|  |         parser_cases.append( | ||||||
|  |             result.DiffCasesConfig( | ||||||
|  |                 outputs=[ | ||||||
|  |                     result.DiffOutputConfig( | ||||||
|  |                         score=diff_output.score, | ||||||
|  |                         file_name="stdout", | ||||||
|  |                         answer_path=str(base_dir / stdout), | ||||||
|  |                         force_quit_on_diff=diff_output.force_quit, | ||||||
|  |                         always_hide=diff_output.hide, | ||||||
|  |                         compare_space=not diff_output.ignore_spaces, | ||||||
|  |                     ) | ||||||
|  |                 ] | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     diff_executor.with_.cases = stage_cases | ||||||
|  |     diff_parser_config.with_ = result.DiffConfig(name="diff", cases=parser_cases) | ||||||
|  | @ -2,7 +2,7 @@ import logging | ||||||
| import sys | import sys | ||||||
| from sys import stderr | from sys import stderr | ||||||
| from types import FrameType | from types import FrameType | ||||||
| from typing import Optional | from typing import Optional, Union | ||||||
| 
 | 
 | ||||||
| from loguru import logger as logger | from loguru import logger as logger | ||||||
| 
 | 
 | ||||||
|  | @ -10,7 +10,7 @@ from loguru import logger as logger | ||||||
| # recipe from https://loguru.readthedocs.io/en/stable/overview.html#entirely-compatible-with-standard-logging | # recipe from https://loguru.readthedocs.io/en/stable/overview.html#entirely-compatible-with-standard-logging | ||||||
| class InterceptHandler(logging.Handler): | class InterceptHandler(logging.Handler): | ||||||
|     def emit(self, record: logging.LogRecord) -> None: |     def emit(self, record: logging.LogRecord) -> None: | ||||||
|         level: str | int |         level: Union[str, int] | ||||||
|         try: |         try: | ||||||
|             level = logger.level(record.levelname).name |             level = logger.level(record.levelname).name | ||||||
|         except ValueError: |         except ValueError: | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ dependencies = [ | ||||||
|     "pydantic>=2.9.2", |     "pydantic>=2.9.2", | ||||||
|     "inquirer>=3.4.0", |     "inquirer>=3.4.0", | ||||||
|     "rtoml>=0.11.0", |     "rtoml>=0.11.0", | ||||||
|  |     "humanfriendly>=10.0", | ||||||
| ] | ] | ||||||
| requires-python = ">=3.9" | requires-python = ">=3.9" | ||||||
| authors = [{ name = "JOJ3-dev", email = "joj3@focs.ji.sjtu.edu.cn" }] | authors = [{ name = "JOJ3-dev", email = "joj3@focs.ji.sjtu.edu.cn" }] | ||||||
|  |  | ||||||
							
								
								
									
										33
									
								
								tests/convert/basic/immutable_files/.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,33 @@ | ||||||
|  | *.avi filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.bz2 filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.djvu filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.doc filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.docx filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.epub filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.gz filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.ipynb filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.jpeg filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.JPEG filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.jpg filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.JPG filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.mkv filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.mp4 filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.ods filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.odt filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.otf filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.pdf filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.PDF filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.png filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.PNG filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.ppt filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.pptx filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.ps filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.rar filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.tar filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.tgz filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.ttf filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.webm filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.xls filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.xlsx filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.xz filter=lfs diff=lfs merge=lfs -text | ||||||
|  | *.zip filter=lfs diff=lfs merge=lfs -text | ||||||
							
								
								
									
										23
									
								
								tests/convert/basic/immutable_files/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,23 @@ | ||||||
|  | ################################ | ||||||
|  | ## White list based gitignore ## | ||||||
|  | ################################ | ||||||
|  | 
 | ||||||
|  | # forbidden | ||||||
|  | * | ||||||
|  | .* | ||||||
|  | 
 | ||||||
|  | # allowed | ||||||
|  | !.gitignore | ||||||
|  | !.gitattributes | ||||||
|  | !.gitea/ | ||||||
|  | !.gitea/issue_template/ | ||||||
|  | !.gitea/workflows/ | ||||||
|  | !*.yaml | ||||||
|  | !Makefile | ||||||
|  | !CMakeLists.txt | ||||||
|  | !h[0-8]/ | ||||||
|  | !*.m | ||||||
|  | !*.c | ||||||
|  | !*.cpp | ||||||
|  | !*.h | ||||||
|  | !*.md | ||||||
							
								
								
									
										19
									
								
								tests/convert/basic/immutable_files/push.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,19 @@ | ||||||
|  | name: Run JOJ3 on Push | ||||||
|  | on: [push] | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   run: | ||||||
|  |     container: | ||||||
|  |       runs-on: focs-latest-slim | ||||||
|  |       volumes: | ||||||
|  |         - /home/tt/.config:/home/tt/.config | ||||||
|  |         - /home/tt/.cache:/home/tt/.cache | ||||||
|  |         - /home/tt/.ssh:/home/tt/.ssh | ||||||
|  |     steps: | ||||||
|  |       - name: Check out repository code | ||||||
|  |         uses: actions/checkout@focs | ||||||
|  |         with: | ||||||
|  |           fetch-depth: 0 | ||||||
|  |       - name: Run joj3 | ||||||
|  |         run: | | ||||||
|  |           sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/homework | ||||||
							
								
								
									
										21
									
								
								tests/convert/basic/immutable_files/release.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,21 @@ | ||||||
|  | name: Run JOJ3 on Release | ||||||
|  | on: | ||||||
|  |   release: | ||||||
|  |     types: [published] | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   run: | ||||||
|  |     runs-on: focs-latest-slim | ||||||
|  |     container: | ||||||
|  |       volumes: | ||||||
|  |         - /home/tt/.config:/home/tt/.config | ||||||
|  |         - /home/tt/.cache:/home/tt/.cache | ||||||
|  |         - /home/tt/.ssh:/home/tt/.ssh | ||||||
|  |     steps: | ||||||
|  |       - name: Check out repository code | ||||||
|  |         uses: actions/checkout@focs | ||||||
|  |         with: | ||||||
|  |           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 }}" | ||||||
|  | @ -1,10 +1,16 @@ | ||||||
| teaching_team = ["prof_john", "ta_alice", "ta_bob"] | grading_repo_name = "ece280-joj" | ||||||
| max_size = 50.5 | 
 | ||||||
| release_tags = ["v1.0", "v2.0", "final"] |  | ||||||
| sandbox_token = "test" | sandbox_token = "test" | ||||||
|  | # reconfigure later | ||||||
|  | max_total_score = 100 | ||||||
|  | max_size = 50.5 | ||||||
|  | 
 | ||||||
|  | # for tests | ||||||
|  | [groups] | ||||||
|  | name = ["joj", "run"] | ||||||
|  | max_count = [1000, 1000] | ||||||
|  | time_period_hour = [24, 24] | ||||||
| 
 | 
 | ||||||
| [files] | [files] | ||||||
| whitelist_patterns = ["*.py", "*.txt", "*.md"] | required = ["README.md", "Changelog.md"] | ||||||
| whitelist_file = ".whitelist" | immutable = [".gitignore", ".gitattributes",".gitea/workflows/push.yaml", ".gitea/workflows/release.yaml"] | ||||||
| required = ["main.py", "README.md"] |  | ||||||
| immutable = ["config.yaml", "setup.py"] |  | ||||||
|  |  | ||||||
|  | @ -1,46 +1,151 @@ | ||||||
| { | { | ||||||
|     "name": "hw3 ex5", |     "name": "hw7 ex2", | ||||||
|     "logPath": "hw3_ex5.log", |     "logPath": "/home/tt/.cache/joj3/homework/h7/e2.log", | ||||||
|     "expireUnixTimestamp": 1729267140, |     "expireUnixTimestamp": 1735574399, | ||||||
|  |     "effectiveUnixTimestamp": 1735487999, | ||||||
|  |     "actorCsvPath": "/home/tt/.config/joj/students.csv", | ||||||
|  |     "maxTotalScore": 100, | ||||||
|     "stage": { |     "stage": { | ||||||
|         "sandboxExecServer": "172.17.0.1:5051", |         "sandboxExecServer": "172.17.0.1:5051", | ||||||
|         "sandboxToken": "test", |         "sandboxToken": "test", | ||||||
|         "outputPath": "/tmp/joj3_result.json", |         "outputPath": "/tmp/joj3_result.json", | ||||||
|         "stages": [ |         "stages": [ | ||||||
|             { |             { | ||||||
|                 "name": "judge_base", |                 "name": "Health Check", | ||||||
|                 "group": "hw3 ex5", |                 "group": "", | ||||||
|  |                 "executor": { | ||||||
|  |                     "name": "local", | ||||||
|  |                     "with": { | ||||||
|  |                         "default": { | ||||||
|  |                             "args": [], | ||||||
|  |                             "env": [], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": {}, | ||||||
|  |                             "copyInCached": {}, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [ | ||||||
|  |                             { | ||||||
|  |                                 "args": [ | ||||||
|  |                                     "/usr/local/bin/repo-health-checker", | ||||||
|  |                                     "-root=.", | ||||||
|  |                                     "-repoSize=50.5", | ||||||
|  |                                     "-meta=README.md", | ||||||
|  |                                     "-meta=Changelog.md", | ||||||
|  |                                     "-checkFileSumList=a5b63323a692d3d8b952442969649b4f823d58dae26429494f613df160710dfc,b1bbad25b830db0a77b15a033f9ca1b7ab44c1d2d05056412bd3e4421645f0bf,2ba059f3977e2e3dee6cacbfbf0ba2578baa1b8e04b4977aec400868b6e49856,bf7d181362affdcc72aac33f3520e4e6371adc48ea62a6f24524b4a3e76724c5", | ||||||
|  |                                     "-checkFileNameList=.gitignore,.gitattributes,.gitea/workflows/push.yaml,.gitea/workflows/release.yaml" | ||||||
|  |                                 ] | ||||||
|  |                             }, | ||||||
|  |                             { | ||||||
|  |                                 "args": [ | ||||||
|  |                                     "/usr/local/bin/joint-teapot", | ||||||
|  |                                     "joj3-check-env", | ||||||
|  |                                     "/home/tt/.config/teapot/teapot.env", | ||||||
|  |                                     "--grading-repo-name", | ||||||
|  |                                     "ece280-joj", | ||||||
|  |                                     "--group-config", | ||||||
|  |                                     "joj=1000:24,run=1000:24" | ||||||
|  |                                 ], | ||||||
|  |                                 "env": [ | ||||||
|  |                                     "LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log" | ||||||
|  |                                 ] | ||||||
|  |                             } | ||||||
|  |                         ] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "healthcheck", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 1 | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "debug", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0 | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 "name": "Compilation", | ||||||
|  |                 "group": "", | ||||||
|                 "executor": { |                 "executor": { | ||||||
|                     "name": "sandbox", |                     "name": "sandbox", | ||||||
|                     "with": { |                     "with": { | ||||||
|                         "default": { |                         "default": { | ||||||
|                             "args": [ |                             "args": [ | ||||||
|                                 "./matlab-joj", |                                 "./tools/compile" | ||||||
|                                 "./h3/ex5.m" |  | ||||||
|                             ], |                             ], | ||||||
|                             "env": [], |                             "env": [], | ||||||
|                             "cpuLimit": 0, |                             "stdin": { | ||||||
|                             "realCpuLimit": 0, |                                 "content": "" | ||||||
|                             "clockLimit": 0, |                             }, | ||||||
|                             "memoryLimit": 0, |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|                             "stackLimit": 0, |                             "stackLimit": 0, | ||||||
|                             "procLimit": 0, |                             "procLimit": 50, | ||||||
|                             "cpuRateLimit": 0, |                             "cpuRateLimit": 0, | ||||||
|                             "cpuSetLimit": "", |                             "cpuSetLimit": "", | ||||||
|                             "copyIn": { |                             "copyIn": { | ||||||
|                                 "tools/matlab-joj": { |                                 "tools/compile": { | ||||||
|                                     "src": "tools/matlab-joj" |                                     "src": "/home/tt/.config/joj/tools/compile" | ||||||
|                                 }, |  | ||||||
|                                 "tools/matlab_formatter.py": { |  | ||||||
|                                     "src": "tools/matlab_formatter.py" |  | ||||||
|                                 } |                                 } | ||||||
|                             }, |                             }, | ||||||
|                             "copyInCached": {}, |                             "copyInCached": {}, | ||||||
|                             "copyInDir": ".", |                             "copyInDir": ".", | ||||||
|                             "copyOut": [], |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|                             "copyOutCached": [ |                             "copyOutCached": [ | ||||||
|                                 "output/ex5_results.txt", |                                 "h7/build/ex2", | ||||||
|                                 "output/ex5_logs.txt" |                                 "h7/build/ex2-asan", | ||||||
|  |                                 "h7/build/ex2-ubsan", | ||||||
|  |                                 "h7/build/ex2-msan", | ||||||
|  |                                 "h7/build/compile_commands.json" | ||||||
|                             ], |                             ], | ||||||
|                             "copyOutMax": 0, |                             "copyOutMax": 0, | ||||||
|                             "copyOutDir": "", |                             "copyOutDir": "", | ||||||
|  | @ -53,56 +158,82 @@ | ||||||
|                     } |                     } | ||||||
|                 }, |                 }, | ||||||
|                 "parsers": [ |                 "parsers": [ | ||||||
|                     { |  | ||||||
|                         "name": "diff", |  | ||||||
|                         "with": {} |  | ||||||
|                     }, |  | ||||||
|                     { |                     { | ||||||
|                         "name": "result-detail", |                         "name": "result-detail", | ||||||
|                         "with": { |                         "with": { | ||||||
|                             "time": false, |                             "score": 0, | ||||||
|                             "mem": false, |                             "comment": "", | ||||||
|                             "stdout": false, |                             "showFiles": [ | ||||||
|                             "stderr": true |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": false, | ||||||
|  |                             "showMemory": false | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "result-status", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "Congratulations! Your code compiled successfully.", | ||||||
|  |                             "forceQuitOnNotAccepted": true | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 ] |                 ] | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
|                 "name": "judge_base2", |                 "name": "[cq] Filelength", | ||||||
|                 "group": "hw3 ex5", |                 "group": "cq", | ||||||
|                 "executor": { |                 "executor": { | ||||||
|                     "name": "sandbox", |                     "name": "sandbox", | ||||||
|                     "with": { |                     "with": { | ||||||
|                         "default": { |                         "default": { | ||||||
|                             "args": [ |                             "args": [ | ||||||
|                                 "./matlab-joj", |                                 "./tools/filelength", | ||||||
|                                 "./h3/ex5.m" |                                 "400", | ||||||
|  |                                 "300", | ||||||
|  |                                 "*.cpp", | ||||||
|  |                                 "*.h" | ||||||
|                             ], |                             ], | ||||||
|                             "env": [], |                             "env": [], | ||||||
|                             "cpuLimit": 0, |                             "stdin": { | ||||||
|                             "realCpuLimit": 0, |                                 "content": "" | ||||||
|                             "clockLimit": 0, |                             }, | ||||||
|                             "memoryLimit": 0, |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|                             "stackLimit": 0, |                             "stackLimit": 0, | ||||||
|                             "procLimit": 0, |                             "procLimit": 50, | ||||||
|                             "cpuRateLimit": 0, |                             "cpuRateLimit": 0, | ||||||
|                             "cpuSetLimit": "", |                             "cpuSetLimit": "", | ||||||
|                             "copyIn": { |                             "copyIn": { | ||||||
|                                 "tools/matlab-joj": { |                                 "tools/filelength": { | ||||||
|                                     "src": "tools/matlab-joj" |                                     "src": "/home/tt/.config/joj/tools/filelength" | ||||||
|                                 }, |  | ||||||
|                                 "tools/matlab_formatter.py": { |  | ||||||
|                                     "src": "tools/matlab_formatter.py" |  | ||||||
|                                 } |                                 } | ||||||
|                             }, |                             }, | ||||||
|                             "copyInCached": {}, |                             "copyInCached": { | ||||||
|  |                                 "h7/build/ex2": "h7/build/ex2", | ||||||
|  |                                 "h7/build/ex2-asan": "h7/build/ex2-asan", | ||||||
|  |                                 "h7/build/ex2-ubsan": "h7/build/ex2-ubsan", | ||||||
|  |                                 "h7/build/ex2-msan": "h7/build/ex2-msan", | ||||||
|  |                                 "h7/build/compile_commands.json": "h7/build/compile_commands.json" | ||||||
|  |                             }, | ||||||
|                             "copyInDir": ".", |                             "copyInDir": ".", | ||||||
|                             "copyOut": [], |                             "copyOut": [ | ||||||
|                             "copyOutCached": [ |                                 "stdout", | ||||||
|                                 "output/ex5_results2.txt", |                                 "stderr" | ||||||
|                                 "output/ex5_logs2.txt" |  | ||||||
|                             ], |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|                             "copyOutMax": 0, |                             "copyOutMax": 0, | ||||||
|                             "copyOutDir": "", |                             "copyOutDir": "", | ||||||
|                             "tty": false, |                             "tty": false, | ||||||
|  | @ -115,29 +246,604 @@ | ||||||
|                 }, |                 }, | ||||||
|                 "parsers": [ |                 "parsers": [ | ||||||
|                     { |                     { | ||||||
|                         "name": "diff", |                         "name": "keyword", | ||||||
|                         "with": {} |                         "with": { | ||||||
|  |                             "matches": [ | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "max" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 20 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "recommended" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 10 | ||||||
|  |                                 } | ||||||
|  |                             ] | ||||||
|  |                         } | ||||||
|                     }, |                     }, | ||||||
|                     { |                     { | ||||||
|                         "name": "result-detail", |                         "name": "result-detail", | ||||||
|                         "with": { |                         "with": { | ||||||
|                             "time": true, |                             "score": 0, | ||||||
|                             "mem": true, |                             "comment": "", | ||||||
|                             "stdout": false, |                             "showFiles": [ | ||||||
|                             "stderr": false |                                 "stdout" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": false, | ||||||
|  |                             "showMemory": false | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 ] |                 ] | ||||||
|             } |  | ||||||
|         ] |  | ||||||
|             }, |             }, | ||||||
|     "teapot": { |             { | ||||||
|         "logPath": "/home/tt/.cache/joint-teapot-debug.log", |                 "name": "[cq] Clang-tidy", | ||||||
|         "scoreboardPath": "scoreboard.csv", |                 "group": "cq", | ||||||
|         "failedTablePath": "failed-table.md", |                 "executor": { | ||||||
|         "gradingRepoName": "", |                     "name": "sandbox", | ||||||
|         "skipIssue": false, |                     "with": { | ||||||
|         "skipScoreboard": false, |                         "default": { | ||||||
|         "skipFailedTable": false |                             "args": [ | ||||||
|  |                                 "run-clang-tidy-18", | ||||||
|  |                                 "-header-filter=.*", | ||||||
|  |                                 "-quiet", | ||||||
|  |                                 "-load=/usr/local/lib/libcodequality.so", | ||||||
|  |                                 "-p", | ||||||
|  |                                 "h7/build", | ||||||
|  |                                 "h7/ex2.cpp" | ||||||
|  |                             ], | ||||||
|  |                             "env": [], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 4194304, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": { | ||||||
|  |                                 "tests/homework/h7/.clang-tidy": { | ||||||
|  |                                     "src": "/home/tt/.config/joj/tests/homework/h7/.clang-tidy" | ||||||
|  |                                 } | ||||||
|  |                             }, | ||||||
|  |                             "copyInCached": { | ||||||
|  |                                 "h7/build/ex2": "h7/build/ex2", | ||||||
|  |                                 "h7/build/ex2-asan": "h7/build/ex2-asan", | ||||||
|  |                                 "h7/build/ex2-ubsan": "h7/build/ex2-ubsan", | ||||||
|  |                                 "h7/build/ex2-msan": "h7/build/ex2-msan", | ||||||
|  |                                 "h7/build/compile_commands.json": "h7/build/compile_commands.json" | ||||||
|  |                             }, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "clangtidy", | ||||||
|  |                         "with": { | ||||||
|  |                             "matches": [ | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "codequality-unchecked-malloc-result", | ||||||
|  |                                         "readability-duplicate-include", | ||||||
|  |                                         "readability-identifier-naming", | ||||||
|  |                                         "readability-redundant", | ||||||
|  |                                         "readability-misplaced-array-index", | ||||||
|  |                                         "cppcoreguidelines-init-variables", | ||||||
|  |                                         "bugprone-suspicious-string-compare", | ||||||
|  |                                         "google-global-names-in-headers", | ||||||
|  |                                         "clang-diagnostic", | ||||||
|  |                                         "clang-analyzer", | ||||||
|  |                                         "misc", | ||||||
|  |                                         "performance", | ||||||
|  |                                         "portability" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 5 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "codequality-no-global-variables", | ||||||
|  |                                         "codequality-no-header-guard", | ||||||
|  |                                         "codequality-no-fflush-stdin" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 20 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "readability-function-size" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 10 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "readability-misleading-indentation" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 15 | ||||||
|  |                                 } | ||||||
|  |                             ] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "result-detail", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "showFiles": [ | ||||||
|  |                                 "stdout" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": false, | ||||||
|  |                             "showMemory": false | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 "name": "[cq] Cppcheck", | ||||||
|  |                 "group": "cq", | ||||||
|  |                 "executor": { | ||||||
|  |                     "name": "sandbox", | ||||||
|  |                     "with": { | ||||||
|  |                         "default": { | ||||||
|  |                             "args": [ | ||||||
|  |                                 "cppcheck", | ||||||
|  |                                 "--template={\"file\":\"{file}\",\"line\":{line}, \"column\":{column}, \"severity\":\"{severity}\", \"message\":\"{message}\", \"id\":\"{id}\"}", | ||||||
|  |                                 "--force", | ||||||
|  |                                 "--enable=all", | ||||||
|  |                                 "--suppress=missingIncludeSystem", | ||||||
|  |                                 "--quiet", | ||||||
|  |                                 "h7/ex2.cpp" | ||||||
|  |                             ], | ||||||
|  |                             "env": [], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 8388608, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": {}, | ||||||
|  |                             "copyInCached": { | ||||||
|  |                                 "h7/build/ex2": "h7/build/ex2", | ||||||
|  |                                 "h7/build/ex2-asan": "h7/build/ex2-asan", | ||||||
|  |                                 "h7/build/ex2-ubsan": "h7/build/ex2-ubsan", | ||||||
|  |                                 "h7/build/ex2-msan": "h7/build/ex2-msan", | ||||||
|  |                                 "h7/build/compile_commands.json": "h7/build/compile_commands.json" | ||||||
|  |                             }, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "keyword", | ||||||
|  |                         "with": { | ||||||
|  |                             "matches": [] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "cppcheck", | ||||||
|  |                         "with": { | ||||||
|  |                             "matches": [ | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "error" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 15 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "warning", | ||||||
|  |                                         "portability", | ||||||
|  |                                         "performance", | ||||||
|  |                                         "style" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 5 | ||||||
|  |                                 } | ||||||
|  |                             ] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "clangtidy", | ||||||
|  |                         "with": { | ||||||
|  |                             "matches": [] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "result-detail", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "showFiles": [ | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": false, | ||||||
|  |                             "showMemory": false | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "cpplint", | ||||||
|  |                         "with": { | ||||||
|  |                             "matches": [] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "result-status", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "forceQuitOnNotAccepted": false | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "file", | ||||||
|  |                         "with": { | ||||||
|  |                             "name": "" | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "dummy", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "forceQuitOnNotAccepted": false | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "diff", | ||||||
|  |                         "with": { | ||||||
|  |                             "name": "diff", | ||||||
|  |                             "cases": [] | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 "name": "[cq] Cpplint", | ||||||
|  |                 "group": "cq", | ||||||
|  |                 "executor": { | ||||||
|  |                     "name": "sandbox", | ||||||
|  |                     "with": { | ||||||
|  |                         "default": { | ||||||
|  |                             "args": [ | ||||||
|  |                                 "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" | ||||||
|  |                             ], | ||||||
|  |                             "env": [], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 68157440, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": {}, | ||||||
|  |                             "copyInCached": { | ||||||
|  |                                 "h7/build/ex2": "h7/build/ex2", | ||||||
|  |                                 "h7/build/ex2-asan": "h7/build/ex2-asan", | ||||||
|  |                                 "h7/build/ex2-ubsan": "h7/build/ex2-ubsan", | ||||||
|  |                                 "h7/build/ex2-msan": "h7/build/ex2-msan", | ||||||
|  |                                 "h7/build/compile_commands.json": "h7/build/compile_commands.json" | ||||||
|  |                             }, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "cpplint", | ||||||
|  |                         "with": { | ||||||
|  |                             "matches": [ | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "runtime" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 5 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "readability" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 20 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "build" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 10 | ||||||
|  |                                 } | ||||||
|  |                             ] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "result-detail", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "showFiles": [ | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": false, | ||||||
|  |                             "showMemory": false | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 "name": "[joj] ex2-asan", | ||||||
|  |                 "group": "joj", | ||||||
|  |                 "executor": { | ||||||
|  |                     "name": "sandbox", | ||||||
|  |                     "with": { | ||||||
|  |                         "default": { | ||||||
|  |                             "args": [ | ||||||
|  |                                 "./h7/build/ex2-asan", | ||||||
|  |                                 "-a" | ||||||
|  |                             ], | ||||||
|  |                             "env": [], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": {}, | ||||||
|  |                             "copyInCached": { | ||||||
|  |                                 "h7/build/ex2": "h7/build/ex2", | ||||||
|  |                                 "h7/build/ex2-asan": "h7/build/ex2-asan", | ||||||
|  |                                 "h7/build/ex2-ubsan": "h7/build/ex2-ubsan", | ||||||
|  |                                 "h7/build/ex2-msan": "h7/build/ex2-msan", | ||||||
|  |                                 "h7/build/compile_commands.json": "h7/build/compile_commands.json" | ||||||
|  |                             }, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [ | ||||||
|  |                             { | ||||||
|  |                                 "stdin": { | ||||||
|  |                                     "src": "/home/tt/.config/joj/basic/case0.in" | ||||||
|  |                                 }, | ||||||
|  |                                 "cpuLimit": 500000000, | ||||||
|  |                                 "clockLimit": 1000000000, | ||||||
|  |                                 "memoryLimit": 5242880, | ||||||
|  |                                 "procLimit": 50 | ||||||
|  |                             }, | ||||||
|  |                             { | ||||||
|  |                                 "stdin": { | ||||||
|  |                                     "src": "/home/tt/.config/joj/basic/case1.in" | ||||||
|  |                                 }, | ||||||
|  |                                 "cpuLimit": 1000000000, | ||||||
|  |                                 "clockLimit": 2000000000, | ||||||
|  |                                 "memoryLimit": 5242880, | ||||||
|  |                                 "procLimit": 50 | ||||||
|  |                             } | ||||||
|  |                         ] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "diff", | ||||||
|  |                         "with": { | ||||||
|  |                             "name": "diff", | ||||||
|  |                             "cases": [ | ||||||
|  |                                 { | ||||||
|  |                                     "outputs": [ | ||||||
|  |                                         { | ||||||
|  |                                             "score": 5, | ||||||
|  |                                             "fileName": "stdout", | ||||||
|  |                                             "answerPath": "/home/tt/.config/joj/basic/case0.out", | ||||||
|  |                                             "forceQuitOnDiff": false, | ||||||
|  |                                             "alwaysHide": false, | ||||||
|  |                                             "compareSpace": false | ||||||
|  |                                         } | ||||||
|  |                                     ] | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "outputs": [ | ||||||
|  |                                         { | ||||||
|  |                                             "score": 5, | ||||||
|  |                                             "fileName": "stdout", | ||||||
|  |                                             "answerPath": "/home/tt/.config/joj/basic/case1.out", | ||||||
|  |                                             "forceQuitOnDiff": false, | ||||||
|  |                                             "alwaysHide": false, | ||||||
|  |                                             "compareSpace": false | ||||||
|  |                                         } | ||||||
|  |                                     ] | ||||||
|  |                                 } | ||||||
|  |                             ] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "result-detail", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "showFiles": [ | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": true, | ||||||
|  |                             "showMemory": true | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "preStages": [], | ||||||
|  |         "postStages": [ | ||||||
|  |             { | ||||||
|  |                 "name": "teapot", | ||||||
|  |                 "group": "", | ||||||
|  |                 "executor": { | ||||||
|  |                     "name": "local", | ||||||
|  |                     "with": { | ||||||
|  |                         "default": { | ||||||
|  |                             "args": [ | ||||||
|  |                                 "/usr/local/bin/joint-teapot", | ||||||
|  |                                 "joj3-all-env", | ||||||
|  |                                 "/home/tt/.config/teapot/teapot.env", | ||||||
|  |                                 "--grading-repo-name", | ||||||
|  |                                 "ece280-joj", | ||||||
|  |                                 "--max-total-score", | ||||||
|  |                                 "100" | ||||||
|  |                             ], | ||||||
|  |                             "env": [ | ||||||
|  |                                 "LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log" | ||||||
|  |                             ], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": {}, | ||||||
|  |                             "copyInCached": {}, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "log", | ||||||
|  |                         "with": { | ||||||
|  |                             "msg": "joj3 summary" | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,30 +1,102 @@ | ||||||
| task = "hw3 ex5" | # general task configuration | ||||||
|  | task.name = "hw7 ex2" # task name | ||||||
|  | task.type = "homework/h7/e2" # remove this task type later | ||||||
| 
 | 
 | ||||||
| [release] | release.end_time = 2024-12-30 23:59:59+08:00 | ||||||
| deadline = "2024-10-18T23:59:00+08:00" | release.begin_time = 2024-12-29 23:59:59+08:00 | ||||||
| 
 | 
 | ||||||
| [[stages]] | [[stages]] | ||||||
| name = "judge_base" | name = "Compilation" | ||||||
| command = "./matlab-joj ./h3/ex5.m" | command = "./tools/compile" # eg. script running cmake commands | ||||||
| score = 100 | files.import = [ "tools/compile" ] | ||||||
| parsers = ["diff", "result-detail"] | files.export = [ "h7/build/ex2", "h7/build/ex2-asan", "h7/build/ex2-ubsan", "h7/build/ex2-msan", "h7/build/compile_commands.json" ] | ||||||
|  | score = 1 | ||||||
| 
 | 
 | ||||||
| files.import = ["tools/matlab-joj", "tools/matlab_formatter.py"] | # compile parsers | ||||||
| files.export = ["output/ex5_results.txt", "output/ex5_logs.txt"] | parsers = [ "result-detail", "result-status" ] | ||||||
| 
 | result-status.comment = "Congratulations! Your code compiled successfully." | ||||||
| result_detail.time = false | result-detail.exitstatus = true | ||||||
| result_detail.mem = false | result-detail.stderr = true | ||||||
| result_detail.stderr = true | result-detail.time = false | ||||||
|  | result-detail.mem = false | ||||||
|  | result-status.force_quit = true | ||||||
| 
 | 
 | ||||||
| [[stages]] | [[stages]] | ||||||
| name = "judge_base2" | name = "[cq] Filelength" | ||||||
| command = "./matlab-joj ./h3/ex5.m" | command = "./tools/filelength 400 300 *.cpp *.h" | ||||||
| score = 80 | files.import = [ "tools/filelength" ] | ||||||
| parsers = ["diff", "result-detail"] |  | ||||||
| 
 | 
 | ||||||
| files.import = ["tools/matlab-joj", "tools/matlab_formatter.py"] | parsers = [ "keyword", "result-detail" ] | ||||||
| files.export = ["output/ex5_results2.txt", "output/ex5_logs2.txt"] | keyword.keyword = [ "max", "recommended"] | ||||||
|  | keyword.weight = [ 20, 10 ] | ||||||
|  | result-detail.exitstatus = true | ||||||
|  | result-detail.stdout = true | ||||||
|  | result-detail.time = false | ||||||
|  | result-detail.mem = false | ||||||
| 
 | 
 | ||||||
| result_detail.time = true | [[stages]] | ||||||
| result_detail.mem = true | name = "[cq] Clang-tidy" | ||||||
| result_detail.stderr = false | 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 = "4m" | ||||||
|  | 
 | ||||||
|  | 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 = "8m" | ||||||
|  | 
 | ||||||
|  | parsers = [ "keyword", "cppcheck", "clangtidy", "result-detail", "cpplint", "result-status", "file", "dummy", "diff" ] | ||||||
|  | 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 = "65m" | ||||||
|  | 
 | ||||||
|  | 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" | ||||||
|  | command="./h7/build/ex2-asan -a" | ||||||
|  | files.import = [ "h7/build/ex2-asan" ] | ||||||
|  | limit.mem = "128m" | ||||||
|  | 
 | ||||||
|  | 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 = "0.5s" | ||||||
|  | case0.limit.mem = "5m" | ||||||
|  | case0.diff.output.ignore_spaces = true | ||||||
|  | #case0.limit.stdout = 8 | ||||||
|  | #case0.command = "./h7/build/ex2" | ||||||
|  | case0.in = "case0.in" | ||||||
|  | 
 | ||||||
|  | case1.diff.output.score = 5 | ||||||
|  | case1.limit.cpu = "1s" | ||||||
|  | case1.limit.mem = "5m" | ||||||
|  | case1.diff.output.ignore_spaces = true | ||||||
|  | #case1.limit.stdout = 8 | ||||||
|  | #case1.command = "./h7/build/ex2" | ||||||
|  | case1.in = "case1.in" | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								tests/convert/clang-tidy/repo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,2 @@ | ||||||
|  | force_skip_health_check_on_test = true | ||||||
|  | force_skip_teapot_on_test = true | ||||||
							
								
								
									
										140
									
								
								tests/convert/clang-tidy/task.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,140 @@ | ||||||
|  | { | ||||||
|  |     "name": "hw7 ex2", | ||||||
|  |     "logPath": "/home/tt/.cache/joj3/homework/h7/e2.log", | ||||||
|  |     "expireUnixTimestamp": 1735574399, | ||||||
|  |     "effectiveUnixTimestamp": 1735487999, | ||||||
|  |     "actorCsvPath": "/home/tt/.config/joj/students.csv", | ||||||
|  |     "maxTotalScore": 100, | ||||||
|  |     "stage": { | ||||||
|  |         "sandboxExecServer": "172.17.0.1:5051", | ||||||
|  |         "sandboxToken": "", | ||||||
|  |         "outputPath": "/tmp/joj3_result.json", | ||||||
|  |         "stages": [ | ||||||
|  |             { | ||||||
|  |                 "name": "[cq] Clang-tidy", | ||||||
|  |                 "group": "cq", | ||||||
|  |                 "executor": { | ||||||
|  |                     "name": "sandbox", | ||||||
|  |                     "with": { | ||||||
|  |                         "default": { | ||||||
|  |                             "args": [ | ||||||
|  |                                 "run-clang-tidy-18", | ||||||
|  |                                 "-header-filter=.*", | ||||||
|  |                                 "-quiet", | ||||||
|  |                                 "-load=/usr/local/lib/libcodequality.so", | ||||||
|  |                                 "-p", | ||||||
|  |                                 "h7/build", | ||||||
|  |                                 "h7/ex2.cpp" | ||||||
|  |                             ], | ||||||
|  |                             "env": [], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 68157440, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": { | ||||||
|  |                                 "tests/homework/h7/.clang-tidy": { | ||||||
|  |                                     "src": "/home/tt/.config/joj/tests/homework/h7/.clang-tidy" | ||||||
|  |                                 }, | ||||||
|  |                                 "h7/build/compile_commands.json": { | ||||||
|  |                                     "src": "/home/tt/.config/joj/h7/build/compile_commands.json" | ||||||
|  |                                 } | ||||||
|  |                             }, | ||||||
|  |                             "copyInCached": {}, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "clangtidy", | ||||||
|  |                         "with": { | ||||||
|  |                             "matches": [ | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "codequality-unchecked-malloc-result", | ||||||
|  |                                         "readability-duplicate-include", | ||||||
|  |                                         "readability-identifier-naming", | ||||||
|  |                                         "readability-redundant", | ||||||
|  |                                         "readability-misplaced-array-index", | ||||||
|  |                                         "cppcoreguidelines-init-variables", | ||||||
|  |                                         "bugprone-suspicious-string-compare", | ||||||
|  |                                         "google-global-names-in-headers", | ||||||
|  |                                         "clang-diagnostic", | ||||||
|  |                                         "clang-analyzer", | ||||||
|  |                                         "misc", | ||||||
|  |                                         "performance", | ||||||
|  |                                         "portability" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 5 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "codequality-no-global-variables", | ||||||
|  |                                         "codequality-no-header-guard", | ||||||
|  |                                         "codequality-no-fflush-stdin" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 20 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "readability-function-size" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 10 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "readability-misleading-indentation" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 15 | ||||||
|  |                                 } | ||||||
|  |                             ] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "result-detail", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "showFiles": [ | ||||||
|  |                                 "stdout" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": false, | ||||||
|  |                             "showMemory": false | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "preStages": [], | ||||||
|  |         "postStages": [] | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										20
									
								
								tests/convert/clang-tidy/task.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,20 @@ | ||||||
|  | # general task configuration | ||||||
|  | task.name = "hw7 ex2" # task name | ||||||
|  | task.type = "homework/h7/e2" # remove this task type later | ||||||
|  | 
 | ||||||
|  | release.end_time = 2024-12-30 23:59:59+08:00 | ||||||
|  | release.begin_time = 2024-12-29 23:59:59+08:00 | ||||||
|  | 
 | ||||||
|  | [[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 = "65m" | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
							
								
								
									
										2
									
								
								tests/convert/cppcheck/repo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,2 @@ | ||||||
|  | force_skip_health_check_on_test = true | ||||||
|  | force_skip_teapot_on_test = true | ||||||
							
								
								
									
										110
									
								
								tests/convert/cppcheck/task.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,110 @@ | ||||||
|  | { | ||||||
|  |     "name": "hw7 ex2", | ||||||
|  |     "logPath": "/home/tt/.cache/joj3/homework/h7/e2.log", | ||||||
|  |     "expireUnixTimestamp": 1735574399, | ||||||
|  |     "effectiveUnixTimestamp": 1735487999, | ||||||
|  |     "actorCsvPath": "/home/tt/.config/joj/students.csv", | ||||||
|  |     "maxTotalScore": 100, | ||||||
|  |     "stage": { | ||||||
|  |         "sandboxExecServer": "172.17.0.1:5051", | ||||||
|  |         "sandboxToken": "", | ||||||
|  |         "outputPath": "/tmp/joj3_result.json", | ||||||
|  |         "stages": [ | ||||||
|  |             { | ||||||
|  |                 "name": "[cq] Cppcheck", | ||||||
|  |                 "group": "cq", | ||||||
|  |                 "executor": { | ||||||
|  |                     "name": "sandbox", | ||||||
|  |                     "with": { | ||||||
|  |                         "default": { | ||||||
|  |                             "args": [ | ||||||
|  |                                 "cppcheck", | ||||||
|  |                                 "--template={\"file\":\"{file}\",\"line\":{line}, \"column\":{column}, \"severity\":\"{severity}\", \"message\":\"{message}\", \"id\":\"{id}\"}", | ||||||
|  |                                 "--force", | ||||||
|  |                                 "--enable=all", | ||||||
|  |                                 "--suppress=missingIncludeSystem", | ||||||
|  |                                 "--quiet", | ||||||
|  |                                 "h7/ex2.cpp" | ||||||
|  |                             ], | ||||||
|  |                             "env": [], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 68157440, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": {}, | ||||||
|  |                             "copyInCached": {}, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "cppcheck", | ||||||
|  |                         "with": { | ||||||
|  |                             "matches": [ | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "error" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 15 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "warning", | ||||||
|  |                                         "portability", | ||||||
|  |                                         "performance", | ||||||
|  |                                         "style" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 5 | ||||||
|  |                                 } | ||||||
|  |                             ] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "result-detail", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "showFiles": [ | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": false, | ||||||
|  |                             "showMemory": false | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "preStages": [], | ||||||
|  |         "postStages": [] | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								tests/convert/cppcheck/task.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,19 @@ | ||||||
|  | # general task configuration | ||||||
|  | task.name = "hw7 ex2" # task name | ||||||
|  | task.type = "homework/h7/e2" # remove this task type later | ||||||
|  | 
 | ||||||
|  | release.end_time = 2024-12-30 23:59:59+08:00 | ||||||
|  | release.begin_time = 2024-12-29 23:59:59+08:00 | ||||||
|  | 
 | ||||||
|  | [[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 = "65m" | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
							
								
								
									
										2
									
								
								tests/convert/cpplint/repo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,2 @@ | ||||||
|  | force_skip_health_check_on_test = true | ||||||
|  | force_skip_teapot_on_test = true | ||||||
							
								
								
									
										112
									
								
								tests/convert/cpplint/task.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,112 @@ | ||||||
|  | { | ||||||
|  |     "name": "hw7 ex2", | ||||||
|  |     "logPath": "/home/tt/.cache/joj3/homework/h7/e2.log", | ||||||
|  |     "expireUnixTimestamp": 1735574399, | ||||||
|  |     "effectiveUnixTimestamp": 1735487999, | ||||||
|  |     "actorCsvPath": "/home/tt/.config/joj/students.csv", | ||||||
|  |     "maxTotalScore": 100, | ||||||
|  |     "stage": { | ||||||
|  |         "sandboxExecServer": "172.17.0.1:5051", | ||||||
|  |         "sandboxToken": "", | ||||||
|  |         "outputPath": "/tmp/joj3_result.json", | ||||||
|  |         "stages": [ | ||||||
|  |             { | ||||||
|  |                 "name": "[cq] Cpplint", | ||||||
|  |                 "group": "cq", | ||||||
|  |                 "executor": { | ||||||
|  |                     "name": "sandbox", | ||||||
|  |                     "with": { | ||||||
|  |                         "default": { | ||||||
|  |                             "args": [ | ||||||
|  |                                 "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" | ||||||
|  |                             ], | ||||||
|  |                             "env": [], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 68157440, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": {}, | ||||||
|  |                             "copyInCached": {}, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "cpplint", | ||||||
|  |                         "with": { | ||||||
|  |                             "matches": [ | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "runtime" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 5 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "readability" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 20 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "build" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 10 | ||||||
|  |                                 } | ||||||
|  |                             ] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "result-detail", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "showFiles": [ | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": false, | ||||||
|  |                             "showMemory": false | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "preStages": [], | ||||||
|  |         "postStages": [] | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								tests/convert/cpplint/task.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,19 @@ | ||||||
|  | # general task configuration | ||||||
|  | task.name = "hw7 ex2" # task name | ||||||
|  | task.type = "homework/h7/e2" # remove this task type later | ||||||
|  | 
 | ||||||
|  | release.end_time = 2024-12-30 23:59:59+08:00 | ||||||
|  | release.begin_time = 2024-12-29 23:59:59+08:00 | ||||||
|  | 
 | ||||||
|  | [[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 = "65m" | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
							
								
								
									
										2
									
								
								tests/convert/diff/repo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,2 @@ | ||||||
|  | force_skip_health_check_on_test = true | ||||||
|  | force_skip_teapot_on_test = true | ||||||
							
								
								
									
										138
									
								
								tests/convert/diff/task.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,138 @@ | ||||||
|  | { | ||||||
|  |     "name": "hw7 ex2", | ||||||
|  |     "logPath": "/home/tt/.cache/joj3/homework/h7/e2.log", | ||||||
|  |     "expireUnixTimestamp": 1735574399, | ||||||
|  |     "effectiveUnixTimestamp": 1735487999, | ||||||
|  |     "actorCsvPath": "/home/tt/.config/joj/students.csv", | ||||||
|  |     "maxTotalScore": 100, | ||||||
|  |     "stage": { | ||||||
|  |         "sandboxExecServer": "172.17.0.1:5051", | ||||||
|  |         "sandboxToken": "", | ||||||
|  |         "outputPath": "/tmp/joj3_result.json", | ||||||
|  |         "stages": [ | ||||||
|  |             { | ||||||
|  |                 "name": "[joj] ex2-asan", | ||||||
|  |                 "group": "joj", | ||||||
|  |                 "executor": { | ||||||
|  |                     "name": "sandbox", | ||||||
|  |                     "with": { | ||||||
|  |                         "default": { | ||||||
|  |                             "args": [ | ||||||
|  |                                 "./h7/build/ex2-asan", | ||||||
|  |                                 "-a" | ||||||
|  |                             ], | ||||||
|  |                             "env": [], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 68157440, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": { | ||||||
|  |                                 "h7/build/ex2-asan": { | ||||||
|  |                                     "src": "/home/tt/.config/joj/h7/build/ex2-asan" | ||||||
|  |                                 } | ||||||
|  |                             }, | ||||||
|  |                             "copyInCached": {}, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [ | ||||||
|  |                             { | ||||||
|  |                                 "stdin": { | ||||||
|  |                                     "src": "/home/tt/.config/joj/diff/case0.in" | ||||||
|  |                                 }, | ||||||
|  |                                 "cpuLimit": 1000000000, | ||||||
|  |                                 "clockLimit": 2000000000, | ||||||
|  |                                 "memoryLimit": 2097152, | ||||||
|  |                                 "procLimit": 50 | ||||||
|  |                             }, | ||||||
|  |                             { | ||||||
|  |                                 "stdin": { | ||||||
|  |                                     "src": "/home/tt/.config/joj/diff/case1.in" | ||||||
|  |                                 }, | ||||||
|  |                                 "cpuLimit": 2000000000, | ||||||
|  |                                 "clockLimit": 4000000000, | ||||||
|  |                                 "memoryLimit": 4194304, | ||||||
|  |                                 "procLimit": 50 | ||||||
|  |                             } | ||||||
|  |                         ] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "diff", | ||||||
|  |                         "with": { | ||||||
|  |                             "name": "diff", | ||||||
|  |                             "cases": [ | ||||||
|  |                                 { | ||||||
|  |                                     "outputs": [ | ||||||
|  |                                         { | ||||||
|  |                                             "score": 5, | ||||||
|  |                                             "fileName": "stdout", | ||||||
|  |                                             "answerPath": "/home/tt/.config/joj/diff/case0.out", | ||||||
|  |                                             "forceQuitOnDiff": false, | ||||||
|  |                                             "alwaysHide": false, | ||||||
|  |                                             "compareSpace": false | ||||||
|  |                                         } | ||||||
|  |                                     ] | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "outputs": [ | ||||||
|  |                                         { | ||||||
|  |                                             "score": 5, | ||||||
|  |                                             "fileName": "stdout", | ||||||
|  |                                             "answerPath": "/home/tt/.config/joj/diff/case1.out", | ||||||
|  |                                             "forceQuitOnDiff": false, | ||||||
|  |                                             "alwaysHide": false, | ||||||
|  |                                             "compareSpace": false | ||||||
|  |                                         } | ||||||
|  |                                     ] | ||||||
|  |                                 } | ||||||
|  |                             ] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "result-detail", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "showFiles": [ | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": true, | ||||||
|  |                             "showMemory": true | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "preStages": [], | ||||||
|  |         "postStages": [] | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								tests/convert/diff/task.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,33 @@ | ||||||
|  | # general task configuration | ||||||
|  | task.name = "hw7 ex2" # task name | ||||||
|  | task.type = "homework/h7/e2" # remove this task type later | ||||||
|  | 
 | ||||||
|  | release.end_time = 2024-12-30 23:59:59+08:00 | ||||||
|  | release.begin_time = 2024-12-29 23:59:59+08:00 | ||||||
|  | 
 | ||||||
|  | [[stages]] | ||||||
|  | name = "[joj] ex2-asan" | ||||||
|  | command="./h7/build/ex2-asan -a" | ||||||
|  | files.import = [ "h7/build/ex2-asan" ] | ||||||
|  | limit.mem = "65m" | ||||||
|  | 
 | ||||||
|  | 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 = "1s" | ||||||
|  | case0.limit.mem = "2m" | ||||||
|  | case0.diff.output.ignore_spaces = true | ||||||
|  | #case0.limit.stdout = 8 | ||||||
|  | #case0.command = "./h7/build/ex2" | ||||||
|  | case0.in = "case0.in" | ||||||
|  | 
 | ||||||
|  | case1.diff.output.score = 5 | ||||||
|  | case1.limit.cpu = "2s" | ||||||
|  | case1.limit.mem = "4m" | ||||||
|  | case1.diff.output.ignore_spaces = true | ||||||
|  | #case1.limit.stdout = 8 | ||||||
|  | #case1.command = "./h7/build/ex2" | ||||||
|  | case1.in = "case1.in" | ||||||
							
								
								
									
										2
									
								
								tests/convert/keyword/repo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,2 @@ | ||||||
|  | force_skip_health_check_on_test = true | ||||||
|  | force_skip_teapot_on_test = true | ||||||
							
								
								
									
										109
									
								
								tests/convert/keyword/task.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,109 @@ | ||||||
|  | { | ||||||
|  |     "name": "hw7 ex2", | ||||||
|  |     "logPath": "/home/tt/.cache/joj3/homework/h7/e2.log", | ||||||
|  |     "expireUnixTimestamp": 1735574399, | ||||||
|  |     "effectiveUnixTimestamp": 1735487999, | ||||||
|  |     "actorCsvPath": "/home/tt/.config/joj/students.csv", | ||||||
|  |     "maxTotalScore": 100, | ||||||
|  |     "stage": { | ||||||
|  |         "sandboxExecServer": "172.17.0.1:5051", | ||||||
|  |         "sandboxToken": "", | ||||||
|  |         "outputPath": "/tmp/joj3_result.json", | ||||||
|  |         "stages": [ | ||||||
|  |             { | ||||||
|  |                 "name": "[cq] Filelength", | ||||||
|  |                 "group": "cq", | ||||||
|  |                 "executor": { | ||||||
|  |                     "name": "sandbox", | ||||||
|  |                     "with": { | ||||||
|  |                         "default": { | ||||||
|  |                             "args": [ | ||||||
|  |                                 "./tools/filelength", | ||||||
|  |                                 "400", | ||||||
|  |                                 "300", | ||||||
|  |                                 "*.cpp", | ||||||
|  |                                 "*.h" | ||||||
|  |                             ], | ||||||
|  |                             "env": [], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": { | ||||||
|  |                                 "tools/filelength": { | ||||||
|  |                                     "src": "/home/tt/.config/joj/tools/filelength" | ||||||
|  |                                 } | ||||||
|  |                             }, | ||||||
|  |                             "copyInCached": {}, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "keyword", | ||||||
|  |                         "with": { | ||||||
|  |                             "matches": [ | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "max" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 20 | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     "keywords": [ | ||||||
|  |                                         "recommended" | ||||||
|  |                                     ], | ||||||
|  |                                     "score": 10 | ||||||
|  |                                 } | ||||||
|  |                             ] | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "name": "result-detail", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "showFiles": [ | ||||||
|  |                                 "stdout" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": false, | ||||||
|  |                             "showMemory": false | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "preStages": [], | ||||||
|  |         "postStages": [] | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								tests/convert/keyword/task.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,19 @@ | ||||||
|  | # general task configuration | ||||||
|  | task.name = "hw7 ex2" # task name | ||||||
|  | task.type = "homework/h7/e2" # remove this task type later | ||||||
|  | 
 | ||||||
|  | release.end_time = 2024-12-30 23:59:59+08:00 | ||||||
|  | release.begin_time = 2024-12-29 23:59:59+08:00 | ||||||
|  | 
 | ||||||
|  | [[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 | ||||||
							
								
								
									
										2
									
								
								tests/convert/result-detail/repo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,2 @@ | ||||||
|  | force_skip_health_check_on_test = true | ||||||
|  | force_skip_teapot_on_test = true | ||||||
							
								
								
									
										91
									
								
								tests/convert/result-detail/task.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,91 @@ | ||||||
|  | { | ||||||
|  |     "name": "hw7 ex2", | ||||||
|  |     "logPath": "/home/tt/.cache/joj3/homework/h7/e2.log", | ||||||
|  |     "expireUnixTimestamp": 1735574399, | ||||||
|  |     "effectiveUnixTimestamp": 1735487999, | ||||||
|  |     "actorCsvPath": "/home/tt/.config/joj/students.csv", | ||||||
|  |     "maxTotalScore": 100, | ||||||
|  |     "stage": { | ||||||
|  |         "sandboxExecServer": "172.17.0.1:5051", | ||||||
|  |         "sandboxToken": "", | ||||||
|  |         "outputPath": "/tmp/joj3_result.json", | ||||||
|  |         "stages": [ | ||||||
|  |             { | ||||||
|  |                 "name": "[cq] Filelength", | ||||||
|  |                 "group": "cq", | ||||||
|  |                 "executor": { | ||||||
|  |                     "name": "sandbox", | ||||||
|  |                     "with": { | ||||||
|  |                         "default": { | ||||||
|  |                             "args": [ | ||||||
|  |                                 "./tools/filelength", | ||||||
|  |                                 "400", | ||||||
|  |                                 "300", | ||||||
|  |                                 "*.cpp", | ||||||
|  |                                 "*.h" | ||||||
|  |                             ], | ||||||
|  |                             "env": [], | ||||||
|  |                             "stdin": { | ||||||
|  |                                 "content": "" | ||||||
|  |                             }, | ||||||
|  |                             "stdout": { | ||||||
|  |                                 "name": "stdout", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "stderr": { | ||||||
|  |                                 "name": "stderr", | ||||||
|  |                                 "max": 33554432, | ||||||
|  |                                 "pipe": true | ||||||
|  |                             }, | ||||||
|  |                             "cpuLimit": 1000000000, | ||||||
|  |                             "clockLimit": 2000000000, | ||||||
|  |                             "memoryLimit": 134217728, | ||||||
|  |                             "stackLimit": 0, | ||||||
|  |                             "procLimit": 50, | ||||||
|  |                             "cpuRateLimit": 0, | ||||||
|  |                             "cpuSetLimit": "", | ||||||
|  |                             "copyIn": { | ||||||
|  |                                 "tools/filelength": { | ||||||
|  |                                     "src": "/home/tt/.config/joj/tools/filelength" | ||||||
|  |                                 } | ||||||
|  |                             }, | ||||||
|  |                             "copyInCached": {}, | ||||||
|  |                             "copyInDir": ".", | ||||||
|  |                             "copyOut": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "copyOutCached": [], | ||||||
|  |                             "copyOutMax": 0, | ||||||
|  |                             "copyOutDir": "", | ||||||
|  |                             "tty": false, | ||||||
|  |                             "strictMemoryLimit": false, | ||||||
|  |                             "dataSegmentLimit": false, | ||||||
|  |                             "addressSpaceLimit": false | ||||||
|  |                         }, | ||||||
|  |                         "cases": [] | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "parsers": [ | ||||||
|  |                     { | ||||||
|  |                         "name": "result-detail", | ||||||
|  |                         "with": { | ||||||
|  |                             "score": 0, | ||||||
|  |                             "comment": "", | ||||||
|  |                             "showFiles": [ | ||||||
|  |                                 "stdout", | ||||||
|  |                                 "stderr" | ||||||
|  |                             ], | ||||||
|  |                             "showExitStatus": true, | ||||||
|  |                             "showRuntime": false, | ||||||
|  |                             "showMemory": false | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "preStages": [], | ||||||
|  |         "postStages": [] | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								tests/convert/result-detail/task.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,18 @@ | ||||||
|  | # general task configuration | ||||||
|  | task.name = "hw7 ex2" # task name | ||||||
|  | task.type = "homework/h7/e2" # remove this task type later | ||||||
|  | 
 | ||||||
|  | release.end_time = 2024-12-30 23:59:59+08:00 | ||||||
|  | release.begin_time = 2024-12-29 23:59:59+08:00 | ||||||
|  | 
 | ||||||
|  | [[stages]] | ||||||
|  | name = "[cq] Filelength" | ||||||
|  | command = "./tools/filelength 400 300 *.cpp *.h" | ||||||
|  | files.import = [ "tools/filelength" ] | ||||||
|  | 
 | ||||||
|  | parsers = [ "result-detail" ] | ||||||
|  | result-detail.exitstatus = true | ||||||
|  | result-detail.stdout = true | ||||||
|  | result-detail.stderr = true | ||||||
|  | result-detail.time = false | ||||||
|  | result-detail.mem = false | ||||||
|  | @ -3,3 +3,27 @@ from tests.convert.utils import load_case | ||||||
| 
 | 
 | ||||||
| def test_basic() -> None: | def test_basic() -> None: | ||||||
|     load_case("basic") |     load_case("basic") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_clang_tidy() -> None: | ||||||
|  |     load_case("clang-tidy") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_cppcheck() -> None: | ||||||
|  |     load_case("cppcheck") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_cpplint() -> None: | ||||||
|  |     load_case("cpplint") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_diff() -> None: | ||||||
|  |     load_case("diff") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_keyword() -> None: | ||||||
|  |     load_case("keyword") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_result_detail() -> None: | ||||||
|  |     load_case("result-detail") | ||||||
|  |  | ||||||
|  | @ -1,32 +1,18 @@ | ||||||
| import json | import json | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
| from typing import Any, Dict, Tuple |  | ||||||
| 
 |  | ||||||
| import rtoml |  | ||||||
| 
 | 
 | ||||||
| from joj3_config_generator.convert import convert | from joj3_config_generator.convert import convert | ||||||
| from joj3_config_generator.models import repo, task | from joj3_config_generator.load import load_joj3_toml | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def read_convert_files( |  | ||||||
|     case_name: str, |  | ||||||
| ) -> Tuple[repo.Config, task.Config, Dict[str, Any]]: |  | ||||||
|     root = Path(__file__).resolve().parent / case_name |  | ||||||
|     repo_toml_path = root / "repo.toml" |  | ||||||
|     repo_toml = repo_toml_path.read_text() if repo_toml_path.exists() else "" |  | ||||||
|     task_toml_path = root / "task.toml" |  | ||||||
|     task_toml = task_toml_path.read_text() if task_toml_path.exists() else "" |  | ||||||
|     result = json.loads((root / "task.json").read_text()) |  | ||||||
|     return ( |  | ||||||
|         repo.Config(root=root, **rtoml.loads(repo_toml)), |  | ||||||
|         task.Config(root=root, **rtoml.loads(task_toml)), |  | ||||||
|         result, |  | ||||||
|     ) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def load_case(case_name: str) -> None: | def load_case(case_name: str) -> None: | ||||||
|     repo, task, expected_result = read_convert_files(case_name) |     root = Path(__file__).resolve().parent | ||||||
|     result = convert(repo, task).model_dump( |     repo_toml_path = root / case_name / "repo.toml" | ||||||
|  |     task_toml_path = root / case_name / "task.toml" | ||||||
|  |     repo_conf, task_conf = load_joj3_toml(root, repo_toml_path, task_toml_path) | ||||||
|  |     result_json_path = root / case_name / "task.json" | ||||||
|  |     expected_result = json.loads(result_json_path.read_text()) | ||||||
|  |     result = convert(repo_conf, task_conf).model_dump( | ||||||
|         mode="json", by_alias=True, exclude_none=True |         mode="json", by_alias=True, exclude_none=True | ||||||
|     ) |     ) | ||||||
|     assert result == expected_result |     assert result == expected_result | ||||||
|  |  | ||||||
|  | @ -1,23 +1,19 @@ | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
| from typing import Any, Dict, Tuple |  | ||||||
| 
 | 
 | ||||||
| import rtoml | import rtoml | ||||||
| import yaml |  | ||||||
| 
 | 
 | ||||||
| from joj3_config_generator.convert import convert_joj1 | from joj3_config_generator.convert import convert_joj1 | ||||||
| from joj3_config_generator.models import joj1 | from joj3_config_generator.load import load_joj1_yaml | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def read_convert_joj1_files(case_name: str) -> Tuple[joj1.Config, Dict[str, Any]]: |  | ||||||
|     root = Path(__file__).resolve().parent |  | ||||||
|     task_yaml_path = root / case_name / "task.yaml" |  | ||||||
|     task_yaml = task_yaml_path.read_text() |  | ||||||
|     task_toml_path = root / case_name / "task.toml" |  | ||||||
|     task_toml = task_toml_path.read_text() |  | ||||||
|     return joj1.Config(**yaml.safe_load(task_yaml)), rtoml.loads(task_toml) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def load_case(case_name: str) -> None: | def load_case(case_name: str) -> None: | ||||||
|     joj1, expected_result = read_convert_joj1_files(case_name) |     root = Path(__file__).resolve().parent | ||||||
|     result = convert_joj1(joj1).model_dump(by_alias=True, exclude_none=True) |     task_yaml_path = root / case_name / "task.yaml" | ||||||
|  |     task_yaml = load_joj1_yaml(task_yaml_path) | ||||||
|  |     task_toml_path = root / case_name / "task.toml" | ||||||
|  |     task_toml = task_toml_path.read_text() | ||||||
|  |     expected_result = rtoml.loads(task_toml) | ||||||
|  |     result = convert_joj1(task_yaml).model_dump( | ||||||
|  |         mode="json", by_alias=True, exclude_none=True | ||||||
|  |     ) | ||||||
|     assert result == expected_result |     assert result == expected_result | ||||||
|  |  | ||||||
this file should not be changed