Repository navigation
Expand file tree
/
Copy pathmain.py
More file actions
173 lines (151 loc) · 8.23 KB
/
Copy pathmain.py
File metadata and controls
173 lines (151 loc) · 8.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import os
import sys
import logging
import argparse
import traceback
from datetime import timedelta
import subprocess
from typing import List
import run
from email_sender import send_mail, create_report, get_driver_origin_remote
logging.basicConfig(level=logging.INFO)
def resolve_driver_version(repo_directory: str, checkout_ref: str) -> str:
try:
version = subprocess.check_output(
[
"git",
"-C",
repo_directory,
"describe",
"--tags",
"--abbrev=0",
"--match",
"[0-9]*",
checkout_ref,
],
text=True,
).strip()
except subprocess.CalledProcessError as exc:
raise ValueError(
f"Unable to resolve a driver version tag for ref '{checkout_ref}' in '{repo_directory}'"
) from exc
if not version:
raise ValueError(f"Unable to resolve a driver version tag for ref '{checkout_ref}' in '{repo_directory}'")
return version
def main(java_driver_git, scylla_install_dir, tests, versions, driver_type, scylla_version, recipients, patch_only=False, checkout_ref=None, driver_version=None):
status = 0
results = {}
if driver_version:
versions = [driver_version]
logging.info("Testing driver ref '%s' as version '%s'", checkout_ref or driver_version, driver_version)
elif checkout_ref:
versions = [resolve_driver_version(java_driver_git, checkout_ref)]
logging.info("Resolved driver ref '%s' to version '%s'", checkout_ref, versions[0])
logging.info("=== Going to test those versions: %s", versions)
for version in versions:
logging.info("=== JAVA DRIVER VERSION %s ===", version)
runner = run.Run(
java_driver_git=java_driver_git,
scylla_install_dir=scylla_install_dir,
tag=version,
tests=tests,
driver_type=driver_type,
scylla_version=scylla_version,
patch_only=patch_only,
checkout_ref=checkout_ref)
try:
report = runner.run()
if report is None:
# patch-only mode — no test report to process
results[version] = {'patch_only': True, 'status': 'OK'}
continue
logging.info("=== JAVA DRIVER MATRIX RESULTS FOR %s ===", version)
logging.info(", ".join(f"{key}: {value}" for key, value in report.summary.items()))
if report.is_failed:
status = 1
if not run.DEV_MODE:
report.clear_original_reports()
results[version] = report.summary
results[version]['time'] = str(timedelta(seconds=results[version]['time']))[:-3]
except Exception:
logging.exception(f"{version} failed")
status = 1
exc_type, exc_value, exc_traceback = sys.exc_info()
failure_reason = traceback.format_exception(exc_type, exc_value, exc_traceback)
results[version] = dict(exception=failure_reason)
runner.create_metadata_for_failure(reason="\n".join(failure_reason))
if recipients and not patch_only:
email_report = create_report(results=results)
email_report['driver_remote'] = get_driver_origin_remote(java_driver_git)
email_report['status'] = "SUCCESS" if status == 0 else "FAILED"
send_mail(recipients, email_report)
quit(status)
def extract_n_latest_repo_tags(repo_directory: str, major_versions: List[str], latest_tags_size: int = 2,
is_scylla_driver: bool = True) -> List[str]:
major_versions = sorted(major_versions, key=lambda major_ver: float(major_ver))
filter_version = "| grep -P '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'" if is_scylla_driver else "| grep -P '^[0-9]+\.[0-9]+\.[0-9]+$'"
commands = [f"cd {repo_directory}", "git checkout .", ]
if not os.environ.get("DEV_MODE", False):
commands.append("git fetch -p --all")
commands.append(f"git tag --sort=-creatordate {filter_version}")
selected_tags = {}
ignore_tags = set()
result = []
lines = subprocess.check_output("\n".join(commands), shell=True).decode().splitlines()
for repo_tag in lines:
if "." in repo_tag:
version = tuple(repo_tag.split(".", maxsplit=3)[:3])
if version not in ignore_tags:
ignore_tags.add(version)
selected_tags.setdefault(repo_tag[0], []).append(repo_tag)
for major_version in major_versions:
if len(selected_tags[major_version]) < latest_tags_size:
raise ValueError(f"There are no '{latest_tags_size}' different versions that start with the major version"
f" '{major_version}'")
result.extend(selected_tags[major_version][:latest_tags_size])
return result
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('java_driver_git', help='folder with git repository of java-driver')
parser.add_argument('scylla_install_dir',
help='folder with scylla installation, e.g. a checked out git scylla has been built',
nargs='?', default='')
parser.add_argument('--versions', default=[],
help='java-driver versions to test')
parser.add_argument('--tests', default='',
help='Initial tests list to pass along. Runner will modify it according to ignore.yaml from version patch. default=\'\'')
parser.add_argument('--scylla-version', help="relocatable scylla version to use", default=os.environ.get('SCYLLA_VERSION', None))
parser.add_argument('--checkout-ref', help="git ref to checkout before testing. When set, the driver version is resolved from this ref and the value in --versions is ignored.", default=None)
parser.add_argument('--driver-version', help="version used to select matrix patches and ignores for --checkout-ref, even when that ref is untagged", default=None)
parser.add_argument('--recipients', help="whom to send mail at the end of the run", nargs='+', default=None)
parser.add_argument('--driver-type', help='Type of java-driver ("scylla" or "apache")',
dest='driver_type', default='apache')
parser.add_argument('--patch-only', action='store_true', default=False,
help='Only check out and apply patches, skip build and tests. Used for release validation.')
parser.add_argument('--version-size', help='The number of the latest versions that will test.'
'The version is filtered by the major and minor values.'
'For example, the user selects the 2 latest versions for version 4.'
'The values to be returned are: 4.9.0-scylla-1 and 4.8.0-scylla-0',
type=int, default=None, nargs='?')
arguments = parser.parse_args()
if arguments.driver_version and not arguments.checkout_ref:
parser.error("--driver-version requires --checkout-ref")
versions = []
_input_versions = []
if not isinstance(arguments.versions, list):
versions = _input_versions = arguments.versions.split(',')
if arguments.version_size:
# all one digit version, would be used to look up latest tags
versions = extract_n_latest_repo_tags(arguments.java_driver_git, list({v.split('.')[0] for v in _input_versions}),
latest_tags_size=arguments.version_size,
is_scylla_driver=arguments.driver_type == "scylla")
# add back all the full qualified versions specified in `--versions` (i.e. not one digit versions)
versions += [v for v in _input_versions if len(v.split('.')) > 1]
main(java_driver_git=arguments.java_driver_git, scylla_install_dir=arguments.scylla_install_dir,
tests=arguments.tests, versions=versions,
scylla_version=arguments.scylla_version,
driver_type=arguments.driver_type,
recipients=arguments.recipients,
patch_only=arguments.patch_only,
checkout_ref=arguments.checkout_ref,
driver_version=arguments.driver_version)