Ejemplo n.º 1
0
    def generate_test_files(self,
                            main_file,
                            device,
                            check,
                            diff,
                            db,
                            snap_del,
                            pre=None,
                            action=None,
                            post=None):
        """
        generate names of snap files from hostname and out files given by user,
        tests are performed on values stored in these snap files, in which test is
        to be performed
        :param main_file: main config file, to extract test files user wants to run
        :param device: device name
        :param check: variable to check if --check option is given or not
        :param diff: variable to check if --diff option is given or not
        :param db: database object
        :param snap_del: if --snapcheck operator is used without any test file name
                        it will create temprory file and then will delete it at the end
        :param pre: file name of pre snapshot
        :param post: file name of post snapshot
        :param action: given by module version, either snap, snapcheck or check
        :return: object of operator.Operator containing test details
        """
        op = Operator()
        op.device = device
        tests_files = []
        self.log_detail['hostname'] = device
        # pre_user and post_user are the names of the snapshot files
        # that the user wants to keep and store the snapfiles
        # with these names
        pre_user = pre
        post_user = post
        # get the test files from config.yml
        if main_file.get('tests') is None:
            self.logger_check.error(
                colorama.Fore.RED +
                "\nERROR!! No test file found, Please mention test files !!",
                extra=self.log_detail)
        else:
            # extract test files, first search in path given in jsnapy.cfg
            for tfile in main_file.get('tests'):
                if not os.path.isfile(tfile):
                    tfile = os.path.join(
                        expanduser(get_path('DEFAULT', 'test_file_path')),
                        tfile)
                if os.path.isfile(tfile):
                    test_file = open(tfile, 'r')
                    tests_files.append(
                        yaml.load(test_file, Loader=yaml.FullLoader))
                else:
                    self.logger_check.error(
                        colorama.Fore.RED +
                        "ERROR!! File %s not found for testing" % tfile,
                        extra=self.log_detail)

            # check what all test cases need to be included, if nothing given
            # then include all test cases ####
            for tests in tests_files:
                tests_included = []
                if 'tests_include' in tests:
                    tests_included = tests.get('tests_include')
                else:
                    for t in tests:
                        tests_included.append(t)
                message = self._print_testmssg("Device: " + device, "*")
                self.logger_check.info(colorama.Fore.BLUE + message,
                                       extra=self.log_detail)
                for val in tests_included:
                    self.logger_check.info("Tests Included: %s " % (val),
                                           extra=self.log_detail)

                    # This is Where we are going to print the description mentioned by the user for the testcase
                    # Enumerate generate a tuple of index and corresponding element in the list
                    # index[0] is index and index[1] is the dictionary in which it will search.

                    description_index = [
                        index[0] for index in enumerate(tests[val])
                        if 'description' in index[1]
                    ]
                    if len(description_index) > 0:
                        description_index = description_index[0]
                        description = tests[val][description_index][
                            'description']
                        if description is not None:
                            self.logger_check.info("Description: %s " %
                                                   (description),
                                                   extra=self.log_detail)
                    try:
                        if any('command' in d for d in tests[val]):
                            index = next((i for i, x in enumerate(tests[val])
                                          if 'command' in x), 0)
                            command = tests[val][index].get('command').split(
                                '|')[0].strip()
                            reply_format = tests[val][0].get('format', 'xml')
                            message = self._print_testmssg(
                                "Command: " + command, "*")

                            self.logger_check.info(colorama.Fore.BLUE +
                                                   message,
                                                   extra=self.log_detail)

                            name = '_'.join(command.split())
                            teston = command

                            # this is necessary for the pre and post to be the same that user specified
                            # In a case when there are multiple rpc's with kwargs and a rpc with no kwargs
                            pre = pre_user
                            post = post_user
                        else:
                            index = next((i for i, x in enumerate(tests[val])
                                          if 'rpc' in x), 0)
                            index_kwargs = next(
                                (i for i, x in enumerate(tests[val])
                                 if 'kwargs' in x or 'args' in x), 1)
                            rpc = tests[val][index]['rpc']
                            reply_format = tests[val][index].get(
                                'format', 'xml')
                            self.logger_check.info(colorama.Fore.BLUE +
                                                   (25) * "*" + "RPC is " +
                                                   rpc + (25) * '*',
                                                   extra=self.log_detail)
                            name = rpc
                            teston = rpc
                            # this is necessary for the pre and post to be the same that user specified
                            # In a case when there are multiple rpc's with kwargs and a rpc with no kwargs
                            pre = pre_user
                            post = post_user

                            # here the user specified name is being used and the hash value generated for
                            # kwargs part is appended to the name

                            if 'kwargs' in tests[val][index_kwargs] and tests[
                                    val][index_kwargs].get('kwargs') is None:
                                del tests[val][index_kwargs]['kwargs']

                            if 'args' in tests[val][index_kwargs] and tests[
                                    val][index_kwargs].get('args') is None:
                                del tests[val][index_kwargs]['args']

                            if 'kwargs' in tests[val][
                                    index_kwargs] or 'args' in tests[val][
                                        index_kwargs]:
                                if tests[val][index_kwargs].get('kwargs'):
                                    data = tests[val][index_kwargs].get(
                                        'kwargs')
                                elif tests[val][index_kwargs].get('args'):
                                    data = tests[val][index_kwargs].get('args')
                                hash_kwargs = hashlib.md5(
                                    json.dumps(data, sort_keys=True).encode(
                                        'utf-8')).digest()
                                hash_kwargs = base64.urlsafe_b64encode(
                                    hash_kwargs).strip()
                                if action == 'check' and pre_user is not None and post_user is not None:
                                    pre = pre_user + '_' + hash_kwargs.decode(
                                        'utf-8')
                                    post = post_user + '_' + hash_kwargs.decode(
                                        'utf-8')
                                elif action == 'snapcheck' and pre_user is not None and post_user is None:
                                    pre = pre_user + '_' + hash_kwargs.decode(
                                        'utf-8')
                                elif diff is True and pre_user is not None and post_user is not None:
                                    pre = pre_user + '_' + hash_kwargs.decode(
                                        'utf-8')
                                    post = post_user + '_' + hash_kwargs.decode(
                                        'utf-8')
                    except KeyError:
                        self.logger_check.error(
                            colorama.Fore.RED +
                            "ERROR occurred, test keys 'command' or 'rpc' not defined properly",
                            extra=self.log_detail)
                    except Exception as ex:
                        self.logger_check.error(colorama.Fore.RED +
                                                "ERROR Occurred: %s" % str(ex),
                                                extra=self.log_detail)
                    else:
                        # extract snap files, if check from sqlite is true t
                        if db.get('check_from_sqlite') is True and (
                                check is True or diff is True
                                or action in ["check", "diff"]):
                            a = SqliteExtractXml(db.get('db_name'))
                            # while checking from database, preference is given
                            # to id and then snap name
                            if (db['first_snap_id']
                                    is not None) and (db['second_snap_id']
                                                      is not None):
                                snapfile1, data_format1 = a.get_xml_using_snap_id(
                                    str(device), name, db['first_snap_id'])
                                snapfile2, data_format2 = a.get_xml_using_snap_id(
                                    str(device), name, db['second_snap_id'])
                            else:
                                snapfile1, data_format1 = a.get_xml_using_snapname(
                                    str(device), name, pre)
                                snapfile2, data_format2 = a.get_xml_using_snapname(
                                    str(device), name, post)
                            if reply_format != data_format1 or reply_format != data_format2:
                                self.logger_check.error(
                                    colorama.Fore.RED +
                                    "ERROR!! Data stored in database is not in %s format."
                                    % reply_format,
                                    extra=self.log_detail)
                                pass
                                # sys.exit(1)
                        ###### taking snapshot for --snapcheck operation ####
                        elif db.get('check_from_sqlite') is True:
                            a = SqliteExtractXml(db.get('db_name'))
                            snapfile1, data_format1 = a.get_xml_using_snapname(
                                str(device), name, pre)
                            if reply_format != data_format1:
                                self.logger_check.error(
                                    colorama.Fore.RED +
                                    "ERROR!! Data stored in database is not in %s format."
                                    % reply_format,
                                    extra=self.log_detail)
                                pass
                                # sys.exit(1)
                        else:
                            snapfile1 = self.generate_snap_file(
                                device, pre, name, reply_format)

                        # if check is true then call function to compare two
                        # snapshots ####
                        if (check is True or action
                                == "check") and reply_format == 'xml':
                            if db.get('check_from_sqlite') is False:
                                snapfile2 = self.generate_snap_file(
                                    device, post, name, reply_format)
                            self.compare_reply(op, tests[val], val, teston,
                                               check, db, snapfile1, snapfile2,
                                               action)

                        # if --diff is true then call compare_diff to compare
                        # two snapshots word by word ####
                        elif (diff is True):
                            if db.get('check_from_sqlite') is False:
                                snapfile2 = self.generate_snap_file(
                                    device, post, name, reply_format)
                            self.compare_diff(snapfile1, snapfile2,
                                              db.get('check_from_sqlite'))

                        # else call --snapcheck test operation, it works only
                        # for xml reply format   ####
                        elif (reply_format == 'xml'):
                            self.compare_reply(op, tests[val], val, teston,
                                               check, db, snapfile1, action)
                            ######## bug here ############
                            # multiple testcases for single command and same device, its deleting that file
                            ####################
                            """
                            if snap_del is True:
                                snapfile1 = snapfile1 if os.path.isfile(snapfile1) else self.generate_snap_file(device, pre, name, reply_format)
                                os.remove(snapfile1)
                                """
                        else:
                            # give error message if snapshot in text format is
                            # used with operations other than --diff  ####
                            self.logger_check.error(
                                colorama.Fore.RED +
                                "ERROR!! for checking snapshots in text format use '--diff' option ",
                                extra=self.log_detail)

            # print final result, if operation is --diff then message gets
            # printed compare_diff function only ####
            if (diff is not True):
                op.final_result(self.log_detail)

        return op
