Skip to content

Commit be85cc8

Browse files
Add support for test result ingestion in the CLI (#347)
* feat: add test result file finding in FileFinder * feat: update upload collector to handle test result files * feat: update upload senders to handle test result files * feat: add report type option and rename coverage files options to files * tests: add tests for test_results * fix: fix file finder excluded patterns * tests: update file finder tests * tests: add tests for generate_upload_data * fix: move url and data choice to separate function in upload sender * fix: no more prep plugins in test results upload * fix: pass report type to file finder constructor * test: fix tests due to prep plugin and file finder changes Signed-off-by: joseph-sentry <joseph.sawaya@sentry.io>
1 parent f3827b3 commit be85cc8

14 files changed

Lines changed: 513 additions & 170 deletions

codecov_cli/commands/upload.py

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ def _turn_env_vars_into_dict(ctx, params, value):
3333
"-s",
3434
"--dir",
3535
"--coverage-files-search-root-folder",
36-
"coverage_files_search_root_folder",
36+
"--files-search-root-folder",
37+
"files_search_root_folder",
3738
help="Folder where to search for coverage files",
3839
type=click.Path(path_type=pathlib.Path),
3940
default=pathlib.Path.cwd,
@@ -42,7 +43,8 @@ def _turn_env_vars_into_dict(ctx, params, value):
4243
click.option(
4344
"--exclude",
4445
"--coverage-files-search-exclude-folder",
45-
"coverage_files_search_exclude_folders",
46+
"--files-search-exclude-folder",
47+
"files_search_exclude_folders",
4648
help="Folders to exclude from search",
4749
type=click.Path(path_type=pathlib.Path),
4850
multiple=True,
@@ -52,7 +54,8 @@ def _turn_env_vars_into_dict(ctx, params, value):
5254
"-f",
5355
"--file",
5456
"--coverage-files-search-direct-file",
55-
"coverage_files_search_explicitly_listed_files",
57+
"--files-search-direct-file",
58+
"files_search_explicitly_listed_files",
5659
help="Explicit files to upload. These will be added to the coverage files found for upload. If you wish to only upload the specified files, please consider using --disable-search to disable uploading other files.",
5760
type=click.Path(path_type=pathlib.Path),
5861
multiple=True,
@@ -155,6 +158,12 @@ def _turn_env_vars_into_dict(ctx, params, value):
155158
is_flag=True,
156159
help="Raise no excpetions when no coverage reports found.",
157160
),
161+
click.option(
162+
"--report-type",
163+
help="The type of the file to upload, coverage by default. Possible values are: testing, coverage.",
164+
default="coverage",
165+
type=click.Choice(["coverage", "test_results"]),
166+
),
158167
]
159168

160169

