def _create_source_file(self, version):
        source_file = os.path.join(self._test_dir, self._source_file)
        with open(source_file, 'w') as source_f:
            source_f.write(self.sources[version])

        build_json = os.path.join(self._test_dir, "build.json")

        # Create a compilation database.
        build_log = [
            {
                "directory": self.test_workspace,
                "command": "gcc -c " + source_file,
                "file": source_file
            },
            {
                "directory": self.test_workspace,
                "command": "clang -c " + source_file,
                "file": source_file
            }
        ]

        with open(build_json, 'w') as outfile:
            json.dump(build_log, outfile)

        # Create analyze command.
        analyze_cmd = [self._codechecker_cmd, "analyze", build_json,
                       "--analyzers", "clangsa", "-o", self._reports_dir]

        # Run analyze.
        process = subprocess.Popen(
            analyze_cmd, stdout=subprocess.PIPE,
            stderr=subprocess.PIPE, cwd=self._test_dir)
        process.communicate()

        codechecker.store(self._codechecker_cfg, 'example')
Ejemplo n.º 2
0
    def setUp(self):
        """
        Not much setup is needed.
        Runs and results are automatically generated.
        """

        test_workspace = os.environ['TEST_WORKSPACE']

        test_class = self.__class__.__name__
        print('Running ' + test_class + ' tests in ' + test_workspace)

        # Get the clang version which is tested.
        self._clang_to_test = env.clang_to_test()

        self._testproject_data = env.setup_test_proj_cfg(test_workspace)
        self.assertIsNotNone(self._testproject_data)

        self._report = env.setup_viewer_client(test_workspace)
        self.assertIsNotNone(self._report)

        # Store runs to check.
        self._codechecker_cfg = env.import_codechecker_cfg(test_workspace)

        source_dir = os.path.join(os.path.dirname(__file__), 'test_files')
        self._test_dir = os.path.join(test_workspace, 'test_files')

        shutil.copytree(source_dir, self._test_dir)

        _replace_path(os.path.join(self._test_dir, 'run.plist'),
                      self._test_dir)

        self._codechecker_cfg['reportdir'] = self._test_dir
        codechecker.store(self._codechecker_cfg,
                          'test_hash_clash_' + uuid4().hex)
Ejemplo n.º 3
0
    def test_store(self):
        """
        Store should fail if the source files were modified since the
        last analysis.
        """

        test_proj = os.path.join(self.test_workspace, 'test_proj')

        ret = codechecker.check(self._codechecker_cfg, 'test_proj', test_proj)

        self.assertEqual(ret, 0)

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

        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')

        touch(null_deref_file)

        ret = codechecker.store(self._codechecker_cfg, 'test_proj')
        self.assertEqual(ret, 1)
Ejemplo n.º 4
0
    def test_store(self):
        """
        Store should fail if the source files were modified since the
        last analysis.
        """

        test_proj = os.path.join(self.test_workspace, 'test_proj')

        ret = codechecker.check(self._codechecker_cfg,
                                'test_proj',
                                test_proj)

        self.assertEqual(ret, 0)

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

        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')

        touch(null_deref_file)

        ret = codechecker.store(self._codechecker_cfg, 'test_proj')
        self.assertEqual(ret, 1)
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
    def _create_source_file(self, version):
        source_file = os.path.join(self._test_dir, self._source_file)
        with open(source_file, 'w') as source_f:
            source_f.write(self.sources[version])

        build_json = os.path.join(self._test_dir, "build.json")

        # Create a compilation database.
        build_log = [{
            "directory": self.test_workspace,
            "command": "gcc -c " + source_file,
            "file": source_file
        }, {
            "directory": self.test_workspace,
            "command": "clang -c " + source_file,
            "file": source_file
        }]

        with open(build_json, 'w') as outfile:
            json.dump(build_log, outfile)

        # Create analyze command.
        analyze_cmd = [
            self._codechecker_cmd, "analyze", build_json, "--analyzers",
            "clangsa", "-o", self._reports_dir
        ]

        # Run analyze.
        process = subprocess.Popen(analyze_cmd,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   cwd=self._test_dir)
        process.communicate()

        codechecker.store(self._codechecker_cfg, 'example')
    def test_check_without_metadata(self):
        """
        This test checks whether the storage works without a metadata.json.
        """
        runs = self._cc_client.getRunData(None, None, 0, None)
        if runs:
            run_id = max(map(lambda run: run.runId, runs))

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

        self._create_source_file(0)

        codechecker.log_and_analyze(self._codechecker_cfg, 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, None, 0, None)
        run_id = max(map(lambda run: run.runId, runs))

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

        self.assertEqual(len(reports), 2)
    def test_storage_empty_report_dir(self):
        """
        Check that storing an empty report directory will not store analyzer
        statistics information on the server.
        """
        os.mkdir(self._reports_dir)

        # Trying to store the empty directory.
        codechecker.store(self._codechecker_cfg, 'example')

        # Check that we do not store any analyzer statistic information.
        self.assertFalse(os.path.exists(self._analyzer_stats_dir))
