Exemple #1
0
def test_flake8_rules(mock_config, mock_repository, mock_revision):
    '''
    Check flake8 rule detection
    '''
    from static_analysis_bot.lint import MozLintIssue

    # Build fake python files
    path = os.path.join(mock_config.repo_dir, 'test.py')
    with open(path, 'w') as f:
        f.write('print("TEST")')

    path = os.path.join(mock_config.repo_dir, 'test/dummy/XXX.py')
    os.makedirs(os.path.dirname(path), exist_ok=True)
    with open(path, 'w') as f:
        f.write('print("TEST 2")')

    # Valid issue
    issue = MozLintIssue('test.py', 1, 'error', 1, 'flake8', 'Dummy test', 'dummy rule', mock_revision)
    assert not issue.is_disabled_rule()
    assert issue.validates()

    # 3rd party
    issue = MozLintIssue('test/dummy/XXX.py', 1, 'error', 1, 'flake8', 'Dummy test', 'dummy rule', mock_revision)
    assert not issue.is_disabled_rule()
    assert issue.is_third_party()
    assert not issue.validates()

    # Flake8 bad quotes
    issue = MozLintIssue('test.py', 1, 'error', 1, 'flake8', 'Remove bad quotes or whatever.', 'Q000', mock_revision)
    assert issue.is_disabled_rule()
    assert not issue.validates()
Exemple #2
0
def test_as_text(mock_revision):
    '''
    Test text export for ClangTidyIssue
    '''
    from static_analysis_bot.lint import MozLintIssue
    issue = MozLintIssue('test.py', 1, 'error', 1, 'flake8', 'dummy test withUppercaseChars', 'dummy rule', mock_revision)

    assert issue.as_text() == 'Error: Dummy test withUppercaseChars [flake8: dummy rule]'
Exemple #3
0
def test_as_text(mock_config, mock_revision, mock_repository):
    '''
    Test text export for ClangTidyIssue
    '''
    from static_analysis_bot.lint import MozLintIssue

    path = os.path.join(mock_config.repo_dir, 'test.py')
    with open(path, 'w') as f:
        f.write('print("TEST")')

    issue = MozLintIssue('test.py', 1, 'error', 1, 'flake8', 'dummy test withUppercaseChars', 'dummy rule', mock_revision)

    assert issue.as_text() == 'Error: Dummy test withUppercaseChars [flake8: dummy rule]'
Exemple #4
0
def test_issue_path(mock_repository, mock_config, mock_revision):
    '''
    A mozlint issue can be absolute or relative
    But the path sent to reporters must always be relative
    '''
    from static_analysis_bot.lint import MozLintIssue

    relative_path = 'test.txt'
    issue = MozLintIssue(relative_path, 1, 'error', 1, 'dummy', 'Any error', 'XXX', mock_revision)
    assert issue.path == 'test.txt'

    absolute_path = os.path.join(mock_config.repo_dir, relative_path)
    issue = MozLintIssue(absolute_path, 1, 'error', 1, 'dummy', 'Any error', 'XXX', mock_revision)
    assert issue.path == 'test.txt'
Exemple #5
0
    def _test_reporter(api, analyzers):
        # Always use the same setup, only varies the analyzers
        revision = PhabricatorRevision('PHID-DIFF-abcdef', api)
        revision.lines = {
            'test.cpp': [41, 42, 43],
        }
        reporter = PhabricatorReporter({'analyzers': analyzers}, api=api)

        issues = [
            ClangFormatIssue('test.cpp', 42, 1, revision),
            ClangTidyIssue(('test.cpp', '42', '51', 'error', 'dummy message', 'modernize-use-nullptr'), revision),
            InferIssue({
                'file': 'test.cpp',
                'line': 42,
                'column': 1,
                'bug_type': 'dummy',
                'kind': 'whatever',
                'qualifier': 'dummy message.',
            }, revision),
            MozLintIssue('test.cpp', 1, 'danger', 42, 'flake8', 'Python error', 'EXXX', revision),
        ]

        assert all(i.is_publishable() for i in issues)

        revision.improvement_patches = {
            'dummy': 'not gonna work',
            'clang-format': 'https://diff.url/clang-format',
            'clang-tidy': 'https://diff.url/clang-tidy',
            'mozlint': 'https://diff.url/mozlint',
            'infer': 'https://diff.url/infer',
        }

        return reporter.publish(issues, revision)
