예제 #1
0
 def __init__(self):
     self.config = ConfigReader()
     self.mariadb = mariadb.MariaDB()
     self.mongodb = mongodb.MongoDB()
     self.mysql = mysql.MySQL()
     self.oracle = oracle.Oracle()
     self.reader = Reader()
예제 #2
0
class Pipeline(object):
    def __init__(self):
        self.conf = ConfigReader()
        self.test = Main()
        self.after_test = AfterTest()

    def setting(self, ext: str) -> NoReturn:
        """
        Set the configuration file to be used.

            Parameters:
                ext(str): File extension.
                          Supported forms are available at: https://github.com/HwDhyeon/TIMO#setting
        """

        self.conf.read_config_file(ext)

    def get(self, option: str) -> Union[str, NoReturn]:
        """
        This is used when you want to see various information in the configuration file or the score of the entire test.

            Parameters:
                option(str): This is the information you want to view.

            Returns:
                Union(str, NoReturn): It can return a string or nothing.
        """

        if (option := option.lower()) == 'name':
            return "Project name: " + color(self.conf.get_project_name(),
                                            'green')
        elif option == 'version':
            return ("Project version: %s\nTIMO version: %s" %
                    (color(self.conf.get_project_version(),
                           'green'), color('alpha', 'orange')))
예제 #3
0
class AfterTest(object):
    def __init__(self):
        self.config = ConfigReader()
        self.db = DatabaseManager()
        self.parser = Parser()
        self.score = ScoreCalculator()

    def parse(self, test_name: str, db: str, build_number: int) -> NoReturn:
        """
        Parse test results.

            Parameters:
                test_name(str): The name of the test for which you want to parse the results.
                db(str): This is the type of database if you want to store the results in a database.
                build_number(int): Jenkins build number if you want to store the results in a database.
        """

        report_conf = self.config.get_report_info(test_name=test_name)
        test_tool = self.config.get_test_tool(test_name=test_name)
        test_result = self.parser.parse(kind=test_name,
                                        file_type=report_conf['type'],
                                        test_tool=test_tool['uses'])
        if db is not None and build_number is not None:
            test_result['build_number'] = build_number
            self.db.insert_test_result(test_name, test_result, db)
        else:
            pretty_print(test_result)
예제 #4
0
 def __init__(self):
     self.conf = ConfigReader()
     self.parser = Parser()
     self.r = {
         'CSW': 0,
         'Unittest': 0,
         'Coverage': 0,
         'APItest': 0,
         'E2Etest': 0,
     }
예제 #5
0
 def __init__(self) -> NoReturn:
     self.conf = ConfigReader()
     self.surefire = SurefireParser()
     self.unittest = UnittestParser()
     self.jacoco = JacocoParser()
     self.flake8 = Flake8Parser()
     self.coverage = CoverageParser()
     self.selenium = SeleniumParser()
     self.eslint = ESLintParser()
     self.pmd = PMDParser()
예제 #6
0
class Main(object):
    def __init__(self):
        self.conf = ConfigReader()
        self.runner = CommandRunner()

    def run(self, test_name: str) -> NoReturn:
        """
        Execute the command.

            Parameters:
                test_name(str): Name of the test to run.
        """

        # test_kinds = ['CSW', 'Unittest', 'Coverage', 'APItest', 'E2Etest']
        colored_print(f'Running {test_name} in now. 🚀', 'magenta')
        command_list = self.conf.get_test_suites(test_name)
        self.runner.run_all(command_list)
