Exemplo n.º 1
0
def test_custom_error_retryable():
    """
    Custom errors status codes are handled as expected.

    """
    graph = create_object_graph(name="example", testing=True)

    @graph.app.route("/conflict")
    @graph.audit
    def conflict():
        raise MyConflictError("Conflict")

    client = graph.app.test_client()

    response = client.get("/conflict")
    assert_that(response.status_code, is_(equal_to(409)))
    data = response.json
    assert_that(data, is_(equal_to({
        "code": 409,
        "message": "Conflict",
        "retryable": True,
        "context": {
            "errors": [{
                "message": "Banana!",
            }]
        },
    })))
Exemplo n.º 2
0
def produce():
    """
    Produce test messages.

    """
    parser = ArgumentParser()
    parser.add_argument("--count", default=1, type=int)
    parser.add_argument("--message")
    parser.add_argument("--message-type", default="test")
    parser.add_argument("--topic-arn", required=True)
    args = parser.parse_args()

    def load_config(metadata):
        return dict(
            pubsub_message_codecs=dict(
                default=SimpleSchema,
            ),
            sns_topic_arns=dict(
                default=args.topic_arn,
            ),
        )

    graph = create_object_graph("example", loader=load_config)
    for _ in range(args.count):
        message_id = graph.sns_producer.produce(
            args.message_type,
            message=args.message or uuid4().hex,
            timestamp=time(),
        )
        print message_id  # noqa
def test_configure_sessionmaker():
    """
    Should create the `SQLAlchemy` sessionmaker

    """
    graph = create_object_graph(name="example", testing=True)
    assert_that(graph.sessionmaker, is_(instance_of(sessionmaker)))
Exemplo n.º 4
0
def test_error_wrap():
    """
    Wrapped errors work properly.

    """
    graph = create_object_graph(name="example", testing=True)

    def fail():
        raise Exception("fail")

    @graph.app.route("/wrap")
    @graph.audit
    def wrap():
        try:
            fail()
        except Exception as error:
            raise Exception(error)

    client = graph.app.test_client()

    response = client.get("/wrap")
    assert_that(response.status_code, is_(equal_to(500)))
    data = response.json
    assert_that(data, is_(equal_to({
        "code": 500,
        "message": "fail",
        "retryable": False,
        "context": {"errors": []}
    })))
Exemplo n.º 5
0
def test_configure_flywheel_engine():
    """
    Should create the `flywheel` engine

    """
    graph = create_object_graph(name="example", testing=True, import_name="microcosm_dynamodb")
    assert_that(graph.dynamodb, is_(instance_of(Engine)))
Exemplo n.º 6
0
def test_override_default_limit_from_request_header():
    graph = create_object_graph(name="example", testing=True)
    with graph.flask.test_request_context(headers={"X-Request-Limit": "2"}):
        page = OffsetLimitPage.from_dict(dict(foo="bar"))
        assert_that(page.offset, is_(equal_to(0)))
        assert_that(page.limit, is_(equal_to(2)))
        assert_that(page.kwargs, has_entry("foo", "bar"))
Exemplo n.º 7
0
def test_werkzeug_http_error():
    """
    Explicit HTTP errors are reported as expected.

    """
    graph = create_object_graph(name="example", testing=True)

    @graph.app.route("/not_found")
    @graph.audit
    def not_found():
        raise NotFound

    client = graph.app.test_client()

    response = client.get("/not_found")
    assert_that(response.status_code, is_(equal_to(404)))
    data = response.json
    assert_that(data, is_(equal_to({
        "code": 404,
        "context": {
            "errors": [],
        },
        "message": "The requested URL was not found on the server. "
                   "If you entered the URL manually please check your spelling and try again.",
        "retryable": False,
    })))
def test_configure_flask():
    """
    Should create the `Flask` application.

    """
    graph = create_object_graph(name="example", testing=True)
    assert_that(graph.app, is_(instance_of(Flask)))
def test_configure_elasticsearch_client_with_defaults():
    """
    Default configuration works and returns client.

    """
    graph = create_object_graph(name="test", testing=True)
    assert_that(graph.elasticsearch_client, is_(instance_of(Elasticsearch)))
Exemplo n.º 10
0
def test_health_check_custom_check():
    """
    Should return Custom health check results.

    """
    loader = load_from_dict(
        health_convention=dict(
            include_build_info="false",
        ),
    )
    graph = create_object_graph(name="example", testing=True, loader=loader)
    graph.use("health_convention")

    client = graph.flask.test_client()

    graph.health_convention.checks["foo"] = lambda graph: "hi"

    response = client.get("/api/health")
    assert_that(response.status_code, is_(equal_to(200)))
    data = loads(response.get_data().decode("utf-8"))
    assert_that(data, is_(equal_to({
        "name": "example",
        "ok": True,
        "checks": {
            "foo": {
                "message": "hi",
                "ok": True,
            },
        },
    })))
