示例#1
0
 def test_sio_list_data_type_input_json(self):
     cid = rand_string()
     data_format = DATA_FORMAT.JSON
     transport = rand_string()
     
     sio_config = {'int_parameters': [rand_string()]} # Not really used but needed
     
     service_sio = Bunch()
     service_sio.input_required = ('first_name', 'last_name', List('emails'))
     
     expected_first_name = faker.first_name()
     expected_last_name = faker.last_name()
     expected_emails = sorted([faker.email(), faker.email()])
     
     r = Request(getLogger(__name__), sio_config)
     r.payload = {
         'first_name': expected_first_name,
         'last_name': expected_last_name,
         'emails': expected_emails,
         }
     
     r.init(True, cid, service_sio, data_format, transport, {})
     
     eq_(r.input.first_name, expected_first_name)
     eq_(r.input.last_name, expected_last_name)
     eq_(r.input.emails, expected_emails)
示例#2
0
    def test_nested_to_json(self):

        n = Nested('elem', 'sub1', Bool('my_bool1'), 'sub2', 'sub3', Dict('my_dict1', 'key1', 'key2'))

        expected_sub1_2 = rand_string()
        expected_sub2_2 = rand_string()
        expected_sub3_2 = rand_string()
        expected_my_bool1_2 = rand_bool()
        expected_key1_2 = rand_string()
        expected_key2_2 = rand_string()

        value2 = {'elem': {
            'sub1': expected_sub1_2,
            'sub2': expected_sub2_2,
            'my_bool1': expected_my_bool1_2,
            'sub3': expected_sub3_2,
            'my_dict1' : {
                'key1': expected_key1_2,
                'key2': expected_key2_2,
            }
        }}

        ret_value = n.to_json(value2)

        eq_(ret_value,
            {'elem':
             {'my_bool1': expected_my_bool1_2, 'sub2': expected_sub2_2, 'sub3': expected_sub3_2,
              'my_dict1': {'key2': expected_key2_2, 'key1': expected_key1_2},
              'sub1': expected_sub1_2}}
        )
示例#3
0
    def test_add(self):
        jps = JSONPointerStore()

        name1, expr1 = '1', config_value('/{}/{}'.format(*rand_string(2)))
        name2, expr2 = '2', config_value('/aaa/{}/{}'.format(*rand_string(2)))
        name3, expr3 = '3', config_value('/aaa/{}/{}'.format(*rand_string(2)))
        name4, expr4 = '2', config_value('/aaa/{}/{}'.format(*rand_string(2)))

        jps.add(name1, expr1)
        self.assertIn(name1, jps.data)
        self.assertEquals(expr1.value, jps.data[name1].path)

        jps.add(name2, expr2)
        self.assertIn(name2, jps.data)
        self.assertEquals(expr2.value, jps.data[name2].path)

        jps.add(name3, expr3)
        self.assertIn(name3, jps.data)
        self.assertEquals(expr3.value, jps.data[name3].path)

        # name4's value is '2' so it overrides 2

        jps.add(name4, expr4)
        self.assertIn(name4, jps.data)

        self.assertEquals(expr4.value, jps.data[name2].path)
        self.assertEquals(expr4.value, jps.data[name4].path)
示例#4
0
 def test_publish_custom_attrs(self):
     self._check_publish(**{
         'mime_type': rand_string(),
         'priority': rand_int(),
         'expiration': rand_int(1000, 2000),
         'msg_id': rand_string(),
     })
示例#5
0
    def test_main_loop_max_repeats_reached(self):

        runs_ctx = []

        def callback(ctx):
            runs_ctx.append(ctx)

        cb_kwargs = {
            rand_string():rand_string(),
            rand_string():rand_string()
        }

        interval_in_seconds = 0.01
        max_repeats = choice(range(2, 5))

        job = get_job(interval_in_seconds=interval_in_seconds, max_repeats=max_repeats)
        job.callback = callback
        job.cb_kwargs = cb_kwargs

        self.assertTrue(job.main_loop())
        sleep(0.2)

        len_runs_ctx = len(runs_ctx)
        self.assertEquals(len_runs_ctx, max_repeats)

        self.assertFalse(job.keep_running)
        self.assertIs(job.callback, callback)

        for idx, ctx in enumerate(runs_ctx, 1):
            self.check_ctx(ctx, job, interval_in_seconds, max_repeats, idx, cb_kwargs, len_runs_ctx)
示例#6
0
 def test_response(self):
     request = {'cluster_id':rand_int(), 'name':rand_string()}
     
     expected_id = rand_int()
     expected_name = rand_string()
     expected_is_active = rand_bool()
     expected_impl_name = rand_string()
     expected_is_internal = rand_bool()
     
     service = Service()
     service.id = expected_id
     service.name = expected_name
     service.is_active = expected_is_active
     service.impl_name = expected_impl_name
     service.is_internal = expected_is_internal
     
     expected = Expected()
     expected.add(service)
     
     instance = self.invoke(GetByName, request, expected)
     response = Bunch(loads(instance.response.payload.getvalue())['response'])
     
     eq_(response.id, expected_id)
     eq_(response.name, expected_name)
     eq_(response.is_active, expected_is_active)
     eq_(response.impl_name, expected_impl_name)
     eq_(response.is_internal, expected_is_internal)
     eq_(response.usage, 0)
示例#7
0
    def test_nested_from_json(self):

        n = Nested('elem', 'sub1', Bool('my_bool1'), 'sub2', 'sub3', Dict('my_dict1', 'key1', 'key2'))

        expected_sub1_1 = rand_string()
        expected_sub2_1 = rand_string()
        expected_sub3_1 = rand_string()
        expected_my_bool1_1 = rand_bool()
        expected_key1_1 = rand_string()
        expected_key2_1 = rand_string()

        value1 = {'elem': {
            'sub1': expected_sub1_1,
            'sub2': expected_sub2_1,
            'my_bool1': expected_my_bool1_1,
            'sub3': expected_sub3_1,
            'my_dict1' : {
                'key1': expected_key1_1,
                'key2': expected_key2_1,
            }
        }}

        ret_value = n.from_json(value1)

        eq_(ret_value,
            {'elem':
             {'my_bool1': expected_my_bool1_1, 'sub2': expected_sub2_1, 'sub3': expected_sub3_1,
              'my_dict1': {'key2': expected_key2_1, 'key1': expected_key1_1},
              'sub1': expected_sub1_1}}
        )
示例#8
0
 def get_response_data(self):
     return Bunch({'id':rand_int(), 'name':self.name, 'is_active':rand_bool(), 'is_internal':rand_bool(), 'url_path':rand_string(),
                   'service_id':rand_int(), 'service_name':rand_string(), 'security_id':rand_int(),
                   'security_name':rand_int(), 'sec_type':rand_string(), 'method':rand_string(), 'soap_action':rand_string(), 'soap_version':rand_string(),
                   'data_format':rand_string(), 'host':rand_string(), 'ping_method':rand_string(),
                   'pool_size':rand_int()}
     )
