Пример #1
0
    def test_explicit_mode(self):
        from .. import TransactionManager
        from ..interfaces import AlreadyInTransaction, NoTransaction

        tm = TransactionManager()
        self.assertFalse(tm.explicit)

        tm = TransactionManager(explicit=True)
        self.assertTrue(tm.explicit)
        for name in 'get', 'commit', 'abort', 'doom', 'isDoomed', 'savepoint':
            with self.assertRaises(NoTransaction):
                getattr(tm, name)()

        t = tm.begin()
        with self.assertRaises(AlreadyInTransaction):
            tm.begin()

        self.assertTrue(t is tm.get())

        self.assertFalse(tm.isDoomed())
        tm.doom()
        self.assertTrue(tm.isDoomed())
        tm.abort()

        for name in 'get', 'commit', 'abort', 'doom', 'isDoomed', 'savepoint':
            with self.assertRaises(NoTransaction):
                getattr(tm, name)()

        t = tm.begin()
        self.assertFalse(tm.isDoomed())
        with self.assertRaises(AlreadyInTransaction):
            tm.begin()
        tm.savepoint()
        tm.commit()
Пример #2
0
    def checkResolve(self, resolvable=True):
        db = DB(self._storage)

        t1 = TransactionManager()
        c1 = db.open(t1)
        o1 = c1.root()['p'] = (PCounter if resolvable else PCounter2)()
        o1.inc()
        t1.commit()

        t2 = TransactionManager()
        c2 = db.open(t2)
        o2 = c2.root()['p']
        o2.inc(2)
        t2.commit()

        o1.inc(3)
        try:
            t1.commit()
        except ConflictError as err:
            self.assertIn(".PCounter2,", str(err))
            self.assertEqual(o1._value, 3)
        else:
            self.assertTrue(resolvable, "Expected ConflictError")
            self.assertEqual(o1._value, 6)

        t2.begin()
        self.assertEqual(o2._value, o1._value)

        db.close()
Пример #3
0
    def test_endpoint_error(self):
        trManager = TransactionManager(timedelta(seconds=0), MAX_QUEUE_SIZE,
                                       timedelta(seconds=0), max_endpoint_errors=2)

        step = 10
        oneTrSize = (MAX_QUEUE_SIZE / step) - 1
        for i in xrange(step):
            trManager.append(memTransaction(oneTrSize, trManager))

        trManager.flush()

        # There should be exactly step transaction in the list,
        # and only 2 of them with a flush count of 1
        self.assertEqual(len(trManager._transactions), step)
        flush_count = 0
        for tr in trManager._transactions:
            flush_count += tr._flush_count
        self.assertEqual(flush_count, 2)

        # If we retry to flush, two OTHER transactions should be tried
        trManager.flush()

        self.assertEqual(len(trManager._transactions), step)
        flush_count = 0
        for tr in trManager._transactions:
            flush_count += tr._flush_count
            self.assertIn(tr._flush_count, [0, 1])
        self.assertEqual(flush_count, 4)

        # Finally when it's possible to flush, everything should go smoothly
        for tr in trManager._transactions:
            tr.is_flushable = True

        trManager.flush()
        self.assertEqual(len(trManager._transactions), 0)
    def testCustomEndpoint(self):
        MetricTransaction._endpoints = []

        config = {
            "dd_url": "https://foo.bar.com",
            "api_key": "foo",
            "use_dd": True
        }

        app = Application()
        app.skip_ssl_validation = False
        app._agentConfig = config
        app.use_simple_http_client = True

        trManager = TransactionManager(timedelta(seconds=0), MAX_QUEUE_SIZE,
                                       THROTTLING_DELAY)
        trManager._flush_without_ioloop = True  # Use blocking API to emulate tornado ioloop
        MetricTransaction._trManager = trManager
        MetricTransaction.set_application(app)
        MetricTransaction.set_endpoints()

        transaction = MetricTransaction(None, {}, "msgtype")
        endpoints = [transaction.get_url(e) for e in transaction._endpoints]
        expected = ['https://foo.bar.com/intake/msgtype?api_key=foo']
        self.assertEqual(endpoints, expected, (endpoints, expected))
