Beispiel #1
0
async def test_prepare(loop, postgres_url):
    app = BaseApplication(BaseConfig())
    app.add(
        'db',
        Postgres(
            PostgresConfig(url=postgres_url, log_result=True, log_query=True)),
    )
    await app.start()
    db: Postgres = app.get('db')  # type: ignore

    async with db.connection() as conn:
        st = await conn.prepare('SELECT $1::int as a', query_name='db4')
        row = await st.query_one(10)
        assert row['a'] == 10

        rows = await st.query_all(20)
        assert len(rows) == 1
        assert rows[0]['a'] == 20

        st2 = await conn.prepare('SELECT $1::text as a')
        row = await st2.query_one('30')
        assert row['a'] == '30'

        rows = await st2.query_all('30')
        assert len(rows) == 1
        assert rows[0]['a'] == '30'
Beispiel #2
0
async def create_lock(url: Optional[str]) -> Lock:
    app = BaseApplication(BaseConfig())
    app.add(
        'lock',
        Lock(LockConfig(url=url)),
    )
    await app.start()
    lock: Lock = app.get('lock')  # type: ignore
    return lock
Beispiel #3
0
async def test_sftp(loop) -> None:
    app = BaseApplication(BaseConfig())
    app.add(
        "sftp",
        SftpClient(
            SftpClientConfig(
                url="sftp://*****:*****@localhost:2222/upload")),
    )
    await app.start()

    sftp: SftpClient = app.get("sftp")  # type: ignore
    test_data = "Test data"

    base_remote_path = await sftp.getcwd()
    assert base_remote_path == "/upload"

    remote_path = os.path.join(base_remote_path, str(uuid.uuid4()))
    await sftp.mkdir(remote_path)
    await sftp.chdir(remote_path)

    with TemporaryDirectory() as local_path:
        local_file_out = os.path.join(local_path, f"{uuid.uuid4()}_out.txt")
        local_file_ren = os.path.join(local_path, f"{uuid.uuid4()}_ren.txt")
        local_file_in = os.path.join(local_path, f"{uuid.uuid4()}_in.txt")
        with open(local_file_out, "w") as f:
            f.write(test_data)

        remote_file_out = os.path.join(remote_path,
                                       os.path.basename(local_file_out))

        remote_file_ren = os.path.join(remote_path,
                                       os.path.basename(local_file_ren))

        await sftp.put(local_file_out, remote_file_out)
        assert await sftp.exists(remote_file_out) is True
        assert os.path.basename(local_file_out) in await sftp.listdir(
            remote_path)

        await sftp.get(remote_file_out, local_file_in)
        with open(local_file_in) as f:
            assert f.read() == test_data

        await sftp.rename(remote_file_out, remote_file_ren)
        assert await sftp.exists(remote_file_ren) is True
        assert os.path.basename(remote_file_ren) in [
            path.filename for path in await sftp.readdir(remote_path)
        ]

        await sftp.remove(remote_file_ren)
        assert await sftp.exists(remote_file_ren) is False
        assert os.path.basename(remote_file_ren) not in await sftp.listdir(
            remote_path)

    await app.stop()
Beispiel #4
0
async def s3() -> AsyncGenerator[S3, None]:
    s3 = S3(
        S3Config(
            endpoint_url='http://127.0.0.1:9000',
            aws_access_key_id='EXAMPLEACCESSKEY',
            aws_secret_access_key='EXAMPLESECRETKEY',
        ))
    app = BaseApplication(BaseConfig())
    app.add('s3', s3)

    await app.start()
    yield s3
    await app.stop()
Beispiel #5
0
async def startup() -> [BaseApplication, Oracle]:
    app = BaseApplication(BaseConfig())
    app.add(
        'db',
        Oracle(
            OracleConfig(
                user=oracle_user,
                password=oracle_pwd,
                dsn=oracle_host,
            )),
    )
    await app.start()
    db: Oracle = app.get('db')  # type: ignore
    return app, db
