3
import multiprocessing as mp
7
from typing import Any, Dict, List, Optional, Tuple
10
import rockset # type: ignore[import]
11
from gitutils import retries_decorator
17
push.head_commit.id as sha,
21
push.ref = 'refs/heads/viable/strict'
22
AND push.repository.full_name = 'pytorch/pytorch'
33
join shas on shas.sha = j.head_sha
35
j.name like '% / test%'
36
and j.name not like '%rerun_disabled_tests%'
37
and j.name not like '%mem_leak_check%'
40
TEST_EXISTS_QUERY = """
46
cast(name as string) like :name
47
and classname like :classname
48
and _event_time > CURRENT_TIMESTAMP() - DAYS(7)
52
"I cannot find any mention of this test in rockset for the past 7 days "
53
"or in the logs for the past 5 commits on viable/strict. Closing this "
54
"issue as it is highly likely that this test has either been renamed or "
55
"removed. If you think this is a false positive, please feel free to "
59
DISABLED_TESTS_JSON = (
60
"https://ossci-metrics.s3.amazonaws.com/disabled-tests-condensed.json"
64
def parse_args() -> Any:
65
parser = argparse.ArgumentParser()
69
help="Only list the tests.",
71
return parser.parse_args()
76
query: str, params: Optional[Dict[str, Any]] = None
77
) -> List[Dict[str, Any]]:
78
res = rockset.RocksetClient(
79
host="api.rs2.usw2.rockset.com", api_key=os.environ["ROCKSET_API_KEY"]
81
results: List[Dict[str, Any]] = res.results
85
def download_log_worker(temp_dir: str, id: int, name: str) -> None:
86
url = f"https://ossci-raw-job-status.s3.amazonaws.com/log/{id}"
87
data = requests.get(url).text
88
with open(f"{temp_dir}/{name.replace('/', '_')} {id}.txt", "x") as f:
92
def printer(item: Tuple[str, Tuple[int, str, List[Any]]], extra: str) -> None:
93
test, (_, link, _) = item
94
print(f"{link:<55} {test:<120} {extra}")
97
def close_issue(num: int) -> None:
99
"Accept": "application/vnd.github.v3+json",
100
"Authorization": f"token {os.environ['GITHUB_TOKEN']}",
103
f"https://api.github.com/repos/pytorch/pytorch/issues/{num}/comments",
104
data=json.dumps({"body": CLOSING_COMMENT}),
108
f"https://api.github.com/repos/pytorch/pytorch/issues/{num}",
109
data=json.dumps({"state": "closed"}),
115
item: Tuple[str, Tuple[int, str, List[str]]], all_logs: List[str]
116
) -> Tuple[bool, str]:
117
test, (_, link, _) = item
118
# Test names should look like `test_a (module.path.classname)`
119
reg = re.match(r"(\S+) \((\S*)\)", test)
121
return False, "poorly formed"
124
classname = reg[2].split(".")[-1]
126
# Check if there is any mention of the link or the test name in the logs.
127
# The link usually shows up in the skip reason.
133
if f"{classname}::{name}" in log:
137
return True, "found in logs"
139
# Query rockset to see if the test is there
140
count = query_rockset(
141
TEST_EXISTS_QUERY, {"name": f"{name}%", "classname": f"{classname}%"}
143
if count[0]["c"] == 0:
144
return False, "not found"
145
return True, "found in rockset"
148
if __name__ == "__main__":
150
disabled_tests_json = json.loads(requests.get(DISABLED_TESTS_JSON).text)
153
jobs = query_rockset(LOGS_QUERY)
154
with tempfile.TemporaryDirectory() as temp_dir:
159
pool.apply_async(download_log_worker, args=(temp_dir, id, name))
163
for filename in os.listdir(temp_dir):
164
with open(f"{temp_dir}/{filename}") as f:
165
all_logs.append(f.read())
167
# If its less than 200 something definitely went wrong.
168
assert len(all_logs) > 200
169
assert len(all_logs) == len(jobs)
172
for item in disabled_tests_json.items():
173
exists, reason = check_if_exists(item, all_logs)
174
printer(item, reason)
176
to_be_closed.append(item)
178
print(f"There are {len(to_be_closed)} issues that will be closed:")
179
for item in to_be_closed:
183
print("dry run, not actually closing")
185
for item in to_be_closed:
186
_, (num, _, _) = item