Ejemplo n.º 2
0
    def generate_test_files(self,
                            main_file,
                            device,
                            check,
                            diff,
                            db,
                            snap_del,
                            pre=None,
                            action=None,
                            post=None):
        """
        generate names of snap files from hostname and out files given by user,
        tests are performed on values stored in these snap files, in which test is
        to be performed
        :param main_file: main config file, to extract test files user wants to run
        :param device: device name
        :param check: variable to check if --check option is given or not
        :param diff: variable to check if --diff option is given or not
        :param db: database object
        :param snap_del: if --snapcheck operator is used without any test file name
                        it will create temprory file and then will delete it at the end
        :param pre: file name of pre snapshot
        :param post: file name of post snapshot
        :param action: given by module version, either snap, snapcheck or check
        :return: object of operator.Operator containing test details
        """
        op = Operator()
        op.device = device
        tests_files = []
        self.log_detail['hostname'] = device
        # get the test files from config.yml
        if main_file.get('tests') is None:
            self.logger_check.error(
                colorama.Fore.RED +
                "\nERROR!! No test file found, Please mention test files !!",
                extra=self.log_detail)
        else:
            # extract test files, first search in path given in jsnapy.cfg
            for tfile in main_file.get('tests'):
                if not os.path.isfile(tfile):
                    tfile = os.path.join(get_path('DEFAULT', 'test_file_path'),
                                         tfile)
                if os.path.isfile(tfile):
                    test_file = open(tfile, 'r')
                    tests_files.append(yaml.load(test_file))
                else:
                    self.logger_check.error(
                        colorama.Fore.RED +
                        "ERROR!! File %s not found for testing" % tfile,
                        extra=self.log_detail)

            # check what all test cases need to be included, if nothing given
            # then include all test cases ####
            for tests in tests_files:
                tests_included = []
                if 'tests_include' in tests:
                    tests_included = tests.get('tests_include')
                else:
                    for t in tests:
                        tests_included.append(t)
                message = self._print_testmssg("Device: " + device, "*")
                self.logger_check.info(colorama.Fore.BLUE + message,
                                       extra=self.log_detail)
                for val in tests_included:
                    self.logger_check.info("Tests Included: %s " % (val),
                                           extra=self.log_detail)
                    try:
                        if 'command' in list(tests[val][0].keys()):
                            command = tests[val][0].get('command').split(
                                '|')[0].strip()
                            reply_format = tests[val][0].get('format', 'xml')
                            message = self._print_testmssg(
                                "Command: " + command, "*")

                            self.logger_check.info(colorama.Fore.BLUE +
                                                   message,
                                                   extra=self.log_detail)

                            name = '_'.join(command.split())
                            teston = command
                        else:
                            rpc = tests[val][0]['rpc']
                            reply_format = tests[val][0].get('format', 'xml')
                            self.logger_check.info(colorama.Fore.BLUE +
                                                   (25) * "*" + "RPC is " +
                                                   rpc + (25) * '*',
                                                   extra=self.log_detail)
                            name = rpc
                            teston = rpc
                    except KeyError:
                        self.logger_check.error(
                            colorama.Fore.RED +
                            "ERROR occurred, test keys 'command' or 'rpc' not defined properly",
                            extra=self.log_detail)
                    except Exception as ex:
                        self.logger_check.error(colorama.Fore.RED +
                                                "ERROR Occurred: %s" % str(ex),
                                                extra=self.log_detail)
                    else:
                        # extract snap files, if check from sqlite is true t
                        if db.get('check_from_sqlite') is True and (
                                check is True or diff is True
                                or action in ["check", "diff"]):
                            a = SqliteExtractXml(db.get('db_name'))
                            # while checking from database, preference is given
                            # to id and then snap name
                            if (db['first_snap_id']
                                    is not None) and (db['second_snap_id']
                                                      is not None):
                                snapfile1, data_format1 = a.get_xml_using_snap_id(
                                    str(device), name, db['first_snap_id'])
                                snapfile2, data_format2 = a.get_xml_using_snap_id(
                                    str(device), name, db['second_snap_id'])
                            else:
                                snapfile1, data_format1 = a.get_xml_using_snapname(
                                    str(device), name, pre)
                                snapfile2, data_format2 = a.get_xml_using_snapname(
                                    str(device), name, post)
                            if reply_format != data_format1 or reply_format != data_format2:
                                self.logger_check.error(
                                    colorama.Fore.RED +
                                    "ERROR!! Data stored in database is not in %s format."
                                    % reply_format,
                                    extra=self.log_detail)
                                pass
                                # sys.exit(1)
                        ###### taking snapshot for --snapcheck operation ####
                        elif db.get('check_from_sqlite') is True:
                            a = SqliteExtractXml(db.get('db_name'))
                            snapfile1, data_format1 = a.get_xml_using_snapname(
                                str(device), name, pre)
                            if reply_format != data_format1:
                                self.logger_check.error(
                                    colorama.Fore.RED +
                                    "ERROR!! Data stored in database is not in %s format."
                                    % reply_format,
                                    extra=self.log_detail)
                                pass
                                # sys.exit(1)
                        else:
                            snapfile1 = self.generate_snap_file(
                                device, pre, name, reply_format)

                        # if check is true then call function to compare two
                        # snapshots ####
                        if (check is True or
                                action is "check") and reply_format == 'xml':
                            if db.get('check_from_sqlite') is False:
                                snapfile2 = self.generate_snap_file(
                                    device, post, name, reply_format)
                            self.compare_reply(op, tests[val], val, teston,
                                               check, db, snapfile1, snapfile2,
                                               action)

                        # if --diff is true then call compare_diff to compare
                        # two snapshots word by word ####
                        elif (diff is True):
                            if db.get('check_from_sqlite') is False:
                                snapfile2 = self.generate_snap_file(
                                    device, post, name, reply_format)
                            self.compare_diff(snapfile1, snapfile2,
                                              db.get('check_from_sqlite'))

                        # else call --snapcheck test operation, it works only
                        # for xml reply format   ####
                        elif (reply_format == 'xml'):
                            self.compare_reply(op, tests[val], val, teston,
                                               check, db, snapfile1, action)
                            ######## bug here ############
                            # multiple testcases for single command and same device, its deleting that file
                            ####################
                            """
                            if snap_del is True:
                                snapfile1 = snapfile1 if os.path.isfile(snapfile1) else self.generate_snap_file(device, pre, name, reply_format)
                                os.remove(snapfile1)
                                """
                        else:
                            # give error message if snapshot in text format is
                            # used with operations other than --diff  ####
                            self.logger_check.error(
                                colorama.Fore.RED +
                                "ERROR!! for checking snapshots in text format use '--diff' option ",
                                extra=self.log_detail)

            # print final result, if operation is --diff then message gets
            # printed compare_diff function only ####
            if (diff is not True):
                op.final_result(self.log_detail)

        return op