batsir 0.1.0 → 0.3.7

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.
Files changed (63) hide show
  1. data/.travis.yml +9 -1
  2. data/CHANGES.md +54 -0
  3. data/Gemfile +7 -10
  4. data/README.md +49 -5
  5. data/Rakefile +23 -16
  6. data/batsir.gemspec +43 -15
  7. data/lib/batsir/acceptors/acceptor.rb +31 -5
  8. data/lib/batsir/acceptors/amqp_acceptor.rb +36 -8
  9. data/lib/batsir/amqp.rb +35 -7
  10. data/lib/batsir/amqp_consumer.rb +8 -0
  11. data/lib/batsir/compiler/stage_worker_compiler.rb +86 -0
  12. data/lib/batsir/config.rb +208 -24
  13. data/lib/batsir/dsl/conditional_notifier_declaration.rb +31 -0
  14. data/lib/batsir/dsl/dsl_mappings.rb +27 -2
  15. data/lib/batsir/errors.rb +18 -0
  16. data/lib/batsir/filter.rb +5 -0
  17. data/lib/batsir/log.rb +7 -0
  18. data/lib/batsir/logger.rb +37 -0
  19. data/lib/batsir/logo.rb +3 -8
  20. data/lib/batsir/notifiers/amqp_notifier.rb +14 -4
  21. data/lib/batsir/notifiers/conditional_notifier.rb +29 -0
  22. data/lib/batsir/notifiers/notifier.rb +6 -5
  23. data/lib/batsir/registry.rb +6 -2
  24. data/lib/batsir/stage.rb +9 -4
  25. data/lib/batsir/stage_worker.rb +3 -56
  26. data/lib/batsir/strategies/retry_strategy.rb +35 -0
  27. data/lib/batsir/strategies/strategy.rb +20 -0
  28. data/lib/batsir/transformers/field_transformer.rb +2 -3
  29. data/lib/batsir/transformers/json_input_transformer.rb +6 -2
  30. data/lib/batsir/transformers/json_output_transformer.rb +6 -2
  31. data/lib/batsir/transformers/transformer.rb +5 -1
  32. data/lib/batsir/version.rb +10 -0
  33. data/lib/batsir.rb +31 -13
  34. data/spec/batsir/acceptors/acceptor_spec.rb +7 -78
  35. data/spec/batsir/acceptors/amqp_acceptor_spec.rb +55 -66
  36. data/spec/batsir/acceptors/shared_examples.rb +102 -0
  37. data/spec/batsir/amqp_spec.rb +58 -0
  38. data/spec/batsir/chain_spec.rb +4 -4
  39. data/spec/batsir/config_spec.rb +97 -0
  40. data/spec/batsir/dsl/chain_mapping_spec.rb +5 -6
  41. data/spec/batsir/dsl/conditional_notifier_mapping_spec.rb +80 -0
  42. data/spec/batsir/dsl/stage_mapping_spec.rb +38 -20
  43. data/spec/batsir/filter_queue_spec.rb +9 -15
  44. data/spec/batsir/filter_spec.rb +4 -5
  45. data/spec/batsir/log_spec.rb +10 -0
  46. data/spec/batsir/logger_spec.rb +46 -0
  47. data/spec/batsir/notifiers/amqp_notifier_spec.rb +43 -22
  48. data/spec/batsir/notifiers/conditional_notifier_spec.rb +62 -0
  49. data/spec/batsir/notifiers/notifier_spec.rb +4 -66
  50. data/spec/batsir/notifiers/shared_examples.rb +100 -0
  51. data/spec/batsir/registry_spec.rb +48 -0
  52. data/spec/batsir/stage_spec.rb +91 -85
  53. data/spec/batsir/stage_worker_spec.rb +13 -13
  54. data/spec/batsir/strategies/retry_strategy_spec.rb +58 -0
  55. data/spec/batsir/strategies/strategy_spec.rb +28 -0
  56. data/spec/batsir/support/bunny_mocks.rb +78 -5
  57. data/spec/batsir/transformers/field_transformer_spec.rb +22 -22
  58. data/spec/batsir/transformers/json_input_transformer_spec.rb +8 -3
  59. data/spec/batsir/transformers/json_output_transformer_spec.rb +2 -2
  60. data/spec/batsir/transformers/transformer_spec.rb +18 -4
  61. data/spec/spec_helper.rb +6 -2
  62. metadata +78 -23
  63. data/VERSION +0 -1
