22import contextlib
33import io
44import tarfile
5+ from contextlib import nullcontext as does_not_raise
56from pathlib import Path
67from typing import cast
78
89import pytest
910
1011import run_release
1112from release import ReleaseShelf , Tag
13+ from run_release import ReleaseException
1214
1315
1416@pytest .mark .parametrize (
@@ -26,8 +28,7 @@ def test_check_sigstore_version_success(version) -> None:
2628)
2729def test_check_sigstore_version_exception (version ) -> None :
2830 with pytest .raises (
29- run_release .ReleaseException ,
30- match = "Sigstore version not detected or not valid" ,
31+ ReleaseException , match = "Sigstore version not detected or not valid"
3132 ):
3233 run_release .check_sigstore_version (version )
3334
@@ -46,21 +47,104 @@ def test_extract_github_owner(url: str, expected: str) -> None:
4647
4748def test_invalid_extract_github_owner () -> None :
4849 with pytest .raises (
49- run_release . ReleaseException ,
50+ ReleaseException ,
5051 match = "Could not parse GitHub owner from 'origin' remote URL: "
5152 "https://example.com" ,
5253 ):
5354 run_release .extract_github_owner ("https://example.com" )
5455
5556
57+ @pytest .mark .parametrize (
58+ ["release_tag" , "git_current_branch" , "expectation" ],
59+ [
60+ # Success cases
61+ ("3.15.0rc1" , "3.15\n " , does_not_raise ()),
62+ ("3.15.0b1" , "3.15\n " , does_not_raise ()),
63+ ("3.15.0a6" , "main\n " , does_not_raise ()),
64+ ("3.14.3" , "3.14\n " , does_not_raise ()),
65+ ("3.13.12" , "3.13\n " , does_not_raise ()),
66+ # Failure cases
67+ (
68+ "3.15.0rc1" ,
69+ "main\n " ,
70+ pytest .raises (ReleaseException , match = "on main branch, expected 3.15" ),
71+ ),
72+ (
73+ "3.15.0b1" ,
74+ "main\n " ,
75+ pytest .raises (ReleaseException , match = "on main branch, expected 3.15" ),
76+ ),
77+ (
78+ "3.15.0a6" ,
79+ "3.14\n " ,
80+ pytest .raises (ReleaseException , match = "on 3.14 branch, expected main" ),
81+ ),
82+ (
83+ "3.14.3" ,
84+ "main\n " ,
85+ pytest .raises (ReleaseException , match = "on main branch, expected 3.14" ),
86+ ),
87+ ],
88+ )
89+ def test_check_cpython_repo_branch (
90+ monkeypatch , release_tag : str , git_current_branch : str , expectation
91+ ) -> None :
92+ # Arrange
93+ db = {"release" : Tag (release_tag ), "git_repo" : "/fake/repo" }
94+ monkeypatch .setattr (
95+ run_release .subprocess ,
96+ "check_output" ,
97+ lambda * args , ** kwargs : git_current_branch ,
98+ )
99+
100+ # Act / Assert
101+ with expectation :
102+ run_release .check_cpython_repo_branch (cast (ReleaseShelf , db ))
103+
104+
105+ @pytest .mark .parametrize (
106+ ["age_seconds" , "user_continues" , "expectation" ],
107+ [
108+ # Recent repo (< 1 day) - no question asked
109+ (3600 , None , does_not_raise ()),
110+ # Old repo (> 1 day) + user says yes
111+ (90000 , True , does_not_raise ()),
112+ # Old repo (> 1 day) + user says no
113+ (90000 , False , pytest .raises (ReleaseException , match = "repository is old" )),
114+ ],
115+ )
116+ def test_check_cpython_repo_age (
117+ monkeypatch , age_seconds : int , user_continues : bool | None , expectation
118+ ) -> None :
119+ # Arrange
120+ db = {"release" : Tag ("3.15.0a6" ), "git_repo" : "/fake/repo" }
121+ current_time = 1700000000
122+ commit_timestamp = current_time - age_seconds
123+
124+ def fake_check_output (cmd , ** kwargs ):
125+ cmd_str = " " .join (cmd )
126+ if "%ct" in cmd_str :
127+ return f"{ commit_timestamp } \n "
128+ if "%cr" in cmd_str :
129+ return "some time ago\n "
130+ return ""
131+
132+ monkeypatch .setattr (run_release .subprocess , "check_output" , fake_check_output )
133+ monkeypatch .setattr (run_release .time , "time" , lambda : current_time )
134+ if user_continues is not None :
135+ monkeypatch .setattr (run_release , "ask_question" , lambda _ : user_continues )
136+
137+ # Act / Assert
138+ with expectation :
139+ run_release .check_cpython_repo_age (cast (ReleaseShelf , db ))
140+
141+
56142def test_check_magic_number () -> None :
57143 db = {
58144 "release" : Tag ("3.14.0rc1" ),
59145 "git_repo" : str (Path (__file__ ).parent / "magicdata" ),
60146 }
61- with pytest .raises (
62- run_release .ReleaseException , match = "Magic numbers in .* don't match"
63- ):
147+ with pytest .raises (ReleaseException , match = "Magic numbers in .* don't match" ):
64148 run_release .check_magic_number (cast (ReleaseShelf , db ))
65149
66150
0 commit comments