diff --git a/codecov-cli/README.md b/codecov-cli/README.md index 7aea238b..13549e57 100644 --- a/codecov-cli/README.md +++ b/codecov-cli/README.md @@ -17,12 +17,9 @@ CodecovCLI is a new way for users to interact with Codecov directly from the use - [create-commit](#create-commit) - [create-report](#create-report) - [do-upload](#do-upload) - - [create-report-results](#create-report-results) - - [get-report-results](#get-report-results) - [pr-base-picking](#pr-base-picking) - [send-notifications](#send-notifications) - [empty-upload](#empty-upload) -- [How to Use Local Upload](#how-to-use-local-upload) - [Work in Progress Features](#work-in-progress-features) - [Plugin System](#plugin-system) - [Static Analysis](#static-analysis) @@ -123,8 +120,6 @@ Codecov-cli supports user input. These inputs, along with their descriptions and | `create-commit` | Saves the commit's metadata in codecov, it's only necessary to run this once per commit | `create-report` | Creates an empty report in codecov with initial data e.g. report name, report's commit | `do-upload` | Searches for and uploads coverage data to codecov -| `create-report-results` | Used for local upload. It tells codecov that you finished local uploading and want it to calculate the results for you to get them locally. -| `get-report-results` | Used for local upload. It asks codecov to provide you the report results you calculated with the previous command. | `pr-base-picking` | Tells codecov that you want to explicitly define a base for your PR | `upload-process` | A wrapper for 3 commands. Create-commit, create-report and do-upload. You can use this command to upload to codecov instead of using the previously mentioned commands. | `send-notifications` | A command that tells Codecov that you finished uploading and you want to be sent notifications. To disable automatically sent notifications please consider adding manual_trigger to your codecov.yml, so it will look like codecov: notify: manual_trigger: true. @@ -156,7 +151,6 @@ Codecov-cli supports user input. These inputs, along with their descriptions and |-r, --slug | owner/repo slug used instead of the private repo token in Self-hosted | Required |-t, --token | Codecov upload token | Required |--git-service | Git Provider. Options: github, gitlab, bitbucket, github_enterprise, gitlab_enterprise, bitbucket_server | Required -|--code| The code of the report. This is used in local uploading to isolate local reports from regular or cloud reports uploaded to codecov so they don't get merged. It's basically a name you give to your report e.g. local-report. | Optional |-h, --help | Shows usage, and command options ## do-upload @@ -165,7 +159,6 @@ Codecov-cli supports user input. These inputs, along with their descriptions and | Option | Description | Usage | :---: | :---: | :---: | |-C, --sha, --commit-sha| Commit SHA (with 40 chars) | Required -|--report-code | The code of the report defined when creating the report. If unsure, leave default | Optional |--network-root-folder | Root folder from which to consider paths on the network section default: (Current working directory) | Optional |-s, --dir, --coverage-files-search-root-folder | Folder where to search for coverage files default: (Current Working Directory) | Optional |--exclude, --coverage-files-search-exclude-folder | Folders to exclude from search | Optional @@ -189,30 +182,6 @@ Codecov-cli supports user input. These inputs, along with their descriptions and |--git-service | Git Provider. Options: github, gitlab, bitbucket, github_enterprise, gitlab_enterprise, bitbucket_server | Required |-h, --help | Shows usage, and command options -## create-report-results -`codecovcli create-report-results [OPTIONS]` - -| Option | Description | Usage -| :---: | :---: | :---: | -|--commit-sha | Commit SHA (with 40 chars) | Required -|--code | The code of the report. If unsure, leave default | Required -|--slug | owner/repo slug | Required -|--git-service | Git provider. Options: github, gitlab, bitbucket, github_enterprise, gitlab_enterprise, bitbucket_server | Optional -|-t, --token | Codecov upload token | Required -|-h, --help | Shows usage, and command options - -## get-report-results -`codecovcli get-report-results [OPTIONS]` - -| Option | Description | Usage -| :---: | :---: | :---: | -|--commit-sha | Commit SHA (with 40 chars) | Required -|--code | The code of the report. If unsure, leave default | Required -|--slug | owner/repo slug | Required -|--git-service | Git provider. Options: github, gitlab, bitbucket, github_enterprise, gitlab_enterprise, bitbucket_server | Optional -|-t, --token | Codecov upload token | Required -|-h, --help | Shows usage, and command options - ## pr-base-picking `codecovcli pr-base-picking [OPTIONS]` @@ -254,25 +223,6 @@ are ignored by codecov (including README and configuration files) | --git-service | Options: github, gitlab, bitbucket, github_enterprise, gitlab_enterprise, bitbucket_server | Optional | | -h, --help | Show this message and exit. | Optional | -# How to Use Local Upload - -The CLI also supports "dry run" local uploading. This is useful if you prefer to see Codecov status checks and coverage reporting locally, in your terminal, as opposed to opening a PR and waiting for your full CI to run. Local uploads do not interfere with regular uploads made from your CI for any given commit / Pull Request. - -Local Upload is accomplished as follows: - -``` -pip install codecov-cli -codecovcli create-commit -codecovcli create-report --code -codecovcli do-upload --report-code -codecovcli create-report-results --code -codecovcli get-report-results --code -``` - -Codecov will calculate the coverage results, and return them in your terminal, telling you whether your PR will fail or pass the coverage check. - -Note: In order for Local Upload to work, it must be used against a commit on the origin repository. Local Upload does not work for arbitrary diffs or uncommitted changes on your local machine. - # Work in Progress Features The following features are somewhat implemented in code, but are not yet meant for use. These features will be documented once they are fully implemented in the CLI. @@ -281,10 +231,6 @@ The following features are somewhat implemented in code, but are not yet meant f To provide extensibility to some of its commands, the CLI makes use of a plugin system. For most cases, the default commands are sufficient. But in some cases, having some custom logic specific to your use case can be beneficial. Note that full documentation of the plugin system is pending, as the feature is still heavily a work in progress. -## Static Analysis - -The CLI can perform basic static analysis on Python code today. This static analysis is meant to power more future looking Codecov features and, as such, is not required or in active use today. As more functionality dependent on static analysis becomes available for use, we will document static analysis in detail here. - # Contributions This repository, like all of Codecov's repositories, strives to follow our general [Contributing guidelines](https://github.com/codecov/contributing). If you're considering making a contribution to this repository, we encourage review of our Contributing guidelines first. diff --git a/codecov-cli/codecov_cli/commands/create_report_result.py b/codecov-cli/codecov_cli/commands/create_report_result.py index 486eecbe..ec3e3464 100644 --- a/codecov-cli/codecov_cli/commands/create_report_result.py +++ b/codecov-cli/codecov_cli/commands/create_report_result.py @@ -11,7 +11,7 @@ logger = logging.getLogger("codecovcli") -@click.command() +@click.command(hidden=True, deprecated=True) @click.option( "--code", help="The code of the report. If unsure, leave default", default="default" ) diff --git a/codecov-cli/codecov_cli/commands/get_report_results.py b/codecov-cli/codecov_cli/commands/get_report_results.py index eb0c3283..bff03eab 100644 --- a/codecov-cli/codecov_cli/commands/get_report_results.py +++ b/codecov-cli/codecov_cli/commands/get_report_results.py @@ -3,10 +3,8 @@ import click import sentry_sdk -from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum from codecov_cli.helpers.args import get_cli_args from codecov_cli.helpers.encoder import encode_slug -from codecov_cli.helpers.git import GitService from codecov_cli.helpers.options import global_options from codecov_cli.services.report import send_reports_result_get_request from codecov_cli.types import CommandContext @@ -15,7 +13,7 @@ logger = logging.getLogger("codecovcli") -@click.command() +@click.command(hidden=True, deprecated=True) @click.option( "--code", help="The code of the report. If unsure, leave default", default="default" ) diff --git a/codecov-cli/codecov_cli/commands/labelanalysis.py b/codecov-cli/codecov_cli/commands/labelanalysis.py index 8f720e28..9e117bc7 100644 --- a/codecov-cli/codecov_cli/commands/labelanalysis.py +++ b/codecov-cli/codecov_cli/commands/labelanalysis.py @@ -1,17 +1,13 @@ import json import logging import pathlib -import time from typing import Dict, List, Optional import click -import requests import sentry_sdk from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum -from codecov_cli.helpers import request from codecov_cli.helpers.args import get_cli_args -from codecov_cli.helpers.config import CODECOV_API_URL from codecov_cli.helpers.validators import validate_commit_sha from codecov_cli.runners import get_runner from codecov_cli.runners.types import ( @@ -92,7 +88,6 @@ def label_analysis( ): with sentry_sdk.start_transaction(op="task", name="Label Analysis"): with sentry_sdk.start_span(name="labelanalysis"): - enterprise_url = ctx.obj.get("enterprise_url") args = get_cli_args(ctx) logger.debug( "Starting label analysis", @@ -124,18 +119,6 @@ def label_analysis( extra=dict(extra_log_attributes=dict(config=runner.params)), ) - upload_url = enterprise_url or CODECOV_API_URL - url = f"{upload_url}/labels/labels-analysis" - token_header = f"Repotoken {token}" - payload = { - "base_commit": base_commit_sha, - "head_commit": head_commit_sha, - "requested_labels": None, - } - # Send the initial label analysis request without labels - # Because labels might take a long time to collect - eid = _send_labelanalysis_request(payload, url, token_header) - logger.info("Collecting labels...") requested_labels = runner.collect_tests() logger.info(f"Collected {len(requested_labels)} test labels") @@ -145,98 +128,15 @@ def label_analysis( extra_log_attributes=dict(labels_collected=requested_labels) ), ) - payload["requested_labels"] = requested_labels - - if eid: - # Initial request with no labels was successful - # Now we PATCH the labels in - patch_url = f"{upload_url}/labels/labels-analysis/{eid}" - _patch_labels(payload, patch_url, token_header) - else: - # Initial request with no labels failed - # Retry it - eid = _send_labelanalysis_request(payload, url, token_header) - if eid is None: - _fallback_to_collected_labels( - requested_labels, - runner, - dry_run=dry_run, - dry_run_format=dry_run_format, - fallback_reason="codecov_unavailable", - ) - return - has_result = False - logger.info("Waiting for list of tests to run...") - start_wait = time.monotonic() - time.sleep(1) - while not has_result: - resp_data = request.get( - f"{upload_url}/labels/labels-analysis/{eid}", - headers={"Authorization": token_header}, - ) - resp_json = resp_data.json() - if resp_json["state"] == "finished": - logger.info( - "Received list of tests from Codecov", - extra=dict( - extra_log_attributes=dict( - processing_errors=resp_json.get("errors", []) - ) - ), - ) - request_result = _potentially_calculate_absent_labels( - resp_json["result"], requested_labels - ) - if not dry_run: - runner.process_labelanalysis_result(request_result) - else: - _dry_run_output( - LabelAnalysisRequestResult(request_result), - runner, - dry_run_format, - # It's possible that the task had processing errors and fallback to all tests - # Even though it's marked as FINISHED (not ERROR) it's not a true success - fallback_reason=( - "test_list_processing_errors" - if resp_json.get("errors", None) - else None - ), - ) - return - if resp_json["state"] == "error": - logger.error( - "Request had problems calculating", - extra=dict( - extra_log_attributes=dict( - base_commit=resp_json["base_commit"], - head_commit=resp_json["head_commit"], - external_id=resp_json["external_id"], - ) - ), - ) - _fallback_to_collected_labels( - collected_labels=requested_labels, - runner=runner, - dry_run=dry_run, - dry_run_format=dry_run_format, - fallback_reason="test_list_processing_failed", - ) - return - if max_wait_time and (time.monotonic() - start_wait) > max_wait_time: - logger.error( - f"Exceeded max waiting time of {max_wait_time} seconds. Running all tests.", - ) - _fallback_to_collected_labels( - collected_labels=requested_labels, - runner=runner, - dry_run=dry_run, - dry_run_format=dry_run_format, - fallback_reason="max_wait_time_exceeded", - ) - return - logger.info("Waiting more time for result...") - time.sleep(5) + _fallback_to_collected_labels( + requested_labels, + runner, + dry_run=dry_run, + dry_run_format=dry_run_format, + fallback_reason="codecov_unavailable", + ) + return def _parse_runner_params(runner_params: List[str]) -> Dict[str, str]: @@ -271,103 +171,6 @@ def _parse_runner_params(runner_params: List[str]) -> Dict[str, str]: return final_params -def _potentially_calculate_absent_labels( - request_result, requested_labels -) -> LabelAnalysisRequestResult: - if request_result["absent_labels"]: - # This means that Codecov already calculated everything for us - final_result = LabelAnalysisRequestResult(request_result) - else: - # Here we have to calculate the absent labels - # And also remove labels that maybe don't exist anymore from the set of labels to test - # Because codecov didn't have this info previously - requested_labels_set = set(requested_labels) - present_diff_labels_set = set(request_result.get("present_diff_labels", [])) - present_report_labels_set = set(request_result.get("present_report_labels", [])) - global_level_labels_set = set(request_result.get("global_level_labels", [])) - final_result = LabelAnalysisRequestResult( - { - "present_report_labels": sorted( - present_report_labels_set & requested_labels_set - ), - "present_diff_labels": sorted( - present_diff_labels_set & requested_labels_set - ), - "absent_labels": sorted( - requested_labels_set - present_report_labels_set - ), - "global_level_labels": sorted( - global_level_labels_set & requested_labels_set - ), - } - ) - logger.info( - "Received information about tests to run", - extra=dict( - extra_log_attributes=dict( - absent_labels=len(final_result.absent_labels), - present_diff_labels=len(final_result.present_diff_labels), - global_level_labels=len(final_result.global_level_labels), - present_report_labels=len(final_result.present_report_labels), - ) - ), - ) - return final_result - - -def _patch_labels(payload, url, token_header): - logger.info("Sending collected labels to Codecov...") - try: - response = request.patch( - url, json=payload, headers={"Authorization": token_header} - ) - if response.status_code < 300: - logger.info("Labels successfully sent to Codecov") - except requests.RequestException: - raise click.ClickException(click.style("Unable to reach Codecov", fg="red")) - - -def _send_labelanalysis_request(payload, url, token_header): - logger.info( - "Requesting set of labels to run...", - extra=dict( - extra_log_attributes=dict( - with_labels=(payload["requested_labels"] is not None) - ) - ), - ) - try: - response = request.post( - url, data=payload, headers={"Authorization": token_header} - ) - if response.status_code >= 500: - logger.warning( - "Sorry. Codecov is having problems", - extra=dict(extra_log_attributes=dict(status_code=response.status_code)), - ) - return None - if response.status_code >= 400: - logger.warning( - "Got a 4XX status code back from Codecov", - extra=dict( - extra_log_attributes=dict( - status_code=response.status_code, response_json=response.json() - ) - ), - ) - raise click.ClickException( - "There is some problem with the submitted information" - ) - except requests.RequestException: - raise click.ClickException(click.style("Unable to reach Codecov", fg="red")) - eid = response.json()["external_id"] - logger.info( - "Label Analysis request successful", - extra=dict(extra_log_attributes=dict(request_id=eid)), - ) - return eid - - def _dry_run_json_output( labels_to_run: set, labels_to_skip: set, diff --git a/codecov-cli/codecov_cli/commands/report.py b/codecov-cli/codecov_cli/commands/report.py index 280e8492..ce52f112 100644 --- a/codecov-cli/codecov_cli/commands/report.py +++ b/codecov-cli/codecov_cli/commands/report.py @@ -14,7 +14,7 @@ @click.command() @click.option( - "--code", help="The code of the report. If unsure, leave default", default="default" + "--code", help="The code of the report. If unsure, leave default", default="default", hidden=True ) @click.option( "-P", diff --git a/codecov-cli/codecov_cli/commands/staticanalysis.py b/codecov-cli/codecov_cli/commands/staticanalysis.py index 58592291..6dd8f3cd 100644 --- a/codecov-cli/codecov_cli/commands/staticanalysis.py +++ b/codecov-cli/codecov_cli/commands/staticanalysis.py @@ -1,4 +1,3 @@ -import asyncio import logging import pathlib import typing @@ -7,9 +6,7 @@ import sentry_sdk from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum -from codecov_cli.helpers.args import get_cli_args from codecov_cli.helpers.validators import validate_commit_sha -from codecov_cli.services.staticanalysis import run_analysis_entrypoint from codecov_cli.types import CommandContext logger = logging.getLogger("codecovcli") @@ -62,25 +59,4 @@ def static_analysis( ): with sentry_sdk.start_transaction(op="task", name="Static Analysis"): with sentry_sdk.start_span(name="static_analysis"): - enterprise_url = ctx.obj.get("enterprise_url") - args = get_cli_args(ctx) - logger.debug( - "Starting Static Analysis processing", - extra=dict( - extra_log_attributes=args, - ), - ) - return asyncio.run( - run_analysis_entrypoint( - ctx.obj["codecov_yaml"], - foldertosearch, - numberprocesses, - pattern, - commit, - token, - force, - list(folders_to_exclude), - enterprise_url, - args, - ) - ) + pass diff --git a/codecov-cli/codecov_cli/commands/upload.py b/codecov-cli/codecov_cli/commands/upload.py index 2b283002..87380910 100644 --- a/codecov-cli/codecov_cli/commands/upload.py +++ b/codecov-cli/codecov_cli/commands/upload.py @@ -26,6 +26,7 @@ def _turn_env_vars_into_dict(ctx, params, value): "report_code", help="The code of the report. If unsure, leave default", default="default", + hidden=True, ), click.option( "--network-root-folder", diff --git a/codecov-cli/codecov_cli/main.py b/codecov-cli/codecov_cli/main.py index e27d94e3..ba537b87 100644 --- a/codecov-cli/codecov_cli/main.py +++ b/codecov-cli/codecov_cli/main.py @@ -77,17 +77,19 @@ def cli( cli.add_command(do_upload) cli.add_command(create_commit) cli.add_command(create_report) -cli.add_command(create_report_results) -cli.add_command(get_report_results) cli.add_command(pr_base_picking) -cli.add_command(label_analysis) -cli.add_command(static_analysis) cli.add_command(empty_upload) cli.add_command(upload_coverage) cli.add_command(upload_process) cli.add_command(send_notifications) cli.add_command(process_test_results) +# deprecated commands: +cli.add_command(create_report_results) +cli.add_command(get_report_results) +cli.add_command(label_analysis) +cli.add_command(static_analysis) + def run(): cli(obj={}) diff --git a/codecov-cli/codecovcli_commands b/codecov-cli/codecovcli_commands index 34cca21e..691eaa47 100644 --- a/codecov-cli/codecovcli_commands +++ b/codecov-cli/codecovcli_commands @@ -13,10 +13,8 @@ Options: Commands: create-commit create-report - create-report-results do-upload empty-upload - get-report-results pr-base-picking process-test-results send-notifications @@ -44,8 +42,6 @@ Options: Usage: codecovcli create-report [OPTIONS] Options: - --code TEXT The code of the report. If unsure, leave - default -P, --pr, --pull-request-number TEXT Specify the pull request number manually. Used to override pre-existing CI environment @@ -58,24 +54,9 @@ Options: repo token in Self-hosted -h, --help Show this message and exit. -Usage: codecovcli create-report-results [OPTIONS] - -Options: - --code TEXT The code of the report. If unsure, leave - default - -C, --sha, --commit-sha TEXT Commit SHA (with 40 chars) [required] - -Z, --fail-on-error Exit with non-zero code in case of error - --git-service [github|gitlab|bitbucket|github_enterprise|gitlab_enterprise|bitbucket_server] - -t, --token TEXT Codecov upload token - -r, --slug TEXT owner/repo slug used instead of the private - repo token in Self-hosted - -h, --help Show this message and exit. - Usage: codecovcli do-upload [OPTIONS] Options: - --code, --report-code TEXT The code of the report. If unsure, leave - default --network-root-folder PATH Root folder from which to consider paths on the network section [default: (Current working directory)] @@ -164,19 +145,6 @@ Options: repo token in Self-hosted -h, --help Show this message and exit. -Usage: codecovcli get-report-results [OPTIONS] - -Options: - --code TEXT The code of the report. If unsure, leave - default - -C, --sha, --commit-sha TEXT Commit SHA (with 40 chars) [required] - -Z, --fail-on-error Exit with non-zero code in case of error - --git-service [github|gitlab|bitbucket|github_enterprise|gitlab_enterprise|bitbucket_server] - -t, --token TEXT Codecov upload token - -r, --slug TEXT owner/repo slug used instead of the private - repo token in Self-hosted - -h, --help Show this message and exit. - Usage: codecovcli pr-base-picking [OPTIONS] Options: @@ -230,8 +198,6 @@ Options: -t, --token TEXT Codecov upload token -r, --slug TEXT owner/repo slug used instead of the private repo token in Self-hosted - --code, --report-code TEXT The code of the report. If unsure, leave - default --network-root-folder PATH Root folder from which to consider paths on the network section [default: (Current working directory)] @@ -306,8 +272,6 @@ Options: -t, --token TEXT Codecov upload token -r, --slug TEXT owner/repo slug used instead of the private repo token in Self-hosted - --code, --report-code TEXT The code of the report. If unsure, leave - default --network-root-folder PATH Root folder from which to consider paths on the network section [default: (Current working directory)] diff --git a/codecov-cli/tests/commands/test_invoke_labelanalysis.py b/codecov-cli/tests/commands/test_invoke_labelanalysis.py index 729f2965..d5eeaa28 100644 --- a/codecov-cli/tests/commands/test_invoke_labelanalysis.py +++ b/codecov-cli/tests/commands/test_invoke_labelanalysis.py @@ -1,9 +1,7 @@ import json from contextlib import redirect_stdout from io import StringIO -from pathlib import Path -import click import pytest import responses from click.testing import CliRunner @@ -14,10 +12,7 @@ _dry_run_list_output, _fallback_to_collected_labels, _parse_runner_params, - _potentially_calculate_absent_labels, - _send_labelanalysis_request, ) -from codecov_cli.commands.labelanalysis import time as labelanalysis_time from codecov_cli.main import cli from codecov_cli.runners.types import LabelAnalysisRequestResult from tests.factory import FakeProvider, FakeRunner, FakeVersioningSystem @@ -41,7 +36,6 @@ def get_labelanalysis_deps(mocker): fake_runner = FakeRunner(collect_tests_response=collected_labels) fake_runner.process_labelanalysis_result = mocker.MagicMock() - mocker.patch.object(labelanalysis_time, "sleep") mocker.patch("codecov_cli.main.get_ci_adapter", return_value=fake_ci_provider) mocker.patch( "codecov_cli.main.get_versioning_system", @@ -61,52 +55,6 @@ def get_labelanalysis_deps(mocker): class TestLabelAnalysisNotInvoke(object): - def test_potentially_calculate_labels_recalculate(self): - request_result = { - "present_report_labels": [ - "label_1", - "label_2", - "label_3", - "label_old", - "label_older", - ], - "absent_labels": [], - "present_diff_labels": ["label_2", "label_3", "label_old"], - "global_level_labels": ["label_1", "label_older"], - } - collected_labels = ["label_1", "label_2", "label_3", "label_4"] - expected = { - "present_diff_labels": ["label_2", "label_3"], - "global_level_labels": ["label_1"], - "absent_labels": ["label_4"], - "present_report_labels": ["label_1", "label_2", "label_3"], - } - assert ( - _potentially_calculate_absent_labels(request_result, collected_labels) - == expected - ) - - def test_send_label_analysis_bad_payload(self): - payload = { - "base_commit": "base_commit", - "head_commit": "head_commit", - "requested_labels": [], - } - url = "https://api.codecov.io/labels/labels-analysis" - header = "Repotoken STATIC_TOKEN" - with responses.RequestsMock() as rsps: - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - json={"error": "list field cannot be empty list"}, - status=400, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - with pytest.raises(click.ClickException): - _send_labelanalysis_request(payload, url, header) - def test__dry_run_json_output(self): list_to_run = ["label_1", "label_2"] list_to_skip = ["label_3", "label_4"] @@ -223,187 +171,6 @@ def test_invoke_label_analysis_base_sha_same_as_head_sha( assert result.exit_code != 0 assert "Base and head sha can't be the same" in result.output - def test_invoke_label_analysis( - self, get_labelanalysis_deps, mocker, use_verbose_option - ): - mock_get_runner = get_labelanalysis_deps["mock_get_runner"] - fake_runner = get_labelanalysis_deps["fake_runner"] - _ = get_labelanalysis_deps["collected_labels"] - - label_analysis_result = { - "present_report_labels": ["test_present"], - "absent_labels": ["test_absent"], - "present_diff_labels": ["test_in_diff"], - "global_level_labels": ["test_global"], - } - - with responses.RequestsMock() as rsps: - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.PATCH, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.GET, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"state": "finished", "result": label_analysis_result}, - ) - cli_runner = CliRunner() - result = cli_runner.invoke( - cli, - [ - "label-analysis", - "--token=STATIC_TOKEN", - f"--base-sha={FAKE_BASE_SHA}", - ], - obj={}, - ) - assert result.exit_code == 0 - mock_get_runner.assert_called() - fake_runner.process_labelanalysis_result.assert_called_with( - label_analysis_result - ) - print(result.output) - - @pytest.mark.parametrize("processing_errors", [[], [{"error": "missing_data"}]]) - def test_invoke_label_analysis_dry_run( - self, processing_errors, get_labelanalysis_deps, mocker - ): - mock_get_runner = get_labelanalysis_deps["mock_get_runner"] - fake_runner = get_labelanalysis_deps["fake_runner"] - - label_analysis_result = { - "present_report_labels": ["test_present", "test_in_diff", "test_global"], - "absent_labels": ["test_absent"], - "present_diff_labels": ["test_in_diff"], - "global_level_labels": ["test_global"], - } - - with responses.RequestsMock() as rsps: - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.PATCH, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.GET, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={ - "state": "finished", - "result": label_analysis_result, - "errors": processing_errors, - }, - ) - cli_runner = CliRunner(mix_stderr=False) - with cli_runner.isolated_filesystem(): - result = cli_runner.invoke( - cli, - [ - "label-analysis", - "--token=STATIC_TOKEN", - f"--base-sha={FAKE_BASE_SHA}", - "--dry-run", - ], - obj={}, - ) - mock_get_runner.assert_called() - fake_runner.process_labelanalysis_result.assert_not_called() - # Dry run format defaults to json - print(result.stdout) - ats_fallback_reason = ( - "test_list_processing_errors" if processing_errors else None - ) - assert json.loads(result.stdout) == { - "runner_options": ["--labels"], - "ats_tests_to_run": ["test_absent", "test_global", "test_in_diff"], - "ats_tests_to_skip": ["test_present"], - "ats_fallback_reason": ats_fallback_reason, - } - - def test_invoke_label_analysis_dry_run_pytest_format( - self, get_labelanalysis_deps, mocker - ): - _ = get_labelanalysis_deps["mock_get_runner"] - fake_runner = get_labelanalysis_deps["fake_runner"] - - label_analysis_result = { - "present_report_labels": ["test_present", "test_in_diff", "test_global"], - "absent_labels": ["test_absent"], - "present_diff_labels": ["test_in_diff"], - "global_level_labels": ["test_global"], - } - - with responses.RequestsMock() as rsps: - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.PATCH, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.GET, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"state": "finished", "result": label_analysis_result}, - ) - cli_runner = CliRunner(mix_stderr=False) - with cli_runner.isolated_filesystem(): - result = cli_runner.invoke( - cli, - [ - "label-analysis", - "--token=STATIC_TOKEN", - f"--base-sha={FAKE_BASE_SHA}", - "--dry-run", - "--dry-run-format=space-separated-list", - ], - obj={}, - ) - fake_runner.process_labelanalysis_result.assert_not_called() - print(result.stdout) - assert result.exit_code == 0 - assert ( - result.stdout - == "TESTS_TO_RUN='--labels' 'test_absent' 'test_global' 'test_in_diff'\nTESTS_TO_SKIP='--labels' 'test_present'\n" - ) - def test_fallback_to_collected_labels(self, mocker): mock_runner = mocker.MagicMock() collected_labels = ["label_1", "label_2", "label_3"] @@ -424,360 +191,3 @@ def test_fallback_to_collected_labels_no_labels(self, mocker): _fallback_to_collected_labels([], mock_runner) mock_runner.process_labelanalysis_result.assert_not_called() assert str(exp.value) == "Failed to get list of labels to run" - - def test_fallback_collected_labels_covecov_500_error( - self, get_labelanalysis_deps, mocker, use_verbose_option - ): - mock_get_runner = get_labelanalysis_deps["mock_get_runner"] - fake_runner = get_labelanalysis_deps["fake_runner"] - collected_labels = get_labelanalysis_deps["collected_labels"] - with responses.RequestsMock() as rsps: - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - status=500, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - cli_runner = CliRunner() - result = cli_runner.invoke( - cli, - [ - "label-analysis", - "--token=STATIC_TOKEN", - f"--base-sha={FAKE_BASE_SHA}", - ], - obj={}, - ) - mock_get_runner.assert_called() - fake_runner.process_labelanalysis_result.assert_called_with( - { - "present_report_labels": [], - "absent_labels": collected_labels, - "present_diff_labels": [], - "global_level_labels": [], - } - ) - print(result.output) - assert result.exit_code == 0 - - def test_fallback_collected_labels_covecov_500_error_dry_run( - self, get_labelanalysis_deps, mocker - ): - mock_get_runner = get_labelanalysis_deps["mock_get_runner"] - fake_runner = get_labelanalysis_deps["fake_runner"] - collected_labels = get_labelanalysis_deps["collected_labels"] - with responses.RequestsMock() as rsps: - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - status=500, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - cli_runner = CliRunner(mix_stderr=False) - with cli_runner.isolated_filesystem(): - result = cli_runner.invoke( - cli, - [ - "label-analysis", - "--token=STATIC_TOKEN", - f"--base-sha={FAKE_BASE_SHA}", - "--dry-run", - ], - obj={}, - ) - mock_get_runner.assert_called() - fake_runner.process_labelanalysis_result.assert_not_called() - # Dry run format defaults to json - assert json.loads(result.stdout) == { - "runner_options": ["--labels"], - "ats_tests_to_run": sorted(collected_labels), - "ats_tests_to_skip": [], - "ats_fallback_reason": "codecov_unavailable", - } - assert result.exit_code == 0 - - def test_fallback_collected_labels_codecov_error_processing_label_analysis( - self, get_labelanalysis_deps, mocker, use_verbose_option - ): - mock_get_runner = get_labelanalysis_deps["mock_get_runner"] - fake_runner = get_labelanalysis_deps["fake_runner"] - collected_labels = get_labelanalysis_deps["collected_labels"] - - with responses.RequestsMock() as rsps: - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.PATCH, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.GET, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={ - "state": "error", - "external_id": "uuid4-external-id", - "base_commit": "BASE_COMMIT_SHA", - "head_commit": "HEAD_COMMIT_SHA", - }, - ) - cli_runner = CliRunner() - result = cli_runner.invoke( - cli, - [ - "label-analysis", - "--token=STATIC_TOKEN", - f"--base-sha={FAKE_BASE_SHA}", - ], - obj={}, - ) - print(result) - mock_get_runner.assert_called() - fake_runner.process_labelanalysis_result.assert_called_with( - { - "present_report_labels": [], - "absent_labels": collected_labels, - "present_diff_labels": [], - "global_level_labels": [], - } - ) - print(result.output) - assert result.exit_code == 0 - - def test_fallback_collected_labels_codecov_error_processing_label_analysis_dry_run( - self, get_labelanalysis_deps, mocker, use_verbose_option - ): - mock_get_runner = get_labelanalysis_deps["mock_get_runner"] - fake_runner = get_labelanalysis_deps["fake_runner"] - collected_labels = get_labelanalysis_deps["collected_labels"] - - with responses.RequestsMock() as rsps: - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.PATCH, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.GET, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={ - "state": "error", - "external_id": "uuid4-external-id", - "base_commit": "BASE_COMMIT_SHA", - "head_commit": "HEAD_COMMIT_SHA", - }, - ) - cli_runner = CliRunner(mix_stderr=False) - with cli_runner.isolated_filesystem(): - result = cli_runner.invoke( - cli, - [ - "label-analysis", - "--token=STATIC_TOKEN", - f"--base-sha={FAKE_BASE_SHA}", - "--dry-run", - ], - obj={}, - ) - mock_get_runner.assert_called() - fake_runner.process_labelanalysis_result.assert_not_called() - # Dry run format defaults to json - assert json.loads(result.stdout) == { - "runner_options": ["--labels"], - "ats_tests_to_run": sorted(collected_labels), - "ats_tests_to_skip": [], - "ats_fallback_reason": "test_list_processing_failed", - } - assert result.exit_code == 0 - - def test_fallback_collected_labels_codecov_max_wait_time_exceeded( - self, get_labelanalysis_deps, mocker, use_verbose_option - ): - mock_get_runner = get_labelanalysis_deps["mock_get_runner"] - fake_runner = get_labelanalysis_deps["fake_runner"] - collected_labels = get_labelanalysis_deps["collected_labels"] - mocker.patch.object(labelanalysis_time, "monotonic", side_effect=[0, 6]) - - with responses.RequestsMock() as rsps: - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.PATCH, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.GET, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"state": "processing"}, - ) - cli_runner = CliRunner() - result = cli_runner.invoke( - cli, - [ - "label-analysis", - "--token=STATIC_TOKEN", - f"--base-sha={FAKE_BASE_SHA}", - "--max-wait-time=5", - ], - obj={}, - ) - print(result) - assert result.exit_code == 0 - mock_get_runner.assert_called() - fake_runner.process_labelanalysis_result.assert_called_with( - { - "present_report_labels": [], - "absent_labels": collected_labels, - "present_diff_labels": [], - "global_level_labels": [], - } - ) - - def test_fallback_collected_labels_codecov_max_wait_time_exceeded_dry_run( - self, get_labelanalysis_deps, mocker, use_verbose_option - ): - mock_get_runner = get_labelanalysis_deps["mock_get_runner"] - fake_runner = get_labelanalysis_deps["fake_runner"] - collected_labels = get_labelanalysis_deps["collected_labels"] - mocker.patch.object(labelanalysis_time, "monotonic", side_effect=[0, 6]) - - with responses.RequestsMock() as rsps: - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.PATCH, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.GET, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"state": "processing"}, - ) - cli_runner = CliRunner(mix_stderr=False) - result = cli_runner.invoke( - cli, - [ - "label-analysis", - "--token=STATIC_TOKEN", - f"--base-sha={FAKE_BASE_SHA}", - "--max-wait-time=5", - "--dry-run", - ], - obj={}, - ) - mock_get_runner.assert_called() - fake_runner.process_labelanalysis_result.assert_not_called() - # Dry run format defaults to json - assert json.loads(result.stdout) == { - "runner_options": ["--labels"], - "ats_tests_to_run": sorted(collected_labels), - "ats_tests_to_skip": [], - "ats_fallback_reason": "max_wait_time_exceeded", - } - assert result.exit_code == 0 - - def test_first_labelanalysis_request_fails_but_second_works( - self, get_labelanalysis_deps, mocker, use_verbose_option - ): - mock_get_runner = get_labelanalysis_deps["mock_get_runner"] - fake_runner = get_labelanalysis_deps["fake_runner"] - _ = get_labelanalysis_deps["collected_labels"] - - label_analysis_result = { - "present_report_labels": ["test_present"], - "absent_labels": ["test_absent"], - "present_diff_labels": ["test_in_diff"], - "global_level_labels": ["test_global"], - } - - with responses.RequestsMock() as rsps: - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - status=502, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.POST, - "https://api.codecov.io/labels/labels-analysis", - json={"external_id": "label-analysis-request-id"}, - status=201, - match=[ - matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) - ], - ) - rsps.add( - responses.GET, - "https://api.codecov.io/labels/labels-analysis/label-analysis-request-id", - json={"state": "finished", "result": label_analysis_result}, - ) - cli_runner = CliRunner() - result = cli_runner.invoke( - cli, - [ - "label-analysis", - "--token=STATIC_TOKEN", - f"--base-sha={FAKE_BASE_SHA}", - ], - obj={}, - ) - assert result.exit_code == 0 - mock_get_runner.assert_called() - fake_runner.process_labelanalysis_result.assert_called_with( - label_analysis_result - ) - print(result.output) diff --git a/codecov-cli/tests/commands/test_invoke_upload_coverage.py b/codecov-cli/tests/commands/test_invoke_upload_coverage.py index 58e6507f..1084c4c4 100644 --- a/codecov-cli/tests/commands/test_invoke_upload_coverage.py +++ b/codecov-cli/tests/commands/test_invoke_upload_coverage.py @@ -75,8 +75,6 @@ def test_upload_coverage_options(mocker): " -t, --token TEXT Codecov upload token", " -r, --slug TEXT owner/repo slug used instead of the private", " repo token in Self-hosted", - " --code, --report-code TEXT The code of the report. If unsure, leave", - " default", " --network-root-folder PATH Root folder from which to consider paths on", " the network section [default: (Current", " working directory)]", diff --git a/codecov-cli/tests/commands/test_invoke_upload_process.py b/codecov-cli/tests/commands/test_invoke_upload_process.py index 967e0dfe..e5421d3f 100644 --- a/codecov-cli/tests/commands/test_invoke_upload_process.py +++ b/codecov-cli/tests/commands/test_invoke_upload_process.py @@ -75,8 +75,6 @@ def test_upload_process_options(mocker): " -t, --token TEXT Codecov upload token", " -r, --slug TEXT owner/repo slug used instead of the private", " repo token in Self-hosted", - " --code, --report-code TEXT The code of the report. If unsure, leave", - " default", " --network-root-folder PATH Root folder from which to consider paths on", " the network section [default: (Current", " working directory)]",