Пример #5
0
    def test_proxy(self):
        config = {
            "endpoints": {"https://app.datadoghq.com": ["foo"]},
            "proxy_settings": {
                "host": "localhost",
                "port": PROXY_PORT,
                "user": None,
                "password": None
            }
        }

        app = Application()
        app.skip_ssl_validation = True
        app._agentConfig = config

        trManager = TransactionManager(MAX_WAIT_FOR_REPLAY, MAX_QUEUE_SIZE, THROTTLING_DELAY)
        trManager._flush_without_ioloop = True  # Use blocking API to emulate tornado ioloop
        CustomAgentTransaction.set_tr_manager(trManager)
        app.use_simple_http_client = False # We need proxy capabilities
        app.agent_dns_caching = False
        # _test is the instance of this class. It is needed to call the method stop() and deal with the asynchronous
        # calls as described here : http://www.tornadoweb.org/en/stable/testing.html
        CustomAgentTransaction._test = self
        CustomAgentTransaction.set_application(app)
        CustomAgentTransaction.set_endpoints(config['endpoints'])

        CustomAgentTransaction('body', {}, "") # Create and flush the transaction
        self.wait()
        del CustomAgentTransaction._test
        access_log = self.docker_client.exec_start(
            self.docker_client.exec_create(CONTAINER_NAME, 'cat /var/log/squid/access.log')['Id'])
        self.assertTrue("CONNECT" in access_log) # There should be an entry in the proxy access log
        self.assertEquals(len(trManager._endpoints_errors), 1) # There should be an error since we gave a bogus api_key
Пример #6
0
    def __init__(self,
                 port,
                 agentConfig,
                 watchmonitor=True,
                 skip_ssl_validation=False,
                 use_simple_http_client=False):
        self.ip = get_ip(agentConfig, log)
        self._port = int(port)
        self._agentConfig = agentConfig
        self._metrics = {}
        AgentTransaction.set_application(self)
        AgentTransaction.set_endpoints()
        self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY,
                                              MAX_QUEUE_SIZE, THROTTLING_DELAY)
        AgentTransaction.set_tr_manager(self._tr_manager)

        self._watchmonitor = None
        self.skip_ssl_validation = skip_ssl_validation or agentConfig.get(
            'skip_ssl_validation', False)
        self.use_simple_http_client = use_simple_http_client
        self._send_controler = 0  # control self.postAgentInfoToServer run once a minute
        if self.skip_ssl_validation:
            log.info(
                "Skipping SSL hostname validation, useful when using a transparent proxy"
            )

        if watchmonitor:
            watchmonitor_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHmonitor_INTERVAL_MULTIPLIER / 1000
            self._watchmonitor = Watchmonitor(watchmonitor_timeout,
                                              max_mem_mb=agentConfig.get(
                                                  'limit_memory_consumption',
                                                  None))
Пример #7
0
    def __init__(self,
                 port,
                 agentConfig,
                 watchdog=True,
                 skip_ssl_validation=False,
                 use_simple_http_client=False):
        self._port = int(port)
        self._agentConfig = agentConfig
        self._metrics = {}
        MetricTransaction.set_application(self)
        MetricTransaction.set_endpoints()
        self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY,
                                              MAX_QUEUE_SIZE, THROTTLING_DELAY)
        MetricTransaction.set_tr_manager(self._tr_manager)

        self._watchdog = None
        self.skip_ssl_validation = skip_ssl_validation or agentConfig.get(
            'skip_ssl_validation', False)
        self.use_simple_http_client = use_simple_http_client
        if self.skip_ssl_validation:
            log.info(
                "Skipping SSL hostname validation, useful when using a transparent proxy"
            )

        if watchdog:
            watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER
            self._watchdog = Watchdog(watchdog_timeout,
                                      max_mem_mb=agentConfig.get(
                                          'limit_memory_consumption', None))
