grpc 0.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +10 -0
  5. data/.rubocop_todo.yml +52 -0
  6. data/Gemfile +4 -0
  7. data/README.md +82 -0
  8. data/Rakefile +54 -0
  9. data/bin/apis/google/protobuf/empty.rb +44 -0
  10. data/bin/apis/pubsub_demo.rb +267 -0
  11. data/bin/apis/tech/pubsub/proto/pubsub.rb +174 -0
  12. data/bin/apis/tech/pubsub/proto/pubsub_services.rb +103 -0
  13. data/bin/interop/README.md +8 -0
  14. data/bin/interop/interop_client.rb +334 -0
  15. data/bin/interop/interop_server.rb +192 -0
  16. data/bin/interop/test/cpp/interop/empty.rb +44 -0
  17. data/bin/interop/test/cpp/interop/messages.rb +89 -0
  18. data/bin/interop/test/cpp/interop/test.rb +43 -0
  19. data/bin/interop/test/cpp/interop/test_services.rb +60 -0
  20. data/bin/math.proto +80 -0
  21. data/bin/math.rb +61 -0
  22. data/bin/math_client.rb +147 -0
  23. data/bin/math_server.rb +190 -0
  24. data/bin/math_services.rb +56 -0
  25. data/bin/noproto_client.rb +108 -0
  26. data/bin/noproto_server.rb +112 -0
  27. data/ext/grpc/extconf.rb +76 -0
  28. data/ext/grpc/rb_byte_buffer.c +241 -0
  29. data/ext/grpc/rb_byte_buffer.h +54 -0
  30. data/ext/grpc/rb_call.c +569 -0
  31. data/ext/grpc/rb_call.h +59 -0
  32. data/ext/grpc/rb_channel.c +264 -0
  33. data/ext/grpc/rb_channel.h +49 -0
  34. data/ext/grpc/rb_channel_args.c +154 -0
  35. data/ext/grpc/rb_channel_args.h +52 -0
  36. data/ext/grpc/rb_completion_queue.c +185 -0
  37. data/ext/grpc/rb_completion_queue.h +50 -0
  38. data/ext/grpc/rb_credentials.c +281 -0
  39. data/ext/grpc/rb_credentials.h +50 -0
  40. data/ext/grpc/rb_event.c +361 -0
  41. data/ext/grpc/rb_event.h +53 -0
  42. data/ext/grpc/rb_grpc.c +274 -0
  43. data/ext/grpc/rb_grpc.h +74 -0
  44. data/ext/grpc/rb_metadata.c +215 -0
  45. data/ext/grpc/rb_metadata.h +53 -0
  46. data/ext/grpc/rb_server.c +278 -0
  47. data/ext/grpc/rb_server.h +50 -0
  48. data/ext/grpc/rb_server_credentials.c +210 -0
  49. data/ext/grpc/rb_server_credentials.h +50 -0
  50. data/grpc.gemspec +41 -0
  51. data/lib/grpc.rb +39 -0
  52. data/lib/grpc/core/event.rb +44 -0
  53. data/lib/grpc/core/time_consts.rb +71 -0
  54. data/lib/grpc/errors.rb +61 -0
  55. data/lib/grpc/generic/active_call.rb +536 -0
  56. data/lib/grpc/generic/bidi_call.rb +221 -0
  57. data/lib/grpc/generic/client_stub.rb +413 -0
  58. data/lib/grpc/generic/rpc_desc.rb +150 -0
  59. data/lib/grpc/generic/rpc_server.rb +404 -0
  60. data/lib/grpc/generic/service.rb +235 -0
  61. data/lib/grpc/logconfig.rb +40 -0
  62. data/lib/grpc/version.rb +33 -0
  63. data/spec/alloc_spec.rb +44 -0
  64. data/spec/byte_buffer_spec.rb +67 -0
  65. data/spec/call_spec.rb +163 -0
  66. data/spec/channel_spec.rb +181 -0
  67. data/spec/client_server_spec.rb +372 -0
  68. data/spec/completion_queue_spec.rb +74 -0
  69. data/spec/credentials_spec.rb +71 -0
  70. data/spec/event_spec.rb +53 -0
  71. data/spec/generic/active_call_spec.rb +373 -0
  72. data/spec/generic/client_stub_spec.rb +519 -0
  73. data/spec/generic/rpc_desc_spec.rb +357 -0
  74. data/spec/generic/rpc_server_pool_spec.rb +139 -0
  75. data/spec/generic/rpc_server_spec.rb +404 -0
  76. data/spec/generic/service_spec.rb +342 -0
  77. data/spec/metadata_spec.rb +64 -0
  78. data/spec/server_credentials_spec.rb +69 -0
  79. data/spec/server_spec.rb +212 -0
  80. data/spec/spec_helper.rb +51 -0
  81. data/spec/testdata/README +1 -0
  82. data/spec/testdata/ca.pem +15 -0
  83. data/spec/testdata/server1.key +16 -0
  84. data/spec/testdata/server1.pem +16 -0
  85. data/spec/time_consts_spec.rb +89 -0
  86. metadata +353 -0
