async def test_message_from_bob_to_alice_multi_backends(
    postgresql_url, alice, bob, backend_factory, backend_sock_factory
):
    d1 = datetime(2000, 1, 1)
    async with backend_factory(
        config={"blockstore_config": PostgreSQLBlockStoreConfig(), "db_url": postgresql_url}
    ) as backend_1, backend_factory(
        populated=False,
        config={"blockstore_config": PostgreSQLBlockStoreConfig(), "db_url": postgresql_url},
    ) as backend_2:

        async with backend_sock_factory(backend_1, alice) as alice_backend_sock:

            await events_subscribe(alice_backend_sock)
            async with events_listen(alice_backend_sock) as listen:
                await backend_2.message.send(
                    bob.organization_id, bob.device_id, alice.user_id, d1, b"Hello from Bob !"
                )

            assert listen.rep == {"status": "ok", "event": APIEvent.MESSAGE_RECEIVED, "index": 1}

            rep = await message_get(alice_backend_sock)
            assert rep == {
                "status": "ok",
                "messages": [
                    {
                        "body": b"Hello from Bob !",
                        "sender": bob.device_id,
                        "timestamp": d1,
                        "count": 1,
                    }
                ],
            }
Exemple #2
0
def test_parse_simple_raid():
    config = _parse_blockstore_params([
        "raid0:0:MOCKED",
        "raid0:1:POSTGRESQL",
        "raid0:2:s3:s3.example.com:region1:bucketA:key123:S3cr3t",
        "raid0:3:swift:swift.example.com:tenant2:containerB:user123:S3cr3t",
    ])
    assert config == RAID0BlockStoreConfig(blockstores=[
        MockedBlockStoreConfig(),
        PostgreSQLBlockStoreConfig(),
        S3BlockStoreConfig(
            s3_endpoint_url="s3.example.com",
            s3_region="region1",
            s3_bucket="bucketA",
            s3_key="key123",
            s3_secret="S3cr3t",
        ),
        SWIFTBlockStoreConfig(
            swift_authurl="swift.example.com",
            swift_tenant="tenant2",
            swift_container="containerB",
            swift_user="******",
            swift_password="******",
        ),
    ])
Exemple #3
0
async def test_retry_policy_allow_retry(postgresql_url, unused_tcp_port,
                                        asyncio_loop):
    host = "localhost"
    port = unused_tcp_port
    app_config = BackendConfig(
        administration_token="s3cr3t",
        db_min_connections=1,
        db_max_connections=5,
        debug=False,
        blockstore_config=PostgreSQLBlockStoreConfig(),
        email_config=None,
        backend_addr=None,
        forward_proto_enforce_https=None,
        ssl_context=False,
        spontaneous_organization_bootstrap=False,
        organization_bootstrap_webhook_url=None,
        db_url=postgresql_url,
    )
    # Allow to retry once
    retry_policy = RetryPolicy(maximum_attempts=1, pause_before_retry=0)
    async with trio.open_nursery() as nursery:
        # Run backend in the background
        nursery.start_soon(lambda: _run_backend(host,
                                                port,
                                                ssl_context=False,
                                                retry_policy=retry_policy,
                                                app_config=app_config))
        # Connect to PostgreSQL database
        async with triopg.connect(postgresql_url) as conn:

            # Test for 10 cycles
            pid = None
            for _ in range(10):
                # Wait for the backend to be connected
                new_pid, = await wait_for_listeners(conn)
                # Make sure a new connection has been created
                assert new_pid != pid
                pid = new_pid
                # Terminate the backend listener connection
                value, = await conn.fetchrow("SELECT pg_terminate_backend($1)",
                                             pid)
                assert value
                # Wait for the listener to terminate
                await wait_for_listeners(conn, to_terminate=True)

            # Cancel the backend nursery
            nursery.cancel_scope.cancel()
Exemple #4
0
def _parse_blockstore_param(value):
    if value.upper() == "MOCKED":
        return MockedBlockStoreConfig()
    elif value.upper() == "POSTGRESQL":
        return PostgreSQLBlockStoreConfig()
    else:
        parts = _split_with_escaping(value)
        if parts[0].upper() == "S3":
            try:
                endpoint_url, region, bucket, key, secret = parts[1:]
            except ValueError:
                raise click.BadParameter(
                    "Invalid S3 config, must be `s3:[<endpoint_url>]:<region>:<bucket>:<key>:<secret>`"
                )
            # Provide https by default to avoid anoying escaping for most cases
            if (endpoint_url and not endpoint_url.startswith("http://")
                    and not endpoint_url.startswith("https://")):
                endpoint_url = f"https://{endpoint_url}"
            return S3BlockStoreConfig(
                s3_endpoint_url=endpoint_url or None,
                s3_region=region,
                s3_bucket=bucket,
                s3_key=key,
                s3_secret=secret,
            )

        elif parts[0].upper() == "SWIFT":
            try:
                auth_url, tenant, container, user, password = parts[1:]
            except ValueError:
                raise click.BadParameter(
                    "Invalid SWIFT config, must be `swift:<auth_url>:<tenant>:<container>:<user>:<password>`"
                )
            # Provide https by default to avoid anoying escaping for most cases
            if (auth_url and not auth_url.startswith("http://")
                    and not auth_url.startswith("https://")):
                auth_url = f"https://{auth_url}"
            return SWIFTBlockStoreConfig(
                swift_authurl=auth_url,
                swift_tenant=tenant,
                swift_container=container,
                swift_user=user,
                swift_password=password,
            )
        else:
            raise click.BadParameter(f"Invalid blockstore type `{parts[0]}`")