Пример #8
0
    def testCustomEndpoint(self):
        MetricTransaction._endpoints = []

        config = {
            "endpoints": {
                "https://foo.bar.com": ["foo"]
            },
            "dd_url": "https://foo.bar.com",
            "api_key": "foo",
            "use_dd": True
        }

        app = Application()
        app.skip_ssl_validation = False
        app.agent_dns_caching = False
        app._agentConfig = config
        app.use_simple_http_client = True

        trManager = TransactionManager(timedelta(seconds=0),
                                       MAX_QUEUE_SIZE,
                                       THROTTLING_DELAY,
                                       max_endpoint_errors=100)
        trManager._flush_without_ioloop = True  # Use blocking API to emulate tornado ioloop
        MetricTransaction._trManager = trManager
        MetricTransaction.set_application(app)
        MetricTransaction.set_endpoints(config['endpoints'])

        transaction = MetricTransaction(None, {}, "msgtype")
        endpoints = []
        for endpoint in transaction._endpoints:
            for api_key in transaction._endpoints[endpoint]:
                endpoints.append(transaction.get_url(endpoint, api_key))
        expected = ['https://foo.bar.com/intake/msgtype?api_key=foo']
        self.assertEqual(endpoints, expected, (endpoints, expected))
Пример #9
0
    def test_multiple_endpoints(self):
        config = {
            "endpoints": {
                "https://app.datadoghq.com": ['api_key'],
                "https://app.example.com": ['api_key']
            },
            "dd_url": "https://app.datadoghq.com",
            "api_key": 'api_key',
            "use_dd": True
        }
        app = Application()
        app.skip_ssl_validation = False
        app._agentConfig = config
        app.use_simple_http_client = True
        trManager = TransactionManager(timedelta(seconds=0),
                                       MAX_QUEUE_SIZE,
                                       THROTTLING_DELAY,
                                       max_endpoint_errors=100)
        trManager._flush_without_ioloop = True  # Use blocking API to emulate tornado ioloop
        MetricTransaction._trManager = trManager
        MetricTransaction.set_application(app)
        MetricTransaction.set_endpoints(config['endpoints'])

        MetricTransaction({}, {})
        # 2 endpoints = 2 transactions
        self.assertEqual(len(trManager._transactions), 2)
        self.assertEqual(trManager._transactions[0]._endpoint,
                         'https://app.datadoghq.com')
        self.assertEqual(trManager._transactions[1]._endpoint,
                         'https://app.example.com')
Пример #10
0
def make_routable_request(dbsession: Optional[Session],
                          registry: Registry,
                          path="/") -> IRequest:
    """Creates a dummy request that has route_url and other routing methods.

    As this request does not get HTTP hostname and such stuff from WSGI environment, a configuration variable ``websauna.site_url`` is passed as the base URL.

    See also :func:`make_dummy_request`.

    :param dbsession: Use existing dbsession or set to ``None`` to generate a new dbsession and transaction manager. None that this TM is not the thread local transaction manager in ``transaction.mananger``.
    """

    base_url = registry.get("websauna.site_url", None)

    # TODO: Honour request_factory here
    request = Request.blank(path, base_url=base_url)
    # apply_request_extensions()?
    request.registry = registry
    request.user = None

    if dbsession:
        request.dbsession = dbsession
    else:
        tm = TransactionManager()
        dbsession = create_dbsession(request.registry, tm)
        request.dbsession = dbsession
        request.tm = request.transaction_manager = tm

        def terminate_session(request):
            # Close db session at the end of the request and return the db connection back to the pool
            dbsession.close()

        request.add_finished_callback(terminate_session)

    return request
Пример #11
0
 def exec_eager(self, *args, **kwargs):
     """Run transaction aware task in eager mode."""
     # We are run in a post-commit hook, so there is no transaction manager available
     tm = TransactionManager()
     # Do not attempt any transaction retries in eager mode
     tm.retry_attempt_count = 1
     self.request.update(request=self.make_faux_request(tm=tm))
     return self.run(*args, **kwargs)
