cloud_cache 1.0.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  = cloud_cache
2
2
 
3
- http://code.google.com/p/cloudcache-ruby/
3
+ http://www.quetzall.com/
4
4
 
5
5
  == DESCRIPTION:
6
6
 
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
- require 'hmac-sha1'
8
-
9
-
10
- module ActiveSupport
11
- module Cache
12
-
13
- class CloudCache < Store
14
-
15
- VERSION = '1.0.2'
16
-
17
- attr_accessor :secret_key
18
-
19
- def initialize(access_key, secret_key)
20
- puts 'Creating new CloudCache'
21
- @access_key = access_key
22
- @secret_key = secret_key
23
-
24
- end
25
-
26
- def run_http(http_method, command_name, command_path, body=nil, parameters=nil, extra_headers=nil)
27
- ts = generate_timestamp(Time.now.gmtime)
28
- # puts 'timestamp = ' + ts
29
- sig = generate_signature("CloudCache", command_name, ts, @secret_key)
30
- # puts "My signature = " + sig
31
- url = "http://cloudcache.ws/" + command_path
32
- # puts url
33
-
34
- user_agent = "CloudCache Ruby Client"
35
- headers = {'User-Agent' => user_agent, 'signature' => sig, 'timestamp' => ts, 'akey' => @access_key}
36
-
37
- if !extra_headers.nil?
38
- extra_headers.each_pair do |k, v|
39
- headers[k] = v
40
- end
41
- end
42
-
43
-
44
- uri = URI.parse(url)
45
- if (http_method == :put)
46
- req = Net::HTTP::Put.new(uri.path)
47
- req.body = body unless body.nil?
48
- elsif (http_method == :post)
49
- req = Net::HTTP::Post.new(uri.path)
50
- if !parameters.nil?
51
- req.set_form_data(parameters)
52
- end
53
- elsif (http_method == :delete)
54
- req = Net::HTTP::Delete.new(uri.path)
55
- if !parameters.nil?
56
- req.set_form_data(parameters)
57
- end
58
- else
59
- req = Net::HTTP::Get.new(uri.path)
60
- end
61
- headers.each_pair do |k, v|
62
- req[k] = v
63
- end
64
- # req.each_header do |k, v|
65
- # puts 'header ' + k + '=' + v
66
- #end
67
- res = Net::HTTP.start(uri.host, uri.port) do |http|
68
- http.request(req)
69
- end
70
- case res
71
- when Net::HTTPSuccess
72
- # puts 'response body=' + res.body
73
- res.body
74
- else
75
- res.error!
76
- end
77
-
78
- end
79
-
80
- def auth()
81
- command_name = "auth"
82
- command_path = "auth"
83
- run_http(:get, command_name, command_path)
84
- end
85
-
86
- def put(key, val, seconds_to_store=0)
87
- # seconds_to_store = seconds_to_store > 0 ? seconds_to_store : 9999999
88
- # puts 'seconds=' + seconds_to_store.to_s
89
- data = Marshal.dump(val)
90
- val_to_put = data #(Time.now+seconds_to_store).to_i.to_s + "::" + data
91
- extra_headers = seconds_to_store > 0 ? {"ttl"=>seconds_to_store} : nil
92
- run_http(:put, "PUT", key, val_to_put, nil, extra_headers)
93
- end
94
-
95
-
96
- def get_multi(keys)
97
- kj = keys.to_json
98
- puts "keys.to_json = " + kj
99
- extra_headers = {"keys" => kj }
100
- puts "get_multi, extra_headers keys = " + extra_headers.keys.to_s
101
- puts "get_multi, extra_headers vals = " + extra_headers.values.to_s
102
- body = run_http(:get, "GET", "getmulti" , nil,nil,extra_headers)
103
- vals = ActiveSupport::JSON.decode body
104
- vals
105
- end
106
- def get(key)
107
-
108
- begin
109
- cache_entry = run_http(:get, "GET", key)
110
- rescue Net::HTTPServerException
111
- # puts $!.message
112
- return nil if $!.message.include? "404"
113
- raise $!
114
- end
115
- # puts 'cache_entry=' + cache_entry
116
- =begin
117
- index = cache_entry.index('::')
118
- puts 'index=' + index.to_s
119
- expires = cache_entry[0..index].to_i
120
- puts 'expires in get=' + expires.to_s
121
- expires2 = (expires - Time.now.to_i)
122
- data = cache_entry[(index+2)...cache_entry.length]
123
- =end
124
-
125
- data = cache_entry
126
- return Marshal.load(data)
127
-
128
- =begin
129
- if expires2 > 0
130
- return Marshal.load(data)
131
- else
132
- puts 'expired=' + key + ' about ' + expires2.to_s + ' ago... now=' + Time.now.to_s
133
- end
134
- =end
135
-
136
- end
137
-
138
- def list_keys
139
- body = run_http(:get, "listkeys", "listkeys")
140
- keys = ActiveSupport::JSON.decode body # body[1..-2].split(',').collect! {|n| n.to_i}
141
- keys
142
- end
143
-
144
- def stats
145
- body = run_http(:get, "mystats", "mystats")
146
- #keys = ActiveSupport::JSON.decode body # body[1..-2].split(',').collect! {|n| n.to_i}
147
- body
148
- end
149
-
150
-
151
- def flush
152
- body = run_http(:get, "flush", "flush")
153
- body.strip
154
- end
155
-
156
- def clear
157
- flush
158
- end
159
-
160
- def read(name, options = nil)
161
- # puts 'read from localcache'
162
- super
163
- ret = get(name)
164
- # puts 'ret.frozen=' + ret.frozen?.to_s
165
- return ret
166
- end
167
-
168
- def write(name, value, options = nil)
169
- super
170
- put(name, value, options.nil? ? nil : options[:expires_in])
171
- # puts 'write.frozen=' + value.frozen?.to_s
172
- end
173
-
174
- def delete(name, options = nil)
175
- super
176
- run_http(:delete, "DELETE", name)
177
- end
178
-
179
- def delete_matched(matcher, options = nil)
180
- super
181
- raise "delete_matched not yet supported by CloudCache"
182
- end
183
-
184
- def exist?(key, options = nil)
185
- x = get(key)
186
- r = true
187
- if (x == nil)
188
- r = false
189
- end
190
- r
191
- end
192
-
193
- def fetch(key , options = {})
194
- if (options != {})
195
- raise "Options on fetch() not yet supported by this library"
196
- end
197
- v = get(key)
198
- v
199
- end
200
-
201
- def increment(key,val=1)
202
- ret = run_http(:post, "POST", key + "/incr", nil, {"val"=>val})
203
- ret.to_i
204
- end
205
-
206
- def decrement(key,val=1)
207
- ret = run_http(:post, "POST", key + "/decr", nil, {"val"=>val})
208
- ret.to_i
209
- end
210
-
211
- def silence!
212
- super
213
- end
214
-
215
- def shutdown
216
-
217
- end
218
-
219
-
220
- def generate_timestamp(gmtime)
221
- return gmtime.strftime("%Y-%m-%dT%H:%M:%SZ")
222
- end
223
-
224
- def generate_signature(service, operation, timestamp, secret_access_key)
225
- my_sha_hmac = HMAC::SHA1.digest(secret_access_key, service + operation + timestamp)
226
- my_b64_hmac_digest = Base64.encode64(my_sha_hmac).strip
227
- return my_b64_hmac_digest
228
- end
229
- end
230
- end
231
- end
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
@@ -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
@@ -0,0 +1,9 @@
1
+
2
+ class MyClass
3
+ attr_accessor :name, :age
4
+
5
+ def initialize(name, age)
6
+ @name = name
7
+ @age = age
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # temporary until rubymine supports ruby 1.i
2
+
3
+ #require 'test/unit'
4
+ #require 'cache_tests'
5
+
6
+ #t = CacheTests.new("test_get_multi")
7
+ #Test::Unit::UI::Console::TestRunner.run(CacheTests)
8
+ #t.setup
9
+ #t.test_counters
10
+ #t.teardown
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.0.2
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-05-27 00:00:00 -07:00
12
+ date: 2009-09-21 00:00:00 -07:00
13
13
  default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: hoe
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
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
- - test/test_cloud_cache.rb
27
+ - lib/hmac.rb
28
+ - README.txt
46
29
  has_rdoc: true