Exemplo n.º 11
0
def test_health_check_custom_check_failed():
    """
    Should return 503 on health check failure.

    """
    loader = load_from_dict(
        health_convention=dict(
            include_build_info="false",
        ),
    )
    graph = create_object_graph(name="example", testing=True, loader=loader)
    graph.use("health_convention")

    client = graph.flask.test_client()

    def fail(graph):
        raise Exception("failure!")

    graph.health_convention.checks["foo"] = fail

    response = client.get("/api/health")
    assert_that(response.status_code, is_(equal_to(503)))
    data = loads(response.get_data().decode("utf-8"))
    assert_that(data, is_(equal_to({
        "name": "example",
        "ok": False,
        "checks": {
            "foo": {
                "message": "failure!",
                "ok": False,
            },
        },
    })))
Exemplo n.º 12
0
def test_produce_custom_topic():
    """
    Producer delegates to SNS client.

    """
    def loader(metadata):
        return dict(
            pubsub_message_codecs=dict(
                default=FooSchema,
            ),
            sns_topic_arns=dict(
                default=None,
                mappings={
                    FOO_MEDIA_TYPE: FOO_TOPIC,
                },
            )
        )

    graph = create_object_graph("example", testing=True, loader=loader)

    # set up response
    graph.sns_producer.sns_client.publish.return_value = dict(MessageId=MESSAGE_ID)

    message_id = graph.sns_producer.produce(FOO_MEDIA_TYPE, bar="baz")

    assert_that(graph.sns_producer.sns_client.publish.call_count, is_(equal_to(1)))
    assert_that(graph.sns_producer.sns_client.publish.call_args[1]["TopicArn"], is_(equal_to(FOO_TOPIC)))
    assert_that(loads(graph.sns_producer.sns_client.publish.call_args[1]["Message"]), is_(equal_to({
        "bar": "baz",
        "mediaType": "application/vnd.globality.pubsub.foo",
    })))
    assert_that(message_id, is_(equal_to(MESSAGE_ID)))
def test_codec_sqs_envelope():
    graph = create_object_graph("example", testing=True)
    consumer = None
    message_id = "message_id"
    receipt_handle = "receipt_handle"
    envelope = CodecSQSEnvelope(graph)

    media_type = created("foo")
    uri = "http://foo/id"

    sqs_message = envelope.parse_raw_message(consumer, dict(
        MessageId=message_id,
        ReceiptHandle=receipt_handle,
        Body=dumps(dict(
            Message=dumps(dict(
                mediaType=media_type,
                foo="bar",
                uri=uri,
            )),
        )),
    ))

    assert_that(sqs_message.content, is_(equal_to(dict(
        # NB: no foo key here because it's not part of the schema
        media_type=media_type,
        uri=uri,
    ))))
    assert_that(sqs_message.media_type, is_(equal_to(media_type)))
    assert_that(sqs_message.message_id, is_(equal_to(message_id)))
    assert_that(sqs_message.receipt_handle, is_(equal_to(receipt_handle)))
def test_deferred_production_decorator():
    """
    Deferred production can be used to decorate a function

    """
    def loader(metadata):
        return dict(
            sns_topic_arns=dict(
                default="topic",
            )
        )

    class Foo:
        def __init__(self, graph):
            self.graph = graph
            self.sns_producer = graph.sns_producer

        def bar(self):
            assert isinstance(self.sns_producer, DeferredProducer)
            self.sns_producer.produce(DerivedSchema.MEDIA_TYPE, data="data")
            assert_that(graph.sns_producer.sns_client.publish.call_count, is_(equal_to(0)))

    graph = create_object_graph("example", testing=True, loader=loader)
    foo = Foo(graph)

    func = deferred(foo)(foo.bar)
    func()

    assert_that(graph.sns_producer.sns_client.publish.call_count, is_(equal_to(1)))
def test_publish_batch_with_no_topic_fails():
    """
    Require explicit configuration of a topic for batch messages.

    """
    def loader(metadata):
        return dict(
            sns_topic_arns=dict(
                default="topic",
            )
        )

    graph = create_object_graph("example", testing=True, loader=loader)
    graph.use("opaque")

    # set up response
    graph.sns_producer.sns_client.publish.return_value = dict(MessageId=MESSAGE_ID)

    assert_that(
        calling(graph.sns_producer.produce).with_args(
            MessageBatchSchema.MEDIA_TYPE,
            messages=[]
        ),
        raises(TopicNotDefinedError)
    )
def test_configure_logging_with_custom_library_levels():
    """
    Logging levels can be configured.

    """
    def loader(metadata):
        return dict(
            logging=dict(
                level=INFO,
                levels=dict(
                    default=dict(
                        debug=["foo", "bar"],
                    ),
                    override=dict(
                        warn=["foo"],
                    )
                )
            )
        )

    graph = create_object_graph(name="test", testing=True, loader=loader)
    graph.use("logger")

    assert_that(getLogger("foo").getEffectiveLevel(), is_(equal_to(WARN)))
    assert_that(getLogger("bar").getEffectiveLevel(), is_(equal_to(DEBUG)))

    getLogger("bar").info("Bar should be visible at info")
    getLogger("foo").info("Foo should not be visible at info")
    getLogger("foo").warn("Foo should be visible at warn")