Exemple #5
0
async def test_retry_policy_no_retry(postgresql_url, unused_tcp_port,
                                     asyncio_loop):
    host = "localhost"
    port = unused_tcp_port
    app_config = BackendConfig(
        administration_token="s3cr3t",
        db_min_connections=1,
        db_max_connections=5,
        debug=False,
        blockstore_config=PostgreSQLBlockStoreConfig(),
        email_config=None,
        backend_addr=None,
        forward_proto_enforce_https=None,
        ssl_context=False,
        spontaneous_organization_bootstrap=False,
        organization_bootstrap_webhook_url=None,
        db_url=postgresql_url,
    )

    # No retry
    retry_policy = RetryPolicy(maximum_attempts=0, pause_before_retry=0)

    # Expect a connection error
    with pytest.raises(ConnectionError):
        async with trio.open_nursery() as nursery:
            # Run backend in the background
            nursery.start_soon(lambda: _run_backend(host,
                                                    port,
                                                    ssl_context=False,
                                                    retry_policy=retry_policy,
                                                    app_config=app_config))
            # Connect to PostgreSQL database
            async with triopg.connect(postgresql_url) as conn:
                # Wait for the backend to be connected
                pid, = await wait_for_listeners(conn)
                # Terminate the backend listener connection
                value, = await conn.fetchrow("SELECT pg_terminate_backend($1)",
                                             pid)
                assert value
                # Wait to get cancelled by the connection error `_run_backend`
                with trio.fail_after(3):
                    await trio.sleep_forever()
Exemple #6
0
def blockstore(request, backend_store):
    # TODO: allow to test against swift ?
    if backend_store.startswith("postgresql://"):
        config = PostgreSQLBlockStoreConfig()
    else:
        config = MockedBlockStoreConfig()

    # More or less a hack to be able to to configure this fixture from
    # the test function by adding tags to it
    if request.node.get_closest_marker("raid0_blockstore"):
        config = RAID0BlockStoreConfig(
            blockstores=[config, MockedBlockStoreConfig()])
    if request.node.get_closest_marker("raid1_blockstore"):
        config = RAID1BlockStoreConfig(
            blockstores=[config, MockedBlockStoreConfig()])
    if request.node.get_closest_marker("raid5_blockstore"):
        config = RAID5BlockStoreConfig(blockstores=[
            config, MockedBlockStoreConfig(),
            MockedBlockStoreConfig()
        ])

    return config
Exemple #7
0
def _parse_blockstore_param(value):
    if value.upper() == "MOCKED":
        return MockedBlockStoreConfig()
    elif value.upper() == "POSTGRESQL":
        return PostgreSQLBlockStoreConfig()
    else:
        parts = value.split(":")
        if parts[0].upper() == "S3":
            try:
                endpoint_url, region, bucket, key, secret = parts[1:]
            except ValueError:
                raise click.BadParameter(
                    "Invalid S3 config, must be `s3:<endpoint_url>:<region>:<bucket>:<key>:<secret>`"
                )
            return S3BlockStoreConfig(
                s3_endpoint_url=endpoint_url or None,
                s3_region=region,
                s3_bucket=bucket,
                s3_key=key,
                s3_secret=secret,
            )

        elif parts[0].upper() == "SWIFT":
            try:
                authurl, tenant, container, user, password = parts[1:]
            except ValueError:
                raise click.BadParameter(
                    "Invalid SWIFT config, must be `swift:<authurl>:<tenant>:<container>:<user>:<password>`"
                )
            return SWIFTBlockStoreConfig(
                swift_authurl=authurl,
                swift_tenant=tenant,
                swift_container=container,
                swift_user=user,
                swift_password=password,
            )
        else:
            raise click.BadParameter(f"Invalid blockstore type `{parts[0]}`")
Exemple #8
0
def blockstore(backend_store, fixtures_customization):
    # TODO: allow to test against swift ?
    if backend_store.startswith("postgresql://"):
        config = PostgreSQLBlockStoreConfig()
    else:
        config = MockedBlockStoreConfig()

    raid = fixtures_customization.get("blockstore_mode", "NO_RAID").upper()
    if raid == "RAID0":
        config = RAID0BlockStoreConfig(
            blockstores=[config, MockedBlockStoreConfig()])
    elif raid == "RAID1":
        config = RAID1BlockStoreConfig(
            blockstores=[config, MockedBlockStoreConfig()])
    elif raid == "RAID1_PARTIAL_CREATE_OK":
        config = RAID1BlockStoreConfig(
            blockstores=[config, MockedBlockStoreConfig()],
            partial_create_ok=True)
    elif raid == "RAID5":
        config = RAID5BlockStoreConfig(blockstores=[
            config, MockedBlockStoreConfig(),
            MockedBlockStoreConfig()
        ])
    elif raid == "RAID5_PARTIAL_CREATE_OK":
        config = RAID5BlockStoreConfig(
            blockstores=[
                config,
                MockedBlockStoreConfig(),
                MockedBlockStoreConfig()
            ],
            partial_create_ok=True,
        )
    else:
        assert raid == "NO_RAID"

    return config
Exemple #9
0
def test_parse_postgresql():
    config = _parse_blockstore_params(["POSTGRESQL"])
    assert config == PostgreSQLBlockStoreConfig()