@@ -0,0 +1,174 @@
1
+ # Copyright 2015, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
31
+ # source: tech/pubsub/proto/pubsub.proto
32
+
33
+ require 'google/protobuf'
34
+
35
+ require 'google/protobuf/empty'
36
+ Google::Protobuf::DescriptorPool.generated_pool.build do
37
+ add_message "tech.pubsub.Topic" do
38
+ optional :name, :string, 1
39
+ end
40
+ add_message "tech.pubsub.PubsubMessage" do
41
+ optional :data, :string, 1
42
+ optional :message_id, :string, 3
43
+ end
44
+ add_message "tech.pubsub.GetTopicRequest" do
45
+ optional :topic, :string, 1
46
+ end
47
+ add_message "tech.pubsub.PublishRequest" do
48
+ optional :topic, :string, 1
49
+ optional :message, :message, 2, "tech.pubsub.PubsubMessage"
50
+ end
51
+ add_message "tech.pubsub.PublishBatchRequest" do
52
+ optional :topic, :string, 1
53
+ repeated :messages, :message, 2, "tech.pubsub.PubsubMessage"
54
+ end
55
+ add_message "tech.pubsub.PublishBatchResponse" do
56
+ repeated :message_ids, :string, 1
57
+ end
58
+ add_message "tech.pubsub.ListTopicsRequest" do
59
+ optional :query, :string, 1
60
+ optional :max_results, :int32, 2
61
+ optional :page_token, :string, 3
62
+ end
63
+ add_message "tech.pubsub.ListTopicsResponse" do
64
+ repeated :topic, :message, 1, "tech.pubsub.Topic"
65
+ optional :next_page_token, :string, 2
66
+ end
67
+ add_message "tech.pubsub.DeleteTopicRequest" do
68
+ optional :topic, :string, 1
69
+ end
70
+ add_message "tech.pubsub.Subscription" do
71
+ optional :name, :string, 1
72
+ optional :topic, :string, 2
73
+ optional :query, :string, 3
74
+ optional :truncation_policy, :message, 4, "tech.pubsub.Subscription.TruncationPolicy"
75
+ optional :push_config, :message, 5, "tech.pubsub.PushConfig"
76
+ optional :ack_deadline_seconds, :int32, 6
77
+ optional :garbage_collect_seconds, :int64, 7
78
+ end
79
+ add_message "tech.pubsub.Subscription.TruncationPolicy" do
80
+ optional :max_bytes, :int64, 1
81
+ optional :max_age_seconds, :int64, 2
82
+ end
83
+ add_message "tech.pubsub.PushConfig" do
84
+ optional :push_endpoint, :string, 1
85
+ end
86
+ add_message "tech.pubsub.PubsubEvent" do
87
+ optional :subscription, :string, 1
88
+ optional :message, :message, 2, "tech.pubsub.PubsubMessage"
89
+ optional :truncated, :bool, 3
90
+ optional :deleted, :bool, 4
91
+ end
92
+ add_message "tech.pubsub.GetSubscriptionRequest" do
93
+ optional :subscription, :string, 1
94
+ end
95
+ add_message "tech.pubsub.ListSubscriptionsRequest" do
96
+ optional :query, :string, 1
97
+ optional :max_results, :int32, 3
98
+ optional :page_token, :string, 4
99
+ end
100
+ add_message "tech.pubsub.ListSubscriptionsResponse" do
101
+ repeated :subscription, :message, 1, "tech.pubsub.Subscription"
102
+ optional :next_page_token, :string, 2
103
+ end
104
+ add_message "tech.pubsub.TruncateSubscriptionRequest" do
105
+ optional :subscription, :string, 1
106
+ end
107
+ add_message "tech.pubsub.DeleteSubscriptionRequest" do
108
+ optional :subscription, :string, 1
109
+ end
110
+ add_message "tech.pubsub.ModifyPushConfigRequest" do
111
+ optional :subscription, :string, 1
112
+ optional :push_config, :message, 2, "tech.pubsub.PushConfig"
113
+ end
114
+ add_message "tech.pubsub.PullRequest" do
115
+ optional :subscription, :string, 1
116
+ optional :return_immediately, :bool, 2
117
+ end
118
+ add_message "tech.pubsub.PullResponse" do
119
+ optional :ack_id, :string, 1
120
+ optional :pubsub_event, :message, 2, "tech.pubsub.PubsubEvent"
121
+ end
122
+ add_message "tech.pubsub.PullBatchRequest" do
123
+ optional :subscription, :string, 1
124
+ optional :return_immediately, :bool, 2
125
+ optional :max_events, :int32, 3
126
+ end
127
+ add_message "tech.pubsub.PullBatchResponse" do
128
+ repeated :pull_responses, :message, 2, "tech.pubsub.PullResponse"
129
+ end
130
+ add_message "tech.pubsub.ModifyAckDeadlineRequest" do
131
+ optional :subscription, :string, 1
132
+ optional :ack_id, :string, 2
133
+ optional :ack_deadline_seconds, :int32, 3
134
+ end
135
+ add_message "tech.pubsub.AcknowledgeRequest" do
136
+ optional :subscription, :string, 1
137
+ repeated :ack_id, :string, 2
138
+ end
139
+ add_message "tech.pubsub.NackRequest" do
140
+ optional :subscription, :string, 1
141
+ repeated :ack_id, :string, 2
142
+ end
143
+ end
144
+
145
+ module Tech
146
+ module Pubsub
147
+ Topic = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.Topic").msgclass
148
+ PubsubMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PubsubMessage").msgclass
149
+ GetTopicRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.GetTopicRequest").msgclass
150
+ PublishRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PublishRequest").msgclass
151
+ PublishBatchRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PublishBatchRequest").msgclass
152
+ PublishBatchResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PublishBatchResponse").msgclass
153
+ ListTopicsRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListTopicsRequest").msgclass
154
+ ListTopicsResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListTopicsResponse").msgclass
155
+ DeleteTopicRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.DeleteTopicRequest").msgclass
156
+ Subscription = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.Subscription").msgclass
157
+ Subscription::TruncationPolicy = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.Subscription.TruncationPolicy").msgclass
158
+ PushConfig = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PushConfig").msgclass
159
+ PubsubEvent = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PubsubEvent").msgclass
160
+ GetSubscriptionRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.GetSubscriptionRequest").msgclass
161
+ ListSubscriptionsRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListSubscriptionsRequest").msgclass
162
+ ListSubscriptionsResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListSubscriptionsResponse").msgclass
163
+ TruncateSubscriptionRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.TruncateSubscriptionRequest").msgclass
164
+ DeleteSubscriptionRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.DeleteSubscriptionRequest").msgclass
165
+ ModifyPushConfigRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ModifyPushConfigRequest").msgclass
166
+ PullRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullRequest").msgclass
167
+ PullResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullResponse").msgclass
168
+ PullBatchRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullBatchRequest").msgclass
169
+ PullBatchResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullBatchResponse").msgclass
170
+ ModifyAckDeadlineRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ModifyAckDeadlineRequest").msgclass
171
+ AcknowledgeRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.AcknowledgeRequest").msgclass
172
+ NackRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.NackRequest").msgclass
173
+ end
174
+ end
@@ -0,0 +1,103 @@
1
+ # Copyright 2015, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
31
+ # Source: tech/pubsub/proto/pubsub.proto for package 'tech.pubsub'
32
+
33
+ require 'grpc'
34
+ require 'google/protobuf/empty'
35
+ require 'tech/pubsub/proto/pubsub'
36
+
37
+ module Tech
38
+ module Pubsub
39
+ module PublisherService
40
+
41
+ # TODO: add proto service documentation here
42
+ class Service
43
+
44
+ include GRPC::GenericService
45
+
46
+ self.marshal_class_method = :encode
47
+ self.unmarshal_class_method = :decode
48
+ self.service_name = 'tech.pubsub.PublisherService'
49
+
50
+ rpc :CreateTopic, Topic, Topic
51
+ rpc :Publish, PublishRequest, Google::Protobuf::Empty
52
+ rpc :PublishBatch, PublishBatchRequest, PublishBatchResponse
53
+ rpc :GetTopic, GetTopicRequest, Topic
54
+ rpc :ListTopics, ListTopicsRequest, ListTopicsResponse
55
+ rpc :DeleteTopic, DeleteTopicRequest, Google::Protobuf::Empty
56
+ end
57
+
58
+ Stub = Service.rpc_stub_class
59
+ end
60
+ module SubscriberService
61
+
62
+ # TODO: add proto service documentation here
63
+ class Service
64
+
65
+ include GRPC::GenericService
66
+
67
+ self.marshal_class_method = :encode
68
+ self.unmarshal_class_method = :decode
69
+ self.service_name = 'tech.pubsub.SubscriberService'
70
+
71
+ rpc :CreateSubscription, Subscription, Subscription
72
+ rpc :GetSubscription, GetSubscriptionRequest, Subscription
73
+ rpc :ListSubscriptions, ListSubscriptionsRequest, ListSubscriptionsResponse
74
+ rpc :DeleteSubscription, DeleteSubscriptionRequest, Google::Protobuf::Empty
75
+ rpc :TruncateSubscription, TruncateSubscriptionRequest, Google::Protobuf::Empty
76
+ rpc :ModifyPushConfig, ModifyPushConfigRequest, Google::Protobuf::Empty
77
+ rpc :Pull, PullRequest, PullResponse
78
+ rpc :PullBatch, PullBatchRequest, PullBatchResponse
79
+ rpc :ModifyAckDeadline, ModifyAckDeadlineRequest, Google::Protobuf::Empty
80
+ rpc :Acknowledge, AcknowledgeRequest, Google::Protobuf::Empty
81
+ rpc :Nack, NackRequest, Google::Protobuf::Empty
82
+ end
83
+
84
+ Stub = Service.rpc_stub_class
85
+ end
86
+ module PushEndpointService
87
+
88
+ # TODO: add proto service documentation here
89
+ class Service
90
+
91
+ include GRPC::GenericService
92
+
93
+ self.marshal_class_method = :encode
94
+ self.unmarshal_class_method = :decode
95
+ self.service_name = 'tech.pubsub.PushEndpointService'
96
+
97
+ rpc :HandlePubsubEvent, PubsubEvent, Google::Protobuf::Empty
98
+ end
99
+
100
+ Stub = Service.rpc_stub_class
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,8 @@
1
+ Interop test protos
2
+ ===================
3
+
4
+ These ruby classes were generated with protoc v3, using grpc's ruby compiler
5
+ plugin.
6
+
7
+ - As of 2015/01 protoc v3 is available in the
8
+ [google-protobuf](https://github.com/google/protobuf) repo
@@ -0,0 +1,334 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright 2015, Google Inc.
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are
8
+ # met:
9
+ #
10
+ # * Redistributions of source code must retain the above copyright
11
+ # notice, this list of conditions and the following disclaimer.
12
+ # * Redistributions in binary form must reproduce the above
13
+ # copyright notice, this list of conditions and the following disclaimer
14
+ # in the documentation and/or other materials provided with the
15
+ # distribution.
16
+ # * Neither the name of Google Inc. nor the names of its
17
+ # contributors may be used to endorse or promote products derived from
18
+ # this software without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ # interop_client is a testing tool that accesses a gRPC interop testing
33
+ # server and runs a test on it.
34
+ #
35
+ # Helps validate interoperation b/w different gRPC implementations.
36
+ #
37
+ # Usage: $ path/to/interop_client.rb --server_host=<hostname> \
38
+ # --server_port=<port> \
39
+ # --test_case=<testcase_name>
40
+
41
+ this_dir = File.expand_path(File.dirname(__FILE__))
42
+ lib_dir = File.join(File.dirname(File.dirname(this_dir)), 'lib')
43
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
44
+ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
45
+
46
+ require 'optparse'
47
+ require 'minitest'
48
+ require 'minitest/assertions'
49
+
50
+ require 'grpc'
51
+ require 'googleauth'
52
+ require 'google/protobuf'
53
+
54
+ require 'test/cpp/interop/test_services'
55
+ require 'test/cpp/interop/messages'
56
+ require 'test/cpp/interop/empty'
57
+
58
+ require 'signet/ssl_config'
59
+
60
+ AUTH_ENV = Google::Auth::ServiceAccountCredentials::ENV_VAR
61
+
62
+ # loads the certificates used to access the test server securely.
63
+ def load_test_certs
64
+ this_dir = File.expand_path(File.dirname(__FILE__))
65
+ data_dir = File.join(File.dirname(File.dirname(this_dir)), 'spec/testdata')
66
+ files = ['ca.pem', 'server1.key', 'server1.pem']
67
+ files.map { |f| File.open(File.join(data_dir, f)).read }
68
+ end
69
+
70
+ # loads the certificates used to access the test server securely.
71
+ def load_prod_cert
72
+ fail 'could not find a production cert' if ENV['SSL_CERT_FILE'].nil?
73
+ logger.info("loading prod certs from #{ENV['SSL_CERT_FILE']}")
74
+ File.open(ENV['SSL_CERT_FILE']).read
75
+ end
76
+
77
+ # creates SSL Credentials from the test certificates.
78
+ def test_creds
79
+ certs = load_test_certs
80
+ GRPC::Core::Credentials.new(certs[0])
81
+ end
82
+
83
+ # creates SSL Credentials from the production certificates.
84
+ def prod_creds
85
+ cert_text = load_prod_cert
86
+ GRPC::Core::Credentials.new(cert_text)
87
+ end
88
+
89
+ # creates the SSL Credentials.
90
+ def ssl_creds(use_test_ca)
91
+ return test_creds if use_test_ca
92
+ prod_creds
93
+ end
94
+
95
+ # creates a test stub that accesses host:port securely.
96
+ def create_stub(opts)
97
+ address = "#{opts.host}:#{opts.port}"
98
+ if opts.secure
99
+ stub_opts = {
100
+ :creds => ssl_creds(opts.use_test_ca),
101
+ GRPC::Core::Channel::SSL_TARGET => opts.host_override
102
+ }
103
+
104
+ # Add service account creds if specified
105
+ wants_creds = %w(all compute_engine_creds service_account_creds)
106
+ if wants_creds.include?(opts.test_case)
107
+ unless opts.oauth_scope.nil?
108
+ auth_creds = Google::Auth.get_application_default(opts.oauth_scope)
109
+ stub_opts[:update_metadata] = auth_creds.updater_proc
110
+ end
111
+ end
112
+
113
+ logger.info("... connecting securely to #{address}")
114
+ Grpc::Testing::TestService::Stub.new(address, **stub_opts)
115
+ else
116
+ logger.info("... connecting insecurely to #{address}")
117
+ Grpc::Testing::TestService::Stub.new(address)
118
+ end
119
+ end
120
+
121
+ # produces a string of null chars (\0) of length l.
122
+ def nulls(l)
123
+ fail 'requires #{l} to be +ve' if l < 0
124
+ [].pack('x' * l).force_encoding('utf-8')
125
+ end
126
+
127
+ # a PingPongPlayer implements the ping pong bidi test.
128
+ class PingPongPlayer
129
+ include Minitest::Assertions
130
+ include Grpc::Testing
131
+ include Grpc::Testing::PayloadType
132
+ attr_accessor :assertions # required by Minitest::Assertions
133
+ attr_accessor :queue
134
+
135
+ # reqs is the enumerator over the requests
136
+ def initialize(msg_sizes)
137
+ @queue = Queue.new
138
+ @msg_sizes = msg_sizes
139
+ @assertions = 0 # required by Minitest::Assertions
140
+ end
141
+
142
+ def each_item
143
+ return enum_for(:each_item) unless block_given?
144
+ req_cls, p_cls = StreamingOutputCallRequest, ResponseParameters # short
145
+ count = 0
146
+ @msg_sizes.each do |m|
147
+ req_size, resp_size = m
148
+ req = req_cls.new(payload: Payload.new(body: nulls(req_size)),
149
+ response_type: :COMPRESSABLE,
150
+ response_parameters: [p_cls.new(size: resp_size)])
151
+ yield req
152
+ resp = @queue.pop
153
+ assert_equal(:COMPRESSABLE, resp.payload.type,
154
+ 'payload type is wrong')
155
+ assert_equal(resp_size, resp.payload.body.length,
156
+ 'payload body #{i} has the wrong length')
157
+ p "OK: ping_pong #{count}"
158
+ count += 1
159
+ end
160
+ end
161
+ end
162
+
163
+ # defines methods corresponding to each interop test case.
164
+ class NamedTests
165
+ include Minitest::Assertions
166
+ include Grpc::Testing
167
+ include Grpc::Testing::PayloadType
168
+ attr_accessor :assertions # required by Minitest::Assertions
169
+
170
+ def initialize(stub, args)
171
+ @assertions = 0 # required by Minitest::Assertions
172
+ @stub = stub
173
+ @args = args
174
+ end
175
+
176
+ def empty_unary
177
+ resp = @stub.empty_call(Empty.new)
178
+ assert resp.is_a?(Empty), 'empty_unary: invalid response'
179
+ p 'OK: empty_unary'
180
+ end
181
+
182
+ def large_unary
183
+ perform_large_unary
184
+ p 'OK: large_unary'
185
+ end
186
+
187
+ def service_account_creds
188
+ # ignore this test if the oauth options are not set
189
+ if @args.oauth_scope.nil?
190
+ p 'NOT RUN: service_account_creds; no service_account settings'
191
+ return
192
+ end
193
+ json_key = File.read(ENV[AUTH_ENV])
194
+ wanted_email = MultiJson.load(json_key)['client_email']
195
+ resp = perform_large_unary(fill_username: true,
196
+ fill_oauth_scope: true)
197
+ assert_equal(wanted_email, resp.username,
198
+ 'service_account_creds: incorrect username')
199
+ assert(@args.oauth_scope.include?(resp.oauth_scope),
200
+ 'service_account_creds: incorrect oauth_scope')
201
+ p 'OK: service_account_creds'
202
+ end
203
+
204
+ def compute_engine_creds
205
+ resp = perform_large_unary(fill_username: true,
206
+ fill_oauth_scope: true)
207
+ assert_equal(@args.default_service_account, resp.username,
208
+ 'compute_engine_creds: incorrect username')
209
+ p 'OK: compute_engine_creds'
210
+ end
211
+
212
+ def client_streaming
213
+ msg_sizes = [27_182, 8, 1828, 45_904]
214
+ wanted_aggregate_size = 74_922
215
+ reqs = msg_sizes.map do |x|
216
+ req = Payload.new(body: nulls(x))
217
+ StreamingInputCallRequest.new(payload: req)
218
+ end
219
+ resp = @stub.streaming_input_call(reqs)
220
+ assert_equal(wanted_aggregate_size, resp.aggregated_payload_size,
221
+ 'client_streaming: aggregate payload size is incorrect')
222
+ p 'OK: client_streaming'
223
+ end
224
+
225
+ def server_streaming
226
+ msg_sizes = [31_415, 9, 2653, 58_979]
227
+ response_spec = msg_sizes.map { |s| ResponseParameters.new(size: s) }
228
+ req = StreamingOutputCallRequest.new(response_type: :COMPRESSABLE,
229
+ response_parameters: response_spec)
230
+ resps = @stub.streaming_output_call(req)
231
+ resps.each_with_index do |r, i|
232
+ assert i < msg_sizes.length, 'too many responses'
233
+ assert_equal(:COMPRESSABLE, r.payload.type,
234
+ 'payload type is wrong')
235
+ assert_equal(msg_sizes[i], r.payload.body.length,
236
+ 'payload body #{i} has the wrong length')
237
+ end
238
+ p 'OK: server_streaming'
239
+ end
240
+
241
+ def ping_pong
242
+ msg_sizes = [[27_182, 31_415], [8, 9], [1828, 2653], [45_904, 58_979]]
243
+ ppp = PingPongPlayer.new(msg_sizes)
244
+ resps = @stub.full_duplex_call(ppp.each_item)
245
+ resps.each { |r| ppp.queue.push(r) }
246
+ p 'OK: ping_pong'
247
+ end
248
+
249
+ def all
250
+ all_methods = NamedTests.instance_methods(false).map(&:to_s)
251
+ all_methods.each do |m|
252
+ next if m == 'all' || m.start_with?('assert')
253
+ p "TESTCASE: #{m}"
254
+ method(m).call
255
+ end
256
+ end
257
+
258
+ private
259
+
260
+ def perform_large_unary(fill_username: false, fill_oauth_scope: false)
261
+ req_size, wanted_response_size = 271_828, 314_159
262
+ payload = Payload.new(type: :COMPRESSABLE, body: nulls(req_size))
263
+ req = SimpleRequest.new(response_type: :COMPRESSABLE,
264
+ response_size: wanted_response_size,
265
+ payload: payload)
266
+ req.fill_username = fill_username
267
+ req.fill_oauth_scope = fill_oauth_scope
268
+ resp = @stub.unary_call(req)
269
+ assert_equal(:COMPRESSABLE, resp.payload.type,
270
+ 'large_unary: payload had the wrong type')
271
+ assert_equal(wanted_response_size, resp.payload.body.length,
272
+ 'large_unary: payload had the wrong length')
273
+ assert_equal(nulls(wanted_response_size), resp.payload.body,
274
+ 'large_unary: payload content is invalid')
275
+ resp
276
+ end
277
+ end
278
+
279
+ # Args is used to hold the command line info.
280
+ Args = Struct.new(:default_service_account, :host, :host_override,
281
+ :oauth_scope, :port, :secure, :test_case,
282
+ :use_test_ca)
283
+
284
+ # validates the the command line options, returning them as a Hash.
285
+ def parse_args
286
+ args = Args.new
287
+ args.host_override = 'foo.test.google.fr'
288
+ OptionParser.new do |opts|
289
+ opts.on('--oauth_scope scope',
290
+ 'Scope for OAuth tokens') { |v| args['oauth_scope'] = v }
291
+ opts.on('--server_host SERVER_HOST', 'server hostname') do |v|
292
+ args['host'] = v
293
+ end
294
+ opts.on('--default_service_account email_address',
295
+ 'email address of the default service account') do |v|
296
+ args['default_service_account'] = v
297
+ end
298
+ opts.on('--server_host_override HOST_OVERRIDE',
299
+ 'override host via a HTTP header') do |v|
300
+ args['host_override'] = v
301
+ end
302
+ opts.on('--server_port SERVER_PORT', 'server port') { |v| args['port'] = v }
303
+ # instance_methods(false) gives only the methods defined in that class
304
+ test_cases = NamedTests.instance_methods(false).map(&:to_s)
305
+ test_case_list = test_cases.join(',')
306
+ opts.on('--test_case CODE', test_cases, {}, 'select a test_case',
307
+ " (#{test_case_list})") { |v| args['test_case'] = v }
308
+ opts.on('-s', '--use_tls', 'require a secure connection?') do |v|
309
+ args['secure'] = v
310
+ end
311
+ opts.on('-t', '--use_test_ca',
312
+ 'if secure, use the test certificate?') do |v|
313
+ args['use_test_ca'] = v
314
+ end
315
+ end.parse!
316
+ _check_args(args)
317
+ end
318
+
319
+ def _check_args(args)
320
+ %w(host port test_case).each do |a|
321
+ if args[a].nil?
322
+ fail(OptionParser::MissingArgument, "please specify --#{arg}")
323
+ end
324
+ end
325
+ args
326
+ end
327
+
328
+ def main
329
+ opts = parse_args
330
+ stub = create_stub(opts)
331
+ NamedTests.new(stub, opts).method(opts['test_case']).call
332
+ end
333
+
334
+ main