Ejemplo n.º 9
0
    def test_store_multiple_dir_no_off(self):
        """
        Store multiple report directory and check that no reports are marked
        as OFF.
        """
        cfg = dict(self._codechecker_cfg)
        cfg['checkers'] = ['-d', 'core.DivideZero']

        self._create_source_file(1)
        codechecker.log_and_analyze(cfg,
                                    self._test_dir)

        # Remove metadata.json.
        try:
            os.remove(os.path.join(cfg['reportdir'],
                                   'metadata.json'))
        except OSError:
            pass

        # Analyze the same project to a different report directory and disable
        # modernize checkers.
        cfg['checkers'] = ['-d', 'deadcode.DeadStores']
        cfg['reportdir'] = self._codechecker_cfg['reportdir'] + "2"

        orig_test_dir = self._test_dir
        self._test_dir = self._test_dir + "2"
        shutil.copytree(orig_test_dir, self._test_dir)
        self._create_source_file(3)

        codechecker.log_and_analyze(cfg,
                                    self._test_dir)

        # Set back test dir.
        self._test_dir = orig_test_dir

        # Store two report directory.
        cfg['reportdir'] = '{0} {1}'.format(
            cfg['reportdir'],
            self._codechecker_cfg['reportdir'])
        codechecker.store(cfg, 'hello')

        # Check that no reports are marked as OFF.
        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), 0)
Ejemplo n.º 10
0
def setup_package():
    """Setup the environment for testing detection_status."""

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

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

    test_env = env.test_env(TEST_WORKSPACE)

    # Configuration options.
    codechecker_cfg = {
        'check_env': test_env,
        'workspace': TEST_WORKSPACE,
        'run_names': []
    }

    # 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'] = 'extended_report_data'
    codechecker.add_test_package_product(server_access, TEST_WORKSPACE)

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

    # Copy test projects and replace file path in plist files.
    test_projects = ['notes', 'macros']
    for test_project in test_projects:
        test_project_path = os.path.join(TEST_WORKSPACE, "test_proj",
                                         test_project)
        shutil.copytree(project.path(test_project), test_project_path)

        for test_file in os.listdir(test_project_path):
            if test_file.endswith(".plist"):
                test_file_path = os.path.join(test_project_path, test_file)
                with open(test_file_path,
                          'r+',
                          encoding="utf-8",
                          errors="ignore") as plist_file:
                    content = plist_file.read()
                    new_content = content.replace("$FILE_PATH$",
                                                  test_project_path)
                    plist_file.seek(0)
                    plist_file.truncate()
                    plist_file.write(new_content)

        codechecker_cfg['reportdir'] = test_project_path

        ret = codechecker.store(codechecker_cfg, test_project)
        if ret:
            sys.exit(1)
        print("Analyzing test project was succcessful.")

        codechecker_cfg['run_names'].append(test_project)

    # Export the test configuration to the workspace.
    env.export_test_cfg(TEST_WORKSPACE, {'codechecker_cfg': codechecker_cfg})
Ejemplo n.º 11
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_storage_simple_report_dir(self):
        """
        Checks storing report directory without a failure zip will not
        store any statistics.
        """
        run_name = 'example'

        self._create_source_file(0, self._reports_dir)
        codechecker.store(self._codechecker_cfg, run_name)

        product_stat_dir = os.path.join(self._analyzer_stats_dir,
                                        self._product_name)

        # Check that directory for product under analyzer statistics dir
        # does not exists
        self.assertFalse(os.path.exists(product_stat_dir))

        self._remove_run(['example'])