@@ -0,0 +1,20 @@
1
+ module Batsir
2
+ module Strategies
3
+ class Strategy
4
+
5
+ attr_reader :context
6
+
7
+ def initialize(context)
8
+ if context.respond_to? :execute
9
+ @context = context
10
+ else
11
+ raise Batsir::Errors::ExecuteMethodNotImplementedError.new
12
+ end
13
+ end
14
+
15
+ def execute(message, error = nil)
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -14,7 +14,7 @@ module Batsir
14
14
  end
15
15
  end
16
16
 
17
- def transform(message)
17
+ def execute(message)
18
18
  fields = self.fields
19
19
  if fields.any? && message.respond_to?(:keys)
20
20
  symbolized_message_keys = {}
@@ -25,7 +25,7 @@ module Batsir
25
25
  fields_to_remove = symbolized_message_keys.keys - fields.keys - fields.values
26
26
 
27
27
  fields.each do |new, old|
28
- message[new] = message.delete(symbolized_message_keys[old])
28
+ message[new.to_s] = message.delete(symbolized_message_keys[old])
29
29
  end
30
30
 
31
31
  fields_to_remove.each do |field|
@@ -34,7 +34,6 @@ module Batsir
34
34
  end
35
35
  message
36
36
  end
37
-
38
37
  end
39
38
  end
40
39
  end
@@ -1,8 +1,12 @@
1
1
  module Batsir
2
2
  module Transformers
3
3
  class JSONInputTransformer < Transformer
4
- def transform(message)
5
- JSON.parse(message, :symbolize_names => false)
4
+ def execute(message)
5
+ begin
6
+ JSON.parse(message, :symbolize_names => false)
7
+ rescue JSON::JSONError => e
8
+ raise Batsir::Errors::JSONInputTransformError.new(e.message)
9
+ end
6
10
  end
7
11
  end
8
12
  end
@@ -1,8 +1,12 @@
1
1
  module Batsir
2
2
  module Transformers
3
3
  class JSONOutputTransformer < Transformer
4
- def transform(message)
5
- JSON.dump(message)
4
+ def execute(message)
5
+ begin
6
+ JSON.dump(message)
7
+ rescue JSON::JSONError => e
8
+ raise Batsir::Errors::JSONOutputTransformError.new(e.message)
9
+ end
6
10
  end
7
11
  end
8
12
  end
@@ -8,7 +8,11 @@ module Batsir
8
8
  end
9
9
 
10
10
  def transform(message)
11
- message
11
+ execute(message)
12
+ end
13
+
14
+ def execute(message)
15
+ raise NotImplementedError.new
12
16
  end
13
17
  end
14
18
  end
@@ -0,0 +1,10 @@
1
+ module Batsir
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 3
5
+ PATCH = 7
6
+ BUILD = nil
7
+ end
8
+
9
+ VERSION = [Version::MAJOR, Version::MINOR, Version::PATCH, Version::BUILD].compact.join('.')
10
+ end
data/lib/batsir.rb CHANGED
@@ -1,42 +1,48 @@
1
1
  require 'blockenspiel'
2
2
  require 'celluloid'
3
3
  require 'json'
4
+ require 'log4r'
4
5
  require 'bunny'
5
6
  require 'sidekiq'
6
7
  require 'sidekiq/cli'
7
- require 'batsir/registry'
8
+ require 'batsir/amqp_consumer'
8
9
  require 'batsir/config'
9
10
  require 'batsir/chain'
11
+ require 'batsir/errors'
10
12
  require 'batsir/filter'
11
13
  require 'batsir/filter_queue'
14
+ require 'batsir/log'
15
+ require 'batsir/logger'
16
+ require 'batsir/logo'
17
+ require 'batsir/registry'
12
18
  require 'batsir/stage'
13
19
  require 'batsir/stage_worker'
20
+ require 'batsir/compiler/stage_worker_compiler'
14
21
  require 'batsir/dsl/dsl_mappings'
22
+ require 'batsir/dsl/conditional_notifier_declaration'
15
23
  require 'batsir/acceptors/acceptor'
16
24
  require 'batsir/acceptors/amqp_acceptor'
17
25
  require 'batsir/notifiers/notifier'