Beispiel #6
0
async def test_success(loop):
    async with SentryServer() as ss:
        cfg = SentryConfig(dsn=ss.addr)
        adapter = SentryAdapter(cfg)
        app = BaseApplication(BaseConfig())
        app.logger.add(adapter)
        lgr = app.logger
        await lgr.start()

        with lgr.span_new(name='t1', kind=Span.KIND_SERVER) as span:
            span.tag('tag', 'abc')
            span.annotate('k1', 'val1', ts=123456)

            with pytest.raises(Exception):
                with span.new_child('t2', Span.KIND_CLIENT):
                    raise Exception('bla bla')

        await lgr.stop()

        assert len(ss.errors) == 1
        err = ss.errors[0]

        assert err['level'] == 'error', str(err)
        assert 'exception' in err, str(err)
        assert 'event_id' in err, str(err)
        assert 'timestamp' in err, str(err)
        assert 'breadcrumbs' in err, str(err)
        assert 'contexts' in err, str(err)
        assert 'platform' in err, str(err)

        assert err['exception']['values'][0]['type'] == 'Exception', str(err)
        assert err['exception']['values'][0]['value'] == 'bla bla', str(err)
Beispiel #7
0
async def test_statement_cache_size(loop, postgres_url):
    app = BaseApplication(BaseConfig())
    app.add(
        'db',
        Postgres(
            PostgresConfig(
                url=postgres_url,
                log_result=True,
                log_query=True,
                statement_cache_size=0,
            )),
    )
    await app.start()
    db: Postgres = app.get('db')  # type: ignore
    async with db.connection() as conn:
        assert conn._conn._stmt_cache._max_size == 0
    await app.stop()
Beispiel #8
0
async def test_pika(loop, rabbitmq_url):

    messages: List[Tuple[bytes]] = []

    class TestPubChg(PikaChannel):
        name = 'pub'

    class TestCnsChg(PikaChannel):
        name = 'sub'

        async def prepare(self) -> None:
            await self.exchange_declare('myexchange', durable=False)
            await self.queue_declare('myqueue', durable=False)
            await self.queue_bind('myqueue', 'myexchange', '')
            await self.qos(prefetch_count=1)

        async def start(self) -> None:
            await self.consume('myqueue', self.message)

        async def message(
            self, body: bytes, deliver: Deliver, proprties: Properties
        ) -> None:
            await self.ack(delivery_tag=deliver.delivery_tag)
            messages.append((body,))

    app = BaseApplication(BaseConfig())
    app.add(
        'mq',
        Pika(
            PikaConfig(url=rabbitmq_url),
            [
                lambda: TestPubChg(PikaChannelConfig()),
                lambda: TestCnsChg(PikaChannelConfig()),
            ],
        ),
    )
    await app.start()
    mq: Pika = app.get('mq')  # type: ignore

    await mq.channel('pub').publish('myexchange', '', 'testmsg')

    await wait_for(lambda: len(messages) > 0)
    assert messages == [(b'testmsg',)]

    await app.stop()
Beispiel #9
0
async def test_span_from_hdrs_new_2():
    app = BaseApplication(BaseConfig())
    lgr = app.logger

    with lgr.span_from_headers(None) as span:
        assert span.trace_id is not None
        assert span.id is not None
        assert span.parent_id is None
        assert not span._skip
Beispiel #10
0
async def test_zipkin_trace_id_size_settings(
    loop, use_64bit_trace_id: bool, trace_id_string_length: int
):
    app = BaseApplication(BaseConfig())
    lgr = app.logger
    cfg = ZipkinConfig(name='123', use_64bit_trace_id=use_64bit_trace_id)
    lgr.add(ZipkinAdapter(cfg))
    with lgr.span_new(name='test_span') as span:
        assert len(span.trace_id) == trace_id_string_length