Ejemplo n.º 13
0
def setup_package():
    """Setup the environment for testing detection_status."""

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

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

    test_env = env.test_env(TEST_WORKSPACE)

    # Configuration options.
    codechecker_cfg = {
        'check_env': test_env,
        'workspace': TEST_WORKSPACE,
        'run_names': []
    }

    # 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'] = 'extended_report_data'
    codechecker.add_test_package_product(server_access, TEST_WORKSPACE)

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

    # Copy test projects and replace file path in plist files.
    test_projects = ['notes', 'macros']
    for test_project in test_projects:
        test_project_path = os.path.join(TEST_WORKSPACE, "test_proj",
                                         test_project)
        shutil.copytree(project.path(test_project), test_project_path)

        for test_file in os.listdir(test_project_path):
            if test_file.endswith(".plist"):
                test_file_path = os.path.join(test_project_path, test_file)
                with open(test_file_path, 'r+') as plist_file:
                    content = plist_file.read()
                    new_content = content.replace("$FILE_PATH$",
                                                  test_project_path)
                    plist_file.seek(0)
                    plist_file.truncate()
                    plist_file.write(new_content)

        codechecker_cfg['reportdir'] = test_project_path

        ret = codechecker.store(codechecker_cfg, test_project)
        if ret:
            sys.exit(1)
        print("Analyzing test project was succcessful.")

        codechecker_cfg['run_names'].append(test_project)

    # Export the test configuration to the workspace.
    env.export_test_cfg(TEST_WORKSPACE, {'codechecker_cfg': codechecker_cfg})
    def test_storage_empty_report_dir(self):
        """
        Check that storing an empty report directory will not store analyzer
        statistics information on the server.
        """
        # Remove analyzer statistics directory if it exists before store.
        if os.path.exists(self._analyzer_stats_dir):
            os.removedirs(self._analyzer_stats_dir)

        # Remove reports directory if it exists and create an empty one.
        if os.path.exists(self._reports_dir):
            os.removedirs(self._reports_dir)

        os.mkdir(self._reports_dir)

        # Trying to store the empty directory.
        codechecker.store(self._codechecker_cfg, 'example')

        # Check that we do not store any analyzer statistic information.
        self.assertFalse(os.path.exists(self._analyzer_stats_dir))
Ejemplo n.º 15
0
def setup_package():
    """Setup the environment for the tests. """

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

    os.environ['TEST_WORKSPACE'] = TEST_WORKSPACE

    test_config = {}

    test_project_name = uuid.uuid4().hex

    test_project_path = os.path.join(test_dir, "test_proj")

    temp_test_project_data = project.prepare(test_project_path, TEST_WORKSPACE)

    test_config['test_project'] = temp_test_project_data

    test_env = env.test_env(TEST_WORKSPACE)

    base_reports = os.path.join(temp_test_project_data['test_project_reports'],
                                'base')

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

    # 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'] = 'update'
    codechecker.add_test_package_product(server_access, TEST_WORKSPACE)

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

    ret = codechecker.store(codechecker_cfg,
                            test_project_name)
    if ret:
        sys.exit(1)
    print("Storing the base reports was succcessful.")

    codechecker_cfg['run_names'] = [test_project_name]

    test_config['codechecker_cfg'] = codechecker_cfg

    env.export_test_cfg(TEST_WORKSPACE, test_config)
    def test_storage_failed_zips(self):
        """
        Checks if compilation database and failed zips can be found in the
        uploaded zip.
        """
        run_ids = None

        # Check if there is no failed files in the database yet.
        num_of_failed_files = self._cc_client.getFailedFilesCount(run_ids)
        self.assertEqual(num_of_failed_files, 0)

        failed_files = self._cc_client.getFailedFiles(run_ids)
        self.assertEqual(len(failed_files), 0)

        # Store the failure.
        self._create_source_file(1, self._reports_dir)

        codechecker.store(self._codechecker_cfg, 'statistics1')
        self._check_analyzer_statistics_zip('statistics1', self._reports_dir)

        codechecker.store(self._codechecker_cfg, 'statistics2')
        self._check_analyzer_statistics_zip('statistics2', self._reports_dir)

        # Check the failed files again in the database.
        num_of_failed_files = self._cc_client.getFailedFilesCount(run_ids)

        self.assertEqual(num_of_failed_files, 1)

        failed_files = self._cc_client.getFailedFiles(run_ids)
        self.assertEqual(len(failed_files), 1)
        self.assertTrue(self._source_file in failed_files)

        failed_file_info = failed_files[self._source_file]
        self.assertEqual(len(failed_file_info), 2)

        self.assertTrue(
            all(i.runName in ['statistics1', 'statistics2']
                for i in failed_file_info))

        self._remove_run(['statistics1', 'statistics2'])
