Google protobuf, match expected message size versus bytes received from network

49 views Asked by At

In order to test receiving and deserializing protobuf messages sent from a server I would like to check the received network bytes vs the expected size of a serialized fully populated message. There are some intermediate black-box steps and I want to check that the server sends the correct serialized message upon a request. I already assured that the received bytes from the network is actually a serialized message, but it is not clear if it is the correct one.

Still two messages could have the same serialized size but it is a corner case and when I hit something like this, this would be part of some further step and I don't want to include it into this question.

I used protoc with the --python_out dir option to generate a X_pb2.py file containing the message definitions from .proto file.

I thought of the following possible (hacky) alternatives:

1.) Iterate over the X_pb2.MY_Message().DESCRIPTOR.fields, determine the field sizes from their individual sizes and sum them up to get the expected size of the fully populated message

2.) Iterate over the X_pb2.MY_Message().DESCRIPTOR.fields, determine the field types and initialize them randomly. Then just call X_pb2.MY_Message().ByteSize()

3.) Initialize a X_pb2.MY_Message(), serialize it and then get the ByteSize()

However, I stumbled over some problems:

1.) When trying this alternative, the calculated expected size of the serialized msg is smaller then the original msg, which is impossible. E.g. a message consisting of [int8_t, int32_t, uint32_t] has a serialized size of 5 whereas the sum of the datatype sizes is 9. Code: sum([x.GetOptions().ByteSize() for x in X_pb2.MY_Message().DESCRIPTOR.fields])

2.) I did not found a generic way to set the fields value. It seems I can only set them via MY_MESSAGE().fieldx = ..., which is not suitable for generic access.

3.) Same as 2.)

Maybe you can help me find a solution so I can assert expected_size == bytes_received_from_network.

0

There are 0 answers