Пример #12
0
    def exec_eager(self, *args, **kwargs):
        """Run transaction aware task in eager mode."""

        # We are run in a post-commit hook, so there is no transaction manager available
        tm = TransactionManager()

        self.request.update(request=self.make_faux_request(
            transaction_manager=tm))
        return self.run(*args, **kwargs)
Пример #13
0
def update_schema_manager(event):
    # Use a local transaction manager to sidestep any issues
    # with an active transaction or explicit mode.
    txm = TransactionManager(explicit=True)
    txm.begin()
    with contextlib.closing(event.database.open(txm)) as conn:
        state = conn.root().get(PersistentWebhookSchemaManager.key, State())
        txm.abort()

    schema = get_schema_manager()
    schema.compareSubscriptionsAndComputeGeneration(state)
Пример #14
0
    def exec_eager(self, *args, **kwargs):
        """Run transaction aware task in eager mode."""

        # We are run in a post-commit hook, so there is no transaction manager available
        tm = TransactionManager()
        self.request.update(request=self.make_faux_request(
            transaction_manager=tm))

        with tm:
            # This doesn't do transaction retry attempts, but should be good enough for eager
            return self.run(*args, **kwargs)
Пример #15
0
class Replica(ServiceBase):
    
    transaction_manager = TransactionManager()

    @rpc(String)
    def set_server(ctx, server):
        logging.info(' set_server()')
        Replica.transaction_manager.set_server(server)

    @rpc(String)
    def add_replica(ctx, replica):
        logging.info(' add_replica()')
        Replica.transaction_manager.add_replica(replica)

    @srpc(String, _returns=Boolean)    
    def tpc_vote_replica(msg):
        logging.info(' tpc_vote_replica()')
        return Replica.transaction_manager.tpc_vote_replica(msg)

    @srpc(String, _returns=Boolean)
    def tpc_commit_replica(msg,):
        logging.info(' tpc_commit_replica()')
        return Replica.transaction_manager.tpc_commit_replica(msg)

    @srpc(String, _returns=Boolean)
    def tpc_abort_replica(msg):
        logging.info(' tpc_abort_replica()')
        return Replica.transaction_manager.tpc_abort_replica(msg)
    
    @rpc(String)
    def tpc_ack(ctx, msg):
        logging.info(' tpc_ack()')
        Replica.transaction_manager.tpc_ack(msg)

    @rpc(String, String)
    def put(ctx, key, value):
        logging.info(' put()')
        return Replica.transaction_manager.put(key, value)

    @srpc(String, _returns=Boolean)      
    def delete(key):
        logging.info(' delete()')
        return Replica.transaction_manager.delete(key)

    @srpc(String, _returns=String)
    def get(key):
        logging.info(' get()')
        return Replica.transaction_manager.get(key)
    
    @srpc(String, _returns=String)
    def get_value_replica(key):
        logging.info(' get_value_replica()')
        return Replica.transaction_manager.get_value_replica(key)
Пример #16
0
    def testEndpoints(self):
        """Tests that the logic behind the agent version specific endpoints is ok.
        Also tests that these endpoints actually exist.
        """
        MetricTransaction._endpoints = []

        config = {
            "dd_url": "https://app.datadoghq.com",
            "api_key": "foo",
            "use_dd": True
        }

        app = Application()
        app.skip_ssl_validation = False
        app._agentConfig = config
        app.use_simple_http_client = True

        trManager = TransactionManager(timedelta(seconds=0), MAX_QUEUE_SIZE,
                                       THROTTLING_DELAY)
        trManager._flush_without_ioloop = True  # Use blocking API to emulate tornado ioloop
        MetricTransaction._trManager = trManager
        MetricTransaction.set_application(app)
        MetricTransaction.set_endpoints()

        transaction = MetricTransaction(None, {})
        endpoints = [transaction.get_url(e) for e in transaction._endpoints]
        expected = [
            'https://{0}-app.agent.datadoghq.com/intake?api_key=foo'.format(
                get_version().replace(".", "-"))
        ]
        self.assertEqual(endpoints, expected, (endpoints, expected))

        for url in endpoints:
            r = requests.post(url,
                              data=json.dumps({"foo": "bar"}),
                              headers={'Content-Type': "application/json"})
            r.raise_for_status()

        transaction = APIMetricTransaction(None, {})
        endpoints = [transaction.get_url(e) for e in transaction._endpoints]
        expected = [
            'https://{0}-app.agent.datadoghq.com/api/v1/series/?api_key=foo'.
            format(get_version().replace(".", "-"))
        ]
        self.assertEqual(endpoints, expected, (endpoints, expected))

        for url in endpoints:
            r = requests.post(url,
                              data=json.dumps({"foo": "bar"}),
                              headers={'Content-Type': "application/json"})
            r.raise_for_status()