示例#9
0
    def test__set_tls_info(self):

        expected_cert_dict = rand_string()
        expected_cert_der = rand_string()
        expected_cert_sha1 = sha1(expected_cert_der).hexdigest().upper()
        
        for wsgi_url_scheme in('https', 'http'):
            wsgi_environ = {
                'wsgi.url_scheme': wsgi_url_scheme,
                'gunicorn.socket': FakeGunicornSocket(expected_cert_der, expected_cert_dict),
                'zato.http.response.status': rand_string(),
                'zato.http.channel_item': Bunch(audit_enabled=False),
            }
    
            ps = ParallelServer()
            ps.worker_store = FakeWorkerStore()
            ps.on_wsgi_request(wsgi_environ, StartResponse())
            
            if wsgi_url_scheme == 'https':
                eq_(wsgi_environ['zato.tls.client_cert.dict'], expected_cert_dict)
                eq_(wsgi_environ['zato.tls.client_cert.der'], expected_cert_der)
                eq_(wsgi_environ['zato.tls.client_cert.sha1'], expected_cert_sha1)
            else:
                self.assertTrue('zato.tls.client_cert.dict' not in wsgi_environ)
                self.assertTrue('zato.tls.client_cert.der' not in wsgi_environ)
                self.assertTrue('zato.tls.client_cert.sha1' not in wsgi_environ)
示例#10
0
    def test_client_ok(self):

        cid = new_cid()
        headers = {'x-zato-cid':cid}
        ok = True
        _rand = rand_string()
        soap_action = rand_string()
        
        text = """
            <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
             <soapenv:Body>
              <abc>{}</abc>
             </soapenv:Body>
            </soapenv:Envelope>""".format(_rand).strip()
        status_code = rand_int()
        
        client = self.get_client(FakeInnerResponse(headers, ok, text, status_code))
        response = client.invoke(soap_action)

        expected_response_data = """
            <abc xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">{}</abc>
            """.format(_rand).strip()

        eq_(response.details, None)
        eq_(response.ok, ok)
        eq_(response.inner.text, text)
        eq_(etree.tostring(response.data), expected_response_data)
        eq_(response.has_data, True)
        eq_(response.cid, cid)
示例#11
0
 def get_response_data(self):
     return Bunch({'id':rand_int(), 'name':self.name, 'host':rand_string(), 'port':rand_int(),
          'queue_manager':rand_int(), 'channel':rand_string(),
          'cache_open_send_queues':rand_bool(), 'cache_open_receive_queues':rand_bool(),
          'use_shared_connections':rand_bool(), 'ssl':rand_bool(),
          'needs_mcd':rand_bool(), 'max_chars_printed':rand_int(),
          'ssl_cipher_spec':rand_string(), 'ssl_key_repository':rand_string()})
示例#12
0
    def test_message_serialization(self):
        msg_id = rand_string()
        creation_time_utc = rand_date_utc()
        expire_at_utc = rand_date_utc()
        producer = rand_string()
        topic = rand_string()

        actual = self._get_object(Message, {
            'msg_id': msg_id,
            'creation_time_utc': creation_time_utc,
            'expire_at_utc': expire_at_utc,
            'producer': producer,
            'topic':topic,
        })

        expected = {
            'mime_type': PUB_SUB.DEFAULT_MIME_TYPE,
            'msg_id': msg_id,
            'topic': topic,
            'expiration': PUB_SUB.DEFAULT_EXPIRATION,
            'producer': producer,
            'creation_time_utc': creation_time_utc.isoformat(),
            'priority': PUB_SUB.DEFAULT_PRIORITY,
            'expire_at_utc': expire_at_utc.isoformat()
        }

        # Dicts must be equal ..
        assert_equal(actual.to_dict(), expected)

        # .. as well as JSON.
        json = actual.to_json()
        self.assertIsInstance(json, str)
        unjsonified = loads(json)
        assert_equal(unjsonified, expected)
示例#13
0
    def test__startup_services(self):

        class FakeBrokerClient(object):
            def __init__(self):
                self.messages = {}
                
            def invoke_async(self, msg):
                self.messages[msg['service']] = msg
                
        broker_client = FakeBrokerClient()
        
        startup_services = Bunch()
        for x in range(10):
            name =  rand_string()
            payload = rand_string()
            startup_services[name] = payload
        
        ps = ParallelServer()
        ps.broker_client = broker_client
        ps.fs_server_config = Bunch()
        ps.fs_server_config.startup_services = startup_services
        
        ps.invoke_startup_services()
        
        for expected_service, expected_payload in startup_services.items():
            msg = Bunch(broker_client.messages[expected_service])
            eq_(msg.action, SERVICE.PUBLISH)
            eq_(msg.channel, CHANNEL.STARTUP_SERVICE)
            eq_(msg.payload, expected_payload)
            eq_(msg.service, expected_service)
            ok_(msg.cid.startswith('K'))
            self.assertEquals(len(msg.cid), 40)
示例#14
0
    def test_client(self):

        cid = new_cid()
        headers = {'x-zato-cid':cid}
        ok = True
        
        env = {
            'details': rand_string(),
            'result': ZATO_OK,
            'cid': cid
        }
        
        sio_payload_key = rand_string()
        sio_payload = {rand_string(): rand_string()}
        
        sio_response = {
            'zato_env': env,
            sio_payload_key: sio_payload
        }
        
        text = dumps(sio_response)
        status_code = rand_int()
        
        client = self.get_client(FakeInnerResponse(headers, ok, text, status_code))
        response = client.invoke()
        
        eq_(response.ok, ok)
        eq_(response.inner.text, text)
        eq_(response.data.items(), sio_response[sio_payload_key].items())
        eq_(response.has_data, True)
        eq_(response.cid, cid)
        eq_(response.cid, sio_response['zato_env']['cid'])
        eq_(response.details, sio_response['zato_env']['details'])
示例#15
0
    def test_get_retry_settings_has_invalid_async_callback(self):

        ir = InvokeRetry(None)

        callback = [None, rand_string()]
        repeats = [None, rand_int()]

        target = rand_string()

        for callback_item in callback:
            for repeats_item in repeats:
                kwargs = {
                    'async_fallback': True,
                    'callback': callback_item,
                    'repeats': repeats_item,
                }

            try:
                ir._get_retry_settings(target, **kwargs)
            except ValueError, e:

                for name in 'callback', 'repeats':
                    if name in e.message:
                        self.assertEquals(e.message, 'Could not invoke `{}`, `{}` was not provided ({})'.format(
                            target, name, None))
            else:
                self.assertTrue(callback_item is not None)
                self.assertTrue(repeats_item is not None)
示例#16
0
 def test_sio_list_data_type_input_xml(self):
     cid = rand_string()
     data_format = DATA_FORMAT.XML
     transport = rand_string()
     
     sio_config = {'int_parameters': [rand_string()]} # Not really used but needed
     
     service_sio = Bunch()
     service_sio.input_required = ('first_name', 'last_name', List('emails'))
     
     expected_first_name = faker.first_name()
     expected_last_name = faker.last_name()
     expected_emails = sorted([faker.email(), faker.email()])
     
     r = Request(getLogger(__name__), sio_config)
     r.payload = etree.fromstring("""<request>
       <first_name>{}</first_name>
       <last_name>{}</last_name>
       <emails>
        <item>{}</item>
        <item>{}</item>
       </emails>
     </request>""".format(
         expected_first_name, expected_last_name, expected_emails[0], expected_emails[1]))
     
     r.init(True, cid, service_sio, data_format, transport, {})
     
     eq_(r.input.first_name, expected_first_name)
     eq_(r.input.last_name, expected_last_name)
     eq_(r.input.emails, expected_emails)
示例#17
0
 def setUp(self):
     self.url = rand_string()
     self.auth = None
     self.path = rand_string()
     self.session = FakeSession()
     self.to_bunch = rand_bool()
     self.max_response_repr = 10000
     self.max_cid_repr = rand_int()
     self.logger = rand_object()
