def test_service_name_colliding_modules():
    service = make_service(name='ThingDoer',
                           methods=(
                               get_method('DoThing', 'foo.bar.ThingRequest',
                                          'foo.bar.ThingResponse'),
                               get_method('Jump', 'bacon.bar.JumpRequest',
                                          'bacon.bar.JumpResponse'),
                               get_method('Yawn', 'a.b.v1.c.YawnRequest',
                                          'a.b.v1.c.YawnResponse'),
                           ))
    expected_names = {
        'ThingDoer', 'ThingDoerClient', 'do_thing', 'jump', 'yawn', 'bar'
    }
    assert service.names == expected_names
def test_service_any_streaming():
    for client, server in itertools.product((True, False), (True, False)):
        service = make_service(
            f'ClientStream{client}:ServerStream{server}',
            methods=((make_method(
                f"GetMollusc",
                input_message=make_message("GetMolluscRequest", ),
                output_message=make_message("GetMolluscResponse", ),
                client_streaming=client,
                server_streaming=server,
            ), )))

        assert service.any_client_streaming == client
        assert service.any_server_streaming == server
예제 #3
0
def test_service_python_modules():
    service = make_service(methods=(
        get_method('DoThing', 'foo.bar.ThingRequest', 'foo.baz.ThingResponse'),
        get_method('Jump', 'foo.bacon.JumpRequest', 'foo.bacon.JumpResponse'),
        get_method('Yawn', 'a.b.v1.c.YawnRequest', 'x.y.v1.z.YawnResponse'),
    ))
    imports = {
        i.ident.python_import
        for m in service.methods.values() for i in m.ref_types
    }
    assert imports == {
        imp.Import(package=('a', 'b', 'v1'), module='c'),
        imp.Import(package=('foo', ), module='bacon'),
        imp.Import(package=('foo', ), module='bar'),
        imp.Import(package=('foo', ), module='baz'),
        imp.Import(package=('x', 'y', 'v1'), module='z'),
    }
예제 #4
0
def test_service_unknown_resource_reference():
    # This happens occasionally.
    opts = descriptor_pb2.FieldOptions()
    res_ref = opts.Extensions[resource_pb2.resource_reference]
    res_ref.type = "*"
    squid_request = make_message(
        "CreateSquid",
        fields=(make_field(
            "parent",
            type="TYPE_STRING",
            options=opts,
        ), ),
    )
    squid_service = make_service(
        "SquidService",
        methods=(make_method(
            "CreateSquid",
            input_message=squid_request,
        ), ),
    )

    assert not squid_service.resource_messages
예제 #5
0
def test_service_scopes():
    service = make_service(scopes=('https://foo/user/', 'https://foo/admin/'))
    assert 'https://foo/user/' in service.oauth_scopes
    assert 'https://foo/admin/' in service.oauth_scopes
예제 #6
0
def test_service_no_host():
    service = make_service()
    assert not service.host
예제 #7
0
def test_service_host():
    service = make_service(host='thingdoer.googleapis.com')
    assert service.host == 'thingdoer.googleapis.com'
예제 #8
0
def test_extended_operations_lro_detection():
    T = descriptor_pb2.FieldDescriptorProto.Type

    operation = make_message(
        name="Operation",
        fields=(make_field(
            name=name, type=T.Value("TYPE_STRING"),
            number=i) for i, name in enumerate(
                ("name", "status", "error_code", "error_message"), start=1)),
    )
    for f in operation.field:
        options = descriptor_pb2.FieldOptions()
        # Note: The field numbers were carefully chosen to be the corresponding enum values.
        options.Extensions[ex_ops_pb2.operation_field] = f.number
        f.options.MergeFrom(options)

    request = make_message(
        name="GetOperation",
        fields=[
            make_field(name="name", type=T.Value("TYPE_STRING"), number=1)
        ],
    )

    options = descriptor_pb2.MethodOptions()
    options.Extensions[ex_ops_pb2.operation_polling_method] = True
    polling_method = make_method(
        name="Get",
        input_message=request,
        output_message=operation,
        options=options,
    )

    ops_service = make_service(
        name="CustomOperations",
        methods=[
            polling_method,
            make_method(
                name="Delete",
                input_message=make_message(name="Input"),
                output_message=make_message("Output"),
            ),
        ],
    )

    assert not polling_method.operation_service

    # Methods are LROs, so they are not polling methods
    lro_opts = descriptor_pb2.MethodOptions()
    lro_opts.Extensions[ex_ops_pb2.operation_service] = "CustomOperations"
    lro = make_method(
        name="Start",
        input_message=make_message(name="StartRequest"),
        output_message=operation,
        options=lro_opts,
    )
    user_service = make_service(
        name="ComputationStarter",
        methods=[
            lro,
        ],
    )

    # Note: we can't have the operation_serivce property point to the actual operation service
    # because Service objects can't perform the lookup.
    # Instead we kick that can to the API object and make it do the lookup and verification.
    assert lro.operation_service == "CustomOperations"
