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