def test_produce_custom_topic():
    """
    Producer delegates to SNS client.

    """
    def loader(metadata):
        return dict(
            sns_topic_arns=dict(
                default=None,
                mappings={
                    DerivedSchema.MEDIA_TYPE: "special-topic",
                },
            )
        )

    graph = create_object_graph("example", testing=True, loader=loader)
    graph.use("opaque")

    # set up response
    graph.sns_producer.sns_client.publish.return_value = dict(MessageId=MESSAGE_ID)

    message_id = graph.sns_producer.produce(DerivedSchema.MEDIA_TYPE, data="data")

    assert_that(graph.sns_producer.sns_client.publish.call_count, is_(equal_to(1)))
    assert_that(graph.sns_producer.sns_client.publish.call_args[1]["TopicArn"], is_(equal_to("special-topic")))
    assert_that(loads(graph.sns_producer.sns_client.publish.call_args[1]["Message"]), is_(equal_to({
        "data": "data",
        "mediaType": DerivedSchema.MEDIA_TYPE,
        "opaqueData": {},
    })))
    assert_that(message_id, is_(equal_to(MESSAGE_ID)))
def test_configure_engine():
    """
    Engine factory should work with zero configuration.

    """
    graph = create_object_graph(name="example", testing=True)
    engine = graph.postgres

    assert_that(engine, is_(instance_of(Engine)))

    # engine has expected configuration
    assert_that(
        str(engine.url),
        starts_with("postgresql://example:@"),
    )

    assert_that(
        str(engine.url),
        ends_with(":5432/example_test_db"),
    )

    # engine supports connections
    with engine.connect() as connection:
        row = connection.execute("SELECT 1;").fetchone()
        assert_that(row[0], is_(equal_to(1)))
def test_discovery():
    graph = create_object_graph(name="example", testing=True)
    graph.use("discovery_convention")

    ns = Namespace("foo")

    @graph.route(ns.collection_path, Operation.Search, ns)
    def search_foo():
        pass

    client = graph.flask.test_client()

    response = client.get("/api")
    assert_that(response.status_code, is_(equal_to(200)))
    data = loads(response.get_data().decode("utf-8"))
    assert_that(data, is_(equal_to({
        "_links": {
            "search": [{
                "href": "http://localhost/api/foo?offset=0&limit=20",
                "type": "foo",
            }],
            "self": {
                "href": "http://localhost/api?offset=0&limit=20",
            },
        }
    })))
def test_basic_auth_custom_credentials():
    """
    Basic auth default credentials work.

    """
    config = dict(
        basic_auth=dict(
            credentials=dict(
                username="******",
            )
        )
    )

    graph = create_object_graph(name="example", testing=True, loader=lambda metadata: config)

    @graph.app.route("/ok")
    @graph.audit
    @graph.basic_auth.required
    def unauthorized():
        return "OK"

    client = graph.app.test_client()

    response = client.get("/ok", headers={
        "Authorization": encode_basic_auth("username", "password"),
    })
    assert_that(response.status_code, is_(equal_to(200)))
 def setup(self):
     self.graph = create_object_graph("test")
     self.graph.use(
         "pubsub_message_schema_registry",
         "pubsub_lifecycle_change",
     )
     self.graph.lock()
Exemplo n.º 22
0
def test_ack():
    """
    Consumer delegates to SQS client.

    """
    def loader(metadata):
        return dict(
            sqs_consumer=dict(
                sqs_queue_url=FOO_QUEUE_URL,
            ),
            pubsub_message_codecs=dict(
                default=FooSchema,
            ),
        )

    graph = create_object_graph("example", testing=True, loader=loader)
    message = SQSMessage(
        consumer=graph.sqs_consumer,
        message_id=MESSAGE_ID,
        receipt_handle=RECEIPT_HANDLE,
        content=None,
    )
    message.ack()
    graph.sqs_consumer.sqs_client.delete_message.assert_called_with(
        QueueUrl='foo-queue-url',
        ReceiptHandle=RECEIPT_HANDLE,
    )
def test_basic_auth_default_realm():
    """
    Basic auth uses the convention that the metadata's name is the realm.

    """
    graph = create_object_graph(name="example", testing=True)

    @graph.app.route("/unauthorized")
    @graph.audit
    @graph.basic_auth.required
    def unauthorized():
        raise Exception("Should not be raised!")

    client = graph.app.test_client()

    response = client.get("/unauthorized")
    assert_that(response.status_code, is_(equal_to(401)))
    data = loads(response.get_data().decode("utf-8"))
    assert_that(data, is_(equal_to({
        "code": 401,
        "message": "The server could not verify that you are authorized to access the URL requested. "
                   "You either supplied the wrong credentials (e.g. a bad password), or your browser "
                   "doesn't understand how to supply the credentials required.",
        "retryable": False,
        "context": {"errors": []},
    })))
    assert_that(response.headers["WWW-Authenticate"], is_(equal_to('Basic realm="example"')))
    def setup(self):
        self.graph = create_object_graph(name="example", testing=True, import_name="microcosm_postgres")
        self.company_store = self.graph.company_store

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()
    def setup(self):
        loaders = load_each(
            load_from_dict(
                multi_tenant_key_registry=dict(
                    context_keys=[
                        "private",
                    ],
                    key_ids=[
                        "key_id",
                    ],
                ),
            ),
            load_from_environ,
        )
        self.graph = create_object_graph(
            name="example",
            testing=True,
            import_name="microcosm_postgres",
            loader=loaders,
        )
        self.encryptable_store = self.graph.encryptable_store
        self.encrypted_store = self.graph.encrypted_store
        self.json_encryptable_store = self.graph.json_encryptable_store
        self.json_encrypted_store = self.graph.json_encrypted_store
        self.nullable_encryptable_store = self.graph.nullable_encryptable_store
        self.nullable_encrypted_store = self.graph.nullable_encrypted_store
        self.encryptor = self.graph.multi_tenant_encryptor

        with SessionContext(self.graph) as context:
            context.recreate_all()
    def setup(self):
        self.graph = create_object_graph(
            name="example",
            testing=True,
            import_name="microcosm_postgres",
        )
        self.company_store = self.graph.company_store

        self.companies = [
            Company(
                name="name1",
                type=CompanyType.private,
            ),
            Company(
                name="name2",
                type=CompanyType.private,
            ),
            Company(
                name="name3",
                type=CompanyType.private,
            ),
        ]

        with SessionContext(self.graph) as context:
            context.recreate_all()
