dharmarth-starling 0.9.9

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.
@@ -0,0 +1,216 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
+
3
+ require 'rubygems'
4
+ require 'fileutils'
5
+ require 'memcache'
6
+ require 'digest/md5'
7
+ require 'starling'
8
+
9
+ require 'starling/server'
10
+
11
+ class StarlingServer::PersistentQueue
12
+ remove_const :SOFT_LOG_MAX_SIZE
13
+ SOFT_LOG_MAX_SIZE = 16 * 1024 # 16 KB
14
+ end
15
+
16
+ def safely_fork(&block)
17
+ # anti-race juice:
18
+ blocking = true
19
+ Signal.trap("USR1") { blocking = false }
20
+
21
+ pid = Process.fork(&block)
22
+
23
+ while blocking
24
+ sleep 0.1
25
+ end
26
+
27
+ pid
28
+ end
29
+
30
+ describe "StarlingServer" do
31
+ before do
32
+ @tmp_path = File.join(File.dirname(__FILE__), "tmp")
33
+
34
+ begin
35
+ Dir::mkdir(@tmp_path)
36
+ rescue Errno::EEXIST
37
+ end
38
+
39
+ @server_pid = safely_fork do
40
+ server = StarlingServer::Base.new(:host => '127.0.0.1',
41
+ :port => 22133,
42
+ :path => @tmp_path,
43
+ :logger => Logger.new(STDERR),
44
+ :log_level => Logger::FATAL)
45
+ Signal.trap("INT") {
46
+ server.stop
47
+ exit
48
+ }
49
+
50
+ Process.kill("USR1", Process.ppid)
51
+ server.run
52
+ end
53
+
54
+ @client = MemCache.new('127.0.0.1:22133')
55
+
56
+ end
57
+
58
+ it "should test if temp_path exists and is writeable" do
59
+ File.exist?(@tmp_path).should be_true
60
+ File.directory?(@tmp_path).should be_true
61
+ File.writable?(@tmp_path).should be_true
62
+ end
63
+
64
+ it "should set and get" do
65
+ v = rand((2**32)-1)
66
+ @client.get('test_set_and_get_one_entry').should be_nil
67
+ @client.set('test_set_and_get_one_entry', v)
68
+ @client.get('test_set_and_get_one_entry').should eql(v)
69
+ end
70
+
71
+ it "should respond to delete" do
72
+ @client.delete("my_queue").should eql("END\r\n")
73
+ starling_client = Starling.new('127.0.0.1:22133')
74
+ starling_client.set('my_queue', 50)
75
+ starling_client.available_queues.size.should eql(1)
76
+ starling_client.delete("my_queue")
77
+ starling_client.available_queues.size.should eql(0)
78
+ end
79
+
80
+ it "should expire entries" do
81
+ v = rand((2**32)-1)
82
+ @client.get('test_set_with_expiry').should be_nil
83
+ now = Time.now.to_i
84
+ @client.set('test_set_with_expiry', v + 2, now)
85
+ @client.set('test_set_with_expiry', v)
86
+ sleep(1.0)
87
+ @client.get('test_set_with_expiry').should eql(v)
88
+ end
89
+
90
+ it "should have age stat" do
91
+ now = Time.now.to_i
92
+ @client.set('test_age', 'nibbler')
93
+ sleep(1.0)
94
+ @client.get('test_age').should eql('nibbler')
95
+
96
+ stats = @client.stats['127.0.0.1:22133']
97
+ stats.has_key?('queue_test_age_age').should be_true
98
+ (stats['queue_test_age_age'] >= 1000).should be_true
99
+ end
100
+
101
+ it "should rotate log" do
102
+ log_rotation_path = File.join(@tmp_path, 'test_log_rotation')
103
+
104
+ Dir.glob("#{log_rotation_path}*").each do |file|
105
+ File.unlink(file) rescue nil
106
+ end
107
+ @client.get('test_log_rotation').should be_nil
108
+
109
+ v = 'x' * 8192
110
+
111
+ @client.set('test_log_rotation', v)
112
+ File.size(log_rotation_path).should eql(8207)
113
+ @client.get('test_log_rotation')
114
+
115
+ @client.get('test_log_rotation').should be_nil
116
+
117
+ @client.set('test_log_rotation', v)
118
+ @client.get('test_log_rotation').should eql(v)
119
+
120
+ File.size(log_rotation_path).should eql(1)
121
+ # rotated log should be erased after a successful roll.
122
+ Dir.glob("#{log_rotation_path}*").size.should eql(1)
123
+ end
124
+
125
+ it "should output statistics per server" do
126
+ stats = @client.stats
127
+ assert_kind_of Hash, stats
128
+ assert stats.has_key?('127.0.0.1:22133')
129
+
130
+ server_stats = stats['127.0.0.1:22133']
131
+
132
+ basic_stats = %w( bytes pid time limit_maxbytes cmd_get version
133
+ bytes_written cmd_set get_misses total_connections
134
+ curr_connections curr_items uptime get_hits total_items
135
+ rusage_system rusage_user bytes_read )
136
+
137
+ basic_stats.each do |stat|
138
+ server_stats.has_key?(stat).should be_true
139
+ end
140
+ end
141
+
142
+ it "should return valid response with unkown command" do
143
+ response = @client.add('blah', 1)
144
+ response.should eql("CLIENT_ERROR bad command line format\r\n")
145
+ end
146
+
147
+ it "should disconnect and reconnect again" do
148
+ v = rand(2**32-1)
149
+ @client.set('test_that_disconnecting_and_reconnecting_works', v)
150
+ @client.reset
151
+ @client.get('test_that_disconnecting_and_reconnecting_works').should eql(v)
152
+ end
153
+
154
+ it "should use epoll on linux" do
155
+ # this may take a few seconds.
156
+ # the point is to make sure that we're using epoll on Linux, so we can
157
+ # handle more than 1024 connections.
158
+
159
+ unless IO::popen("uname").read.chomp == "Linux"
160
+ pending "skipping epoll test: not on Linux"
161
+ end
162
+
163
+ fd_limit = IO::popen("bash -c 'ulimit -n'").read.chomp.to_i
164
+ unless fd_limit > 1024
165
+ pending "skipping epoll test: 'ulimit -n' = #{fd_limit}, need > 1024"
166
+ end
167
+
168
+ v = rand(2**32 - 1)
169
+ @client.set('test_epoll', v)
170
+
171
+ # we can't open 1024 connections to memcache from within this process,
172
+ # because we will hit ruby's 1024 fd limit ourselves!
173
+ pid1 = safely_fork do
174
+ unused_sockets = []
175
+ 600.times do
176
+ unused_sockets << TCPSocket.new("127.0.0.1", 22133)
177
+ end
178
+ Process.kill("USR1", Process.ppid)
179
+ sleep 90
180
+ end
181
+ pid2 = safely_fork do
182
+ unused_sockets = []
183
+ 600.times do
184
+ unused_sockets << TCPSocket.new("127.0.0.1", 22133)
185
+ end
186
+ Process.kill("USR1", Process.ppid)
187
+ sleep 90
188
+ end
189
+
190
+ begin
191
+ client = MemCache.new('127.0.0.1:22133')
192
+ client.get('test_epoll').should eql(v)
193
+ ensure
194
+ Process.kill("TERM", pid1)
195
+ Process.kill("TERM", pid2)
196
+ end
197
+ end
198
+
199
+ it "should raise error if queue collection is an invalid path" do
200
+ invalid_path = nil
201
+ while invalid_path.nil? || File.exist?(invalid_path)
202
+ invalid_path = File.join('/', Digest::MD5.hexdigest(rand(2**32-1).to_s)[0,8])
203
+ end
204
+
205
+ lambda {
206
+ StarlingServer::QueueCollection.new(invalid_path)
207
+ }.should raise_error(StarlingServer::InaccessibleQueuePath)
208
+ end
209
+
210
+ after do
211
+ Process.kill("INT", @server_pid)
212
+ Process.wait(@server_pid)
213
+ @client.reset
214
+ FileUtils.rm(Dir.glob(File.join(@tmp_path, '*')))
215
+ end
216
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dharmarth-starling
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.9
5
+ platform: ruby
6
+ authors:
7
+ - Blaine Cook
8
+ - Chris Wanstrath
9
+ - Britt Selvitelle
10
+ - Glenn Rempe
11
+ - Abdul-Rahman Advany
12
+ - Seth Fitzsimmons
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2009-04-01 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: fiveruns-memcache-client
22
+ type: :runtime
23
+ version_requirement:
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: "0"
29
+ version:
30
+ - !ruby/object:Gem::Dependency
31
+ name: eventmachine
32
+ type: :runtime
33
+ version_requirement:
34
+ version_requirements: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: 0.12.0
39
+ version:
40
+ description: Starling is a lightweight, transactional, distributed queue server
41
+ email:
42
+ - blaine@twitter.com
43
+ - chris@ozmm.org
44
+ - abdulrahman@advany.com
45
+ - starlingmq@groups.google.com
46
+ executables:
47
+ - starling
48
+ - starling_top
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - README.rdoc
53
+ - CHANGELOG
54
+ - LICENSE
55
+ files:
56
+ - bin/starling
57
+ - bin/starling_top
58
+ - CHANGELOG
59
+ - etc/sample-config.yml
60
+ - etc/starling.redhat
61
+ - etc/starling.ubuntu
62
+ - lib/starling/handler.rb
63
+ - lib/starling/persistent_queue.rb
64
+ - lib/starling/queue_collection.rb
65
+ - lib/starling/server.rb
66
+ - lib/starling/server_runner.rb
67
+ - lib/starling.rb
68
+ - LICENSE
69
+ - Rakefile
70
+ - README.rdoc
71
+ - spec/starling_server_spec.rb
72
+ has_rdoc: true
73
+ homepage: http://github.com/starling/starling/
74
+ post_install_message:
75
+ rdoc_options:
76
+ - --quiet
77
+ - --title
78
+ - starling documentation
79
+ - --opname
80
+ - index.html
81
+ - --line-numbers
82
+ - --main
83
+ - README.rdoc
84
+ - --inline-source
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: "0"
92
+ version:
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "0"
98
+ version:
99
+ requirements: []
100
+
101
+ rubyforge_project:
102
+ rubygems_version: 1.2.0
103
+ signing_key:
104
+ specification_version: 2
105
+ summary: Starling is a lightweight, transactional, distributed queue server
106
+ test_files: []
107
+