def test_phabricator_coverage(mock_config, mock_phabricator, mock_try_task):
    """
    Test Phabricator reporter publication on a mock coverage issue
    """
    from code_review_bot.report.phabricator import PhabricatorReporter
    from code_review_bot.revisions import Revision
    from code_review_bot.tasks.coverage import CoverageIssue

    def _check_comment(request):
        # Check the Phabricator main comment is well formed
        payload = urllib.parse.parse_qs(request.body)
        assert payload["output"] == ["json"]
        assert len(payload["params"]) == 1
        details = json.loads(payload["params"][0])
        assert details["message"] == VALID_COVERAGE_MESSAGE

        # Outputs dummy empty response
        resp = {"error_code": None, "result": None}
        return (
            201,
            {
                "Content-Type": "application/json",
                "unittest": "coverage"
            },
            json.dumps(resp),
        )

    responses.add_callback(
        responses.POST,
        "http://phabricator.test/api/differential.createcomment",
        callback=_check_comment,
    )

    with mock_phabricator as api:
        revision = Revision(api, mock_try_task)
        revision.lines = {
            # Add dummy lines diff
            "test.txt": [0],
            "path/to/test.cpp": [0],
            "dom/test.cpp": [42],
        }
        reporter = PhabricatorReporter({"analyzers": ["coverage"]}, api=api)

    issue = CoverageIssue("path/to/test.cpp", 0, "This file is uncovered",
                          revision)
    assert issue.is_publishable()

    issues, patches = reporter.publish([issue], revision, [])
    assert len(issues) == 1
    assert len(patches) == 0

    # Check the callback has been used
    assert len(responses.calls) > 0
    call = responses.calls[-1]
    assert call.request.url == "http://phabricator.test/api/differential.createcomment"
    assert call.response.headers.get("unittest") == "coverage"
def test_phabricator_coverage(
    mock_config, mock_phabricator, phab, mock_try_task, mock_task
):
    """
    Test Phabricator reporter publication on a mock coverage issue
    """

    with mock_phabricator as api:
        revision = Revision.from_try(mock_try_task, api)
        revision.mercurial_revision = "deadbeef1234"
        revision.repository = "https://hg.mozilla.org/try"
        revision.repository_try_name = "try"
        revision.lines = {
            # Add dummy lines diff
            "test.txt": [0],
            "path/to/test.cpp": [0],
            "dom/test.cpp": [42],
        }
        reporter = PhabricatorReporter({"analyzers": ["coverage"]}, api=api)

    issue = CoverageIssue(
        mock_task(ZeroCoverageTask, "coverage"),
        "path/to/test.cpp",
        0,
        "This file is uncovered",
        revision,
    )
    assert issue.is_publishable()

    issues, patches = reporter.publish([issue], revision, [])
    assert len(issues) == 1
    assert len(patches) == 0

    # Check the lint results
    assert phab.build_messages["PHID-HMBT-test"] == [
        {
            "buildTargetPHID": "PHID-HMBT-test",
            "lint": [
                {
                    "code": "no-coverage",
                    "description": "WARNING: This file is uncovered",
                    "line": 1,
                    "name": "code coverage analysis",
                    "path": "path/to/test.cpp",
                    "severity": "warning",
                }
            ],
            "type": "work",
            "unit": [],
        }
    ]

    # Check the callback has been used
    assert phab.comments[51] == [VALID_COVERAGE_MESSAGE]
def test_phabricator_clang_tidy_and_coverage(
    mock_config, mock_phabricator, phab, mock_try_task, mock_task
):
    """
    Test Phabricator reporter publication on a mock coverage issue
    """

    with mock_phabricator as api:
        revision = Revision.from_try(mock_try_task, api)
        revision.mercurial_revision = "deadbeef1234"
        revision.repository = "https://hg.mozilla.org/try"
        revision.repository_try_name = "try"
        revision.lines = {
            # Add dummy lines diff
            "test.txt": [0],
            "path/to/test.cpp": [0],
            "another_test.cpp": [41, 42, 43],
        }
        revision.files = ["test.txt", "test.cpp", "another_test.cpp"]
        reporter = PhabricatorReporter(
            {"analyzers": ["coverage", "clang-tidy"]}, api=api
        )

    issue_clang_tidy = ClangTidyIssue(
        mock_task(ClangTidyTask, "source-test-clang-tidy"),
        revision,
        "another_test.cpp",
        "42",
        "51",
        "modernize-use-nullptr",
        "dummy message",
    )
    assert issue_clang_tidy.is_publishable()

    issue_coverage = CoverageIssue(
        mock_task(ZeroCoverageTask, "coverage"),
        "path/to/test.cpp",
        0,
        "This file is uncovered",
        revision,
    )
    assert issue_coverage.is_publishable()

    issues, patches = reporter.publish([issue_clang_tidy, issue_coverage], revision, [])
    assert len(issues) == 2
    assert len(patches) == 0

    # Check the lint results
    assert phab.build_messages["PHID-HMBT-test"] == [
        {
            "buildTargetPHID": "PHID-HMBT-test",
            "lint": [
                {
                    "char": 51,
                    "code": "modernize-use-nullptr",
                    "description": "WARNING: dummy message",
                    "line": 42,
                    "name": "clang-tidy",
                    "path": "another_test.cpp",
                    "severity": "warning",
                },
                {
                    "code": "no-coverage",
                    "description": "WARNING: This file is uncovered",
                    "line": 1,
                    "name": "code coverage analysis",
                    "path": "path/to/test.cpp",
                    "severity": "warning",
                },
            ],
            "type": "work",
            "unit": [],
        }
    ]

    # Check the callback has been used to post unique comment
    assert phab.comments[51] == [VALID_CLANG_TIDY_COVERAGE_MESSAGE]
