Example #1
0
    def testDatabaseContent(self):
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        parser = ConfigParser()
        parser.optionxform = str

        parser.read(script_output_file)
        self.assertListEqual(sorted(parser.sections()), ELEMENTS)

        for metric, value in EXPECTED_METRICS.items():
            self.assertTrue(
                parser.has_option(SECTION, metric),
                'missing entry for "%s"' % metric)
            self.assertEqual(
                parser.getfloat(SECTION, metric), value,
                'unexpected value for "%s"' % metric)

        for emetric, value in EXPECTED_EMETRICS.items():
            self.assertTrue(
                parser.has_option(ESECTION, emetric),
                'missing entry for "%s"' % emetric)
            self.assertEqual(
                parser.getfloat(ESECTION, emetric), value,
                'unexpected value for "%s"' % emetric)
Example #2
0
    def testDatabaseContent(self):
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        parser = ConfigParser()
        parser.optionxform = str

        parser.read(script_output_file)

        sections = parser.sections()

        for s in SECTIONS:
            self.assertTrue(s in sections, "Missing section: " + s)

        self.assertTrue(parser.has_option(TEXT_IO[1], EXTERNAL_CALL[0]),
                        "Should be an external call")
        self.assertEqual(parser.get(TEXT_IO[1], EXTERNAL_CALL[0]),
                         EXTERNAL_CALL[1], 'Wrong message')
        self.assertTrue(parser.has_option(B_SIMPLE_ADB[1], ENTRY_POINT[0]),
                        "Entry point not found")
        self.assertTrue(
            parser.get(B_SIMPLE_ADB[1],
                       ENTRY_POINT[0]).endswith(ENTRY_POINT[1]),
            'unexpected value for the entry point')

        for metric in METRICS_SIMPLE_4_1:
            self.assertTrue(parser.has_option(SIMPLE_4_1[0], metric),
                            'missing entry for "%s"' % metric)
Example #3
0
    def testDatabaseContent(self):
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        parser = SafeConfigParser()
        parser.optionxform = str

        parser.read(script_output_file)
        sections = parser.sections()
        for s in SECTIONS:
            self.assertTrue(s in sections, "Missing section: " + s)

        self.assertTrue(parser.has_option(TEXT_IO[0], EXTERNAL_CALL[0]),
                        "Should be an external call")
        self.assertEqual(parser.get(TEXT_IO[0], EXTERNAL_CALL[0]),
                         EXTERNAL_CALL[1],
                         'Wrong message')

        self.assertTrue(parser.has_option(B_SIMPLE_ADB[0], ENTRY_POINT[0]),
                        "Entry point not found")
        self.assertTrue(parser.get(B_SIMPLE_ADB[0],
                                   ENTRY_POINT[0]).endswith(ENTRY_POINT[1]),
                        'unexpected value for the entry point')

        for metric in METRICS_SIMPLE_4_1:
            self.assertTrue(
                parser.has_option(SIMPLE_4_1[0], metric),
                'missing entry for "%s"' % metric)