示例#18
0
 def test_publish_custom_attrs(self):
     self._check_publish(
         **{
             "mime_type": rand_string(),
             "priority": rand_int(),
             "expiration": rand_int(1000, 2000),
             "msg_id": rand_string(),
         }
     )
示例#19
0
    def test_retry_limit_reached_msg(self):
        retry_repeats = rand_int()
        service_name = rand_string()
        retry_seconds = rand_int()
        orig_cid = rand_string()

        msg = retry_limit_reached_msg(retry_repeats, service_name, retry_seconds, orig_cid)

        self.assertEquals(msg, '({}/{}) Retry limit reached for:`{}`, retry_seconds:`{}`, orig_cid:`{}`'.format(
            retry_repeats, retry_repeats, service_name, retry_seconds, orig_cid))
示例#20
0
 def get_request_data(self):
     return {
         "cluster_id": rand_int(),
         "name": self.name,
         "is_active": rand_bool(),
         "address": rand_string(),
         "socket_type": rand_string(),
         "service": rand_string(),
         "sub_key": rand_string(),
         "data_format": rand_string(),
     }
示例#21
0
    def test_retry_failed_msg(self):
        so_far = rand_int()
        retry_repeats = rand_int()
        service_name = rand_string()
        retry_seconds = rand_int()
        orig_cid = rand_string()

        try:
            raise_exception()
        except Exception, e:
            pass
示例#22
0
    def test_clients(self):
        for class_ in AnyServiceInvoker, JSONClient, JSONSIOClient, XMLClient, RawDataClient, SOAPClient, SOAPSIOClient:
            with patch('zato.client._Client.inner_invoke', self.get_inner_invoke()):

                client = class_(*rand_string(2))

                header1, value1 = rand_string(2)
                header2, value2 = rand_string(2)
                headers = {header1:value1, header2:value2}

                response = client.invoke(rand_string(), headers=headers)
                eq_(sorted(headers.items()), sorted(response.headers.items()))
示例#23
0
    def test_get_ctx_custom_attrs(self):
        sub_key = rand_string()
        max_batch_size = rand_int()
        is_fifo = rand_bool()
        get_format = rand_string()

        ctx = GetCtx(sub_key, max_batch_size, is_fifo, get_format)

        self.assertEquals(ctx.sub_key, sub_key)
        self.assertEquals(ctx.max_batch_size, max_batch_size)
        self.assertEquals(ctx.is_fifo, is_fifo)
        self.assertEquals(ctx.get_format, get_format)
示例#24
0
 def handle(self):
     dn = self.dictnav(self.request.input)
     response = {
         'key1': sorted(dn.get(['nested', 'a']).items()),
         'value': dn.get(['nested', 'a', 'b', 'c']),
         'has_key_flat_true': dn.has_key('flat', False),
         'has_key_flat_false': dn.has_key(rand_string(), True),
         'has_key_nested_true': dn.has_key('b'),
         'has_key_nested_false': dn.has_key(rand_string()),
         'has_path': dn.has_path(['nested', 'a', 'b', 'c']),
     }
     self.response.payload = response
示例#25
0
    def test_reject_ctx_custom_attrs(self):
        sub_key = rand_string()
        msg_ids = rand_string(2)

        ctx = RejectCtx(sub_key, msg_ids)

        self.assertEquals(ctx.sub_key, sub_key)
        self.assertEquals(ctx.msg_ids, msg_ids)

        msg_id = rand_string()
        ctx.append(msg_id)

        self.assertEquals(ctx.msg_ids, msg_ids)
示例#26
0
    def test_subscribe(self):
        client_id, client_name = rand_int(), rand_string()
        client = Client(client_id, client_name)
        topics = rand_string(rand_int())

        sub_key = self.api.subscribe(client.id, topics)

        self.assertEquals(self.api.impl.sub_to_cons[sub_key], client_id)
        self.assertEquals(self.api.impl.cons_to_sub[client_id], sub_key)
        self.assertEquals(sorted(self.api.impl.cons_to_topic[client_id]), sorted(topics))

        for topic in topics:
            self.assertIn(client_id, self.api.impl.topic_to_cons[topic])
示例#27
0
    def test_ping_method(self):
        """ https://github.com/zatosource/zato/issues/44 (outconn HTTP/SOAP ping method)
        """
        config = self._get_config()
        expected_ping_method = 'ping-{}'.format(rand_string())
        config['ping_method'] = expected_ping_method
        requests_module = _FakeRequestsModule()

        wrapper = HTTPSOAPWrapper(config, requests_module)
        wrapper.ping(rand_string())

        ping_method = requests_module.session_obj.request_args[0]
        eq_(expected_ping_method, ping_method)
示例#28
0
 def test_pool_size(self):
     """ https://github.com/zatosource/zato/issues/77 (outconn HTTP/SOAP pool size)
     """
     expected_pool_size = rand_int()
     requests_module = _FakeRequestsModule()
     
     config = {'sec_type':rand_string(), 'address':rand_string(), 
               'ping_method':rand_string(), 'pool_size':expected_pool_size}
     
     wrapper = HTTPSOAPWrapper(config, requests_module)
     wrapper.ping(rand_string())
     
     eq_(expected_pool_size, requests_module.session_obj.pool_size)
示例#29
0
 def test_ping_method(self):
     """ https://github.com/zatosource/zato/issues/44 (outconn HTTP/SOAP ping method)
     """
     expected_ping_method = 'ping-{}'.format(rand_string())
     requests_module = _FakeRequestsModule()
     
     config = {'sec_type':rand_string(), 'address':rand_string(), 
               'ping_method':expected_ping_method, 'pool_size':rand_int()}
     
     wrapper = HTTPSOAPWrapper(config, requests_module)
     wrapper.ping(rand_string())
     
     ping_method = requests_module.session_obj.request_args[0]
     eq_(expected_ping_method, ping_method)
示例#30
0
    def _publish_move(self, move=True, **kwargs):
        payload = rand_string()

        topic = Topic(rand_string())
        self.api.add_topic(topic)

        producer = Client(rand_int(), rand_string())
        self.api.add_producer(producer, topic)

        ctx = self.api.publish(payload, topic.name, client_id=producer.id, **kwargs)
        if move:
            self.api.impl.move_to_target_queues()

        return payload, topic, producer, ctx
示例#31
0
    def test_dictnav(self):

        key1, key2, key3 = 'a', 'b', 'c'
        value = rand_string()

        d = {'flat': 123, 'nested': {key1: {key2: {key3: value}}}}

        class MyService(Service):
            def handle(self):
                dn = self.dictnav(self.request.input)

                # 'nopep8' is needed because otherwise flake8 treats .has_key as though
                # it belonged to a dict which is not the case.
                # I.e. W601 .has_key() is deprecated, use 'in'

                response = {
                    'key1': sorted(dn.get(['nested', 'a']).items()),
                    'value': dn.get(['nested', 'a', 'b', 'c']),
                    'has_key_flat_true': dn.has_key('flat', False),  # nopep8
                    'has_key_flat_false': dn.has_key(rand_string(), True),
                    'has_key_nested_true': dn.has_key('b'),
                    'has_key_nested_false': dn.has_key(rand_string()),
                    'has_path': dn.has_path(['nested', 'a', 'b', 'c']),
                }
                self.response.payload = response

        service = MyService()
        service.request.input = d
        service.handle()

        eq_(service.response.payload['key1'], [('b', {'c': value})])
        eq_(service.response.payload['value'], value)
        eq_(service.response.payload['has_key_flat_true'], True)
        eq_(service.response.payload['has_key_flat_false'], False)
        eq_(service.response.payload['has_key_nested_true'], True)
        eq_(service.response.payload['has_key_nested_false'], False)
        eq_(service.response.payload['has_path'], True)
