示例#1
0
    def test_z_check_without_metadata(self):
        """
        This test checks whether the storage works without a metadata.json.
        The name of the test contains a "z" character at the beginning. The
        test run in alphabetical order and it is necessary to run previous
        tests before this one.
        """
        runs = self._cc_client.getRunData(None)
        run_id = max(map(lambda run: run.runId, runs))

        codechecker.analyze(self._codechecker_cfg, 'hello', self._test_dir)

        try:
            # Test storage without metadata.json.
            os.remove(
                os.path.join(self._codechecker_cfg['reportdir'],
                             'metadata.json'))
        except OSError:
            # metadata.json already removed.
            pass

        codechecker.store(self._codechecker_cfg, 'hello',
                          self._codechecker_cfg['reportdir'])

        reports = self._cc_client.getRunResults([run_id], 100, 0, [], None,
                                                None)

        self.assertEqual(len(reports), 4)
    def test_check_without_metadata(self):
        """
        This test checks whether the storage works without a metadata.json.
        """
        runs = self._cc_client.getRunData(None)
        if runs:
            run_id = max(map(lambda run: run.runId, runs))

            # Remove the run.
            self._cc_client.removeRun(run_id)

        self._create_source_file(0)

        codechecker.analyze(self._codechecker_cfg, 'hello', self._test_dir)

        try:
            # Test storage without metadata.json.
            os.remove(
                os.path.join(self._codechecker_cfg['reportdir'],
                             'metadata.json'))
        except OSError:
            # metadata.json already removed.
            pass

        codechecker.store(self._codechecker_cfg, 'hello')

        runs = self._cc_client.getRunData(None)
        run_id = max(map(lambda run: run.runId, runs))

        reports = self._cc_client.getRunResults([run_id], 100, 0, [], None,
                                                None)

        self.assertEqual(len(reports), 2)
示例#3
0
    def test_parse(self):
        """
        Test if parse there are skip messages in the output of the parse if
        the source files did change between the analysis and the parse.
        """

        test_proj_path = self._testproject_data['project_path']

        test_proj_files = os.listdir(test_proj_path)
        print(test_proj_files)

        null_deref_file = os.path.join(test_proj_path, 'null_dereference.cpp')

        codechecker.analyze(self._codechecker_cfg, 'hash_change',
                            test_proj_path)

        ret, out, _ = codechecker.parse(self._codechecker_cfg)
        self.assertEqual(ret, 0)

        # Need to wait a little before updating the last modification time.
        # If we do not wait, not enough time will be past
        # between the analysis and the parse in the test.
        time.sleep(2)
        touch(null_deref_file)

        ret, out, _ = codechecker.parse(self._codechecker_cfg)
        self.assertEqual(ret, 0)
        print(out)

        msg = 'did change since the last analysis.'
        self.assertTrue(msg in out,
                        '"' + msg + '" was not found in the parse output')
示例#4
0
    def test_store_config_file_mod(self):
        """Storage should be successful if a non report related file changed.

        Checking the modification time stamps should be done only for
        the source files mentioned in the report plist files.
        Modifying any non report related file should not prevent the storage
        of the reports.
        """
        test_proj = os.path.join(self.test_workspace, 'test_proj')

        ret = codechecker.log(self._codechecker_cfg, test_proj,
                              clean_project=True)
        self.assertEqual(ret, 0)

        ret = codechecker.analyze(self._codechecker_cfg, test_proj)
        self.assertEqual(ret, 0)

        test_proj_path = self._testproject_data['project_path']

        # touch one file so it will be analyzed again
        touch(os.path.join(test_proj_path, 'null_dereference.cpp'))

        ret = codechecker.log(self._codechecker_cfg, test_proj)
        self.assertEqual(ret, 0)

        ret = codechecker.analyze(self._codechecker_cfg,
                                  test_proj)
        self.assertEqual(ret, 0)

        touch(os.path.join(self._codechecker_cfg['reportdir'],
                           'compile_cmd.json'))

        ret = codechecker.store(self._codechecker_cfg, 'test_proj')
        self.assertEqual(ret, 0)
    def test_parse(self):
        """
        Test if parse there are skip messages in the output of the parse if
        the source files did change between the analysis and the parse.
        """

        test_proj_path = self._testproject_data['project_path']

        test_proj_files = os.listdir(test_proj_path)
        print(test_proj_files)

        null_deref_file = os.path.join(test_proj_path, 'null_dereference.cpp')

        codechecker.analyze(self._codechecker_cfg,
                            'hash_change',
                            test_proj_path)

        ret, out, _ = codechecker.parse(self._codechecker_cfg)
        self.assertEqual(ret, 0)

        # Need to wait a little before updating the last modification time.
        # If we do not wait, not enough time will be past
        # between the analysis and the parse in the test.
        time.sleep(2)
        touch(null_deref_file)

        ret, out, _ = codechecker.parse(self._codechecker_cfg)
        self.assertEqual(ret, 0)
        print(out)

        msg = 'did change since the last analysis.'
        self.assertTrue(msg in out,
                        '"' + msg + '" was not found in the parse output')