18
26
  require 'batsir/notifiers/amqp_notifier'
27
+ require 'batsir/notifiers/conditional_notifier'
19
28
  require 'batsir/transformers/transformer'
20
29
  require 'batsir/transformers/field_transformer'
21
30
  require 'batsir/transformers/json_input_transformer'
22
31
  require 'batsir/transformers/json_output_transformer'
23
- require 'batsir/logo'
32
+ require 'batsir/strategies/strategy'
33
+ require 'batsir/strategies/retry_strategy'
34
+ require 'batsir/version'
24
35
 
25
36
  module Batsir
26
- def self.config
27
- @config ||= Batsir::Config.new(config_defaults)
28
- end
29
37
 
30
- def self.config_defaults
31
- {
32
- :redis_url => "redis://localhost:6379/0"
33
- }
38
+ def self.config
39
+ Batsir::Config
34
40
  end
35
41
 
36
42
  def self.create(&block)
37
43
  puts logo
38
44
  new_block = ::Proc.new do
39
- aggregator_chain &block
45
+ aggregator_chain(&block)
40
46
  end
41
47
  @chain = ::Blockenspiel.invoke(new_block, Batsir::DSL::ChainMapping.new)
42
48
  end
@@ -45,7 +51,7 @@ module Batsir
45
51
  return unless @chain
46
52
 
47
53
  sidekiq_cli = Sidekiq::CLI.instance
48
- Sidekiq.options[:queues] << 'default'
54
+ Sidekiq.options[:queues] << Batsir::Config.sidekiq_queue
49
55
 
50
56
  initialize_sidekiq
51
57
 
@@ -58,11 +64,12 @@ module Batsir
58
64
  end
59
65
 
60
66
  def self.initialize_sidekiq
67
+ Sidekiq.logger = Batsir::Logger.log
61
68
  Sidekiq.configure_server do |config|
62
- config.redis = {:url => Batsir.config.redis_url}
69
+ config.redis = {:url => redis_url, :namespace => redis_namespace}
63
70
  end
64
71
  Sidekiq.configure_client do |config|
65
- config.redis = {:url => Batsir.config.redis_url}
72
+ config.redis = {:url => redis_url, :namespace => redis_namespace}
66
73
  end
67
74
  end
68
75
 
@@ -70,4 +77,15 @@ module Batsir
70
77
  create(&block)
71
78
  start
72
79
  end
80
+
81
+ def self.redis_url
82
+ host = Batsir::Config.redis_host
83
+ port = Batsir::Config.redis_port
84
+ dbase = Batsir::Config.redis_database
85
+ "redis://#{host}:#{port}/#{dbase}"
86
+ end
87
+
88
+ def self.redis_namespace
89
+ Batsir::Config.redis_namespace
90
+ end
73
91
  end
@@ -1,89 +1,19 @@
1
1
  require File.join( File.dirname(__FILE__), "..", "..", "spec_helper" )
2
+ require File.join( File.dirname(__FILE__), 'shared_examples')
3
+
2
4
 
3
5
  describe Batsir::Acceptors::Acceptor do
6
+ it_behaves_like "an acceptor", Batsir::Acceptors::Acceptor
7
+
4
8
  let( :acceptor_class ) {
5
9
  Batsir::Acceptors::Acceptor
6
10
  }
7
11
 
8
- it "should be a Celluloid actor" do
12
+ it "is a Celluloid actor" do
9
13
  acceptor_class.ancestors.should include Celluloid
10
14
  end
11
15
 