Beispiel #11
0
async def test_span_from_hdrs_1():
    app = BaseApplication(BaseConfig())
    lgr = app.logger

    hdrs = {'X-B3-TraceId': 'f3d33b325b9458f1a18de5f226ea54d8'}
    with lgr.span_from_headers(hdrs) as span:
        assert span.trace_id == 'f3d33b325b9458f1a18de5f226ea54d8'
        assert span.id is not None
        assert span.parent_id is None
        assert not span._skip
Beispiel #12
0
async def test_span_ctx():
    app = BaseApplication(BaseConfig())
    lgr = app.logger

    assert ctx_span_get() is None
    with lgr.span_new() as span1:
        assert ctx_span_get() is span1
        with span1.new_child() as span2:
            assert ctx_span_get() is span2
        assert ctx_span_get() is span1
    assert ctx_span_get() is None
Beispiel #13
0
async def test_span_from_hdrs_2():
    app = BaseApplication(BaseConfig())
    lgr = app.logger

    hdrs = {'X-B3-TraceId': ''}
    with lgr.span_from_headers(hdrs) as span:
        assert span.trace_id is not None
        assert span.trace_id != ''
        assert span.id is not None
        assert span.parent_id is None
        assert not span._skip
Beispiel #14
0
async def test_errors(loop, ):
    app = BaseApplication(BaseConfig())
    lgr = app.logger
    cfg = ZipkinConfig(name='123')
    adapter = ZipkinAdapter(cfg)

    with pytest.raises(AdapterConfigurationError):
        adapter.handle(lgr.span_new())

    with pytest.raises(AdapterConfigurationError):
        await adapter.stop()
Beispiel #15
0
async def test_base(loop, postgres_url):
    app = BaseApplication(BaseConfig())
    app.add(
        'db',
        Postgres(
            PostgresConfig(url=postgres_url, log_result=True, log_query=True)),
    )
    await app.start()
    db: Postgres = app.get('db')  # type: ignore

    res = await db.execute('SELECT $1::int as a', 10, query_name='db1')
    assert 'SELECT 1' == res

    res = await db.query_one('SELECT $1::int as a', 10, query_name='db2')
    assert isinstance(res, asyncpg.Record)
    assert res['a'] == 10

    # json
    res = await db.query_one('SELECT $1::json as a', {'a': 1})
    assert isinstance(res, asyncpg.Record)
    assert res['a'] == {'a': 1}

    # jsonb
    res = await db.query_one('SELECT $1::jsonb as a', {'a': 1})
    assert isinstance(res, asyncpg.Record)
    assert res['a'] == {'a': 1}

    res = await db.query_one('SELECT 1 as a WHERE FALSE')
    assert res is None

    res = await db.query_all('SELECT $1::int as a', 10, query_name='db3')
    assert isinstance(res, list)
    assert len(res) == 1
    assert isinstance(res[0], asyncpg.Record)
    assert res[0]['a'] == 10

    res = await db.query_all('SELECT 1 as a WHERE FALSE')
    assert isinstance(res, list)
    assert len(res) == 0

    await app.stop()
Beispiel #16
0
async def test_xact(loop, postgres_url):
    app = BaseApplication(BaseConfig())
    app.add(
        'db',
        Postgres(
            PostgresConfig(url=postgres_url, log_result=True, log_query=True)),
    )
    await app.start()
    db: Postgres = app.get('db')  # type: ignore

    async with db.connection() as conn:
        await conn.execute('CREATE TEMPORARY TABLE _test_xact(id int)')
        try:
            async with conn.xact():
                await conn.execute('INSERT INTO _test_xact(id) VALUES (12)')
                r = await conn.query_one('SELECT COUNT(*) c FROM _test_xact')
                assert r['c'] == 1
                raise Exception('rollback')
        except Exception as err:
            assert str(err) == 'rollback', err

        r = await conn.query_one('SELECT COUNT(*) c FROM _test_xact')
        assert r['c'] == 0
