alondra 0.0.3

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 (117) hide show
  1. data/.gitignore +9 -0
  2. data/Gemfile +22 -0
  3. data/Gemfile.lock +166 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +177 -0
  6. data/Rakefile +34 -0
  7. data/alondra.gemspec +23 -0
  8. data/app/assets/javascripts/alondra-client.js.coffee.erb +71 -0
  9. data/app/assets/javascripts/moz_websocket.js +5 -0
  10. data/app/assets/javascripts/vendor/jquery.json-2.2.js +178 -0
  11. data/app/assets/javascripts/vendor/json2.js +480 -0
  12. data/app/assets/javascripts/vendor/swfobject.js +4 -0
  13. data/app/assets/javascripts/vendor/web_socket.js +379 -0
  14. data/app/assets/swf/WebSocketMain.swf +0 -0
  15. data/app/helpers/alondra_helper.rb +24 -0
  16. data/lib/alondra/changes_callbacks.rb +52 -0
  17. data/lib/alondra/changes_push.rb +23 -0
  18. data/lib/alondra/channel.rb +84 -0
  19. data/lib/alondra/command.rb +38 -0
  20. data/lib/alondra/command_dispatcher.rb +22 -0
  21. data/lib/alondra/connection.rb +52 -0
  22. data/lib/alondra/event.rb +74 -0
  23. data/lib/alondra/event_listener.rb +86 -0
  24. data/lib/alondra/event_router.rb +27 -0
  25. data/lib/alondra/listener_callback.rb +37 -0
  26. data/lib/alondra/message.rb +35 -0
  27. data/lib/alondra/message_queue.rb +70 -0
  28. data/lib/alondra/message_queue_client.rb +71 -0
  29. data/lib/alondra/push_controller.rb +53 -0
  30. data/lib/alondra/pushing.rb +14 -0
  31. data/lib/alondra/server.rb +44 -0
  32. data/lib/alondra/session_parser.rb +57 -0
  33. data/lib/alondra.rb +80 -0
  34. data/lib/generators/alondra/USAGE +8 -0
  35. data/lib/generators/alondra/alondra_generator.rb +7 -0
  36. data/lib/generators/alondra/templates/alondra +33 -0
  37. data/lib/tasks/alondra_tasks.rake +4 -0
  38. data/script/rails +6 -0
  39. data/test/dummy/Rakefile +7 -0
  40. data/test/dummy/app/assets/javascripts/application.js +9 -0
  41. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  42. data/test/dummy/app/controllers/application_controller.rb +14 -0
  43. data/test/dummy/app/controllers/chats_controller.rb +85 -0
  44. data/test/dummy/app/controllers/messages_controller.rb +12 -0
  45. data/test/dummy/app/controllers/sessions_controller.rb +20 -0
  46. data/test/dummy/app/controllers/users_controller.rb +30 -0
  47. data/test/dummy/app/helpers/application_helper.rb +2 -0
  48. data/test/dummy/app/helpers/chats_helper.rb +6 -0
  49. data/test/dummy/app/helpers/error_messages_helper.rb +23 -0
  50. data/test/dummy/app/helpers/layout_helper.rb +22 -0
  51. data/test/dummy/app/mailers/.gitkeep +0 -0
  52. data/test/dummy/app/models/.gitkeep +0 -0
  53. data/test/dummy/app/models/chat.rb +5 -0
  54. data/test/dummy/app/models/message.rb +4 -0
  55. data/test/dummy/app/models/user.rb +37 -0
  56. data/test/dummy/app/views/chats/_form.html.erb +21 -0
  57. data/test/dummy/app/views/chats/edit.html.erb +6 -0
  58. data/test/dummy/app/views/chats/index.html.erb +23 -0
  59. data/test/dummy/app/views/chats/new.html.erb +5 -0
  60. data/test/dummy/app/views/chats/show.html.erb +49 -0
  61. data/test/dummy/app/views/layouts/application.html.erb +19 -0
  62. data/test/dummy/app/views/sessions/new.html.erb +15 -0
  63. data/test/dummy/app/views/shared/_message.js.erb +1 -0
  64. data/test/dummy/app/views/users/_form.html.erb +20 -0
  65. data/test/dummy/app/views/users/edit.html.erb +3 -0
  66. data/test/dummy/app/views/users/index.html.erb +25 -0
  67. data/test/dummy/app/views/users/new.html.erb +5 -0
  68. data/test/dummy/app/views/users/show.html.erb +15 -0
  69. data/test/dummy/config/application.rb +42 -0
  70. data/test/dummy/config/boot.rb +10 -0
  71. data/test/dummy/config/database.yml +31 -0
  72. data/test/dummy/config/environment.rb +5 -0
  73. data/test/dummy/config/environments/development.rb +27 -0
  74. data/test/dummy/config/environments/production.rb +54 -0
  75. data/test/dummy/config/environments/test.rb +39 -0
  76. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  77. data/test/dummy/config/initializers/inflections.rb +10 -0
  78. data/test/dummy/config/initializers/mime_types.rb +5 -0
  79. data/test/dummy/config/initializers/secret_token.rb +7 -0
  80. data/test/dummy/config/initializers/session_store.rb +9 -0
  81. data/test/dummy/config/initializers/wrap_parameters.rb +12 -0
  82. data/test/dummy/config/locales/en.yml +5 -0
  83. data/test/dummy/config/routes.rb +19 -0
  84. data/test/dummy/config.ru +4 -0
  85. data/test/dummy/db/migrate/20110719090458_create_chats.rb +9 -0
  86. data/test/dummy/db/migrate/20110719090538_create_messages.rb +10 -0
  87. data/test/dummy/db/migrate/20110720193249_create_users.rb +16 -0
  88. data/test/dummy/db/schema.rb +38 -0
  89. data/test/dummy/lib/controller_authentication.rb +48 -0
  90. data/test/dummy/log/.gitkeep +0 -0
  91. data/test/dummy/public/404.html +26 -0
  92. data/test/dummy/public/422.html +26 -0
  93. data/test/dummy/public/500.html +26 -0
  94. data/test/dummy/public/favicon.ico +0 -0
  95. data/test/dummy/public/stylesheets/application.css +75 -0
  96. data/test/dummy/script/rails +6 -0
  97. data/test/integration/push_changes_test.rb +41 -0
  98. data/test/integration/push_messages_test.rb +40 -0
  99. data/test/models/channel_test.rb +49 -0
  100. data/test/models/command_test.rb +29 -0
  101. data/test/models/configuration_test.rb +22 -0
  102. data/test/models/connection_test.rb +18 -0
  103. data/test/models/event_listener_test.rb +217 -0
  104. data/test/models/event_router_test.rb +7 -0
  105. data/test/models/message_queue_client_test.rb +26 -0
  106. data/test/models/message_queue_test.rb +70 -0
  107. data/test/models/pushing_test.rb +34 -0
  108. data/test/performance/message_queue_performance.rb +66 -0
  109. data/test/support/factories.rb +19 -0
  110. data/test/support/integration_helper.rb +18 -0
  111. data/test/support/integration_test.rb +6 -0
  112. data/test/support/mocks/bogus_event.rb +15 -0
  113. data/test/support/mocks/mock_connection.rb +24 -0
  114. data/test/support/mocks/mock_event_router.rb +12 -0
  115. data/test/support/mocks/mock_listener.rb +9 -0
  116. data/test/test_helper.rb +14 -0
  117. metadata +316 -0
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ module Alondra
4
+
5
+ class ChannelTest < ActiveSupport::TestCase
6
+
7
+ def setup
8
+ @connection = MockConnection.new
9
+ end
10
+
11
+ test "it has a name" do
12
+ channel = Channel.new('test name channel')
13
+ assert_equal 'test name channel', channel.name
14
+ end
15
+
16
+ test "can fetch channel by name" do
17
+ channel = Channel['dummy channel']
18
+ assert_equal 'dummy channel', channel.name
19
+ end
20
+
21
+ test "allow clients to subscribe" do
22
+ channel = Channel.new('test subscriptions channel')
23
+ assert_equal 0, channel.connections.size
24
+
25
+ channel.subscribe @connection
26
+
27
+ assert_equal 1, channel.connections.size
28
+ assert channel.connections.keys.include? @connection
29
+ end
30
+
31
+ test "deliver events to all subscribed connections" do
32
+ channel = Channel.new('test deliver events channel')
33
+ channel.subscribe @connection
34
+
35
+ assert @connection.channels.include?(channel)
36
+
37
+ event = Event.new :event => :created, :resource => Chat.new, :channel => 'test deliver events channel'
38
+
39
+ channel.receive event
40
+
41
+ assert EM.reactor_running?
42
+
43
+ sleep(0.5) # Leave event machine to catch up
44
+
45
+ last_message = @connection.messages.last
46
+ assert_equal event.to_json, last_message
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,29 @@
1
+ require 'test_helper'
2
+
3
+ module Alondra
4
+
5
+ class CommandTest < ActiveSupport::TestCase
6
+
7
+ def setup
8
+ @connection = MockConnection.new
9
+ end
10
+
11
+ test "it is created with a connection and a hash" do
12
+ command = Command.new @connection, :command => 'subscribe', :channel => 'test'
13
+
14
+ assert_equal :subscribe, command.name
15
+ assert_equal 'test', command.channel.name
16
+ end
17
+
18
+ test "subscribe to channel when subscribe command is executed" do
19
+ channel = Channel['test']
20
+ assert_equal 0, channel.connections.size
21
+
22
+ command = Command.new @connection, :command => 'subscribe', :channel => 'test'
23
+ command.execute!
24
+
25
+ assert_equal 1, channel.connections.size
26
+ assert channel.connections.keys.include? @connection
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ module Alondra
4
+
5
+ class ConfigurationTest < ActiveSupport::TestCase
6
+
7
+ test "it has default values" do
8
+ assert_equal 12346, Alondra.config.port
9
+ end
10
+
11
+ test "it allows to override default values" do
12
+ assert_equal 'localhost', Alondra.config.host
13
+ Alondra.config.host = 'www.example.com'
14
+ assert_equal 'www.example.com', Alondra.config.host
15
+ end
16
+
17
+ test "it allows to define new variables" do
18
+ Alondra.config.test_variable = 'something'
19
+ assert_equal 'something', Alondra.config.test_variable
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+
3
+ module Alondra
4
+
5
+ class ConnectionTest < ActiveSupport::TestCase
6
+
7
+ test "it is assigned an UUI on creation" do
8
+ assert MockConnection.new.uuid.present?
9
+ end
10
+
11
+ test "can find if there is a session" do
12
+ session = {:user_id => 10}
13
+ connection = MockConnection.new(session)
14
+
15
+ assert_equal session, connection.session
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,217 @@
1
+ require 'test_helper'
2
+
3
+ module Alondra
4
+
5
+ class ChatListener < EventListener
6
+
7
+ def self.created_chat_ids
8
+ @created_chat_ids ||= []
9
+ end
10
+
11
+ def self.subscribed_user_ids
12
+ @subscribed_user_ids ||= []
13
+ end
14
+
15
+ def self.subscribed_to_collection
16
+ @subscribed_to_collection ||= []
17
+ end
18
+
19
+ def self.subscribed_to_member
20
+ @subscribed_to_member ||= []
21
+ end
22
+
23
+ def self.custom_events
24
+ @custom_events ||= []
25
+ end
26
+
27
+ on :created do |event|
28
+ ChatListener.created_chat_ids << event.resource.id
29
+ end
30
+
31
+ on :destroyed do |event|
32
+ chat = event.resource
33
+ ChatListener.created_chat_ids.delete(chat.id)
34
+ end
35
+
36
+ on :subscribed do |event|
37
+ ChatListener.subscribed_user_ids << session[:user_id]
38
+ end
39
+
40
+ on :unsubscribed do |event|
41
+ ChatListener.subscribed_user_ids.delete(session[:user_id])
42
+ end
43
+
44
+ on :subscribed, :to => :collection do |event|
45
+ ChatListener.subscribed_to_collection << session[:user_id]
46
+ end
47
+
48
+ on :unsubscribed, :to => :collection do |event|
49
+ ChatListener.subscribed_to_collection.delete(session[:user_id])
50
+ end
51
+
52
+ on :subscribed, :to => :member do |event|
53
+ ChatListener.subscribed_to_member << session[:user_id]
54
+ end
55
+
56
+ on :unsubscribed, :to => :member do |event|
57
+ ChatListener.subscribed_to_member.delete(session[:user_id])
58
+ end
59
+
60
+ on :custom do |event|
61
+ ChatListener.custom_events << event
62
+ end
63
+
64
+ on :boom do |event|
65
+ event.boom!
66
+ end
67
+
68
+ end
69
+
70
+
71
+ class EventListenerTest < ActiveSupport::TestCase
72
+
73
+ test "can listen to a specific channel providing a string pattern" do
74
+ class TextPatternListener < EventListener
75
+ listen_to 'string pattern'
76
+ end
77
+
78
+ assert TextPatternListener.listen_to?('string pattern')
79
+ assert TextPatternListener.listen_to?('string pattern and more')
80
+ assert !TextPatternListener.listen_to?('other string pattern')
81
+ end
82
+
83
+ test "can listen to specific channel providing a regexp as pattern" do
84
+ class RegexpPatternListener < EventListener
85
+ listen_to /man$/
86
+ end
87
+
88
+ assert RegexpPatternListener.listen_to?('Superman')
89
+ assert !RegexpPatternListener.listen_to?('Lex Luthor')
90
+ end
91
+
92
+ test "it has a default channel pattern" do
93
+ class DefaultPatternsListener < EventListener; end
94
+
95
+ assert DefaultPatternsListener.listen_to?('/default/patterns/')
96
+ assert DefaultPatternsListener.listen_to?('/default/patterns/1')
97
+
98
+ assert !DefaultPatternsListener.listen_to?('/default/other/')
99
+ assert !DefaultPatternsListener.listen_to?('/other/patterns/')
100
+ end
101
+
102
+ test "default channel pattern is ignored if explicit listen_to pattern is called" do
103
+ class OverwrittenDefaultPatternsListener < EventListener
104
+ listen_to '/others'
105
+ end
106
+
107
+ assert OverwrittenDefaultPatternsListener.listen_to?('/others')
108
+ assert OverwrittenDefaultPatternsListener.listen_to?('/others/1/')
109
+ assert !OverwrittenDefaultPatternsListener.listen_to?('/overwritten/default/patterns')
110
+ end
111
+
112
+
113
+ test 'receive created and destroyes events' do
114
+ ChatListener.listen_to '/chats/'
115
+
116
+ chat = Chat.create(:name => 'Observed chat')
117
+
118
+ sleep(0.1)
119
+
120
+ assert ChatListener.created_chat_ids.include?(chat.id)
121
+
122
+ chat.destroy
123
+
124
+ sleep(0.1)
125
+
126
+ assert !ChatListener.created_chat_ids.include?(chat.id)
127
+ end
128
+
129
+ test 'react to subscribed and unsubscribed events' do
130
+ session = {:user_id => 28 }
131
+ connection = MockConnection.new(session)
132
+
133
+ assert !ChatListener.subscribed_user_ids.include?(28)
134
+
135
+ Command.new(connection, :command => 'subscribe', :channel => '/chats/').execute!
136
+
137
+ sleep(0.1)
138
+
139
+ assert ChatListener.subscribed_user_ids.include?(28)
140
+
141
+ Command.new(connection, :command => 'unsubscribe', :channel => '/chats/').execute!
142
+
143
+ sleep(0.1)
144
+
145
+ assert !ChatListener.subscribed_user_ids.include?(28)
146
+ end
147
+
148
+ test 'react to subscribed and unsubscribed events on collection' do
149
+ session = {:user_id => 29 }
150
+ connection = MockConnection.new(session)
151
+
152
+ assert !ChatListener.subscribed_to_collection.include?(29)
153
+ assert !ChatListener.subscribed_to_member.include?(29)
154
+
155
+ Command.new(connection, :command => 'subscribe', :channel => '/chats/').execute!
156
+
157
+ sleep(0.1)
158
+
159
+ assert ChatListener.subscribed_to_collection.include?(29)
160
+ assert !ChatListener.subscribed_to_member.include?(29)
161
+
162
+ Command.new(connection, :command => 'unsubscribe', :channel => '/chats/').execute!
163
+
164
+ sleep(0.1)
165
+
166
+ assert !ChatListener.subscribed_to_collection.include?(29)
167
+ assert !ChatListener.subscribed_to_member.include?(29)
168
+ end
169
+
170
+ test 'react to subscribed and unsubscribed events on member' do
171
+ session = {:user_id => 30 }
172
+ connection = MockConnection.new(session)
173
+
174
+ chat = Factory.create :chat
175
+
176
+ chat_channel = "/chats/#{chat.id}"
177
+
178
+ assert !ChatListener.subscribed_to_collection.include?(30)
179
+ assert !ChatListener.subscribed_to_member.include?(30)
180
+
181
+ Command.new(connection, :command => 'subscribe', :channel => chat_channel).execute!
182
+
183
+ sleep(0.1)
184
+
185
+ assert !ChatListener.subscribed_to_collection.include?(30)
186
+ assert ChatListener.subscribed_to_member.include?(30)
187
+
188
+ Command.new(connection, :command => 'unsubscribe', :channel => chat_channel).execute!
189
+
190
+ sleep(0.1)
191
+
192
+ assert !ChatListener.subscribed_to_collection.include?(30)
193
+ assert !ChatListener.subscribed_to_member.include?(30)
194
+ end
195
+
196
+ test 'receive customs events' do
197
+ event = Event.new :event => :custom, :resource => Chat.new, :channel => '/chats/'
198
+ EventRouter.new.process(event)
199
+
200
+ sleep(0.1)
201
+
202
+ assert_equal ChatListener.custom_events.last, event
203
+ end
204
+
205
+ test 'capture exceptions launched in event listener' do
206
+ boom = BogusEvent.new :event => :boom, :resource => Chat.new, :channel => '/chats/'
207
+ EventRouter.new.process(boom)
208
+
209
+ event = Event.new :event => :custom, :resource => Chat.new, :channel => '/chats/'
210
+ EventRouter.new.process(event)
211
+
212
+ sleep(0.1)
213
+
214
+ assert_equal ChatListener.custom_events.last, event
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ module Alondra
4
+
5
+ class EventRouterTest < ActiveSupport::TestCase
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+
3
+ module Alondra
4
+
5
+ class MessageQueueClientTest < ActiveSupport::TestCase
6
+
7
+ test "a sync client uses a sync zeromq context" do
8
+ context = SyncMessageQueueClient.new.send :context
9
+ assert context.class == ZMQ::Context
10
+ end
11
+
12
+ test "an async client uses an async zeromq context" do
13
+ context = nil
14
+
15
+ assert EM.reactor_running?
16
+
17
+ EM.schedule do
18
+ context = MessageQueueClient.instance.send :context
19
+ end
20
+
21
+ sleep(0.1)
22
+
23
+ assert context.class == EM::ZeroMQ::Context
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,70 @@
1
+ require 'test_helper'
2
+
3
+ module Alondra
4
+
5
+ class MessageQueueTest < ActiveSupport::TestCase
6
+ setup do
7
+ @original_event_router = MessageQueue.instance.send :event_router
8
+ @router = MockEventRouter.new
9
+
10
+ @chat = Chat.create(:name => 'Silly chat')
11
+
12
+ MessageQueue.instance.instance_variable_set :@event_router, @router
13
+ @event = Event.new :event => :custom, :resource => @chat, :channel => '/chats/'
14
+ end
15
+
16
+ teardown do
17
+ MessageQueue.instance.instance_variable_set :@event_router, @original_event_router
18
+ end
19
+
20
+ test "a message pushed asynchronously to the queue is received by the event router" do
21
+ assert MessageQueueClient.instance.class == AsyncMessageQueueClient
22
+
23
+ MessageQueueClient.push @event
24
+
25
+ sleep(0.1)
26
+
27
+ assert received(@event)
28
+ end
29
+
30
+ test "a message pushed synchronously to the queue is received by the event router" do
31
+
32
+ client = MessageQueueClient.sync_instance
33
+ context = client.send :context
34
+ assert context.class == ZMQ::Context
35
+
36
+ client.send_message(@event)
37
+
38
+ sleep(0.1)
39
+
40
+ assert received(@event)
41
+ end
42
+
43
+ test "message queue still works when an exception is thrown while processing an event" do
44
+ 3.times do
45
+ bogus = BogusEvent.new :event => :custom, :resource => @chat, :channel => '/chats/'
46
+
47
+ begin
48
+ MessageQueueClient.push bogus
49
+ rescue BogusException
50
+ puts "rescued exception"
51
+ end
52
+ end
53
+
54
+ MessageQueueClient.push @event
55
+
56
+ sleep(0.1)
57
+
58
+ assert received(@event)
59
+ end
60
+
61
+ def received(event)
62
+ @router.received_events.find do |matching_event|
63
+ matching_event.type == event.type &&
64
+ matching_event.resource_type == event.resource_type &&
65
+ matching_event.resource.id == event.resource.id &&
66
+ matching_event.channel_name == event.channel_name
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+
3
+ module Alondra
4
+
5
+ class PushingTest < ActiveSupport::TestCase
6
+
7
+ test "publish created events to the specified channel" do
8
+ chat = Factory.create :chat
9
+ connection = MockConnection.new
10
+ message = chat.messages.build(:text => 'test message')
11
+
12
+ channel_name = Channel.default_name_for(chat)
13
+ assert channel_name =~ /chats\/\d+/
14
+
15
+ channel = Channel[channel_name]
16
+ channel.subscribe connection
17
+
18
+ sleep(0.1)
19
+
20
+ message.save!
21
+
22
+ sleep(0.1)
23
+
24
+ assert connection.messages.last, "should publish a message"
25
+
26
+ last_event = ActiveSupport::JSON.decode(connection.messages.last)
27
+ resource = last_event['resource']
28
+
29
+ assert_equal 'created', last_event['event']
30
+ assert_equal 'Message', last_event['resource_type']
31
+ assert_equal message.id, resource['id']
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,66 @@
1
+ require 'test_helper'
2
+
3
+ module Alondra
4
+
5
+ class MessageQueuePerformanceTest < ActiveSupport::TestCase
6
+
7
+ NUM_MESSAGES = 1_000
8
+
9
+ setup do
10
+ @event = Event.new :event => :custom, :resource => Chat.new, :channel => '/chats/'
11
+
12
+ # Initialize queue
13
+ MessageQueueClient.push @event
14
+
15
+ @original_event_router = MessageQueue.instance.send :event_router
16
+ @router = MockEventRouter.new
17
+
18
+ MessageQueue.instance.instance_variable_set :@event_router, @router
19
+ end
20
+
21
+ teardown do
22
+ MessageQueue.instance.instance_variable_set :@event_router, @original_event_router
23
+ end
24
+
25
+ test "message queue performance" do
26
+ puts "send #{NUM_MESSAGES} messages to queue"
27
+
28
+ time = Benchmark.measure do
29
+ NUM_MESSAGES.times do
30
+ MessageQueueClient.async_instance.send_message @event
31
+ end
32
+
33
+ while @router.received_events.size < NUM_MESSAGES
34
+ sleep(0.1)
35
+ end
36
+ end
37
+
38
+ events_per_second = NUM_MESSAGES/time.total
39
+
40
+ puts "aprox. received events per second #{events_per_second}"
41
+
42
+ assert events_per_second >= 500
43
+ end
44
+
45
+
46
+ test "message queue performance with sync client" do
47
+ puts "send #{NUM_MESSAGES} messages to queue"
48
+
49
+ time = Benchmark.measure do
50
+ NUM_MESSAGES.times do
51
+ MessageQueueClient.sync_instance.send_message @event
52
+ end
53
+
54
+ while @router.received_events.size < NUM_MESSAGES
55
+ sleep(0.1)
56
+ end
57
+ end
58
+
59
+ events_per_second = NUM_MESSAGES/time.total
60
+
61
+ puts "aprox. received events per second #{events_per_second}"
62
+
63
+ assert events_per_second >= 500
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,19 @@
1
+ Factory.define :chat do |f|
2
+ f.name 'Test chat'
3
+ end
4
+
5
+ Factory.define :message do |f|
6
+ f.association :chat
7
+ f.text 'Test message'
8
+ end
9
+
10
+ Factory.sequence :username do |i|
11
+ "user#{i}"
12
+ end
13
+
14
+ Factory.define :user do |f|
15
+ f.username { Factory.next(:username) }
16
+ f.email { |u| "#{u.username}@example.com" }
17
+ f.password 'secret'
18
+ f.password_confirmation 'secret'
19
+ end
@@ -0,0 +1,18 @@
1
+ module Alondra
2
+ module IntegrationHelper
3
+ def login_as(user)
4
+ visit new_session_path
5
+ fill_in "login", :with => user.username
6
+ fill_in "password", :with => "secret"
7
+ click_button "Log in"
8
+ end
9
+
10
+ def log_out
11
+ click_link _('logout')
12
+ end
13
+
14
+ def clean_db
15
+ [User, Chat, ::Message].each { |model| model.delete_all }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ # Define a bare test case to use with Capybara
2
+ class ActiveSupport::IntegrationCase < ActiveSupport::TestCase
3
+ include Capybara::DSL
4
+ include Rails.application.routes.url_helpers
5
+ include Alondra::IntegrationHelper
6
+ end
@@ -0,0 +1,15 @@
1
+ module Alondra
2
+
3
+ class BogusException < StandardError; end
4
+
5
+ class BogusEvent < Event
6
+
7
+ def to_json
8
+ boom!
9
+ end
10
+
11
+ def boom!
12
+ raise BogusException.new("Ha ha ha, I'm evil!")
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ module Alondra
2
+ class MockConnection < Connection
3
+
4
+ def initialize(session = {})
5
+ super UUIDTools::UUID.random_create, session
6
+ end
7
+
8
+ def send(message)
9
+ messages << message
10
+ end
11
+
12
+ def receive(event)
13
+ messages << event.to_json
14
+ end
15
+
16
+ def channels
17
+ @channels ||= []
18
+ end
19
+
20
+ def messages
21
+ @messages ||= []
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ module Alondra
2
+ class MockEventRouter
3
+
4
+ def process(event)
5
+ received_events << event
6
+ end
7
+
8
+ def received_events
9
+ @received_events ||= []
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ class MockListener
2
+ def received_events
3
+ @received_events ||= []
4
+ end
5
+
6
+ def receive(event)
7
+ received_events << event
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ # Configure Rails Environment
2
+ ENV["RAILS_ENV"] = "test"
3
+ ENV["ALONDRA_SERVER"] = 'true'
4
+
5
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
6
+ require "rails/test_help"
7
+ require 'capybara/rails'
8
+
9
+ Alondra::Alondra.start_server_in_new_thread!
10
+
11
+ Rails.backtrace_cleaner.remove_silencers!
12
+
13
+ # Load support files
14
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }