beaneater 0.1.0
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/.gitignore +17 -0
- data/.yardopts +8 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +399 -0
- data/REF +23 -0
- data/Rakefile +23 -0
- data/TODO +2 -0
- data/beaneater.gemspec +24 -0
- data/examples/demo.rb +96 -0
- data/lib/beaneater.rb +10 -0
- data/lib/beaneater/connection.rb +110 -0
- data/lib/beaneater/errors.rb +73 -0
- data/lib/beaneater/job.rb +2 -0
- data/lib/beaneater/job/collection.rb +91 -0
- data/lib/beaneater/job/record.rb +174 -0
- data/lib/beaneater/pool.rb +141 -0
- data/lib/beaneater/pool_command.rb +71 -0
- data/lib/beaneater/stats.rb +55 -0
- data/lib/beaneater/stats/fast_struct.rb +96 -0
- data/lib/beaneater/stats/stat_struct.rb +39 -0
- data/lib/beaneater/tube.rb +2 -0
- data/lib/beaneater/tube/collection.rb +134 -0
- data/lib/beaneater/tube/record.rb +158 -0
- data/lib/beaneater/version.rb +4 -0
- data/test/beaneater_test.rb +115 -0
- data/test/connection_test.rb +64 -0
- data/test/errors_test.rb +26 -0
- data/test/job_test.rb +213 -0
- data/test/jobs_test.rb +107 -0
- data/test/pool_command_test.rb +68 -0
- data/test/pool_test.rb +154 -0
- data/test/stat_struct_test.rb +41 -0
- data/test/stats_test.rb +42 -0
- data/test/test_helper.rb +21 -0
- data/test/tube_test.rb +164 -0
- data/test/tubes_test.rb +153 -0
- metadata +181 -0
data/test/pool_test.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# test/connection_test.rb
|
2
|
+
|
3
|
+
require File.expand_path('../test_helper', __FILE__)
|
4
|
+
|
5
|
+
describe Beaneater::Pool do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@hosts = ['localhost', 'localhost']
|
9
|
+
@bp = Beaneater::Pool.new(@hosts)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'for #new' do
|
13
|
+
|
14
|
+
describe "for multiple connection" do
|
15
|
+
before do
|
16
|
+
@host_string_port = 'localhost:11301'
|
17
|
+
@host_num_port = '127.0.0.1:11302'
|
18
|
+
@host_string = 'host.local'
|
19
|
+
@host_num = '1.1.1.1:11303'
|
20
|
+
@hosts = [@host_string_port, @host_num_port, @host_string, @host_num]
|
21
|
+
|
22
|
+
Net::Telnet.expects(:new).with('Host' => 'localhost', "Port" => 11301, "Prompt" => /\n/).once
|
23
|
+
Net::Telnet.expects(:new).with('Host' => '127.0.0.1', "Port" => 11302, "Prompt" => /\n/).once
|
24
|
+
Net::Telnet.expects(:new).with('Host' => 'host.local', "Port" => 11300, "Prompt" => /\n/).once
|
25
|
+
Net::Telnet.expects(:new).with('Host' => '1.1.1.1', "Port" => 11303, "Prompt" => /\n/).once
|
26
|
+
|
27
|
+
@bp = Beaneater::Pool.new(@hosts)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should init 4 connections" do
|
31
|
+
assert_equal 4, @bp.connections.size
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "for invalid connection in setup" do
|
36
|
+
it "should raise NotConnected" do
|
37
|
+
assert_raises(Beaneater::NotConnected) { Beaneater::Pool.new('localhost:5679') }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "for clearing watch list" do
|
42
|
+
it "should clear connections of tube watches" do
|
43
|
+
@bp.tubes.watch!('foo', 'bar')
|
44
|
+
assert_equal ['foo', 'bar'].sort, @bp.tubes.watched.map(&:name).sort
|
45
|
+
@bp2 = Beaneater::Pool.new(@hosts)
|
46
|
+
assert_equal ['default'], @bp2.tubes.watched.map(&:name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "with ENV variable set" do
|
51
|
+
before do
|
52
|
+
ENV['BEANSTALKD_URL'] = '0.0.0.0:11300,127.0.0.1:11300'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should create 1 connection" do
|
56
|
+
bp = Beaneater::Pool.new
|
57
|
+
bc = bp.connections.first
|
58
|
+
bc2 = bp.connections.last
|
59
|
+
|
60
|
+
assert_equal 2, bp.connections.size
|
61
|
+
assert_equal '0.0.0.0', bc.host
|
62
|
+
assert_equal 11300, bc.port
|
63
|
+
|
64
|
+
assert_equal '127.0.0.1', bc2.host
|
65
|
+
assert_equal 11300, bc2.port
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end # new
|
69
|
+
|
70
|
+
describe 'for #transmit_to_all' do
|
71
|
+
it "should return yaml loaded response" do
|
72
|
+
res = @bp.transmit_to_all 'stats'
|
73
|
+
assert_equal 2, res.size
|
74
|
+
refute_nil res.first[:body]['current-connections']
|
75
|
+
end
|
76
|
+
end # transmit_to_all
|
77
|
+
|
78
|
+
describe 'for #transmit_to_rand' do
|
79
|
+
it "should return yaml loaded response" do
|
80
|
+
res = @bp.transmit_to_rand 'stats'
|
81
|
+
refute_nil res[:body]['current-connections']
|
82
|
+
assert_equal 'OK', res[:status]
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should return id" do
|
86
|
+
Net::Telnet.any_instance.expects(:cmd).with(has_entries('String' => 'foo')).returns('INSERTED 254')
|
87
|
+
res = @bp.transmit_to_rand 'foo'
|
88
|
+
assert_equal '254', res[:id]
|
89
|
+
assert_equal 'INSERTED', res[:status]
|
90
|
+
end
|
91
|
+
end # transmit_to_rand
|
92
|
+
|
93
|
+
describe 'for #transmit_until_res' do
|
94
|
+
before do
|
95
|
+
Beaneater::Connection.any_instance.expects(:transmit).with('foo', {}).twice.
|
96
|
+
returns({:status => "FAILED", :body => 'x'}).then.
|
97
|
+
returns({:status => "OK", :body => 'y'}).then.returns({:status => "OK", :body => 'z'})
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should returns first matching status" do
|
101
|
+
assert_equal 'y', @bp.transmit_until_res('foo', :status => 'OK')[:body]
|
102
|
+
end
|
103
|
+
end # transmit_until_res
|
104
|
+
|
105
|
+
describe 'for #stats' do
|
106
|
+
it("should return stats object"){ assert_kind_of Beaneater::Stats, @bp.stats }
|
107
|
+
end # stats
|
108
|
+
|
109
|
+
describe 'for #tubes' do
|
110
|
+
it("should return Tubes object"){ assert_kind_of Beaneater::Tubes, @bp.tubes }
|
111
|
+
end # tubes
|
112
|
+
|
113
|
+
describe "for #safe_transmit" do
|
114
|
+
it "should retry 3 times for temporary failed connection" do
|
115
|
+
Net::Telnet.any_instance.expects(:cmd).raises(EOFError).then.
|
116
|
+
raises(Errno::ECONNRESET).then.returns('INSERTED 254').times(3)
|
117
|
+
res = @bp.transmit_to_rand 'foo'
|
118
|
+
assert_equal '254', res[:id]
|
119
|
+
assert_equal 'INSERTED', res[:status]
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should retry on fail 3 times for dead connection" do
|
123
|
+
Net::Telnet.any_instance.expects(:cmd).raises(EOFError).times(3)
|
124
|
+
assert_raises(Beaneater::NotConnected) { @bp.transmit_to_rand 'foo' }
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should raise proper exception for invalid status NOT_FOUND' do
|
128
|
+
Net::Telnet.any_instance.expects(:cmd).returns('NOT_FOUND')
|
129
|
+
assert_raises(Beaneater::NotFoundError) { @bp.transmit_to_rand 'foo' }
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should raise proper exception for invalid status BAD_FORMAT' do
|
133
|
+
Net::Telnet.any_instance.expects(:cmd).returns('BAD_FORMAT')
|
134
|
+
assert_raises(Beaneater::BadFormatError) { @bp.transmit_to_rand 'foo' }
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should raise proper exception for invalid status DEADLINE_SOON' do
|
138
|
+
Net::Telnet.any_instance.expects(:cmd).returns('DEADLINE_SOON')
|
139
|
+
assert_raises(Beaneater::DeadlineSoonError) { @bp.transmit_to_rand 'foo' }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "for #close" do
|
144
|
+
it "should support closing the pool" do
|
145
|
+
connection = @bp.connections.first
|
146
|
+
assert_equal 2, @bp.connections.size
|
147
|
+
assert_kind_of Beaneater::Connection, connection
|
148
|
+
assert_kind_of Net::Telnet, connection.telnet_connection
|
149
|
+
@bp.close
|
150
|
+
assert_equal 0, @bp.connections.size
|
151
|
+
assert_nil connection.telnet_connection
|
152
|
+
end
|
153
|
+
end # close
|
154
|
+
end # Beaneater::Pool
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# test/connection_test.rb
|
2
|
+
|
3
|
+
require File.expand_path('../test_helper', __FILE__)
|
4
|
+
|
5
|
+
describe Beaneater::StatStruct do
|
6
|
+
before do
|
7
|
+
@hash = { :foo => "bar", :bar => "baz", :baz => "foo", :"under-score" => "demo" }
|
8
|
+
@struct = Beaneater::StatStruct.from_hash(@hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "for #from_hash" do
|
12
|
+
it "should have 4 keys" do
|
13
|
+
assert_equal 'bar', @struct.foo
|
14
|
+
assert_equal 'baz', @struct.bar
|
15
|
+
assert_equal 'foo', @struct.baz
|
16
|
+
assert_equal 'demo', @struct.under_score
|
17
|
+
end
|
18
|
+
end # from_hash
|
19
|
+
|
20
|
+
describe "for [] access" do
|
21
|
+
it "should have hash lookup" do
|
22
|
+
assert_equal 'bar', @struct['foo']
|
23
|
+
assert_equal 'baz', @struct['bar']
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should convert keys to string" do
|
27
|
+
assert_equal 'foo', @struct[:baz]
|
28
|
+
assert_equal 'demo', @struct[:"under_score"]
|
29
|
+
end
|
30
|
+
end # []
|
31
|
+
|
32
|
+
describe "for #keys" do
|
33
|
+
it "should return 4 keys" do
|
34
|
+
assert_equal 4, @struct.keys.size
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return expected keys" do
|
38
|
+
assert_equal ['foo', 'bar', 'baz', 'under_score'], @struct.keys
|
39
|
+
end
|
40
|
+
end # keys
|
41
|
+
end
|
data/test/stats_test.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# test/connection_test.rb
|
2
|
+
|
3
|
+
require File.expand_path('../test_helper', __FILE__)
|
4
|
+
|
5
|
+
describe Beaneater::Stats do
|
6
|
+
before do
|
7
|
+
@pool = stub(:transmit_to_all => [{ :body => { 'uptime' => 1, 'cmd-use' => 2 }}, {:body => { 'uptime' => 3,'cmd-use' => 4 }}])
|
8
|
+
@stats = Beaneater::Stats.new(@pool)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'for #[]' do
|
12
|
+
it "should return stats by key" do
|
13
|
+
assert_equal 4, @stats[:uptime]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return stats by underscore key" do
|
17
|
+
assert_equal 6, @stats[:'cmd_use']
|
18
|
+
end
|
19
|
+
end # []
|
20
|
+
|
21
|
+
describe 'for #keys' do
|
22
|
+
it "should return list of keys" do
|
23
|
+
assert_equal 2, @stats.keys.size
|
24
|
+
assert @stats.keys.include?('uptime'), "Expected keys to include 'uptime'"
|
25
|
+
assert @stats.keys.include?('cmd_use'), "Expected keys to include 'cmd-use'"
|
26
|
+
end
|
27
|
+
end # keys
|
28
|
+
|
29
|
+
describe 'for #method_missing' do
|
30
|
+
it "should return stats by key" do
|
31
|
+
assert_equal 4, @stats.uptime
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return stats by underscore key" do
|
35
|
+
assert_equal 6, @stats.cmd_use
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should raise NoMethodError" do
|
39
|
+
assert_raises(NoMethodError) { @stats.cmd }
|
40
|
+
end
|
41
|
+
end # method_missing
|
42
|
+
end # Beaneater::Stats
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
ENV["TEST"] = 'true'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
$:.unshift File.expand_path("../../lib")
|
5
|
+
require 'beaneater'
|
6
|
+
require 'fakeweb'
|
7
|
+
require 'mocha'
|
8
|
+
|
9
|
+
FakeWeb.allow_net_connect = false
|
10
|
+
|
11
|
+
class MiniTest::Unit::TestCase
|
12
|
+
|
13
|
+
# Cleans up all jobs from tubes
|
14
|
+
# cleanup_tubes!(['foo'], @bp)
|
15
|
+
def cleanup_tubes!(tubes, bp=nil)
|
16
|
+
bp ||= @pool
|
17
|
+
tubes.each do |name|
|
18
|
+
bp.tubes.find(name).clear
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/test/tube_test.rb
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
# test/connection_test.rb
|
2
|
+
|
3
|
+
require File.expand_path('../test_helper', __FILE__)
|
4
|
+
|
5
|
+
describe Beaneater::Tube do
|
6
|
+
before do
|
7
|
+
@pool = Beaneater::Pool.new(['localhost'])
|
8
|
+
@tube = Beaneater::Tube.new(@pool, 'baz')
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "for #put" do
|
12
|
+
before do
|
13
|
+
@time = Time.now.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should insert a job" do
|
17
|
+
@tube.put "bar put #{@time}"
|
18
|
+
assert_equal "bar put #{@time}", @tube.peek(:ready).body
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should insert a delayed job" do
|
22
|
+
@tube.put "delayed put #{@time}", :delay => 1
|
23
|
+
assert_equal "delayed put #{@time}", @tube.peek(:delayed).body
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should try to put 2 times before put successfully" do
|
27
|
+
Beaneater::Connection.any_instance.expects(:transmit).once.with(includes('use baz'), {})
|
28
|
+
Beaneater::Connection.any_instance.expects(:transmit).times(2).with(includes("bar put #{@time}"), {}).
|
29
|
+
raises(Beaneater::DrainingError.new(nil, nil)).then.returns('foo')
|
30
|
+
assert_equal 'foo', @tube.put("bar put #{@time}")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should try to put 3 times before to raise" do
|
34
|
+
Beaneater::Connection.any_instance.expects(:transmit).once.with(includes('use baz'), {})
|
35
|
+
Beaneater::Connection.any_instance.expects(:transmit).with(includes("bar put #{@time}"), {}).
|
36
|
+
times(3).raises(Beaneater::DrainingError.new(nil, nil))
|
37
|
+
assert_raises(Beaneater::DrainingError) { @tube.put "bar put #{@time}" }
|
38
|
+
end
|
39
|
+
|
40
|
+
it "supports JSON" do
|
41
|
+
json = "{ 'foo' : 'bar' }"
|
42
|
+
@tube.put(json)
|
43
|
+
assert_equal 'bar', @tube.peek(:ready).body['foo']
|
44
|
+
end
|
45
|
+
|
46
|
+
after do
|
47
|
+
Beaneater::Connection.any_instance.unstub(:transmit)
|
48
|
+
end
|
49
|
+
end # put
|
50
|
+
|
51
|
+
describe "for #peek" do
|
52
|
+
before do
|
53
|
+
@time = Time.now.to_i
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should peek delayed" do
|
57
|
+
@tube.put "foo delay #{@time}", :delay => 1
|
58
|
+
assert_equal "foo delay #{@time}", @tube.peek(:delayed).body
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should peek ready" do
|
62
|
+
@tube.put "foo ready #{@time}", :delay => 0
|
63
|
+
assert_equal "foo ready #{@time}", @tube.peek(:ready).body
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should peek buried" do
|
67
|
+
@tube.put "foo buried #{@time}"
|
68
|
+
@tube.reserve.bury
|
69
|
+
|
70
|
+
assert_equal "foo buried #{@time}", @tube.peek(:buried).body
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should return nil for empty peek" do
|
74
|
+
assert_nil @tube.peek(:buried)
|
75
|
+
end
|
76
|
+
end # peek
|
77
|
+
|
78
|
+
describe "for #reserve" do
|
79
|
+
before do
|
80
|
+
@time = Time.now.to_i
|
81
|
+
@tube.put "foo reserve #{@time}"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should reserve job" do
|
85
|
+
assert_equal "foo reserve #{@time}", @tube.reserve.body
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should reserve job with block" do
|
89
|
+
job = nil
|
90
|
+
@tube.reserve { |j| job = j; job.delete }
|
91
|
+
assert_equal "foo reserve #{@time}", job.body
|
92
|
+
end
|
93
|
+
end # reserve
|
94
|
+
|
95
|
+
describe "for #pause" do
|
96
|
+
before do
|
97
|
+
@time = Time.now.to_i
|
98
|
+
@tube = Beaneater::Tube.new(@pool, 'bam')
|
99
|
+
@tube.put "foo pause #{@time}"
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should allow tube pause" do
|
103
|
+
assert_equal 0, @tube.stats.pause
|
104
|
+
@tube.pause(1)
|
105
|
+
assert_equal 1, @tube.stats.pause
|
106
|
+
end
|
107
|
+
end # pause
|
108
|
+
|
109
|
+
describe "for #stats" do
|
110
|
+
before do
|
111
|
+
@time = Time.now.to_i
|
112
|
+
@tube.put "foo stats #{@time}"
|
113
|
+
@stats = @tube.stats
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should return total number of jobs in tube" do
|
117
|
+
assert_equal 1, @stats['current_jobs_ready']
|
118
|
+
assert_equal 0, @stats.current_jobs_delayed
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should raise error for empty tube" do
|
122
|
+
assert_raises(Beaneater::NotFoundError) { @pool.tubes.find('fake_tube').stats }
|
123
|
+
end
|
124
|
+
end # stats
|
125
|
+
|
126
|
+
describe "for #kick" do
|
127
|
+
before do
|
128
|
+
@time, @time2 = 2.times.map { Time.now.to_i }
|
129
|
+
@tube.put "kick #{@time}"
|
130
|
+
@tube.put "kick #{@time2}"
|
131
|
+
|
132
|
+
2.times.map { @tube.reserve.bury }
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should kick 2 buried jobs" do
|
136
|
+
assert_equal 2, @tube.stats.current_jobs_buried
|
137
|
+
@tube.kick(2)
|
138
|
+
assert_equal 0, @tube.stats.current_jobs_buried
|
139
|
+
assert_equal 2, @tube.stats.current_jobs_ready
|
140
|
+
end
|
141
|
+
end # kick
|
142
|
+
|
143
|
+
describe "for #clear" do
|
144
|
+
@time = Time.now.to_i
|
145
|
+
before do
|
146
|
+
2.times { |i| @tube.put "to clear success #{i} #{@time}" }
|
147
|
+
2.times { |i| @tube.put "to clear delayed #{i} #{@time}", :delay => 5 }
|
148
|
+
2.times { |i| @tube.put "to clear bury #{i} #{@time}", :pri => 1 }
|
149
|
+
@tube.reserve.bury while @tube.peek(:ready).stats['pri'] == 1
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should clear all jobs in tube" do
|
153
|
+
tube_counts = lambda { %w(ready buried delayed).map { |s| @tube.stats["current_jobs_#{s}"] } }
|
154
|
+
assert_equal [2, 2, 2], tube_counts.call
|
155
|
+
@tube.clear
|
156
|
+
stats = @tube.stats
|
157
|
+
assert_equal [0, 0, 0], tube_counts.call
|
158
|
+
end
|
159
|
+
end # clear
|
160
|
+
|
161
|
+
after do
|
162
|
+
cleanup_tubes!(['baz'])
|
163
|
+
end
|
164
|
+
end # Beaneater::Tubes
|
data/test/tubes_test.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
# test/connection_test.rb
|
2
|
+
|
3
|
+
require File.expand_path('../test_helper', __FILE__)
|
4
|
+
|
5
|
+
describe Beaneater::Tubes do
|
6
|
+
describe "for #find" do
|
7
|
+
before do
|
8
|
+
@pool = stub
|
9
|
+
@tubes = Beaneater::Tubes.new(@pool)
|
10
|
+
end
|
11
|
+
|
12
|
+
it("should return Tube obj") { assert_kind_of Beaneater::Tube, @tubes.find(:foo) }
|
13
|
+
it("should return Tube name") { assert_equal "foo", @tubes.find(:foo).name }
|
14
|
+
it("should support hash syntax") { assert_equal "bar", @tubes["bar"].name }
|
15
|
+
end # find
|
16
|
+
|
17
|
+
describe "for #use" do
|
18
|
+
before do
|
19
|
+
@pool = Beaneater::Pool.new(['localhost'])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should switch to used tube for valid name" do
|
23
|
+
tube = Beaneater::Tube.new(@pool, 'some_name')
|
24
|
+
@pool.tubes.use('some_name')
|
25
|
+
assert_equal 'some_name', @pool.tubes.used.name
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should raise for invalid tube name" do
|
29
|
+
assert_raises(Beaneater::InvalidTubeName) { @pool.tubes.use('; ') }
|
30
|
+
end
|
31
|
+
end # use
|
32
|
+
|
33
|
+
describe "for #watch & #watched" do
|
34
|
+
before do
|
35
|
+
@pool = Beaneater::Pool.new(['localhost'])
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should watch specified tubes' do
|
39
|
+
@pool.tubes.watch('foo')
|
40
|
+
@pool.tubes.watch('bar')
|
41
|
+
assert_equal ['default', 'foo', 'bar'].sort, @pool.tubes.watched.map(&:name).sort
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should raise invalid name for bad tube' do
|
45
|
+
assert_raises(Beaneater::InvalidTubeName) { @pool.tubes.watch('; ') }
|
46
|
+
end
|
47
|
+
end # watch! & watched
|
48
|
+
|
49
|
+
describe "for #all" do
|
50
|
+
before do
|
51
|
+
@pool = Beaneater::Pool.new(['localhost'])
|
52
|
+
@pool.tubes.find('foo').put 'bar'
|
53
|
+
@pool.tubes.find('bar').put 'foo'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should retrieve all tubes' do
|
57
|
+
['default', 'foo', 'bar'].each do |t|
|
58
|
+
assert @pool.tubes.all.map(&:name).include?(t)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end # all
|
62
|
+
|
63
|
+
describe "for #used" do
|
64
|
+
before do
|
65
|
+
@pool = Beaneater::Pool.new(['localhost'])
|
66
|
+
@pool.tubes.find('foo').put 'bar'
|
67
|
+
@pool.tubes.find('bar').put 'foo'
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should retrieve used tube' do
|
71
|
+
assert_equal'bar', @pool.tubes.used.name
|
72
|
+
end
|
73
|
+
end # used
|
74
|
+
|
75
|
+
describe "for #watch!" do
|
76
|
+
before do
|
77
|
+
@pool = Beaneater::Pool.new(['localhost'])
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should watch specified tubes' do
|
81
|
+
@pool.tubes.watch!(:foo)
|
82
|
+
@pool.tubes.watch!('bar')
|
83
|
+
assert_equal ['bar'].sort, @pool.tubes.watched.map(&:name).sort
|
84
|
+
end
|
85
|
+
end # watch!
|
86
|
+
|
87
|
+
describe "for #ignore" do
|
88
|
+
before do
|
89
|
+
@pool = Beaneater::Pool.new(['localhost'])
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should ignore specified tubes' do
|
93
|
+
@pool.tubes.watch('foo')
|
94
|
+
@pool.tubes.watch('bar')
|
95
|
+
@pool.tubes.ignore('foo')
|
96
|
+
assert_equal ['default', 'bar'].sort, @pool.tubes.watched.map(&:name).sort
|
97
|
+
end
|
98
|
+
end # ignore
|
99
|
+
|
100
|
+
describe "for #reserve" do
|
101
|
+
before do
|
102
|
+
@pool = Beaneater::Pool.new(['localhost'])
|
103
|
+
@tube = @pool.tubes.find 'tube'
|
104
|
+
@time = Time.now.to_i
|
105
|
+
@tube.put "foo reserve #{@time}"
|
106
|
+
end
|
107
|
+
|
108
|
+
it("should reserve job") do
|
109
|
+
@pool.tubes.watch 'tube'
|
110
|
+
job = @pool.tubes.reserve
|
111
|
+
assert_equal "foo reserve #{@time}", job.body
|
112
|
+
job.delete
|
113
|
+
end
|
114
|
+
|
115
|
+
it("should reserve job with block") do
|
116
|
+
@pool.tubes.watch 'tube'
|
117
|
+
job = nil
|
118
|
+
@pool.tubes.reserve { |j| job = j; job.delete }
|
119
|
+
assert_equal "foo reserve #{@time}", job.body
|
120
|
+
end
|
121
|
+
|
122
|
+
it("should reserve job with block and timeout") do
|
123
|
+
@pool.tubes.watch 'tube'
|
124
|
+
job = nil
|
125
|
+
res = @pool.tubes.reserve(0) { |j| job = j; job.delete }
|
126
|
+
assert_equal "foo reserve #{@time}", job.body
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should raise TimedOutError with timeout" do
|
130
|
+
@pool.tubes.watch 'tube'
|
131
|
+
@pool.tubes.reserve(0) { |j| job = j; job.delete }
|
132
|
+
assert_raises(Beaneater::TimedOutError) { @pool.tubes.reserve(0) }
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should raise TimedOutError no delete, with timeout" do
|
136
|
+
@pool.tubes.watch 'tube'
|
137
|
+
@pool.tubes.reserve(0)
|
138
|
+
assert_raises(Beaneater::TimedOutError) { @pool.tubes.reserve(0) }
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should raise DeadlineSoonError with ttr 1" do
|
142
|
+
@tube.reserve.delete
|
143
|
+
@tube.put "foo reserve #{@time}", :ttr => 1
|
144
|
+
@pool.tubes.watch 'tube'
|
145
|
+
@pool.tubes.reserve
|
146
|
+
assert_raises(Beaneater::DeadlineSoonError) { @pool.tubes.reserve(0) }
|
147
|
+
end
|
148
|
+
|
149
|
+
after do
|
150
|
+
cleanup_tubes!(['foo', 'tube'])
|
151
|
+
end
|
152
|
+
end # reserve
|
153
|
+
end # Beaneater::Tubes
|