Exemple #6
0
 def build_issue(self, task_name, issue, revision):
     '''
     Convert a raw text issue into an Issue instance
     TODO: this should be simplified by using mach JSON output
     '''
     if task_name.startswith(MozLintIssue.TRY_PREFIX):
         return MozLintIssue.from_try(task_name, issue, revision)
     else:
         logger.warn('Unsupported task type', name=task_name)
Exemple #7
0
def test_as_text(mock_config, mock_revision, mock_repository):
    '''
    Test text export for ClangTidyIssue
    '''
    from static_analysis_bot.lint import MozLintIssue

    path = os.path.join(mock_config.repo_dir, 'test.py')
    with open(path, 'w') as f:
        f.write('print("TEST")')

    issue = MozLintIssue('test.py', 1, 'error', 1, 'flake8', 'dummy test withUppercaseChars', 'dummy rule', mock_revision)

    assert issue.as_text() == 'Error: Dummy test withUppercaseChars [flake8: dummy rule]'

    assert issue.as_phabricator_lint() == {
        'char': 1,
        'code': 'flake8.dummy rule',
        'line': 1,
        'name': 'MozLint Flake8 - dummy rule',
        'description': 'dummy test withUppercaseChars',
        'path': 'test.py',
        'severity': 'error',
    }
Exemple #8
0
def test_from_try(mock_revision, mock_config):
    '''
    Test issue building from try lines
    '''
    mock_config.has_local_clone = False

    from static_analysis_bot.lint import MozLintIssue

    line = """/builds/worker/checkouts/gecko/tools/tryselect/cli.py:14:1 | block comment should start with '# ' (E265)"""  # noqa

    issue = MozLintIssue.from_try('source-test-mozlint-py-flake8', line, mock_revision)
    assert issue.path == 'gecko/tools/tryselect/cli.py'
    assert issue.line == 14
    assert issue.column == 1
    assert issue.message == "block comment should start with '# '"
    assert issue.linter == 'py-flake8'
    assert issue.rule == 'E265'
    def _test_reporter(api, analyzers):
        # Always use the same setup, only varies the analyzers
        revision = PhabricatorRevision(api, 'PHID-DIFF-abcdef')
        revision.lines = {
            'test.cpp': [0, 41, 42, 43],
            'dom/test.cpp': [
                42,
            ],
        }
        reporter = PhabricatorReporter({'analyzers': analyzers}, api=api)

        issues = [
            ClangFormatIssue('dom/test.cpp', 42, 1, revision),
            ClangTidyIssue(('test.cpp', '42', '51', 'error', 'dummy message',
                            'modernize-use-nullptr'), revision),
            InferIssue(
                {
                    'file': 'test.cpp',
                    'line': 42,
                    'column': 1,
                    'bug_type': 'dummy',
                    'kind': 'whatever',
                    'qualifier': 'dummy message.',
                }, revision),
            MozLintIssue('test.cpp', 1, 'danger', 42, 'flake8', 'Python error',
                         'EXXX', revision),
            CoverageIssue('test.cpp', 0, 'This file is uncovered', revision),
        ]

        assert all(i.is_publishable() for i in issues)

        revision.improvement_patches = [
            ImprovementPatch('dummy', repr(revision), 'Whatever'),
            ImprovementPatch('clang-tidy', repr(revision), 'Some C fixes'),
            ImprovementPatch('clang-format', repr(revision),
                             'Some lint fixes'),
            ImprovementPatch('infer', repr(revision), 'Some java fixes'),
            ImprovementPatch('mozlint', repr(revision), 'Some js fixes'),
        ]
        list(map(lambda p: p.write(),
                 revision.improvement_patches))  # trigger local write

        return reporter.publish(issues, revision)
