1#!/usr/bin/env ruby 2# 3# Protocol Buffers - Google's data interchange format 4# Copyright 2008 Google Inc. All rights reserved. 5# 6# Use of this source code is governed by a BSD-style 7# license that can be found in the LICENSE file or at 8# https://developers.google.com/open-source/licenses/bsd 9 10require 'conformance/conformance_pb' 11require 'conformance/test_protos/test_messages_edition2023_pb' 12require 'google/protobuf' 13require 'google/protobuf/test_messages_proto3_pb' 14require 'google/protobuf/test_messages_proto2_pb' 15require 'test_messages_proto2_editions_pb' 16require 'test_messages_proto3_editions_pb' 17 18$test_count = 0 19$verbose = false 20 21def do_test(request) 22 test_message = ProtobufTestMessages::Proto3::TestAllTypesProto3.new 23 response = Conformance::ConformanceResponse.new 24 descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(request.message_type) 25 26 unless descriptor 27 response.runtime_error = "Unknown message type: " + request.message_type 28 return response 29 end 30 31 if request.test_category == :TEXT_FORMAT_TEST 32 response.skipped = "Ruby doesn't support text format" 33 return response 34 end 35 36 begin 37 case request.payload 38 when :protobuf_payload 39 begin 40 test_message = descriptor.msgclass.decode(request.protobuf_payload) 41 rescue Google::Protobuf::ParseError => err 42 response.parse_error = err.message.encode('utf-8') 43 return response 44 end 45 46 when :json_payload 47 begin 48 options = {} 49 if request.test_category == :JSON_IGNORE_UNKNOWN_PARSING_TEST 50 options[:ignore_unknown_fields] = true 51 end 52 test_message = descriptor.msgclass.decode_json(request.json_payload, options) 53 rescue Google::Protobuf::ParseError => err 54 response.parse_error = err.message.encode('utf-8') 55 return response 56 end 57 58 when nil 59 fail "Request didn't have payload" 60 end 61 62 case request.requested_output_format 63 when :UNSPECIFIED 64 fail 'Unspecified output format' 65 66 when :PROTOBUF 67 begin 68 response.protobuf_payload = test_message.to_proto 69 rescue Google::Protobuf::ParseError => err 70 response.serialize_error = err.message.encode('utf-8') 71 end 72 73 when :JSON 74 begin 75 response.json_payload = test_message.to_json 76 rescue Google::Protobuf::ParseError => err 77 response.serialize_error = err.message.encode('utf-8') 78 end 79 80 when nil 81 fail "Request didn't have requested output format" 82 end 83 rescue StandardError => err 84 response.runtime_error = err.message.encode('utf-8') 85 end 86 87 response 88end 89 90# Returns true if the test ran successfully, false on legitimate EOF. 91# If EOF is encountered in an unexpected place, raises IOError. 92def do_test_io 93 length_bytes = STDIN.read(4) 94 return false if length_bytes.nil? 95 96 length = length_bytes.unpack('V').first 97 serialized_request = STDIN.read(length) 98 if serialized_request.nil? || serialized_request.length != length 99 fail IOError 100 end 101 102 request = Conformance::ConformanceRequest.decode(serialized_request) 103 104 response = do_test(request) 105 106 serialized_response = Conformance::ConformanceResponse.encode(response) 107 STDOUT.write([serialized_response.length].pack('V')) 108 STDOUT.write(serialized_response) 109 STDOUT.flush 110 111 if $verbose 112 STDERR.puts("conformance_ruby: request=#{request.to_json}, " \ 113 "response=#{response.to_json}\n") 114 end 115 116 $test_count += 1 117 118 true 119end 120 121loop do 122 unless do_test_io 123 STDERR.puts('conformance_ruby: received EOF from test runner ' \ 124 "after #{$test_count} tests, exiting") 125 break 126 end 127end 128