Example #4
0
def test_phabricator_clang_tidy_and_coverage(
    mock_config, mock_phabricator, mock_try_task
):
    """
    Test Phabricator reporter publication on a mock coverage issue
    """
    from code_review_bot.report.phabricator import PhabricatorReporter
    from code_review_bot.revisions import Revision
    from code_review_bot.tasks.coverage import CoverageIssue
    from code_review_bot.tasks.clang_tidy import ClangTidyIssue

    def _check_comment_sa(request):
        # Check the Phabricator main comment is well formed
        payload = urllib.parse.parse_qs(request.body)
        assert payload["output"] == ["json"]
        assert len(payload["params"]) == 1
        details = json.loads(payload["params"][0])
        assert details == {
            "revision_id": 51,
            "message": VALID_CLANG_TIDY_MESSAGE,
            "attach_inlines": 1,
            "__conduit__": {"token": "deadbeef"},
        }

        # Outputs dummy empty response
        resp = {"error_code": None, "result": None}
        return (
            201,
            {"Content-Type": "application/json", "unittest": "clang-tidy"},
            json.dumps(resp),
        )

    def _check_comment_ccov(request):
        # Check the Phabricator main comment is well formed
        payload = urllib.parse.parse_qs(request.body)
        assert payload["output"] == ["json"]
        assert len(payload["params"]) == 1
        details = json.loads(payload["params"][0])
        assert details["message"] == VALID_COVERAGE_MESSAGE

        # Outputs dummy empty response
        resp = {"error_code": None, "result": None}
        return (
            201,
            {"Content-Type": "application/json", "unittest": "coverage"},
            json.dumps(resp),
        )

    responses.add_callback(
        responses.POST,
        "http://phabricator.test/api/differential.createcomment",
        callback=_check_comment_sa,
    )

    responses.add_callback(
        responses.POST,
        "http://phabricator.test/api/differential.createcomment",
        callback=_check_comment_ccov,
    )

    with mock_phabricator as api:
        revision = Revision.from_try(mock_try_task, api)
        revision.lines = {
            # Add dummy lines diff
            "test.txt": [0],
            "path/to/test.cpp": [0],
            "another_test.cpp": [41, 42, 43],
        }
        revision.files = ["test.txt", "test.cpp", "another_test.cpp"]
        reporter = PhabricatorReporter(
            {"analyzers": ["coverage", "clang-tidy"]}, api=api
        )

    issue_clang_tidy = ClangTidyIssue(
        "source-test-clang-tidy",
        revision,
        "another_test.cpp",
        "42",
        "51",
        "modernize-use-nullptr",
        "dummy message",
    )
    assert issue_clang_tidy.is_publishable()

    issue_coverage = CoverageIssue(
        "path/to/test.cpp", 0, "This file is uncovered", revision
    )
    assert issue_coverage.is_publishable()

    issues, patches = reporter.publish([issue_clang_tidy, issue_coverage], revision, [])
    assert len(issues) == 2
    assert len(patches) == 0

    # Check the callback has been used
    assert len(responses.calls) > 0
    call = responses.calls[-2]
    assert call.request.url == "http://phabricator.test/api/differential.createcomment"
    assert call.response.headers.get("unittest") == "clang-tidy"

    # Check the callback has been used
    assert len(responses.calls) > 0
    call = responses.calls[-1]
    assert call.request.url == "http://phabricator.test/api/differential.createcomment"
    assert call.response.headers.get("unittest") == "coverage"