示例#32
0
    def test_namespace(self):
        gen = Generator(get_service_store_services(
            Namespace1, Namespace2, Namespace3, Namespace11, Namespace22, Namespace33, NoNamespace), simple_io_config)
        info = gen.get_info(rand_string())

        sns1 = get_services_from_info('name', '_test.namespace1', info)
        sns2 = get_services_from_info('name', '_test.namespace2', info)
        sns3 = get_services_from_info('name', '_test.namespace3', info)
        sns11 = get_services_from_info('name', '_test.namespace11', info)
        sns22 = get_services_from_info('name', '_test.namespace22', info)
        sns33 = get_services_from_info('name', '_test.namespace33', info)
        snons = get_services_from_info('name', '_test.no-namespace', info)

        namespaces = bunchify(info['namespaces'])
        myns = namespaces['myns']
        my_other_ns = namespaces['my-other-ns']
        my_other_ns_abc = namespaces['my-other-ns-abc']

        self.assertEquals(myns.name, 'myns')
        self.assertEquals(myns.docs, """This is my namespace.\nAs with regular docstrings it can contain multi-line documentation.\n\n* Documentation will be parsed as Markdown\n* Bullet lists *and* other non-obtrusive markup can be used\n""")
        self.assertEquals(myns.docs_md, """<p>This is my namespace.\nAs with regular docstrings it can contain multi-line documentation.</p>\n<ul>\n<li>Documentation will be parsed as Markdown</li>\n<li>Bullet lists <em>and</em> other non-obtrusive markup can be used</li>\n</ul>""")

        self.assertEquals(my_other_ns.name, 'my-other-ns')
        self.assertEquals(my_other_ns.docs, '')
        self.assertEquals(my_other_ns.docs_md, '')

        self.assertEquals(my_other_ns_abc.name, 'my-other-ns-abc')
        self.assertEquals(my_other_ns_abc.docs, '')
        self.assertEquals(my_other_ns_abc.docs_md, '')

        self.assertEquals(sns1.namespace_name, 'myns')
        self.assertEquals(sns2.namespace_name, 'my-other-ns')
        self.assertEquals(sns3.namespace_name, 'myns')
        self.assertEquals(sns11.namespace_name, 'myns')
        self.assertEquals(sns22.namespace_name, 'myns')
        self.assertEquals(sns33.namespace_name, 'my-other-ns-abc')
        self.assertEquals(snons.namespace_name, APISPEC.NAMESPACE_NULL)
示例#33
0
    def test_lock_ok(self):
        """ Succesfully grab a service lock.
        """
        my_kvdb = FakeKVDB()
        my_kvdb.conn.setnx_return_value = True

        lock_name = rand_string()
        expires = 500 + rand_int(
        )  # It's 500 which means DummyService.invoke has that many seconds to complete
        timeout = rand_int()

        class DummyService(Service):
            kvdb = my_kvdb

            def handle(self):
                with self.lock(lock_name, expires, timeout):
                    pass

        instance = DummyService()
        instance.handle()

        eq_(my_kvdb.conn.delete_args, KVDB.LOCK_SERVICE_PREFIX + lock_name)
        eq_(my_kvdb.conn.expire_args,
            (KVDB.LOCK_SERVICE_PREFIX + lock_name, expires))

        # First arg is the lock_name that can ne checked directly but the other
        # one is the expiration time that we can check only approximately,
        # anything within 3 seconds range is OK. The value of 3 is the maximum
        # time allowed for execution of DummyService's invoke method which is
        # way more than needed but let's use 3 to be on the safe side when the
        # test is run on a very slow system.
        eq_(my_kvdb.conn.setnx_args[0], KVDB.LOCK_SERVICE_PREFIX + lock_name)
        expires_approx = time() + expires
        self.assertAlmostEquals(my_kvdb.conn.setnx_args[1],
                                expires_approx,
                                delta=3)
示例#34
0
    def test_convert_check_priority(self):

        func_to_type = {
            rand_bool: Boolean,
            rand_float: Float,
            rand_int: Integer,
            rand_string: str,
        }

        for func, type_ in func_to_type.items():
            for params_priority in PARAMS_PRIORITY:

                param_name = rand_string()
                payload_value = func()
                channel_value = func()

                args = self.get_args(param=type_(param_name), channel_params={param_name:channel_value},
                    payload={param_name:payload_value}, params_priority=params_priority)

                given_param_name, given_value = convert_param(**args)
                expected_value = channel_value if params_priority == PARAMS_PRIORITY.CHANNEL_PARAMS_OVER_MSG else payload_value

                self.assertEquals(param_name, given_param_name)
                self.assertEquals(expected_value, given_value)
示例#35
0
    def test_publish_exceptions(self):
        payload = rand_string()
        producer = Client(rand_int(), rand_string())

        def invoke_publish(payload, topic, producer_id):
            self.api.publish(payload, topic, client_id=producer_id)

        # KeyError because no such producer is in self.api.impl.producers.
        self.assertRaises(KeyError, invoke_publish, payload, rand_string(),
                          producer.id)

        # Adding a producer but still, no such topic.
        self.api.add_producer(producer, Topic(rand_string()))
        self.assertRaises(PubSubException, invoke_publish, payload,
                          rand_string(), producer.id)

        # Adding a topic but still PubSubException is raised because the producer is not allowed to use it.
        topic = Topic(rand_string())
        self.api.add_topic(topic)
        self.assertRaises(PubSubException, invoke_publish, payload, topic.name,
                          producer.id)

        # Combining the topic and producer, no exception is raised now.
        self.api.add_producer(producer, topic)
        invoke_publish(payload, topic.name, producer.id)

        # But it's not possible to publish to inactive topics.
        self.api.impl.topics[topic.name].is_active = False
        self.assertRaises(PubSubException, invoke_publish, payload, topic.name,
                          producer.id)

        # Make the topic active and it can be published to again.
        self.api.impl.topics[topic.name].is_active = True
        invoke_publish(payload, topic.name, producer.id)

        # Inactive producers cannot publish to topics either.
        self.api.impl.producers[producer.id].is_active = False
        self.assertRaises(PubSubException, invoke_publish, payload, topic.name,
                          producer.id)

        # Making them active means they can publish again.
        self.api.impl.producers[producer.id].is_active = True
        invoke_publish(payload, topic.name, producer.id)
示例#36
0
    def test_create_headers_user_headers_data_format(self):

        cid = rand_string()
        now = datetime.utcnow().isoformat()
        content_type = rand_string()
        requests_module = _FakeRequestsModule()

        config = self._get_config()

        wrapper = HTTPSOAPWrapper(config, requests_module)
        user_headers = {rand_string():rand_string(), rand_string():rand_string(), 'Content-Type':content_type}

        headers = wrapper._create_headers(cid, user_headers, now)

        eq_(headers.pop('X-Zato-CID'), cid)
        eq_(headers.pop('X-Zato-Msg-TS'), now)
        eq_(headers.pop('X-Zato-Component'), get_component_name())
        eq_(headers.pop('Content-Type'), content_type)

        # Anything that is left must be user headers
        self.assertDictEqual(headers, user_headers)
示例#37
0
 def get_request_data(self):
     return {
         'cluster_id': rand_int(),
         'connection': rand_string(),
         'transport': rand_string()
     }