Пример #17
0
    def __init__(self, port, agentConfig, watchdog=True):
        self._port = int(port)
        self._agentConfig = agentConfig
        self._metrics = {}
        MetricTransaction.set_application(self)
        MetricTransaction.set_endpoints()
        self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY,
                                              MAX_QUEUE_SIZE, THROTTLING_DELAY)
        MetricTransaction.set_tr_manager(self._tr_manager)

        self._watchdog = None
        if watchdog:
            watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER
            self._watchdog = Watchdog(watchdog_timeout)
Пример #18
0
    def __init__(self,
                 port,
                 agentConfig,
                 watchdog=True,
                 skip_ssl_validation=False,
                 use_simple_http_client=False):
        self._port = int(port)
        self._agentConfig = agentConfig
        self._metrics = {}
        self._dns_cache = None
        AgentTransaction.set_application(self)
        AgentTransaction.set_endpoints(agentConfig['endpoints'])
        if agentConfig['endpoints'] == {}:
            log.warning(
                u"No valid endpoint found. Forwarder will drop all incoming payloads."
            )
        AgentTransaction.set_request_timeout(agentConfig['forwarder_timeout'])

        max_parallelism = self.NO_PARALLELISM
        # Multiple endpoints => enable parallelism
        if len(agentConfig['endpoints']) > 1:
            max_parallelism = self.DEFAULT_PARALLELISM

        self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY,
                                              MAX_QUEUE_SIZE,
                                              THROTTLING_DELAY,
                                              max_parallelism=max_parallelism)
        AgentTransaction.set_tr_manager(self._tr_manager)

        self._watchdog = None
        self.skip_ssl_validation = skip_ssl_validation or _is_affirmative(
            agentConfig.get('skip_ssl_validation'))
        self.agent_dns_caching = _is_affirmative(
            agentConfig.get('dns_caching'))
        self.agent_dns_ttl = int(agentConfig.get('dns_ttl', DEFAULT_DNS_TTL))
        if self.agent_dns_caching:
            self._dns_cache = DNSCache(ttl=self.agent_dns_ttl)
        self.use_simple_http_client = use_simple_http_client
        if self.skip_ssl_validation:
            log.info(
                "Skipping SSL hostname validation, useful when using a transparent proxy"
            )

        # Monitor activity
        if watchdog:
            watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER / 1000
            self._watchdog = Watchdog.create(
                watchdog_timeout, max_resets=WATCHDOG_HIGH_ACTIVITY_THRESHOLD)
Пример #19
0
 def test_no_parallelism(self):
     step = 2
     trManager = TransactionManager(timedelta(seconds=0),
                                    MAX_QUEUE_SIZE,
                                    timedelta(seconds=0),
                                    max_parallelism=1,
                                    max_endpoint_errors=100)
     for i in xrange(step):
         trManager.append(SleepingTransaction(trManager, delay=1))
     trManager.flush()
     # Flushes should be sequential
     for i in xrange(step):
         self.assertEqual(trManager._running_flushes, 1)
         self.assertEqual(trManager._finished_flushes, i)
         self.assertEqual(len(trManager._trs_to_flush), step - (i + 1))
         time.sleep(1)
