ruby_ami 1.0.1 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -3,10 +3,10 @@ rvm:
3
3
  - 1.9.2
4
4
  - 1.9.3
5
5
  - jruby-19mode
6
- - rbx-19mode
6
+ # - rbx-19mode
7
7
  - ruby-head
8
8
  before_install:
9
- - wget http://ftp.us.debian.org/debian/pool/main/r/ragel/ragel_6.7-1_i386.deb
10
- - sudo dpkg -i ragel_6.7-1_i386.deb
9
+ - wget http://ftp.us.debian.org/debian/pool/main/r/ragel/ragel_6.7-1.1_i386.deb
10
+ - sudo dpkg -i ragel_6.7-1.1_i386.deb
11
11
  notifications:
12
12
  irc: "irc.freenode.org#adhearsion"
data/CHANGELOG.md CHANGED
@@ -1,4 +1,10 @@
1
- # develop
1
+ # [develop](https://github.com/adhearsion/ruby_ami)
2
+
3
+ # [1.1.1](https://github.com/adhearsion/ruby_ami/compare/v1.1.0...v1.1.1) - [2012-06-25](https://rubygems.org/gems/ruby_ami/versions/1.1.1)
4
+ * v1.1.0 re-released with fixed celluloid-io dependency
5
+
6
+ # [1.1.0](https://github.com/adhearsion/ruby_ami/compare/v1.0.1...v1.1.0) - [2012-06-16](https://rubygems.org/gems/ruby_ami/versions/1.1.0)
7
+ * Change: Switch from EventMachine to Celluloid & CelluloidIO for better JRuby compatability and performance (action and events connections are now in separate threads)
2
8
 
3
9
  # 1.0.1 - 2012-04-25
4
10
  * Bugfix: Actions which do not receive a response within 10s will allow further actions to be executed. Synchronous originate has a 60s timeout.
data/lib/ruby_ami.rb CHANGED
@@ -1,18 +1,10 @@
1
1
  %w{
2
- active_support/dependencies/autoload
3
- active_support/core_ext/object/blank
4
- active_support/core_ext/numeric/time
5
- active_support/core_ext/numeric/bytes
6
- active_support/hash_with_indifferent_access
7
-
8
2
  uuidtools
9
- eventmachine
10
3
  future-resource
11
4
  logger
12
5
  girl_friday
13
6
  countdownlatch
14
-
15
- ruby_ami/metaprogramming
7
+ celluloid/io
16
8
  }.each { |f| require f }
17
9
 
18
10
  class Logger
@@ -20,14 +12,16 @@ class Logger
20
12
  end
21
13
 
22
14
  module RubyAMI
23
- extend ActiveSupport::Autoload
24
-
25
- autoload :Action
26
- autoload :Client
27
- autoload :Error
28
- autoload :Event
29
- autoload :Lexer
30
- autoload :Response
31
- autoload :Stream
32
- autoload :Version
33
15
  end
16
+
17
+ %w{
18
+ action
19
+ client
20
+ error
21
+ event
22
+ lexer
23
+ metaprogramming
24
+ response
25
+ stream
26
+ version
27
+ }.each { |f| require "ruby_ami/#{f}" }
@@ -9,7 +9,7 @@ module RubyAMI
9
9
 
10
10
  def initialize(name, headers = {}, &block)
11
11
  @name = name.to_s.downcase.freeze
12
- @headers = headers.stringify_keys.freeze
12
+ @headers = headers.freeze
13
13
  @action_id = UUIDTools::UUID.random_create.to_s
14
14
  @response = FutureResource.new
15
15
  @response_callback = block
@@ -121,7 +121,7 @@ module RubyAMI
121
121
  alias :== :eql?
122
122
 
123
123
  def sync_timeout
124
- name.downcase == 'originate' && !headers['async'] ? 60 : 10
124
+ name.downcase == 'originate' && !headers[:async] ? 60 : 10
125
125
  end
126
126
 
127
127
  ##
@@ -41,16 +41,20 @@ module RubyAMI
41
41
  end
42
42
 
43
43
  def start