示例#38
0
    def test_handle_simple_ok_exception(self):

        test_instance = self

        for is_ok in True, False:

            expected_response = 'expected_response_{}'.format(
                rand_string()) if is_ok else None

            class Ping(object):
                name = 'zato.ping'

                def __init__(self):
                    self.response = Bunch(payload=expected_response)
                    test_instance.given_response = expected_response

                def accept(self):
                    return True

                def update(self, *ignored_args, **ignored_kwargs):
                    if not is_ok:
                        raise Exception()

                post_handle = validate_output = handle = validate_input = call_hooks = pre_handle = update

            callback = rand_string()
            target = 'zato.ping'

            orig_cid, call_cid = new_cid(), new_cid()
            source, req_ts_utc = rand_string(), rand_string()

            ping_impl = 'zato.service.internal.Ping'
            service_store_name_to_impl_name = {
                'zato.ping': ping_impl,
                callback: ping_impl
            }
            service_store_impl_name_to_service = {ping_impl: Ping}

            payload = {
                'source': source,
                'req_ts_utc': req_ts_utc,
                'orig_cid': orig_cid,
                'call_cid': call_cid,
                'callback': callback,
                'callback_context': {
                    rand_string(): rand_string()
                },
                'target': target,
                'retry_repeats': 4,
                'retry_seconds': 0.1,
                'args': [1, 2, 3],
                'kwargs': {
                    rand_string(): rand_string(),
                    rand_int(): rand_int()
                },
            }

            instance = self.invoke(
                InvokeRetry,
                dumps(payload),
                None,
                service_store_name_to_impl_name=service_store_name_to_impl_name,
                service_store_impl_name_to_service=
                service_store_impl_name_to_service)

            gevent.sleep(0.5)

            self.assertEquals(len(instance.broker_client.invoke_async_args), 1)
            self.assertEquals(len(instance.broker_client.invoke_async_args[0]),
                              1)

            async_msg = Bunch(instance.broker_client.invoke_async_args[0][0])
            self.assertEquals(len(async_msg), 11)

            self.assertEquals(async_msg.action, SERVICE.PUBLISH.value)
            self.assertEquals(async_msg.channel, CHANNEL.INVOKE_ASYNC)
            self.assertEquals(async_msg.data_format, DATA_FORMAT.DICT)
            self.assertEquals(async_msg.transport, None)

            resp_ts_utc = async_msg.payload.pop('resp_ts_utc')

            # Is it a date? If not, an exception will be raised while parsing.
            arrow.get(resp_ts_utc)

            expected_response_msg = {
                'ok': is_ok,
                'source': source,
                'target': target,
                'req_ts_utc': req_ts_utc,
                'orig_cid': orig_cid,
                'call_cid': call_cid,
                'retry_seconds': payload['retry_seconds'],
                'context': payload['callback_context'],
                'retry_repeats': payload['retry_repeats'],
                'response': expected_response,
            }

            self.assertDictEqual(expected_response_msg, async_msg.payload)

            self.assertTrue(
                len(instance.broker_client.invoke_async_kwargs) == 1)
            self.assertEquals(instance.broker_client.invoke_async_kwargs[0],
                              {'expiration': BROKER.DEFAULT_EXPIRATION})
示例#39
0
 def get_request_data(self):
     return {'cluster_id': rand_int(), 'name':rand_string()}
示例#40
0
 def get_response_data(self):
     return Bunch({'id':rand_int(), 'name':rand_string, 'is_active':rand_bool(), 'sec_type':rand_string(), 'username':rand_string(),
                   'realm':rand_string(), 'password_type':rand_string(), 'reject_empty_nonce_creat':rand_bool(),
                   'reject_stale_tokens':rand_bool(),'reject_expiry_limit':rand_int(), 'nonce_freshness_time':rand_int()})
示例#41
0
文件: test__init__.py 项目: xbx/zato
 def get_request_data(self):
     return {'pong': rand_string()}
示例#42
0
 def get_request_data(self):
     return ({'cluster_id':rand_int(), 'name':rand_string(), 'is_active':rand_bool(), 'job_type':rand_string(),
              'service':rand_string(), 'start_date':rand_datetime(), 'id':rand_int(), 'extra':rand_string(),
              'weeks':rand_int(), 'days':rand_int(), 'hours':rand_int(), 'minutes':rand_int(),
              'seconds':rand_int(), 'repeats':rand_int(), 'cron_definition':rand_string()}
             )
示例#43
0
 def get_request_data(self):
     return ({
         'cluster_id': rand_int(),
         'name': rand_string(),
         'is_active': rand_bool(),
         'connection': rand_string(),
         'transport': rand_string(),
         'url_path': rand_string(),
         'service': rand_string(),
         'security': rand_string(),
         'security_id': rand_int(),
         'method': rand_string(),
         'soap_action': rand_string(),
         'soap_version': rand_string(),
         'data_format': rand_string(),
         'host': rand_string()
     })
示例#44
0
 def test_pub_ctx_custom_attrs(self):
     client_id, topic, msg = rand_string(3)
     ctx = PubCtx(client_id, topic, msg)
     self.assertEquals(ctx.client_id, client_id)
     self.assertEquals(ctx.topic, topic)
     self.assertEquals(ctx.msg, msg)
示例#45
0
    def test_get_reject_acknowledge(self):
        payload, topic, producer, ctx = self._publish_move(move=False)
        client_id, client_name = rand_int(), rand_string()

        client = Client(client_id, client_name)
        sub_key = self.api.subscribe(client.id, topic.name)

        # Moves a message to the consumer's queue
        self.api.impl.move_to_target_queues()
        self._check_consumer_queue_before_get(ctx, sub_key)

        # Consumer gets a message which puts it in the in-flight state.
        self._check_get(ctx, sub_key, topic, producer, client)

        # However, there should be nothing in the consumer's queue.
        consumer_msg_ids = self.kvdb.lrange(
            self.api.impl.CONSUMER_MSG_IDS_PREFIX.format(sub_key), 0, -1)
        self.assertEquals(consumer_msg_ids, [])

        # Consumer rejects the message which puts it back on a queue.
        self.api.reject(sub_key, ctx.msg.msg_id)

        # After rejection it's as though the message has just been published.
        self._check_consumer_queue_before_get(ctx, sub_key)

        # Get after rejection works as before.
        self._check_get(ctx, sub_key, topic, producer, client)

        # Consumer acknowledges a message.
        self.api.acknowledge(sub_key, ctx.msg.msg_id)

        # This was the only one subscription so now that the message has been delivered
        # there should be no trace of it in backend.
        # The only keys left are LAST_PUB_TIME_KEY, LAST_SEEN_CONSUMER_KEY and LAST_SEEN_PRODUCER_KEY - nothing else.

        keys = self.kvdb.keys('{}*'.format(self.key_prefix))
        self.assertEquals(len(keys), 3)

        now = datetime.utcnow()

        last_pub_time = parse(
            self.kvdb.hgetall(self.api.impl.LAST_PUB_TIME_KEY)[topic.name])
        last_seen_consumer = parse(
            self.kvdb.hgetall(self.api.impl.LAST_SEEN_CONSUMER_KEY)[str(
                client.id)])
        last_seen_producer = parse(
            self.kvdb.hgetall(self.api.impl.LAST_SEEN_PRODUCER_KEY)[str(
                producer.id)])

        self.assertTrue(
            last_pub_time < now,
            'last_pub_time:`{}` is not less than now:`{}`'.format(
                last_pub_time, now))
        self.assertTrue(
            last_seen_consumer < now,
            'last_seen_consumer:`{}` is not less than now:`{}`'.format(
                last_seen_consumer, now))
        self.assertTrue(
            last_seen_producer < now,
            'last_seen_producer:`{}` is not less than now:`{}`'.format(
                last_seen_producer, now))