Example #4
0
    def testDatabaseContent(self):
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        parser = ConfigParser()
        parser.optionxform = str

        parser.read(script_output_file)
        self.assertListEqual(sorted(parser.sections()), SECTIONS)

        self.assertTrue(parser.has_option(F_ADB, 'warnings'),
                        'missing "warnings" entry')
        self.assertTrue(parser.has_option(F_ADB, 'identifier_casing'),
                        'missing "identifier_casing" entry')

        self.assertTrue(
            parser.has_option(P_ADB, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(
            parser.has_option(P_ADS_1, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')

        self.assertTrue(parser.has_option(PG_ADB_1, 'improper_returns'),
                        'missing "improper_returns" entry')
        self.assertTrue(parser.has_option(PG_ADB_2, 'improper_returns'),
                        'missing "improper_returns" entry')
        self.assertTrue(
            parser.has_option(PG_ADB_3, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(parser.has_option(PG_ADB_4, 'warnings'),
                        'missing "warnings" entry')
        self.assertTrue(parser.has_option(PG_ADB_5, 'warnings'),
                        'missing "warnings" entry')

        self.assertTrue(
            parser.has_option(PG_ADS_1, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(
            parser.has_option(PG_ADS_2, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(
            parser.has_option(PG_ADS_3, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(parser.has_option(PG_ADS_4, 'recursive_subprograms'),
                        'missing "recursive_subprograms" entry')

        self.assertTrue(
            parser.has_option(PGG_ADS_1, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(parser.has_option(PGG_ADS_2, 'warnings'),
                        'missing "warnings" entry')

        self.assertTrue(parser.has_option(SIMPLE_ADB_1, 'improper_returns'),
                        'missing "improper_returns" entry')
        self.assertTrue(parser.has_option(SIMPLE_ADB_3, 'identifier_suffixes'),
                        'missing "identifier_suffixes" entry')
        self.assertTrue(parser.has_option(SIMPLE_ADB_3, 'identifier_prefixes'),
                        'missing "identifier_prefixes" entry')
Example #5
0
    def testDatabaseContent(self):
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        parser = SafeConfigParser()
        parser.optionxform = str

        parser.read(script_output_file)
        self.assertListEqual(sorted(parser.sections()), RESULTS)
Example #6
0
    def setUp(self):
        self.longMessage = True
        self.project = Project.simple_gnatstack()
        self.project.build()
        self.gnathub = GNAThub(self.project, plugins=['gnatstack'])

        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        self.parser = SafeConfigParser()
        self.parser.optionxform = str

        self.parser.read(script_output_file)
Example #7
0
    def testDatabaseContent(self):
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script='check-run.py')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        parser = SafeConfigParser()
        parser.optionxform = str

        parser.read(script_output_file)
        self.assertListEqual(sorted(parser.sections()), FILES)

        for metric, value in EXPECTED_METRICS.iteritems():
            self.assertTrue(
                parser.has_option(SECTION, metric),
                'missing entry for "%s"' % metric)
            self.assertEqual(
                parser.getfloat(SECTION, metric), value,
                'unexpected value for "%s"' % metric)
Example #8
0
    def setUp(self):
        self.longMessage = True

        # Just import the project. Do no try to build it nor to run it: we
        # don't expect GNATcoverage to be available during testsuite runs, so
        # use the precomputed coverage reports instead.
        self.project = Project.coverage_exhaustive()

        # Run GNAThub with only the GNATcoverage plugin
        self.gnathub = GNAThub(self.project, plugins=['gnatcoverage'])

        # Extract coverage information from the database
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        self.parser = ConfigParser()
        self.parser.optionxform = str

        self.parser.read(script_output_file)
Example #9
0
    def setUp(self):
        self.longMessage = True

        # Import the project, build it and run it
        self.project = Project.gcov_multi_object_dir()
        self.project.build()
        self.project.run()

        # Run GNAThub with only the gcov plugin
        self.gnathub = GNAThub(self.project, plugins=['gcov'])

        # Extract coverage information from the database
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        self.parser = SafeConfigParser()
        self.parser.optionxform = str

        self.parser.read(script_output_file)
Example #10
0
    def setUp(self):
        self.longMessage = True

        # Just import the project. Do no try to build it nor to run it: we
        # don't expect GNATcoverage to be available during testsuite runs, so
        # use the precomputed coverage reports instead.
        self.project = Project.coverage_exhaustive()

        # Run GNAThub with only the GNATcoverage plugin
        self.gnathub = GNAThub(self.project, plugins=['gnatcoverage'])

        # Extract coverage information from the database
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        self.parser = SafeConfigParser()
        self.parser.optionxform = str

        self.parser.read(script_output_file)
Example #11
0
    def setUp(self):
        self.longMessage = True

        # Import the project, build it and run it
        self.project = Project.gcov_multi_object_dir()
        self.project.build()
        self.project.run()

        # Run GNAThub with only the gcov plugin
        self.gnathub = GNAThub(self.project, plugins=['gcov'])

        # Extract coverage information from the database
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        self.parser = SafeConfigParser()
        self.parser.optionxform = str

        self.parser.read(script_output_file)
Example #12
0
    def testDatabaseContent(self):
        PROJECT = Project.simple()

        # Create path to /obj and /codepeer folders
        OBJ_FOLDER = 'obj'
        OBJ_PATH = os.path.join(Project.simple().install_dir, OBJ_FOLDER)

        CODEPEER_FOLDER = 'codepeer'
        CODEPEER_PATH = os.path.join(OBJ_PATH, CODEPEER_FOLDER)

        # Run GNAThub with Codepeer
        gnathub = GNAThub(PROJECT, plugins=['codepeer'])

        # Check that /obj and /codepeer folders exists
        assert os.path.exists(OBJ_PATH), 'Object folder should exist'
        assert os.path.exists(CODEPEER_PATH), 'Codepeer folder should exist'

        # Check the existence of expected simple.csv file
        CSV_COUNT = 0
        CSV_PATH = CODEPEER_PATH
        for entry in os.listdir(CODEPEER_PATH):
            if entry.endswith('.csv') and entry.startswith('simple'):
                CSV_COUNT += 1
                CSV_PATH = os.path.join(CSV_PATH, entry)
        assert CSV_COUNT == 1, 'simple.csv should be generated in /obj/codepeer folder'
        assert os.path.isfile(CSV_PATH), 'simple.csv is a file'

        # Check .csv content
        columns = defaultdict(list) # each value in each column is appended to a list
        with open(CSV_PATH) as f:
            # read rows into a dictionary format
            reader = csv.DictReader(f)
            # read a row as {column1: value1, column2: value2,...}
            for row in reader:
                # go over each column name and value
                for (k,v) in row.items():
                    # append the value into the appropriate list based on column name k
                    columns[k].append(v)

        # Check column 'Line'
        self.assertListEqual(columns['Line'], EXPECTED_LINES_FROM_CSV)
        # Check column 'Column'
        self.assertListEqual(columns['Column'], EXPECTED_COLUMNS_FROM_CSV)
        # Check column 'Category'
        self.assertListEqual(columns['Category'], EXPECTED_CATEGORIES_FROM_CSV)
        # Check column 'Ranking'
        self.assertListEqual(columns['Ranking'], EXPECTED_RANKINGS_FROM_CSV)
        # Check column 'Kind'
        self.assertListEqual(columns['Kind'], EXPECTED_KINDS_FROM_CSV)
        # Check column 'Message'
        self.assertListEqual(columns['Message'], EXPECTED_MESSAGES_FROM_CSV)

        # Checks the analysis report results are as expected
        script_output_file = os.path.abspath('script.out')
        gnathub.run(script=Script.db2cfg(), output=script_output_file)

        parser = SafeConfigParser()
        parser.optionxform = str

        parser.read(script_output_file)
        self.assertListEqual(sorted(parser.sections()), RESULTS)
Example #13
0
    def testDatabaseContent(self):
        PROJECT = Project.simple()

        # Create path to /obj and /codepeer folders
        OBJ_FOLDER = 'obj'
        OBJ_PATH = os.path.join(Project.simple().install_dir, OBJ_FOLDER)

        CODEPEER_FOLDER = 'codepeer'
        CODEPEER_PATH = os.path.join(OBJ_PATH, CODEPEER_FOLDER)

        # Run GNAThub with Codepeer
        gnathub = GNAThub(PROJECT, plugins=['codepeer'])

        # Check that /obj and /codepeer folders exists
        assert os.path.exists(OBJ_PATH), 'Object folder should exist'
        assert os.path.exists(CODEPEER_PATH), 'Codepeer folder should exist'

        # Check the existence of expected simple.csv file
        CSV_COUNT = 0
        CSV_PATH = CODEPEER_PATH
        for entry in os.listdir(CODEPEER_PATH):
            if entry.endswith('.csv') and entry.startswith('simple'):
                CSV_COUNT += 1
                CSV_PATH = os.path.join(CSV_PATH, entry)
        assert CSV_COUNT == 1, 'simple.csv should be generated in /obj/codepeer folder'
        assert os.path.isfile(CSV_PATH), 'simple.csv is a file'

        # Check .csv content
        columns = defaultdict(
            list)  # each value in each column is appended to a list
        with open(CSV_PATH) as f:
            # read rows into a dictionary format
            reader = csv.DictReader(f)
            # read a row as {column1: value1, column2: value2,...}
            for row in reader:
                # go over each column name and value
                for (k, v) in row.items():
                    # append the value into the appropriate list based on column name k
                    columns[k].append(v)

        # Check column 'Line'
        self.assertListEqual(columns['Line'], EXPECTED_LINES_FROM_CSV)
        # Check column 'Column'
        self.assertListEqual(columns['Column'], EXPECTED_COLUMNS_FROM_CSV)
        # Check column 'Category'
        self.assertListEqual(columns['Category'], EXPECTED_CATEGORIES_FROM_CSV)
        # Check column 'Ranking'
        self.assertListEqual(columns['Ranking'], EXPECTED_RANKINGS_FROM_CSV)
        # Check column 'Kind'
        self.assertListEqual(columns['Kind'], EXPECTED_KINDS_FROM_CSV)
        # Check column 'Message'
        self.assertListEqual(columns['Message'], EXPECTED_MESSAGES_FROM_CSV)

        # Checks the analysis report results are as expected
        script_output_file = os.path.abspath('script.out')
        gnathub.run(script=Script.db2cfg(), output=script_output_file)

        parser = SafeConfigParser()
        parser.optionxform = str

        parser.read(script_output_file)
        self.assertListEqual(sorted(parser.sections()), RESULTS)
Example #14
0
    def testDatabaseContent(self):
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        parser = ConfigParser()
        parser.optionxform = str

        parser.read(script_output_file)
        self.assertEqual(len(parser.sections()), 26)

        if os.environ["WITH_SONAR"]:
            user = '******'
            pwd = 'admin'

            def check_Ada_language():
                ''' Check if Ada language is supported
                '''
                SONAR_LANGUAGES_URL = 'http://localhost:9000/api/languages/list'

                session = requests.Session()
                session.auth = user, pwd
                call = getattr(session, 'get')
                response = call(SONAR_LANGUAGES_URL)

                self.assertTrue(
                    response.status_code < 300,
                    'Expected < 300 return HTT response (OK).' +
                    'Got %s' % str(response.status_code))
                binary = response.content
                output = json.loads(binary)
                # pprint.pprint(output)

                ADA_LANG = False
                for record in output['languages']:
                    if record['key'] == 'ada' and record['name'] == 'Ada':
                        ADA_LANG = True
                        break
                    else:
                        continue

                self.assertTrue(ADA_LANG, 'Ada language is not supported')
                session.close()

            def check_Ada_quality_profile():
                ''' Check if Ada quality profile is supported
                '''
                SONAR_QP_URL = 'http://localhost:9000/api/qualityprofiles/search'

                session = requests.Session()
                session.auth = user, pwd
                call = getattr(session, 'get')
                response = call(SONAR_QP_URL)

                self.assertTrue(
                    response.status_code < 300,
                    'Expected < 300 return HTT response (OK).' +
                    'Got %s' % str(response.status_code))
                binary = response.content
                output = json.loads(binary)
                # pprint.pprint(output)

                GNATDASHBOARD_WAY = False
                LANGUAGE_ADA = False
                ACTIVE_RULES_COUNT = 0
                for record in output['profiles']:
                    if 'name' in record and record[
                            'name'] == 'GNATdashboard way':
                        GNATDASHBOARD_WAY = True
                        if 'language' in record and record['language'] == 'ada':
                            LANGUAGE_ADA = (record['languageName'] == 'Ada')
                            ACTIVE_RULES_COUNT = record['activeRuleCount']
                    else:
                        continue

                self.assertTrue(
                    GNATDASHBOARD_WAY,
                    'missing GNATdashboard way from Quality Profile')
                self.assertEqual(
                    ACTIVE_RULES_COUNT, 476,
                    'unexpected value for Ada active rules.' +
                    ' Found "%s" instead of 476' % str(ACTIVE_RULES_COUNT))
                session.close()

            def check_Ada_project_uploaded():
                ''' Check if Ada project is uploaded
                The exected uploaded project name is 'Simple_Sonar'
                '''
                SONAR_SEARCH_URL = 'http://localhost:9000/api/projects/search'
                EXPECTED_NAME = 'Simple_Sonar'

                session = requests.Session()
                session.auth = user, pwd
                call = getattr(session, 'get')
                response = call(SONAR_SEARCH_URL)

                self.assertTrue(
                    response.status_code < 300,
                    'Expected < 300 return HTT response (OK).' +
                    'Got %s' % str(response.status_code))
                binary = response.content
                output = json.loads(binary)
                # pprint.pprint(output)

                for record in output['components']:
                    self.assertTrue(
                        'key' in record,
                        'missing entry for name in record %s' % str(record))
                    self.assertEqual(
                        record['key'], EXPECTED_NAME,
                        'unexpected value for "%s"' % record['key'])
                    self.assertTrue(
                        'name' in record,
                        'missing entry for name in record %s' % str(record))
                    self.assertEqual(
                        record['name'], EXPECTED_NAME,
                        'unexpected value for "%s"' % record['name'])
                session.close()

            def check_Ada_project_analysis():
                ''' Check if Ada project has expected number of code_smells
                    For the dashboard project 'Simple_Sonar' 17 code smells are expected

                    The request should be
                       http://localhost:9000/api/measures/component?
                         component=Simple_Sonar&metricKeys=reliability_rating,bugs,code_smells
                    The expected response is

                       {"component":{"id":"AXfP0Sfu2OokptDLjqm9",
                            "key":"Simple_Sonar",
                            "name":"Simple_Sonar",
                            "qualifier":"TRK",
                            "measures":[{"metric":"reliability_rating", "value":"1.0","bestValue":true},
                                        {"metric":"bugs","value":"0","bestValue":true},
                                        {"metric":"code_smells","value":"17","bestValue":false}]}}
                '''
                PROJECT_KEY = 'Simple_Sonar'
                METRICS_LIST = ['reliability_rating', 'code_smells', 'bugs']
                RQ_PARAMS = {
                    'component': PROJECT_KEY,
                    'metricKeys': ','.join(METRICS_LIST)
                }
                SONAR_MEASURES_URL = 'http://localhost:9000/api/measures/component'

                session = requests.Session()
                session.auth = user, pwd
                call = getattr(session, 'get')

                # Sleep for 30 seconds to be sure that the analysis results are uploaded
                time.sleep(30)

                response = call(SONAR_MEASURES_URL, params=RQ_PARAMS)
                self.assertTrue(
                    response.status_code < 300,
                    'Expected < 300 return HTT response (OK).' +
                    'Got %s' % str(response.status_code))

                print(response.url)
                print(response.text)

                json_data = response.json(
                ) if response and response.status_code == 200 else None
                self.assertTrue(json_data and 'component' in json_data,
                                'unexpected value for returned data')
                self.assertTrue('measures' in json_data['component'],
                                'unexpected value for returned data')
                self.assertTrue(
                    len(json_data['component']['measures']) != 0,
                    'no metric is found in measures')

                # Gather the informations from the response
                reliability_rating = 0.0
                bugs = 0
                code_smells = 0
                for record in json_data['component']['measures']:
                    if record['metric'] == 'reliability_rating':
                        reliability_rating = record['value']

                    if record['metric'] == 'bugs':
                        bugs = int(record['value'])

                    if record['metric'] == 'code_smells':
                        code_smells = int(record['value'])

                self.assertEqual(bugs, 0, 'Not expected metric %s' % str(bugs))
                self.assertEqual(code_smells, 17,
                                 'Not expected metric %s' % str(code_smells))
                session.close()

            # Check if the Sonar Ada plugin is used
            # 1. Check if the Ada language is supported
            check_Ada_language()

            # 2. Check if the Ada quality profile is present
            check_Ada_quality_profile()

            # 3. Check if the uploaded project name is 'Simple_Sonar'
            check_Ada_project_uploaded()

            # 4. Check if the expected metrics are uploaded for 'Simple_Sonar'
            check_Ada_project_analysis()
Example #15
0
    def testDatabaseContent(self):
        script_output_file = os.path.abspath('script.out')
        self.gnathub.run(script=Script.db2cfg(), output=script_output_file)

        parser = SafeConfigParser()
        parser.optionxform = str

        parser.read(script_output_file)
        self.assertListEqual(sorted(parser.sections()), SECTIONS)

        self.assertTrue(
            parser.has_option(F_ADB, 'warnings'),
            'missing "warnings" entry')
        self.assertTrue(
            parser.has_option(F_ADB, 'identifier_casing'),
            'missing "identifier_casing" entry')

        self.assertTrue(
            parser.has_option(P_ADB, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(
            parser.has_option(P_ADS_1, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')

        self.assertTrue(
            parser.has_option(PG_ADB_1, 'improper_returns'),
            'missing "improper_returns" entry')
        self.assertTrue(
            parser.has_option(PG_ADB_2, 'improper_returns'),
            'missing "improper_returns" entry')
        self.assertTrue(
            parser.has_option(PG_ADB_3, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(
            parser.has_option(PG_ADB_4, 'warnings'),
            'missing "warnings" entry')
        self.assertTrue(
            parser.has_option(PG_ADB_5, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(
            parser.has_option(PG_ADB_6, 'warnings'),
            'missing "warnings" entry')

        self.assertTrue(
            parser.has_option(PG_ADS_1, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(
            parser.has_option(PG_ADS_2, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(
            parser.has_option(PG_ADS_3, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(
            parser.has_option(PG_ADS_4, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(
            parser.has_option(PG_ADS_5, 'recursive_subprograms'),
            'missing "recursive_subprograms" entry')
        self.assertTrue(
            parser.has_option(PG_ADS_6, 'recursive_subprograms'),
            'missing "recursive_subprograms" entry')

        self.assertTrue(
            parser.has_option(PGG_ADS_1, 'unconstrained_array_returns'),
            'missing "unconstrained_array_returns" entry')
        self.assertTrue(
            parser.has_option(PGG_ADS_2, 'warnings'),
            'missing "warnings" entry')

        self.assertTrue(
            parser.has_option(SIMPLE_ADB_1, 'improper_returns'),
            'missing "improper_returns" entry')
        self.assertTrue(
            parser.has_option(SIMPLE_ADB_3, 'identifier_suffixes'),
            'missing "identifier_suffixes" entry')
        self.assertTrue(
            parser.has_option(SIMPLE_ADB_3, 'identifier_prefixes'),
            'missing "identifier_prefixes" entry')