Exemplo n.º 27
0
    def setup(self):
        self.graph = create_object_graph(name="example", testing=True)

        self.ns = Namespace(subject="file")
        self.relation_ns = Namespace(subject=Person, object_="file")

        self.controller = FileController()

        UPLOAD_MAPPINGS = {
            Operation.Upload: EndpointDefinition(
                func=self.controller.upload,
                request_schema=FileExtraSchema(),
            ),
        }

        UPLOAD_FOR_MAPPINGS = {
            Operation.UploadFor: EndpointDefinition(
                func=self.controller.upload_for_person,
                request_schema=FileExtraSchema(),
                response_schema=FileResponseSchema(),
            ),
        }

        configure_upload(self.graph, self.ns, UPLOAD_MAPPINGS)
        configure_upload(self.graph, self.relation_ns, UPLOAD_FOR_MAPPINGS)
        configure_swagger(self.graph)

        self.client = self.graph.flask.test_client()
Exemplo n.º 28
0
def test_encode_missing_field():
    """
    An invalid message will raise errors.

    """
    graph = create_object_graph("example", testing=True)
    codec = graph.pubsub_message_schema_registry.find(DerivedSchema.MEDIA_TYPE)
    assert_that(calling(codec.encode), raises(ValidationError))
Exemplo n.º 29
0
def test_custom_schema():
    """
    A configured message type will use its schema.

    """
    graph = create_object_graph("example", testing=True)
    codec = graph.pubsub_message_schema_registry.find(DerivedSchema.MEDIA_TYPE)
    assert_that(codec.schema, is_(instance_of(DerivedSchema)))
def test_name_for_testing():
    graph = create_object_graph("example", testing=True)
    graph.lock()

    assert_that(IndexRegistry.name_for(graph), is_(equal_to("example_test")))
    assert_that(IndexRegistry.name_for(graph, name="foo"), is_(equal_to("foo_test")))
    assert_that(IndexRegistry.name_for(graph, version="v1"), is_(equal_to("example_v1_test")))
    assert_that(IndexRegistry.name_for(graph, name="foo", version="v2"), is_(equal_to("foo_v2_test")))
Exemplo n.º 31
0
def test_paginated_list_relation_to_dict():
    graph = create_object_graph(name="example", testing=True)
    ns = Namespace(subject="foo", object_="bar")

    @graph.route(ns.relation_path, Operation.SearchFor, ns)
    def search_foo():
        pass

    paginated_list = PaginatedList(
        ns,
        Page(2, 2),
        ["1", "2"],
        10,
        operation=Operation.SearchFor,
        foo_id="FOO_ID",
    )

    with graph.flask.test_request_context():
        assert_that(
            paginated_list.to_dict(),
            is_(
                equal_to({
                    "count": 10,
                    "items": [
                        "1",
                        "2",
                    ],
                    "offset": 2,
                    "limit": 2,
                    "_links": {
                        "self": {
                            "href":
                            "http://localhost/api/foo/FOO_ID/bar?offset=2&limit=2",
                        },
                        "next": {
                            "href":
                            "http://localhost/api/foo/FOO_ID/bar?offset=4&limit=2",
                        },
                        "prev": {
                            "href":
                            "http://localhost/api/foo/FOO_ID/bar?offset=0&limit=2",
                        },
                    }
                })))
Exemplo n.º 32
0
def test_basic_auth_default_credentials():
    """
    Basic auth default credentials work.

    """
    graph = create_object_graph(name="example", testing=True)

    @graph.app.route("/ok")
    @graph.audit
    @graph.basic_auth.required
    def unauthorized():
        return "OK"

    client = graph.app.test_client()

    response = client.get("/ok", headers={
        "Authorization": encode_basic_auth("default", "secret"),
    })
    assert_that(response.status_code, is_(equal_to(200)))
Exemplo n.º 33
0
def test_qualified_operation_href_for():
    """
    Qualified operations add to the URI.

    """
    graph = create_object_graph(name="example", testing=True)
    ns = Namespace(subject="foo", qualifier="bar", version="v1")

    @graph.route(ns.collection_path, Operation.Search, ns)
    def search_foo():
        pass

    @graph.route(ns.instance_path, Operation.Retrieve, ns)
    def get_foo(foo_id):
        pass

    with graph.app.test_request_context():
        url = ns.href_for(Operation.Retrieve, foo_id="baz")
        assert_that(url, is_(equal_to("http://localhost/api/v1/bar/foo/baz")))