44
- EventMachine.run do
45
- yield if block_given?
46
- @events_stream = start_stream lambda { |event| @event_processor << event }
47
- @actions_stream = start_stream lambda { |message| @message_processor << message }
48
- @state = :started
49
- end
44
+ @events_stream = start_stream lambda { |event| @event_processor << event }
45
+ @actions_stream = start_stream lambda { |message| @message_processor << message }
46
+ @state = :started
47
+ streams.each(&:join)
50
48
  end
51
49
 
52
50
  def stop
53
- streams.each { |s| s.close_connection_after_writing }
51
+ streams.each do |stream|
52
+ begin
53
+ stream.terminate
54
+ rescue => e
55
+ logger.error e if logger
56
+ end
57
+ end
54
58
  end
55
59
 
56
60
  def send_action(action, headers = {}, &block)
@@ -68,7 +72,7 @@ module RubyAMI
68
72
  login_actions
69
73
  when Stream::Disconnected
70
74
  stop_writing_actions
71
- unbind
75
+ stop
72
76
  when Event
73
77
  action = @current_action_with_causal_events
74
78
  if action
@@ -103,7 +107,7 @@ module RubyAMI
103
107
  when Stream::Connected
104
108
  login_events
105
109
  when Stream::Disconnected
106
- unbind
110
+ stop
107
111
  else
108
112
  pass_event event
109
113
  end
@@ -117,10 +121,6 @@ module RubyAMI
117
121
  action
118
122
  end
119
123
 
120
- def unbind
121
- EM.reactor_running? && EM.stop
122
- end
123
-
124
124
  private
125
125
 
126
126
  def pass_event(event)
@@ -179,7 +179,7 @@ module RubyAMI
179
179
  end
180
180
 
181
181
  def start_stream(callback)
182
- Stream.start @options[:host], @options[:port], callback
182
+ Stream.new @options[:host], @options[:port], callback
183
183
  end
184
184
 
185
185
  def logger
@@ -3,7 +3,7 @@ module RubyAMI
3
3
  attr_accessor :message, :action
4
4
 
5
5
  def initialize
6
- @headers = HashWithIndifferentAccess.new
6
+ @headers = Hash.new
7
7
  end
8
8
 
9
9
  def [](key)
@@ -1,3 +1,5 @@
1
+ require 'ruby_ami/response'
2
+
1
3
  module RubyAMI
2
4
  class Event < Response
3
5
  attr_reader :name
@@ -6,5 +8,9 @@ module RubyAMI
6
8
  super()
7
9
  @name = name
8
10
  end
11
+
12
+ def inspect_attributes
13
+ [:name] + super
14
+ end
9
15
  end
10
16
  end # RubyAMI
@@ -1,7 +1,8 @@
1
1
  module RubyAMI
2
2
  class Lexer
3
3
 
4
- BUFFER_SIZE = 128.kilobytes unless defined? BUFFER_SIZE
4
+ KILOBYTE = 1024
5
+ BUFFER_SIZE = 128 * KILOBYTE unless defined? BUFFER_SIZE
5
6
 
6
7
  ##
7
8
  # IMPORTANT! See method documentation for adjust_pointers!
@@ -18,7 +18,7 @@ module RubyAMI
18
18
  attr_reader :events
19
19
 
20
20
  def initialize
21
- @headers = HashWithIndifferentAccess.new
21
+ @headers = Hash.new
22
22
  end
23
23
 
24
24
  def has_text_body?
@@ -30,15 +30,28 @@ module RubyAMI
30
30
  end
31
31
 
32
32
  def [](arg)
33
- @headers[arg]
33
+ @headers[arg.to_s]
34
34
  end
35
35
 
36
36
  def []=(key,value)
37
- @headers[key] = value
37
+ @headers[key.to_s] = value
38
38
  end
39
39
 
40
40
  def action_id
41
41
  @headers['ActionID']
42
42
  end
43
+
44
+ def inspect
45
+ "#<#{self.class} #{inspect_attributes.map { |c| "#{c}=#{self.__send__(c).inspect rescue nil}" }.compact * ', '}>"
46
+ end
47
+
48
+ def inspect_attributes
49
+ [:headers, :text_body, :events, :action]
50
+ end
51
+
52
+ def eql?(o, *fields)
53
+ o.is_a?(self.class) && (fields + inspect_attributes).all? { |f| self.__send__(f) == o.__send__(f) }
54
+ end
55
+ alias :== :eql?
43
56
  end
44
57
  end # RubyAMI