12
- it "should be possible to set the stage name for the acceptor" do
13
- acceptor = acceptor_class.new
14
- stage_name = "some stage"
15
- acceptor.stage_name = stage_name
16
- acceptor.stage_name.should == stage_name
17
- end
18
-
19
- it "should have a #start method" do
20
- acceptor_class.instance_methods.map{|im| im.to_s}.should include "start"
21
- end
22
-
23
- it "should have an #start_filter_chain method" do
24
- acceptor_class.instance_methods.map{|im| im.to_s}.should include "start_filter_chain"
25
- end
26
-
27
- it "should be possible to initialize an Acceptor with on options hash" do
28
- acceptor = acceptor_class.new({})
29
- acceptor.should_not be_nil
30
- end
31
-
32
- it "should look up a worker class when the #start_filter_chain method is called" do
33
- acceptor = acceptor_class.new
34
- stage_name = "some stage"
35
- acceptor.stage_name = stage_name
36
- Batsir::Registry.should_receive(:get).with(stage_name)
37
- acceptor.start_filter_chain({})
38
- end
39
-
40
- it "should have a transformer_queue" do
41
- acceptor = acceptor_class.new
42
- acceptor.transformer_queue.should_not be_nil
43
- end
44
-
45
- it "should initially have an empty transformer_queue" do
46
- acceptor = acceptor_class.new
47
- acceptor.transformer_queue.should_not be_nil
48
- acceptor.transformer_queue.should be_empty
49
- end
50
-
51
- it "should be possible to add a transformer to the transformer_queue" do
52
- transformer = :transformer
53
-
54
- acceptor = acceptor_class.new
55
- acceptor.add_transformer transformer
56
-
57
- acceptor.transformer_queue.should_not be_empty
58
- acceptor.transformer_queue.size.should == 1
59
- acceptor.transformer_queue.first.should == :transformer
60
- end
61
-
62
- it "should be possible to add a transformer multiple times" do
63
- transformer = :transformer
64
-
65
- acceptor = acceptor_class.new
66
- acceptor.add_transformer transformer
67
- acceptor.add_transformer transformer
68
-
69
- acceptor.transformer_queue.should_not be_empty
70
- acceptor.transformer_queue.size.should == 2
71
- end
72
-
73
- it "should be possible to set a cancellator" do
74
- cancellator = :cancel
75
- acceptor = acceptor_class.new
76
- acceptor.cancellator = cancellator
77
- acceptor.cancellator.should == cancellator
78
- end
79
-
80
- it "should be possible to set a cancellator in the constructor using a hash" do
81
- cancellator = :cancel
82
- acceptor = acceptor_class.new(:cancellator => cancellator)
83
- acceptor.cancellator.should == cancellator
84
- end
85
-
86
- it "should call the #perform_async on the worker class when #start_filter_chain is called" do
16
+ it "calls the #perform_async on the worker class when #start_filter_chain is called" do
87
17
  class MockWorker
88
18
  def self.stage_name
89
19
  "mock_stage"
@@ -108,7 +38,7 @@ describe Batsir::Acceptors::Acceptor do
108
38
  acceptor.start_filter_chain({})
109
39
  end
110
40
 
111
- it "should call #transform on the acceptor transformers" do
41
+ it "calls #transform on the acceptor transformers" do
112
42
  class MockTransformer < Batsir::Transformers::Transformer
113
43
  def transform(message)
114
44
  @@transformed ||= 0
@@ -123,7 +53,6 @@ describe Batsir::Acceptors::Acceptor do
123
53
 
124
54
  acceptor = acceptor_class.new
125
55
  stage_name = "some stage"
126
-
127
56
  acceptor.stage_name = stage_name
128
57
  acceptor.add_transformer MockTransformer.new
129
58
 
@@ -1,53 +1,69 @@
1
1
  require File.join( File.dirname(__FILE__), "..", "..", "spec_helper" )
2
+ require File.join( File.dirname(__FILE__), 'shared_examples')
2
3
 
3
4
  describe Batsir::Acceptors::AMQPAcceptor do
5
+ it_behaves_like "an acceptor", Batsir::Acceptors::AMQPAcceptor
4
6
 
5
7
  let(:acceptor_class){
6
8
  Batsir::Acceptors::AMQPAcceptor
7
9
  }
8
10
 
9
- context "With respect to setting options" do
11
+ context "instantiating" do
12
+ it "sets a bunny pool" do
13
+ acceptor = acceptor_class.new
14
+ acceptor.bunny_pool.should be_kind_of ConnectionPool
15
+ end
10
16
 
11
- it "should be a Batsir::Acceptors::Acceptor" do
12
- acceptor_class.ancestors.should include Batsir::Acceptors::Acceptor
17
+ it "uses the same ConnectionPool instance for each acceptor" do
18
+ acceptor1 = acceptor_class.new
19
+ acceptor2 = acceptor_class.new
20
+ acceptor1.should_not eql acceptor2
21
+ acceptor1.bunny_pool.should eql acceptor2.bunny_pool
13
22
  end
23
+ end
14
24
 
