Exemplo n.º 1
0
    def __init__(self):
        self._channel = None
        self._uida_conf_vars = load_variables_from_uida_conf_files()
        self._settings = get_settings(self._uida_conf_vars)
        self._ida_api_url = self._uida_conf_vars['IDA_API_ROOT_URL']

        self._hostname = socket.gethostname()
        self._machine_name = self._hostname.split('.')[0]
        self._process_pid = os.getpid()
        self._sentinel_monitoring_file = '%s/%s-%s-%d' % (
            self._uida_conf_vars['RABBIT_MONITORING_DIR'], self._hostname,
            self.__class__.__name__, self._process_pid)
        self.name = self._get_name()  # name of the agent, displayed in logs
        self.main_queue_name = None  # the queue with original, new actions
        self.failed_queue_name = None  # the queue with republished, failed actions
        self.rabbitmq_message = None  # the currently being processed message from a queue
        self._graceful_shutdown_started = False
        self.gevent = None

        # diagnostic variables for development and testing
        self.last_completed_sub_action = {}
        self.last_failed_action = {}
        self.last_updated_action = {}

        self._logger = get_logger(self.name, self._uida_conf_vars)
        self.connect()
        self._cleanup_old_sentinel_monitoring_files()

        # on process close, try to remove sentinel monitoring files
        signal.signal(signal.SIGTERM,
                      lambda signal, frame: self._signal_shutdown_started())
        signal.signal(signal.SIGINT,
                      lambda signal, frame: self._signal_shutdown_started())
Exemplo n.º 2
0
rabbitmq postprocessing agents require to operate.

Before executing the script, ensure:
- the rabbitmq management plugin is enabled
- rabbitmq admin user has been configured by using script utils/rabbitmq_create_users
- rabbitmq admin credentials are in place in config/config.sh
"""

from json import dumps as json_dumps
from sys import argv

import requests

from agents.utils.utils import get_settings, load_variables_from_uida_conf_files, executing_test_case

uida_conf_vars = load_variables_from_uida_conf_files()

settings = get_settings()

RABBITMQ_API_URL = 'http://%s:%d/api' % (uida_conf_vars['RABBIT_HOST'], uida_conf_vars['RABBIT_WEB_API_PORT'])

RABBITMQ_AUTH = (uida_conf_vars['RABBIT_ADMIN_USER'], uida_conf_vars['RABBIT_ADMIN_PASS'])

HEADERS = { 'Content-Type': 'application/json'}

VHOST_NAME = uida_conf_vars['RABBIT_VHOST']
EXCHANGES = [
    {
        'name': 'actions',
        'type': 'fanout',
        'arguments': {},
Exemplo n.º 3
0
class BaseAgentTestCase(TestCase):

    _settings = get_settings()
    _uida_conf_vars = load_variables_from_uida_conf_files()

    @classmethod
    def setUpClass(cls):
        # instead of setting a signal handler for ctrl+c,
        # call teardown class to make sure everything is clean
        try:
            cls.tearDownClass()
        except Exception:
            pass

    def setUp(self):
        test_utils.init_rabbitmq()
        self._init_files()
        self._prepare_api_responses()

    def tearDown(self):
        test_utils.teardown_rabbitmq()
        self._teardown_files()
        ok = self.currentResult.wasSuccessful()
        # errors = self.currentResult.errors
        # failures = self.currentResult.failures
        #print("Test Successful" if ok else "%d Errors and %d Failures found" % (len(errors), len(failures)))
        print('\033[92m\033[1m' + "\t    ....OK" + '\033[0m' if ok else '\033[91m\033[1m' + "\t    ....FAIL" + '\033[0m')

    def run(self, result=None):
        self.currentResult = result # remember result for use in tearDown
        TestCase.run(self, result) # call superclass run method

    @classmethod
    def tearDownClass(cls):
        test_utils.teardown_rabbitmq()
        cls._teardown_files(cls)

    def _publish_test_messages(self, index=None, exchange='actions'):
        """
        Publish one message from index 'index' from test data, or publish all messages if
        no index is passed.
        """
        message = None
        ga = GenericAgent()
        if index is not None:
            message = ida_test_data['actions'][index]
            ga.publish_message(message, exchange=exchange)
        else:
            for action in ida_test_data['actions']:
                ga.publish_message(action, exchange=exchange)

        # must give some time for messages to get processed in rabbitmq,
        # so that the agents and the asserts can detect the new messages
        sleep(0.5)
        return message

    def _prepare_response(self, method, service, url, status=None, body=None):
        """
        Prepare responses that will be returned by the mock apis that are called
        by the agents during tests, i.e. the response generated here would be what
        the ida-api and metax-api would be expected to return.
        """
        if service == 'ida':
            root_url = self._uida_conf_vars['IDA_API_ROOT_URL']
        elif service == 'metax':
            root_url = self._uida_conf_vars['METAX_API_ROOT_URL']
        else:
            raise Exception('oops! check your settings')

        responses.add(
            method,
            '%s%s' % (root_url, url),
            status=status,
            content_type='application/json',
            body=body
        )

    def _prepare_api_responses(self):
        """
        Generate mock responses made to...
        - ida api using test data. The testdata file is basically a mocked database.
        - metax api. all requests are by default assumed successful. tests which test
          against a failing metax action will override the mock response
        """

        # GET action
        for action in ida_test_data['actions']:
            self._prepare_response(
                responses.GET,
                'ida',
                '/actions/%s' % action['pid'],
                status=200,
                body=json_dumps(action)
            )

        # POST action
        for action in ida_test_data['actions']:
            self._prepare_response(
                responses.POST,
                'ida',
                '/actions/%s' % action['pid'],
                status=204
            )

        # GET nodes associated with action
        for action in ida_test_data['actions']:
            self._prepare_response(
                responses.GET,
                'ida',
                '/files/action/%s' % action['pid'],
                status=200,
                body=json_dumps(
                    [ node for node in ida_test_data['nodes'] if node['action'] == action['pid'] ]
                )
            )

        # POST nodes
        for node in ida_test_data['nodes']:
            self._prepare_response(
                responses.POST,
                'ida',
                '/files/%s' % node['pid'],
                status=204
            )

        # POST to metax /files
        self._prepare_response(
            responses.POST,
            'metax',
            '/files?atomic=true',
            status=200,
            body=json_dumps({
                'success': [
                    { 'object': 'a successfully created object' }
                ],
                'failed': []
            })
        )

        # DELETE to metax /files
        for node in ida_test_data['nodes']:
            self._prepare_response(
                responses.DELETE,
                'metax',
                '/files',
                status=204
            )

    def _init_files(self):
        """
        Create files to the file system from test data
        """
        for f in (f for f in ida_test_data['nodes'] if f['type'] == 'file'):
            test_utils.create_test_file(self._uida_conf_vars, f)

    def _teardown_files(self):
        test_utils.delete_test_directory(self._uida_conf_vars['STORAGE_OC_DATA_ROOT'])
        test_utils.delete_test_directory(self._uida_conf_vars['DATA_REPLICATION_ROOT'])
        test_utils.delete_test_directory(self._uida_conf_vars['RABBIT_MONITORING_DIR'])

    def assert_messages_ended_in_failed_queue(self, message_qty):
        """
        At the end of a test it is useful to check how many messages being processed
        eneded up in the failed queue.
        """
        self.assertEqual(self.agent.messages_in_queue(self.agent.failed_queue_name), message_qty)