jashmenn-dalli 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,37 @@
1
+ class Dalli::Server::KSocket < Socket
2
+ attr_accessor :options
3
+
4
+ def self.open(host, port, options = {})
5
+ # All this ugly code to ensure proper Socket connect timeout
6
+ addr = Socket.getaddrinfo(host, nil)
7
+ sock = new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0)
8
+ sock.options = { :host => host, :port => port }.merge(options)
9
+ begin
10
+ sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3]))
11
+ rescue Errno::EINPROGRESS
12
+ resp = IO.select(nil, [sock], nil, sock.options[:timeout])
13
+ begin
14
+ sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3]))
15
+ rescue Errno::EISCONN
16
+ end
17
+ end
18
+ sock
19
+ end
20
+
21
+ def readfull(count)
22
+ value = ''
23
+ begin
24
+ loop do
25
+ value << sysread(count - value.bytesize)
26
+ break if value.bytesize == count
27
+ end
28
+ rescue Errno::EAGAIN, Errno::EWOULDBLOCK
29
+ if IO.select([self], nil, nil, options[:timeout])
30
+ retry
31
+ else
32
+ raise Timeout::Error, "IO timeout: #{options.inspect}"
33
+ end
34
+ end
35
+ value
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module Dalli
2
+ VERSION = '1.0.3'
3
+ end
@@ -0,0 +1,284 @@
1
+ # Used to test the full Rails stack.
2
+ # Stolen from the Rails 3.0 source.
3
+ # Needed for the session store tests.
4
+ require 'active_support/core_ext/kernel/reporting'
5
+ require 'active_support/core_ext/string/encoding'
6
+ if "ruby".encoding_aware?
7
+ # These are the normal settings that will be set up by Railties
8
+ # TODO: Have these tests support other combinations of these values
9
+ silence_warnings do
10
+ Encoding.default_internal = "UTF-8"
11
+ Encoding.default_external = "UTF-8"
12
+ end
13
+ end
14
+
15
+ require 'test/unit'
16
+ require 'abstract_controller'
17
+ require 'action_controller'
18
+ require 'action_view'
19
+ require 'action_dispatch'
20
+ require 'active_support/dependencies'
21
+ require 'action_controller/caching'
22
+ require 'action_controller/caching/sweeping'
23
+
24
+ require 'pp' # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late
25
+
26
+ module Rails
27
+ def self.logger
28
+ @logger ||= begin
29
+ l = Logger.new(STDOUT)
30
+ l.level = Logger::INFO; l
31
+ end
32
+ end
33
+ end
34
+
35
+ # Monkey patch the old routes initialization to be silenced.
36
+ class ActionDispatch::Routing::DeprecatedMapper
37
+ def initialize_with_silencer(*args)
38
+ ActiveSupport::Deprecation.silence { initialize_without_silencer(*args) }
39
+ end
40
+ alias_method_chain :initialize, :silencer
41
+ end
42
+
43
+ ActiveSupport::Dependencies.hook!
44
+
45
+ # Show backtraces for deprecated behavior for quicker cleanup.
46
+ ActiveSupport::Deprecation.debug = true
47
+
48
+ ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort
49
+
50
+ module RackTestUtils
51
+ def body_to_string(body)
52
+ if body.respond_to?(:each)
53
+ str = ""
54
+ body.each {|s| str << s }
55
+ str
56
+ else
57
+ body
58
+ end
59
+ end
60
+ extend self
61
+ end
62
+
63
+ module SetupOnce
64
+ extend ActiveSupport::Concern
65
+
66
+ included do
67
+ cattr_accessor :setup_once_block
68
+ self.setup_once_block = nil
69
+
70
+ setup :run_setup_once
71
+ end
72
+
73
+ module ClassMethods
74
+ def setup_once(&block)
75
+ self.setup_once_block = block
76
+ end
77
+ end
78
+
79
+ private
80
+ def run_setup_once
81
+ if self.setup_once_block
82
+ self.setup_once_block.call
83
+ self.setup_once_block = nil
84
+ end
85
+ end
86
+ end
87
+
88
+ SharedTestRoutes = ActionDispatch::Routing::RouteSet.new
89
+
90
+ module ActiveSupport
91
+ class TestCase
92
+ include SetupOnce
93
+ # Hold off drawing routes until all the possible controller classes
94
+ # have been loaded.
95
+ setup_once do
96
+ SharedTestRoutes.draw do |map|
97
+ # FIXME: match ':controller(/:action(/:id))'
98
+ map.connect ':controller/:action/:id'
99
+ end
100
+
101
+ ActionController::IntegrationTest.app.routes.draw do |map|
102
+ # FIXME: match ':controller(/:action(/:id))'
103
+ map.connect ':controller/:action/:id'
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ class RoutedRackApp
110
+ attr_reader :routes
111
+
112
+ def initialize(routes, &blk)
113
+ @routes = routes
114
+ @stack = ActionDispatch::MiddlewareStack.new(&blk).build(@routes)
115
+ end
116
+
117
+ def call(env)
118
+ @stack.call(env)
119
+ end
120
+ end
121
+
122
+ class BasicController
123
+ attr_accessor :request
124
+
125
+ def config
126
+ @config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config).tap do |config|
127
+ # VIEW TODO: View tests should not require a controller
128
+ public_dir = File.expand_path("../fixtures/public", __FILE__)
129
+ config.assets_dir = public_dir
130
+ config.javascripts_dir = "#{public_dir}/javascripts"
131
+ config.stylesheets_dir = "#{public_dir}/stylesheets"
132
+ config
133
+ end
134
+ end
135
+ end
136
+
137
+ class ActionDispatch::IntegrationTest < ActiveSupport::TestCase
138
+ setup do
139
+ @routes = SharedTestRoutes
140
+ end
141
+ end
142
+
143
+ class ActionController::IntegrationTest < ActiveSupport::TestCase
144
+ def self.build_app(routes = nil)
145
+ RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware|
146
+ middleware.use "ActionDispatch::ShowExceptions"
147
+ middleware.use "ActionDispatch::Callbacks"
148
+ middleware.use "ActionDispatch::ParamsParser"
149
+ middleware.use "ActionDispatch::Cookies"
150
+ middleware.use "ActionDispatch::Flash"
151
+ middleware.use "ActionDispatch::Head"
152
+ yield(middleware) if block_given?
153
+ end
154
+ end
155
+
156
+ self.app = build_app
157
+
158
+ # Stub Rails dispatcher so it does not get controller references and
159
+ # simply return the controller#action as Rack::Body.
160
+ class StubDispatcher < ::ActionDispatch::Routing::RouteSet::Dispatcher
161
+ protected
162
+ def controller_reference(controller_param)
163
+ controller_param
164
+ end
165
+
166
+ def dispatch(controller, action, env)
167
+ [200, {'Content-Type' => 'text/html'}, ["#{controller}##{action}"]]
168
+ end
169
+ end
170
+
171
+ def self.stub_controllers
172
+ old_dispatcher = ActionDispatch::Routing::RouteSet::Dispatcher
173
+ ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
174
+ ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, StubDispatcher }
175
+ yield ActionDispatch::Routing::RouteSet.new
176
+ ensure
177
+ ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
178
+ ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, old_dispatcher }
179
+ end
180
+
181
+ def with_routing(&block)
182
+ temporary_routes = ActionDispatch::Routing::RouteSet.new
183
+ old_app, self.class.app = self.class.app, self.class.build_app(temporary_routes)
184
+ old_routes = SharedTestRoutes
185
+ silence_warnings { Object.const_set(:SharedTestRoutes, temporary_routes) }
186
+
187
+ yield temporary_routes
188
+ ensure
189
+ self.class.app = old_app
190
+ silence_warnings { Object.const_set(:SharedTestRoutes, old_routes) }
191
+ end
192
+
193
+ def with_autoload_path(path)
194
+ path = File.join(File.dirname(__FILE__), "fixtures", path)
195
+ if ActiveSupport::Dependencies.autoload_paths.include?(path)
196
+ yield
197
+ else
198
+ begin
199
+ ActiveSupport::Dependencies.autoload_paths << path
200
+ yield
201
+ ensure
202
+ ActiveSupport::Dependencies.autoload_paths.reject! {|p| p == path}
203
+ ActiveSupport::Dependencies.clear
204
+ end
205
+ end
206
+ end
207
+ end
208
+
209
+ # Temporary base class
210
+ class Rack::TestCase < ActionController::IntegrationTest
211
+ def self.testing(klass = nil)
212
+ if klass
213
+ @testing = "/#{klass.name.underscore}".sub!(/_controller$/, '')
214
+ else
215
+ @testing
216
+ end
217
+ end
218
+
219
+ def get(thing, *args)
220
+ if thing.is_a?(Symbol)
221
+ super("#{self.class.testing}/#{thing}", *args)
222
+ else
223
+ super
224
+ end
225
+ end
226
+
227
+ def assert_body(body)
228
+ assert_equal body, Array.wrap(response.body).join
229
+ end
230
+
231
+ def assert_status(code)
232
+ assert_equal code, response.status
233
+ end
234
+
235
+ def assert_response(body, status = 200, headers = {})
236
+ assert_body body
237
+ assert_status status
238
+ headers.each do |header, value|
239
+ assert_header header, value
240
+ end
241
+ end
242
+
243
+ def assert_content_type(type)
244
+ assert_equal type, response.headers["Content-Type"]
245
+ end
246
+
247
+ def assert_header(name, value)
248
+ assert_equal value, response.headers[name]
249
+ end
250
+ end
251
+
252
+ class ActionController::Base
253
+ def self.test_routes(&block)
254
+ routes = ActionDispatch::Routing::RouteSet.new
255
+ routes.draw(&block)
256
+ include routes.url_helpers
257
+ end
258
+ end
259
+
260
+ class ::ApplicationController < ActionController::Base
261
+ end
262
+
263
+ module ActionController
264
+ class Base
265
+ include ActionController::Testing
266
+ end
267
+
268
+ Base.view_paths = []
269
+
270
+ class TestCase
271
+ include ActionDispatch::TestProcess
272
+
273
+ setup do
274
+ @routes = SharedTestRoutes
275
+ end
276
+ end
277
+ end
278
+
279
+ # This stub emulates the Railtie including the URL helpers from a Rails application
280
+ module ActionController
281
+ class Base
282
+ include SharedTestRoutes.url_helpers
283
+ end
284
+ end
@@ -0,0 +1,170 @@
1
+ require 'helper'
2
+ require 'benchmark'
3
+
4
+ class TestBenchmark < Test::Unit::TestCase
5
+
6
+ def setup
7
+ puts "Testing #{Dalli::VERSION} with #{RUBY_DESCRIPTION}"
8
+ # We'll use a simple @value to try to avoid spending time in Marshal,
9
+ # which is a constant penalty that both clients have to pay
10
+ @value = []
11
+ @marshalled = Marshal.dump(@value)
12
+
13
+ @servers = ['127.0.0.1:19122', 'localhost:19122']
14
+ @key1 = "Short"
15
+ @key2 = "Sym1-2-3::45"*8
16
+ @key3 = "Long"*40
17
+ @key4 = "Medium"*8
18
+ # 5 and 6 are only used for multiget miss test
19
+ @key5 = "Medium2"*8
20
+ @key6 = "Long3"*40
21
+ @counter = 'counter'
22
+ end
23
+
24
+ def test_benchmark
25
+ memcached do
26
+
27
+ Benchmark.bm(31) do |x|
28
+
29
+ n = 2500
30
+
31
+ @m = Dalli::Client.new(@servers)
32
+ x.report("set:plain:dalli") do
33
+ n.times do
34
+ @m.set @key1, @marshalled, 0, :raw => true
35
+ @m.set @key2, @marshalled, 0, :raw => true
36
+ @m.set @key3, @marshalled, 0, :raw => true
37
+ @m.set @key1, @marshalled, 0, :raw => true
38
+ @m.set @key2, @marshalled, 0, :raw => true
39
+ @m.set @key3, @marshalled, 0, :raw => true
40
+ end
41
+ end
42
+
43
+ @m = Dalli::Client.new(@servers)
44
+ x.report("setq:plain:dalli") do
45
+ @m.multi do
46
+ n.times do
47
+ @m.set @key1, @marshalled, 0, :raw => true
48
+ @m.set @key2, @marshalled, 0, :raw => true
49
+ @m.set @key3, @marshalled, 0, :raw => true
50
+ @m.set @key1, @marshalled, 0, :raw => true
51
+ @m.set @key2, @marshalled, 0, :raw => true
52
+ @m.set @key3, @marshalled, 0, :raw => true
53
+ end
54
+ end
55
+ end
56
+
57
+ @m = Dalli::Client.new(@servers)
58
+ x.report("set:ruby:dalli") do
59
+ n.times do
60
+ @m.set @key1, @value
61
+ @m.set @key2, @value
62
+ @m.set @key3, @value
63
+ @m.set @key1, @value
64
+ @m.set @key2, @value
65
+ @m.set @key3, @value
66
+ end
67
+ end
68
+
69
+ @m = Dalli::Client.new(@servers)
70
+ x.report("get:plain:dalli") do
71
+ n.times do
72
+ @m.get @key1, :raw => true
73
+ @m.get @key2, :raw => true
74
+ @m.get @key3, :raw => true
75
+ @m.get @key1, :raw => true
76
+ @m.get @key2, :raw => true
77
+ @m.get @key3, :raw => true
78
+ end
79
+ end
80
+
81
+ @m = Dalli::Client.new(@servers)
82
+ x.report("get:ruby:dalli") do
83
+ n.times do
84
+ @m.get @key1
85
+ @m.get @key2
86
+ @m.get @key3
87
+ @m.get @key1
88
+ @m.get @key2
89
+ @m.get @key3
90
+ end
91
+ end
92
+
93
+ @m = Dalli::Client.new(@servers)
94
+ x.report("multiget:ruby:dalli") do
95
+ n.times do
96
+ # We don't use the keys array because splat is slow
97
+ @m.get_multi @key1, @key2, @key3, @key4, @key5, @key6
98
+ end
99
+ end
100
+
101
+ @m = Dalli::Client.new(@servers)
102
+ x.report("missing:ruby:dalli") do
103
+ n.times do
104
+ begin @m.delete @key1; rescue; end
105
+ begin @m.get @key1; rescue; end
106
+ begin @m.delete @key2; rescue; end
107
+ begin @m.get @key2; rescue; end
108
+ begin @m.delete @key3; rescue; end
109
+ begin @m.get @key3; rescue; end
110
+ end
111
+ end
112
+
113
+ @m = Dalli::Client.new(@servers)
114
+ x.report("mixed:ruby:dalli") do
115
+ n.times do
116
+ @m.set @key1, @value
117
+ @m.set @key2, @value
118
+ @m.set @key3, @value
119
+ @m.get @key1
120
+ @m.get @key2
121
+ @m.get @key3
122
+ @m.set @key1, @value
123
+ @m.get @key1
124
+ @m.set @key2, @value
125
+ @m.get @key2
126
+ @m.set @key3, @value
127
+ @m.get @key3
128
+ end
129
+ end
130
+
131
+ @m = Dalli::Client.new(@servers)
132
+ x.report("mixedq:ruby:dalli") do
133
+ @m.multi do
134
+ n.times do
135
+ @m.set @key1, @value
136
+ @m.set @key2, @value
137
+ @m.set @key3, @value
138
+ @m.get @key1
139
+ @m.get @key2
140
+ @m.get @key3
141
+ @m.set @key1, @value
142
+ @m.get @key1
143
+ @m.set @key2, @value
144
+ @m.replace @key2, @value
145
+ @m.delete @key3
146
+ @m.add @key3, @value
147
+ @m.get @key2
148
+ @m.set @key3, @value
149
+ @m.get @key3
150
+ end
151
+ end
152
+ end
153
+
154
+ @m = Dalli::Client.new(@servers)
155
+ x.report("incr:ruby:dalli") do
156
+ n.times do
157
+ @m.incr @counter, 1, 0, 1
158
+ end
159
+ n.times do
160
+ @m.decr @counter, 1
161
+ end
162
+
163
+ assert_equal 0, @m.incr(@counter, 0)
164
+ end
165
+
166
+ end
167
+ end
168
+
169
+ end
170
+ end