conformance_python.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # Protocol Buffers - Google's data interchange format
4 # Copyright 2008 Google Inc. All rights reserved.
5 # https://developers.google.com/protocol-buffers/
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are
9 # met:
10 #
11 # * Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following disclaimer
15 # in the documentation and/or other materials provided with the
16 # distribution.
17 # * Neither the name of Google Inc. nor the names of its
18 # contributors may be used to endorse or promote products derived from
19 # this software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 """A conformance test implementation for the Python protobuf library.
34 
35 See conformance.proto for more information.
36 """
37 
38 import struct
39 import sys
40 import os
41 from google.protobuf import descriptor
42 from google.protobuf import descriptor_pool
43 from google.protobuf import json_format
44 from google.protobuf import message
45 from google.protobuf import test_messages_proto3_pb2
46 from google.protobuf import test_messages_proto2_pb2
47 from google.protobuf import text_format
48 import conformance_pb2
49 
50 sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0)
51 sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0)
52 
53 test_count = 0
54 verbose = False
55 
56 class ProtocolError(Exception):
57  pass
58 
59 def do_test(request):
60  response = conformance_pb2.ConformanceResponse()
61 
62  if request.message_type == "conformance.FailureSet":
63  failure_set = conformance_pb2.FailureSet()
64  failures = []
65  # TODO(gerbens): Remove, this is a hack to detect if the old vs new
66  # parser is used by the cpp code. Relying on a bug in the old parser.
67  hack_proto = test_messages_proto2_pb2.TestAllTypesProto2()
68  old_parser = True
69  try:
70  hack_proto.ParseFromString(b"\322\002\001")
71  except message.DecodeError as e:
72  old_parser = False
73  if old_parser:
74  # the string above is one of the failing conformance test strings of the
75  # old parser. If we succeed the c++ implementation is using the old
76  # parser so we add the list of failing conformance tests.
77  failures = [
78  "Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
79  "Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
80  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.BOOL",
81  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.DOUBLE",
82  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.ENUM",
83  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED32",
84  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED64",
85  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.FLOAT",
86  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT32",
87  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT64",
88  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED32",
89  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED64",
90  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT32",
91  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT64",
92  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT32",
93  "Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT64",
94  "Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
95  "Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
96  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.BOOL",
97  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.DOUBLE",
98  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.ENUM",
99  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED32",
100  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED64",
101  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.FLOAT",
102  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT32",
103  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT64",
104  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED32",
105  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED64",
106  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT32",
107  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT64",
108  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT32",
109  "Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT64",
110  ]
111  for x in failures:
112  failure_set.failure.append(x)
113  response.protobuf_payload = failure_set.SerializeToString()
114  return response
115 
116  isProto3 = (request.message_type == "protobuf_test_messages.proto3.TestAllTypesProto3")
117  isJson = (request.WhichOneof('payload') == 'json_payload')
118  isProto2 = (request.message_type == "protobuf_test_messages.proto2.TestAllTypesProto2")
119 
120  if (not isProto3) and (not isJson) and (not isProto2):
121  raise ProtocolError("Protobuf request doesn't have specific payload type")
122 
123  test_message = test_messages_proto2_pb2.TestAllTypesProto2() if isProto2 else \
124  test_messages_proto3_pb2.TestAllTypesProto3()
125 
126  try:
127  if request.WhichOneof('payload') == 'protobuf_payload':
128  try:
129  test_message.ParseFromString(request.protobuf_payload)
130  except message.DecodeError as e:
131  response.parse_error = str(e)
132  return response
133 
134  elif request.WhichOneof('payload') == 'json_payload':
135  try:
136  ignore_unknown_fields = \
137  request.test_category == \
138  conformance_pb2.JSON_IGNORE_UNKNOWN_PARSING_TEST
139  json_format.Parse(request.json_payload, test_message,
140  ignore_unknown_fields)
141  except Exception as e:
142  response.parse_error = str(e)
143  return response
144 
145  elif request.WhichOneof('payload') == 'text_payload':
146  try:
147  text_format.Parse(request.text_payload, test_message)
148  except Exception as e:
149  response.parse_error = str(e)
150  return response
151 
152  else:
153  raise ProtocolError("Request didn't have payload.")
154 
155  if request.requested_output_format == conformance_pb2.UNSPECIFIED:
156  raise ProtocolError("Unspecified output format")
157 
158  elif request.requested_output_format == conformance_pb2.PROTOBUF:
159  response.protobuf_payload = test_message.SerializeToString()
160 
161  elif request.requested_output_format == conformance_pb2.JSON:
162  try:
163  response.json_payload = json_format.MessageToJson(test_message)
164  except Exception as e:
165  response.serialize_error = str(e)
166  return response
167 
168  elif request.requested_output_format == conformance_pb2.TEXT_FORMAT:
169  response.text_payload = text_format.MessageToString(
170  test_message, print_unknown_fields=request.print_unknown_fields)
171 
172  except Exception as e:
173  response.runtime_error = str(e)
174 
175  return response
176 
178  length_bytes = sys.stdin.read(4)
179  if len(length_bytes) == 0:
180  return False # EOF
181  elif len(length_bytes) != 4:
182  raise IOError("I/O error")
183 
184  # "I" is "unsigned int", so this depends on running on a platform with
185  # 32-bit "unsigned int" type. The Python struct module unfortunately
186  # has no format specifier for uint32_t.
187  length = struct.unpack("<I", length_bytes)[0]
188  serialized_request = sys.stdin.read(length)
189  if len(serialized_request) != length:
190  raise IOError("I/O error")
191 
192  request = conformance_pb2.ConformanceRequest()
193  request.ParseFromString(serialized_request)
194 
195  response = do_test(request)
196 
197  serialized_response = response.SerializeToString()
198  sys.stdout.write(struct.pack("<I", len(serialized_response)))
199  sys.stdout.write(serialized_response)
200  sys.stdout.flush()
201 
202  if verbose:
203  sys.stderr.write("conformance_python: request=%s, response=%s\n" % (
204  request.ShortDebugString().c_str(),
205  response.ShortDebugString().c_str()))
206 
207  global test_count
208  test_count += 1
209 
210  return True
211 
212 while True:
213  if not do_test_io():
214  sys.stderr.write("conformance_python: received EOF from test runner " +
215  "after %s tests, exiting\n" % (test_count))
216  sys.exit(0)
google::protobuf
Definition: data_proto2_to_proto3_util.h:12
conformance_python.ProtocolError
Definition: conformance_python.py:56
update_failure_list.str
str
Definition: update_failure_list.py:41
conformance_python.do_test
def do_test(request)
Definition: conformance_python.py:59
conformance_python.do_test_io
def do_test_io()
Definition: conformance_python.py:177
len
int len
Definition: php/ext/google/protobuf/map.c:206


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:48