1#!/usr/bin/env ruby 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 33require 'conformance_pb' 34require 'google/protobuf/test_messages_proto3_pb' 35require 'google/protobuf/test_messages_proto2_pb' 36 37$test_count = 0 38$verbose = false 39 40def do_test(request) 41 test_message = ProtobufTestMessages::Proto3::TestAllTypesProto3.new 42 response = Conformance::ConformanceResponse.new 43 descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(request.message_type) 44 45 unless descriptor 46 response.skipped = "Unknown message type: " + request.message_type 47 end 48 49 begin 50 case request.payload 51 when :protobuf_payload 52 begin 53 test_message = descriptor.msgclass.decode(request.protobuf_payload) 54 rescue Google::Protobuf::ParseError => err 55 response.parse_error = err.message.encode('utf-8') 56 return response 57 end 58 59 when :json_payload 60 begin 61 options = {} 62 if request.test_category == :JSON_IGNORE_UNKNOWN_PARSING_TEST 63 options[:ignore_unknown_fields] = true 64 end 65 test_message = descriptor.msgclass.decode_json(request.json_payload, options) 66 rescue Google::Protobuf::ParseError => err 67 response.parse_error = err.message.encode('utf-8') 68 return response 69 end 70 71 when :text_payload 72 begin 73 response.skipped = "Ruby doesn't support text format" 74 return response 75 end 76 77 when nil 78 fail "Request didn't have payload" 79 end 80 81 case request.requested_output_format 82 when :UNSPECIFIED 83 fail 'Unspecified output format' 84 85 when :PROTOBUF 86 begin 87 response.protobuf_payload = test_message.to_proto 88 rescue Google::Protobuf::ParseError => err 89 response.serialize_error = err.message.encode('utf-8') 90 end 91 92 when :JSON 93 begin 94 response.json_payload = test_message.to_json 95 rescue Google::Protobuf::ParseError => err 96 response.serialize_error = err.message.encode('utf-8') 97 end 98 99 when nil 100 fail "Request didn't have requested output format" 101 end 102 rescue StandardError => err 103 response.runtime_error = err.message.encode('utf-8') 104 end 105 106 response 107end 108 109# Returns true if the test ran successfully, false on legitimate EOF. 110# If EOF is encountered in an unexpected place, raises IOError. 111def do_test_io 112 length_bytes = STDIN.read(4) 113 return false if length_bytes.nil? 114 115 length = length_bytes.unpack('V').first 116 serialized_request = STDIN.read(length) 117 if serialized_request.nil? || serialized_request.length != length 118 fail IOError 119 end 120 121 request = Conformance::ConformanceRequest.decode(serialized_request) 122 123 response = do_test(request) 124 125 serialized_response = Conformance::ConformanceResponse.encode(response) 126 STDOUT.write([serialized_response.length].pack('V')) 127 STDOUT.write(serialized_response) 128 STDOUT.flush 129 130 if $verbose 131 STDERR.puts("conformance_ruby: request=#{request.to_json}, " \ 132 "response=#{response.to_json}\n") 133 end 134 135 $test_count += 1 136 137 true 138end 139 140loop do 141 unless do_test_io 142 STDERR.puts('conformance_ruby: received EOF from test runner ' \ 143 "after #{$test_count} tests, exiting") 144 break 145 end 146end 147