batsir 0.3.7.1 → 0.4.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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES.md +9 -0
  3. data/README.md +1 -1
  4. data/lib/batsir/compiler/stage_worker_compiler.rb +42 -27
  5. data/lib/batsir/dsl/conditional_notifier_declaration.rb +7 -7
  6. data/lib/batsir/version.rb +3 -3
  7. metadata +81 -151
  8. data/.document +0 -5
  9. data/.rspec +0 -3
  10. data/.travis.yml +0 -18
  11. data/Gemfile +0 -19
  12. data/Rakefile +0 -62
  13. data/batsir.gemspec +0 -132
  14. data/batsir.png +0 -0
  15. data/spec/batsir/acceptors/acceptor_spec.rb +0 -65
  16. data/spec/batsir/acceptors/amqp_acceptor_spec.rb +0 -158
  17. data/spec/batsir/acceptors/shared_examples.rb +0 -102
  18. data/spec/batsir/amqp_spec.rb +0 -58
  19. data/spec/batsir/chain_spec.rb +0 -31
  20. data/spec/batsir/config_spec.rb +0 -97
  21. data/spec/batsir/dsl/chain_mapping_spec.rb +0 -116
  22. data/spec/batsir/dsl/conditional_notifier_mapping_spec.rb +0 -80
  23. data/spec/batsir/dsl/stage_mapping_spec.rb +0 -453
  24. data/spec/batsir/filter_queue_spec.rb +0 -68
  25. data/spec/batsir/filter_spec.rb +0 -11
  26. data/spec/batsir/log_spec.rb +0 -10
  27. data/spec/batsir/logger_spec.rb +0 -46
  28. data/spec/batsir/notifiers/amqp_notifier_spec.rb +0 -138
  29. data/spec/batsir/notifiers/conditional_notifier_spec.rb +0 -62
  30. data/spec/batsir/notifiers/notifier_spec.rb +0 -11
  31. data/spec/batsir/notifiers/shared_examples.rb +0 -100
  32. data/spec/batsir/registry_spec.rb +0 -48
  33. data/spec/batsir/stage_spec.rb +0 -684
  34. data/spec/batsir/stage_worker_spec.rb +0 -128
  35. data/spec/batsir/strategies/retry_strategy_spec.rb +0 -58
  36. data/spec/batsir/strategies/strategy_spec.rb +0 -28
  37. data/spec/batsir/support/bunny_mocks.rb +0 -135
  38. data/spec/batsir/support/mock_filters.rb +0 -43
  39. data/spec/batsir/transformers/field_transformer_spec.rb +0 -73
  40. data/spec/batsir/transformers/json_input_transformer_spec.rb +0 -27
  41. data/spec/batsir/transformers/json_output_transformer_spec.rb +0 -18
  42. data/spec/batsir/transformers/transformer_spec.rb +0 -36
  43. data/spec/spec_helper.rb +0 -26