47
- homepage: http://code.google.com/p/cloudcache-ruby/
30
+ homepage: http://github.com/quetzall/cloud_cache/
48
31
  licenses: []
49
32
 
50
33
  post_install_message:
51
34
  rdoc_options:
52
- - --main
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: spacegems
71
- rubygems_version: 1.3.2
52
+ rubyforge_project:
53
+ rubygems_version: 1.3.5
72
54
  signing_key:
73
- specification_version: 3
74
- summary: Instant memcached, no servers required! See www.quetzall.com for more information.
55
+ specification_version: 2
56
+ summary: Client library for Quetzall's CloudCache service.
75
57
  test_files:
76
- - test/test_cloud_cache.rb
58
+ - test/cache_tests.rb
59
+ - test/my_class.rb
60
+ - test/test_runner.rb
data/History.txt DELETED
@@ -1,6 +0,0 @@
1
- === 1.0.0 / 2009-04-23
2
-
3
- * 1 major enhancement
4
-
5
- * Birthday!
6
-
data/Manifest.txt DELETED
@@ -1,9 +0,0 @@
1
- History.txt
2
- Manifest.txt
3
- README.txt
4
- Rakefile
5
- bin/cloud_cache
6
- lib/cloud_cache.rb
7
- lib/hmac.rb
8
- lib/hmac-sha1.rb
9
- test/test_cloud_cache.rb
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
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- abort "you need to write me"
@@ -1,8 +0,0 @@
1
- require "test/unit"
2
- require "cloud_cache"
3
-
4
- class TestCloudCache < Test::Unit::TestCase
5
- def test_sanity
6
- flunk "write tests or I will kneecap you"
7
- end
8
- end