Exemplo n.º 34
0
def test_namespace_accepts_controller():
    """
    Namespaces may optionally contain a controller.

    """
    graph = create_object_graph(name="example", testing=True)
    controller = Mock()
    ns = Namespace(subject="foo", controller=controller)

    @graph.route(ns.collection_path, Operation.Search, ns)
    def search_foo():
        pass

    with graph.app.test_request_context():
        url = ns.href_for(Operation.Search)
        assert_that(url, is_(equal_to("http://localhost/api/foo")))
        url = ns.url_for(Operation.Search)
        assert_that(url, is_(equal_to("http://localhost/api/foo")))
        assert_that(ns.controller, is_(equal_to(controller)))
Exemplo n.º 35
0
def test_publish_batch_with_no_topic_fails():
    """
    Require explicit configuration of a topic for batch messages.

    """
    def loader(metadata):
        return dict(sns_topic_arns=dict(default="topic", ))

    graph = create_object_graph("example", testing=True, loader=loader)
    graph.use("opaque")

    # set up response
    graph.sns_producer.sns_client.publish.return_value = dict(
        MessageId=MESSAGE_ID)

    assert_that(
        calling(graph.sns_producer.produce).with_args(
            MessageBatchSchema.MEDIA_TYPE, messages=[]),
        raises(TopicNotDefinedError))
Exemplo n.º 36
0
    def test_get_resource_empty_headers(self):
        graph = create_object_graph("microcosm")
        graph.use(
            "opaque",
            "sqs_message_context",
        )
        graph.lock()

        uri = "http://localhost"
        message = dict(uri=uri, )

        with patch("microcosm_pubsub.handlers.uri_handler.get") as mocked_get:
            handler = URIHandler(graph)
            handler.get_resource(message, uri)

        mocked_get.assert_called_with(
            uri,
            headers=dict(),
        )
Exemplo n.º 37
0
    def setup(self):
        try:
            import microcosm_metrics  # noqa
        except ImportError:
            raise SkipTest

        self.graph = create_object_graph("example", testing=True)
        self.graph.use(
            "datadog_statsd",
            "flask",
            "route",
        )
        self.client = self.graph.flask.test_client()

        self.ns = Namespace(
            enable_metrics=True,
            subject="foo",
            version="v1",
        )
Exemplo n.º 38
0
def read(args):
    loader = load_from_dict(sqs_consumer=dict(
        profile_name=args.profile,
        region_name=args.region,
        sqs_queue_url=args.queue_url,
    ), )
    graph = create_object_graph("pubsub", debug=args.debug, loader=loader)
    graph.use("sqs_consumer")
    graph.lock()

    for message in graph.sqs_consumer.consume():
        print("Read SQS message: {} ({})".format(  # noqa
            message.message_id,
            message.approximate_receive_count,
        ))
        if args.nack:
            message.nack(args.nack_timeout)
        else:
            message.ack()
Exemplo n.º 39
0
def test_scoped_to():
    """
    Factory can be scoped to a specific value.

    """
    loader = load_from_dict(
        bar=dict(
            adder=dict(
                first=3,
            ),
        ),
    )
    graph = create_object_graph("example", testing=True, loader=loader)

    with graph.adder.scoped_to("bar"):
        assert_that(graph.adder(), is_(equal_to(5)))

    with graph.adder.scoped_to("baz"):
        assert_that(graph.adder(), is_(equal_to(3)))
Exemplo n.º 40
0
    def setup(self):
        self.graph = create_object_graph("example", testing=True)
        self.circle_store = self.graph.circle_store
        self.shape_store = self.graph.shape_store
        self.square_store = self.graph.square_store
        self.graph.elasticsearch_index_registry.createall(force=True)

        self.circle = Circle(
            id="circle",
            circumfrance=20,
        )
        self.shape = Shape(
            id="shape",
            area=10,
        )
        self.square = Square(
            id="square",
            perimeter=30,
        )
Exemplo n.º 41
0
def test_custom_headers():
    """
    Custom headers are sent to the client

    """
    graph = create_object_graph(name="example", testing=True)

    @graph.app.route("/foo")
    @graph.audit
    def foo():
        raise AuthenticationError()

    client = graph.app.test_client()

    response = client.get("/foo")
    data = response.json
    assert_that(data, has_entry("message", AuthenticationError.description))
    www_authenticate = response.headers.get('www-authenticate')
    assert_that(www_authenticate, equal_to('Basic realm=outer-zone'))
Exemplo n.º 42
0
def test_health_check():
    """
    Default health check returns OK.

    """
    loader = load_from_dict(health_convention=dict(
        include_build_info="false", ), )
    graph = create_object_graph(name="example", testing=True, loader=loader)
    graph.use("health_convention")

    client = graph.flask.test_client()

    response = client.get("/api/health")
    assert_that(response.status_code, is_(equal_to(200)))
    data = loads(response.get_data().decode("utf-8"))
    assert_that(data, is_(equal_to({
        "name": "example",
        "ok": True,
    })))