예제 #7
0
class ScoreCalculator(object):
    def __init__(self):
        self.conf = ConfigReader()
        self.parser = Parser()
        self.r = {
            'CSW': 0,
            'Unittest': 0,
            'Coverage': 0,
            'APItest': 0,
            'E2Etest': 0,
        }

    def _refine_test_name(self, test_name: str) -> str:
        if 'CSW' in test_name:
            test_name = 'CSW'
        elif 'Unittest' in test_name:
            test_name = 'Unittest'
        elif 'Coverage' in test_name:
            test_name = 'Coverage'
        elif 'APITest' in test_name:
            test_name = 'APITest'
        elif 'E2Etest' in test_name:
            test_name = 'E2Etest'
        return test_name

    def _get_score_set(self) -> dict:
        r = {
            'CSW': 0,
            'Unittest': 0,
            'Coverage': 0,
            'APItest': 0,
            'E2Etest': 0,
        }
        score_set = self.conf.get_score_info()
        for key, value in score_set.items():
            key = self._refine_test_name(key)
            r[key] = float(value.rstrip('%')) * 0.01
        return r

    def _get_test_results(self) -> list:

        r = []
        tests = self.conf.get_tests()
        for test in tests:
            info = self.conf.get_report_info(test)
            r.append({
                'name':
                self._refine_test_name(test),
                'result':
                self.parser.parse(
                    kind=test,
                    file_type=info['type'],
                    test_tool=self.conf.get_test_tool(test)['uses'])
            })
        return r

    @timer
    def calculate(self) -> dict:
        self.score_set = self._get_score_set()
        score = {
            'CSW': {
                'score': 0,
                'count': 0
            },
            'Unittest': {
                'score': 0,
                'count': 0
            },
            'Coverage': {
                'score': 0,
                'count': 0
            },
            'APItest': {
                'score': 0,
                'count': 0
            },
            'E2Etest': {
                'score': 0,
                'count': 0
            },
        }
        r = self._get_test_results()

        def csw(data: dict) -> float:
            score = (1 - (data['warning'] / 100))
            score = -1 if score < -1 else score
            score *= self.score_set['CSW']
            return score

        def unittest(data: dict) -> float:
            total = sum(data.values())
            success_rate = data['success'] / total
            score = success_rate * self.score_set['Unittest']
            return score

        def coverage(data: dict) -> float:
            return (data['test_val'] / 100) * self.score_set['Coverage']

        def apitest(data: dict) -> float:
            total = sum(data.values())
            success_rate = data['success'] / total
            score = success_rate * self.score_set['APITest']
            return score

        def e2etest(data: dict) -> float:
            total = sum(data.values())
            success_rate = data['success'] / total
            score = success_rate * self.score_set['E2Etest']
            return score

        for data in r:
            if data['name'] == 'CSW':
                score['CSW']['score'] += csw(data['result'])
                score['CSW']['count'] += 1
            elif data['name'] == 'Unittest':
                score['Unittest']['score'] += unittest(data['result'])
                score['Unittest']['count'] += 1
            elif data['name'] == 'Coverage':
                score['Coverage']['score'] += coverage(data['result'])
                score['Coverage']['count'] += 1
            elif data['name'] == 'APITest':
                score['APITest']['score'] += apitest(data['result'])
                score['APITest']['count'] += 1
            elif data['name'] == 'E2Etest':
                score['E2Etest']['score'] += e2etest(data['result'])
                score['E2Etest']['count'] += 1

        res = sum([(data['score'] / data['count'])
                   for data in score.values() if data['count'] != 0]) * 10

        print()
        colored_print('🚀 {:<17}'.format('Test results'), colorname='white')
        colored_print('-' * 19, colorname='white')
        for test, value in score.items():
            _score = value['score'] / value['count'] if value[
                'count'] != 0 else 0
            score[test] = _score * 10
            fstr = f'{_score * 10:>6.2f}' if _score != 0 else '{:>5}'.format(
                '❌')
            colored_print(f'{test:<10}', colorname='white', end='')
            colored_print(' → ', colorname='cyan', end='')
            colored_print(f'{fstr}', colorname='green')
        colored_print('-' * 19, colorname='white')
        colored_print('{:<10}'.format('Total'), colorname='white', end='')
        colored_print(' → ', colorname='cyan', end='')
        colored_print(f'{res:>6.2f}', colorname='blue')
        print()

        return res, score
예제 #8
0
 def __init__(self):
     self.conf = ConfigReader()
     self.test = Main()
     self.after_test = AfterTest()
예제 #9
0
 def __init__(self):
     self.config = ConfigReader()
     self.db = DatabaseManager()
     self.parser = Parser()
     self.score = ScoreCalculator()
예제 #10
0
 def __init__(self):
     self.conf = ConfigReader()
     self.runner = CommandRunner()
예제 #11
0
class Parser(object):
    """Test result parser"""

    def __init__(self) -> NoReturn:
        self.conf = ConfigReader()
        self.surefire = SurefireParser()
        self.unittest = UnittestParser()
        self.jacoco = JacocoParser()
        self.flake8 = Flake8Parser()
        self.coverage = CoverageParser()
        self.selenium = SeleniumParser()
        self.eslint = ESLintParser()
        self.pmd = PMDParser()

    def _csw(self) -> dict:
        """
        Parse Code static analysis result.

            Returns:
                dict: Test result
        """

        result = {}
        if equals(self.test_tool, 'flake8'):
            result = self.flake8.parse(path=self.path, file_type=self.file_type)
        elif equals(self.test_tool, 'eslint'):
            result = self.eslint.parse(path=self.path, file_type=self.file_type)
        elif equals(self.test_tool, 'pmd'):
            result = self.pmd.parse(path=self.path, file_type=self.file_type)
        else:
            raise UnknownTestTestToolError

        return result

    def _unittest(self) -> dict:
        """
        Parse Unittest result.

            Returns:
                dict: Test result
        """

        if equals(self.test_tool, 'surefire'):
            result = self.surefire.parse(path=self.path, file_type=self.file_type)
        elif equals(self.test_tool, 'unittest'):
            result = self.unittest.parse(path=self.path, file_type=self.file_type)
        else:
            raise UnknownTestTestToolError

        return result

    def _coverage(self) -> dict:
        """
        Parse Coverage test result.

            Returns:
                dict: Test result
        """

        if equals(self.test_tool, 'jacoco'):
            result = self.jacoco.parse(path=self.path, file_type=self.file_type)
        elif equals(self.test_tool, 'coverage'):
            result = self.coverage.parse(path=self.path, file_type=self.file_type)
        else:
            raise UnknownTestTestToolError

        return result

    def _apitest(self) -> dict:
        """
        Parse API test result.

            Returns:
                dict: Test result
        """

        result = {}
        return result

    def _e2etest(self) -> dict:
        """
        Parse End to End result.

            Returns:
                dict: Test result
        """

        if equals(self.test_tool, 'selenium'):
            result = self.selenium.parse(path=self.path, file_type=self.file_type)

        return result

    def parse(self, kind: str, file_type: str, test_tool: str) -> dict:
        """
        Parse test result

            Parameters:
                kind(str): Test kind
                report_path: Report file location
                file_type: Report file's ext
                test_tool: Test tool

            Returns:
                dict: Test result
        """

        self.path = self.conf.get_report_info(kind)['path']
        self.file_type = file_type
        self.test_tool = test_tool.lower()

        if not os.path.isfile(self.path) and not os.path.isdir(self.path):
            colored_print(f'We can\'t  find {self.path}.', 'red')
            colored_print('Where is it?', 'red')
            raise FileNotFoundError

        if 'csw' in (kind := kind.lower()):
            result = self._csw()
        elif 'unittest' in kind:
            result = self._unittest()
