timberline 0.1.2
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 +4 -0
- data/Gemfile +4 -0
- data/README.markdown +214 -0
- data/Rakefile +9 -0
- data/bin/timberline +37 -0
- data/lib/timberline/config.rb +45 -0
- data/lib/timberline/envelope.rb +47 -0
- data/lib/timberline/queue.rb +42 -0
- data/lib/timberline/queue_manager.rb +84 -0
- data/lib/timberline/version.rb +3 -0
- data/lib/timberline.rb +65 -0
- data/test/fake_rails/config/timberline.yaml +6 -0
- data/test/partial_minispec.rb +229 -0
- data/test/test_config.yaml +6 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/test_config.rb +115 -0
- data/test/unit/test_envelope.rb +67 -0
- data/test/unit/test_queue.rb +75 -0
- data/test/unit/test_queue_manager.rb +154 -0
- data/test/unit/test_timberline.rb +65 -0
- data/timberline.gemspec +28 -0
- metadata +124 -0
@@ -0,0 +1,229 @@
|
|
1
|
+
## This is code stolen from the definition file for Minitest::Spec. We really
|
2
|
+
# like everything about Minitest::Spec except for the expectations part, so we
|
3
|
+
# are stealing it and using it here. Shamelessly.
|
4
|
+
#
|
5
|
+
# This code may go out of date in future versions of Ruby, so we should keep an
|
6
|
+
# eye on that. But that's better than reinventing the wheel.
|
7
|
+
|
8
|
+
module Kernel # :nodoc:
|
9
|
+
##
|
10
|
+
# Describe a series of expectations for a given target +desc+.
|
11
|
+
#
|
12
|
+
# TODO: find good tutorial url.
|
13
|
+
#
|
14
|
+
# Defines a test class subclassing from either MiniTest::Spec or
|
15
|
+
# from the surrounding describe's class. The surrounding class may
|
16
|
+
# subclass MiniTest::Spec manually in order to easily share code:
|
17
|
+
#
|
18
|
+
# class MySpec < MiniTest::Spec
|
19
|
+
# # ... shared code ...
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# class TestStuff < MySpec
|
23
|
+
# it "does stuff" do
|
24
|
+
# # shared code available here
|
25
|
+
# end
|
26
|
+
# describe "inner stuff" do
|
27
|
+
# it "still does stuff" do
|
28
|
+
# # ...and here
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
|
33
|
+
def describe desc, additional_desc = nil, &block # :doc:
|
34
|
+
stack = MiniTest::Spec.describe_stack
|
35
|
+
name = [stack.last, desc, additional_desc].compact.join("::")
|
36
|
+
sclas = stack.last || if Class === self && self < MiniTest::Spec then
|
37
|
+
self
|
38
|
+
else
|
39
|
+
MiniTest::Spec.spec_type desc
|
40
|
+
end
|
41
|
+
|
42
|
+
cls = sclas.create name, desc
|
43
|
+
|
44
|
+
stack.push cls
|
45
|
+
cls.class_eval(&block)
|
46
|
+
stack.pop
|
47
|
+
cls
|
48
|
+
end
|
49
|
+
private :describe
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# MiniTest::Spec -- The faster, better, less-magical spec framework!
|
54
|
+
#
|
55
|
+
# For a list of expectations, see MiniTest::Expectations.
|
56
|
+
|
57
|
+
class MiniTest::Spec < MiniTest::Unit::TestCase
|
58
|
+
##
|
59
|
+
# Contains pairs of matchers and Spec classes to be used to
|
60
|
+
# calculate the superclass of a top-level describe. This allows for
|
61
|
+
# automatically customizable spec types.
|
62
|
+
#
|
63
|
+
# See: register_spec_type and spec_type
|
64
|
+
|
65
|
+
TYPES = [[//, MiniTest::Spec]]
|
66
|
+
|
67
|
+
##
|
68
|
+
# Register a new type of spec that matches the spec's description.
|
69
|
+
# This method can take either a Regexp and a spec class or a spec
|
70
|
+
# class and a block that takes the description and returns true if
|
71
|
+
# it matches.
|
72
|
+
#
|
73
|
+
# Eg:
|
74
|
+
#
|
75
|
+
# register_spec_type(/Controller$/, MiniTest::Spec::Rails)
|
76
|
+
#
|
77
|
+
# or:
|
78
|
+
#
|
79
|
+
# register_spec_type(MiniTest::Spec::RailsModel) do |desc|
|
80
|
+
# desc.superclass == ActiveRecord::Base
|
81
|
+
# end
|
82
|
+
|
83
|
+
def self.register_spec_type(*args, &block)
|
84
|
+
if block then
|
85
|
+
matcher, klass = block, args.first
|
86
|
+
else
|
87
|
+
matcher, klass = *args
|
88
|
+
end
|
89
|
+
TYPES.unshift [matcher, klass]
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Figure out the spec class to use based on a spec's description. Eg:
|
94
|
+
#
|
95
|
+
# spec_type("BlahController") # => MiniTest::Spec::Rails
|
96
|
+
|
97
|
+
def self.spec_type desc
|
98
|
+
TYPES.find { |matcher, klass|
|
99
|
+
if matcher.respond_to? :call then
|
100
|
+
matcher.call desc
|
101
|
+
else
|
102
|
+
matcher === desc.to_s
|
103
|
+
end
|
104
|
+
}.last
|
105
|
+
end
|
106
|
+
|
107
|
+
@@describe_stack = []
|
108
|
+
def self.describe_stack # :nodoc:
|
109
|
+
@@describe_stack
|
110
|
+
end
|
111
|
+
|
112
|
+
##
|
113
|
+
# Returns the children of this spec.
|
114
|
+
|
115
|
+
def self.children
|
116
|
+
@children ||= []
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.nuke_test_methods! # :nodoc:
|
120
|
+
self.public_instance_methods.grep(/^test_/).each do |name|
|
121
|
+
self.send :undef_method, name
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Define a 'before' action. Inherits the way normal methods should.
|
127
|
+
#
|
128
|
+
# NOTE: +type+ is ignored and is only there to make porting easier.
|
129
|
+
#
|
130
|
+
# Equivalent to MiniTest::Unit::TestCase#setup.
|
131
|
+
|
132
|
+
def self.before type = :each, &block
|
133
|
+
raise "unsupported before type: #{type}" unless type == :each
|
134
|
+
|
135
|
+
add_setup_hook {|tc| tc.instance_eval(&block) }
|
136
|
+
end
|
137
|
+
|
138
|
+
##
|
139
|
+
# Define an 'after' action. Inherits the way normal methods should.
|
140
|
+
#
|
141
|
+
# NOTE: +type+ is ignored and is only there to make porting easier.
|
142
|
+
#
|
143
|
+
# Equivalent to MiniTest::Unit::TestCase#teardown.
|
144
|
+
|
145
|
+
def self.after type = :each, &block
|
146
|
+
raise "unsupported after type: #{type}" unless type == :each
|
147
|
+
|
148
|
+
add_teardown_hook {|tc| tc.instance_eval(&block) }
|
149
|
+
end
|
150
|
+
|
151
|
+
##
|
152
|
+
# Define an expectation with name +desc+. Name gets morphed to a
|
153
|
+
# proper test method name. For some freakish reason, people who
|
154
|
+
# write specs don't like class inheritence, so this goes way out of
|
155
|
+
# its way to make sure that expectations aren't inherited.
|
156
|
+
#
|
157
|
+
# This is also aliased to #specify and doesn't require a +desc+ arg.
|
158
|
+
#
|
159
|
+
# Hint: If you _do_ want inheritence, use minitest/unit. You can mix
|
160
|
+
# and match between assertions and expectations as much as you want.
|
161
|
+
|
162
|
+
def self.it desc = "anonymous", &block
|
163
|
+
block ||= proc { skip "(no tests defined)" }
|
164
|
+
|
165
|
+
@specs ||= 0
|
166
|
+
@specs += 1
|
167
|
+
|
168
|
+
name = "test_%04d_%s" % [ @specs, desc.gsub(/\W+/, '_').downcase ]
|
169
|
+
|
170
|
+
define_method name, &block
|
171
|
+
|
172
|
+
self.children.each do |mod|
|
173
|
+
mod.send :undef_method, name if mod.public_method_defined? name
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# Essentially, define an accessor for +name+ with +block+.
|
179
|
+
#
|
180
|
+
# Why use let instead of def? I honestly don't know.
|
181
|
+
|
182
|
+
def self.let name, &block
|
183
|
+
define_method name do
|
184
|
+
@_memoized ||= {}
|
185
|
+
@_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) }
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
##
|
190
|
+
# Another lazy man's accessor generator. Made even more lazy by
|
191
|
+
# setting the name for you to +subject+.
|
192
|
+
|
193
|
+
def self.subject &block
|
194
|
+
let :subject, &block
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.create name, desc # :nodoc:
|
198
|
+
cls = Class.new(self) do
|
199
|
+
@name = name
|
200
|
+
@desc = desc
|
201
|
+
|
202
|
+
nuke_test_methods!
|
203
|
+
end
|
204
|
+
|
205
|
+
children << cls
|
206
|
+
|
207
|
+
cls
|
208
|
+
end
|
209
|
+
|
210
|
+
def self.to_s # :nodoc:
|
211
|
+
defined?(@name) ? @name : super
|
212
|
+
end
|
213
|
+
|
214
|
+
# :stopdoc:
|
215
|
+
def after_setup
|
216
|
+
run_setup_hooks
|
217
|
+
end
|
218
|
+
|
219
|
+
def before_teardown
|
220
|
+
run_teardown_hooks
|
221
|
+
end
|
222
|
+
|
223
|
+
class << self
|
224
|
+
attr_reader :desc
|
225
|
+
alias :specify :it
|
226
|
+
alias :name :to_s
|
227
|
+
end
|
228
|
+
# :startdoc:
|
229
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require 'partial_minispec'
|
4
|
+
|
5
|
+
# include the gem
|
6
|
+
require 'timberline'
|
7
|
+
|
8
|
+
# Use database 15 for testing, so we don't risk overwriting any data that's
|
9
|
+
# actually useful
|
10
|
+
def clear_test_db
|
11
|
+
Timberline.config do |c|
|
12
|
+
c.database = 15
|
13
|
+
end
|
14
|
+
Timberline.redis.flushdb
|
15
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Timberline::Config do
|
4
|
+
describe "Without any preset YAML configs" do
|
5
|
+
before do
|
6
|
+
@config = Timberline::Config.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "builds a proper config hash for Redis" do
|
10
|
+
@logger = Logger.new STDERR
|
11
|
+
|
12
|
+
@config.host = "localhost"
|
13
|
+
@config.port = 12345
|
14
|
+
@config.timeout = 10
|
15
|
+
@config.password = "foo"
|
16
|
+
@config.database = 3
|
17
|
+
@config.logger = @logger
|
18
|
+
|
19
|
+
config = @config.redis_config
|
20
|
+
|
21
|
+
assert_equal "localhost", config[:host]
|
22
|
+
assert_equal 12345, config[:port]
|
23
|
+
assert_equal 10, config[:timeout]
|
24
|
+
assert_equal "foo", config[:password]
|
25
|
+
assert_equal 3, config[:db]
|
26
|
+
assert_equal @logger, config[:logger]
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
it "reads configuration from a YAML config file" do
|
31
|
+
base_dir = File.dirname(File.path(__FILE__))
|
32
|
+
yaml_file = File.join(base_dir, "..", "test_config.yaml")
|
33
|
+
@config.load_from_yaml(yaml_file)
|
34
|
+
assert_equal "localhost", @config.host
|
35
|
+
assert_equal 12345, @config.port
|
36
|
+
assert_equal 10, @config.timeout
|
37
|
+
assert_equal "foo", @config.password
|
38
|
+
assert_equal 3, @config.database
|
39
|
+
assert_equal "treecurve", @config.namespace
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "when in a Rails app without a config file" do
|
44
|
+
before do
|
45
|
+
RAILS_ROOT = File.join(File.dirname(File.path(__FILE__)), "..", "gibberish")
|
46
|
+
@config = Timberline::Config.new
|
47
|
+
end
|
48
|
+
|
49
|
+
after do
|
50
|
+
Object.send(:remove_const, :RAILS_ROOT)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should load successfully without any configs." do
|
54
|
+
["database","host","port","timeout","password","logger","namespace"].each do |setting|
|
55
|
+
assert_equal nil, @config.instance_variable_get("@#{setting}")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "when in a Rails app with a config file" do
|
61
|
+
before do
|
62
|
+
RAILS_ROOT = File.join(File.dirname(File.path(__FILE__)), "..", "fake_rails")
|
63
|
+
@config = Timberline::Config.new
|
64
|
+
end
|
65
|
+
|
66
|
+
after do
|
67
|
+
Object.send(:remove_const, :RAILS_ROOT)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should load the config/timberline.yaml file" do
|
71
|
+
assert_equal "localhost", @config.host
|
72
|
+
assert_equal 12345, @config.port
|
73
|
+
assert_equal 10, @config.timeout
|
74
|
+
assert_equal "foo", @config.password
|
75
|
+
assert_equal 3, @config.database
|
76
|
+
assert_equal "treecurve", @config.namespace
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "when TIMBERLINE_YAML is defined" do
|
81
|
+
before do
|
82
|
+
TIMBERLINE_YAML = File.join(File.dirname(File.path(__FILE__)), "..", "test_config.yaml")
|
83
|
+
@config = Timberline::Config.new
|
84
|
+
end
|
85
|
+
|
86
|
+
after do
|
87
|
+
Object.send(:remove_const, :TIMBERLINE_YAML)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should load the specified yaml file" do
|
91
|
+
assert_equal "localhost", @config.host
|
92
|
+
assert_equal 12345, @config.port
|
93
|
+
assert_equal 10, @config.timeout
|
94
|
+
assert_equal "foo", @config.password
|
95
|
+
assert_equal 3, @config.database
|
96
|
+
assert_equal "treecurve", @config.namespace
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "when TIMBERLINE_YAML is defined, but doesn't exist" do
|
101
|
+
before do
|
102
|
+
TIMBERLINE_YAML = File.join(File.dirname(File.path(__FILE__)), "..", "fake_config.yaml")
|
103
|
+
end
|
104
|
+
|
105
|
+
after do
|
106
|
+
Object.send(:remove_const, :TIMBERLINE_YAML)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should raise an exception" do
|
110
|
+
assert_raises RuntimeError do
|
111
|
+
@config = Timberline::Config.new
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
describe Timberline::Envelope do
|
5
|
+
before do
|
6
|
+
@envelope = Timberline::Envelope.new
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "newly instantiated" do
|
10
|
+
it "raises a MissingContentException when to_s is called because the contents are nil" do
|
11
|
+
assert_raises Timberline::MissingContentException do
|
12
|
+
@envelope.to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has an empty hash for metadata" do
|
17
|
+
assert_equal({}, @envelope.metadata)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "allows for the reading of attributes via method_missing magic" do
|
21
|
+
@envelope.metadata["original_queue"] = "test_queue"
|
22
|
+
assert_equal "test_queue", @envelope.original_queue
|
23
|
+
end
|
24
|
+
|
25
|
+
it "allows for the setting of attributes via method_missing magic" do
|
26
|
+
@envelope.original_queue = "test_queue"
|
27
|
+
assert_equal "test_queue", @envelope.metadata["original_queue"]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "with contents" do
|
32
|
+
before do
|
33
|
+
@envelope.contents = "Test data"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns a JSON string when to_s is called" do
|
37
|
+
json_string = @envelope.to_s
|
38
|
+
json_data = JSON.parse(json_string)
|
39
|
+
assert_equal "Test data", json_data["contents"]
|
40
|
+
end
|
41
|
+
|
42
|
+
it "only includes a 'contents' parameter by default" do
|
43
|
+
json_string = @envelope.to_s
|
44
|
+
json_data = JSON.parse(json_string)
|
45
|
+
assert_equal 1, json_data.keys.size
|
46
|
+
end
|
47
|
+
|
48
|
+
it "also includes metadata, if provided" do
|
49
|
+
time = DateTime.now
|
50
|
+
time_s = DateTime.now.to_s
|
51
|
+
@envelope.first_posted = time
|
52
|
+
@envelope.origin_queue = "test_queue"
|
53
|
+
|
54
|
+
json_string = @envelope.to_s
|
55
|
+
json_data = JSON.parse(json_string)
|
56
|
+
assert_equal "test_queue", json_data["origin_queue"]
|
57
|
+
assert_equal time_s, json_data["first_posted"]
|
58
|
+
end
|
59
|
+
|
60
|
+
it "parses itself back correctly using from_json" do
|
61
|
+
json_string = @envelope.to_s
|
62
|
+
new_envelope = Timberline::Envelope.from_json(json_string)
|
63
|
+
assert_equal @envelope.contents, new_envelope.contents
|
64
|
+
assert_equal @envelope.metadata, new_envelope.metadata
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Timberline::Queue do
|
4
|
+
describe "newly instantiated" do
|
5
|
+
before do
|
6
|
+
clear_test_db
|
7
|
+
@queue = Timberline::Queue.new("test_queue")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "saves the passed-in string as its queue name" do
|
11
|
+
assert_equal "test_queue", @queue.queue_name
|
12
|
+
end
|
13
|
+
|
14
|
+
it "has a length of 0" do
|
15
|
+
assert_equal 0, @queue.length
|
16
|
+
end
|
17
|
+
|
18
|
+
it "has a default read_timeout of 0" do
|
19
|
+
assert_equal 0, @queue.read_timeout
|
20
|
+
end
|
21
|
+
|
22
|
+
it "responds nil to a pop request after the read_timeout occurs" do
|
23
|
+
# Let's set the read_timeout to 1 in order for this test to return
|
24
|
+
@queue.instance_variable_set("@read_timeout", 1)
|
25
|
+
assert_equal nil, @queue.pop
|
26
|
+
end
|
27
|
+
|
28
|
+
it "puts an item on the queue when that item is pushed" do
|
29
|
+
test_item = "Test Queue Item"
|
30
|
+
assert_equal 1, @queue.push(test_item)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "wraps an item in an envelope when that item is pushed" do
|
34
|
+
test_item = "Test Queue Item"
|
35
|
+
assert_equal 1, @queue.push(test_item)
|
36
|
+
data = @queue.pop
|
37
|
+
assert_kind_of Timberline::Envelope, data
|
38
|
+
assert_equal test_item, data.contents
|
39
|
+
end
|
40
|
+
|
41
|
+
it "doesn't wrap an envelope that gets pushed in another envelope" do
|
42
|
+
test_item = "Test Queue Item"
|
43
|
+
env = Timberline::Envelope.new
|
44
|
+
env.contents = test_item
|
45
|
+
assert_equal 1, @queue.push(env)
|
46
|
+
data = @queue.pop
|
47
|
+
assert_kind_of Timberline::Envelope, data
|
48
|
+
assert_equal test_item, data.contents
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "with one item" do
|
53
|
+
before do
|
54
|
+
clear_test_db
|
55
|
+
@test_item = "Test Queue Item"
|
56
|
+
@queue = Timberline::Queue.new("test_queue")
|
57
|
+
@queue.push(@test_item)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "has a length of 1" do
|
61
|
+
assert_equal 1, @queue.length
|
62
|
+
end
|
63
|
+
|
64
|
+
it "responds to pop with the one item" do
|
65
|
+
assert_equal @test_item, @queue.pop.contents
|
66
|
+
end
|
67
|
+
|
68
|
+
it "responds nil to a second pop" do
|
69
|
+
# Let's set the read_timeout to 1 in order for this test to return
|
70
|
+
@queue.instance_variable_set("@read_timeout", 1)
|
71
|
+
assert_equal @test_item, @queue.pop.contents
|
72
|
+
assert_equal nil, @queue.pop
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Timberline::QueueManager do
|
4
|
+
describe "newly instantiated" do
|
5
|
+
before do
|
6
|
+
clear_test_db
|
7
|
+
@qm = Timberline::QueueManager.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "has an empty queue list" do
|
11
|
+
assert_equal 0, @qm.queue_list.size
|
12
|
+
end
|
13
|
+
|
14
|
+
it "instantiates an error_queue" do
|
15
|
+
assert_kind_of Timberline::Queue, @qm.error_queue
|
16
|
+
assert_equal "timberline_errors", @qm.error_queue.queue_name
|
17
|
+
end
|
18
|
+
|
19
|
+
it "creates a new queue when asked if it doesn't exist" do
|
20
|
+
queue = @qm.queue("test_queue")
|
21
|
+
assert_kind_of Timberline::Queue, queue
|
22
|
+
assert_equal 1, @qm.queue_list.size
|
23
|
+
assert_equal queue, @qm.queue_list["test_queue"]
|
24
|
+
end
|
25
|
+
|
26
|
+
it "doesn't create a new queue if a queue by the same name already exists" do
|
27
|
+
queue = @qm.queue("test_queue")
|
28
|
+
new_queue = @qm.queue("test_queue")
|
29
|
+
assert_equal queue, new_queue
|
30
|
+
assert_equal 1, @qm.queue_list.size
|
31
|
+
end
|
32
|
+
|
33
|
+
it "creates a new queue as necessary when 'push' is called and pushes the item" do
|
34
|
+
@qm.push("test_queue", "Howdy kids.")
|
35
|
+
assert_equal 1, @qm.queue_list.size
|
36
|
+
queue = @qm.queue("test_queue")
|
37
|
+
assert_equal 1, queue.length
|
38
|
+
assert_equal "Howdy kids.", queue.pop.contents
|
39
|
+
end
|
40
|
+
|
41
|
+
it "uses any passed-in metadata to push when building the envelope" do
|
42
|
+
@qm.push("test_queue", "Howdy kids.", { :special_notes => "Super-awesome."})
|
43
|
+
queue = @qm.queue("test_queue")
|
44
|
+
assert_equal 1, queue.length
|
45
|
+
data = queue.pop
|
46
|
+
assert_equal "Howdy kids.", data.contents
|
47
|
+
assert_equal "Super-awesome.", data.special_notes
|
48
|
+
end
|
49
|
+
|
50
|
+
it "includes some default information in the metadata" do
|
51
|
+
@qm.push("test_queue", "Howdy kids.")
|
52
|
+
queue = @qm.queue("test_queue")
|
53
|
+
data = queue.pop
|
54
|
+
assert_equal "Howdy kids.", data.contents
|
55
|
+
assert_kind_of DateTime, DateTime.parse(data.submitted_at)
|
56
|
+
assert_equal "test_queue", data.origin_queue
|
57
|
+
assert_equal 0, data.retries
|
58
|
+
assert_equal 1, data.job_id
|
59
|
+
end
|
60
|
+
|
61
|
+
it "allows you to retry a job that has failed" do
|
62
|
+
@qm.push("test_queue", "Howdy kids.")
|
63
|
+
queue = @qm.queue("test_queue")
|
64
|
+
data = queue.pop
|
65
|
+
|
66
|
+
assert_equal 0, queue.length
|
67
|
+
|
68
|
+
@qm.retry_job(data)
|
69
|
+
|
70
|
+
assert_equal 1, queue.length
|
71
|
+
|
72
|
+
data = queue.pop
|
73
|
+
assert_equal 1, data.retries
|
74
|
+
assert_kind_of DateTime, DateTime.parse(data.last_tried_at)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "will continue retrying until we pass the max retries (defaults to 5)" do
|
78
|
+
@qm.push("test_queue", "Howdy kids.")
|
79
|
+
queue = @qm.queue("test_queue")
|
80
|
+
data = queue.pop
|
81
|
+
|
82
|
+
5.times do |i|
|
83
|
+
@qm.retry_job(data)
|
84
|
+
assert_equal 1, queue.length
|
85
|
+
data = queue.pop
|
86
|
+
assert_equal i + 1, data.retries
|
87
|
+
end
|
88
|
+
|
89
|
+
@qm.retry_job(data)
|
90
|
+
assert_equal 0, queue.length
|
91
|
+
assert_equal 1, @qm.error_queue.length
|
92
|
+
end
|
93
|
+
|
94
|
+
it "will allow you to directly error out a job" do
|
95
|
+
@qm.push("test_queue", "Howdy kids.")
|
96
|
+
queue = @qm.queue("test_queue")
|
97
|
+
data = queue.pop
|
98
|
+
|
99
|
+
@qm.error_job(data)
|
100
|
+
assert_equal 1, @qm.error_queue.length
|
101
|
+
data = @qm.error_queue.pop
|
102
|
+
assert_kind_of DateTime, DateTime.parse(data.fatal_error_at)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "will allow you to watch a queue" do
|
106
|
+
@qm.push("test_queue", "Howdy kids.")
|
107
|
+
|
108
|
+
assert_raises RuntimeError do
|
109
|
+
@qm.watch "test_queue" do |job|
|
110
|
+
if "Howdy kids." == job.contents
|
111
|
+
raise "This works."
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
assert_equal 0, @qm.queue("test_queue").length
|
117
|
+
end
|
118
|
+
|
119
|
+
it "will allow you to retry from a queue watcher" do
|
120
|
+
@qm.push("test_queue", "Howdy kids.")
|
121
|
+
|
122
|
+
assert_raises RuntimeError do
|
123
|
+
@qm.watch "test_queue" do |job|
|
124
|
+
if "Howdy kids." == job.contents
|
125
|
+
retry_job job
|
126
|
+
raise "Job retried."
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
assert_equal 1, @qm.queue("test_queue").length
|
132
|
+
data = @qm.queue("test_queue").pop
|
133
|
+
assert_equal 1, data.retries
|
134
|
+
end
|
135
|
+
|
136
|
+
it "will allow you to error from a queue watcher" do
|
137
|
+
@qm.push("test_queue", "Howdy kids.")
|
138
|
+
|
139
|
+
assert_raises RuntimeError do
|
140
|
+
@qm.watch "test_queue" do |job|
|
141
|
+
if "Howdy kids." == job.contents
|
142
|
+
error_job job
|
143
|
+
raise "Job errored."
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
assert_equal 1, @qm.error_queue.length
|
149
|
+
data = @qm.error_queue.pop
|
150
|
+
assert_kind_of DateTime, DateTime.parse(data.fatal_error_at)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|