示例#6
0
    def test_store_multiple_report_dirs(self):
        """ Test storing multiple report directories.

        Analyze the same project to different report directories with different
        checker configurations and store these report directories with one
        store command to a run.
        """
        cfg = dict(self.codechecker_cfg)
        codechecker.log(cfg, self.test_proj_dir)

        report_dir1 = os.path.join(self.test_proj_dir, 'report_dir1')
        report_dir2 = os.path.join(self.test_proj_dir, 'report_dir2')

        cfg['reportdir'] = report_dir1
        cfg['checkers'] = [
            '-d', 'core.DivideZero', '-e', 'deadcode.DeadStores'
        ]
        codechecker.analyze(cfg, self.test_proj_dir)

        cfg['reportdir'] = report_dir2
        cfg['checkers'] = [
            '-e', 'core.DivideZero', '-d', 'deadcode.DeadStores'
        ]
        codechecker.analyze(cfg, self.test_proj_dir)

        run_name = "multiple_report_dirs"
        store_cmd = [
            env.codechecker_cmd(), "store", report_dir1, report_dir2, "--name",
            run_name, "--url",
            env.parts_to_url(self.codechecker_cfg)
        ]

        proc = subprocess.Popen(store_cmd,
                                encoding="utf-8",
                                errors="ignore",
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        _, err = proc.communicate()

        self.assertNotIn("UserWarning: Duplicate name", err)

        # Check the reports.
        query_cmd = [
            env.codechecker_cmd(), "cmd", "results", run_name, "--url",
            env.parts_to_url(self.codechecker_cfg), "-o", "json"
        ]

        out = subprocess.check_output(query_cmd,
                                      encoding="utf-8",
                                      errors="ignore")
        reports = json.loads(out)

        self.assertTrue(
            any(r['checkerId'] == 'core.DivideZero' for r in reports))

        self.assertTrue(
            any(r['checkerId'] == 'deadcode.DeadStores' for r in reports))
    def test_check_without_metadata(self):
        """
        This test checks whether the storage works without a metadata.json.
        """
        runs = self._cc_client.getRunData(None)
        if runs:
            run_id = max(map(lambda run: run.runId, runs))

            # Remove the run.
            self._cc_client.removeRun(run_id)

        self._create_source_file(0)

        codechecker.analyze(self._codechecker_cfg,
                            'hello',
                            self._test_dir)

        try:
            # Test storage without metadata.json.
            os.remove(os.path.join(self._codechecker_cfg['reportdir'],
                                   'metadata.json'))
        except OSError:
            # metadata.json already removed.
            pass

        codechecker.store(self._codechecker_cfg, 'hello')

        runs = self._cc_client.getRunData(None)
        run_id = max(map(lambda run: run.runId, runs))

        reports = self._cc_client.getRunResults([run_id],
                                                100,
                                                0,
                                                [],
                                                None,
                                                None)

        self.assertEqual(len(reports), 2)
示例#8
0
    def test_store_multiple_report_dirs(self):
        """ Test storing multiple report directories.

        Analyze the same project to different report directories with different
        checker configurations and store these report directories with one
        store command to a run.
        """
        cfg = dict(self._codechecker_cfg)
        codechecker.log(cfg, self._temp_workspace)

        common_report_dir = os.path.join(self._temp_workspace, 'reports')
        report_dir1 = \
            os.path.join(self._temp_workspace, common_report_dir,
                         'report_dir1')
        report_dir2 = \
            os.path.join(self._temp_workspace, common_report_dir,
                         'report_dir2')

        cfg['reportdir'] = report_dir1
        cfg['checkers'] = [
            '-d', 'core.DivideZero', '-e', 'deadcode.DeadStores'
        ]
        codechecker.analyze(cfg, self._temp_workspace)

        cfg['reportdir'] = report_dir2
        cfg['checkers'] = [
            '-e', 'core.DivideZero', '-d', 'deadcode.DeadStores'
        ]
        codechecker.analyze(cfg, self._temp_workspace)

        def store_multiple_report_dirs(report_dirs):
            """ """
            run_name = "multiple_report_dirs"
            store_cmd = [
                env.codechecker_cmd(), "store", *report_dirs, "--name",
                run_name, "--url",
                env.parts_to_url(self._codechecker_cfg)
            ]

            proc = subprocess.Popen(store_cmd,
                                    encoding="utf-8",
                                    errors="ignore",
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            _, err = proc.communicate()

            self.assertNotIn("UserWarning: Duplicate name", err)

            # Check the reports.
            query_cmd = [
                env.codechecker_cmd(), "cmd", "results", run_name, "--url",
                env.parts_to_url(self._codechecker_cfg), "-o", "json"
            ]

            out = subprocess.check_output(query_cmd,
                                          encoding="utf-8",
                                          errors="ignore")
            reports = json.loads(out)

            self.assertTrue(
                any(r['checkerId'] == 'core.DivideZero' for r in reports))

            self.assertTrue(
                any(r['checkerId'] == 'deadcode.DeadStores' for r in reports))

            # Get analysis info.
            limit = None
            offset = 0
            report = [
                r for r in reports if r['checkerId'] == 'core.DivideZero'
            ][0]

            # Get analysis info for a run.
            analysis_info_filter = AnalysisInfoFilter(runId=report['runId'])
            analysis_info = self._cc_client.getAnalysisInfo(
                analysis_info_filter, limit, offset)
            self.assertEqual(len(analysis_info), 2)
            self.assertTrue(
                any(report_dir1 in i.analyzerCommand for i in analysis_info))
            self.assertTrue(
                any(report_dir2 in i.analyzerCommand for i in analysis_info))

            # Get analysis info for a report.
            analysis_info_filter = AnalysisInfoFilter(
                reportId=report['reportId'])

            analysis_info = self._cc_client.getAnalysisInfo(
                analysis_info_filter, limit, offset)
            self.assertEqual(len(analysis_info), 1)
            self.assertTrue(
                any(report_dir2 in i.analyzerCommand for i in analysis_info))

            # Get analysis infor for run history.
            query_cmd = [
                env.codechecker_cmd(), "cmd", "history", "-n", run_name,
                "--url",
                env.parts_to_url(self._codechecker_cfg), "-o", "json"
            ]

            out = subprocess.check_output(query_cmd,
                                          encoding="utf-8",
                                          errors="ignore")
            history = json.loads(out)
            self.assertTrue(history)

            h = max(history, key=lambda h: h["id"])

            analysis_info_filter = AnalysisInfoFilter(runHistoryId=h['id'])
            analysis_info = self._cc_client.getAnalysisInfo(
                analysis_info_filter, limit, offset)
            self.assertEqual(len(analysis_info), 2)
            self.assertTrue(
                any(report_dir1 in i.analyzerCommand for i in analysis_info))
            self.assertTrue(
                any(report_dir2 in i.analyzerCommand for i in analysis_info))

            # Check the reports.
            rm_cmd = [
                env.codechecker_cmd(), "cmd", "del", "-n", run_name, "--url",
                env.parts_to_url(self._codechecker_cfg)
            ]

            out = subprocess.check_output(rm_cmd,
                                          encoding="utf-8",
                                          errors="ignore")

        # Store report directories separately.
        store_multiple_report_dirs([report_dir1, report_dir2])

        # Store report directories recursively.
        store_multiple_report_dirs([common_report_dir])

        shutil.rmtree(common_report_dir, ignore_errors=True)
示例#9
0
def setup_package():
    """
    Setup the environment for the tests.
    Check the test project twice, then start the server.
    """

    global TEST_WORKSPACE
    TEST_WORKSPACE = env.get_workspace('diff')

    os.environ['TEST_WORKSPACE'] = TEST_WORKSPACE

    test_project = 'cpp'

    test_project_path = project.path(test_project)

    pg_db_config = env.get_postgresql_cfg()

    test_config = {}

    project_info = project.get_info(test_project)

    test_config['test_project'] = project_info

    suppress_file = None

    skip_list_file = None

    # Setup environment variabled for test cases.
    host_port_cfg = env.get_host_port_cfg()

    test_env = env.test_env()

    codechecker_cfg = {
        'suppress_file': suppress_file,
        'skip_list_file': skip_list_file,
        'check_env': test_env,
        'workspace': TEST_WORKSPACE,
        'reportdir': os.path.join(TEST_WORKSPACE, 'reports'),
        'pg_db_config': pg_db_config,
        'checkers':
        ['-d', 'core.CallAndMessage', '-e', 'core.StackAddressEscape']
    }

    codechecker_cfg.update(host_port_cfg)

    test_config['codechecker_cfg'] = codechecker_cfg

    ret = project.clean(test_project, test_env)
    if ret:
        sys.exit(ret)

    # Start the CodeChecker server.
    print("Starting server to get results")
    _start_server(codechecker_cfg, test_config, False)

    test_project_name_base = project_info['name'] + '_' + uuid.uuid4().hex

    ret = codechecker.check(codechecker_cfg, test_project_name_base,
                            test_project_path)
    if ret:
        sys.exit(1)
    print("First analysis of the test project was successful.")

    ret = project.clean(test_project, test_env)
    if ret:
        sys.exit(ret)

    test_project_name_new = project_info['name'] + '_' + uuid.uuid4().hex

    # Let's run the second analysis with different
    # checkers to have some real difference.
    codechecker_cfg['checkers'] = [
        '-e', 'core.CallAndMessage', '-d', 'core.StackAddressEscape'
    ]
    ret = codechecker.check(codechecker_cfg, test_project_name_new,
                            test_project_path)
    if ret:
        sys.exit(1)
    print("Second analysis of the test project was successful.")

    # Run the second analysis results
    # into a report directory
    ret = codechecker.analyze(codechecker_cfg, test_project_name_new,
                              test_project_path)
    if ret:
        sys.exit(1)
    print("CodeChecker analyze of test project was successful.")

    if pg_db_config:
        print("Waiting for PotgreSQL to stop.")
        codechecker.wait_for_postgres_shutdown(TEST_WORKSPACE)

    # Order of the test run names matter at comparison!
    codechecker_cfg['run_names'] = [
        test_project_name_base, test_project_name_new
    ]

    test_config['codechecker_cfg'] = codechecker_cfg

    # Export test configuration to the workspace.
    env.export_test_cfg(TEST_WORKSPACE, test_config)
示例#10
0
def setup_package():
    """
    Setup the environment for the tests.
    Check the test project twice.
    """

    global TEST_WORKSPACE
    TEST_WORKSPACE = env.get_workspace('diff')

    os.environ['TEST_WORKSPACE'] = TEST_WORKSPACE

    test_project = 'cpp'

    test_project_path = project.path(test_project)
    test_project_path_altered = os.path.join(TEST_WORKSPACE, "cpp_copy")
    # We create a copy of the test project which we will change
    # to simulate code editing.
    dir_util.copy_tree(test_project_path, test_project_path_altered)

    test_config = {}

    project_info = project.get_info(test_project)

    test_config['test_project'] = project_info

    suppress_file = None

    skip_list_file = None

    test_env = env.test_env(TEST_WORKSPACE)

    codechecker_cfg = {
        'suppress_file': suppress_file,
        'skip_list_file': skip_list_file,
        'check_env': test_env,
        'force': True,
        'workspace': TEST_WORKSPACE,
        'reportdir': os.path.join(TEST_WORKSPACE, 'reports'),
        'checkers':
        ['-d', 'core.CallAndMessage', '-e', 'core.StackAddressEscape']
    }

    test_config['codechecker_cfg'] = codechecker_cfg

    ret = project.clean(test_project, test_env)
    if ret:
        sys.exit(ret)

    # Start or connect to the running CodeChecker server and get connection
    # details.
    print("This test uses a CodeChecker server... connecting...")
    server_access = codechecker.start_or_get_server()
    server_access['viewer_product'] = 'diff'
    codechecker.add_test_package_product(server_access, TEST_WORKSPACE)

    # Extend the checker configuration with the server access.
    codechecker_cfg.update(server_access)

    test_project_name_base = project_info['name'] + '_' + uuid.uuid4().hex

    ret = codechecker.check(codechecker_cfg, test_project_name_base,
                            test_project_path)
    if ret:
        sys.exit(1)
    print("First analysis of the test project was successful.")

    ret = project.clean(test_project, test_env)
    if ret:
        sys.exit(ret)

    test_project_name_new = project_info['name'] + '_' + uuid.uuid4().hex

    # Let's run the second analysis with different
    # checkers to have some real difference.
    codechecker_cfg['checkers'] = [
        '-e', 'core.CallAndMessage', '-d', 'core.StackAddressEscape'
    ]
    ret = codechecker.check(codechecker_cfg, test_project_name_new,
                            test_project_path_altered)
    if ret:
        sys.exit(1)
    print("Second analysis of the test project was successful.")

    # Insert a real suppression into the code

    altered_file = os.path.join(test_project_path_altered,
                                "call_and_message.cpp")
    insert_suppression(altered_file)

    # Run the second analysis results
    # into a report directory
    ret = codechecker.analyze(codechecker_cfg, test_project_name_new,
                              test_project_path_altered)
    if ret:
        sys.exit(1)
    print("CodeChecker analyze of test project was successful.")

    test_project_name_update = project_info['name'] + '_' + uuid.uuid4().hex
    codechecker_cfg['tag'] = 't1'
    codechecker_cfg['checkers'] = [
        '-d', 'core.CallAndMessage', '-e', 'core.StackAddressEscape'
    ]
    codechecker_cfg['reportdir'] = os.path.join(TEST_WORKSPACE, 'reports2')

    ret = codechecker.check(codechecker_cfg, test_project_name_update,
                            test_project_path)
    if ret:
        sys.exit(1)
    print("Third analysis of the test project was successful.")

    codechecker_cfg['tag'] = 't2'
    codechecker_cfg['checkers'] = [
        '-e', 'core.CallAndMessage', '-d', 'core.StackAddressEscape'
    ]
    ret = codechecker.check(codechecker_cfg, test_project_name_update,
                            test_project_path)
    if ret:
        sys.exit(1)
    print("Fourth analysis of the test project was successful.")

    codechecker_cfg['tag'] = 't3'
    ret = codechecker.check(codechecker_cfg, test_project_name_update,
                            test_project_path)
    if ret:
        sys.exit(1)
    print("Fifth analysis of the test project was successful.")

    # Order of the test run names matter at comparison!
    codechecker_cfg['run_names'] = [
        test_project_name_base, test_project_name_new, test_project_name_update
    ]

    test_config['codechecker_cfg'] = codechecker_cfg

    # Export test configuration to the workspace.
    env.export_test_cfg(TEST_WORKSPACE, test_config)
示例#11
0
def setup_package():
    """Setup the environment for testing diff_remote."""

    global TEST_WORKSPACE
    TEST_WORKSPACE = env.get_workspace('diff_remote')

    # Set the TEST_WORKSPACE used by the tests.
    os.environ['TEST_WORKSPACE'] = TEST_WORKSPACE

    test_config = {}

    test_project = 'cpp'

    project_info = project.get_info(test_project)

    # Copy the test project to the workspace. The tests should
    # work only on this test project.
    test_proj_path_base = os.path.join(TEST_WORKSPACE, "test_proj_base")
    shutil.copytree(project.path(test_project), test_proj_path_base)

    # Copy the test project to the workspace. The tests should
    # work only on this test project.
    test_proj_path_new = os.path.join(TEST_WORKSPACE, "test_proj_new")
    shutil.copytree(project.path(test_project), test_proj_path_new)

    # Copy the test project to the workspace. The tests should
    # work only on this test project.
    test_proj_path_update = os.path.join(TEST_WORKSPACE, "test_proj_update")
    shutil.copytree(project.path(test_project), test_proj_path_update)

    project_info['project_path_base'] = test_proj_path_base
    project_info['project_path_new'] = test_proj_path_new
    project_info['project_path_update'] = test_proj_path_update

    # Suppress file should be set here if needed by the tests.
    suppress_file = None

    # Skip list file should be set here if needed by the tests.
    skip_list_file = None

    # Get an environment which should be used by the tests.
    test_env = env.test_env(TEST_WORKSPACE)

    # Create a basic CodeChecker config for the tests, this should
    # be imported by the tests and they should only depend on these
    # configuration options.
    codechecker_cfg = {
        'suppress_file': suppress_file,
        'skip_list_file': skip_list_file,
        'check_env': test_env,
        'workspace': TEST_WORKSPACE,
        'checkers': []
    }

    # Start or connect to the running CodeChecker server and get connection
    # details.
    print("This test uses a CodeChecker server... connecting...")
    server_access = codechecker.start_or_get_server()
    server_access['viewer_product'] = 'diff_remote'
    codechecker.add_test_package_product(server_access, TEST_WORKSPACE)

    # Extend the checker configuration with the server access.
    codechecker_cfg.update(server_access)

    # Base analysis

    altered_file = os.path.join(test_proj_path_base, "call_and_message.cpp")
    project.insert_suppression(altered_file)
    codechecker_cfg['reportdir'] = os.path.join(test_proj_path_base,
                                                'reports')
    codechecker_cfg['checkers'] = ['-e', 'core.CallAndMessage',
                                   '-d', 'core.NullDereference']

    ret = codechecker.log_and_analyze(codechecker_cfg, test_proj_path_base)
    if ret:
        sys.exit(1)
    print('Analyzing base was successful.')

    # Store base results.
    codechecker_cfg['reportdir'] = os.path.join(test_proj_path_base,
                                                'reports')

    test_project_name_base = project_info['name'] + '_' + uuid.uuid4().hex
    ret = codechecker.store(codechecker_cfg, test_project_name_base)
    if ret:
        sys.exit(1)

    # Store with a literal ':' in the name.
    ret = codechecker.store(codechecker_cfg, test_project_name_base + ":base")
    if ret:
        sys.exit(1)

    # New analysis
    altered_file = os.path.join(test_proj_path_new, "call_and_message.cpp")
    project.insert_suppression(altered_file)
    codechecker_cfg['reportdir'] = os.path.join(test_proj_path_new,
                                                'reports')
    codechecker_cfg['checkers'] = ['-d', 'core.CallAndMessage',
                                   '-e', 'core.NullDereference']

    ret = codechecker.log_and_analyze(codechecker_cfg, test_proj_path_new)
    if ret:
        sys.exit(1)
    print('Analyzing new was successful.')

    # Store new results.
    codechecker_cfg['reportdir'] = os.path.join(test_proj_path_new,
                                                'reports')

    test_project_name_new = project_info['name'] + '_' + uuid.uuid4().hex
    ret = codechecker.store(codechecker_cfg, test_project_name_new)
    if ret:
        sys.exit(1)

    # Store with a literal ':' in the name.
    ret = codechecker.store(codechecker_cfg, test_project_name_new + ":new")
    if ret:
        sys.exit(1)

    # Analyze multiple times to store results with multiple tags.
    codechecker_cfg['reportdir'] = os.path.join(test_proj_path_update,
                                                'reports')

    test_project_name_update = project_info['name'] + '_' + uuid.uuid4().hex
    codechecker_cfg['tag'] = 't1'
    codechecker_cfg['checkers'] = ['-d', 'core.CallAndMessage',
                                   '-e', 'core.StackAddressEscape'
                                   ]

    codechecker_cfg['reportdir'] = os.path.join(test_proj_path_update,
                                                'reports')

    ret = codechecker.log_and_analyze(codechecker_cfg, test_proj_path_update)
    if ret:
        sys.exit(1)

    # Store update with t1 tag.
    ret = codechecker.store(codechecker_cfg, test_project_name_update)
    if ret:
        sys.exit(1)

    codechecker_cfg['tag'] = 't2'
    codechecker_cfg['checkers'] = ['-e', 'core.CallAndMessage',
                                   '-d', 'core.StackAddressEscape'
                                   ]
    ret = codechecker.analyze(codechecker_cfg, test_proj_path_update)
    if ret:
        sys.exit(1)

    # Store update with t2 tag.
    ret = codechecker.store(codechecker_cfg, test_project_name_update)
    if ret:
        sys.exit(1)

    codechecker_cfg['tag'] = 't3'
    ret = codechecker.log_and_analyze(codechecker_cfg, test_proj_path_update)
    if ret:
        sys.exit(1)

    # Store update with t3 tag.
    ret = codechecker.store(codechecker_cfg, test_project_name_update)
    if ret:
        sys.exit(1)

    # Order of the test run names matter at comparison!
    codechecker_cfg['run_names'] = [test_project_name_base,
                                    test_project_name_new,
                                    test_project_name_update]

    test_config['test_project'] = project_info
    test_config['codechecker_cfg'] = codechecker_cfg

    # Export the test configuration to the workspace.
    env.export_test_cfg(TEST_WORKSPACE, test_config)

    # Remove report directories which are not used anymore.
    shutil.rmtree(test_proj_path_base, ignore_errors=True)
    shutil.rmtree(test_proj_path_new, ignore_errors=True)
    def test_detection_status_off_with_cfg(self):
        """ Test detection status with .clang-tidy config file. """
        # Explicitly disable all modernize checkers from the command line but
        # enable all hicpp and modernize checkers from the .clang-tidy file.
        # If we store the results to the server than no reports will be marked
        # as OFF.
        cfg = dict(self._codechecker_cfg)
        cfg['checkers'] = ['-d', 'modernize']
        cfg['analyzer_config'] = ['clang-tidy:take-config-from-directory=true']

        self._create_source_file(1)
        self._create_clang_tidy_cfg_file(['-*', 'hicpp-*', 'modernize-*'])
        self._check_source_file(cfg)

        reports = self._cc_client.getRunResults(None, 100, 0, [], None, None,
                                                False)

        hicpp_results = [r for r in reports if r.checkerId.startswith('hicpp')]
        self.assertEqual(len(hicpp_results), 1)

        offed_reports = [
            r for r in reports if r.detectionStatus == DetectionStatus.OFF
        ]
        self.assertEqual(len(offed_reports), 0)

        # Store the reports again to see that still no reports are marked as
        # OFF (every report marked as Unresolved).
        self._check_source_file(cfg)

        reports = self._cc_client.getRunResults(None, 100, 0, [], None, None,
                                                False)
        self.assertTrue([
            r for r in reports
            if r.detectionStatus == DetectionStatus.UNRESOLVED
        ])

        # We turn off all the 'hicpp' checkers too. If we store the results to
        # the server see that 'hicpp' results will be marked as 'OFF' now.
        cfg['checkers'] = ['-d', 'modernize', '-d', 'hicpp']
        self._check_source_file(cfg)

        reports = self._cc_client.getRunResults(None, 100, 0, [], None, None,
                                                False)

        offed_reports = [
            r for r in reports if r.detectionStatus == DetectionStatus.OFF
        ]
        self.assertEqual(len(offed_reports), 1)

        # We do not disable hicpp checkers from the command line, so it will
        # be enabled by the .clang-tidy file. We analyze our test project and
        # remove the plist files to see that every reports will be marked as
        # Resolved.
        # FIXME: Unfortunately it will not work because hicpp checkers will be
        # disabled by the metadata.json config file so the server will mark
        # these reports as OFF.
        # A solution for this problem can be if we mark reports as OFF only and
        # only if the user explicitly disabled a checker in the command line.
        cfg['checkers'] = ['-d', 'modernize']
        codechecker.analyze(cfg, self._test_dir)

        # Remove all plist files.
        report_dir = self._codechecker_cfg['reportdir']
        for pfile in glob.glob(os.path.join(report_dir, '*.plist')):
            os.remove(pfile)

        codechecker.store(cfg, self._run_name)

        offed_reports = [
            r for r in reports if r.detectionStatus == DetectionStatus.OFF
        ]
        self.assertEqual(len(offed_reports), 1)

        # Remove .clang-tidy configuration file.
        os.remove(self.clang_tidy_cfg)
示例#13
0
def setup_package():
    """Setup the environment for the tests."""

    global TEST_WORKSPACE
    TEST_WORKSPACE = env.get_workspace('skip')

    os.environ['TEST_WORKSPACE'] = TEST_WORKSPACE

    test_project = 'cpp'

    test_config = {}

    project_info = project.get_info(test_project)

    test_config['test_project'] = project_info

    suppress_file = None

    # Generate skip list file for the tests.
    skip_list_file = os.path.join(TEST_WORKSPACE, 'skip_file')
    if os.path.isfile(skip_list_file):
        os.remove(skip_list_file)
    _generate_skip_list_file(skip_list_file)

    test_env = env.test_env(TEST_WORKSPACE)

    codechecker_cfg = {
        'suppress_file': suppress_file,
        'skip_file': skip_list_file,
        'check_env': test_env,
        'workspace': TEST_WORKSPACE,
        'checkers': []
    }

    ret = project.clean(test_project, test_env)
    if ret:
        sys.exit(ret)

    # Start or connect to the running CodeChecker server and get connection
    # details.
    print("This test uses a CodeChecker server... connecting...")
    server_access = codechecker.start_or_get_server()
    server_access['viewer_product'] = 'skip'
    codechecker.add_test_package_product(server_access, TEST_WORKSPACE)

    # Extend the checker configuration with the server access.
    codechecker_cfg.update(server_access)

    test_project_name = project_info['name'] + '_' + uuid.uuid4().hex

    skip_file = codechecker_cfg.pop('skip_file')

    output_dir = codechecker_cfg['reportdir'] \
        if 'reportdir' in codechecker_cfg \
        else os.path.join(codechecker_cfg['workspace'], 'reports')

    codechecker_cfg['reportdir'] = output_dir

    # Analyze without skip.
    ret = codechecker.analyze(codechecker_cfg, test_project_name,
                              project.path(test_project))
    if ret:
        print("Analyzing the test project without a skip file failed.")
        sys.exit(1)

    codechecker_cfg['skip_file'] = skip_file

    # Analyze with skip.
    ret = codechecker.analyze(codechecker_cfg, test_project_name,
                              project.path(test_project))

    if ret:
        print("Analyzing the test project with a skip file failed.")
        sys.exit(1)

    ret = codechecker.store(codechecker_cfg, test_project_name)
    if ret:
        print("Storing the results failed.")
        sys.exit(1)

    codechecker_cfg['run_names'] = [test_project_name]

    test_config['codechecker_cfg'] = codechecker_cfg

    env.export_test_cfg(TEST_WORKSPACE, test_config)