@@ -1,5 +1,5 @@
1
1
  module RubyAMI
2
- class Stream < EventMachine::Connection
2
+ class Stream
3
3
  class ConnectionStatus
4
4
  def eql?(other)
5
5
  other.is_a? self.class
@@ -11,50 +11,64 @@ module RubyAMI
11
11
  Connected = Class.new ConnectionStatus
12
12
  Disconnected = Class.new ConnectionStatus
13
13
 
14
- def self.start(host, port, event_callback)
15
- EM.connect host, port, self, event_callback
16
- end
14
+ include Celluloid::IO
17
15
 
18
- def initialize(event_callback)
16
+ def initialize(host, port, event_callback)
19
17
  super()
20
18
  @event_callback = event_callback
21
- @logger = Logger.new($stdout)
22
- @logger.level = Logger::FATAL
23
- @logger.debug "Starting up..."
19
+ logger.debug "Starting up..."
24
20
  @lexer = Lexer.new self
21
+ @socket = TCPSocket.from_ruby_socket ::TCPSocket.new(host, port)
22
+ post_init
23
+ run!
25
24
  end
26
25
 
27
26
  [:started, :stopped, :ready].each do |state|
28
27
  define_method("#{state}?") { @state == state }
29
28
  end
30
29
 
30
+ def run
31
+ loop { receive_data @socket.readpartial(4096) }
32
+ rescue EOFError
33
+ logger.info "Client socket closed!"
34
+ current_actor.terminate!
35
+ end
36
+
31
37
  def post_init
32
38
  @state = :started
33
39
  @event_callback.call Connected.new
34
40
  end
35
41
 
42
+ def send_data(data)
43
+ @socket.write data
44
+ end
45
+
36
46
  def send_action(action)
37
- @logger.debug "[SEND] #{action.to_s}"
47
+ logger.debug "[SEND] #{action.to_s}"
38
48
  send_data action.to_s
39
49
  end
40
50
 
41
51
  def receive_data(data)
42
- @logger.debug "[RECV] #{data}"
52
+ logger.debug "[RECV] #{data}"
43
53
  @lexer << data
44
54
  end
45
55
 
46
56
  def message_received(message)
47
- @logger.debug "[RECV] #{message.inspect}"
57
+ logger.debug "[RECV] #{message.inspect}"
48
58
  @event_callback.call message
49
59
  end
50
60
 
51
61
  alias :error_received :message_received
52
62
 
53
- # Called by EM when the connection is closed
54
- # @private
55
- def unbind
63
+ def finalize
64
+ logger.debug "Finalizing stream"
65
+ @socket.close if @socket
56
66
  @state = :stopped
57
67
  @event_callback.call Disconnected.new
58
68
  end
69
+
70
+ def logger
71
+ Logger
72
+ end
59
73
  end
60
74
  end
@@ -1,3 +1,3 @@
1
1
  module RubyAMI
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.1"
3
3
  end
data/ruby_ami.gemspec CHANGED
@@ -18,13 +18,11 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.add_runtime_dependency %q<activesupport>, ["~> 3.0"]
22
21
  s.add_runtime_dependency %q<uuidtools>, [">= 0"]
23
- s.add_runtime_dependency %q<eventmachine>, [">= 0"]
22
+ s.add_runtime_dependency %q<celluloid-io>, ["~> 0.11.0"]
24
23
  s.add_runtime_dependency %q<future-resource>, [">= 0"]
25
24
  s.add_runtime_dependency %q<girl_friday>, [">= 0"]
26
25
  s.add_runtime_dependency %q<countdownlatch>, ["~> 1.0"]
27
- s.add_runtime_dependency %q<i18n>, [">= 0"]
28
26
 
29
27
  s.add_development_dependency %q<bundler>, ["~> 1.0"]
30
28
  s.add_development_dependency %q<rspec>, [">= 2.5.0"]
@@ -26,11 +26,11 @@ module RubyAMI
26
26
 
27
27
  describe 'starting up' do
28
28
  before do
29
- MockServer.any_instance.stubs :receive_data
30
- subject.start do
31
- EM.start_server options[:host], options[:port], ServerMock
32
- EM.add_timer(0.5) { EM.stop if EM.reactor_running? }
33
- end
29
+ ms = MockServer.new
30
+ ms.expects(:receive_data).at_least_once
31
+ s = ServerMock.new options[:host], options[:port], ms
32
+ Thread.new { subject.start }
33
+ sleep 0.2
34
34
  end