Beispiel #17
0
async def test_span_from_hdrs_skippable():
    app = BaseApplication(BaseConfig())
    lgr = app.logger

    hdrs = {
        'X-B3-TraceId': 'f3d33b325b9458f1a18de5f226ea54d8',
        'X-B3-SpanId': 'ed8753e2153a20df',
        'X-B3-Sampled': '0',
    }

    with lgr.span_from_headers(hdrs) as span:
        assert span.trace_id == 'f3d33b325b9458f1a18de5f226ea54d8'
        assert span.id is not None
        assert span.parent_id == 'ed8753e2153a20df'
        assert span._skip
Beispiel #18
0
async def test_success(loop, unused_tcp_port):
    port = unused_tcp_port

    cfg = PrometheusConfig(
        port=port,
        hist_labels={
            'test_span': {
                'le': '1.1,Inf',  # le mapping to quantiles
                'tag1': 'some_tag1',
            }
        },
    )
    adapter = PrometheusAdapter(cfg)
    app = BaseApplication(BaseConfig())
    app.logger.add(adapter)

    await app.start()

    with app.logger.span_new(name='test_span') as span:
        pass
    with app.logger.span_new(name='test_span') as span2:
        span2.tag('some_tag1', '123')

    with app.logger.span_new(name='test_span') as span3:
        span3.tag('some_tag1', '123')

    with app.logger.span_new(cls=PgSpan) as span4:
        span4.set_name4adapter(app.logger.ADAPTER_PROMETHEUS,
                               PgSpan.P8S_NAME_ACQUIRE)

    async with ClientSession() as sess:
        resp = await sess.get('http://127.0.0.1:%d/' % port)
        txt = await resp.text()

    assert 'test_span_bucket{le="1.1",tag1=""} 1.0' in txt
    assert 'test_span_bucket{le="+Inf",tag1=""} 1.0' in txt
    assert 'test_span_count{tag1=""} 1.0' in txt
    assert 'test_span_bucket{le="1.1",tag1="123"} 2.0' in txt
    assert 'test_span_bucket{le="+Inf",tag1="123"} 2.0' in txt
    assert 'test_span_count{tag1="123"} 2.0' in txt

    assert ('test_span_sum{tag1=""} %s' % span.duration) in txt
    assert ('test_span_sum{tag1="123"} %s' %
            (span2.duration + span3.duration)) in txt

    assert 'db_connection_count{error="",free=""} 1.0' in txt

    await app.stop()
Beispiel #19
0
async def test_trap():
    app = BaseApplication(BaseConfig())
    lgr = app.logger

    class ExSpan(Span):
        pass

    assert ctx_span_get() is None

    with app.logger.capture_span(ExSpan) as trap:
        with pytest.raises(UserWarning):
            assert trap.span is None
        with lgr.span_new(name='t1') as span1:
            with span1.new_child(name='t2', cls=ExSpan):
                pass
    assert trap.span is not None
    assert trap.span.name == 't2'
Beispiel #20
0
async def test_span_to_hdrs_non_skippable():
    app = BaseApplication(BaseConfig())
    lgr = app.logger

    with lgr.span_new() as span:
        assert span.to_headers() == {
            'X-B3-TraceId': span.trace_id,
            'X-B3-SpanId': span.id,
            'X-B3-Flags': '0',
            'X-B3-Sampled': '1',
        }

        with span.new_child() as span2:
            assert span2.to_headers() == {
                'X-B3-TraceId': span2.trace_id,
                'X-B3-SpanId': span2.id,
                'X-B3-ParentSpanId': span2.parent_id,
                'X-B3-Flags': '0',
                'X-B3-Sampled': '1',
            }
Beispiel #21
0
async def test_logger_span_callback():
    class TestAdapter(AbcAdapter):
        started = False
        stopped = False
        handled: List[Span] = []

        async def start(self, logger: 'Logger'):
            self.started = True

        def handle(self, span: Span):
            self.handled.append(span)

        async def stop(self):
            self.stopped = True

    def replace_tags(span: Span) -> None:
        for tag in span.tags.keys():
            span.tag(tag, '***')

    app = BaseApplication(BaseConfig())
    lgr = app.logger
    lgr.add(TestAdapter())

    adapter = lgr.adapters[TestAdapter.__name__]
    assert isinstance(adapter, TestAdapter)
    lgr.add_before_handle_cb(replace_tags)

    await lgr.start()
    assert adapter.started

    with lgr.span_new() as span:
        span.tag('tag', 'abc')

    await lgr.stop()
    assert adapter.stopped

    assert len(adapter.handled) == 1
    assert span.start_stamp is not None
    assert span.finish_stamp is not None
    assert 'tag' in span.tags
    assert span.tags['tag'] == '***'
