batsir 0.3.7.1 → 0.4.0

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