示例#46
0
 def get_request_data(self):
     return {'id':rand_int(), 'cluster_id':rand_int(), 'name':rand_string(), 'is_active':rand_bool(), 'def_id':rand_int(),
             'delivery_mode':rand_string(),'priority':rand_int(), 'content_type':rand_string(), 'content_encoding':rand_string(),
             'expiration':rand_int(), 'user_id':rand_string(), 'app_id':rand_string()}
示例#47
0
        config = self._get_config()
        config['address_host'] = address_host
        config['address_url_path'] = address_url_path

        requests_module = _FakeRequestsModule()
        wrapper = HTTPSOAPWrapper(config, requests_module)

        try:
            wrapper.format_address(cid, None)
        except ValueError, e:
            eq_(e.message,
                'CID:[{}] No parameters given for URL path'.format(cid))
        else:
            self.fail('Expected ValueError (params is None)')

        a = rand_string()
        b = rand_string()
        c = rand_string()
        d = rand_string()
        e = rand_string()
        f = rand_string()

        params = {'a': a, 'b': b, 'c': c, 'd': d, 'e': e, 'f': f}
        address, non_path_params = wrapper.format_address(cid, params)
        eq_(address, '{}/a/{}/b{}/c-{}/{}d/'.format(address_host, a, b, c, d))
        eq_(non_path_params, {'e': e, 'f': f})

        params = {'a': a, 'b': b}

        try:
            address, non_path_params = wrapper.format_address(cid, params)
示例#48
0
    def test_http_methods(self):
        address_host = rand_string()

        config = self._get_config()
        config['is_active'] = True
        config['soap_version'] = '1.2'
        config['address_host'] = address_host

        requests_module = _FakeRequestsModule()
        wrapper = HTTPSOAPWrapper(config, requests_module)

        for address_url_path in ('/zzz', '/a/{a}/b/{b}'):
            for transport in ('soap', rand_string()):
                for name in ('get', 'delete', 'options', 'post', 'put',
                             'patch'):
                    config['transport'] = transport

                    _cid = rand_string()
                    _data = rand_string()

                    expected_http_request_value = rand_string()
                    expected_http_request_value = rand_string()

                    expected_params = rand_string()

                    expected_args1 = rand_string()
                    expected_args2 = rand_string()

                    expected_kwargs1 = rand_string()
                    expected_kwargs2 = rand_string()

                    def http_request(method,
                                     cid,
                                     data='',
                                     params=None,
                                     *args,
                                     **kwargs):

                        eq_(method, name.upper())
                        eq_(cid, _cid)

                        if name in ('get', 'delete', 'options'):
                            eq_(data, '')
                        else:
                            eq_(data, _data)

                        eq_(params, expected_params)
                        eq_(args, (expected_args1, expected_args2))
                        eq_(sorted(kwargs.items()),
                            [('bar', expected_kwargs2),
                             ('foo', expected_kwargs1)])

                        return expected_http_request_value

                    def format_address(cid, params):
                        return expected_http_request_value

                    wrapper.http_request = http_request
                    wrapper.format_address = format_address

                    func = getattr(wrapper, name)

                    if name in ('get', 'delete', 'options'):
                        http_request_value = func(_cid,
                                                  expected_params,
                                                  expected_args1,
                                                  expected_args2,
                                                  foo=expected_kwargs1,
                                                  bar=expected_kwargs2)
                    else:
                        http_request_value = func(_cid,
                                                  _data,
                                                  expected_params,
                                                  expected_args1,
                                                  expected_args2,
                                                  foo=expected_kwargs1,
                                                  bar=expected_kwargs2)

                    eq_(http_request_value, expected_http_request_value)
示例#49
0
    def test_dict_no_keys_specified(self):
        d = Dict('d')
        value = {rand_string(): rand_string(), rand_string(): rand_string()}

        ret_value = d.from_json(value)
        eq_(value, ret_value)
示例#50
0
文件: test_outgoing.py 项目: xbx/zato
    def request(self, *args, **kwargs):
        self.request_args = args
        self.request_kwargs = kwargs

        return Bunch({'status_code': rand_string()})
示例#51
0
 def get_response_data(self):
     return Bunch({'info': rand_string()})
示例#52
0
    def test_main_loop_sleep_spawn_called(self):

        wait_time = 0.2
        sleep_time = rand_int()

        now_values = [parse_datetime('2019-12-23 22:19:03'), parse_datetime('2021-05-13 17:35:48')]

        sleep_history = []
        spawn_history = []
        sleep_time_history = []

        def sleep(value):
            if value != wait_time:
                sleep_history.append(value)

        def spawn(*args, **kwargs):
            spawn_history.append([args, kwargs])

        def get_sleep_time(*args, **kwargs):
            sleep_time_history.append(args[1])
            return sleep_time

        with patch('gevent.sleep', sleep):
            with patch('zato.scheduler.backend.Job._spawn', spawn):
                with patch('zato.scheduler.backend.Job.get_sleep_time', get_sleep_time):
                    for now in now_values:
                        self.now = now
                        with patch('zato.scheduler.backend.datetime', self._datetime):
                            for job_type in SCHEDULER.JOB_TYPE.CRON_STYLE, SCHEDULER.JOB_TYPE.INTERVAL_BASED:

                                max_repeats = choice(range(2, 5))

                                cb_kwargs = {
                                    rand_string():rand_string(),
                                    rand_string():rand_string()
                                }

                                interval = Interval(seconds=sleep_time) if job_type == SCHEDULER.JOB_TYPE.INTERVAL_BASED \
                                    else CronTab(DEFAULT_CRON_DEFINITION)

                                job = Job(rand_int(), rand_string(), job_type, interval, max_repeats=max_repeats)

                                if job.type == SCHEDULER.JOB_TYPE.CRON_STYLE:
                                    job.cron_definition = DEFAULT_CRON_DEFINITION

                                job.cb_kwargs = cb_kwargs
                                job.start_time = datetime.utcnow()
                                job.callback = dummy_callback

                                self.assertTrue(job.main_loop())
                                time.sleep(0.5)

                                self.assertEquals(max_repeats, len(sleep_history))
                                self.assertEquals(max_repeats, len(spawn_history))

                                for item in sleep_history:
                                    self.assertEquals(sleep_time, item)

                                for idx, (callback, ctx_dict) in enumerate(spawn_history, 1):
                                    self.assertEquals(2, len(callback))
                                    callback = callback[1]
                                    self.check_ctx(
                                        ctx_dict['ctx'], job, sleep_time, max_repeats, idx, cb_kwargs, len(spawn_history), job_type)
                                    self.assertIs(callback, dummy_callback)

                                del sleep_history[:]
                                del spawn_history[:]

                            for item in sleep_time_history:
                                self.assertEquals(item, now)

                            del sleep_time_history[:]
示例#53
0
 def dispatch(self, *ignored_args, **ignored_kwargs):
     return rand_string()
示例#54
0
 def get_response_data(self):
     return Bunch({'id':rand_int(), 'name':self.name, 'is_active':rand_bool(), 'job_type':rand_string(),
                   'start_date':rand_datetime(), 'service_id':rand_int(), 'service_name':rand_string(),
                   'extra':rand_string(), 'weeks':rand_int(), 'days':rand_int(), 'minutes':rand_int(), 'seconds':rand_int(),
                   'repeats':rand_int(), 'cron_definition':rand_string(), '':True}
     )
