Пример #1
0
    def __initialize(self, **kwargs):
        # Controller and Log collector socket port
        self.port = kwargs.get('controller_port', 7878)

        #  Controller address, void at the beginning
        self.server_address = kwargs.get('controller_ip_address', None)

        # Scenario folder, defaults to current directory
        self.scenario_folder = kwargs.get('scenario_folder', os.getcwd())

        # Scenario file name, defaults to './scenario.py'
        self.scenario_file_path = utils.get_abs_path(kwargs.get('scenario_file', './scenario.py'),
                                                     self.scenario_folder)

        # Results file path, defaults to './results/results.sqlite'
        self.results_file_path = utils.get_abs_path(kwargs.get('results_file', './results/results.sqlite'),
                                                    self.scenario_folder)

        # Scenario name, defaults to 'Scenario'
        self.scenario_name = kwargs.get('scenario_name', 'Scenario')

        # Spawn quota for local spawner
        self.spawn_quota = kwargs.get('spawn_quota', 1)

        # Placeholder for scenario
        self.scenario = None

        # Armed flag, used to start and stop running
        self.armed = False

        # Elapsed time since scenario beginning
        self.elapsed_time = 0

        # Internal message sender placeholder
        self.sender = Sender(self.server_address, self.port, 'UDP') if self.server_address else None

        # Sender spawn message poll interval
        self.sender_spawn_polling_interval = kwargs.get('sender_spawn_polling_interval', 5)
        self.sender_spawn_elapsed_time = 0.0

        # Internal Sysmonitor object and related thread
        self.sysmonitor_polling_interval = kwargs.get('sysmonitor_polling_interval', 1.0)

        click.secho(utils.logify('Setting up Sysmonitor... ', 'Spawner'))
        self.sysmonitor = Sysmonitor(self.server_address, self.port, self.sysmonitor_polling_interval)
        click.secho(utils.logify('Sysmonitor started'), fg='green', bold=True)
Пример #2
0
    def __init__(self, **kwargs):
        # Navigation name, defaults to class name
        self.name = kwargs.get('navigation_name', self.__class__.__name__)

        # Navigation settings and scenario
        self.settings = kwargs.get('settings', {})
        self.scenario_folder = kwargs.get('scenario_folder', os.getcwd())

        # Sender data
        self.server_address = kwargs.get('server_address', 'localhost')
        self.server_port = kwargs.get('server_port', 7878)
        self.sender = Sender(self.server_address, self.server_port, 'UDP')

        # Internal variables
        self.thread_variables = {}
        self.test_transactions = []
        self.spawn_id = None
        self.iteration = 1
        self.debug = False
Пример #3
0
class Navigation(object):
    __metaclass__ = abc.ABCMeta

    def __init__(self, **kwargs):
        # Navigation name, defaults to class name
        self.name = kwargs.get('navigation_name', self.__class__.__name__)

        # Navigation settings and scenario
        self.settings = kwargs.get('settings', {})
        self.scenario_folder = kwargs.get('scenario_folder', os.getcwd())

        # Sender data
        self.server_address = kwargs.get('server_address', 'localhost')
        self.server_port = kwargs.get('server_port', 7878)
        self.sender = Sender(self.server_address, self.server_port, 'UDP')

        # Internal variables
        self.thread_variables = {}
        self.test_transactions = []
        self.spawn_id = None
        self.iteration = 1
        self.debug = False

    @abc.abstractmethod
    def transactions(self):
        """
        Insert here the transactions to be included in the test,
        in the execution order
        """
        pass

    def configure(self):
        pass

    def add_setting(self, str_default_key, str_value):
        """
        Add a setting value to the specified key
        """
        self.settings[str_default_key] = str_value

    def set_variable(self, str_name, str_value):
        """
        Add a variable to the thread variables dict
        """
        self.thread_variables[str_name] = str_value

    def add_transaction(self, str_name, str_path):
        str_abspath = utils.get_abs_path(str_path, self.scenario_folder)
        obj_transaction = {
            'name': str_name,
            'path': str_abspath,
            'class': utils.import_from_path(str_abspath, str_name, {'navigation_name': self.name}),
            'server_address': self.server_address,
            'server_port': self.server_port
        }
        self.test_transactions.append(obj_transaction)

    def run(self, str_spawn_id=None):
        self.spawn_id = str_spawn_id

        # Cycle through transactions
        for obj_transaction_item in self.test_transactions:
            # Send transaction start message
            self.sender.send('transactionStart',
                             {
                                 'hostName': utils.get_ip_address(),
                                 'spawnID': self.spawn_id,
                                 'testName': self.name,
                                 'iteration': self.iteration,
                                 'transactionName': obj_transaction_item['name'],
                                 'startTimestamp': utils.get_timestamp()
                             })

            # Run the transaction
            self.settings,\
                self.thread_variables = \
                obj_transaction_item['class'].run(self.spawn_id, self.iteration, self.settings, self.thread_variables)

            # Send transaction end message
            self.sender.send('transactionEnd',
                             {
                                 'hostName': utils.get_ip_address(),
                                 'spawnID': self.spawn_id,
                                 'testName': self.name,
                                 'iteration': self.iteration,
                                 'transactionName': obj_transaction_item['name'],
                                 'endTimestamp': utils.get_timestamp()
                             })

        self.iteration += 1

        # Print line if in Debug mode
        if self.debug:
            print('ID: ' + str(self.spawn_id) + ' Timestamp: ' + utils.get_timestamp())