35
35
 
36
36
  it { should be_started }
@@ -89,8 +89,8 @@ module RubyAMI
89
89
  end
90
90
 
91
91
  describe 'when the events stream disconnects' do
92
- it 'should unbind' do
93
- subject.expects(:unbind).once
92
+ it 'should stop' do
93
+ subject.expects(:stop).once
94
94
  subject.handle_event Stream::Disconnected.new
95
95
  event_handler.should be_empty
96
96
  end
@@ -117,8 +117,8 @@ module RubyAMI
117
117
  action.should be_new
118
118
  end
119
119
 
120
- it 'should unbind' do
121
- subject.expects(:unbind).once
120
+ it 'should stop' do
121
+ subject.expects(:stop).once
122
122
  subject.handle_message Stream::Disconnected.new
123
123
  end
124
124
  end
@@ -340,27 +340,9 @@ module RubyAMI
340
340
  end
341
341
 
342
342
  it 'should close both streams' do
343
- streams.each { |s| s.expects :close_connection_after_writing }
343
+ streams.each { |s| s.expects :terminate }
344
344
  subject.stop
345
345
  end
346
346
  end
347
-
348
- describe '#unbind' do
349
- context 'if EM is running' do
350
- it 'shuts down EM' do
351
- EM.expects(:reactor_running?).returns true
352
- EM.expects(:stop)
353
- subject.unbind
354
- end
355
- end
356
-
357
- context 'if EM is not running' do
358
- it 'does nothing' do
359
- EM.expects(:reactor_running?).returns false
360
- EM.expects(:stop).never
361
- subject.unbind
362
- end
363
- end
364
- end
365
347
  end
366
348
  end
@@ -2,6 +2,72 @@ require 'spec_helper'
2
2
 
3
3
  module RubyAMI
4
4
  describe Event do
5
- pending
5
+ describe "equality" do
6
+ context "with the same name and the same headers" do
7
+ let :event1 do
8
+ Event.new('Hangup').tap do |e|
9
+ e['Channel'] = 'SIP/101-3f3f'
10
+ e['Uniqueid'] = '1094154427.10'
11
+ e['Cause'] = '0'
12
+ end
13
+ end
14
+
15
+ let :event2 do
16
+ Event.new('Hangup').tap do |e|
17
+ e['Channel'] = 'SIP/101-3f3f'
18
+ e['Uniqueid'] = '1094154427.10'
19
+ e['Cause'] = '0'
20
+ end
21
+ end
22
+
23
+ it "should be equal" do
24
+ event1.should be == event2
25
+ end
26
+ end
27
+
28
+ context "with a different name and the same headers" do
29
+ let :event1 do
30
+ Event.new('Hangup').tap do |e|
31
+ e['Channel'] = 'SIP/101-3f3f'
32
+ e['Uniqueid'] = '1094154427.10'
33
+ e['Cause'] = '0'
34
+ end
35
+ end
36
+
37
+ let :event2 do
38
+ Event.new('Foo').tap do |e|
39
+ e['Channel'] = 'SIP/101-3f3f'
40
+ e['Uniqueid'] = '1094154427.10'
41
+ e['Cause'] = '0'
42
+ end
43
+ end
44
+
45
+ it "should not be equal" do
46
+ event1.should_not be == event2
47
+ end
48
+ end
49
+
50
+ context "with the same name and different headers" do
51
+ let :event1 do
52
+ Event.new('Hangup').tap do |e|
53
+ e['Channel'] = 'SIP/101-3f3f'
54
+ e['Uniqueid'] = '1094154427.10'
55
+ e['Cause'] = '0'
56
+ end
57
+ end
58
+
59
+ let :event2 do
60
+ Event.new('Hangup').tap do |e|
61
+ e['Channel'] = 'SIP/101-3f3f'
62
+ e['Uniqueid'] = '1094154427.10'
63
+ e['Cause'] = '1'
64
+ end
65
+ end
66
+
67
+ it "should not be equal" do
68
+ event1.should_not be == event2
69
+ end
70
+ end
71
+ end
6
72
  end # Event