15
- it "should be possible to set the queue on which to listen" do
25
+ context "setting options" do
26
+ it "can set the queue on which to listen" do
16
27
  acceptor = acceptor_class.new(:queue => :queue)
17
28
  acceptor.queue.should == :queue
18
29
  end
19
30
 
20
- it "should be possible to set the host of the amqp broker" do
31
+ it "can set the host of the amqp broker" do
21
32
  acceptor = acceptor_class.new(:host => 'localhost')
22
33
  acceptor.host.should == 'localhost'
23
34
  end
24
35
 
25
- it "should be possible to set the port of the amqp broker" do
36
+ it "can set the port of the amqp broker" do
26
37
  acceptor = acceptor_class.new(:port => 1234)
27
38
  acceptor.port.should == 1234
28
39
  end
29
40
 
30
- it "should be possible to set the username with which to connect to the broker" do
41
+ it "can set the username with which to connect to the broker" do
31
42
  acceptor = acceptor_class.new(:username => 'some_user')
32
43
  acceptor.username.should == 'some_user'
33
44
  end
34
45
 
35
- it "should be possible to set the password with which to connect to the broker" do
46
+ it "can set the password with which to connect to the broker" do
36
47
  acceptor = acceptor_class.new(:password => 'password')
37
48
  acceptor.password.should == 'password'
38
49
  end
39
50
 
40
- it "should be possible to set the vhost to use on the broker" do
51
+ it "can set the vhost to use on the broker" do
41
52
  acceptor = acceptor_class.new(:vhost => '/vhost')
42
53
  acceptor.vhost.should == '/vhost'
43
54
  end
44
55
 
45
- it "should be possible to set the exchange to use on the broker" do
56
+ it "can set the exchange to use on the broker" do
46
57
  acceptor = acceptor_class.new(:exchange => 'amq.direct')
47
58
  acceptor.exchange.should == 'amq.direct'
48
59
  end
49
60
 
50
- it "should default to amqp://guest:guest@localhost:5672/ with direct exchange on vhost ''" do
61
+ it "can set the queue to be durable" do
62
+ acceptor = acceptor_class.new(:durable => true)
63
+ acceptor.durable.should == true
64
+ end
65
+
66
+ it "defaults to amqp://guest:guest@localhost:5672/ with direct exchange on vhost ''" do
51
67
  acceptor = acceptor_class.new(:queue => :somequeue)
52
68
  acceptor.queue.should == :somequeue
53
69
  acceptor.host.should == 'localhost'
@@ -59,79 +75,58 @@ describe Batsir::Acceptors::AMQPAcceptor do
59
75
  end
60
76
  end
61
77
 
62
- context "with respect to starting the acceptor" do
78
+ context "starting the acceptor" do
63
79
  def new_acceptor(options = {})
64
- acceptor_class.new(options)
80
+ acceptor_class.new({:queue => 'test_queue'}.merge options)
65
81
  end
66
82
 
67
- it "should connect to the configured host" do
68
- acceptor = new_acceptor(:host => 'somehost')
69
- acceptor.start
70
- instance = Bunny.instance
71
- instance.options[:host].should == 'somehost'
83
+ it "starts listening on the configured queue" do
84
+ acceptor = new_acceptor()
85
+ acceptor.bunny_pool do |bunny|
86
+ acceptor.consumer.queue.name.should == 'test_queue'
87
+ end
72
88
  end
73
89
 
74
- it "should connect to the configured port" do
75
- acceptor = new_acceptor(:port => 1234)
90
+ it "connects to the configured host" do
91
+ acceptor = new_acceptor(:host => 'localhost')
76
92
  acceptor.start
77
- instance = Bunny.instance
78
- instance.options[:port].should == 1234
93
+ acceptor.consumer.queue.channel.connection.host.should == 'localhost'
79
94
  end
80
95
 
81
- it "should connect with the configured username" do
82
- acceptor = new_acceptor(:username => 'user')
96
+ it "connects to the configured port" do
97
+ acceptor = new_acceptor(:port => 5672)
83
98
  acceptor.start
84
- instance = Bunny.instance
85
- instance.options[:user].should == 'user'
99
+ acceptor.consumer.queue.channel.connection.port.should == 5672
86
100
  end
87
101
 
88
- it "should connect with the configured password" do
89
- acceptor = new_acceptor(:password => 'pass')
102
+ it "connects with the configured username" do
103
+ acceptor = new_acceptor(:username => 'guest', :password => 'guest')
90
104
  acceptor.start