Пример #20
0
    def test_drop_repeated_error(self):
        trManager = TransactionManager(timedelta(seconds=0),
                                       MAX_QUEUE_SIZE,
                                       timedelta(seconds=0),
                                       max_endpoint_errors=1)

        # Fail it once
        oneTrSize = 10
        trManager.append(memTransaction(oneTrSize, trManager))

        # It should still be there after flush
        trManager.flush()
        self.assertEqual(len(trManager._transactions), 1)

        #Try again, now it should be gone
        trManager.flush()
        self.assertEqual(len(trManager._transactions), 0)
Пример #21
0
def make_routable_request(dbsession: t.Optional[Session] = None,
                          registry: t.Optional[Registry] = None,
                          path='/') -> IRequest:
    """Creates a dummy request that has route_url and other routing methods.

    As this request does not get HTTP hostname and such stuff from WSGI environment, a configuration variable ``websauna.site_url`` is passed as the base URL.

    See also :func:`make_dummy_request`.

    TODO: Split this to two different functions: one for existing dbsession and one for where dbsession is connected.

    :param dbsession: Use existing dbsession or set to ``None`` to generate a new dbsession and transaction manager. None that this TM is not the thread local transaction manager in ``transaction.mananger``.
    :param registry: Configuration registry
    :param path: Path being requested.
    :return: Current request.
    """
    base_url = registry.settings.get("websauna.site_url", None)
    # TODO: Honour request_factory here
    request = Request.blank(path, base_url=base_url)
    request.registry = registry
    request.user = None
    request.view_name = ''

    # This will create request.tm, others
    apply_request_extensions(request)

    if dbsession:
        # Use the provided dbsession for this request
        request.dbsession = dbsession
        if hasattr(dbsession, "transaction_manager"):
            request.tm = request.transaction_manager = dbsession.transaction_manager
    else:
        # Create a new dbsession and transaction manager for this request
        tm = TransactionManager()
        dbsession = create_dbsession(request.registry, tm)
        request.dbsession = dbsession
        request.tm = request.transaction_manager = tm

        def terminate_session(request):
            # Close db session at the end of the request and return the db connection back to the pool
            dbsession.close()

        request.add_finished_callback(terminate_session)

    return request
Пример #22
0
    def testThrottling(self):
        """Test throttling while flushing"""
 
        # No throttling, no delay for replay
        trManager = TransactionManager(timedelta(seconds = 0), MAX_QUEUE_SIZE, THROTTLING_DELAY)
        trManager._flush_without_ioloop = True # Use blocking API to emulate tornado ioloop

        # Add 3 transactions, make sure no memory limit is in the way
        oneTrSize = MAX_QUEUE_SIZE / 10
        for i in xrange(3):
            tr = memTransaction(oneTrSize, trManager)
            trManager.append(tr)

        # Try to flush them, time it
        before = datetime.now()
        trManager.flush()
        after = datetime.now()
        self.assertTrue( (after-before) > 3 * THROTTLING_DELAY)
    def testMemoryLimit(self):
        """Test memory limit as well as simple flush"""

        # No throttling, no delay for replay
        trManager = TransactionManager(timedelta(seconds=0), MAX_QUEUE_SIZE,
                                       timedelta(seconds=0))

        step = 10
        oneTrSize = (MAX_QUEUE_SIZE / step) - 1
        for i in xrange(step):
            tr = memTransaction(oneTrSize, trManager)
            trManager.append(tr)

        trManager.flush()

        # There should be exactly step transaction in the list, with
        # a flush count of 1
        self.assertEqual(len(trManager._transactions), step)
        for tr in trManager._transactions:
            self.assertEqual(tr._flush_count, 1)

        # Try to add one more
        tr = memTransaction(oneTrSize + 10, trManager)
        trManager.append(tr)

        # At this point, transaction one (the oldest) should have been removed from the list
        self.assertEqual(len(trManager._transactions), step)
        for tr in trManager._transactions:
            self.assertNotEqual(tr._id, 1)

        trManager.flush()
        self.assertEqual(len(trManager._transactions), step)
        # Check and allow transactions to be flushed
        for tr in trManager._transactions:
            tr.is_flushable = True
            # Last transaction has been flushed only once
            if tr._id == step + 1:
                self.assertEqual(tr._flush_count, 1)
            else:
                self.assertEqual(tr._flush_count, 2)

        trManager.flush()
        self.assertEqual(len(trManager._transactions), 0)
