feat: support overwrite of groups & max_total_score in task.toml (#22)
All checks were successful
build / build (push) Successful in 2m30s
build / trigger-build-image (push) Successful in 12s

support #21

Reviewed-on: #22
Co-authored-by: jon-lee <jon-lee@sjtu.edu.cn>
Co-committed-by: jon-lee <jon-lee@sjtu.edu.cn>
This commit is contained in:
李衍志523370910113 2025-06-10 15:39:12 +08:00 committed by 李衍志523370910113
parent 45450b4451
commit f72189dc81
6 changed files with 50 additions and 14 deletions

View File

@ -29,19 +29,25 @@ def convert_joj3_conf(repo_conf: repo.Config, task_conf: task.Config) -> result.
expire_unix_timestamp=int(task_conf.release.end_time.timestamp()), expire_unix_timestamp=int(task_conf.release.end_time.timestamp()),
effective_unix_timestamp=int(task_conf.release.begin_time.timestamp()), effective_unix_timestamp=int(task_conf.release.begin_time.timestamp()),
actor_csv_path=str(ACTOR_CSV_PATH), # students.csv position actor_csv_path=str(ACTOR_CSV_PATH), # students.csv position
max_total_score=repo_conf.max_total_score, max_total_score=(
repo_conf.max_total_score
if not task_conf.max_total_score
else task_conf.max_total_score
),
stage=result.Stage(sandbox_token=repo_conf.sandbox_token), stage=result.Stage(sandbox_token=repo_conf.sandbox_token),
) )
current_test = os.environ.get("PYTEST_CURRENT_TEST") is not None current_test = os.environ.get("PYTEST_CURRENT_TEST") is not None
# Construct health check stage # Construct health check stage
if not repo_conf.force_skip_health_check_on_test or not current_test: 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)) result_conf.stage.stages.append(get_health_check_stage(repo_conf, task_conf))
cached: Dict[str, None] = {} 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:
result_conf.stage.stages.append(get_conf_stage(task_conf, task_stage, cached)) result_conf.stage.stages.append(get_conf_stage(task_conf, task_stage, cached))
if not repo_conf.force_skip_teapot_on_test or not current_test: if not repo_conf.force_skip_teapot_on_test or not current_test:
result_conf.stage.post_stages.append(get_teapot_post_stage(repo_conf)) result_conf.stage.post_stages.append(
get_teapot_post_stage(repo_conf, task_conf)
)
return result_conf return result_conf

View File

@ -20,6 +20,7 @@ from joj3_config_generator.models.const import (
DEFAULT_MEMORY_LIMIT, DEFAULT_MEMORY_LIMIT,
DEFAULT_PROC_LIMIT, DEFAULT_PROC_LIMIT,
) )
from joj3_config_generator.models.repo import Groups
class ParserResultDetail(BaseModel): class ParserResultDetail(BaseModel):
@ -204,3 +205,7 @@ class Config(BaseModel):
task: Task = Task() # Task name (e.g., hw3 ex5) task: Task = Task() # Task name (e.g., hw3 ex5)
release: Release = Release() # Release configuration release: Release = Release() # Release configuration
stages: List[Stage] = [] # list of stage configurations stages: List[Stage] = [] # list of stage configurations
groups: Groups = Groups()
max_total_score: int = Field(
100, validation_alias=AliasChoices("max-total-score", "max_total_score")
)

View File

