gcloud 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +13 -5
- data/AUTHENTICATION.md +71 -0
- data/CHANGELOG.md +5 -0
- data/README.md +10 -15
- data/lib/gcloud.rb +30 -0
- data/lib/gcloud/backoff.rb +3 -0
- data/lib/gcloud/credentials.rb +47 -30
- data/lib/gcloud/datastore.rb +246 -15
- data/lib/gcloud/datastore/connection.rb +4 -2
- data/lib/gcloud/datastore/credentials.rb +3 -1
- data/lib/gcloud/datastore/dataset.rb +130 -25
- data/lib/gcloud/datastore/dataset/lookup_results.rb +1 -0
- data/lib/gcloud/datastore/dataset/query_results.rb +7 -5
- data/lib/gcloud/datastore/entity.rb +99 -17
- data/lib/gcloud/datastore/errors.rb +13 -2
- data/lib/gcloud/datastore/key.rb +133 -2
- data/lib/gcloud/datastore/properties.rb +6 -1
- data/lib/gcloud/datastore/proto.rb +2 -1
- data/lib/gcloud/datastore/query.rb +4 -4
- data/lib/gcloud/datastore/transaction.rb +3 -0
- data/lib/gcloud/storage.rb +280 -13
- data/lib/gcloud/storage/bucket.rb +248 -11
- data/lib/gcloud/storage/bucket/acl.rb +631 -4
- data/lib/gcloud/storage/bucket/list.rb +1 -0
- data/lib/gcloud/storage/connection.rb +1 -0
- data/lib/gcloud/storage/credentials.rb +3 -1
- data/lib/gcloud/storage/errors.rb +9 -1
- data/lib/gcloud/storage/file.rb +231 -6
- data/lib/gcloud/storage/file/acl.rb +365 -2
- data/lib/gcloud/storage/file/list.rb +1 -0
- data/lib/gcloud/storage/file/verifier.rb +1 -0
- data/lib/gcloud/storage/project.rb +119 -10
- data/lib/gcloud/version.rb +18 -3
- metadata +33 -80
- data/.gemtest +0 -0
- data/.rubocop.yml +0 -17
- data/Manifest.txt +0 -66
- data/Rakefile +0 -35
- data/gcloud.gemspec +0 -63
- data/rakelib/console.rake +0 -28
- data/rakelib/manifest.rake +0 -24
- data/rakelib/proto.rake +0 -17
- data/rakelib/rubocop.rake +0 -17
- data/rakelib/test.rake +0 -144
- data/test/gcloud/datastore/proto/test_cursor.rb +0 -36
- data/test/gcloud/datastore/proto/test_direction.rb +0 -60
- data/test/gcloud/datastore/proto/test_operator.rb +0 -76
- data/test/gcloud/datastore/proto/test_value.rb +0 -231
- data/test/gcloud/datastore/test_connection.rb +0 -93
- data/test/gcloud/datastore/test_credentials.rb +0 -38
- data/test/gcloud/datastore/test_dataset.rb +0 -413
- data/test/gcloud/datastore/test_entity.rb +0 -161
- data/test/gcloud/datastore/test_entity_exclude.rb +0 -225
- data/test/gcloud/datastore/test_key.rb +0 -189
- data/test/gcloud/datastore/test_query.rb +0 -271
- data/test/gcloud/datastore/test_transaction.rb +0 -121
- data/test/gcloud/storage/test_backoff.rb +0 -127
- data/test/gcloud/storage/test_bucket.rb +0 -270
- data/test/gcloud/storage/test_bucket_acl.rb +0 -253
- data/test/gcloud/storage/test_default_acl.rb +0 -256
- data/test/gcloud/storage/test_file.rb +0 -221
- data/test/gcloud/storage/test_file_acl.rb +0 -367
- data/test/gcloud/storage/test_project.rb +0 -180
- data/test/gcloud/storage/test_storage.rb +0 -29
- data/test/gcloud/storage/test_verifier.rb +0 -62
- data/test/gcloud/test_version.rb +0 -8
- data/test/helper.rb +0 -91
@@ -1,271 +0,0 @@
|
|
1
|
-
# Copyright 2014 Google Inc. All rights reserved.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
|
15
|
-
require "helper"
|
16
|
-
require "gcloud/datastore"
|
17
|
-
|
18
|
-
describe Gcloud::Datastore::Query do
|
19
|
-
it "can query on kind" do
|
20
|
-
query = Gcloud::Datastore::Query.new
|
21
|
-
query.kind "Task"
|
22
|
-
|
23
|
-
proto = query.to_proto
|
24
|
-
proto.kind.name.must_include "Task"
|
25
|
-
proto.kind.name.wont_include "User"
|
26
|
-
|
27
|
-
# Add a second kind to the query
|
28
|
-
query.kind "User"
|
29
|
-
|
30
|
-
proto = query.to_proto
|
31
|
-
proto.kind.name.must_include "Task"
|
32
|
-
proto.kind.name.must_include "User"
|
33
|
-
end
|
34
|
-
|
35
|
-
it "can filter properties" do
|
36
|
-
query = Gcloud::Datastore::Query.new
|
37
|
-
query.kind "Task"
|
38
|
-
query.where "completed", "=", true
|
39
|
-
|
40
|
-
proto = query.to_proto
|
41
|
-
refute_nil proto.filter
|
42
|
-
assert_nil proto.filter.property_filter
|
43
|
-
refute_nil proto.filter.composite_filter
|
44
|
-
assert_equal Gcloud::Datastore::Proto::CompositeFilter::Operator::AND,
|
45
|
-
proto.filter.composite_filter.operator
|
46
|
-
assert_equal 1, proto.filter.composite_filter.filter.count
|
47
|
-
|
48
|
-
new_filter = proto.filter.composite_filter.filter.first
|
49
|
-
assert_equal "completed", new_filter.property_filter.property.name
|
50
|
-
assert_equal Gcloud::Datastore::Proto::PropertyFilter::Operator::EQUAL,
|
51
|
-
new_filter.property_filter.operator
|
52
|
-
assert_equal true, Gcloud::Datastore::Proto.from_proto_value(new_filter.property_filter.value)
|
53
|
-
|
54
|
-
# Add a second filter and generate new protobuf
|
55
|
-
# Use the filter alias to add the second filter
|
56
|
-
query.filter "due", :>, Time.new(2014, 1, 1, 0, 0, 0, 0)
|
57
|
-
proto = query.to_proto
|
58
|
-
assert_equal 2, proto.filter.composite_filter.filter.count
|
59
|
-
|
60
|
-
first_filter = proto.filter.composite_filter.filter.first
|
61
|
-
refute_nil first_filter.property_filter
|
62
|
-
assert_nil first_filter.composite_filter
|
63
|
-
assert_equal "completed", first_filter.property_filter.property.name
|
64
|
-
assert_equal Gcloud::Datastore::Proto::PropertyFilter::Operator::EQUAL,
|
65
|
-
first_filter.property_filter.operator
|
66
|
-
assert_equal true, Gcloud::Datastore::Proto.from_proto_value(first_filter.property_filter.value)
|
67
|
-
|
68
|
-
second_filter = proto.filter.composite_filter.filter.last
|
69
|
-
refute_nil second_filter.property_filter
|
70
|
-
assert_nil second_filter.composite_filter
|
71
|
-
assert_equal "due", second_filter.property_filter.property.name
|
72
|
-
assert_equal Gcloud::Datastore::Proto::PropertyFilter::Operator::GREATER_THAN,
|
73
|
-
second_filter.property_filter.operator
|
74
|
-
assert_equal Time.new(2014, 1, 1, 0, 0, 0, 0),
|
75
|
-
Gcloud::Datastore::Proto.from_proto_value(second_filter.property_filter.value)
|
76
|
-
end
|
77
|
-
|
78
|
-
it "can order results" do
|
79
|
-
query = Gcloud::Datastore::Query.new
|
80
|
-
query.kind "Task"
|
81
|
-
query.order "due"
|
82
|
-
|
83
|
-
proto = query.to_proto
|
84
|
-
order = order_as_arrays proto
|
85
|
-
order.must_include [ "due", :asc ]
|
86
|
-
order.wont_include [ "completed", :desc ]
|
87
|
-
|
88
|
-
# Add a second kind to the query
|
89
|
-
query.order "completed", :desc
|
90
|
-
|
91
|
-
proto = query.to_proto
|
92
|
-
order = order_as_arrays proto
|
93
|
-
order.must_include [ "due", :asc ]
|
94
|
-
order.must_include [ "completed", :desc ]
|
95
|
-
end
|
96
|
-
|
97
|
-
it "accepts any string that starts with 'd' for DESCENDING" do
|
98
|
-
query = Gcloud::Datastore::Query.new
|
99
|
-
query.kind "Task"
|
100
|
-
query.order "completed", "DOWN"
|
101
|
-
|
102
|
-
proto = query.to_proto
|
103
|
-
order = order_as_arrays proto
|
104
|
-
|
105
|
-
order.must_include [ "completed", :desc ]
|
106
|
-
end
|
107
|
-
|
108
|
-
it "can limit and offset" do
|
109
|
-
query = Gcloud::Datastore::Query.new
|
110
|
-
query.kind "Task"
|
111
|
-
|
112
|
-
proto = query.to_proto
|
113
|
-
proto.limit.must_be :nil?
|
114
|
-
|
115
|
-
query.limit 10
|
116
|
-
|
117
|
-
proto = query.to_proto
|
118
|
-
proto.limit.must_equal 10
|
119
|
-
|
120
|
-
proto.offset.must_be :nil?
|
121
|
-
|
122
|
-
query.offset 20
|
123
|
-
|
124
|
-
proto = query.to_proto
|
125
|
-
proto.offset.must_equal 20
|
126
|
-
end
|
127
|
-
|
128
|
-
it "can specify a cursor" do
|
129
|
-
raw_cursor = "\x13\xE0\x01\x00\xEB".force_encoding Encoding::ASCII_8BIT
|
130
|
-
encoded_cursor = "E+ABAOs="
|
131
|
-
|
132
|
-
query = Gcloud::Datastore::Query.new
|
133
|
-
query.kind "Task"
|
134
|
-
|
135
|
-
proto = query.to_proto
|
136
|
-
proto.start_cursor.must_be :nil?
|
137
|
-
|
138
|
-
query.cursor encoded_cursor
|
139
|
-
|
140
|
-
proto = query.to_proto
|
141
|
-
proto.start_cursor.must_equal raw_cursor
|
142
|
-
end
|
143
|
-
|
144
|
-
it "can select the properties to return" do
|
145
|
-
query = Gcloud::Datastore::Query.new
|
146
|
-
query.kind "Task"
|
147
|
-
|
148
|
-
proto = query.to_proto
|
149
|
-
proto.projection.must_be :nil?
|
150
|
-
|
151
|
-
query.select "completed"
|
152
|
-
|
153
|
-
proto = query.to_proto
|
154
|
-
proto.projection.wont_be :nil?
|
155
|
-
proto.projection.count.must_equal 1
|
156
|
-
proto.projection.first.property.name.must_equal "completed"
|
157
|
-
end
|
158
|
-
|
159
|
-
it "can select the properties using projection alias" do
|
160
|
-
query = Gcloud::Datastore::Query.new
|
161
|
-
query.kind "Task"
|
162
|
-
|
163
|
-
proto = query.to_proto
|
164
|
-
proto.projection.must_be :nil?
|
165
|
-
|
166
|
-
# Use projection instead of select
|
167
|
-
query.projection "completed"
|
168
|
-
|
169
|
-
proto = query.to_proto
|
170
|
-
proto.projection.wont_be :nil?
|
171
|
-
proto.projection.count.must_equal 1
|
172
|
-
proto.projection.first.property.name.must_equal "completed"
|
173
|
-
end
|
174
|
-
|
175
|
-
it "can group on properties" do
|
176
|
-
query = Gcloud::Datastore::Query.new
|
177
|
-
query.kind "Task"
|
178
|
-
|
179
|
-
proto = query.to_proto
|
180
|
-
proto.group_by.must_be :nil?
|
181
|
-
|
182
|
-
query.group_by "completed"
|
183
|
-
|
184
|
-
proto = query.to_proto
|
185
|
-
proto.group_by.wont_be :nil?
|
186
|
-
proto.group_by.count.must_equal 1
|
187
|
-
proto.group_by.first.name.must_equal "completed"
|
188
|
-
end
|
189
|
-
|
190
|
-
it "can query ancestor" do
|
191
|
-
ancestor_key = Gcloud::Datastore::Key.new("User", "username")
|
192
|
-
query = Gcloud::Datastore::Query.new
|
193
|
-
query.kind "Task"
|
194
|
-
query.ancestor ancestor_key
|
195
|
-
|
196
|
-
proto = query.to_proto
|
197
|
-
|
198
|
-
assert_equal 1, proto.filter.composite_filter.filter.count
|
199
|
-
|
200
|
-
ancestor_filter = proto.filter.composite_filter.filter.first
|
201
|
-
assert_equal "__key__", ancestor_filter.property_filter.property.name
|
202
|
-
assert_equal Gcloud::Datastore::Proto::PropertyFilter::Operator::HAS_ANCESTOR,
|
203
|
-
ancestor_filter.property_filter.operator
|
204
|
-
key = Gcloud::Datastore::Proto.from_proto_value(ancestor_filter.property_filter.value)
|
205
|
-
key.kind.must_equal ancestor_key.kind
|
206
|
-
key.id.must_equal ancestor_key.id
|
207
|
-
key.name.must_equal ancestor_key.name
|
208
|
-
end
|
209
|
-
|
210
|
-
it "can manually filter on ancestor" do
|
211
|
-
ancestor_key = Gcloud::Datastore::Key.new("User", "username")
|
212
|
-
query = Gcloud::Datastore::Query.new
|
213
|
-
query.kind "Task"
|
214
|
-
query.filter "__key__", "~", ancestor_key
|
215
|
-
|
216
|
-
proto = query.to_proto
|
217
|
-
|
218
|
-
assert_equal 1, proto.filter.composite_filter.filter.count
|
219
|
-
|
220
|
-
ancestor_filter = proto.filter.composite_filter.filter.first
|
221
|
-
assert_equal "__key__", ancestor_filter.property_filter.property.name
|
222
|
-
assert_equal Gcloud::Datastore::Proto::PropertyFilter::Operator::HAS_ANCESTOR,
|
223
|
-
ancestor_filter.property_filter.operator
|
224
|
-
key = Gcloud::Datastore::Proto.from_proto_value(ancestor_filter.property_filter.value)
|
225
|
-
key.kind.must_equal ancestor_key.kind
|
226
|
-
key.id.must_equal ancestor_key.id
|
227
|
-
key.name.must_equal ancestor_key.name
|
228
|
-
end
|
229
|
-
|
230
|
-
it "can chain query methods" do
|
231
|
-
query = Gcloud::Datastore::Query.new
|
232
|
-
q2 = query.kind("Task").select("due", "completed").
|
233
|
-
where("completed", "=", true).group_by("completed").
|
234
|
-
order("due", :desc).limit(10).offset(20)
|
235
|
-
|
236
|
-
q2.must_equal query
|
237
|
-
q2.to_proto.must_equal query.to_proto
|
238
|
-
|
239
|
-
proto = query.to_proto
|
240
|
-
|
241
|
-
proto.kind.name.must_include "Task"
|
242
|
-
|
243
|
-
proto.projection.wont_be :nil?
|
244
|
-
proto.projection.count.must_equal 2
|
245
|
-
proto.projection.first.property.name.must_equal "due"
|
246
|
-
proto.projection.last.property.name.must_equal "completed"
|
247
|
-
|
248
|
-
filter = proto.filter.composite_filter.filter.first
|
249
|
-
filter.property_filter.property.name.must_equal "completed"
|
250
|
-
filter.property_filter.operator.must_equal Gcloud::Datastore::Proto::PropertyFilter::Operator::EQUAL
|
251
|
-
Gcloud::Datastore::Proto.from_proto_value(filter.property_filter.value).must_equal true
|
252
|
-
|
253
|
-
proto.group_by.wont_be :nil?
|
254
|
-
proto.group_by.count.must_equal 1
|
255
|
-
proto.group_by.first.name.must_equal "completed"
|
256
|
-
|
257
|
-
order = order_as_arrays proto
|
258
|
-
order.must_include [ "due", :desc ]
|
259
|
-
|
260
|
-
proto.limit.must_equal 10
|
261
|
-
|
262
|
-
proto.offset.must_equal 20
|
263
|
-
end
|
264
|
-
|
265
|
-
def order_as_arrays proto
|
266
|
-
proto.order.map do |o|
|
267
|
-
[o.property.name,
|
268
|
-
(o.direction == Gcloud::Datastore::Proto::PropertyOrder::Direction::DESCENDING) ? :desc : :asc]
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|
@@ -1,121 +0,0 @@
|
|
1
|
-
# Copyright 2014 Google Inc. All rights reserved.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
|
15
|
-
require "helper"
|
16
|
-
require "gcloud/datastore"
|
17
|
-
|
18
|
-
describe Gcloud::Datastore::Transaction do
|
19
|
-
let(:project) { "my-todo-project" }
|
20
|
-
let(:credentials) { OpenStruct.new }
|
21
|
-
let(:connection) do
|
22
|
-
mock = Minitest::Mock.new
|
23
|
-
mock.expect :begin_transaction, begin_transaction_response
|
24
|
-
mock
|
25
|
-
end
|
26
|
-
let(:transaction) { Gcloud::Datastore::Transaction.new connection }
|
27
|
-
let(:commit_response) do
|
28
|
-
Gcloud::Datastore::Proto::CommitResponse.new.tap do |response|
|
29
|
-
response.mutation_result = Gcloud::Datastore::Proto::MutationResult.new
|
30
|
-
end
|
31
|
-
end
|
32
|
-
let(:begin_transaction_response) do
|
33
|
-
Gcloud::Datastore::Proto::BeginTransactionResponse.new.tap do |response|
|
34
|
-
response.transaction = "giterdone"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
after do
|
39
|
-
transaction.connection.verify
|
40
|
-
end
|
41
|
-
|
42
|
-
it "save does not persist entities" do
|
43
|
-
entity = Gcloud::Datastore::Entity.new.tap do |e|
|
44
|
-
e.key = Gcloud::Datastore::Key.new "ds-test", "thingie"
|
45
|
-
e["name"] = "thingamajig"
|
46
|
-
end
|
47
|
-
transaction.save entity
|
48
|
-
end
|
49
|
-
|
50
|
-
it "delete does not persist entities" do
|
51
|
-
entity = Gcloud::Datastore::Entity.new.tap do |e|
|
52
|
-
e.key = Gcloud::Datastore::Key.new "ds-test", "thingie"
|
53
|
-
e["name"] = "thingamajig"
|
54
|
-
end
|
55
|
-
transaction.delete entity
|
56
|
-
end
|
57
|
-
|
58
|
-
it "commit persists entities" do
|
59
|
-
transaction.connection.expect :commit,
|
60
|
-
commit_response,
|
61
|
-
[Gcloud::Datastore::Proto::Mutation,
|
62
|
-
String]
|
63
|
-
|
64
|
-
entity = Gcloud::Datastore::Entity.new.tap do |e|
|
65
|
-
e.key = Gcloud::Datastore::Key.new "ds-test", "thingie"
|
66
|
-
e["name"] = "thingamajig"
|
67
|
-
end
|
68
|
-
transaction.save entity
|
69
|
-
transaction.commit
|
70
|
-
end
|
71
|
-
|
72
|
-
it "rollback does not persist entities" do
|
73
|
-
transaction.connection.expect :rollback,
|
74
|
-
true,
|
75
|
-
[String]
|
76
|
-
|
77
|
-
entity = Gcloud::Datastore::Entity.new.tap do |e|
|
78
|
-
e.key = Gcloud::Datastore::Key.new "ds-test", "thingie"
|
79
|
-
e["name"] = "thingamajig"
|
80
|
-
end
|
81
|
-
transaction.save entity
|
82
|
-
transaction.rollback
|
83
|
-
end
|
84
|
-
|
85
|
-
describe "error handling" do
|
86
|
-
it "start will raise if transaction is already open" do
|
87
|
-
transaction.id.wont_be :nil?
|
88
|
-
error = assert_raises Gcloud::Datastore::TransactionError do
|
89
|
-
transaction.start
|
90
|
-
end
|
91
|
-
error.wont_be :nil?
|
92
|
-
error.message.must_equal "Transaction already opened."
|
93
|
-
end
|
94
|
-
|
95
|
-
it "commit will raise if transaction is not open" do
|
96
|
-
transaction.connection.expect :begin_transaction, begin_transaction_response
|
97
|
-
|
98
|
-
transaction.id.wont_be :nil?
|
99
|
-
transaction.reset!
|
100
|
-
transaction.id.must_be :nil?
|
101
|
-
error = assert_raises Gcloud::Datastore::TransactionError do
|
102
|
-
transaction.commit
|
103
|
-
end
|
104
|
-
error.wont_be :nil?
|
105
|
-
error.message.must_equal "Cannot commit when not in a transaction."
|
106
|
-
end
|
107
|
-
|
108
|
-
it "transaction will raise if transaction is not open" do
|
109
|
-
transaction.connection.expect :begin_transaction, begin_transaction_response
|
110
|
-
|
111
|
-
transaction.id.wont_be :nil?
|
112
|
-
transaction.reset!
|
113
|
-
transaction.id.must_be :nil?
|
114
|
-
error = assert_raises Gcloud::Datastore::TransactionError do
|
115
|
-
transaction.rollback
|
116
|
-
end
|
117
|
-
error.wont_be :nil?
|
118
|
-
error.message.must_equal "Cannot rollback when not in a transaction."
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
@@ -1,127 +0,0 @@
|
|
1
|
-
# Copyright 2014 Google Inc. All rights reserved.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
|
15
|
-
require "helper"
|
16
|
-
require "json"
|
17
|
-
require "uri"
|
18
|
-
|
19
|
-
describe "Gcloud Storage Backoff", :mock_storage do
|
20
|
-
# Create a bucket object with the project's mocked connection object
|
21
|
-
let(:bucket) { Gcloud::Storage::Bucket.from_gapi random_bucket_hash,
|
22
|
-
storage.connection }
|
23
|
-
|
24
|
-
it "creates a bucket even when rate limited" do
|
25
|
-
new_bucket_name = "new-bucket-#{Time.now.to_i}"
|
26
|
-
|
27
|
-
2.times do
|
28
|
-
mock_connection.post "/storage/v1/b?project=#{project}" do |env|
|
29
|
-
JSON.parse(env.body)["name"].must_equal new_bucket_name
|
30
|
-
[429, {"Content-Type"=>"application/json"},
|
31
|
-
rate_limit_exceeded_json]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
mock_connection.post "/storage/v1/b?project=#{project}" do |env|
|
35
|
-
JSON.parse(env.body)["name"].must_equal new_bucket_name
|
36
|
-
[200, {"Content-Type"=>"application/json"},
|
37
|
-
create_bucket_json]
|
38
|
-
end
|
39
|
-
|
40
|
-
# Should be delayed ~3 seconds
|
41
|
-
assert_backoff_sleep 1, 2 do
|
42
|
-
storage.create_bucket new_bucket_name
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
it "creates a bucket with backoff settings" do
|
48
|
-
new_bucket_name = "new-bucket-#{Time.now.to_i}"
|
49
|
-
|
50
|
-
5.times do
|
51
|
-
mock_connection.post "/storage/v1/b?project=#{project}" do |env|
|
52
|
-
JSON.parse(env.body)["name"].must_equal new_bucket_name
|
53
|
-
[429, {"Content-Type"=>"application/json"},
|
54
|
-
rate_limit_exceeded_json]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
mock_connection.post "/storage/v1/b?project=#{project}" do |env|
|
58
|
-
JSON.parse(env.body)["name"].must_equal new_bucket_name
|
59
|
-
[200, {"Content-Type"=>"application/json"},
|
60
|
-
create_bucket_json]
|
61
|
-
end
|
62
|
-
|
63
|
-
# Should be delayed ~15 seconds
|
64
|
-
assert_backoff_sleep 1, 2, 3, 4, 5 do
|
65
|
-
storage.create_bucket new_bucket_name, retries: 5
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
it "deletes a bucket even when rate limited" do
|
70
|
-
2.times do
|
71
|
-
mock_connection.delete "/storage/v1/b/#{bucket.name}" do |env|
|
72
|
-
[429, {"Content-Type"=>"application/json"},
|
73
|
-
rate_limit_exceeded_json]
|
74
|
-
end
|
75
|
-
end
|
76
|
-
mock_connection.delete "/storage/v1/b/#{bucket.name}" do |env|
|
77
|
-
[200, {"Content-Type"=>"application/json"}, ""]
|
78
|
-
end
|
79
|
-
|
80
|
-
# Should be delayed ~3 seconds
|
81
|
-
assert_backoff_sleep 1, 2 do
|
82
|
-
bucket.delete
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
it "deletes a bucket with backoff settings" do
|
87
|
-
5.times do
|
88
|
-
mock_connection.delete "/storage/v1/b/#{bucket.name}" do |env|
|
89
|
-
[429, {"Content-Type"=>"application/json"},
|
90
|
-
rate_limit_exceeded_json]
|
91
|
-
end
|
92
|
-
end
|
93
|
-
mock_connection.delete "/storage/v1/b/#{bucket.name}" do |env|
|
94
|
-
[200, {"Content-Type"=>"application/json"}, ""]
|
95
|
-
end
|
96
|
-
|
97
|
-
# Should be delayed ~15 seconds
|
98
|
-
assert_backoff_sleep 1, 2, 3, 4, 5 do
|
99
|
-
bucket.delete retries: 5
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def assert_backoff_sleep *args
|
104
|
-
mock = Minitest::Mock.new
|
105
|
-
args.each { |intv| mock.expect :sleep, nil, [intv] }
|
106
|
-
callback = ->(retries) { mock.sleep retries }
|
107
|
-
backoff = Gcloud::Backoff.new retries: 5, backoff: callback
|
108
|
-
|
109
|
-
Gcloud::Backoff.stub :new, backoff do
|
110
|
-
yield
|
111
|
-
end
|
112
|
-
|
113
|
-
mock.verify
|
114
|
-
end
|
115
|
-
|
116
|
-
def create_bucket_json
|
117
|
-
random_bucket_hash.to_json
|
118
|
-
end
|
119
|
-
|
120
|
-
def rate_limit_exceeded_json
|
121
|
-
{ "error" => { "errors" => [{ "domain" => "usageLimits",
|
122
|
-
"reason" => "rateLimitExceeded",
|
123
|
-
"message" => "The project exceeded the rate limit for creating and deleting buckets."}], "code"=>429, "message"=>"The project exceeded the rate limit for creating and deleting buckets."
|
124
|
-
}
|
125
|
-
}.to_json
|
126
|
-
end
|
127
|
-
end
|