Skip to content

Commit 821f4f9

Browse files
committed
Fix tests
1 parent fb681ec commit 821f4f9

File tree

5 files changed

+64
-42
lines changed

5 files changed

+64
-42
lines changed

grader.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ def _find_pattern(
560560
匹配结束的位置,未找到则返回-1
561561
"""
562562
if regex_mode:
563-
match = re.search(pattern, text[start_pos:])
563+
match = re.search(pattern, text[start_pos:], re.MULTILINE)
564564
if match:
565565
match_end = start_pos + match.end()
566566
return match_end
@@ -1243,8 +1243,12 @@ def _execute_interactive_steps(
12431243
# 获取步骤描述基础信息
12441244
step_name = step.get("name", step["command"])
12451245
base_description = current_description if current_description else f"Running {test.meta['name']}: {step_name}"
1246+
result = None
12461247

12471248
for i, interaction_step in enumerate(step.get("steps", []), 1):
1249+
if result:
1250+
break
1251+
12481252
step_type = interaction_step.get("type", "")
12491253

12501254
# 更新进度显示,显示内部步骤进度
@@ -1305,8 +1309,6 @@ def _execute_interactive_steps(
13051309
cmd,
13061310
args,
13071311
)
1308-
if result:
1309-
return result
13101312
elif step_type == "sleep":
13111313
self._handle_sleep_step(interaction_step)
13121314
elif step_type == "signal":
@@ -1326,8 +1328,6 @@ def _execute_interactive_steps(
13261328
cmd,
13271329
args,
13281330
)
1329-
if result:
1330-
return result
13311331

13321332
self.previous_step_type = step_type
13331333

@@ -1367,6 +1367,9 @@ def _execute_interactive_steps(
13671367
interactive_process.terminate()
13681368
if ref_process:
13691369
ref_process.terminate()
1370+
1371+
if result:
1372+
return result
13701373

13711374
# 如果没有分步评分,使用整体分数
13721375
if not self.step_scores:
@@ -1818,17 +1821,14 @@ def _resolve_relative_path(self, path: str, cwd: Path = os.getcwd()) -> str:
18181821
def _resolve_path(
18191822
self, path: str, test_dir: Path, cwd: Path = os.getcwd(), relative: bool = True
18201823
) -> str:
1821-
# 检查是否是预定义的可执行文件
18221824
if path.startswith("${") and path.endswith("}"):
1823-
# 提取可执行文件名称
18241825
exec_name = path[2:-1] # 去掉 ${ 和 }
1825-
# 检查是否在预定义的可执行文件列表中
18261826
if exec_name in self.config.executables:
1827-
# 替换为预定义的可执行文件路径
18281827
path = self.config.executables[exec_name]
18291828

18301829
build_dir = test_dir / "build"
18311830
build_dir.mkdir(exist_ok=True)
1831+
18321832
if relative:
18331833
replacements = {
18341834
"${test_dir}": self._resolve_relative_path(test_dir, cwd),
@@ -2483,6 +2483,11 @@ def _resolve_relative_path(self, path: str, cwd: Path = os.getcwd()) -> str:
24832483
return result
24842484

24852485
def _resolve_path(self, path: str, test_dir: Path, cwd: Path = os.getcwd()) -> str:
2486+
if path.startswith("${") and path.endswith("}"):
2487+
exec_name = path[2:-1]
2488+
if exec_name in self.config.executables:
2489+
path = self.config.executables[exec_name]
2490+
24862491
build_dir = test_dir / "build"
24872492
build_dir.mkdir(exist_ok=True)
24882493

tests/cases/10-fg/config.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ type = "close"
6666
# Wait for shell to finish processing
6767
[[run.steps]]
6868
type = "wait"
69-
timeout = 3.0
7069

7170
# Validate output against reference
7271
[[run.steps]]

tests/cases/17-cd/judge.py

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,50 @@ def judge():
1010
stdout = input_data["stdout"]
1111
max_score = input_data["max_score"]
1212

13-
# 查找 shell 提示符模式,以便正确识别命令输出
14-
prompt_pattern = r"[\w\d\-_]+[@:][\w\d\-_/]+[#$%>]"
15-
prompt_matches = re.findall(prompt_pattern, stdout)
16-
prompt = None
17-
if prompt_matches:
18-
# 使用最常见的提示符
19-
from collections import Counter
13+
prompt = "> "
14+
success = True
15+
score = 0
16+
17+
# 分析输出,查找命令和它们的输出
18+
commands_with_output = []
19+
20+
# 使用提示符分割输出
21+
lines = stdout.split("\n")
22+
prompt_line_indices = []
23+
24+
# 找出所有提示符所在行的索引
25+
for i, line in enumerate(lines):
26+
if line.startswith(prompt.strip()):
27+
prompt_line_indices.append(i)
28+
29+
# 解析每个命令和它的输出
30+
for i, prompt_index in enumerate(prompt_line_indices):
31+
# 获取命令
32+
cmd_line = lines[prompt_index]
33+
cmd = cmd_line[len(prompt.strip()) :].strip()
2034

21-
prompt = Counter(prompt_matches).most_common(1)[0][0]
35+
# 获取输出: 从命令行的下一行开始,到下一个提示符行(或文件结束)
36+
output_start = prompt_index + 1
37+
output_end = (
38+
prompt_line_indices[i + 1]
39+
if i + 1 < len(prompt_line_indices)
40+
else len(lines)
41+
)
42+
43+
# 如果没有输出行或者下一行就是提示符,则输出为空
44+
if output_start >= output_end:
45+
output = ""
46+
else:
47+
output = "\n".join(lines[output_start:output_end])
48+
49+
commands_with_output.append((cmd, output))
2250

2351
# 提取 pwd 命令的输出
2452
pwd_outputs = []
25-
if prompt:
26-
# 查找 pwd 命令的输出
27-
pwd_pattern = rf"{re.escape(prompt)} pwd\s*\n(.*?)(?={re.escape(prompt)}|$)"
28-
pwd_matches = re.findall(pwd_pattern, stdout, re.DOTALL)
29-
pwd_outputs = [match.strip() for match in pwd_matches]
30-
else:
31-
# 如果找不到提示符,尝试直接提取可能的路径
32-
path_pattern = r"/[a-zA-Z0-9_\-./]+"
33-
pwd_outputs = re.findall(path_pattern, stdout)
53+
54+
for cmd, output in commands_with_output:
55+
if cmd.strip() == "pwd":
56+
pwd_outputs.append(output.strip())
3457

3558
# 检查是否有至少两个不同的目录输出(初始目录和 cd 后的目录)
3659
success = False
@@ -44,17 +67,17 @@ def judge():
4467
try:
4568
first_dir = os.path.normpath(pwd_outputs[0])
4669
second_dir = os.path.normpath(pwd_outputs[1])
47-
parent_dir = os.path.normpath(os.path.join(first_dir, ".."))
70+
71+
# 支持中文路径,确保正确处理路径分隔符
72+
parent_dir = os.path.normpath(os.path.dirname(first_dir))
4873

4974
if second_dir == parent_dir:
5075
success = True
5176
message = "Directory change verified successfully"
5277
score = max_score
5378
else:
5479
message = f"Second directory ({second_dir}) is not the parent of first directory ({first_dir})"
55-
score = (
56-
max_score * 0.5
57-
) # 部分得分,因为目录确实改变了,但不是预期的父目录
80+
score = max_score * 0.5 # 部分得分,因为目录确实改变了,但不是预期的父目录
5881
except Exception as e:
5982
message = f"Error comparing directories: {str(e)}"
6083
else:

tests/cases/3-foreground-job/config.toml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ echo = false
2727

2828
# Quit the shell
2929
[[run.steps]]
30-
type = "input"
31-
content = "quit"
32-
echo = false
30+
type = "close"
3331

3432
# Wait for the shell to terminate
3533
[[run.steps]]
@@ -40,7 +38,7 @@ type = "check"
4038

4139
[run.steps.check.sequence]
4240
patterns = [
43-
{ pattern = "^Hello from foreground job!\n$", required = true, description = "First message" },
44-
{ pattern = "^Another message from tsh!\n$", required = true, description = "Second message" },
41+
{ pattern = "^Hello from foreground job!", required = true, description = "First message" },
42+
{ pattern = "^Another message from tsh!", required = true, description = "Second message" },
4543
]
4644
verify_end = true

tests/cases/4-background-job/config.toml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ echo = false
4141

4242
# Quit the shell
4343
[[run.steps]]
44-
type = "input"
45-
content = "quit"
46-
echo = false
44+
type = "close"
4745

4846
# Wait for the shell to terminate
4947
[[run.steps]]
@@ -54,8 +52,7 @@ type = "check"
5452

5553
[run.steps.check.sequence]
5654
patterns = [
57-
{ pattern = '''^\[\d+\] \(\d+\) \.\/myspin 1 &\n$''', required = true, description = "Background job started" },
58-
{ pattern = '''^\[\d+\] \(\d+\) Running \.\/myspin 1 &\n$''', required = true, description = "Background job running" },
59-
{ pattern = "^$", required = true, description = "Background job completed" },
55+
{ pattern = '''^\[\d+\] \(\d+\) \.\/myspin 2 &''', required = true, description = "Background job started" },
56+
{ pattern = '''^\[\d+\] \(\d+\) Running \.\/myspin 2 &''', required = true, description = "Background job running" },
6057
]
6158
verify_end = true

0 commit comments

Comments
 (0)