batsir 0.1.0 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
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