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 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