• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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