예제 #12
0
class DatabaseManager(object):
    """Everything that happens in the database is done through this class."""
    def __init__(self):
        self.config = ConfigReader()
        self.mariadb = mariadb.MariaDB()
        self.mongodb = mongodb.MongoDB()
        self.mysql = mysql.MySQL()
        self.oracle = oracle.Oracle()
        self.reader = Reader()

    def _create_new_query(self, test_name: str, data: dict) -> str:
        """
        Generates SQL query statement containing each test result.

            Parameters:
                test_name(str): Name of the test performed.
                data(dict): This is a dictionary containing test results.

            Returns:
                str: Generated SQL query statement.
        """

        test_name = test_name.lower()
        project_name = self.config.get_project_name()
        test_tool = self.config.get_test_tool(test_name=test_name.upper())
        if equals(test_name, 'csw'):
            return f"INSERT INTO CSW(PROJECT_NAME, BUILD_NUMBER, TEST_TOOL, TEST_VAL) VALUES('{project_name}', {data['build_number']}, '{test_tool['uses']}', {data['warning']})"
        elif equals(test_name, 'unittest'):
            return f"""INSERT
            INTO
                UNITTEST(PROJECT_NAME, BUILD_NUMBER, TEST_TOOL, SUCCESS, FAIL, SKIP)
            VALUES
                ('{project_name}', {data['build_number']}, '{test_tool['uses']}', {data['success']}, {data['fail']}, {data['skip']})"""
        elif equals(test_name, 'coverage'):
            return f"""INSERT
            INTO
                COVERAGE(PROJECT_NAME, BUILD_NUMBER, TEST_TOOL, TEST_VAL)
            VALUES
                ('{project_name}', {data['build_number']}, '{test_tool['uses']}', {data['test_val']})
            """
        elif equals(test_name, 'apitest'):
            pass
        elif equals(test_name, 'e2etest'):
            pass

    def insert_test_result(self, test_name: str, data: dict,
                           db_name: str) -> NoReturn:
        """
        The test results are analyzed and inserted into the database.\n
        Tables must be prepared for each test name.\n
        Example: CSW, UNITTEST, E2ETEST

            Parameters:
                test_name(str): Name of the test performed.
                data(dict): This is a dictionary containing test results.
                db_name(str): Database type name.
                              Examples: MySQL, Oracle, MongoDB, MariaDB...
        """

        if not os.path.isfile('data/db.json'):  # db.json 파일이 없을경우 오류 발생
            raise FileNotFoundError
        else:
            db_data = self.reader.read_json_file('data/db.json')

        if db_name in list(db_data):  # 입력받은 데이터베이스가 목록에 없을 경우 오류 발생
            if equals(db_name, 'mariadb'):
                colored_print('Currently MariaDB is handled as MySQL.',
                              'orange')
                self.insert_test_result(test_name=test_name,
                                        data=data,
                                        db_name='mysql')
            elif equals(db_name, 'mongodb'):
                colored_print('Database type not currently supported.',
                              'orange')
            elif equals(db_name, 'mysql'):
                self.mysql.open_DB_session()
                self.mysql.send_query(sql=self._create_new_query(
                    test_name, data),
                                      type='insert')
                self.mysql.close_DB_session()
            elif equals(db_name, 'oracle'):
                colored_print('Database type not currently supported.',
                              'orange')
            else:
                colored_print('Database type not currently supported.',
                              'orange')
                raise UnknownDatabaseError  # 목록에는 있지만 지원하지 않는 데이터베이스의 경우 오류 발생
        else:
            raise UnknownDataError