91
- instance = Bunny.instance
92
- instance.options[:pass].should == 'pass'
105
+ acceptor.consumer.queue.channel.connection.user.should == 'guest'
106
+ acceptor.consumer.queue.channel.connection.pass.should == 'guest'
93
107
  end
94
108
 
95
- it "should connect to the configured vhost" do
96
- acceptor = new_acceptor(:vhost => '/vhost')
109
+ it "connects to the configured vhost" do
110
+ acceptor = new_acceptor(:vhost => '/')
97
111
  acceptor.start
98
- instance = Bunny.instance
99
- instance.options[:vhost].should == '/vhost'
112
+ acceptor.consumer.queue.channel.connection.vhost.should == '/'
100
113
  end
101
114
 
102
- it "should declare the configured exchange" do
115
+ it "declares the configured exchange" do
103
116
  acceptor = new_acceptor(:exchange => 'some_exchange')
104
117
  acceptor.start
105
- instance = Bunny.instance
106
- instance.exchange.name.should == 'some_exchange'
118
+ acceptor.consumer.queue.instance_variable_get(:@bindings).first[:exchange].should == 'some_exchange'
107
119
  end
108
120
 
109
- it "should bind the configured exchange to the queue" do
121
+ it "binds the configured exchange to the queue" do
110
122
  acceptor = new_acceptor(:exchange => 'some_exchange', :queue => :queue)
111
123
  acceptor.start
112
- instance = Bunny.instance
113
- queue = instance.queues[:queue]
114
- queue.bound_exchange.name.should == 'some_exchange'
115
- queue.bound_key.should == :queue
124
+ binding = acceptor.consumer.queue.instance_variable_get(:@bindings).first
125
+ binding[:exchange].should == 'some_exchange'
126
+ binding[:routing_key].should == :queue
116
127
  end
117
128
 
118
- it "should start listening on the configured queue" do
119
- acceptor = new_acceptor(:queue => :some_queue)
120
- acceptor.start
121
- instance = Bunny.instance
122
- instance.queues.size.should == 1
123
- instance.queues.keys.should include :some_queue
124
- end
125
-
126
- it "should initialize the subscription with the acceptor's cancellator" do
127
- cancellator = :cancellator
128
- acceptor = new_acceptor(:queue => :some_queue, :cancellator => cancellator)
129
- acceptor.start
130
- instance = Bunny.instance
131
- puts instance.queues[:some_queue].arguments.first[:cancellator].should == cancellator
132
- end
133
-
134
- it "should call the #start_filter_chain method when a message is received" do
129
+ it "calls the #start_filter_chain method when a message is received" do
135
130
  acceptor = new_acceptor(:queue => :some_queue)
136
131
 
137
132
  # Because acceptor is a Celluloid Actor, it is not possible to define a method
@@ -155,13 +150,7 @@ describe Batsir::Acceptors::AMQPAcceptor do
155
150
  acceptor._send_(:define_singleton_method, :method_called, method_called_mock_method)
156
151
 
157
152
  acceptor.start
158
-
159
- instance = Bunny.instance
160
- queue = instance.queues[:some_queue]
161
- queue.should_not be_nil
162
-
163
- block = queue.block
164
- block.call({})
153
+ acceptor.consumer.call({})
165
154
 
166
155
  acceptor.method_called.should == 1
167
156
  end