Exemplo n.º 43
0
def test_collaboration():
    """
    All microcosm collaborators should have access to the same opaque context.

    """
    # set up a parent collaborator that uses a child collaborator
    @binding("parent_collaborator")
    class Parent:
        def __init__(self, graph):
            self.child_collaborator = graph.child_collaborator

        def __call__(self):
            return self.child_collaborator()

    @binding("child_collaborator")
    class Child:
        def __init__(self, graph):
            self.opaque = graph.opaque

        def __call__(self):
            return self.opaque.as_dict()

    # create the object graph with both collaborators and opaque data
    graph = create_object_graph(
        "test",
        testing=True,
        loader=load_from_dict(opaque={THIS: VALUE}))

    graph.use(
        "child_collaborator",
        "opaque",
        "parent_collaborator",
    )
    graph.lock()

    # we should be able to initialize the opaque data and observe it from the collaborators
    decorated_func = graph.opaque.initialize(
        example_func, OTHER, OTHER
    )(graph.parent_collaborator.__call__)

    assert_that(graph.opaque.as_dict(), is_(equal_to({THIS: VALUE})))
    assert_that(decorated_func(), is_(equal_to(example_func(OTHER, OTHER))))
    assert_that(graph.opaque.as_dict(), is_(equal_to({THIS: VALUE})))
    def test_get_whitelisted_resource_with_cache_enabled_and_cache_hit(self):
        config = dict(
            resource_cache=dict(
                enabled=True,
            ),
        )
        graph = create_object_graph("microcosm", testing=True, loader=load_from_dict(config))
        graph.use(
            "opaque",
            "resource_cache",
            "sqs_message_context",
        )
        graph.lock()

        uri = "https://service.env.globality.io/api/v2/project_event/0598355c-5b19-49bd-a755-146204220a5b"
        media_type = "application/vnd.globality.pubsub._.created.project_event.project_brief_submitted"
        message = dict(
            uri=uri,
            mediaType=media_type,
        )
        json_data = dict(foo="bar", bar="baz")

        with patch("microcosm_pubsub.handlers.uri_handler.get") as mocked_get:
            mocked_get.return_value = MockResponse(
                status_code=200,
                json_data=json_data,
            )
            handler = URIHandler(graph)

            with patch.object(handler.resource_cache, "get") as mocked_cache_get:
                mocked_cache_get.return_value = json_data
                with patch.object(handler.resource_cache, "set") as mocked_cache_set:
                    handler.get_resource(message, uri)

        # Nb. cache get was attempted
        mocked_cache_get.assert_called_with(
            uri,
        )
        # Nb. actual resource HTTP retrieve not called since cache was hit
        assert_that(mocked_get.called, is_(equal_to(False)))

        # Nb. cache set was not called due to cache hit
        assert_that(mocked_cache_set.called, is_(equal_to(False)))
Exemplo n.º 45
0
def test_raw_sqs_envelope():
    graph = create_object_graph("example", testing=True)
    consumer = None
    message_id = "message_id"
    receipt_handle = "receipt_handle"
    envelope = RawSQSEnvelope(graph)

    sqs_message = envelope.parse_raw_message(
        consumer,
        dict(
            MessageId=message_id,
            ReceiptHandle=receipt_handle,
            Body=dumps(dict(foo="bar", )),
        ))

    assert_that(sqs_message.content, is_(equal_to(dict(foo="bar"))))
    assert_that(sqs_message.media_type, is_(equal_to("application/json")))
    assert_that(sqs_message.message_id, is_(equal_to(message_id)))
    assert_that(sqs_message.receipt_handle, is_(equal_to(receipt_handle)))
Exemplo n.º 46
0
def test_configure_logging_with_invalid_token():
    """
    Enabling loggly.

    """
    def loader(metadata):
        return dict(
            logging=dict(
                loggly=dict(
                    token=environ.get("LOGGLY_TOKEN", "TOKEN"),
                    environment="unittest",
                )
            )
        )

    graph = create_object_graph(name="test", loader=loader)
    graph.use("logger")

    graph.logger.info("Info will appear in loggly if LOGGLY_TOKEN is set correctly.")
Exemplo n.º 47
0
def test_publish_by_uri_convention():
    """
    Message publishing can use this convention.

    """
    def loader(metadata):
        return dict(sns_topic_arns=dict(default="default", ))

    graph = create_object_graph("example", testing=True, loader=loader)

    published_time = str(time())
    with patch("microcosm_pubsub.producer.time") as mocked_time:
        mocked_time.return_value = published_time
        graph.sns_producer.produce(created("foo"),
                                   uri="http://example.com",
                                   opaque_data=dict())

    assert_that(graph.sns_producer.sns_client.publish.call_count,
                is_(equal_to(1)))
    assert_that(graph.sns_producer.sns_client.publish.call_args[1]["TopicArn"],
                is_(equal_to("default")))
    assert_that(
        loads(graph.sns_producer.sns_client.publish.call_args[1]["Message"]),
        is_(
            equal_to({
                "mediaType": "application/vnd.globality.pubsub._.created.foo",
                "uri": "http://example.com",
                "opaqueData": {
                    "X-Request-Published": published_time,
                },
            })))
    assert_that(
        graph.sns_producer.sns_client.publish.call_args[1]
        ["MessageAttributes"],
        is_(
            equal_to({
                "media_type": {
                    "DataType": "String",
                    "StringValue":
                    "application/vnd.globality.pubsub._.created.foo"
                },
            })))