Пример #4
0
class Spawner(StoppableThread):

    def __init__(self,
                 str_server_address,
                 int_controller_port,
                 str_scenario_folder,
                 str_scenario_name,
                 str_scenario_file_path,
                 str_results_file_path,
                 dbl_spawn_quota):
        # Initialize the father stoppable thread class
        super(Spawner, self).__init__()

        # Instantiates everything
        self.__initialize(controller_ip_address=str_server_address,
                          controller_port=int_controller_port,
                          scenario_folder=str_scenario_folder,
                          scenario_file=str_scenario_file_path,
                          scenario_name=str_scenario_name,
                          results_file=str_results_file_path,
                          spawn_quota=dbl_spawn_quota)
        self.__set_scenario_class()
        self.__arm()

    def run(self):
        self.__run()

    def __initialize(self, **kwargs):
        # Controller and Log collector socket port
        self.port = kwargs.get('controller_port', 7878)

        #  Controller address, void at the beginning
        self.server_address = kwargs.get('controller_ip_address', None)

        # Scenario folder, defaults to current directory
        self.scenario_folder = kwargs.get('scenario_folder', os.getcwd())

        # Scenario file name, defaults to './scenario.py'
        self.scenario_file_path = utils.get_abs_path(kwargs.get('scenario_file', './scenario.py'),
                                                     self.scenario_folder)

        # Results file path, defaults to './results/results.sqlite'
        self.results_file_path = utils.get_abs_path(kwargs.get('results_file', './results/results.sqlite'),
                                                    self.scenario_folder)

        # Scenario name, defaults to 'Scenario'
        self.scenario_name = kwargs.get('scenario_name', 'Scenario')

        # Spawn quota for local spawner
        self.spawn_quota = kwargs.get('spawn_quota', 1)

        # Placeholder for scenario
        self.scenario = None

        # Armed flag, used to start and stop running
        self.armed = False

        # Elapsed time since scenario beginning
        self.elapsed_time = 0

        # Internal message sender placeholder
        self.sender = Sender(self.server_address, self.port, 'UDP') if self.server_address else None

        # Sender spawn message poll interval
        self.sender_spawn_polling_interval = kwargs.get('sender_spawn_polling_interval', 5)
        self.sender_spawn_elapsed_time = 0.0

        # Internal Sysmonitor object and related thread
        self.sysmonitor_polling_interval = kwargs.get('sysmonitor_polling_interval', 1.0)

        click.secho(utils.logify('Setting up Sysmonitor... ', 'Spawner'))
        self.sysmonitor = Sysmonitor(self.server_address, self.port, self.sysmonitor_polling_interval)
        click.secho(utils.logify('Sysmonitor started'), fg='green', bold=True)

    def __set_scenario_class(self):
        # Load scenario from temporary folder
        self.scenario = utils.import_from_path(self.scenario_file_path, self.scenario_name,
                                               {'scenario_folder': self.scenario_folder})
        self.scenario.rescale_spawns_by_factor(self.spawn_quota)

    def __arm(self):
        # Arm itself
        self.armed = True

    def __unarm(self):
        # Disarm itself
        self.armed = False

    def __run(self):
        click.secho(utils.logify('Starting Sysmonitor... ', 'Spawner'), nl=False)
        self.sysmonitor.start()
        click.secho('DONE', fg='green', bold=True)

        self.scenario.configure()
        self.scenario.navigations_definition()

        self.scenario.scenario_start = utils.get_timestamp(False)
        self.scenario.scenario_duration =\
            self.scenario.get_scenario_duration()
        list_navigations = self.scenario.get_navigation_names()

        # Update sender spawn message elapsed time
        self.sender_spawn_elapsed_time += self.elapsed_time

        # Write beginning message
        click.secho(utils.logify('Running scenario...', 'Spawner'), fg='green')

        while self.elapsed_time <= self.scenario.scenario_duration and self.armed:
            # Get elapsed time
            time_elapsed = utils.get_timestamp(False) - self.scenario.scenario_start
            self.elapsed_time = time_elapsed.total_seconds()

            # Cycle through navigations
            for str_navigation_name in list_navigations:
                # Get planned and current spawn number
                self.scenario.navigations[str_navigation_name]['planned_spawns'] =\
                    self.scenario.get_planned_spawns(str_navigation_name, self.elapsed_time)

                self.scenario.navigations[str_navigation_name]['current_spawns'] =\
                    len(self.scenario.navigations[str_navigation_name]['threads'])

                # Send spawn message, but only if is passed enough time from last sending
                if self.sender_spawn_elapsed_time >= self.sender_spawn_polling_interval:
                    self.sender.send('spawns',
                                     {
                                         'hostName': utils.get_ip_address(),
                                         'timestamp': utils.get_timestamp(),
                                         'navigationName': str_navigation_name,
                                         'plannedSpawns': self.scenario.navigations[str_navigation_name]['planned_spawns'],
                                         'runningSpawns': self.scenario.navigations[str_navigation_name]['current_spawns']
                                     })
                    self.sender_spawn_elapsed_time = 0.0

                int_spawns_difference = self.scenario.navigations[str_navigation_name][
                    'current_spawns'] - self.scenario.navigations[
                    str_navigation_name]['planned_spawns']

                # If there are less spawns than planned, add some spawns
                if int_spawns_difference < 0:
                    for int_counter in range(0, -int_spawns_difference):
                        str_navigation_path = self.scenario.get_navigation_path(str_navigation_name)
                        str_id = utils.random_id(16)
                        print(str_id)
                        obj_spawn = Spawn(str_id,
                                          str_navigation_name,
                                          str_navigation_path,
                                          self.scenario_folder,
                                          self.server_address,
                                          self.port,
                                          self.scenario.settings)
                        obj_spawn.start()
                        self.scenario.navigations[str_navigation_name]['threads'].append(obj_spawn)

                # If there are more spawns than planned, start killing older spawns
                elif int_spawns_difference > 0:
                    for int_counter in range(0, int_spawns_difference):
                        obj_spawn = self.scenario.navigations[str_navigation_name]['threads'].pop(0)
                        obj_spawn.terminate()
                        obj_spawn.join()
                        print('Killed one')

        self.__unarm()

        # Clean all the remaining threads
        click.secho(utils.logify('Cleaning up... ', 'Spawner'), nl=False)
        for str_navigation_name in list_navigations:
            for int_counter in range(0, len(self.scenario.navigations[str_navigation_name]['threads'])):
                obj_spawn = self.scenario.navigations[str_navigation_name]['threads'].pop(0)
                obj_spawn.terminate()
                obj_spawn.join()
                print('Killed one - Cleanup')
        click.secho('DONE', fg='green', bold=True)

        # Close Sysmonitor thread
        click.secho(utils.logify('Closing Sysmonitor... ', 'Spawner'), nl=False)
        self.sysmonitor.terminate()
        self.sysmonitor.join()
        click.secho('DONE', fg='green', bold=True)

        click.secho(utils.logify('Scenario gracefully completed!', 'Spawner'), fg='green', bold=True)