示例#55
0
 def get_context():
     ctx = {'name': rand_string(), 'type':SCHEDULER.JOB_TYPE.INTERVAL_BASED}
     data['ctx'].append(ctx)
     return ctx
示例#56
0
 def get_request_data(self):
     return {
         'id': rand_int(),
         'password1': rand_string(),
         'password2': rand_string()
     }
示例#57
0
 def test_sub_ctx_custom_attrs(self):
     client_id, topics = rand_string(2)
     ctx = SubCtx(client_id, topics)
     self.assertEquals(ctx.client_id, client_id)
     self.assertEquals(ctx.topics, topics)
示例#58
0
    def test_audit(self):
        for expected_audit_enabled in (True, False):
            for expected_status_code in (httplib.OK, httplib.FORBIDDEN):
                for use_x_remote_addr in (True, False):

                    expected_auth_ok = True if expected_status_code == httplib.OK else False
                    expected_invoke_ok = True if expected_auth_ok is True else False

                    expected_cid = new_cid()
                    expected_url_scheme = rand_string()
                    expected_payload = rand_string()

                    expected_audit_repl_patt_type = rand_string()
                    expected_replace_patterns_json_pointer = []
                    expected_replace_patterns_xpath = []
                    expected_cluster_id = rand_int()
                    expected_id = rand_int()
                    expected_name = rand_string()
                    expected_password = '******'
                    expected_username = rand_string()
                    expected_transport = rand_string()
                    expected_connection = rand_string()
                    expected_data_format = DATA_FORMAT.JSON
                    expected_is_active = True
                    expected_request = rand_string()
                    expected_audit_max_payload = len(
                        expected_request
                    ) - 7  # Substracting any value would do

                    expected_channel_item_key1 = rand_string()
                    expected_channel_item_value1 = rand_string()

                    expected_match_target = rand_string()

                    channel_item = {
                        'id': expected_id,
                        'name': expected_name,
                        'transport': expected_transport,
                        'connection': expected_connection,
                        'audit_enabled': expected_audit_enabled,
                        expected_channel_item_key1:
                        expected_channel_item_value1,
                        'audit_repl_patt_type': expected_audit_repl_patt_type,
                        'replace_patterns_json_pointer':
                        expected_replace_patterns_json_pointer,
                        'replace_patterns_xpath':
                        expected_replace_patterns_xpath,
                        'audit_max_payload': expected_audit_max_payload,
                        'is_active': expected_is_active,
                        'data_format': DATA_FORMAT.JSON,
                        'match_target': expected_match_target,
                        'username': expected_username,
                        'method': '',
                    }

                    wsgi_environ = {
                        'wsgi.url_scheme': expected_url_scheme,
                        'gunicorn.socket': FakeGunicornSocket(None, None),
                        'zato.http.response.status': expected_status_code,
                        'zato.http.channel_item': channel_item,
                        'PATH_INFO': rand_string(),
                        'wsgi.input': StringIO(expected_request),
                        'REQUEST_METHOD': rand_string(),
                        'SERVER_PROTOCOL': rand_string(),
                        'HTTP_USER_AGENT': rand_string(),
                    }

                    expected_remote_addr = rand_string()

                    if use_x_remote_addr:
                        expected_remote_addr_header = 'HTTP_X_FORWARDED_FOR'
                        wsgi_environ[
                            expected_remote_addr_header] = expected_remote_addr
                    else:
                        expected_remote_addr_header = 'REMOTE_ADDR'
                        wsgi_environ[
                            expected_remote_addr_header] = expected_remote_addr

                    class FakeSession:
                        def __init__(self, audit=None):
                            self.audit = audit
                            self.commit_called = False

                        def close(self):
                            pass

                        def commit(self):
                            self.commit_called = True

                        def add(self, audit):
                            self.audit = audit

                    fake_session = FakeSession()

                    class FakeBrokerClient(object):
                        def __init__(self):
                            self.msg = None

                        def publish(self, msg):
                            self.msg = msg

                    class FakeODB(ODBManager):
                        def __init__(self):
                            self.msg = None
                            self.cluster = Bunch(id=expected_cluster_id)

                        def session(self):
                            return fake_session

                    class FakeURLData(URLData):
                        def __init__(self):
                            self.url_sec = {
                                expected_match_target: Bunch(sec_def=ZATO_NONE)
                            }

                        def match(self, *ignored_args, **ignored_kwargs):
                            return True, channel_item

                    class FakeRequestHandler(object):
                        def handle(self, *ignored_args, **ignored_kwargs):
                            return Bunch(payload=expected_payload,
                                         content_type='text/plain',
                                         headers={},
                                         status_code=expected_status_code)

                    bc = FakeBrokerClient()
                    ws = FakeWorkerStore()
                    ws.request_dispatcher = RequestDispatcher()
                    ws.request_dispatcher.request_handler = FakeRequestHandler(
                    )
                    ws.request_dispatcher.url_data = FakeURLData()
                    ws.request_dispatcher.url_data.broker_client = bc
                    ws.request_dispatcher.url_data.odb = FakeODB()

                    ps = ParallelServer()
                    ps.worker_store = ws
                    ps.on_wsgi_request(wsgi_environ,
                                       StartResponse(),
                                       cid=expected_cid)

                    if expected_audit_enabled:

                        #
                        # Audit 1/2 - Request
                        #

                        # Parsing will confirm the proper value was used
                        datetime.strptime(
                            fake_session.audit.req_time.isoformat(),
                            '%Y-%m-%dT%H:%M:%S.%f')

                        self.assertEquals(fake_session.audit.name,
                                          expected_name)
                        self.assertEquals(fake_session.audit.cid, expected_cid)
                        self.assertEquals(fake_session.audit.transport,
                                          expected_transport)
                        self.assertEquals(fake_session.audit.connection,
                                          expected_connection)
                        self.assertEquals(fake_session.audit.resp_time, None)
                        self.assertEquals(fake_session.audit.user_token,
                                          expected_username)
                        self.assertEquals(fake_session.audit.auth_ok, None)
                        self.assertEquals(fake_session.audit.invoke_ok, None)
                        self.assertEquals(fake_session.audit.remote_addr,
                                          expected_remote_addr)
                        self.assertEquals(
                            fake_session.audit.req_payload,
                            expected_request[:expected_audit_max_payload])
                        self.assertEquals(fake_session.audit.resp_headers,
                                          None)
                        self.assertEquals(fake_session.audit.resp_payload,
                                          None)

                        req_headers = literal_eval(
                            fake_session.audit.req_headers)

                        self.assertEquals(
                            req_headers[expected_remote_addr_header],
                            repr(expected_remote_addr))
                        self.assertEquals(req_headers['wsgi.url_scheme'],
                                          repr(expected_url_scheme))
                        self.assertEquals(req_headers['gunicorn.socket'],
                                          repr(FakeGunicornSocket(None, None)))

                        channel_item = literal_eval(
                            req_headers['zato.http.channel_item'])

                        self.assertEquals(channel_item['audit_max_payload'],
                                          expected_audit_max_payload)
                        self.assertEquals(channel_item['name'], expected_name)
                        self.assertEquals(channel_item['username'],
                                          expected_username)
                        self.assertEquals(
                            channel_item[expected_channel_item_key1],
                            expected_channel_item_value1)
                        self.assertEquals(channel_item['audit_repl_patt_type'],
                                          expected_audit_repl_patt_type)
                        self.assertEquals(
                            channel_item['replace_patterns_json_pointer'],
                            expected_replace_patterns_json_pointer)
                        self.assertEquals(channel_item['is_active'],
                                          expected_is_active)
                        self.assertEquals(channel_item['data_format'],
                                          expected_data_format)
                        self.assertEquals(channel_item['audit_enabled'],
                                          expected_audit_enabled)
                        self.assertEquals(channel_item['password'],
                                          expected_password)
                        self.assertEquals(channel_item['transport'],
                                          expected_transport)
                        self.assertEquals(channel_item['match_target'],
                                          expected_match_target)

                        #
                        # Audit 2/2 - Response
                        #

                        self.assertEquals(
                            bc.msg['action'], CHANNEL_BROKER_MESSAGE.
                            HTTP_SOAP_AUDIT_RESPONSE.value)
                        self.assertEquals(bc.msg['cid'], expected_cid)
                        self.assertEquals(bc.msg['data_format'],
                                          DATA_FORMAT.JSON)
                        self.assertEquals(
                            bc.msg['service'],
                            'zato.http-soap.set-audit-response-data')

                        payload = loads(bc.msg['payload'])

                        self.assertEquals(payload['auth_ok'], expected_auth_ok)
                        self.assertEquals(payload['invoke_ok'],
                                          expected_invoke_ok)
                        self.assertEquals(payload['resp_payload'],
                                          expected_payload)

                        # Parsing alone will check its format is valid
                        datetime.strptime(payload['resp_time'],
                                          '%Y-%m-%dT%H:%M:%S.%f')

                        wsgi_environ = loads(payload['resp_headers'])

                        self.assertEquals(wsgi_environ['wsgi.url_scheme'],
                                          repr(expected_url_scheme))
                        self.assertEquals(wsgi_environ['gunicorn.socket'],
                                          repr(FakeGunicornSocket(None, None)))
                        self.assertEquals(
                            wsgi_environ['zato.http.response.status'],
                            "'{} {}'".format(
                                expected_status_code,
                                httplib.responses[expected_status_code],
                            ))

                        channel_item = literal_eval(
                            wsgi_environ['zato.http.channel_item'])

                        self.assertEquals(
                            channel_item[expected_channel_item_key1],
                            expected_channel_item_value1)
                        self.assertEquals(channel_item['audit_enabled'],
                                          expected_audit_enabled)
                        self.assertEquals(channel_item['audit_repl_patt_type'],
                                          expected_audit_repl_patt_type)
                        self.assertEquals(
                            channel_item['replace_patterns_json_pointer'],
                            expected_replace_patterns_json_pointer)
                        self.assertEquals(
                            channel_item['replace_patterns_xpath'],
                            expected_replace_patterns_xpath)
                        self.assertEquals(channel_item['name'], expected_name)
                        self.assertEquals(channel_item['id'], expected_id)
                        self.assertEquals(channel_item['password'],
                                          expected_password)
                        self.assertEquals(channel_item['data_format'],
                                          expected_data_format)
                        self.assertEquals(channel_item['transport'],
                                          expected_transport)
                        self.assertEquals(channel_item['connection'],
                                          expected_connection)
                        self.assertEquals(channel_item['audit_max_payload'],
                                          expected_audit_max_payload)
                        self.assertEquals(channel_item['is_active'],
                                          expected_is_active)
                    else:
                        # Audit not enabled so no response audit message was published on the broker
                        self.assertTrue(bc.msg is None)