예제 #9
0
def test_resource_messages_dict():
    # Regular, top level resource
    squid_resource = make_message("Squid", options=make_resource_opts("squid"))
    squid_request = make_message(
        "CreateSquid",
        fields=(make_field('squid', message=squid_resource), ),
    )

    # Nested resource
    squamosa_message = make_message(
        "Squamosa",
        options=make_resource_opts("clam", "squamosa"),
    )
    clam_resource = make_message(
        "Clam",
        options=make_resource_opts("clam"),
        fields=(make_field('squamosa', message=squamosa_message), ),
    )
    clam_request = make_message(
        'CreateClam',
        fields=(
            make_field('clam', message=clam_resource),
            # Red herring, not resources :)
            make_field('zone', 2, enum=make_enum('Zone')),
            make_field('pearls', 3, True, message=make_message('Pearl')),
        ),
    )

    # Some special APIs have request messages that _are_ resources.
    whelk_resource = make_message("Whelk", options=make_resource_opts("whelk"))

    # Not a resource
    octopus_request = make_message(
        "CreateOctopus",
        fields=(make_field('Octopus', message=make_message('Octopus')), ),
    )

    service = make_service('Molluscs',
                           methods=(make_method(
                               f"{message.name}",
                               input_message=message,
                           ) for message in (
                               squid_request,
                               clam_request,
                               whelk_resource,
                               octopus_request,
                           )))

    expected = {
        # Service specific
        "squid/{squid}":
        squid_resource,
        "clam/{clam}":
        clam_resource,
        "whelk/{whelk}":
        whelk_resource,
        "clam/{clam}/squamosa/{squamosa}":
        squamosa_message,
        # Common resources
        "cloudresourcemanager.googleapis.com/Project":
        service.common_resources["cloudresourcemanager.googleapis.com/Project"]
        .message_type,
        "cloudresourcemanager.googleapis.com/Organization":
        service.common_resources[
            "cloudresourcemanager.googleapis.com/Organization"].message_type,
        "cloudresourcemanager.googleapis.com/Folder":
        service.common_resources["cloudresourcemanager.googleapis.com/Folder"].
        message_type,
        "cloudbilling.googleapis.com/BillingAccount":
        service.common_resources["cloudbilling.googleapis.com/BillingAccount"].
        message_type,
        "locations.googleapis.com/Location":
        service.common_resources["locations.googleapis.com/Location"].
        message_type
    }
    actual = service.resource_messages_dict
    assert expected == actual
예제 #10
0
def test_module_name():
    service = make_service(name='MyService')
    assert service.module_name == 'my_service'
예제 #11
0
def test_service_no_lro():
    service = make_service()
    assert service.has_lro is False
예제 #12
0
def test_service_no_scopes():
    service = make_service()
    assert len(service.oauth_scopes) == 0
def test_resource_messages():
    # Resources are labeled via an options extension
    def make_resource_opts(*args):
        opts = descriptor_pb2.MessageOptions()
        opts.Extensions[resource_pb2.resource].pattern.append(
            "/".join("{{{arg}}}/{arg}" for arg in args)
        )
        return opts

    # Regular, top level resource
    squid_resource = make_message("Squid", options=make_resource_opts("squid"))
    squid_request = make_message(
        "CreateSquid",
        fields=(
            make_field('squid', message=squid_resource),
        ),
    )

    # Nested resource
    squamosa_message = make_message(
        "Squamosa",
        options=make_resource_opts("clam", "squamosa"),
    )
    clam_resource = make_message(
        "Clam",
        options=make_resource_opts("clam"),
        fields=(
            make_field('squamosa', message=squamosa_message),
        ),
    )
    clam_request = make_message(
        'CreateClam',
        fields=(
            make_field('clam', message=clam_resource),
            # Red herring, not resources :)
            make_field('zone', 2, enum=make_enum('Zone')),
            make_field('pearls', 3, True, message=make_message('Pearl')),
        ),
    )

    # Some special APIs have request messages that _are_ resources.
    whelk_resource = make_message("Whelk", options=make_resource_opts("whelk"))

    # Not a resource
    octopus_request = make_message(
        "CreateOctopus",
        fields=(
            make_field('Octopus', message=make_message('Octopus')),
        ),
    )

    service = make_service(
        'Molluscs',
        methods=(
            make_method(
                f"{message.name}",
                input_message=message,
            )
            for message in (
                squid_request,
                clam_request,
                whelk_resource,
                octopus_request,
            )
        )
    )

    expected = {
        squid_resource,
        clam_resource,
        whelk_resource,
        squamosa_message,
    }
    actual = service.resource_messages
    assert expected == actual
def test_service_properties():
    service = make_service(name='ThingDoer')
    assert service.name == 'ThingDoer'
    assert service.client_name == 'ThingDoerClient'
    assert service.transport_name == 'ThingDoerTransport'
    assert service.grpc_transport_name == 'ThingDoerGrpcTransport'
def test_operation_polling_method():
    T = descriptor_pb2.FieldDescriptorProto.Type

    operation = make_message(
        name="Operation",
        fields=[
            make_field(name=name, type=T.Value("TYPE_STRING"), number=i)
            for i, name in enumerate(
                ("name", "status", "error_code", "error_message"), start=1)
        ],
    )
    for f in operation.fields.values():
        options = descriptor_pb2.FieldOptions()
        # Note: The field numbers were carefully chosen to be the corresponding enum values.
        options.Extensions[ex_ops_pb2.operation_field] = f.number
        f.options.MergeFrom(options)

    request = make_message(
        name="GetOperation",
        fields=[
            make_field(name="name", type=T.Value("TYPE_STRING"), number=1)
        ],
    )

    options = descriptor_pb2.MethodOptions()
    options.Extensions[ex_ops_pb2.operation_polling_method] = True
    polling_method = make_method(
        name="Get",
        input_message=request,
        output_message=operation,
        options=options,
    )

    # Even though polling_method returns an Operation, it isn't an LRO
    ops_service = make_service(
        name="CustomOperations",
        methods=[
            polling_method,
            make_method(
                name="Delete",
                input_message=make_message(name="Input"),
                output_message=make_message("Output"),
            ),
        ],
    )

    assert ops_service.operation_polling_method == polling_method

    # Methods are LROs, so they are not polling methods
    user_service = make_service(
        name="ComputationStarter",
        methods=[
            make_method(
                name="Start",
                input_message=make_message(name="StartRequest"),
                output_message=operation,
            ),
        ],
    )

    assert not user_service.operation_polling_method