Beispiel #22
0
async def test_success(loop, ):
    async with ZipkinServer() as zs:
        cfg = ZipkinConfig(name='123', addr=zs.addr)
        adapter = ZipkinAdapter(cfg)
        app = BaseApplication(BaseConfig())
        app.logger.add(adapter)
        lgr = app.logger
        await lgr.start()

        with lgr.span_new(name='t1', kind=Span.KIND_SERVER) as sp:
            sp.tag('tag', 'abc')
            sp.annotate('k1', 'val1', ts=123456)

            with pytest.raises(Exception):
                with sp.new_child('t2', Span.KIND_CLIENT):
                    raise Exception()

        await lgr.stop()

    assert len(zs.spans) == 2

    span: SpanModel = zs.spans[1]
    span2: SpanModel = zs.spans[0]
    assert span.name == 't1'
    assert span.tags == {'tag': 'abc'}
    assert span.annotations == [
        Annotation(value='val1', timestamp=123456000000)
    ]
    assert span.duration > 0
    assert span.timestamp > 0
    assert not span.debug
    assert span.shared

    assert span2.name == 't2'
    assert span2.tags == {
        'error': 'true',
        'error.class': 'Exception',
        'error.message': '',
    }

    assert 'raise Exception()' in span2.annotations[0].value
Beispiel #23
0
async def test_span_skip():
    class TestAdapter(AbcAdapter):
        started = False
        stopped = False
        handled: List[Span] = []

        async def start(self, logger: 'Logger'):
            self.started = True

        def handle(self, span: Span):
            self.handled.append(span)

        async def stop(self):
            self.stopped = True

    app = BaseApplication(BaseConfig())
    lgr = app.logger
    lgr.add(TestAdapter())

    adapter = lgr.adapters[TestAdapter.__name__]
    assert isinstance(adapter, TestAdapter)

    await lgr.start()
    assert adapter.started

    with lgr.span_new() as span:
        with span.new_child():
            pass
        span.skip()
        with span.new_child():
            pass

    assert len(adapter.handled) == 0

    await lgr.stop()
    assert adapter.stopped

    assert len(adapter.handled) == 0
Beispiel #24
0
async def test_logger_adapter():
    class TestAdapter(AbcAdapter):
        started = False
        stopped = False
        handled: List[Span] = []

        async def start(self, logger: 'Logger'):
            self.started = True

        def handle(self, span: Span):
            self.handled.append(span)

        async def stop(self):
            self.stopped = True

    app = BaseApplication(BaseConfig())
    lgr = app.logger
    lgr.add(TestAdapter())

    adapter = lgr.adapters[0]
    assert isinstance(adapter, TestAdapter)

    await lgr.start()
    assert adapter.started

    with lgr.span_new() as span:
        span.tag('tag', 'abc')

    await lgr.stop()
    assert adapter.stopped

    assert len(adapter.handled) == 1
    assert span.start_stamp is not None
    assert span.finish_stamp is not None
    assert 'tag' in span.tags
    assert span.tags['tag'] == 'abc'
Beispiel #25
0
async def test_logger_invalid_adapter():

    app = BaseApplication(BaseConfig())
    lgr = app.logger
    with pytest.raises(UserWarning):
        lgr.add(object())