Exemplo n.º 48
0
def test_basic_auth():
    """
    Basic auth prevents resource access.

    """
    config = {
        "BASIC_AUTH_REALM": "microcosm",
    }

    graph = create_object_graph(name="example",
                                testing=True,
                                loader=lambda metadata: config)

    @graph.app.route("/unauthorized")
    @graph.audit
    @graph.basic_auth.required
    def unauthorized():
        raise Exception("Should not be raised!")

    client = graph.app.test_client()

    response = client.get("/unauthorized")
    assert_that(response.status_code, is_(equal_to(401)))
    data = loads(response.get_data().decode("utf-8"))
    assert_that(
        data,
        is_(
            equal_to({
                "code":
                401,
                "message":
                "The server could not verify that you are authorized to access the URL requested. "
                "You either supplied the wrong credentials (e.g. a bad password), or your browser "
                "doesn't understand how to supply the credentials required.",
                "retryable":
                False,
                "context": {
                    "errors": []
                },
            })))
    assert_that(response.headers["WWW-Authenticate"],
                is_(equal_to('Basic realm="microcosm"')))
Exemplo n.º 49
0
def test_no_prefix_no_version_path():
    loader = load_from_dict(
        dict(
            # We want our routes to come directly after the root /
            build_route_path=dict(prefix=""), ))
    graph = create_object_graph(name="example", testing=True, loader=loader)

    ns = Namespace(
        subject=Person,
        version="",
    )
    configure_crud(graph, ns, PERSON_MAPPINGS)

    with graph.flask.test_request_context():
        operations = list(iter_endpoints(graph, match_function))
        swagger_schema = build_swagger(graph, ns, operations)

    # Test that in a no prefix, no version case we still get a leading slash in our paths
    assert_that("/person" in swagger_schema["paths"])
    assert_that(swagger_schema["basePath"], equal_to("/"))
Exemplo n.º 50
0
    def setup(self):
        self.example_tmp_file = NamedTemporaryFile()
        loader = load_from_dict(
            sqlite=dict(
                paths=dict(
                    # NB using a file instead of ':memory:' path
                    # to preserve data after SQLAlchemy engine disposal.
                    example=self.example_tmp_file.name, ), ), )
        self.graph = create_object_graph(
            "example",
            testing=True,
            loader=loader,
        )
        self.foo_store = FooStore()
        self.foo = Foo(id=1)

        Foo.recreate_all(self.graph)
        Bar.recreate_all(self.graph)
        Baz.recreate_all(self.graph)
        Foo2.recreate_all(self.graph)
Exemplo n.º 51
0
def test_make_response():
    graph = create_object_graph(name="example", testing=True)
    formatter = JSONFormatter()

    with graph.app.test_request_context():
        response = formatter(dict(foo="bar"))

    assert_that(response.data, is_(equal_to(b'{"foo":"bar"}\n')))
    assert_that(response.content_type, is_(equal_to("application/json")))
    assert_that(
        response.headers,
        contains_inanyorder(
            ("Content-Type", "application/json"),
            ("Content-Length", "14"),
            ("ETag",
             etag_for(
                 md5_hash='"2f8acf3fe5e5c2839a04b7677d9399b8"',
                 spooky_hash='"af072b51e1eb2a8d7b2ab84dab972674"',
             )),
        ))
    def test_nack_when_404(self):
        graph = create_object_graph("microcosm")
        graph.use(
            "opaque",
            "sqs_message_context",
        )
        graph.lock()

        uri = "http://localhost"
        message = dict(
            uri=uri,
        )

        with patch("microcosm_pubsub.handlers.uri_handler.get") as mocked_get:
            mocked_get.return_value = MockResponse(dict(), 404)
            handler = URIHandler(graph)
            assert_that(
                calling(handler.get_resource).with_args(message, uri),
                raises(Nack),
            )
Exemplo n.º 53
0
    def setup(self):
        self.graph = create_object_graph(name="example",
                                         testing=True,
                                         import_name="microcosm_postgres")
        self.company_store = self.graph.company_store
        self.employee_store = self.graph.employee_store

        with SessionContext(self.graph) as context:
            context.recreate_all()

            with transaction():
                self.company = Company(
                    name="name",
                    type=CompanyType.private,
                ).create()
                self.employee = Employee(
                    first="first",
                    last="last",
                    company_id=self.company.id,
                ).create()
Exemplo n.º 54
0
    def setup(self):
        # override configuration to use "query" operations for swagger
        def loader(metadata):
            return dict(
                swagger_convention=dict(
                    # default behavior appends this list to defaults; use a tuple to override
                    operations=["command"],
                    version="v1",
                ), )

        self.graph = create_object_graph(name="example",
                                         testing=True,
                                         loader=loader)
        self.graph.use("swagger_convention")
        self.ns = Namespace(subject="foo")

        make_command(self.graph, self.ns, CommandArgumentSchema(),
                     CommandResultSchema())

        self.client = self.graph.flask.test_client()