Exemple #10
0
def test_flake8_rules(tmpdir, mock_config, mock_revision):
    '''
    Check flake8 rule detection
    '''
    from static_analysis_bot.lint import MozLintIssue

    # Build fake python files
    path = os.path.join(mock_config.repo_dir, 'test.py')
    with open(path, 'w') as f:
        f.write('print("TEST")')

    path = os.path.join(mock_config.repo_dir, 'test/dummy/XXX.py')
    os.makedirs(os.path.dirname(path), exist_ok=True)
    with open(path, 'w') as f:
        f.write('print("TEST 2")')

    # Valid issue
    issue = MozLintIssue('test.py', 1, 'error', 1, 'flake8', 'Dummy test',
                         'dummy rule', mock_revision)
    assert not issue.is_disabled_rule()
    assert issue.validates()

    # 3rd party
    issue = MozLintIssue('test/dummy/XXX.py', 1, 'error', 1, 'flake8',
                         'Dummy test', 'dummy rule', mock_revision)
    assert not issue.is_disabled_rule()
    assert issue.is_third_party()
    assert not issue.validates()

    # Flake8 bad quotes
    issue = MozLintIssue('test.py', 1, 'error', 1, 'flake8',
                         'Remove bad quotes or whatever.', 'Q000',
                         mock_revision)
    assert issue.is_disabled_rule()
    assert not issue.validates()
Exemple #11
0
def test_comment(mock_mozreview, test_cpp, mock_revision):
    '''
    Test comment creation for specific issues
    '''
    from static_analysis_bot.clang.tidy import ClangTidyIssue
    from static_analysis_bot.clang.format import ClangFormatIssue
    from static_analysis_bot.lint import MozLintIssue
    from static_analysis_bot.report.base import Reporter

    # Init dummy reporter
    class TestReporter(Reporter):
        def __init__(self):
            pass

    reporter = TestReporter()

    # Build clang tidy fake issue, while forcing publication status
    header = ('test.cpp', 1, 1, 'error', 'Dummy message', 'test-check')
    clang_tidy_publishable = ClangTidyIssue(header, mock_revision)
    clang_tidy_publishable.is_publishable = lambda: True
    assert clang_tidy_publishable.is_publishable()
    issues = [
        clang_tidy_publishable,
    ]

    assert reporter.build_comment(issues, 'https://report.example.com') == '''
Code analysis found 1 defect in this patch:
 - 1 defect found by clang-tidy

You can run this analysis locally with:
 - `./mach static-analysis check path/to/file.cpp` (C/C++)


If you see a problem in this automated review, please report it here: https://report.example.com
'''

    # Now add a clang-format issue
    clang_format_publishable = ClangFormatIssue('test.cpp', '', '',
                                                ('delete', 1, 2, 3, 4),
                                                mock_revision)
    clang_format_publishable.is_publishable = lambda: True
    assert clang_tidy_publishable.is_publishable()
    issues.append(clang_format_publishable)

    assert reporter.build_comment(issues, 'https://report.example.com') == '''
Code analysis found 2 defects in this patch:
 - 1 defect found by clang-format
 - 1 defect found by clang-tidy

You can run this analysis locally with:
 - `./mach clang-format -p path/to/file.cpp` (C/C++)
 - `./mach static-analysis check path/to/file.cpp` (C/C++)


If you see a problem in this automated review, please report it here: https://report.example.com
'''

    # Now add a mozlint issue
    mozlint_publishable = MozLintIssue('test.cpp', 1, 'error', 1, 'test',
                                       'Dummy test', 'dummy rule',
                                       mock_revision)
    mozlint_publishable.is_publishable = lambda: True
    assert mozlint_publishable.is_publishable()
    issues.append(mozlint_publishable)

    assert reporter.build_comment(issues, 'https://report.example.com') == '''