示例#59
0
 def get_response_data(self):
     return Bunch({'id': rand_int(), 'name': rand_string()})
示例#60
0
    def test_access_log(self):
        def _utcnow(self):
            return datetime(year=2014,
                            month=1,
                            day=12,
                            hour=16,
                            minute=22,
                            second=12,
                            tzinfo=UTC)

        local_tz = get_localzone()
        _now = _utcnow(None)

        local_dt = _now.replace(tzinfo=UTC).astimezone(local_tz)
        local_dt = local_tz.normalize(local_dt)

        request_timestamp = local_dt.strftime(ACCESS_LOG_DT_FORMAT)

        with patch('arrow.factory.ArrowFactory.utcnow', _utcnow):
            response = rand_string() * rand_int()
            cid = new_cid()
            cluster_id = 1

            channel_name = rand_string()
            url_path = '/{}'.format(rand_string())
            user_agent = rand_string()
            http_version = rand_string()
            request_method = rand_string()
            remote_ip = '10.{}.{}.{}'.format(rand_int(), rand_int(),
                                             rand_int())
            req_timestamp_utc = utcnow()

            channel_item = {
                'name': channel_name,
                'audit_enabled': False,
                'is_active': True,
                'transport': 'plain_http',
                'data_format': None,
                'match_target': url_path,
                'method': '',
            }

            wsgi_environ = {
                'gunicorn.socket': FakeGunicornSocket(None, None),
                'wsgi.url_scheme': 'http',
                'wsgi.input': StringIO(response),
                'zato.http.response.status': httplib.OK,
                'zato.http.channel_item': channel_item,
                'zato.request_timestamp_utc': req_timestamp_utc,
                'HTTP_X_FORWARDED_FOR': remote_ip,
                'PATH_INFO': url_path,
                'REQUEST_METHOD': request_method,
                'SERVER_PROTOCOL': http_version,
                'HTTP_USER_AGENT': user_agent,
            }

            class FakeBrokerClient(object):
                def __init__(self):
                    self.msg = None

                def publish(self, msg):
                    self.msg = msg

            class FakeODB(ODBManager):
                def __init__(self):
                    self.msg = None
                    self.cluster = Bunch(id=cluster_id)

            class FakeURLData(URLData):
                def __init__(self):
                    self.url_sec = {url_path: Bunch(sec_def=ZATO_NONE)}

                def match(self, *ignored_args, **ignored_kwargs):
                    return True, channel_item

            class FakeRequestHandler(object):
                def handle(self, *ignored_args, **ignored_kwargs):
                    return Bunch(payload=response,
                                 content_type='text/plain',
                                 headers={},
                                 status_code=httplib.OK)

            class FakeAccessLogger(object):
                def __init__(self):
                    self.extra = {}

                def info(self, msg, extra):
                    self.extra = extra

                def isEnabledFor(self, ignored):
                    return True

            bc = FakeBrokerClient()
            ws = FakeWorkerStore()
            ws.request_dispatcher = RequestDispatcher()
            ws.request_dispatcher.request_handler = FakeRequestHandler()
            ws.request_dispatcher.url_data = FakeURLData()
            ws.request_dispatcher.url_data.broker_client = bc
            ws.request_dispatcher.url_data.odb = FakeODB()

            ps = ParallelServer()
            ps.worker_store = ws
            ps.access_logger = FakeAccessLogger()
            ps.on_wsgi_request(wsgi_environ, StartResponse(), cid=cid)

            extra = Bunch(ps.access_logger.extra)

            eq_(extra.channel_name, channel_name)
            eq_(extra.user_agent, user_agent)
            eq_(extra.status_code, '200')
            eq_(extra.http_version, http_version)
            eq_(extra.response_size, len(response))
            eq_(extra.path, url_path)
            eq_(extra.cid_resp_time, '{}/0.0'.format(
                cid))  # It's 0.0 because we mock utcnow to be a constant value
            eq_(extra.method, request_method)
            eq_(extra.remote_ip, remote_ip)
            eq_(extra.req_timestamp_utc, '12/Jan/2014:16:22:12 +0000')
            eq_(extra.req_timestamp, request_timestamp)