Пример #24
0
    def test_parallelism(self):
        step = 4
        trManager = TransactionManager(timedelta(seconds=0), MAX_QUEUE_SIZE,
                                       timedelta(seconds=0), max_parallelism=step,
                                       max_endpoint_errors=100)
        for i in xrange(step):
            trManager.append(SleepingTransaction(trManager))

        trManager.flush()
        self.assertEqual(trManager._running_flushes, step)
        self.assertEqual(trManager._finished_flushes, 0)
        # If _trs_to_flush != None, it means that it's still running as it should be
        self.assertEqual(trManager._trs_to_flush, [])
        time.sleep(1)

        # It should be finished
        self.assertEqual(trManager._running_flushes, 0)
        self.assertEqual(trManager._finished_flushes, step)
        self.assertIs(trManager._trs_to_flush, None)
Пример #25
0
    def __init__(self, cache_backend=None, keyhandler=None, keygen=None):
        self.__dict__ = self.__shared_state
        self.prefix = settings.MIDDLEWARE_KEY_PREFIX
        if keyhandler:
            self.kh_class = keyhandler
        if keygen:
            self.kg_class = keygen
        if not cache_backend and not hasattr(self, 'cache_backend'):
            cache_backend = settings._get_backend()

        if not keygen and not hasattr(self, 'kg_class'):
            self.kg_class = KeyGen
        if keyhandler is None and not hasattr(self, 'kh_class'):
            self.kh_class = KeyHandler

        if cache_backend:
            self.cache_backend = TransactionManager(cache_backend,
                                                    self.kg_class)
            self.keyhandler = self.kh_class(self.cache_backend, self.kg_class,
                                            self.prefix)
        self._patched = getattr(self, '_patched', False)
Пример #26
0
    def test_notify_transaction_late_comers(self):
        # If a datamanager registers for synchonization after a
        # transaction has started, we should call newTransaction so it
        # can do necessry setup.
        import mock
        from .. import TransactionManager
        manager = TransactionManager()
        sync1 = mock.MagicMock()
        manager.registerSynch(sync1)
        sync1.newTransaction.assert_not_called()
        t = manager.begin()
        sync1.newTransaction.assert_called_with(t)
        sync2 = mock.MagicMock()
        manager.registerSynch(sync2)
        sync2.newTransaction.assert_called_with(t)

        # for, um, completeness
        t.commit()
        for s in sync1, sync2:
            s.beforeCompletion.assert_called_with(t)
            s.afterCompletion.assert_called_with(t)
Пример #27
0
    def __init__(self,
                 port,
                 agentConfig,
                 watchdog=True,
                 skip_ssl_validation=False,
                 use_simple_http_client=False):
        self._port = int(port)
        self._agentConfig = agentConfig
        self._metrics = {}
        AgentTransaction.set_application(self)
        AgentTransaction.set_endpoints(agentConfig['endpoints'])
        AgentTransaction.set_request_timeout(agentConfig['forwarder_timeout'])

        max_parallelism = self.NO_PARALLELISM
        # Multiple endpoints => enable parallelism
        if len(agentConfig['endpoints']) > 1:
            max_parallelism = self.DEFAULT_PARALLELISM

        self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY,
                                              MAX_QUEUE_SIZE,
                                              THROTTLING_DELAY,
                                              max_parallelism=max_parallelism)
        AgentTransaction.set_tr_manager(self._tr_manager)

        self._watchdog = None
        self.skip_ssl_validation = skip_ssl_validation or agentConfig.get(
            'skip_ssl_validation', False)
        self.use_simple_http_client = use_simple_http_client
        if self.skip_ssl_validation:
            log.info(
                "Skipping SSL hostname validation, useful when using a transparent proxy"
            )

        # Monitor activity
        if watchdog:
            watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER / 1000
            self._watchdog = Watchdog(
                watchdog_timeout,
                max_mem_mb=agentConfig.get('limit_memory_consumption', None),
                max_resets=WATCHDOG_HIGH_ACTIVITY_THRESHOLD)