7
73
  end # RubyAMI
@@ -2,6 +2,50 @@ require 'spec_helper'
2
2
 
3
3
  module RubyAMI
4
4
  describe Response do
5
- pending
5
+ describe "equality" do
6
+ context "with the same headers" do
7
+ let :event1 do
8
+ Response.new.tap do |e|
9
+ e['Channel'] = 'SIP/101-3f3f'
10
+ e['Uniqueid'] = '1094154427.10'
11
+ e['Cause'] = '0'
12
+ end
13
+ end
14
+
15
+ let :event2 do
16
+ Response.new.tap do |e|
17
+ e['Channel'] = 'SIP/101-3f3f'
18
+ e['Uniqueid'] = '1094154427.10'
19
+ e['Cause'] = '0'
20
+ end
21
+ end
22
+
23
+ it "should be equal" do
24
+ event1.should be == event2
25
+ end
26
+ end
27
+
28
+ context "with different headers" do
29
+ let :event1 do
30
+ Response.new.tap do |e|
31
+ e['Channel'] = 'SIP/101-3f3f'
32
+ e['Uniqueid'] = '1094154427.10'
33
+ e['Cause'] = '0'
34
+ end
35
+ end
36
+
37
+ let :event2 do
38
+ Response.new.tap do |e|
39
+ e['Channel'] = 'SIP/101-3f3f'
40
+ e['Uniqueid'] = '1094154427.10'
41
+ e['Cause'] = '1'
42
+ end
43
+ end
44
+
45
+ it "should not be equal" do
46
+ event1.should_not be == event2
47
+ end
48
+ end
49
+ end
6
50
  end # Response
7
51
  end # RubyAMI
@@ -2,21 +2,33 @@ require 'spec_helper'
2
2
 
3
3
  module RubyAMI
4
4
  describe Stream do
5
- def mocked_server(times = nil, fake_client = nil, &block)
6
- MockServer.any_instance.expects(:receive_data).send(*(times ? [:times, times] : [:at_least, 1])).with &block
7
- EventMachine::run {
8
- EM.add_timer(0.5) { EM.stop if EM.reactor_running? }
5
+ let(:server_port) { 50000 - rand(1000) }
9
6
 
10
- port = 50000 - rand(1000)
7
+ before do
8
+ def client.message_received(message)
9
+ @messages ||= Queue.new
10
+ @messages << message
11
+ end
11
12
 
12
- # Mocked server
13
- EventMachine::start_server '127.0.0.1', port, ServerMock
13
+ def client.messages
14
+ @messages
15
+ end
16
+ end
14
17
 
15
- # Stream connection
16
- EM.connect('127.0.0.1', port, Stream, lambda { |m| client.message_received m }) {|c| @stream = c}
18
+ let :client_messages do
19
+ messages = []
20
+ messages << client.messages.pop until client.messages.empty?
21
+ messages
22
+ end
17
23
 
18
- fake_client.call if fake_client.respond_to? :call
19
- }
24
+ def mocked_server(times = nil, fake_client = nil, &block)
25
+ mock_target = MockServer.new
26
+ mock_target.expects(:receive_data).send(*(times ? [:times, times] : [:at_least, 1])).with &block
27
+ s = ServerMock.new '127.0.0.1', server_port, mock_target
28
+ @stream = Stream.new '127.0.0.1', server_port, lambda { |m| client.message_received m }
29
+ fake_client.call if fake_client.respond_to? :call
30
+ s.join
31
+ @stream.join
20
32
  end
21
33
 
22
34
  def expect_connected_event
@@ -29,22 +41,11 @@ module RubyAMI
29
41
 
30
42
  before { @sequence = 1 }
31
43
 
32
- it 'can be started' do
33
- EM.expects(:connect).with do |*params|
34
- params[0].should == 'example.com'
35
- params[1].should == 1234
36
- params[2].should == Stream
37
- params[3].should be_a Proc
38
- end
39
-
40
- Stream.start 'example.com', 1234, lambda {}
41
- end
42
-
43
44
  describe "after connection" do
44
45
  it "should be started" do
45
46
  expect_connected_event
46
47
  expect_disconnected_event
47
- mocked_server(1, lambda { @stream.send_data 'Foo' }) do |val, server|
48
+ mocked_server(0) do |val, server|
48
49
  @stream.started?.should be_true