Beispiel #26
0
async def test_dead_letter_exchange(loop, rabbitmq_url):
    messages: List[Tuple[bytes]] = []
    queue: str

    class TestPubChg(PikaChannel):
        name = 'pub'

        async def prepare(self) -> None:
            await self.exchange_declare('myexchange1', durable=False)
            await self.queue_declare('myqueue1', durable=False)
            await self.queue_bind('myqueue1', 'myexchange1', '')

            q = await self.queue_declare(
                '',
                exclusive=True,
                arguments={
                    'x-dead-letter-exchange': '',
                    'x-dead-letter-routing-key': 'myqueue1',
                },
            )
            self.queue = q.method.queue

        async def send(self, body: bytes, expiration: str):
            await self.publish(
                '', self.queue, body, BasicProperties(expiration=expiration)
            )

    class TestCnsChg(PikaChannel):
        name = 'sub'

        async def prepare(self) -> None:
            await self.qos(prefetch_count=1)

        async def start(self) -> None:
            await self.consume('myqueue1', self.message)

        async def message(
            self, body: bytes, deliver: Deliver, proprties: Properties
        ) -> None:
            await self.ack(delivery_tag=deliver.delivery_tag)
            messages.append((body, proprties))

    app = BaseApplication(BaseConfig())
    app.add(
        'mq',
        Pika(
            PikaConfig(url=rabbitmq_url),
            [
                lambda: TestPubChg(PikaChannelConfig()),
                lambda: TestCnsChg(PikaChannelConfig()),
            ],
        ),
    )
    await app.start()
    mq: Pika = app.get('mq')  # type: ignore

    await mq.channel('pub').send(b'testmsg', '1')

    await wait_for(lambda: len(messages) > 0)

    assert messages[0][1].headers['x-death'][0]['count'] == 1
    assert repr(messages[0][1].headers['x-death'][0]['count']) == '1L'

    await app.stop()
Beispiel #27
0
async def test_http(unused_tcp_port):
    class TestClient(Client):
        async def send(self, url: str) -> ClientResponse:
            return await self.request('GET', url)

        async def send_add_get(self, url: str) -> ClientResponse:
            return await self.request('GET', url)

        async def send_add_head(self, url: str) -> ClientResponse:
            return await self.request('HEAD', url)

        async def send_add_post(self, url: str) -> ClientResponse:
            return await self.request('POST', url)

        async def send_add_put(self, url: str) -> ClientResponse:
            return await self.request('PUT', url)

        async def send_add_patch(self, url: str) -> ClientResponse:
            return await self.request('PATCH', url)

        async def send_add_delete(self, url: str) -> ClientResponse:
            return await self.request('DELETE', url)

    class Handler(ServerHandler):
        async def prepare(self) -> None:
            self.server.add_route('GET', '/', self.home)
            self.server.add_head('/', self.test_head)
            self.server.add_get('/test_get', self.test_get)
            self.server.add_post('/test_post', self.test_post)
            self.server.add_patch('/test_patch', self.test_patch)
            self.server.add_put('/test_put', self.test_put)
            self.server.add_delete('/test_delete', self.test_delete)

        async def home(self, request: web.Request) -> web.Response:
            return web.Response(text='OK')

        async def test_get(self, request: web.Request) -> web.Response:
            body = request.method
            return web.Response(text=body)

        async def test_head(self, request: web.Request) -> web.Response:
            return web.Response()

        async def test_post(self, request: web.Request) -> web.Response:
            body = request.method
            return web.Response(text=body)

        async def test_patch(self, request: web.Request) -> web.Response:
            body = request.method
            return web.Response(text=body)

        async def test_put(self, request: web.Request) -> web.Response:
            body = request.method
            return web.Response(text=body)

        async def test_delete(self, request: web.Request) -> web.Response:
            body = request.method
            return web.Response(text=body)

    app = BaseApplication(BaseConfig())
    app.add('srv', Server(ServerConfig(port=unused_tcp_port), Handler()))
    app.add('clt', TestClient())
    url_test = 'http://127.0.0.1:%d' % unused_tcp_port

    await app.start()

    resp = await app.get('clt').send(url_test)
    assert resp.status == 200
    assert await resp.text() == 'OK'

    resp_head = await app.get('clt').send_add_head(f'{url_test}/')
    assert resp_head.status == 200

    resp_get = await app.get('clt').send_add_get(f'{url_test}/test_get')
    assert resp_get.status == 200
    assert await resp_get.text() == 'GET'

    resp_post = await app.get('clt').send_add_post(f'{url_test}/test_post')
    assert resp_post.status == 200
    assert await resp_post.text() == 'POST'

    resp_patch = await app.get('clt').send_add_patch(f'{url_test}/test_patch')
    assert resp_patch.status == 200
    assert await resp_patch.text() == 'PATCH'

    resp_put = await app.get('clt').send_add_put(f'{url_test}/test_put')
    assert resp_put.status == 200
    assert await resp_put.text() == 'PUT'

    resp_delete = await app.get('clt').send_add_delete(
        f'{url_test}/test_delete',
    )
    assert resp_delete.status == 200
    assert await resp_delete.text() == 'DELETE'

    await app.stop()