@@ -179,9 +188,9 @@ def do_upload(
179188
flags: typing.List[str],
180189
name: typing.Optional[str],
181190
network_root_folder: pathlib.Path,
182-
coverage_files_search_root_folder: pathlib.Path,
183-
coverage_files_search_exclude_folders: typing.List[pathlib.Path],
184-
coverage_files_search_explicitly_listed_files: typing.List[pathlib.Path],
191+
files_search_root_folder: pathlib.Path,
192+
files_search_exclude_folders: typing.List[pathlib.Path],
193+
files_search_explicitly_listed_files: typing.List[pathlib.Path],
185194
disable_search: bool,
186195
disable_file_fixes: bool,
187196
token: typing.Optional[str],
@@ -194,6 +203,7 @@ def do_upload(
194203
dry_run: bool,
195204
git_service: typing.Optional[str],
196205
handle_no_reports_found: bool,
206+
report_type: str,
197207
):
198208
versioning_system = ctx.obj["versioning_system"]
199209
codecov_yaml = ctx.obj["codecov_yaml"] or {}
@@ -204,6 +214,7 @@ def do_upload(
204214
"Starting upload processing",
205215
extra=dict(
206216
extra_log_attributes=dict(
217+
upload_file_type=report_type,
207218
commit_sha=commit_sha,
208219
report_code=report_code,
209220
build_code=build_code,
@@ -213,9 +224,9 @@ def do_upload(
213224
flags=flags,
214225
name=name,
215226
network_root_folder=network_root_folder,
216-
coverage_files_search_root_folder=coverage_files_search_root_folder,
217-
coverage_files_search_exclude_folders=coverage_files_search_exclude_folders,
218-
coverage_files_search_explicitly_listed_files=coverage_files_search_explicitly_listed_files,
227+
files_search_root_folder=files_search_root_folder,
228+
files_search_exclude_folders=files_search_exclude_folders,
229+
files_search_explicitly_listed_files=files_search_explicitly_listed_files,
219230
plugin_names=plugin_names,
220231
token=token,
221232
branch=branch,
@@ -233,6 +244,7 @@ def do_upload(
233244
cli_config,
234245
versioning_system,
235246
ci_adapter,
247+
upload_file_type=report_type,
236248
commit_sha=commit_sha,
237249
report_code=report_code,
238250
build_code=build_code,
@@ -242,13 +254,9 @@ def do_upload(
242254
flags=flags,
243255
name=name,
244256
network_root_folder=network_root_folder,
245-
coverage_files_search_root_folder=coverage_files_search_root_folder,
246-
coverage_files_search_exclude_folders=list(
247-
coverage_files_search_exclude_folders
248-
),
249-
coverage_files_search_explicitly_listed_files=list(
250-
coverage_files_search_explicitly_listed_files
251-
),
257+
files_search_root_folder=files_search_root_folder,
258+
files_search_exclude_folders=list(files_search_exclude_folders),
259+
files_search_explicitly_listed_files=list(files_search_explicitly_listed_files),
252260
plugin_names=plugin_names,
253261
token=token,
254262
branch=branch,

codecov_cli/commands/upload_process.py

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ def upload_process(
3232
flags: typing.List[str],
3333
name: typing.Optional[str],
3434
network_root_folder: pathlib.Path,
35-
coverage_files_search_root_folder: pathlib.Path,
36-
coverage_files_search_exclude_folders: typing.List[pathlib.Path],
37-
coverage_files_search_explicitly_listed_files: typing.List[pathlib.Path],
35+
files_search_root_folder: pathlib.Path,
36+
files_search_exclude_folders: typing.List[pathlib.Path],
37+
files_search_explicitly_listed_files: typing.List[pathlib.Path],
3838
disable_search: bool,
3939
disable_file_fixes: bool,
4040
token: typing.Optional[str],
@@ -48,6 +48,7 @@ def upload_process(
4848
git_service: typing.Optional[str],
4949
parent_sha: typing.Optional[str],
5050
handle_no_reports_found: bool,
51+
report_type: str,
5152
):
5253
logger.debug(
5354
"Starting upload process",
@@ -62,9 +63,9 @@ def upload_process(
6263
flags=flags,
6364
name=name,
6465
network_root_folder=network_root_folder,
65-
coverage_files_search_root_folder=coverage_files_search_root_folder,
66-
coverage_files_search_exclude_folders=coverage_files_search_exclude_folders,
67-
coverage_files_search_explicitly_listed_files=coverage_files_search_explicitly_listed_files,
66+
files_search_root_folder=files_search_root_folder,
67+
files_search_exclude_folders=files_search_exclude_folders,
68+
files_search_explicitly_listed_files=files_search_explicitly_listed_files,
6869
plugin_names=plugin_names,
6970
token=token,
7071
branch=branch,
@@ -90,15 +91,16 @@ def upload_process(
9091
git_service=git_service,
9192
fail_on_error=True,
9293
)
93-
ctx.invoke(
94-
create_report,
95-
token=token,
96-
code=report_code,
97-
fail_on_error=True,
98-
commit_sha=commit_sha,
99-
slug=slug,
100-
git_service=git_service,
101-
)
94+
if report_type == "coverage":
95+
ctx.invoke(
96+
create_report,
97+
token=token,
98+
code=report_code,
99+
fail_on_error=True,
100+
commit_sha=commit_sha,
101+
slug=slug,
102+
git_service=git_service,
103+
)
102104
ctx.invoke(
103105
do_upload,
104106
commit_sha=commit_sha,
@@ -110,9 +112,9 @@ def upload_process(
110112
flags=flags,
111113
name=name,
112114
network_root_folder=network_root_folder,
113-
coverage_files_search_root_folder=coverage_files_search_root_folder,
114-
coverage_files_search_exclude_folders=coverage_files_search_exclude_folders,
115-
coverage_files_search_explicitly_listed_files=coverage_files_search_explicitly_listed_files,
115+
files_search_root_folder=files_search_root_folder,
116+
files_search_exclude_folders=files_search_exclude_folders,
117+
files_search_explicitly_listed_files=files_search_explicitly_listed_files,
116118
disable_search=disable_search,
117119
token=token,
118120
plugin_names=plugin_names,
@@ -125,4 +127,5 @@ def upload_process(
125127
git_service=git_service,
126128
handle_no_reports_found=handle_no_reports_found,
127129
disable_file_fixes=disable_file_fixes,
130+
report_type=report_type,
128131
)

codecov_cli/services/upload/__init__.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from codecov_cli.helpers.request import log_warnings_and_errors_if_any
1010
from codecov_cli.helpers.versioning_systems import VersioningSystemInterface
1111
from codecov_cli.plugins import select_preparation_plugins
12-
from codecov_cli.services.upload.coverage_file_finder import select_coverage_file_finder
12+
from codecov_cli.services.upload.file_finder import select_file_finder
1313
from codecov_cli.services.upload.legacy_upload_sender import LegacyUploadSender
1414
from codecov_cli.services.upload.network_finder import select_network_finder
1515
from codecov_cli.services.upload.upload_collector import UploadCollector
@@ -34,14 +34,15 @@ def do_upload_logic(
3434
flags: typing.List[str],
3535
name: typing.Optional[str],
3636
network_root_folder: Path,
37-
coverage_files_search_root_folder: Path,
38-
coverage_files_search_exclude_folders: typing.List[Path],
39-
coverage_files_search_explicitly_listed_files: typing.List[Path],
37+
files_search_root_folder: Path,
38+
files_search_exclude_folders: typing.List[Path],
39+
files_search_explicitly_listed_files: typing.List[Path],
4040
plugin_names: typing.List[str],
4141
token: str,
4242
branch: typing.Optional[str],
4343
slug: typing.Optional[str],
4444
pull_request_number: typing.Optional[str],
45+
upload_file_type: str = "coverage",
4546
use_legacy_uploader: bool = False,
4647
fail_on_error: bool = False,
4748
dry_run: bool = False,
@@ -51,19 +52,23 @@ def do_upload_logic(
5152
handle_no_reports_found: bool = False,
5253
disable_file_fixes: bool = False,
5354
):
54-
preparation_plugins = select_preparation_plugins(cli_config, plugin_names)
55-
coverage_file_selector = select_coverage_file_finder(
56-
coverage_files_search_root_folder,
57-
coverage_files_search_exclude_folders,
58-
coverage_files_search_explicitly_listed_files,
55+
if upload_file_type == "coverage":
56+
preparation_plugins = select_preparation_plugins(cli_config, plugin_names)
57+
elif upload_file_type == "test_results":
58+
preparation_plugins = []
59+
file_selector = select_file_finder(
60+
files_search_root_folder,
61+
files_search_exclude_folders,
62+
files_search_explicitly_listed_files,
5963
disable_search,
64+
upload_file_type,
6065
)
6166
network_finder = select_network_finder(versioning_system)
6267
collector = UploadCollector(
63-
preparation_plugins, network_finder, coverage_file_selector, disable_file_fixes
68+
preparation_plugins, network_finder, file_selector, disable_file_fixes
6469
)
6570
try:
66-
upload_data = collector.generate_upload_data()
71+
upload_data = collector.generate_upload_data(upload_file_type)
6772
except click.ClickException as exp:
6873
if handle_no_reports_found:
6974
logger.info(
@@ -103,6 +108,7 @@ def do_upload_logic(
103108
token,
104109
env_vars,
105110
report_code,
111+
upload_file_type,
106112
name,
107113
branch,
108114
slug,

codecov_cli/services/upload/coverage_file_finder.py renamed to codecov_cli/services/upload/file_finder.py

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
"test_cov.xml",
3636
]
3737

38+
test_results_files_patterns = [
39+
"*junit*",
40+
]
3841

3942
coverage_files_excluded_patterns = [
4043
"*.am",
@@ -134,6 +137,10 @@
134137
"*.zip",
135138
]
136139

140+
test_results_files_excluded_patterns = (
141+
coverage_files_patterns + coverage_files_excluded_patterns
142+
)
143+
137144

138145
default_folders_to_ignore = [
139146
"vendor",
@@ -170,49 +177,53 @@
170177
]
171178

172179

173-
class CoverageFileFinder(object):
180+
class FileFinder(object):
174181
def __init__(
175182
self,
176183
project_root: Path = None,
177184
folders_to_ignore: typing.List[str] = None,
178185
explicitly_listed_files: typing.List[Path] = None,
179186
disable_search: bool = False,
187+
report_type: str = "coverage",
180188
):
181189
self.project_root = project_root or Path(os.getcwd())
182190
self.folders_to_ignore = folders_to_ignore or []
183191
self.explicitly_listed_files = explicitly_listed_files or None
184192
self.disable_search = disable_search
193+
self.report_type = report_type
185194

186-
def find_coverage_files(self) -> typing.List[UploadCollectionResultFile]:
187-
regex_patterns_to_exclude = globs_to_regex(coverage_files_excluded_patterns)
188-
coverage_files_paths = []
189-
user_coverage_files_paths = []
195+
def find_files(self) -> typing.List[UploadCollectionResultFile]:
196+
if self.report_type == "coverage":
197+
files_excluded_patterns = coverage_files_excluded_patterns
198+
files_patterns = coverage_files_patterns
199+
elif self.report_type == "test_results":
200+
files_excluded_patterns = test_results_files_excluded_patterns
201+
files_patterns = test_results_files_patterns
202+
regex_patterns_to_exclude = globs_to_regex(files_excluded_patterns)
203+
files_paths = []
204+
user_files_paths = []
190205
if self.explicitly_listed_files:
191-
user_coverage_files_paths = self.get_user_specified_coverage_files(
192-
regex_patterns_to_exclude
193-
)
206+
user_files_paths = self.get_user_specified_files(regex_patterns_to_exclude)
194207
if not self.disable_search:
195-
regex_patterns_to_include = globs_to_regex(coverage_files_patterns)
196-
coverage_files_paths = search_files(
208+
regex_patterns_to_include = globs_to_regex(files_patterns)
209+
files_paths = search_files(
197210
self.project_root,
198211
default_folders_to_ignore + self.folders_to_ignore,
199212
filename_include_regex=regex_patterns_to_include,
200213
filename_exclude_regex=regex_patterns_to_exclude,
201214
)
202215
result_files = [
203-
UploadCollectionResultFile(path)
204-
for path in coverage_files_paths
205-
if coverage_files_paths
216+
UploadCollectionResultFile(path) for path in files_paths if files_paths
206217
]
207218
user_result_files = [
208219
UploadCollectionResultFile(path)
209-
for path in user_coverage_files_paths
210-
if user_coverage_files_paths
220+
for path in user_files_paths
221+
if user_files_paths
211222
]
212223

213224
return list(set(result_files + user_result_files))
214225

215-
def get_user_specified_coverage_files(self, regex_patterns_to_exclude):
226+
def get_user_specified_files(self, regex_patterns_to_exclude):
216227
user_filenames_to_include = []
217228
files_excluded_but_user_includes = []
218229
for file in self.explicitly_listed_files:
@@ -230,7 +241,7 @@ def get_user_specified_coverage_files(self, regex_patterns_to_exclude):
230241
multipart_include_regex = globs_to_regex(
231242
[str(path.resolve()) for path in self.explicitly_listed_files]
232243
)
233-
user_coverage_files_paths = list(
244+
user_files_paths = list(
234245
search_files(
235246
self.project_root,
236247
default_folders_to_ignore + self.folders_to_ignore,
@@ -241,7 +252,7 @@ def get_user_specified_coverage_files(self, regex_patterns_to_exclude):
241252
)
242253
not_found_files = []
243254
for filepath in self.explicitly_listed_files:
244-
if filepath.resolve() not in user_coverage_files_paths:
255+
if filepath.resolve() not in user_files_paths:
245256
not_found_files.append(filepath)
246257

247258
if not_found_files:
@@ -250,15 +261,20 @@ def get_user_specified_coverage_files(self, regex_patterns_to_exclude):
250261
extra=dict(extra_log_attributes=dict(not_found_files=not_found_files)),
251262
)
252263

253-
return user_coverage_files_paths
264+
return user_files_paths
254265

255266

256-
def select_coverage_file_finder(
257-
root_folder_to_search, folders_to_ignore, explicitly_listed_files, disable_search
267+
def select_file_finder(
268+
root_folder_to_search,
269+
folders_to_ignore,
270+
explicitly_listed_files,
271+
disable_search,
272+
report_type="coverage",
258273
):
259-
return CoverageFileFinder(
274+
return FileFinder(
260275
root_folder_to_search,
261276
folders_to_ignore,
262277
explicitly_listed_files,
263278
disable_search,
279+
report_type,
264280
)

0 commit comments

Comments
 (0)