49
50
  end
50
51
  end
@@ -60,23 +61,6 @@ module RubyAMI
60
61
  end
61
62
 
62
63
  it 'sends events to the client when the stream is ready' do
63
- client.expects(:message_received).times(3).with do |e|
64
- case @sequence
65
- when 1
66
- e.should be_a Stream::Connected
67
- when 2
68
- EM.stop
69
- e.should be_a Event
70
- e.name.should == 'Hangup'
71
- e['Channel'].should == 'SIP/101-3f3f'
72
- e['Uniqueid'].should == '1094154427.10'
73
- e['Cause'].should == '0'
74
- when 3
75
- e.should be_a Stream::Disconnected
76
- end
77
- @sequence += 1
78
- end
79
-
80
64
  mocked_server(1, lambda { @stream.send_data 'Foo' }) do |val, server|
81
65
  server.send_data <<-EVENT
82
66
  Event: Hangup
@@ -86,24 +70,19 @@ Cause: 0
86
70
 
87
71
  EVENT
88
72
  end
73
+
74
+ client_messages.should be == [
75
+ Stream::Connected.new,
76
+ Event.new('Hangup').tap do |e|
77
+ e['Channel'] = 'SIP/101-3f3f'
78
+ e['Uniqueid'] = '1094154427.10'
79
+ e['Cause'] = '0'
80
+ end,
81
+ Stream::Disconnected.new
82
+ ]
89
83
  end
90
84
 
91
85
  it 'sends responses to the client when the stream is ready' do
92
- client.expects(:message_received).times(3).with do |r|
93
- case @sequence
94
- when 1
95
- r.should be_a Stream::Connected
96
- when 2
97
- EM.stop
98
- r.should be_a Response
99
- r['ActionID'].should == 'ee33eru2398fjj290'
100
- r['Message'].should == 'Authentication accepted'
101
- when 3
102
- r.should be_a Stream::Disconnected
103
- end
104
- @sequence += 1
105
- end
106
-
107
86
  mocked_server(1, lambda { @stream.send_data 'Foo' }) do |val, server|
108
87
  server.send_data <<-EVENT
109
88
  Response: Success
@@ -112,6 +91,15 @@ Message: Authentication accepted
112
91
 
113
92
  EVENT
114
93
  end
94
+
95
+ client_messages.should be == [
96
+ Stream::Connected.new,
97
+ Response.new.tap do |r|
98
+ r['ActionID'] = 'ee33eru2398fjj290'
99
+ r['Message'] = 'Authentication accepted'
100
+ end,
101
+ Stream::Disconnected.new
102
+ ]
115
103
  end
116
104
 
117
105
  it 'sends error to the client when the stream is ready and a bad command was send' do
@@ -120,7 +108,6 @@ Message: Authentication accepted
120
108
  when 1
121
109
  r.should be_a Stream::Connected
122
110
  when 2
123
- EM.stop
124
111
  r.should be_a Error
125
112
  r['ActionID'].should == 'ee33eru2398fjj290'
126
113
  r['Message'].should == 'You stupid git'
@@ -144,10 +131,9 @@ Message: You stupid git
144
131
  expect_connected_event
145
132
  expect_disconnected_event
146
133
  mocked_server(1, lambda { @stream.send_data 'Foo' }) do |val, server|
147
- EM.stop
148
134
  @stream.stopped?.should be false
149
135
  end
150
- @stream.stopped?.should be true
136
+ @stream.alive?.should be false
151
137
  end
152
138
  end
153
139
  end
@@ -1,13 +1,41 @@
1
1
  MockServer = Class.new
2
2
 
3
- module ServerMock
3
+ class ServerMock
4
+ include Celluloid::IO
5
+
6
+ def initialize(host, port, mock_target = MockServer.new)
7
+ puts "*** Starting echo server on #{host}:#{port}"
8
+ @server = TCPServer.new host, port
9
+ @mock_target = mock_target
10
+ @clients = []
11
+ run!
12
+ end
13
+
14
+ def finalize
15
+ Logger.debug "ServerMock finalizing"
16
+ @server.close if @server
17
+ @clients.each(&:close)
18
+ end
19
+
20
+ def run
21
+ after(0.5) { terminate }
22
+ loop { handle_connection! @server.accept }
23
+ end
24
+
25
+ def handle_connection(socket)
26
+ @clients << socket
27
+ _, port, host = socket.peeraddr
28
+ puts "*** Received connection from #{host}:#{port}"
29
+ loop { receive_data socket.readpartial(4096) }
30
+ end
31
+
4
32
  def receive_data(data)
