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