Beispiel #28
0
async def test_success(
    loop,
):
    async with ZipkinServer() as zs:
        cfg = ZipkinConfig(name='123', addr=zs.addr)
        adapter = ZipkinAdapter(cfg)
        app = BaseApplication(BaseConfig())
        app.logger.add(adapter)
        lgr = app.logger
        await lgr.start()

        with lgr.span_new(name='t1', kind=Span.KIND_SERVER) as sp:
            sp.tag('tag', 'abc')
            sp.annotate('k1', 'val1', ts=123456)

            with pytest.raises(Exception):
                with sp.new_child('t2', Span.KIND_CLIENT):
                    raise Exception()

        with lgr.span_new(kind=Span.KIND_SERVER) as sp3:
            sp3.set_name4adapter(lgr.ADAPTER_ZIPKIN, '111')
            sp3.annotate4adapter(
                lgr.ADAPTER_ZIPKIN,
                PgSpan.ANN_RESULT,
                json_encode({'result': '123'}),
                ts=122211000000,
            )
            sp3.set_tag4adapter(
                lgr.ADAPTER_ZIPKIN,
                PgSpan.TAG_QUERY_NAME,
                'get_paym',
            )

        await lgr.stop()

    assert len(zs.spans) == 3

    span: SpanModel = zs.spans[1]
    span2: SpanModel = zs.spans[0]
    span3: SpanModel = zs.spans[2]
    assert span.name == 't1'
    assert span.tags == {'tag': 'abc'}
    assert span.annotations == [
        Annotation(value='val1', timestamp=123456000000)
    ]
    assert span.duration > 0
    assert span.timestamp > 0
    assert not span.debug
    assert span.shared

    assert span2.name == 't2'
    assert span2.tags == {
        'error': 'true',
        'error.class': 'Exception',
        'error.message': '',
    }

    assert 'raise Exception()' in span2.annotations[0].value

    assert span3.name == '111'
    assert span3.tags == {PgSpan.TAG_QUERY_NAME: 'get_paym'}
    assert span3.annotations == [
        Annotation(value='{"result": "123"}', timestamp=122211000000000000)
    ]
Beispiel #29
0
def get_app() -> BaseApplication:
    return BaseApplication(BaseConfig())