@@ -1,128 +0,0 @@
1
- require File.join( File.dirname(__FILE__), "..", "spec_helper" )
2
-
3
- describe Batsir::StageWorker do
4
- it "can set a filter queue" do
5
- Batsir::StageWorker.instance_methods.map{|m| m.to_s}.should include "filter_queue="
6
- end
7
-
8
- context "with respect to including the StageWorker module" do
9
- before :all do
10
- class TestWorker
11
- def self.stage_name
12
- @stage_name_called = true
13
- "TestWorker"
14
- end
15
-
16
- def self.stage_name_called
17
- @stage_name_called || false
18
- end
19
-
20
- def self.initialize_filter_queue
21
- @initialization_count ||= 0
22
- @initialization_count += 1
23
- end
24
-
25
- def self.initialization_count
26
- @initialization_count
27
- end
28
-
29
- include Batsir::StageWorker
30
- end
31
- end
32
-
33
- it "registers workers once they include the stage worker" do
34
- Batsir::Registry.get("TestWorker").should == TestWorker
35
- end
36
-
37
- it "calls the queue initialization method" do
38
- TestWorker.initialization_count.should == 1
39
- end
40
-
41
- it "calls the stage name class method to register itself under" do
42
- TestWorker.stage_name_called.should be_true
43
- end
44
- end
45
-
46
- context "with respect to executing" do
47
- before :all do
48
- class TestWorker
49
- def self.stage_name
50
- "TestWorker"
51
- end
52
-
53
- def self.intitialize_filter_queue
54
- @initialization_count ||= 0
55
- @initialization_count += 1
56
- end
57
-
58
- include Batsir::StageWorker
59
- end
60
-
61
- class TestNotifier
62
- def notify(message)
63
- @notify_count ||= 0
64
- @notify_count += 1
65
- end
66
-
67
- def notify_count
68
- @notify_count ||= 0
69
- end
70
- end
71
- end
72
-
73
- before :each do
74
- chain = Batsir::Chain.new
75
-
76
- stage_options = {
77
- :chain => chain,
78
- }
79
- stage = Batsir::Stage.new(stage_options)
80
-
81
- stage.add_filter SumFilter
82
- stage.add_filter AverageFilter
83
- stage.add_notifier( :notification_queue_1, {:queue => :somequeue} )
84
- stage.add_notifier( :notification_queue_2 )
85
- end
86
-
87
- it "does not execute when no operation queue is set" do
88
- stage_worker = TestWorker.new
89
- stage_worker.execute({}).should be_false
90
- end
91
-
92
- it "executes all operations in the operation queue when an #execute message is received" do
93
- filter_queue = Batsir::FilterQueue.new
94
- filter_queue.add SumFilter.new
95
- filter_queue.add AverageFilter.new
96
-
97
- stage_worker = TestWorker.new
98
- stage_worker.filter_queue = filter_queue
99
-
100
- queue = stage_worker.filter_queue
101
- queue.each do |filter|
102
- filter.execute_count.should == 0
103
- end
104
-
105
- stage_worker.execute({}).should be_true
106
-
107
- queue.each do |filter|
108
- filter.execute_count.should == 1
109
- end
110
- end
111
-
112
- it "calls #notify on all notifiers in the filter queue when an #execute message is received" do
113
- filter_queue = Batsir::FilterQueue.new
114
- filter_queue.add_notifier TestNotifier.new
115
-
116
- stage_worker = TestWorker.new
117
- stage_worker.filter_queue = filter_queue
118
-
119
- notifier = filter_queue.notifiers.first
120
- notifier.should_not be_nil
121
- notifier.notify_count.should == 0
122
-
123
- stage_worker.execute({}).should be_true
124
-
125
- notifier.notify_count.should == 1
126
- end
127
- end
128
- end
@@ -1,58 +0,0 @@
1
- require File.join( File.dirname(__FILE__), "..", "..", "spec_helper" )
2
-
3
- describe Batsir::Strategies::RetryStrategy do
4
- let( :strategy_class ) {
5
- Batsir::Strategies::RetryStrategy
6
- }
7
-
8
- before :all do
9
- class MockError < RuntimeError; end
10
-
11
- class MockRetryContext
12
- attr_accessor :strategy
13
-
14
- def initialize(failures, retries)
15
- @total_iterations = 0
16
- @failures = failures
17
- @strategy = Batsir::Strategies::RetryStrategy.new(self, retries)
18
- end
19
-
20
- def execute(message)
21
- if @total_iterations == @failures
22
- return "test complete"
23
- else
24
- @total_iterations += 1
25
- handle_error(message)
26
- end
27
- end
28
-
29
- def handle_error(message)
30
- @strategy.execute(message, MockError.new)
31
- end
32
- end
33
-
34
- @context = MockRetryContext.new(2,2)
35
- end
36
-
37
- it 'stores the number of allowed retries' do
38
- @context.strategy.retries.should == 2
39
- end
40
-
41
- it 'stores the retry attempts per message' do
42
- @context.strategy.attempts.should == {}
43
- end
44
-
45
- it 'attempts to execute the given number of times' do
46
- @context = MockRetryContext.new(3,3)
47
- @context.strategy.log.level = Batsir::Logger::FATAL
48
- @context.execute("test").should == "test complete"
49
- @context.strategy.attempts.size.should == 0
50
- end
51
-
52
- it 'throws an error when all retry attempts have been used' do
53
- @context = MockRetryContext.new(3,2)
54
- @context.strategy.log.level = Batsir::Logger::FATAL
55
- lambda{@context.execute("test")}.should raise_error Batsir::Errors::RetryStrategyFailed
56
- end
57
-
58
- end
@@ -1,28 +0,0 @@
1
- require File.join( File.dirname(__FILE__), "..", "..", "spec_helper" )
2
-
3
- describe Batsir::Strategies::Strategy do
4
- let( :strategy_class ) {
5
- Batsir::Strategies::Strategy
6
- }
7
-
8
- class MockContext
9
- def execute(message)
10
- end
11
- end
12
-
13
- class DefunctMockContext; end
14
-
15
- it 'has an #execute method' do
16
- strategy_class.instance_methods.map{|im| im.to_s}.should include "execute"
17
- end
18
-
19
- it 'has an accessable context' do
20
- c = MockContext.new
21
- strategy_class.new(c).context.should == c
22
- end
23
-
24
- it 'detects an incorrect context object being passed' do
25
- c = DefunctMockContext.new
26
- lambda{strategy_class.new(c)}.should raise_error Batsir::Errors::ExecuteMethodNotImplementedError
27
- end
28
- end
@@ -1,135 +0,0 @@
1
- module Bunny
2
- def self.instance
3
- @instance
4
- end
5
-
6
- def self.run(options = {})
7
- @instance = BunnyInstance.new(options)
8
- yield @instance
9
- end
10
-
11
- def self.new(options = {})
12
- @instance = BunnyInstance.new(options)
13
- @instance
14
- end
15
-
16
- class Consumer
17
- def initialize(channel, queue, consumer_tag = 'test', no_ack = true, exclusive = false, arguments = {})
18
- @channel = channel
19
- @queue = queue
20
- end
21
- end
22
-
23
- class BunnyInstance
24
- attr_accessor :queues
25
- attr_accessor :options
26
- attr_accessor :channel
27
- attr_accessor :exchange
28
-
29
- def initialize(options = {})
30
- @options = options
31
- @queues = {}
32
- end
33
-
34
- def start
35
- @channel = create_channel
36
- self
37
- end
38
-
39
- def exchange(exchange = nil)
40
- @exchange = BunnyExchange.new(self, exchange) if exchange
41
- @exchange
42
- end
43
-
44
- def queue(queue, options = {})
45
- @queues[queue] = BunnyQueue.new
46
- end
47
-
48
- def create_channel
49
- self
50
- end
51
-
52
- def connection
53
- self
54
- end
55
-
56
- def host
57
- @options[:host]
58
- end
59
-
60
- def port
61
- @options[:port]
62
- end
63
-
64
- def user
65
- @options[:user]
66
- end
67
-
68
- def pass
69
- @options[:pass]
70
- end
71
-
72
- def vhost
73
- @options[:vhost]
74
- end
75
-
76
- def number
77
- 1
78
- end
79
- end
80
-
81
- class BunnyExchange
82
- attr_accessor :name
83
- attr_accessor :key
84
- attr_accessor :message
85
- attr_accessor :channel
86
-
87
- def initialize(channel, name)
88
- @channel = channel
89
- @name = name
90
- end
91
-
92
- def publish(message, options = {})
93
- @key = options[:routing_key] || options[:key]
94
- @message = message
95
- end
96
- end
97
-
98
- class BunnyQueue
99
- attr_accessor :arguments
100
- attr_accessor :block
101
- attr_accessor :bound_exchange
102
- attr_accessor :bound_key
103
- attr_accessor :consumer
104
-
105
- def initialize
106
- @bindings = []
107
- end
108
-
109
- def bind(exchange, options)
110
- @bound_exchange = exchange
111
-
112
- @bound_key = options[:routing_key] || options[:key]
113
- @bindings << {:exchange => @bound_exchange.name, :routing_key => @bound_key}
114
- end
115
-
116
- def subscribe(*args, &block)
117
- @arguments = *args
118
- @block = block
119
- end
120
-
121
- def subscribe_with(consumer, opts = {:block => false})
122
- @block ||= opts[:block]
123
- @consumer = consumer
124
- @consumer
125
- end
126
-
127
- def name
128
- @bound_key
129
- end
130
-
131
- def channel
132
- @bound_exchange.channel
133
- end
134
- end
135
- end
@@ -1,43 +0,0 @@
1
- module Batsir::MockBehavior
2
- attr_accessor :execute_count
3
- def initialize(options = {})
4
- super
5
- @execute_count = 0
6
- end
7
-
8
- def execute(message)
9
- @execute_count += 1
10
- end
11
- end
12
-
13
- class Batsir::MockFilter < Batsir::Filter
14
- include Batsir::MockBehavior
15
- end
16
-
17
- class PersistenceFilter < Batsir::MockFilter
18
- end
19
-
20
- class SumFilter < Batsir::MockFilter
21
- end
22
-
23
- class AverageFilter < Batsir::MockFilter
24
- end
25
-
26
- class Batsir::RetrievalFilter
27
- include Batsir::MockBehavior
28
- end
29
-
30
- class Batsir::MessagePrinter < Batsir::Filter
31
- def execute(message)
32
- puts "In #{self.class.to_s}#execute(#{message.inspect})"
33
- puts message
34
- message
35
- end
36
- end
37
-
38
- class Batsir::MessageCreator < Batsir::Filter
39
- def execute(message)
40
- puts "In #{self.class.to_s}#execute(#{message.inspect})"
41
- {:id => message}
42
- end
43
- end
@@ -1,73 +0,0 @@
1
- require File.join( File.dirname(__FILE__), "..", "..", "spec_helper" )
2
-
3
- describe Batsir::Transformers::FieldTransformer do
4
- let( :transformer_class ) do
5
- Batsir::Transformers::FieldTransformer
6
- end
7
-
8
- it "accepts an options hash in its initializer" do
9
- transformer_instance = transformer_class.new( {} )
10
- transformer_instance.should_not be_nil
11
- transformer_instance.should be_a transformer_class
12
- end
13
-
14
- it "can set a field mapping using the 'fields' option" do
15
- field_mapping = {:foo => :bar}
16
- transformer = transformer_class.new( :fields => field_mapping )
17
- transformer.fields.should == field_mapping
18
- end
19
-
20
- it "uses the fields mapping given in an options hash to transform the message using #transform" do
21
- field_mapping = {:foo => 'bar'}
22
- transformer = transformer_class.new( :fields => field_mapping )
23
-
24
- message = {'bar' => 123}
25
- transformed_message = transformer.transform(message)
26
- transformed_message.should have_key 'foo'
27
- transformed_message.should_not have_key :foo
28
- transformed_message.should_not have_key 'bar'
29
- transformed_message['foo'].should == 123
30
- end
31
-
32
- it "can use symbols and string based keys and values all the same" do
33
- field_mapping = {:foo => "bar", "john" => :doe}
34
- transformer = transformer_class.new( :fields => field_mapping )
35
-
36
- message = {:bar => "foo", "doe" => :john}
37
- transformed_message = transformer.transform(message)
38
- transformed_message['foo'].should == 'foo'
39
- transformed_message['john'].should == :john
40
- end
41
-
42
- it "removes options not in the fields option when a fields option is given" do
43
- field_mapping = {:foo => :bar}
44
- transformer = transformer_class.new( :fields => field_mapping )
45
-
46
- message = {'bar' => "bar", 'john' => :doe}
47
- transformed_message = transformer.transform(message)
48
- transformed_message.should have_key 'foo'
49
- transformed_message.should_not have_key 'bar'
50
- transformed_message.should_not have_key 'john'
51
- end
52
-
53
- it "does not remove fields when no mapping is given, but enforces the no_symbol_keys principle" do
54
- transformer = transformer_class.new
55
-
56
- message = {:bar => "bar", :john => :doe}
57
- transformed_message = transformer.transform(message)
58
- transformed_message.should have_key :bar
59
- transformed_message.should have_key :john
60
- end
61
-
62
- it "correctly handles more complex field mapping" do
63
- field_mapping = {:id => :old_id}
64
- transformer = transformer_class.new( :fields => field_mapping )
65
-
66
- message = {:id => 2, :old_id => 1, :john => :doe}
67
- transformed_message = transformer.transform(message)
68
-
69
- transformed_message.should have_key 'id'
70
- transformed_message.should_not have_key 'old_id'
71
- transformed_message.should_not have_key 'john'
72
- end
73
- end
@@ -1,27 +0,0 @@
1
- require File.join( File.dirname(__FILE__), "..", "..", "spec_helper" )
2
-
3
- describe Batsir::Transformers::JSONInputTransformer do
4
- it "is a Batsir::Transformers::Transformer" do
5
- subject.should be_a Batsir::Transformers::Transformer
6
- end
7
-
8
- it "transforms the input to a ruby object" do
9
- some_json = '{"foo" : "bar"}'
10
- result = subject.transform(some_json)
11
- result.should be_a Hash
12
- end
13
-
14
- it "transforms the input using string names" do
15
- some_json = '{"foo" : "bar"}'
16
- result = subject.transform(some_json)
17
-
18
- result[:foo].should be_nil
19
- result["foo"].should_not be_nil
20
- result["foo"].should == "bar"
21
- end
22
-
23
- it "should throw a TransformError when the input is malformed" do
24
- test = Batsir::Transformers::JSONInputTransformer.new
25
- expect{ test.transform("1") }.to raise_error Batsir::Errors::TransformError
26
- end
27
- end
@@ -1,18 +0,0 @@
1
- require File.join( File.dirname(__FILE__), "..", "..", "spec_helper" )
2
-
3
- describe Batsir::Transformers::JSONOutputTransformer do
4
- it "is a Batsir::Transformers::Transformer" do
5
- subject.should be_a Batsir::Transformers::Transformer
6
- end
7
-
8
- it "transforms a hash to a valid json hash" do
9
- some_hash = {:foo => :bar}
10
- some_hash.should be_a Hash
11
-
12
- result = subject.transform(some_hash)
13
- result.should be_a String
14
-
15
- result2 = JSON.parse(result)
16
- result2.should be_a Hash
17
- end
18
- end
@@ -1,36 +0,0 @@
1
- require File.join( File.dirname(__FILE__), "..", "..", "spec_helper" )
2
-
3
- describe Batsir::Transformers::Transformer do
4
- let( :transformer_class ) do
5
- Batsir::Transformers::Transformer
6
- end
7
-
8
- it "accepts an options hash in its initialiser" do
9
- transformer_instance = transformer_class.new( {} )
10
- transformer_instance.should_not be_nil
11
- transformer_instance.should be_a transformer_class
12
- end
13
-
14
- it "has a #transform method" do
15
- transformer_class.instance_methods.map{|m| m.to_s}.should include "transform"
16
- end
17
-
18
- it "has an #execute method" do
19
- transformer_class.instance_methods.map{|m| m.to_s}.should include "execute"
20
- end
21
-
22
- it 'raises an error when the #execute method is not implemented' do
23
- message = {:foo => :bar}
24
- lambda{transformer_class.new.transform(message)}.should raise_error NotImplementedError
25
- end
26
-
27
- it "can transform the message" do
28
- class Autobot < Batsir::Transformers::Transformer
29
- def execute(message)
30
- message = "transform"
31
- end
32
- end
33
- message = {:foo => :bar}
34
- Autobot.new.transform(message).should == "transform"
35
- end
36
- end
data/spec/spec_helper.rb DELETED
@@ -1,26 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rspec/core'
11
-
12
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
- $LOAD_PATH.unshift(File.dirname(__FILE__))
14
-
15
- require 'batsir'
16
- require 'batsir/support/mock_filters'
17
- require 'batsir/support/bunny_mocks'
18
- Celluloid.logger.level = Logger::ERROR
19
- RSpec.configure do |config|
20
- config.before(:each) do
21
- Celluloid.boot
22
- end
23
- # config.after(:each) do
24
- # Celluloid.shutdown
25
- # end
26
- end