@ -2,11 +2,13 @@ import hashlib
from pathlib import Path from pathlib import Path
from typing import List from typing import List
from joj3_config_generator.models import common, repo, result from joj3_config_generator.models import common, repo, result, task
from joj3_config_generator.models.const import TEAPOT_CONFIG_ROOT, TEAPOT_LOG_PATH from joj3_config_generator.models.const import TEAPOT_CONFIG_ROOT, TEAPOT_LOG_PATH
def get_teapot_post_stage(repo_conf: repo.Config) -> result.StageDetail: def get_teapot_post_stage(
repo_conf: repo.Config, task_conf: task.Config
) -> result.StageDetail:
args = [ args = [
"/usr/local/bin/joint-teapot", "/usr/local/bin/joint-teapot",
"joj3-all-env", "joj3-all-env",
@ -14,7 +16,11 @@ def get_teapot_post_stage(repo_conf: repo.Config) -> result.StageDetail:
"--grading-repo-name", "--grading-repo-name",
repo_conf.grading_repo_name, repo_conf.grading_repo_name,
"--max-total-score", "--max-total-score",
str(repo_conf.max_total_score), (
str(repo_conf.max_total_score)
if not task_conf.max_total_score
else str(task_conf.max_total_score)
),
] ]
if not repo_conf.submitter_in_issue_title: if not repo_conf.submitter_in_issue_title:
args.append("--no-submitter-in-issue-title") args.append("--no-submitter-in-issue-title")
@ -52,7 +58,7 @@ def get_health_check_args(repo_conf: repo.Config) -> List[str]:
] ]
def get_teapot_check_args(repo_conf: repo.Config) -> List[str]: def get_teapot_check_args(repo_conf: repo.Config, task_conf: task.Config) -> List[str]:
res = [ res = [
"/usr/local/bin/joint-teapot", "/usr/local/bin/joint-teapot",
"joj3-check-env", "joj3-check-env",
@ -69,11 +75,24 @@ def get_teapot_check_args(repo_conf: repo.Config) -> List[str]:
repo_conf.groups.time_period_hour, repo_conf.groups.time_period_hour,
) )
) )
res.extend(["--group-config", group_config_str]) if task_conf.groups.name:
overwrite_group_config_str = ",".join(
f"{name}={max_count}:{time_period}"
for name, max_count, time_period in zip(
task_conf.groups.name,
task_conf.groups.max_count,
task_conf.groups.time_period_hour,
)
)
res.extend(["--group-config", overwrite_group_config_str])
else:
res.extend(["--group-config", group_config_str])
return res return res
def get_health_check_stage(repo_conf: repo.Config) -> result.StageDetail: def get_health_check_stage(
repo_conf: repo.Config, task_conf: task.Config
) -> result.StageDetail:
health_check_stage = result.StageDetail( health_check_stage = result.StageDetail(
name="Health Check", name="Health Check",
group="", group="",
@ -88,7 +107,7 @@ def get_health_check_stage(repo_conf: repo.Config) -> result.StageDetail:
args=get_health_check_args(repo_conf), args=get_health_check_args(repo_conf),
), ),
result.OptionalCmd( result.OptionalCmd(
args=get_teapot_check_args(repo_conf), args=get_teapot_check_args(repo_conf, task_conf),
env=[f"LOG_FILE_PATH={TEAPOT_LOG_PATH}"], env=[f"LOG_FILE_PATH={TEAPOT_LOG_PATH}"],
), ),
], ],

View File

@ -2,7 +2,7 @@ grading-repo-name = "ece280-joj"
sandbox-token = "test" sandbox-token = "test"
# reconfigure later # reconfigure later
max-total-score = 100 max-total-score = 1000
max-size = 50.5 max-size = 50.5
# for tests # for tests

View File

@ -4,7 +4,7 @@
"expireUnixTimestamp": 1735574399, "expireUnixTimestamp": 1735574399,
"effectiveUnixTimestamp": 1735487999, "effectiveUnixTimestamp": 1735487999,
"actorCsvPath": "/home/tt/.config/joj/students.csv", "actorCsvPath": "/home/tt/.config/joj/students.csv",
"maxTotalScore": 100, "maxTotalScore": 10245871,
"stage": { "stage": {
"sandboxExecServer": "172.17.0.1:5051", "sandboxExecServer": "172.17.0.1:5051",
"sandboxToken": "test", "sandboxToken": "test",
@ -76,7 +76,7 @@
"--grading-repo-name", "--grading-repo-name",
"ece280-joj", "ece280-joj",
"--group-config", "--group-config",
"joj=1000:24,run=1000:24" "Manuel=500:24,Boming=501:48,Nuvole=502:72"
], ],
"env": [ "env": [
"LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log" "LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"
@ -798,7 +798,7 @@
"--grading-repo-name", "--grading-repo-name",
"ece280-joj", "ece280-joj",
"--max-total-score", "--max-total-score",
"100" "10245871"
], ],
"env": [ "env": [
"LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log" "LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"

View File

@ -1,9 +1,15 @@
# general task configuration # general task configuration
task.name = "hw7 ex2" # task name task.name = "hw7 ex2" # task name
max-total-score = 10245871
release.end-time = 2024-12-30 23:59:59+08:00 release.end-time = 2024-12-30 23:59:59+08:00
release.begin-time = 2024-12-29 23:59:59+08:00 release.begin-time = 2024-12-29 23:59:59+08:00
[groups]
name = ["Manuel", "Boming", "Nuvole"]
max-count = [500, 501, 502]
time-period-hour = [24, 48, 72]
[[stages]] [[stages]]
name = "Compilation" name = "Compilation"
env = [ "CC=clang", "CXX=clang++" ] env = [ "CC=clang", "CXX=clang++" ]