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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +1 -0
- data/.rubocop.yml +10 -0
- data/.rubocop_todo.yml +52 -0
- data/Gemfile +4 -0
- data/README.md +82 -0
- data/Rakefile +54 -0
- data/bin/apis/google/protobuf/empty.rb +44 -0
- data/bin/apis/pubsub_demo.rb +267 -0
- data/bin/apis/tech/pubsub/proto/pubsub.rb +174 -0
- data/bin/apis/tech/pubsub/proto/pubsub_services.rb +103 -0
- data/bin/interop/README.md +8 -0
- data/bin/interop/interop_client.rb +334 -0
- data/bin/interop/interop_server.rb +192 -0
- data/bin/interop/test/cpp/interop/empty.rb +44 -0
- data/bin/interop/test/cpp/interop/messages.rb +89 -0
- data/bin/interop/test/cpp/interop/test.rb +43 -0
- data/bin/interop/test/cpp/interop/test_services.rb +60 -0
- data/bin/math.proto +80 -0
- data/bin/math.rb +61 -0
- data/bin/math_client.rb +147 -0
- data/bin/math_server.rb +190 -0
- data/bin/math_services.rb +56 -0
- data/bin/noproto_client.rb +108 -0
- data/bin/noproto_server.rb +112 -0
- data/ext/grpc/extconf.rb +76 -0
- data/ext/grpc/rb_byte_buffer.c +241 -0
- data/ext/grpc/rb_byte_buffer.h +54 -0
- data/ext/grpc/rb_call.c +569 -0
- data/ext/grpc/rb_call.h +59 -0
- data/ext/grpc/rb_channel.c +264 -0
- data/ext/grpc/rb_channel.h +49 -0
- data/ext/grpc/rb_channel_args.c +154 -0
- data/ext/grpc/rb_channel_args.h +52 -0
- data/ext/grpc/rb_completion_queue.c +185 -0
- data/ext/grpc/rb_completion_queue.h +50 -0
- data/ext/grpc/rb_credentials.c +281 -0
- data/ext/grpc/rb_credentials.h +50 -0
- data/ext/grpc/rb_event.c +361 -0
- data/ext/grpc/rb_event.h +53 -0
- data/ext/grpc/rb_grpc.c +274 -0
- data/ext/grpc/rb_grpc.h +74 -0
- data/ext/grpc/rb_metadata.c +215 -0
- data/ext/grpc/rb_metadata.h +53 -0
- data/ext/grpc/rb_server.c +278 -0
- data/ext/grpc/rb_server.h +50 -0
- data/ext/grpc/rb_server_credentials.c +210 -0
- data/ext/grpc/rb_server_credentials.h +50 -0
- data/grpc.gemspec +41 -0
- data/lib/grpc.rb +39 -0
- data/lib/grpc/core/event.rb +44 -0
- data/lib/grpc/core/time_consts.rb +71 -0
- data/lib/grpc/errors.rb +61 -0
- data/lib/grpc/generic/active_call.rb +536 -0
- data/lib/grpc/generic/bidi_call.rb +221 -0
- data/lib/grpc/generic/client_stub.rb +413 -0
- data/lib/grpc/generic/rpc_desc.rb +150 -0
- data/lib/grpc/generic/rpc_server.rb +404 -0
- data/lib/grpc/generic/service.rb +235 -0
- data/lib/grpc/logconfig.rb +40 -0
- data/lib/grpc/version.rb +33 -0
- data/spec/alloc_spec.rb +44 -0
- data/spec/byte_buffer_spec.rb +67 -0
- data/spec/call_spec.rb +163 -0
- data/spec/channel_spec.rb +181 -0
- data/spec/client_server_spec.rb +372 -0
- data/spec/completion_queue_spec.rb +74 -0
- data/spec/credentials_spec.rb +71 -0
- data/spec/event_spec.rb +53 -0
- data/spec/generic/active_call_spec.rb +373 -0
- data/spec/generic/client_stub_spec.rb +519 -0
- data/spec/generic/rpc_desc_spec.rb +357 -0
- data/spec/generic/rpc_server_pool_spec.rb +139 -0
- data/spec/generic/rpc_server_spec.rb +404 -0
- data/spec/generic/service_spec.rb +342 -0
- data/spec/metadata_spec.rb +64 -0
- data/spec/server_credentials_spec.rb +69 -0
- data/spec/server_spec.rb +212 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/testdata/README +1 -0
- data/spec/testdata/ca.pem +15 -0
- data/spec/testdata/server1.key +16 -0
- data/spec/testdata/server1.pem +16 -0
- data/spec/time_consts_spec.rb +89 -0
- 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,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
|