dep-protobuf/python/google/protobuf/internal/service_reflection_test.py

140 lines
3.8 KiB
Python
Raw Permalink Normal View History

2008-07-10 02:12:20 +00:00
# Protocol Buffers - Google's data interchange format
Integrate changes from internal Google-internal branch. General * License changed from Apache 2.0 to New BSD. * It is now possible to define custom "options", which are basically annotations which may be placed on definitions in a .proto file. For example, you might define a field option called "foo" like so: import "google/protobuf/descriptor.proto" extend google.protobuf.FieldOptions { optional string foo = 12345; } Then you annotate a field using the "foo" option: message MyMessage { optional int32 some_field = 1 [(foo) = "bar"] } The value of this option is then visible via the message's Descriptor: const FieldDescriptor* field = MyMessage::descriptor()->FindFieldByName("some_field"); assert(field->options().GetExtension(foo) == "bar"); This feature has been implemented and tested in C++ and Java. Other languages may or may not need to do extra work to support custom options, depending on how they construct descriptors. C++ * Fixed some GCC warnings that only occur when using -pedantic. * Improved static initialization code, making ordering more predictable among other things. * TextFormat will no longer accept messages which contain multiple instances of a singular field. Previously, the latter instance would overwrite the former. * Now works on systems that don't have hash_map. Python * Strings now use the "unicode" type rather than the "str" type. String fields may still be assigned ASCII "str" values; they will automatically be converted. * Adding a property to an object representing a repeated field now raises an exception. For example: # No longer works (and never should have). message.some_repeated_field.foo = 1
2008-09-24 20:31:01 +00:00
# Copyright 2008 Google Inc. All rights reserved.
2008-07-10 02:12:20 +00:00
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
2008-07-10 02:12:20 +00:00
"""Tests for google.protobuf.internal.service_reflection."""
__author__ = 'petar@google.com (Petar Petrov)'
2016-03-30 11:39:59 -07:00
import unittest
2016-03-30 11:39:59 -07:00
2008-07-10 02:12:20 +00:00
from google.protobuf import service_reflection
from google.protobuf import unittest_pb2
2008-07-10 02:12:20 +00:00
class FooUnitTest(unittest.TestCase):
2008-07-10 02:12:20 +00:00
def testService(self):
class MockRpcChannel:
2008-07-10 02:12:20 +00:00
def CallMethod(self, method, controller, request, response, callback):
self.method = method
self.controller = controller
self.request = request
callback(response)
class MockRpcController:
2008-07-10 02:12:20 +00:00
def SetFailed(self, msg):
self.failure_message = msg
self.callback_response = None
class MyService(unittest_pb2.TestService):
pass
self.callback_response = None
def MyCallback(response):
self.callback_response = response
rpc_controller = MockRpcController()
channel = MockRpcChannel()
srvc = MyService()
srvc.Foo(rpc_controller, unittest_pb2.FooRequest(), MyCallback)
self.assertEqual(
'Method Foo not implemented.', rpc_controller.failure_message
)
2008-07-10 02:12:20 +00:00
self.assertEqual(None, self.callback_response)
rpc_controller.failure_message = None
Push out changes from internal codebase. All Languages * Repeated fields of primitive types (types other that string, group, and nested messages) may now use the option [packed = true] to get a more efficient encoding. In the new encoding, the entire list is written as a single byte blob using the "length-delimited" wire type. Within this blob, the individual values are encoded the same way they would be normally except without a tag before each value (thus, they are tightly "packed"). C++ * UnknownFieldSet now supports STL-like iteration. * Message interface has method ParseFromBoundedZeroCopyStream() which parses a limited number of bytes from an input stream rather than parsing until EOF. Java * Fixed bug where Message.mergeFrom(Message) failed to merge extensions. * Message interface has new method toBuilder() which is equivalent to newBuilderForType().mergeFrom(this). * All enums now implement the ProtocolMessageEnum interface. * Setting a field to null now throws NullPointerException. * Fixed tendency for TextFormat's parsing to overflow the stack when parsing large string values. The underlying problem is with Java's regex implementation (which unfortunately uses recursive backtracking rather than building an NFA). Worked around by making use of possesive quantifiers. Python * Updated RPC interfaces to allow for blocking operation. A client may now pass None for a callback when making an RPC, in which case the call will block until the response is received, and the response object will be returned directly to the caller. This interface change cannot be used in practice until RPC implementations are updated to implement it.
2009-01-22 01:27:00 +00:00
service_descriptor = unittest_pb2.TestService.GetDescriptor()
srvc.CallMethod(
service_descriptor.methods[1],
rpc_controller,
unittest_pb2.BarRequest(),
MyCallback,
)
self.assertTrue(
srvc.GetRequestClass(service_descriptor.methods[1])
is unittest_pb2.BarRequest
)
self.assertTrue(
srvc.GetResponseClass(service_descriptor.methods[1])
is unittest_pb2.BarResponse
)
self.assertEqual(
'Method Bar not implemented.', rpc_controller.failure_message
)
2008-07-10 02:12:20 +00:00
self.assertEqual(None, self.callback_response)
2015-08-12 14:22:25 -04:00
class MyServiceImpl(unittest_pb2.TestService):
def Foo(self, rpc_controller, request, done):
self.foo_called = True
def Bar(self, rpc_controller, request, done):
self.bar_called = True
srvc = MyServiceImpl()
rpc_controller.failure_message = None
srvc.Foo(rpc_controller, unittest_pb2.FooRequest(), MyCallback)
self.assertEqual(None, rpc_controller.failure_message)
self.assertEqual(True, srvc.foo_called)
rpc_controller.failure_message = None
srvc.CallMethod(
service_descriptor.methods[1],
rpc_controller,
unittest_pb2.BarRequest(),
MyCallback,
)
self.assertEqual(None, rpc_controller.failure_message)
self.assertEqual(True, srvc.bar_called)
2008-07-10 02:12:20 +00:00
def testServiceStub(self):
class MockRpcChannel:
def CallMethod(
self, method, controller, request, response_class, callback
):
2008-07-10 02:12:20 +00:00
self.method = method
self.controller = controller
self.request = request
callback(response_class())
self.callback_response = None
def MyCallback(response):
self.callback_response = response
channel = MockRpcChannel()
stub = unittest_pb2.TestService_Stub(channel)
rpc_controller = 'controller'
request = 'request'
# GetDescriptor now static, still works as instance method for compatibility
self.assertEqual(
unittest_pb2.TestService_Stub.GetDescriptor(), stub.GetDescriptor()
)
Push out changes from internal codebase. All Languages * Repeated fields of primitive types (types other that string, group, and nested messages) may now use the option [packed = true] to get a more efficient encoding. In the new encoding, the entire list is written as a single byte blob using the "length-delimited" wire type. Within this blob, the individual values are encoded the same way they would be normally except without a tag before each value (thus, they are tightly "packed"). C++ * UnknownFieldSet now supports STL-like iteration. * Message interface has method ParseFromBoundedZeroCopyStream() which parses a limited number of bytes from an input stream rather than parsing until EOF. Java * Fixed bug where Message.mergeFrom(Message) failed to merge extensions. * Message interface has new method toBuilder() which is equivalent to newBuilderForType().mergeFrom(this). * All enums now implement the ProtocolMessageEnum interface. * Setting a field to null now throws NullPointerException. * Fixed tendency for TextFormat's parsing to overflow the stack when parsing large string values. The underlying problem is with Java's regex implementation (which unfortunately uses recursive backtracking rather than building an NFA). Worked around by making use of possesive quantifiers. Python * Updated RPC interfaces to allow for blocking operation. A client may now pass None for a callback when making an RPC, in which case the call will block until the response is received, and the response object will be returned directly to the caller. This interface change cannot be used in practice until RPC implementations are updated to implement it.
2009-01-22 01:27:00 +00:00
2008-07-10 02:12:20 +00:00
# Invoke method.
stub.Foo(rpc_controller, request, MyCallback)
2015-08-12 14:22:25 -04:00
self.assertIsInstance(self.callback_response, unittest_pb2.FooResponse)
2008-07-10 02:12:20 +00:00
self.assertEqual(request, channel.request)
self.assertEqual(rpc_controller, channel.controller)
self.assertEqual(stub.GetDescriptor().methods[0], channel.method)
if __name__ == '__main__':
unittest.main()