gcloud 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +13 -5
  2. data/AUTHENTICATION.md +71 -0
  3. data/CHANGELOG.md +5 -0
  4. data/README.md +10 -15
  5. data/lib/gcloud.rb +30 -0
  6. data/lib/gcloud/backoff.rb +3 -0
  7. data/lib/gcloud/credentials.rb +47 -30
  8. data/lib/gcloud/datastore.rb +246 -15
  9. data/lib/gcloud/datastore/connection.rb +4 -2
  10. data/lib/gcloud/datastore/credentials.rb +3 -1
  11. data/lib/gcloud/datastore/dataset.rb +130 -25
  12. data/lib/gcloud/datastore/dataset/lookup_results.rb +1 -0
  13. data/lib/gcloud/datastore/dataset/query_results.rb +7 -5
  14. data/lib/gcloud/datastore/entity.rb +99 -17
  15. data/lib/gcloud/datastore/errors.rb +13 -2
  16. data/lib/gcloud/datastore/key.rb +133 -2
  17. data/lib/gcloud/datastore/properties.rb +6 -1
  18. data/lib/gcloud/datastore/proto.rb +2 -1
  19. data/lib/gcloud/datastore/query.rb +4 -4
  20. data/lib/gcloud/datastore/transaction.rb +3 -0
  21. data/lib/gcloud/storage.rb +280 -13
  22. data/lib/gcloud/storage/bucket.rb +248 -11
  23. data/lib/gcloud/storage/bucket/acl.rb +631 -4
  24. data/lib/gcloud/storage/bucket/list.rb +1 -0
  25. data/lib/gcloud/storage/connection.rb +1 -0
  26. data/lib/gcloud/storage/credentials.rb +3 -1
  27. data/lib/gcloud/storage/errors.rb +9 -1
  28. data/lib/gcloud/storage/file.rb +231 -6
  29. data/lib/gcloud/storage/file/acl.rb +365 -2
  30. data/lib/gcloud/storage/file/list.rb +1 -0
  31. data/lib/gcloud/storage/file/verifier.rb +1 -0
  32. data/lib/gcloud/storage/project.rb +119 -10
  33. data/lib/gcloud/version.rb +18 -3
  34. metadata +33 -80
  35. data/.gemtest +0 -0
  36. data/.rubocop.yml +0 -17
  37. data/Manifest.txt +0 -66
  38. data/Rakefile +0 -35
  39. data/gcloud.gemspec +0 -63
  40. data/rakelib/console.rake +0 -28
  41. data/rakelib/manifest.rake +0 -24
  42. data/rakelib/proto.rake +0 -17
  43. data/rakelib/rubocop.rake +0 -17
  44. data/rakelib/test.rake +0 -144
  45. data/test/gcloud/datastore/proto/test_cursor.rb +0 -36
  46. data/test/gcloud/datastore/proto/test_direction.rb +0 -60
  47. data/test/gcloud/datastore/proto/test_operator.rb +0 -76
  48. data/test/gcloud/datastore/proto/test_value.rb +0 -231
  49. data/test/gcloud/datastore/test_connection.rb +0 -93
  50. data/test/gcloud/datastore/test_credentials.rb +0 -38
  51. data/test/gcloud/datastore/test_dataset.rb +0 -413
  52. data/test/gcloud/datastore/test_entity.rb +0 -161
  53. data/test/gcloud/datastore/test_entity_exclude.rb +0 -225
  54. data/test/gcloud/datastore/test_key.rb +0 -189
  55. data/test/gcloud/datastore/test_query.rb +0 -271
  56. data/test/gcloud/datastore/test_transaction.rb +0 -121
  57. data/test/gcloud/storage/test_backoff.rb +0 -127
  58. data/test/gcloud/storage/test_bucket.rb +0 -270
  59. data/test/gcloud/storage/test_bucket_acl.rb +0 -253
  60. data/test/gcloud/storage/test_default_acl.rb +0 -256
  61. data/test/gcloud/storage/test_file.rb +0 -221
  62. data/test/gcloud/storage/test_file_acl.rb +0 -367
  63. data/test/gcloud/storage/test_project.rb +0 -180
  64. data/test/gcloud/storage/test_storage.rb +0 -29
  65. data/test/gcloud/storage/test_verifier.rb +0 -62
  66. data/test/gcloud/test_version.rb +0 -8
  67. 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