Ejemplo n.º 17
0
    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)
    def test_storage_multiple_reports_dir(self):
        """
        Test storing multiple report directories.
        """
        run_ids = None
        run_name = 'multiple_report_dir'
        report_dir1 = os.path.join(self._reports_dir, 'report_dir1')
        report_dir2 = os.path.join(self._reports_dir, 'report_dir2')

        # Analyze the same project multiple times in different report
        # directories.
        self._create_source_file(1, report_dir1)
        self._create_source_file(1, report_dir2)

        cfg = self._codechecker_cfg.copy()
        cfg['reportdir'] = [report_dir1, report_dir2]
        codechecker.store(cfg, run_name)

        # Check the failed files again in the database.
        num_of_failed_files = self._cc_client.getFailedFilesCount(run_ids)
        self.assertEqual(num_of_failed_files, 1)

        self._remove_run([run_name])
Ejemplo n.º 19
0
    def test_disable_checker(self):
        """
        The test depends on a run which was configured for update mode.
        Compared to the original test analysis in this run
        the deadcode.Deadstores checker was disabled.
        In this case the reports are marked as resolved.
        """

        run_results = get_all_run_results(self._cc_client, self._runid)

        print_run_results(run_results)

        # Get check command for the first storage.
        original_check_command = \
            self._cc_client.getCheckCommand(None, self._runid)

        self.assertEqual(original_check_command, "")

        initial_codechecker_cfg = env.import_test_cfg(
            self._test_workspace)['codechecker_cfg']

        initial_test_project_name = self._run_name

        disabled_reports = os.path.join(
            self._testproject_data['test_project_reports'], 'disabled')

        initial_codechecker_cfg['reportdir'] = disabled_reports
        ret = codechecker.store(initial_codechecker_cfg,
                                initial_test_project_name)
        if ret:
            sys.exit(1)

        # Get the results to compare.
        updated_results = get_all_run_results(self._cc_client, self._runid)

        for report in updated_results:
            self.assertEqual(report.detectionStatus, DetectionStatus.RESOLVED)
Ejemplo n.º 20
0
    def test_skip_plist_without_diag(self):
        """ Store plist file without diagnostics.

        Store plist file which does not contain any diagnostic but it refers
        some existing source file.
        """
        test_dir = os.path.join(self.test_workspace, "no_diag")
        if not os.path.isdir(test_dir):
            os.mkdir(test_dir)

        src_file = os.path.join(test_dir, "src.cpp")
        with open(src_file, 'w', encoding='utf-8', errors='ignore') as src_f:
            src_f.write("int main() { return 0; }")

        plist_file = os.path.join(test_dir, "no_diag.plist")
        with open(plist_file, 'wb') as plist_f:
            data = {'diagnostics': [], 'files': [src_file]}
            plistlib.dump(data, plist_f)

        cfg = dict(self._codechecker_cfg)
        cfg['reportdir'] = test_dir

        ret = codechecker.store(cfg, 'no_diag')
        self.assertEqual(ret, 0)