5
- @server ||= MockServer.new
6
- @server.receive_data data, self
33
+ Logger.debug "ServerMock receiving data: #{data}"
34
+ @mock_target.receive_data data, self
7
35
  end
8
36
 
9
37
  def send_data(data)
10
- super data.gsub("\n", "\r\n")
38
+ @clients.each { |client| client.write data.gsub("\n", "\r\n") }
11
39
  end
12
40
  end
13
41
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_ami
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,24 +9,8 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-25 00:00:00.000000000 Z
12
+ date: 2012-06-25 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: activesupport
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: '3.0'
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- version: '3.0'
30
14
  - !ruby/object:Gem::Dependency
31
15
  name: uuidtools
32
16
  requirement: !ruby/object:Gem::Requirement
@@ -44,21 +28,21 @@ dependencies:
44
28
  - !ruby/object:Gem::Version
45
29
  version: '0'
46
30
  - !ruby/object:Gem::Dependency
47
- name: eventmachine
31
+ name: celluloid-io
48
32
  requirement: !ruby/object:Gem::Requirement
49
33
  none: false
50
34
  requirements:
51
- - - ! '>='
35
+ - - ~>
52
36
  - !ruby/object:Gem::Version
53
- version: '0'
37
+ version: 0.11.0
54
38
  type: :runtime
55
39
  prerelease: false
56
40
  version_requirements: !ruby/object:Gem::Requirement
57
41
  none: false
58
42
  requirements:
59
- - - ! '>='
43
+ - - ~>
60
44
  - !ruby/object:Gem::Version
61
- version: '0'
45
+ version: 0.11.0
62
46
  - !ruby/object:Gem::Dependency
63
47
  name: future-resource
64
48
  requirement: !ruby/object:Gem::Requirement
@@ -107,22 +91,6 @@ dependencies:
107
91
  - - ~>
108
92
  - !ruby/object:Gem::Version
109
93
  version: '1.0'
110
- - !ruby/object:Gem::Dependency
111
- name: i18n
112
- requirement: !ruby/object:Gem::Requirement
113
- none: false
114
- requirements:
115
- - - ! '>='
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :runtime
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
- requirements:
123
- - - ! '>='
124
- - !ruby/object:Gem::Version
125
- version: '0'
126
94
  - !ruby/object:Gem::Dependency
127
95
  name: bundler
128
96
  requirement: !ruby/object:Gem::Requirement
@@ -324,7 +292,6 @@ files:
324
292
  - features/support/introspective_lexer.rb
325
293
  - features/support/lexer_helper.rb
326
294
  - lib/ruby_ami.rb
327
- - lib/ruby_ami/Guardfile
328
295
  - lib/ruby_ami/action.rb
329
296
  - lib/ruby_ami/client.rb
330
297
  - lib/ruby_ami/error.rb
@@ -359,7 +326,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
359
326
  version: '0'
360
327
  segments:
361
328
  - 0
362
- hash: -2979332282969643621
329
+ hash: 3703213424052847614
363
330
  required_rubygems_version: !ruby/object:Gem::Requirement
364
331
  none: false
365
332
  requirements:
@@ -368,10 +335,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
368
335
  version: '0'
369
336
  segments:
370
337
  - 0
371
- hash: -2979332282969643621
338
+ hash: 3703213424052847614
372
339
  requirements: []
373
340
  rubyforge_project: ruby_ami
374
- rubygems_version: 1.8.21
341
+ rubygems_version: 1.8.24
375
342
  signing_key:
376
343
  specification_version: 3
377
344
  summary: Futzing with AMI so you don't have to
@@ -1,6 +0,0 @@
1
- ENV['SKIP_RCOV'] = 'true'
2
- guard 'rspec', :version => 2, :cli => '--format documentation' do
3
- watch(%r{^spec/.+_spec\.rb$})
4
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
5
- watch('spec/spec_helper.rb') { "spec/" }
6
- end