Exemplo n.º 55
0
def test_configure_logging_with_custom_library_levels():
    """
    Logging levels can be configured.

    """
    def loader(metadata):
        return dict(
            logging=dict(level=INFO,
                         levels=dict(default=dict(debug=["foo", "bar"], ),
                                     override=dict(warn=["foo"], ))))

    graph = create_object_graph(name="test", testing=True, loader=loader)
    graph.use("logger")

    assert_that(getLogger("foo").getEffectiveLevel(), is_(equal_to(WARN)))
    assert_that(getLogger("bar").getEffectiveLevel(), is_(equal_to(DEBUG)))

    getLogger("bar").info("Bar should be visible at info")
    getLogger("foo").info("Foo should not be visible at info")
    getLogger("foo").warn("Foo should be visible at warn")
Exemplo n.º 56
0
    def setup(self):
        self.graph = create_object_graph(
            "microcosm_eventsource",
            root_path=join(dirname(__file__), pardir),
            testing=True,
        )
        self.graph.use(
            "task_store",
            "task_event_store",
            "activity_store",
            "activity_event_store",
        )
        self.store = self.graph.task_event_store

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()

        with transaction():
            self.task = Task().create()
Exemplo n.º 57
0
def test_offset_limit_page_to_paginated_list():
    graph = create_object_graph(name="example", testing=True)

    ns = Namespace("foo")

    @graph.flask.route("/", methods=["GET"], endpoint="foo.search.v1")
    def search():
        pass

    with graph.flask.test_request_context():
        page = OffsetLimitPage(
            offset=10,
            limit=10,
            foo="bar",
        )
        result = [], 0
        paginated_list, headers = page.to_paginated_list(
            result, _ns=ns, _operation=Operation.Search)

        schema_cls = page.make_paginated_list_schema_class(ns, Schema())
        data = schema_cls().dump(paginated_list).data
        assert_that(
            data,
            is_(
                equal_to(
                    dict(
                        offset=10,
                        limit=10,
                        count=0,
                        items=[],
                        _links=dict(
                            self=dict(
                                href=
                                "http://localhost/?offset=10&limit=10&foo=bar",
                            ),
                            prev=dict(
                                href=
                                "http://localhost/?offset=0&limit=10&foo=bar",
                            ),
                        ),
                    ))))
Exemplo n.º 58
0
def test_produce_custom_topic():
    """
    Producer delegates to SNS client.

    """
    def loader(metadata):
        return dict(sns_topic_arns=dict(
            default=None,
            mappings={
                DerivedSchema.MEDIA_TYPE: "special-topic",
            },
        ))

    graph = create_object_graph("example", testing=True, loader=loader)
    graph.use("opaque")

    # set up response
    graph.sns_producer.sns_client.publish.return_value = dict(
        MessageId=MESSAGE_ID)

    published_time = str(time())
    with patch("microcosm_pubsub.producer.time") as mocked_time:
        mocked_time.return_value = published_time
        message_id = graph.sns_producer.produce(DerivedSchema.MEDIA_TYPE,
                                                data="data")

    assert_that(graph.sns_producer.sns_client.publish.call_count,
                is_(equal_to(1)))
    assert_that(graph.sns_producer.sns_client.publish.call_args[1]["TopicArn"],
                is_(equal_to("special-topic")))
    assert_that(
        loads(graph.sns_producer.sns_client.publish.call_args[1]["Message"]),
        is_(
            equal_to({
                "data": "data",
                "mediaType": DerivedSchema.MEDIA_TYPE,
                "opaqueData": {
                    "X-Request-Published": published_time,
                },
            })))
    assert_that(message_id, is_(equal_to(MESSAGE_ID)))
Exemplo n.º 59
0
def test_config_discovery():
    """
    Config-minus secrets is shareable.

    """
    config = load_from_dict(config_convention=dict(enabled="true", ), )
    secrets = load_from_dict(config_convention=dict(enabled="true", ), )
    paritioned_loader = load_config_and_secrets(config, secrets)

    graph = create_object_graph(name="example",
                                testing=True,
                                loader=paritioned_loader)
    graph.use("config_convention")

    client = graph.flask.test_client()

    response = client.get("/api/config", )
    assert_that(response.status_code, is_(equal_to(200)))
    data = loads(response.get_data().decode("utf-8"))

    assert_that(data, has_entries(config_convention=dict(enabled="true")))
def test_threading():
    with NamedTemporaryFile() as tmp_file:
        loader = load_from_dict(sqlite=dict(paths=dict(
            example=tmp_file.name, ), ), )
        graph = create_object_graph("example", testing=True, loader=loader)
        store = PersonStore()

        Person.recreate_all(graph)

        with SessionContext(graph, Example) as context:
            gw = store.create(Person(id=1, first="George",
                                     last="Washington"), )
            tj = store.create(Person(id=2, first="Thomas", last="Jefferson"), )
            context.commit()

        pool = ThreadPool(2)

        store.get_session = GetOrCreateSession(graph)
        people = pool.map(lambda index: store.search()[index], range(2))

        assert_that(people, contains(gw, tj))