Ejemplo n.º 21
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.log_and_analyze(codechecker_cfg,
                                      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.log_and_analyze(codechecker_cfg,
                                      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)
Ejemplo n.º 22
0
    def test_review_status_update_from_source_trim(self):
        """
        Test if the review status comments changes in the source code
        are updated at the server when trim path is used.

        The report is store twice and between the storage the
        review status as a source code comment is modified.
        The test checks is after the source code modification
        and storage the review status is updated correctly at
        the server too.
        """
        test_project_path = os.path.join(self.test_workspace,
                                         'review_status_files')
        test_project_name = 'review_status_update_proj'

        plist_file = os.path.join(test_project_path, 'divide_zero.plist')
        source_file = os.path.join(test_project_path, 'divide_zero.cpp')
        plist_test.prefix_file_path(plist_file, test_project_path)

        codechecker_cfg = env.import_codechecker_cfg(self.test_workspace)
        codechecker_cfg['reportdir'] = test_project_path

        codechecker.store(codechecker_cfg, test_project_name)

        codechecker_cfg['trim_path_prefix'] = test_project_path

        # Run data for the run created by this test case.
        run_filter = RunFilter(names=[test_project_name], exactMatch=True)

        runs = self._cc_client.getRunData(run_filter, None, 0, None)
        run = runs[0]
        runid = run.runId
        logging.debug('Get all run results from the db for runid: ' +
                      str(runid))

        reports = get_all_run_results(self._cc_client, runid)
        self.assertIsNotNone(reports)
        self.assertNotEqual(len(reports), 0)
        self.assertEqual(len(reports), 2)

        for report in reports:
            print(report)
            self.assertEqual(report.reviewData.status,
                             ReviewStatus.INTENTIONAL)

        # Modify review comments from intentional to confirmed for the
        # second store.
        with open(source_file, 'r+', encoding='utf-8', errors='ignore') as sf:
            content = sf.read()
            new_content = content.replace("codechecker_intentional",
                                          "codechecker_confirmed")
            sf.truncate(0)
            sf.write(new_content)

        # modify review comments and store the reports again
        with open(source_file, encoding='utf-8', errors='ignore') as sf:
            content = sf.read()

        # Update the plist file modification date to be newer than
        # the source file so it can be stored, because there was no
        # actual analysis.
        date = datetime.datetime.now() + datetime.timedelta(minutes=5)
        mod_time = time.mktime(date.timetuple())
        os.utime(plist_file, (mod_time, mod_time))

        codechecker.store(codechecker_cfg, test_project_name)

        # Check if all the review statuses were updated to the new at the
        # server.
        reports = get_all_run_results(self._cc_client, runid)
        self.assertIsNotNone(reports)
        self.assertNotEqual(len(reports), 0)
        self.assertEqual(len(reports), 2)
        for report in reports:
            self.assertEqual(report.reviewData.status, ReviewStatus.CONFIRMED)
Ejemplo n.º 23
0
    def test_read_product_from_another_server(self):
        """
        Test if adding and removing a product is visible from the other server.
        """

        # Check if the main server's product is visible on the second server.
        self.assertEqual(
            self._pr_client_2.getProducts('producttest',
                                          None)[0].endpoint, 'producttest',
            "Main server's product was not loaded by the secondary server.")

        def create_test_product(product_name, product_endpoint):
            # Create a new product on the secondary server.
            name = base64.b64encode(product_name)
            return ProductConfiguration(endpoint=product_endpoint,
                                        displayedName_b64=name,
                                        description_b64=name,
                                        connection=DatabaseConnection(
                                            engine='sqlite',
                                            host='',
                                            port=0,
                                            username_b64='',
                                            password_b64='',
                                            database=os.path.join(
                                                self.test_workspace_secondary,
                                                'data.sqlite')))

        product_cfg = create_test_product('producttest_second',
                                          'producttest_second')

        self.assertTrue(self._pr_client_2.addProduct(product_cfg),
                        "Cannot create product on secondary server.")

        product_cfg = create_test_product('producttest_second 2',
                                          'producttest_second_2')
        self.assertTrue(self._pr_client_2.addProduct(product_cfg),
                        "Cannot create product on secondary server.")

        # Product name full string match.
        products = self._pr_client_2.getProducts('producttest_second', None)
        self.assertEqual(len(products), 1)

        # Product endpoint full string match.
        products = self._pr_client_2.getProducts(None, 'producttest_second')
        self.assertEqual(len(products), 1)

        # Product name substring match.
        products = self._pr_client_2.getProducts('producttest_second*', None)
        self.assertEqual(len(products), 2)

        products = self._pr_client_2.getProducts(None, 'producttest_second*')
        self.assertEqual(len(products), 2)

        # Use the same CodeChecker config that was used on the main server,
        # but store into the secondary one.
        store_cfg = deepcopy(self.test_cfg['codechecker_cfg'])
        store_cfg.update({
            'viewer_port':
            self.codechecker_cfg_2['viewer_port'],
            'viewer_product':
            self.codechecker_cfg_2['viewer_product']
        })
        codechecker.login(store_cfg, self.test_workspace_secondary, 'root',
                          'root')
        store_cfg['reportdir'] = os.path.join(self.test_workspace_main,
                                              'reports')
        store_res = codechecker.store(store_cfg, 'test_proj-secondary')
        self.assertEqual(store_res, 0, "Storing the test project failed.")

        cc_client_2 = env.setup_viewer_client(self.test_workspace_secondary)
        self.assertEqual(len(cc_client_2.getRunData(None)), 1,
                         "There should be a run present in the new server.")

        self.assertEqual(
            len(self._cc_client.getRunData(None)), 1,
            "There should be a run present in the database when "
            "connected through the main server.")

        # Remove the product through the main server.
        p_id = self._root_client.getProducts('producttest_second', None)[0].id
        p_id2 = self._pr_client_2.getProducts('producttest_second', None)[0].id
        self.assertIsNotNone(p_id)
        self.assertEqual(
            p_id, p_id2, "The products have different ID across the two "
            "servers. WHAT? Database isn't shared?!")

        self.assertTrue(self._root_client.removeProduct(p_id),
                        "Main server reported error while removing product.")

        self.assertEqual(len(self._pr_client.getProducts('_second', None)), 0,
                         "Secondary server still sees the removed product.")

        # Try to store into the product just removed through the secondary
        # server, which still sees the product internally.
        store_res = codechecker.store(store_cfg, 'test_proj-secondary')
        self.assertNotEqual(
            store_res, 0, "Storing into the server with "
            "the product missing should've resulted in "
            "an error.")
Ejemplo n.º 24
0
def setup_package():
    """Setup the environment for testing diff_local_remote."""

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

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

    # Get the clang version which is used for testing.
    # Important because different clang releases might
    # find different errors.
    clang_version = env.clang_to_test()

    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_local = os.path.join(TEST_WORKSPACE, "test_proj_local")
    shutil.copytree(project.path(test_project), test_proj_path_local)

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

    project_info['project_path_local'] = test_proj_path_local
    project_info['project_path_remote'] = test_proj_path_remote

    test_config['test_project'] = project_info

    # 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_local_remote'
    codechecker.add_test_package_product(server_access, TEST_WORKSPACE)

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

    # Analyze local, these reports will not be stored to the server.
    altered_file = os.path.join(test_proj_path_local, "call_and_message.cpp")
    project.insert_suppression(altered_file)

    codechecker_cfg['reportdir'] = os.path.join(test_proj_path_local,
                                                'reports')
    codechecker_cfg['checkers'] = [
        '-e', 'core.CallAndMessage', '-d', 'core.NullDereference'
    ]

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

    # Remote analysis, results will be stored to the remote server.
    altered_file = os.path.join(test_proj_path_local, "call_and_message.cpp")
    project.insert_suppression(altered_file)

    codechecker_cfg['reportdir'] = os.path.join(test_proj_path_remote,
                                                'reports')
    codechecker_cfg['checkers'] = [
        '-d', 'core.CallAndMessage', '-e', 'core.NullDereference'
    ]

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

    # Store results to the remote server.
    test_project_name_remote = project_info['name'] + '_' + uuid.uuid4().hex
    ret = codechecker.store(codechecker_cfg, test_project_name_remote)
    if ret:
        sys.exit(1)
    print('Analyzing remote was successful.')

    # Save the run names in the configuration.
    codechecker_cfg['run_names'] = [test_project_name_remote]

    test_config['codechecker_cfg'] = codechecker_cfg

    # Export the test configuration to the workspace.
    env.export_test_cfg(TEST_WORKSPACE, test_config)
Ejemplo n.º 25
0
    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)
Ejemplo n.º 26
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)