cloud_cache 1.0.2 → 1.2.3
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.
- data/README.txt +1 -1
- data/lib/cloud_cache.rb +323 -231
- data/test/cache_tests.rb +318 -0
- data/test/my_class.rb +9 -0
- data/test/test_runner.rb +10 -0
- metadata +19 -35
- data/History.txt +0 -6
- data/Manifest.txt +0 -9
- data/Rakefile +0 -12
- data/bin/cloud_cache +0 -3
- data/test/test_cloud_cache.rb +0 -8
data/README.txt
CHANGED
data/lib/cloud_cache.rb
CHANGED
@@ -1,231 +1,323 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'active_support'
|
3
|
-
require 'net/http'
|
4
|
-
require 'base64'
|
5
|
-
|
6
|
-
$:.unshift(File.dirname(__FILE__))
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# puts
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
req.
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
=
|
117
|
-
|
118
|
-
puts
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
=
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
=
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_support'
|
3
|
+
require 'net/http'
|
4
|
+
require 'base64'
|
5
|
+
|
6
|
+
$:.unshift(File.dirname(__FILE__))
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'digest/hmac'
|
10
|
+
USE_EMBEDDED_HMAC = false
|
11
|
+
rescue
|
12
|
+
puts "HMAC, not found in standard lib." + $!.message
|
13
|
+
require 'hmac-sha1'
|
14
|
+
USE_EMBEDDED_HMAC = true
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
class CloudCache < ActiveSupport::Cache::Store
|
19
|
+
|
20
|
+
|
21
|
+
attr_accessor :secret_key
|
22
|
+
|
23
|
+
def initialize(access_key, secret_key)
|
24
|
+
puts 'Creating new CloudCache'
|
25
|
+
@access_key = access_key
|
26
|
+
@secret_key = secret_key
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def run_http(http_method, command_name, command_path, body=nil, parameters=nil, extra_headers=nil)
|
31
|
+
ts = generate_timestamp(Time.now.gmtime)
|
32
|
+
# puts 'timestamp = ' + ts
|
33
|
+
sig = generate_signature("CloudCache", command_name, ts, @secret_key)
|
34
|
+
# puts "My signature = " + sig
|
35
|
+
url = "http://cloudcache.ws/" + command_path
|
36
|
+
# puts url
|
37
|
+
|
38
|
+
user_agent = "CloudCache Ruby Client"
|
39
|
+
headers = {'User-Agent' => user_agent, 'signature' => sig, 'timestamp' => ts, 'akey' => @access_key}
|
40
|
+
|
41
|
+
if !extra_headers.nil?
|
42
|
+
extra_headers.each_pair do |k, v|
|
43
|
+
headers[k] = v
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
uri = URI.parse(url)
|
49
|
+
#puts 'body=' + body.to_s
|
50
|
+
if (http_method == :put)
|
51
|
+
req = Net::HTTP::Put.new(uri.path)
|
52
|
+
req.body = body unless body.nil?
|
53
|
+
#puts 'BODY SIZE=' + req.body.length.to_s
|
54
|
+
elsif (http_method == :post)
|
55
|
+
req = Net::HTTP::Post.new(uri.path)
|
56
|
+
if !parameters.nil?
|
57
|
+
req.set_form_data(parameters)
|
58
|
+
end
|
59
|
+
elsif (http_method == :delete)
|
60
|
+
req = Net::HTTP::Delete.new(uri.path)
|
61
|
+
if !parameters.nil?
|
62
|
+
req.set_form_data(parameters)
|
63
|
+
end
|
64
|
+
else
|
65
|
+
req = Net::HTTP::Get.new(uri.path)
|
66
|
+
if !parameters.nil?
|
67
|
+
req.set_form_data(parameters)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
headers.each_pair do |k, v|
|
71
|
+
req[k] = v
|
72
|
+
end
|
73
|
+
# req.each_header do |k, v|
|
74
|
+
# puts 'header ' + k + '=' + v
|
75
|
+
#end
|
76
|
+
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
77
|
+
http.request(req)
|
78
|
+
end
|
79
|
+
#puts 'response body=' + res.body
|
80
|
+
case res
|
81
|
+
when Net::HTTPSuccess
|
82
|
+
#puts 'response body=' + res.body
|
83
|
+
res.body
|
84
|
+
else
|
85
|
+
res.error!
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def auth()
|
91
|
+
command_name = "auth"
|
92
|
+
command_path = "auth"
|
93
|
+
run_http(:get, command_name, command_path)
|
94
|
+
end
|
95
|
+
|
96
|
+
def put(key, val, options={})
|
97
|
+
seconds_to_store = options[:expires_in] || options[:ttl]
|
98
|
+
raw = options[:raw]
|
99
|
+
#puts 'putting ' + val.to_s + ' to key=' + key
|
100
|
+
seconds_to_store = 0 if seconds_to_store.nil?
|
101
|
+
if raw
|
102
|
+
data = val.to_s
|
103
|
+
else
|
104
|
+
data = (Marshal.dump(val))
|
105
|
+
#data = Base64.encode64(data)
|
106
|
+
end
|
107
|
+
#puts 'putting=' + data.to_s
|
108
|
+
extra_headers = seconds_to_store > 0 ? {"ttl"=>seconds_to_store} : nil
|
109
|
+
run_http(:put, "PUT", key, data, nil, extra_headers)
|
110
|
+
end
|
111
|
+
|
112
|
+
def get_multi(keys, options={})
|
113
|
+
return {} if keys.size == 0
|
114
|
+
raw = options[:raw]
|
115
|
+
kj = keys.to_json
|
116
|
+
#puts "keys.to_json = " + kj
|
117
|
+
extra_headers = {"keys" => kj }
|
118
|
+
#puts "get_multi, extra_headers keys = " + extra_headers.keys.to_s
|
119
|
+
#puts "get_multi, extra_headers vals = " + extra_headers.values.to_s
|
120
|
+
body = run_http(:get, "GET", "getmulti", nil, nil, extra_headers)
|
121
|
+
#puts 'body=' + body.to_s
|
122
|
+
# todo: should try to stream the body in
|
123
|
+
#vals = ActiveSupport::JSON.decode body
|
124
|
+
# New response format is:
|
125
|
+
# VALUE <key> <bytes> \r\n
|
126
|
+
# <data block>\r\n
|
127
|
+
# VALUE <key> <bytes> \r\n
|
128
|
+
# <data block>\r\n
|
129
|
+
# END
|
130
|
+
values = {}
|
131
|
+
curr_key = nil
|
132
|
+
data_length = 0
|
133
|
+
val = ""
|
134
|
+
count = 0
|
135
|
+
body.each_line do |line|
|
136
|
+
#print 'LINE=' + line
|
137
|
+
if line == "END\r\n"
|
138
|
+
# puts 'ENDED!!!'
|
139
|
+
break
|
140
|
+
end
|
141
|
+
if line =~ /^VALUE (.+) (.+)/ then # (key) (bytes)
|
142
|
+
if !curr_key.nil?
|
143
|
+
values[curr_key] = raw ? val.strip : Marshal.load(val.strip)
|
144
|
+
end
|
145
|
+
curr_key, data_length = $1, $2
|
146
|
+
val = ""
|
147
|
+
#raise CloudCacheError, "Unexpected response #{line.inspect}"
|
148
|
+
else
|
149
|
+
# data block
|
150
|
+
val += line
|
151
|
+
end
|
152
|
+
count += 1
|
153
|
+
end
|
154
|
+
if !val.nil? && val != ""
|
155
|
+
values[curr_key] = raw ? val.strip : Marshal.load((val.strip))
|
156
|
+
end
|
157
|
+
#puts 'values=' + values.inspect
|
158
|
+
values
|
159
|
+
end
|
160
|
+
|
161
|
+
def get(key, options={})
|
162
|
+
raw = options[:raw]
|
163
|
+
begin
|
164
|
+
data = run_http(:get, "GET", key)
|
165
|
+
rescue Net::HTTPServerException
|
166
|
+
# puts $!.message
|
167
|
+
return nil if $!.message.include? "404"
|
168
|
+
raise $!
|
169
|
+
end
|
170
|
+
#puts 'data1=' + data.to_s
|
171
|
+
if raw
|
172
|
+
return data
|
173
|
+
else
|
174
|
+
#data = Base64.decode64(data)
|
175
|
+
return Marshal.load((data))
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# returns the value as an int.
|
180
|
+
def get_i(key)
|
181
|
+
val = get(key, :raw=>true)
|
182
|
+
return nil if val.nil?
|
183
|
+
return val.to_i
|
184
|
+
end
|
185
|
+
|
186
|
+
def list_keys
|
187
|
+
body = run_http(:get, "listkeys", "listkeys")
|
188
|
+
# puts "list_keys=" + body
|
189
|
+
keys = ActiveSupport::JSON.decode body # body[1..-2].split(',').collect! {|n| n.to_i}
|
190
|
+
keys
|
191
|
+
end
|
192
|
+
|
193
|
+
def stats
|
194
|
+
body = run_http(:get, "myusage", "myusage")
|
195
|
+
#keys = ActiveSupport::JSON.decode body # body[1..-2].split(',').collect! {|n| n.to_i}
|
196
|
+
#puts 'body=' + body
|
197
|
+
body.to_i
|
198
|
+
end
|
199
|
+
|
200
|
+
def usage
|
201
|
+
return stats
|
202
|
+
end
|
203
|
+
|
204
|
+
def flush
|
205
|
+
body = run_http(:get, "flush", "flush")
|
206
|
+
body.strip
|
207
|
+
end
|
208
|
+
|
209
|
+
def clear
|
210
|
+
flush
|
211
|
+
end
|
212
|
+
|
213
|
+
def read(name, options={})
|
214
|
+
super
|
215
|
+
ret = get(name)
|
216
|
+
return ret
|
217
|
+
end
|
218
|
+
|
219
|
+
def write(name, value, options={})
|
220
|
+
super
|
221
|
+
put(name, value, options)
|
222
|
+
end
|
223
|
+
|
224
|
+
def delete(name, options = nil)
|
225
|
+
super
|
226
|
+
begin
|
227
|
+
run_http(:delete, "DELETE", name)
|
228
|
+
rescue Net::HTTPServerException => ex
|
229
|
+
puts 'CAUGHT ' + ex.response.inspect
|
230
|
+
case ex.response
|
231
|
+
when Net::HTTPNotFound
|
232
|
+
return false
|
233
|
+
else
|
234
|
+
raise ex
|
235
|
+
end
|
236
|
+
end
|
237
|
+
true
|
238
|
+
end
|
239
|
+
|
240
|
+
def remove(name, options=nil)
|
241
|
+
delete(name, options)
|
242
|
+
end
|
243
|
+
|
244
|
+
def delete_matched(matcher, options = nil)
|
245
|
+
super
|
246
|
+
raise "delete_matched not yet supported by CloudCache"
|
247
|
+
end
|
248
|
+
|
249
|
+
def exist?(key, options = nil)
|
250
|
+
exists?(key, options)
|
251
|
+
end
|
252
|
+
|
253
|
+
def exists?(key, options = nil)
|
254
|
+
x = get(key, :raw=>true)
|
255
|
+
return !x.nil?
|
256
|
+
end
|
257
|
+
|
258
|
+
def fetch(key, options = {})
|
259
|
+
if (options != {})
|
260
|
+
raise "Options on fetch() not yet supported by this library"
|
261
|
+
end
|
262
|
+
v = get(key)
|
263
|
+
v
|
264
|
+
end
|
265
|
+
|
266
|
+
def increment(key, val=1, options={})
|
267
|
+
headers = {"val"=>val}
|
268
|
+
if options[:set_if_not_found]
|
269
|
+
headers["x-cc-set-if-not-found"] = options[:set_if_not_found]
|
270
|
+
end
|
271
|
+
ret = run_http(:post, "POST", key + "/incr", nil, headers)
|
272
|
+
ret.to_i
|
273
|
+
end
|
274
|
+
|
275
|
+
def decrement(key, val=1, options={})
|
276
|
+
headers = {"val"=>val}
|
277
|
+
if options[:set_if_not_found]
|
278
|
+
headers["x-cc-set-if-not-found"] = options[:set_if_not_found]
|
279
|
+
end
|
280
|
+
ret = run_http(:post, "POST", key + "/decr", nil, headers)
|
281
|
+
ret.to_i
|
282
|
+
end
|
283
|
+
|
284
|
+
def silence!
|
285
|
+
super
|
286
|
+
end
|
287
|
+
|
288
|
+
def shutdown
|
289
|
+
close
|
290
|
+
end
|
291
|
+
|
292
|
+
def close
|
293
|
+
# close http connection if it exists.
|
294
|
+
end
|
295
|
+
|
296
|
+
|
297
|
+
def generate_timestamp(gmtime)
|
298
|
+
return gmtime.strftime("%Y-%m-%dT%H:%M:%SZ")
|
299
|
+
end
|
300
|
+
|
301
|
+
def generate_signature(service, operation, timestamp, secret_access_key)
|
302
|
+
if USE_EMBEDDED_HMAC
|
303
|
+
my_sha_hmac = HMAC::SHA1.digest(secret_access_key, service + operation + timestamp)
|
304
|
+
else
|
305
|
+
my_sha_hmac = Digest::HMAC.digest(service + operation + timestamp, secret_access_key, Digest::SHA1)
|
306
|
+
end
|
307
|
+
my_b64_hmac_digest = Base64.encode64(my_sha_hmac).strip
|
308
|
+
return my_b64_hmac_digest
|
309
|
+
end
|
310
|
+
|
311
|
+
class CloudCacheError < RuntimeError
|
312
|
+
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
|
317
|
+
# Backwards compatability
|
318
|
+
module ActiveSupport
|
319
|
+
module Cache
|
320
|
+
class CloudCache < ::CloudCache
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
data/test/cache_tests.rb
ADDED
@@ -0,0 +1,318 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require '../lib/cloud_cache'
|
3
|
+
require 'my_class'
|
4
|
+
#
|
5
|
+
# You'll need make a cloudcache.yml file in this directory that contains:
|
6
|
+
# amazon:
|
7
|
+
# access_key: ACCESS_KEY
|
8
|
+
# secret_key: SECRET
|
9
|
+
#
|
10
|
+
class CacheTests < Test::Unit::TestCase
|
11
|
+
|
12
|
+
def setup
|
13
|
+
puts("Setting up cache...")
|
14
|
+
props = nil
|
15
|
+
begin
|
16
|
+
props = YAML::load(File.read('cloudcache.yml'))
|
17
|
+
rescue
|
18
|
+
raise "Couldn't find cloudcache.yml file. " + $!.message
|
19
|
+
end
|
20
|
+
@cache = ActiveSupport::Cache::CloudCache.new(props['access_key'], props['secret_key'])
|
21
|
+
end
|
22
|
+
|
23
|
+
def teardown
|
24
|
+
@cache.shutdown unless @cache.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_auth
|
28
|
+
@cache.auth()
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_bad_auth
|
32
|
+
|
33
|
+
temp = @cache.secret_key
|
34
|
+
@cache.secret_key = "badkey"
|
35
|
+
|
36
|
+
assert_raise Net::HTTPServerException do
|
37
|
+
test_basic_ops
|
38
|
+
end
|
39
|
+
|
40
|
+
@cache.secret_key = temp
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_basic_ops
|
44
|
+
to_put = "I am a testing string. Take me apart and put me back together again."
|
45
|
+
@cache.put("s1", to_put)
|
46
|
+
|
47
|
+
sleep(1)
|
48
|
+
|
49
|
+
response = @cache.get("s1")
|
50
|
+
assert_equal(to_put, response)
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_not_exists
|
55
|
+
assert_nil @cache.get("does_not_exist")
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_delete
|
59
|
+
to_put = "I am a testing string. Take me apart and put me back together again."
|
60
|
+
@cache.put("s1", to_put)
|
61
|
+
|
62
|
+
sleep(1)
|
63
|
+
|
64
|
+
response = @cache.get("s1")
|
65
|
+
assert_equal(to_put, response)
|
66
|
+
|
67
|
+
@cache.delete("s1")
|
68
|
+
|
69
|
+
response = @cache.get("s1")
|
70
|
+
assert_nil(response)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_expiry
|
74
|
+
to_put = "I am a testing string. Take me apart and put me back together again."
|
75
|
+
@cache.put("s1", to_put, :ttl=>2);
|
76
|
+
sleep(4)
|
77
|
+
response = @cache.get("s1")
|
78
|
+
assert_nil(response)
|
79
|
+
|
80
|
+
@cache.write("s1", to_put, :expires_in=>2);
|
81
|
+
sleep(4)
|
82
|
+
response = @cache.get("s1")
|
83
|
+
assert_nil(response)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_list_keys
|
87
|
+
@cache.put("k1", "v2", :expires_in=>15)
|
88
|
+
sleep 1
|
89
|
+
keys = @cache.list_keys
|
90
|
+
puts("PRINTING KEYS:")
|
91
|
+
for key in keys
|
92
|
+
puts key
|
93
|
+
end
|
94
|
+
haskey = keys.index("k1")
|
95
|
+
assert_not_nil(haskey)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_counters
|
99
|
+
val = 0
|
100
|
+
key = "counter1" # should add a test for a key with a slash
|
101
|
+
@cache.put(key, val, :ttl=>50000, :raw=>true)
|
102
|
+
10.times do
|
103
|
+
val = @cache.increment(key)
|
104
|
+
puts 'val=' + val.to_s
|
105
|
+
end
|
106
|
+
assert_equal(10, val)
|
107
|
+
|
108
|
+
# get as normal int now
|
109
|
+
get_val = @cache.get_i(key)
|
110
|
+
assert_equal(10, get_val)
|
111
|
+
|
112
|
+
10.times do
|
113
|
+
val = @cache.decrement(key)
|
114
|
+
end
|
115
|
+
assert_equal(0, val)
|
116
|
+
|
117
|
+
# One more to make sure it stays at 0
|
118
|
+
val = @cache.decrement(key)
|
119
|
+
assert_equal(0, val)
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_flush
|
124
|
+
x = @cache.flush
|
125
|
+
assert_equal('[]', x)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_stats
|
129
|
+
x = @cache.stats
|
130
|
+
puts x
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_get_multi_raw
|
134
|
+
@cache.remove("m1") rescue false
|
135
|
+
@cache.remove("m2") rescue false
|
136
|
+
@cache.remove("m3") rescue false
|
137
|
+
@cache.remove("m4") rescue false
|
138
|
+
|
139
|
+
@cache.put("m1", "v1", :ttl=>500, :raw=>true)
|
140
|
+
@cache.put("m2", "v2", :ttl=>500, :raw=>true)
|
141
|
+
|
142
|
+
kz = Array["m1", "m2", "m3"]
|
143
|
+
vz = @cache.get_multi(kz, :raw=>true)
|
144
|
+
|
145
|
+
assert_equal("v1", vz["m1"])
|
146
|
+
assert_equal("v2", vz["m2"])
|
147
|
+
assert_nil(vz["m3"])
|
148
|
+
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_get_multi
|
153
|
+
|
154
|
+
kz = []
|
155
|
+
vz = @cache.get_multi(kz)
|
156
|
+
assert vz.size == 0
|
157
|
+
|
158
|
+
kz = ["nothere"]
|
159
|
+
vz = @cache.get_multi(kz)
|
160
|
+
assert vz.size == 0
|
161
|
+
|
162
|
+
@cache.remove("m1") rescue false
|
163
|
+
@cache.remove("m2") rescue false
|
164
|
+
@cache.remove("m3") rescue false
|
165
|
+
@cache.remove("m4") rescue false
|
166
|
+
|
167
|
+
@cache.put("m1", "v1", :ttl=>500, :raw=>false)
|
168
|
+
@cache.put("m2", "v2", :ttl=>500, :raw=>false)
|
169
|
+
@cache.put("m4", MyClass.new("Travis", 10), :ttl=>500, :raw=>false)
|
170
|
+
|
171
|
+
kz = ["m1", "m2", "m3", "m4"]
|
172
|
+
vz = @cache.get_multi(kz)
|
173
|
+
|
174
|
+
assert_equal("v1", vz["m1"]);
|
175
|
+
assert_equal("v2", vz["m2"]);
|
176
|
+
assert_nil(vz["m3"]);
|
177
|
+
assert_equal("Travis", vz["m4"].name)
|
178
|
+
assert_equal(10, vz["m4"].age)
|
179
|
+
|
180
|
+
@cache.put("m3", MyClass.new("Leroy", 3), :ttl=>500, :raw=>false)
|
181
|
+
|
182
|
+
kz = ["m1", "m2", "m3", "m4"]
|
183
|
+
vz = @cache.get_multi(kz)
|
184
|
+
|
185
|
+
assert_equal("v1", vz["m1"]);
|
186
|
+
assert_equal("v2", vz["m2"]);
|
187
|
+
assert_equal("Leroy", vz["m3"].name)
|
188
|
+
assert_equal(3, vz["m3"].age)
|
189
|
+
assert_equal("Travis", vz["m4"].name)
|
190
|
+
assert_equal(10, vz["m4"].age)
|
191
|
+
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_big
|
196
|
+
s = random_string(100000)
|
197
|
+
@cache.put("s1", s)
|
198
|
+
|
199
|
+
s2 = @cache.get("s1")
|
200
|
+
|
201
|
+
assert_equal(s, s2)
|
202
|
+
end
|
203
|
+
|
204
|
+
def random_string(length=10)
|
205
|
+
chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'
|
206
|
+
password = ''
|
207
|
+
length.times { password << chars[rand(chars.size)] }
|
208
|
+
password
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_usage
|
212
|
+
usage = @cache.usage
|
213
|
+
assert_kind_of(Numeric, usage)
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
def test_set_if_not_found
|
218
|
+
key = "sinf"
|
219
|
+
@cache.delete(key)
|
220
|
+
|
221
|
+
assert_raise Net::HTTPServerException do
|
222
|
+
@cache.increment(key, 1)
|
223
|
+
end
|
224
|
+
|
225
|
+
val = 3
|
226
|
+
ret = @cache.increment(key, 1, :set_if_not_found=>val)
|
227
|
+
assert ret == val
|
228
|
+
ret = @cache.get_i(key)
|
229
|
+
assert ret == val
|
230
|
+
ret = @cache.increment(key, 1, :set_if_not_found=>val)
|
231
|
+
assert ret == val + 1
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_failing_data
|
236
|
+
fname = "fail_message.txt"
|
237
|
+
return if !File.exists?(fname)
|
238
|
+
file = File.new fname
|
239
|
+
result = file.read # JSON.parse(file.read)
|
240
|
+
file.close
|
241
|
+
puts result.inspect
|
242
|
+
@cache.put("bigolmsg", result)
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_bad_md5
|
246
|
+
@cache.put("md5val", "BAhvOhFQZXJmTG9nRW50cnkPOhBAZW50cnlfZGF0ZVU6DURhdGVUaW1lWwhV
|
247
|
+
Og1SYXRpb25hbFsHbCsJN5Fzjkoz+wBsKwgAIJ20BgBVOwhbB2n0aR1pAxkV
|
248
|
+
IzoPQGZyb21fbm9kZW86DEFkYXB0ZXIJOhBAYXR0cmlidXRlc3sYSSIJbmFt
|
249
|
+
ZQY6DWVuY29kaW5nIgpVVEYtOFsGSSILVFI1MzAxBjsMQBFJIgx1cGRhdGVk
|
250
|
+
BjsMQBFbBkkiGDIwMDktMDktMTZUMDY6NDM6MTAGOwwiDVVTLUFTQ0lJSSIT
|
251
|
+
bGFzdF9jb25uZWN0ZWQGOwxAEVsGSSIYMjAwOS0wOS0xNlQwNjo0MzowOQY7
|
252
|
+
DEAXSSIOY29ubmVjdGVkBjsMQBFbBkkiGDIwMDktMDktMDFUMTA6MDY6MjYG
|
253
|
+
OwxAEUkiD25ldHdvcmtfaWQGOwxAEVsGSSIpMWY5MTQzNGMtOTZkZi0xMWRl
|
254
|
+
LWExOWItMDAxZWMyYjRhYjQ5BjsMQBFJIgdpZAY7DEARSSIpMWNiZmVjMGUt
|
255
|
+
OTZkZi0xMWRlLWExOWItMDAxZWMyYjRhYjQ5BjsMQBFJIgtzdGF0dXMGOwxA
|
256
|
+
EVsGSSIIbmV3BjsMQBFJIgxjcmVhdGVkBjsMQBFbBkkiGDIwMDktMDktMDFU
|
257
|
+
MTA6MDY6MjcGOwxAEUkiGHBsYXN0ZXJfbmV0d29ya3NfaWQGOwxAEVsGSSIL
|
258
|
+
VFI1MzAxBjsMQBFJIgp3YW5pcAY7DEARWwZJIg4xMjcuMC4wLjEGOwxAEUki
|
259
|
+
CG1hYwY7DEARWwZJIhEwMDI0RThUUjUzMDEGOwxAEUkiDmxhc3Rfc2VlbgY7
|
260
|
+
DEARWwZJIhgyMDA5LTA5LTE2VDA2OjQzOjA5BjsMQBdJIhRkZXZpY2VfcGFz
|
261
|
+
c3dvcmQGOwxAEVsGSSIVMTExMTIyMjIzMzMzNDQ0NAY7DEARSSIKc3d2ZXIG
|
262
|
+
OwxAEVsGSSILMC4wLjM1BjsMQBFJIhRuYW1lX29uX2FkYXB0ZXIGOwxAEVsG
|
263
|
+
SSILVFI1MzAxBjsMQBFJIhJyb2xsb3V0X3BoYXNlBjsMQBFbBkkiGTA5MjIz
|
264
|
+
MzcyMDM2ODU0Nzc1ODA5BjsMQBFJIg5sYXN0X3BlcmYGOwxAEVsGSSIYMjAw
|
265
|
+
OS0wOS0xNlQwNjo0MzowOQY7DEAXSSIUdGltZV9zaW5jZV9ib290BjsMQBFb
|
266
|
+
BkkiGTA5MjIzMzcyMDM2ODU0Nzc1ODMwBjsMQBdJIhhTZGItaXRlbS1pZGVu
|
267
|
+
dGlmaWVyBjsMQBFbBkkiKTFjYmZlYzBlLTk2ZGYtMTFkZS1hMTliLTAwMWVj
|
268
|
+
MmI0YWI0OQY7DEAROhBAbmV3X3JlY29yZEY6DEBlcnJvcnNvOiZTaW1wbGVS
|
269
|
+
ZWNvcmQ6OlNpbXBsZVJlY29yZF9lcnJvcnMGOw5bADoLQGRpcnR5ewpJIhNs
|
270
|
+
YXN0X2Nvbm5lY3RlZAY7DEAXSSIYMjAwOS0wOS0xNlQwNjo0MTozNQY7DEAR
|
271
|
+
SSIObGFzdF9zZWVuBjsMQBd1OglUaW1lDQZiG4BGJZCsSSIObGFzdF9wZXJm
|
272
|
+
BjsMQBdJIhgyMDA5LTA5LTE2VDA2OjQxOjM1BjsMQBFJIhR0aW1lX3NpbmNl
|
273
|
+
X2Jvb3QGOwxAF0kiGTA5MjIzMzcyMDM2ODU0Nzc1ODMwBjsMQBE6DHVwZGF0
|
274
|
+
ZWRJIhgyMDA5LTA5LTEzVDA1OjM1OjMwBjsMQBE6DUBuZXR3b3JrbzoMTmV0
|
275
|
+
d29yawk7C3sPSSINcGFzc3dvcmQGOwxAEVsGSSItMTQ1Yzg0NDIxNTgwZTZl
|
276
|
+
MGU1NGY0YmI2MTBjOTdjMzg3MTRkODZhMQY7DEARSSIMY3JlYXRlZAY7DEAR
|
277
|
+
WwZJIhgyMDA5LTA5LTAxVDEwOjA2OjMxBjsMQBFJIgdpZAY7DEARSSIpMWY5
|
278
|
+
MTQzNGMtOTZkZi0xMWRlLWExOWItMDAxZWMyYjRhYjQ5BjsMQBFJIg1vd25l
|
279
|
+
cl9pZAY7DEARWwZJIik4Y2RiMTJlMC1mODgxLTExZGQtYTBmMS0wMDE2ZWE1
|
280
|
+
ZTcxYzYGOwxAEUkiDHVwZGF0ZWQGOwxAEVsGSSIYMjAwOS0wOS0xMVQwMjo1
|
281
|
+
NDowMwY7DEARSSIJbmFtZQY7DEARWwZJIhVQTE4gVFI1MyBOZXR3b3JrBjsM
|
282
|
+
QBFJIhNwbGFpbl9wYXNzd29yZAY7DEARWwZJIg0xMjM0NTY3OAY7DEARSSIJ
|
283
|
+
Z3dpcAY7DEARWwZJIg4xMjcuMC4wLjEGOwxAEUkiCmd3bWFjBjsMQBFbBkki
|
284
|
+
ETAwMjRFOFRSNTM5OQY7DEARSSIKd2FuaXAGOwxAEVsGSSIOMTI3LjAuMC4x
|
285
|
+
BjsMQBE7DUY7Dm87DwY7DlsAOxB7ADoOQGFkYXB0ZXJzMDoPQHBlcmZfZGF0
|
286
|
+
YTA6EUB0aHJvdWdocHV0czA6F0ByZXF1ZXN0X2FzX3N0cmluZ0kiAjYEUGFy
|
287
|
+
YW1ldGVyczoKbWFjPTAwMjRFOFRSNTMwMQptYWNfY2NvPWNjb19tYWMKbnVt
|
288
|
+
c3Rhcz01Cmd3aXA9MTI3LjAuMC4xCmd3bWFjPTAwMjRFOFRSNTM5OQpzd3Zl
|
289
|
+
cj0wLjAuMzUKdGltZT0yMgpzdGFfbWFjXzA9MDAyNEU4VFI1MzAwCnN0YV9u
|
290
|
+
YW1lXzA9VFI1MzAwCnN0YV9tYWNfMT0wMDI0RThUUjUzMDEKc3RhX25hbWVf
|
291
|
+
MT1UUjUzMDEKc3RhX21hY18yPTAwMjRFOFRSNTMwMgpzdGFfbmFtZV8yPVRS
|
292
|
+
NTMwMgpzdGFfbWFjXzM9MDAyNEU4VFI1MzAzCnN0YV9uYW1lXzM9VFI1MzAz
|
293
|
+
CnN0YV9tYWNfND0wMDI0RThUUjUzMDQKc3RhX25hbWVfND1UUjUzMDQKc3Jj
|
294
|
+
X21hY18wPTAwMjRFOFRSNTMwMApkc3RfbWFjXzA9MDAyNEU4VFI1MzAxCnJh
|
295
|
+
dGVfZndkXzA9MjEKcmF0ZV9yZXZfMD0yMQpzcmNfbWFjXzE9MDAyNEU4VFI1
|
296
|
+
MzAwCmRzdF9tYWNfMT0wMDI0RThUUjUzMDIKcmF0ZV9md2RfMT0xNgpyYXRl
|
297
|
+
X3Jldl8xPTQKc3JjX21hY18yPTAwMjRFOFRSNTMwMApkc3RfbWFjXzI9MDAy
|
298
|
+
NEU4VFI1MzAzCnJhdGVfZndkXzI9MTgKcmF0ZV9yZXZfMj01CnNyY19tYWNf
|
299
|
+
Mz0wMDI0RThUUjUzMDAKZHN0X21hY18zPTAwMjRFOFRSNTMwNApyYXRlX2Z3
|
300
|
+
ZF8zPTcKcmF0ZV9yZXZfMz04CnNyY19tYWNfND0wMDI0RThUUjUzMDEKZHN0
|
301
|
+
X21hY180PTAwMjRFOFRSNTMwMgpyYXRlX2Z3ZF80PTYKcmF0ZV9yZXZfND0y
|
302
|
+
MgpzcmNfbWFjXzU9MDAyNEU4VFI1MzAxCmRzdF9tYWNfNT0wMDI0RThUUjUz
|
303
|
+
MDMKcmF0ZV9md2RfNT0yNwpyYXRlX3Jldl81PTI2CnNyY19tYWNfNj0wMDI0
|
304
|
+
RThUUjUzMDEKZHN0X21hY182PTAwMjRFOFRSNTMwNApyYXRlX2Z3ZF82PTgK
|
305
|
+
cmF0ZV9yZXZfNj0zMQpzcmNfbWFjXzc9MDAyNEU4VFI1MzAyCmRzdF9tYWNf
|
306
|
+
Nz0wMDI0RThUUjUzMDMKcmF0ZV9md2RfNz0xMQpyYXRlX3Jldl83PTYKc3Jj
|
307
|
+
X21hY184PTAwMjRFOFRSNTMwMgpkc3RfbWFjXzg9MDAyNEU4VFI1MzA0CnJh
|
308
|
+
dGVfZndkXzg9NQpyYXRlX3Jldl84PTIyCnNyY19tYWNfOT0wMDI0RThUUjUz
|
309
|
+
MDMKZHN0X21hY185PTAwMjRFOFRSNTMwNApyYXRlX2Z3ZF85PTIwCnJhdGVf
|
310
|
+
cmV2Xzk9MTcKY29udHJvbGxlcj1uYXBpL3YxCmFjdGlvbj1wZXJmCgY7DEAX
|
311
|
+
OhhAcmVzcG9uc2VfYXNfc3RyaW5nSSJZPD94bWwgdmVyc2lvbj0iMS4wIiBl
|
312
|
+
bmNvZGluZz0iVVRGLTgiPz4KPHJlc3BvbnNlPgogIDxtc2c+Y29udGludWU8
|
313
|
+
L21zZz4KPC9yZXNwb25zZT4KBjsMQBc6E0BlcnJvcl9tZXNzYWdlMDoMQGFj
|
314
|
+
dGlvbkkiCXBlcmYGOwxAFw==", :raw=>true)
|
315
|
+
end
|
316
|
+
|
317
|
+
|
318
|
+
end
|
data/test/my_class.rb
ADDED
data/test/test_runner.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloud_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Travis Reeder
|
@@ -9,48 +9,30 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-21 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 1.12.2
|
24
|
-
version:
|
25
|
-
description: Instant memcached, no servers required! See www.quetzall.com for more information.
|
26
|
-
email:
|
27
|
-
- travis@crankapps.com
|
28
|
-
executables:
|
29
|
-
- cloud_cache
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Client library for Quetzall's CloudCache service.
|
17
|
+
email: travis@appoxy.com
|
18
|
+
executables: []
|
19
|
+
|
30
20
|
extensions: []
|
31
21
|
|
32
22
|
extra_rdoc_files:
|
33
|
-
- History.txt
|
34
|
-
- Manifest.txt
|
35
23
|
- README.txt
|
36
24
|
files:
|
37
|
-
- History.txt
|
38
|
-
- Manifest.txt
|
39
|
-
- README.txt
|
40
|
-
- Rakefile
|
41
|
-
- bin/cloud_cache
|
42
25
|
- lib/cloud_cache.rb
|
43
|
-
- lib/hmac.rb
|
44
26
|
- lib/hmac-sha1.rb
|
45
|
-
-
|
27
|
+
- lib/hmac.rb
|
28
|
+
- README.txt
|
46
29
|
has_rdoc: true
|
47
|
-
homepage: http://
|
30
|
+
homepage: http://github.com/quetzall/cloud_cache/
|
48
31
|
licenses: []
|
49
32
|
|
50
33
|
post_install_message:
|
51
34
|
rdoc_options:
|
52
|
-
- --
|
53
|
-
- README.txt
|
35
|
+
- --charset=UTF-8
|
54
36
|
require_paths:
|
55
37
|
- lib
|
56
38
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -67,10 +49,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
49
|
version:
|
68
50
|
requirements: []
|
69
51
|
|
70
|
-
rubyforge_project:
|
71
|
-
rubygems_version: 1.3.
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 1.3.5
|
72
54
|
signing_key:
|
73
|
-
specification_version:
|
74
|
-
summary:
|
55
|
+
specification_version: 2
|
56
|
+
summary: Client library for Quetzall's CloudCache service.
|
75
57
|
test_files:
|
76
|
-
- test/
|
58
|
+
- test/cache_tests.rb
|
59
|
+
- test/my_class.rb
|
60
|
+
- test/test_runner.rb
|
data/History.txt
DELETED
data/Manifest.txt
DELETED
data/Rakefile
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
# -*- ruby -*-
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'hoe'
|
5
|
-
require './lib/cloud_cache.rb'
|
6
|
-
|
7
|
-
Hoe.new('cloud_cache', ActiveSupport::Cache::CloudCache::VERSION) do |p|
|
8
|
-
p.rubyforge_name = 'spacegems' # if different than lowercase project name
|
9
|
-
p.developer('Travis Reeder', 'travis@crankapps.com')
|
10
|
-
end
|
11
|
-
|
12
|
-
# vim: syntax=Ruby
|
data/bin/cloud_cache
DELETED