Пример #28
0
def get_tm():
    if 'tm' not in g:
        if debug:
            print('creating transactionmanager')
        g.tm = TransactionManager()
    return g.tm
Пример #29
0
    def testEndpoints(self):
        """
        Tests that the logic behind the agent version specific endpoints is ok.
        Also tests that these endpoints actually exist.
        """
        raise SkipTest("This test doesn't apply to Server Density.")
        MetricTransaction._endpoints = []
        api_key = "a" * 32
        config = {
            "sd_url": "https://agent.serverdensity.io",
            "api_key": api_key,
            "use_sd": True
        }

        app = Application()
        app.skip_ssl_validation = False
        app.agent_dns_caching = False
        app._agentConfig = config
        app.use_simple_http_client = True

        trManager = TransactionManager(timedelta(seconds=0),
                                       MAX_QUEUE_SIZE,
                                       THROTTLING_DELAY,
                                       max_endpoint_errors=100)
        trManager._flush_without_ioloop = True  # Use blocking API to emulate tornado ioloop
        MetricTransaction._trManager = trManager
        MetricTransaction.set_application(app)
        MetricTransaction.set_endpoints(config['endpoints'])

        transaction = MetricTransaction(None, {}, "")
        endpoints = []
        for endpoint in transaction._endpoints:
            for api_key in transaction._endpoints[endpoint]:
                endpoints.append(transaction.get_url(endpoint, api_key))
        expected = [
            'https://{0}-app.agent.datadoghq.com/intake/?api_key={1}'.format(
                get_version().replace(".", "-"), api_key)
        ]
        self.assertEqual(endpoints, expected, (endpoints, expected))

        for url in endpoints:
            r = requests.post(url,
                              data=json.dumps({"foo": "bar"}),
                              headers={'Content-Type': "application/json"})
            r.raise_for_status()

        # API Metric Transaction
        transaction = APIMetricTransaction(None, {})
        endpoints = []
        for endpoint in transaction._endpoints:
            for api_key in transaction._endpoints[endpoint]:
                endpoints.append(transaction.get_url(endpoint, api_key))
        expected = [
            'https://{0}-app.agent.datadoghq.com/api/v1/series/?api_key={1}'.
            format(get_version().replace(".", "-"), api_key)
        ]
        self.assertEqual(endpoints, expected, (endpoints, expected))

        for url in endpoints:
            try:
                r = requests.post(url,
                                  data=json.dumps({"foo": "bar"}),
                                  headers={'Content-Type': "application/json"})
                r.raise_for_status()
            except requests.HTTPError:
                if r.status_code != 400 or 'No series present in the payload' not in r.content:
                    raise

        # API Service Check Transaction
        APIServiceCheckTransaction._trManager = trManager
        APIServiceCheckTransaction.set_application(app)
        APIServiceCheckTransaction.set_endpoints(config['endpoints'])

        transaction = APIServiceCheckTransaction(None, {})
        endpoints = []
        for endpoint in transaction._endpoints:
            for api_key in transaction._endpoints[endpoint]:
                endpoints.append(transaction.get_url(endpoint, api_key))
        expected = [
            'https://{0}-app.agent.datadoghq.com/api/v1/check_run/?api_key={1}'
            .format(get_version().replace(".", "-"), api_key)
        ]
        self.assertEqual(endpoints, expected, (endpoints, expected))

        for url in endpoints:
            r = requests.post(url,
                              data=json.dumps({
                                  'check': 'test',
                                  'status': 0
                              }),
                              headers={'Content-Type': "application/json"})
            r.raise_for_status()
Пример #30
0
 def __init__(self, *args, **kwargs):
     self.made_seekable = 0
     self.tm = TransactionManager()
     super(DummyRequest, self).__init__(self, *args, **kwargs)