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