@@ -0,0 +1,102 @@
1
+ shared_examples_for "an acceptor" do |acceptor_class|
2
+ before :each do
3
+ subject{acceptor_class.new}
4
+ end
5
+
6
+ context 'properties' do
7
+ it "is a Batsir::Acceptors::Acceptor" do
8
+ subject.should be_kind_of Batsir::Acceptors::Acceptor
9
+ end
10
+
11
+ it "has a #start method" do
12
+ subject.class.instance_methods.map{|im| im.to_s}.should include "start"
13
+ end
14
+
15
+ it "has a #start_filter_chain method" do
16
+ subject.class.instance_methods.map{|im| im.to_s}.should include "start_filter_chain"
17
+ end
18
+
19
+ it "has a transformer_queue" do
20
+ subject.transformer_queue.should_not be_nil
21
+ end
22
+ end
23
+
24
+ context 'instances' do
25
+ it "can initialize an Acceptor with on options hash" do
26
+ acceptor = acceptor_class.new({})
27
+ acceptor.should_not be_nil
28
+ end
29
+
30
+ it "initially has an empty transformer_queue" do
31
+ subject.transformer_queue.should_not be_nil
32
+ subject.transformer_queue.should be_empty
33
+ end
34
+
35
+ it "can set the stage name for the acceptor" do
36
+ acceptor = acceptor_class.new
37
+ stage_name = "some stage"
38
+ acceptor.stage_name = stage_name
39
+ acceptor.stage_name.should == stage_name
40
+ end
41
+
42
+ it "looks up a worker class when the #start_filter_chain method is called" do
43
+ acceptor = acceptor_class.new
44
+ stage_name = "some stage"
45
+ acceptor.stage_name = stage_name
46
+ Batsir::Registry.should_receive(:get).with(stage_name)
47
+ acceptor.start_filter_chain({})
48
+ end
49
+ end
50
+
51
+ context 'transformers' do
52
+ it "can add a transformer to the transformer_queue" do
53
+ transformer = :transformer
54
+
55
+ acceptor = acceptor_class.new
56
+ acceptor.add_transformer transformer
57
+
58
+ acceptor.transformer_queue.should_not be_empty
59
+ acceptor.transformer_queue.size.should == 1
60
+ acceptor.transformer_queue.first.should == :transformer
61
+ end
62
+
63
+ it "can add a transformer multiple times" do
64
+ transformer = :transformer
65
+
66
+ acceptor = acceptor_class.new
67
+ acceptor.add_transformer transformer
68
+ acceptor.add_transformer transformer
69
+
70
+ acceptor.transformer_queue.should_not be_empty
71
+ acceptor.transformer_queue.size.should == 2
72
+ end
73
+
74
+ it "handles errors thrown by transformers" do
75
+ class ErrorAcceptor < Batsir::Acceptors::Acceptor
76
+ attr_accessor :message
77
+ def process_message_error(message, error)
78
+ message = "error"
79
+ @message = message
80
+ end
81
+ end
82
+
83
+ class MockTransformer < Batsir::Transformers::Transformer
84
+ def transform(message)
85
+ raise Batsir::Errors::TransformError.new
86
+ end
87
+ end
88
+
89
+ acceptor = ErrorAcceptor.new
90
+ stage_name = "some stage"
91
+ acceptor.stage_name = stage_name
92
+ acceptor.add_transformer MockTransformer.new
93
+
94
+ acceptor.message.should be_nil
95
+
96
+ acceptor.start_filter_chain({})
97
+
98
+ acceptor.message.should == "error"
99
+ end
100
+ end
101
+
102
+ end
@@ -0,0 +1,58 @@
1
+ require File.join( File.dirname(__FILE__), "..", "spec_helper" )
2
+
3
+ describe Batsir::AMQP do
4
+ before :all do
5
+ class AMQPTest
6
+ include Batsir::AMQP
7
+ end
8
+ @test = AMQPTest.new
9
+ end
10
+
11
+ context 'with respect to default variables' do
12
+ it 'has a host' do
13
+ @test.host.should == 'localhost'
14
+ end
15
+
16
+ it 'has a port' do
17
+ @test.port.should == 5672
18
+ end
19
+
20
+ it 'has a username' do
21
+ @test.username.should == 'guest'
22
+ end
23
+
24
+ it 'has a password' do
25
+ @test.password.should == 'guest'
26
+ end
27
+
28
+ it 'has a vhost' do
29
+ @test.vhost.should == '/'
30
+ end
31
+
32
+ it 'has a exchange' do
33
+ @test.exchange.should == 'amq.direct'
34
+ end
35
+
36
+ it 'is durable' do
37
+ @test.durable.should == true
38
+ end
39
+
40
+ it 'is undead' do
41
+ @test.heartbeat.should == 0
42
+ end
43
+ end
44
+
45
+ context 'with respect to setting variables' do
46
+ it 'can change host' do
47
+ localhost = '127.0.0.1'
48
+ @test.host = localhost
49
+ @test.host.should == localhost
50
+ end
51
+
52
+ it 'can change heartbeat' do
53
+ hb = 512
54
+ @test.heartbeat = hb
55
+ @test.heartbeat.should == hb
56
+ end
57
+ end
58
+ end