Beispiel #30
0
async def test_span():
    class TestAdapter(AbcAdapter):
        started = False
        stopped = False
        handled: List[Span] = []

        async def start(self, logger: 'Logger'):
            self.started = True

        def handle(self, span: Span):
            self.handled.append(span)

        async def stop(self):
            self.stopped = True

    app = BaseApplication(BaseConfig())
    lgr = app.logger
    lgr.add(TestAdapter())

    adapter = lgr.adapters[TestAdapter.__name__]
    assert isinstance(adapter, TestAdapter)

    await lgr.start()
    assert adapter.started

    exc = Exception('Err')
    exc2 = Exception('Err2')

    span = Span(lgr, '1234')
    assert span.duration == 0

    with lgr.span_new('t1', kind=Span.KIND_SERVER) as span:
        dur1 = span.duration
        assert dur1 > 0
        assert span.kind == span.KIND_SERVER
        assert span.name == 't1'
        with span.new_child(name='t2', kind=Span.KIND_CLIENT) as span2:
            assert span2.kind == span.KIND_CLIENT
            assert span2.name == 't2'
            assert span2.parent_id == span.id
            assert span2.parent is span

            try:
                raise exc
            except Exception as err:
                span2.error(err)

            try:
                with span2.new_child(name='t3',
                                     kind=Span.KIND_CLIENT) as span3:
                    assert span3.parent_id == span2.id
                    assert span3.parent is span2
                    raise exc2
            except Exception as err2:
                assert err2 is exc2

        assert span.duration > dur1

        span.set_name4adapter(TestAdapter.name, 'tt1')
        span.annotate('k1', '1', ts=1)
        span.annotate('k1', '2', ts=2)
        span.annotate4adapter(TestAdapter.name, 'k2', '2', ts=2)
        span.annotate4adapter(TestAdapter.name, 'k2', '3', ts=3)

        span.tag('tag1', '11')
        span.set_tag4adapter(TestAdapter.name, 'tag2', '22')
        span.set_tag4adapter(TestAdapter.name, 'tag3', '33')

    await lgr.stop()
    assert adapter.stopped

    assert len(adapter.handled) == 3

    span = adapter.handled[2]
    span2 = adapter.handled[1]
    span3 = adapter.handled[0]
    assert span.kind == span.KIND_SERVER
    assert span2.kind == span.KIND_CLIENT

    assert span.duration > 0

    # name
    assert span.name == 't1'
    assert span2.name == 't2'
    assert span.get_name4adapter(TestAdapter.name) == 'tt1'
    assert span.get_name4adapter(TestAdapter.name, merge=False) == 'tt1'
    assert span2.get_name4adapter(TestAdapter.name) == 't2'
    assert span2.get_name4adapter(TestAdapter.name, merge=False) is None

    # tags
    assert span.tags == {'tag1': '11'}
    assert span.get_tags4adapter(TestAdapter.name) == {
        'tag1': '11',
        'tag2': '22',
        'tag3': '33',
    }
    assert span.get_tags4adapter(TestAdapter.name, merge=False) == {
        'tag2': '22',
        'tag3': '33',
    }
    assert span.get_tags4adapter('unknown') == {'tag1': '11'}
    assert span.get_tags4adapter('unknown', merge=False) == {}

    # annotations
    assert span.annotations == {'k1': [('1', 1), ('2', 2)]}
    assert span.get_annotations4adapter(TestAdapter.name) == {
        'k1': [('1', 1), ('2', 2)],
        'k2': [('2', 2), ('3', 3)],
    }
    assert span.get_annotations4adapter(TestAdapter.name, merge=False) == {
        'k2': [('2', 2), ('3', 3)]
    }
    assert span.get_annotations4adapter('unknown...') == {
        'k1': [('1', 1), ('2', 2)]
    }
    assert span.get_annotations4adapter('unknown...', merge=False) == {}

    # log error
    assert span2.tags == {
        'error': 'true',
        'error.class': 'Exception',
        'error.message': 'Err',
    }
    assert 'traceback' in span2.annotations
    assert len(span2.annotations['traceback']) == 1
    assert isinstance(span2.annotations['traceback'][0][0], str)
    assert len(span2.annotations['traceback'][0][0]) > 0
    assert span2.get_error() is exc

    assert span3.tags == {
        'error': 'true',
        'error.class': 'Exception',
        'error.message': 'Err2',
    }
    assert 'traceback' in span3.annotations
    assert len(span3.annotations['traceback']) == 1
    assert isinstance(span3.annotations['traceback'][0][0], str)
    assert len(span3.annotations['traceback'][0][0]) > 0
    assert span3.get_error() is exc2

    assert 'Span' in str(span)
    assert 'ms' in str(span)