Co-authored-by: Cloud User <ec2-user@ip-10-128-23-129.ec2.internal> Co-authored-by: Noah Stapp <noah.stapp@mongodb.com>
124 lines
4.2 KiB
Python
124 lines
4.2 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import os
|
|
import pathlib
|
|
import subprocess
|
|
from argparse import Namespace
|
|
from subprocess import CalledProcessError
|
|
from typing import Optional
|
|
|
|
|
|
def resync_specs(directory: pathlib.Path, errored: dict[str, str]) -> None:
|
|
"""Actually sync the specs"""
|
|
print("Beginning to sync specs") # noqa: T201
|
|
for spec in os.scandir(directory):
|
|
if not spec.is_dir():
|
|
continue
|
|
|
|
if spec.name in ["asynchronous"]:
|
|
continue
|
|
try:
|
|
subprocess.run(
|
|
["bash", "./.evergreen/resync-specs.sh", spec.name], # noqa: S603, S607
|
|
capture_output=True,
|
|
text=True,
|
|
check=True,
|
|
)
|
|
except CalledProcessError as exc:
|
|
errored[spec.name] = exc.stderr
|
|
print("Done syncing specs") # noqa: T201
|
|
|
|
|
|
def apply_patches():
|
|
print("Beginning to apply patches") # noqa: T201
|
|
subprocess.run(["bash", "./.evergreen/remove-unimplemented-tests.sh"], check=True) # noqa: S603, S607
|
|
subprocess.run(
|
|
["git apply -R --allow-empty --whitespace=fix ./.evergreen/spec-patch/*"], # noqa: S607
|
|
shell=True, # noqa: S602
|
|
check=True,
|
|
)
|
|
|
|
|
|
def check_new_spec_directories(directory: pathlib.Path) -> list[str]:
|
|
"""Check to see if there are any directories in the spec repo that don't exist in pymongo/test"""
|
|
spec_dir = pathlib.Path(os.environ["MDB_SPECS"]) / "source"
|
|
spec_set = {
|
|
entry.name.replace("-", "_")
|
|
for entry in os.scandir(spec_dir)
|
|
if entry.is_dir()
|
|
and (pathlib.Path(entry.path) / "tests").is_dir()
|
|
and len(list(os.scandir(pathlib.Path(entry.path) / "tests"))) > 1
|
|
}
|
|
test_set = {entry.name.replace("-", "_") for entry in os.scandir(directory) if entry.is_dir()}
|
|
known_mappings = {
|
|
"ocsp_support": "ocsp",
|
|
"client_side_operations_timeout": "csot",
|
|
"mongodb_handshake": "handshake",
|
|
"load_balancers": "load_balancer",
|
|
"atlas_data_lake_testing": "atlas",
|
|
"connection_monitoring_and_pooling": "connection_monitoring",
|
|
"command_logging_and_monitoring": "command_logging",
|
|
"initial_dns_seedlist_discovery": "srv_seedlist",
|
|
"server_discovery_and_monitoring": "sdam_monitoring",
|
|
}
|
|
|
|
for k, v in known_mappings.items():
|
|
if k in spec_set:
|
|
spec_set.remove(k)
|
|
spec_set.add(v)
|
|
return list(spec_set - test_set)
|
|
|
|
|
|
def write_summary(errored: dict[str, str], new: list[str], filename: Optional[str]) -> None:
|
|
"""Generate the PR description"""
|
|
pr_body = ""
|
|
process = subprocess.run(
|
|
["git diff --name-only | awk -F'/' '{print $2}' | sort | uniq"], # noqa: S607
|
|
shell=True, # noqa: S602
|
|
capture_output=True,
|
|
text=True,
|
|
check=True,
|
|
)
|
|
succeeded = process.stdout.strip().split()
|
|
if len(succeeded) > 0:
|
|
pr_body += "The following specs were changed:\n -"
|
|
pr_body += "\n -".join(succeeded)
|
|
pr_body += "\n"
|
|
if len(errored) > 0:
|
|
pr_body += "\n\nThe following spec syncs encountered errors:\n -"
|
|
for k, v in errored.items():
|
|
pr_body += f"\n -{k}\n```{v}\n```"
|
|
pr_body += "\n"
|
|
if len(new) > 0:
|
|
pr_body += "\n\nThe following directories are in the specification repository and not in our test directory:\n -"
|
|
pr_body += "\n -".join(new)
|
|
pr_body += "\n"
|
|
if pr_body != "":
|
|
if filename is None:
|
|
print(f"\n{pr_body}") # noqa: T201
|
|
else:
|
|
with open(filename, "w") as f:
|
|
# replacements made for proper json
|
|
f.write(pr_body.replace("\n", "\\n").replace("\t", "\\t"))
|
|
|
|
|
|
def main(args: Namespace):
|
|
directory = pathlib.Path("./test")
|
|
errored: dict[str, str] = {}
|
|
resync_specs(directory, errored)
|
|
apply_patches()
|
|
new = check_new_spec_directories(directory)
|
|
write_summary(errored, new, args.filename)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(
|
|
description="Python Script to resync all specs and generate summary for PR."
|
|
)
|
|
parser.add_argument(
|
|
"--filename", help="Name of file for the summary to be written into.", default=None
|
|
)
|
|
args = parser.parse_args()
|
|
main(args)
|