stompserver 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ require 'frame_journal'
2
+ require 'test/unit' unless defined? $ZENTEST and $ZENTEST
3
+ require 'tesly'
4
+
5
+ # how would you test this? It is pretty simple code
6
+ # based almost completely on Madeleine...
7
+ class TestFrameJournal < Test::Unit::TestCase
8
+ def setup
9
+ end
10
+
11
+ def test_something
12
+
13
+ end
14
+ end
@@ -0,0 +1,83 @@
1
+ require 'queue_manager'
2
+ require 'test/unit' unless defined? $ZENTEST and $ZENTEST
3
+ require 'tesly'
4
+
5
+ class TestQueues < Test::Unit::TestCase
6
+
7
+ class UserMock
8
+ attr_accessor :data
9
+ def initialize ; @data = '' ; end
10
+ def send_data(data); @data += data ; end
11
+ end
12
+
13
+ class MessageMock
14
+ attr_accessor :headers, :data, :command
15
+ def initialize(dest, msg, id=1)
16
+ @headers = { 'destination' => dest, 'message-id' => id }
17
+ @data = msg
18
+ end
19
+ def to_s ; @data ; end
20
+ end
21
+
22
+ FileUtils.rm Dir.glob(".test_queue/*") rescue nil
23
+ @@journal = FrameJournal.new(".test_queue")
24
+
25
+ def setup
26
+ #needs a journal
27
+ @@journal.clear
28
+ @t = QueueManager.new(@@journal)
29
+ end
30
+
31
+ def test_subscribe
32
+ u = UserMock.new
33
+ t = 'foo'
34
+ @t.subscribe(t, u)
35
+
36
+ m1 = MessageMock.new('foo', 'foomsg')
37
+ m2 = MessageMock.new('bar', 'barmsg')
38
+ @t.sendmsg(m1)
39
+ assert_equal(m1.data, u.data)
40
+
41
+ u.data = ''
42
+ @t.sendmsg(m2)
43
+ assert_equal('', u.data)
44
+ end
45
+
46
+ def test_subscribe2
47
+ t = 'sub2'
48
+ m1 = MessageMock.new(t, 'sub2msg')
49
+ @t.sendmsg(m1)
50
+
51
+ u = UserMock.new
52
+ @t.subscribe(t, u)
53
+
54
+ assert_equal(m1.data, u.data)
55
+ end
56
+
57
+ def test_unsubscribe
58
+ u = UserMock.new
59
+ t = 'foo'
60
+ @t.subscribe(t, u)
61
+
62
+ m1 = MessageMock.new('foo', 'foomsg')
63
+ @t.sendmsg(m1)
64
+ assert_equal(m1.data, u.data)
65
+
66
+ @t.unsubscribe(t,u)
67
+ u.data = ''
68
+ @t.sendmsg(m1)
69
+ assert_equal('', u.data)
70
+ end
71
+
72
+ def test_sendmsg(msg)
73
+ u = UserMock.new
74
+ t = 'foo'
75
+ @t.subscribe(t, u)
76
+
77
+ m1 = MessageMock.new('foo', 'foomsg')
78
+ @t.sendmsg(m1)
79
+ assert_equal(m1.data, u.data)
80
+ assert_equal('MESSAGE', m1.command)
81
+ end
82
+
83
+ end
@@ -0,0 +1,121 @@
1
+ require 'stomp_frame'
2
+ require 'test/unit' unless defined? $ZENTEST and $ZENTEST
3
+ require 'tesly'
4
+
5
+ class TestStompFrame < Test::Unit::TestCase
6
+ def setup
7
+ @sfr = StompFrameRecognizer.new
8
+ end
9
+
10
+ def test_simpleframe
11
+ @sfr << <<FRAME
12
+ COMMAND
13
+ name:value
14
+ foo:bar
15
+
16
+ message body
17
+ \000
18
+ FRAME
19
+ assert_equal(1, @sfr.frames.size)
20
+ f = @sfr.frames.shift
21
+ assert_equal(0, @sfr.frames.size)
22
+ assert_equal("COMMAND", f.command)
23
+ assert_equal("value", f.headers["name"])
24
+ assert_equal("bar", f.headers["foo"])
25
+ assert_equal("message body\n", f.body)
26
+ end
27
+
28
+ def test_doubleframe
29
+ @sfr << <<FRAME
30
+ COMMAND
31
+ name:value
32
+ foo:bar
33
+
34
+ message body
35
+ \000
36
+
37
+ COMMAND2
38
+ name2:value2
39
+ foo2:bar2
40
+
41
+ message body 2
42
+ \000
43
+ FRAME
44
+ assert_equal(2, @sfr.frames.size)
45
+ f = @sfr.frames.shift
46
+ assert_equal(1, @sfr.frames.size)
47
+ assert_equal("COMMAND", f.command)
48
+ assert_equal("value", f.headers["name"])
49
+ assert_equal("bar", f.headers["foo"])
50
+ assert_equal("message body\n", f.body)
51
+
52
+ # check second frame
53
+ f = @sfr.frames.shift
54
+ assert_equal(0, @sfr.frames.size)
55
+ assert_equal("COMMAND2", f.command)
56
+ assert_equal("value2", f.headers["name2"])
57
+ assert_equal("bar2", f.headers["foo2"])
58
+ assert_equal("message body 2\n", f.body)
59
+ end
60
+
61
+ def test_partialframe
62
+ @sfr << <<FRAME
63
+ COMMAND
64
+ name:value
65
+ foo:bar
66
+
67
+ message body
68
+ \000
69
+
70
+ COMMAND2
71
+ name2:value2
72
+ foo2:bar2
73
+
74
+ message body 2
75
+ FRAME
76
+ assert_equal(1, @sfr.frames.size)
77
+ f = @sfr.frames.shift
78
+ assert_equal(0, @sfr.frames.size)
79
+ assert_equal("COMMAND", f.command)
80
+ assert_equal("value", f.headers["name"])
81
+ assert_equal("bar", f.headers["foo"])
82
+ assert_equal("message body\n", f.body)
83
+ end
84
+
85
+ def test_partialframe2
86
+ @sfr << <<FRAME
87
+ COMMAND
88
+ name:value
89
+ foo:bar
90
+ FRAME
91
+ assert_equal(0, @sfr.frames.size)
92
+ end
93
+
94
+ def test_headless_frame
95
+ @sfr << <<FRAME
96
+ COMMAND
97
+
98
+ message body\000
99
+ FRAME
100
+ assert_equal(1, @sfr.frames.size)
101
+ f = @sfr.frames.shift
102
+ assert_equal(0, @sfr.frames.size)
103
+ assert_equal("COMMAND", f.command)
104
+ assert_equal("message body", f.body)
105
+ end
106
+
107
+ def test_destination_cache
108
+ @sfr << <<FRAME
109
+ MESSAGE
110
+ destination: /queue/foo
111
+
112
+ message body\000
113
+ FRAME
114
+ assert_equal(1, @sfr.frames.size)
115
+ f = @sfr.frames.shift
116
+ assert_equal(0, @sfr.frames.size)
117
+ assert_equal("MESSAGE", f.command)
118
+ assert_equal("message body", f.body)
119
+ assert_equal('/queue/foo', f.dest)
120
+ end
121
+ end
@@ -0,0 +1,241 @@
1
+ require 'stomp_server'
2
+ require 'frame_journal'
3
+ require 'fileutils'
4
+ require 'test/unit' unless defined? $ZENTEST and $ZENTEST
5
+ require 'tesly'
6
+
7
+ #$DEBUG = true
8
+
9
+ class TestStompServer < Test::Unit::TestCase
10
+
11
+ # Is it a mock? it is what we are testing, but of
12
+ # course I am really testing the module, so I say
13
+ # yes it is a mock :-)
14
+ class MockStompServer
15
+ include StompServer
16
+ attr_accessor :sent, :connected
17
+
18
+ def initialize
19
+ @sent = ''
20
+ @connected = true
21
+ end
22
+
23
+ def send_data(data)
24
+ @sent += data
25
+ end
26
+
27
+ def close_connection_after_writing
28
+ @connected = false
29
+ end
30
+ alias close_connection close_connection_after_writing
31
+
32
+ def stomp(cmd, headers={}, body='', flush_prev = true)
33
+ @sent = '' if flush_prev
34
+ sf = StompFrame.new(cmd, headers, body)
35
+ receive_data(sf.to_s)
36
+ end
37
+
38
+ def do_connect(flush = true)
39
+ stomp('CONNECT')
40
+ @sent = '' if flush
41
+ end
42
+
43
+ def self.make_client(start_connection=true, flush=true)
44
+ ss = MockStompServer.new
45
+ ss.post_init
46
+ ss.do_connect(flush) if start_connection
47
+ ss
48
+ end
49
+
50
+ end
51
+
52
+ def assert_stomp_error(ss=@ss, match = nil)
53
+ assert_match(/ERROR/, ss.sent)
54
+ assert_match(match, ss.sent) if match
55
+ assert(!ss.connected)
56
+ end
57
+
58
+ FileUtils.rm Dir.glob(".test_journal/*") rescue nil
59
+ @@journal = FrameJournal.new(".test_journal")
60
+ StompServer.setup(@@journal)
61
+
62
+ def setup
63
+ # be sure and delete anything in our journal directory
64
+ @@journal.clear
65
+ @ss = MockStompServer.make_client
66
+ end
67
+
68
+ def test_version
69
+ assert(StompServer.const_defined?(:VERSION))
70
+ end
71
+
72
+ def test_invalid_command
73
+ assert_nothing_raised do
74
+ @ss.stomp('INVALID')
75
+ end
76
+ assert_stomp_error
77
+ end
78
+
79
+ def test_unconnected_command
80
+ ss = MockStompServer.make_client(false)
81
+ assert_nothing_raised do
82
+ ss.stomp('SEND')
83
+ end
84
+ assert_stomp_error(ss)
85
+ end
86
+
87
+ def test_connect
88
+ ss = MockStompServer.make_client(false)
89
+ assert(!ss.connected)
90
+ assert_nothing_raised do
91
+ ss.connect(false)
92
+ end
93
+ assert_match(/CONNECTED/, ss.sent)
94
+ assert(ss.connected)
95
+ end
96
+
97
+ def test_disconnect
98
+ assert_nothing_raised do
99
+ @ss.stomp('DISCONNECT')
100
+ end
101
+ assert(!@ss.connected)
102
+ end
103
+
104
+ def test_receipt
105
+ assert_nothing_raised do
106
+ @ss.stomp('SUBSCRIBE', {'receipt' => 'foobar'})
107
+ end
108
+
109
+ assert_match(/RECEIPT/, @ss.sent)
110
+ assert_match(/receipt-id:foobar/, @ss.sent)
111
+
112
+ assert(@ss.connected)
113
+ end
114
+
115
+ def test_topic
116
+ assert_equal('', @ss.sent)
117
+
118
+ # setup two clients (@ss and this one)
119
+ ss2 = MockStompServer.make_client
120
+ assert_equal('', ss2.sent)
121
+
122
+ @ss.stomp('SEND', {'destination' => '/topic/foo'}, 'Hi Pat')
123
+ @ss.stomp('SEND', {'destination' => '/topic/foo'}, 'Hi Sue')
124
+
125
+ assert_equal('', @ss.sent)
126
+ assert_equal('', ss2.sent)
127
+
128
+ ss2.stomp("SUBSCRIBE", {'destination' => '/topic/foo'})
129
+ assert_equal('', ss2.sent)
130
+
131
+ @ss.stomp('SEND', {'destination' => '/topic/foo'}, 'Hi Pat')
132
+ assert_match(/Hi Pat/, ss2.sent)
133
+ assert_equal('', @ss.sent)
134
+ end
135
+
136
+ def test_bad_topic
137
+ assert_equal('', @ss.sent)
138
+
139
+ # setup two clients (@ss and this one)
140
+ ss2 = MockStompServer.make_client
141
+ assert_equal('', ss2.sent)
142
+
143
+ ss2.stomp("SUBSCRIBE", {'destination' => '/badtopic/foo'})
144
+ assert_equal('', ss2.sent)
145
+
146
+ @ss.stomp('SEND', {'destination' => '/badtopic/foo'}, 'Hi Pat')
147
+ assert_match(/Hi Pat/, ss2.sent)
148
+ assert_equal('', @ss.sent)
149
+ end
150
+
151
+ def test_multiple_subscriber_topic
152
+ assert_equal('', @ss.sent)
153
+
154
+ # setup two clients (@ss and this one)
155
+ ss2 = MockStompServer.make_client
156
+ assert_equal('', ss2.sent)
157
+
158
+ @ss.stomp("SUBSCRIBE", {'destination' => '/topic/foo'})
159
+ ss2.stomp("SUBSCRIBE", {'destination' => '/topic/foo'})
160
+
161
+ assert_equal('', @ss.sent)
162
+ assert_equal('', ss2.sent)
163
+
164
+ @ss.stomp('SEND', {'destination' => '/topic/foo'}, 'Hi Pat')
165
+
166
+ assert_match(/Hi Pat/, ss2.sent)
167
+ assert_match(/Hi Pat/, @ss.sent)
168
+ end
169
+
170
+ def test_invalid_transaction
171
+ @ss.stomp("SEND", {'transaction' => 't'})
172
+ assert_stomp_error
173
+ end
174
+
175
+ def test_simple_transaction
176
+ ss1 = MockStompServer.make_client
177
+ ss2 = MockStompServer.make_client
178
+
179
+ ss2.stomp("SUBSCRIBE", {"destination" => '/topic/foo'})
180
+ assert_equal('', ss2.sent)
181
+
182
+ ss1.stomp("BEGIN", {"transaction" => 'simple'})
183
+ ss1.stomp("SEND", {"transaction" => 'simple', 'destination' => '/topic/foo'}, 'Hi Pat')
184
+ assert_equal('', ss2.sent)
185
+ assert_equal('', ss1.sent)
186
+
187
+ ss1.stomp("COMMIT", {"transaction" => 'simple'})
188
+ assert_equal('', ss1.sent)
189
+ assert_match(/Hi Pat/, ss2.sent)
190
+ end
191
+
192
+ def test_simple_transaction2
193
+ ss1 = MockStompServer.make_client
194
+ ss2 = MockStompServer.make_client
195
+
196
+ ss2.stomp("BEGIN", {"transaction" => 'simple'})
197
+ ss2.stomp("SUBSCRIBE", {"transaction" => 'simple', "destination" => '/topic/foo'})
198
+ assert_equal('', ss2.sent)
199
+
200
+ ss1.stomp("SEND", {'destination' => '/topic/foo'}, 'Hi Pat')
201
+ assert_equal('', ss2.sent)
202
+ assert_equal('', ss1.sent)
203
+
204
+ ss2.stomp("COMMIT", {"transaction" => 'simple'})
205
+ assert_equal('', ss1.sent)
206
+ assert_equal('', ss2.sent)
207
+
208
+ ss1.stomp("SEND", {'destination' => '/topic/foo'}, 'Hi Pat')
209
+ assert_match(/Hi Pat/, ss2.sent)
210
+ end
211
+
212
+ def test_simple_abort_transaction
213
+ ss1 = MockStompServer.make_client
214
+ ss2 = MockStompServer.make_client
215
+
216
+ ss2.stomp("BEGIN", {"transaction" => 'simple'})
217
+ ss2.stomp("SUBSCRIBE", {"transaction" => 'simple', "destination" => '/topic/foo'})
218
+ assert_equal('', ss2.sent)
219
+
220
+ ss1.stomp("SEND", {'destination' => '/topic/foo'}, 'Hi Pat')
221
+ assert_equal('', ss2.sent)
222
+ assert_equal('', ss1.sent)
223
+
224
+ ss2.stomp("ABORT", {"transaction" => 'simple'})
225
+ assert_equal('', ss1.sent)
226
+ assert_equal('', ss2.sent)
227
+
228
+ ss1.stomp("SEND", {'destination' => '/topic/foo'}, 'Hi Pat')
229
+ assert_match('', ss2.sent)
230
+ end
231
+
232
+ def test_simple_queue_message
233
+ ss1 = MockStompServer.make_client
234
+ ss1.stomp("SEND", {'destination' => '/queue/foo'}, 'Hi Pat')
235
+ ss1.stomp("DISCONNECT")
236
+
237
+ ss2 = MockStompServer.make_client
238
+ ss2.stomp("SUBSCRIBE", {"destination" => '/queue/foo'})
239
+ assert_match(/Hi Pat/, ss2.sent)
240
+ end
241
+ end
@@ -0,0 +1,68 @@
1
+ require 'topic_manager'
2
+ require 'test/unit' unless defined? $ZENTEST and $ZENTEST
3
+ require 'tesly_reporter'
4
+
5
+ class TestTopics < Test::Unit::TestCase
6
+
7
+ class UserMock
8
+ attr_accessor :data
9
+ def initialize ; @data = '' ; end
10
+ def send_data(data); @data += data ; end
11
+ end
12
+
13
+ class MessageMock
14
+ attr_accessor :headers, :data, :command
15
+ def initialize(dest, msg)
16
+ @headers = { 'destination' => dest }
17
+ @data = msg
18
+ end
19
+ def to_s ; @data ; end
20
+ end
21
+
22
+ def setup
23
+ @t = TopicManager.new
24
+ end
25
+
26
+ def test_subscribe
27
+ u = UserMock.new
28
+ t = 'foo'
29
+ @t.subscribe(t, u)
30
+
31
+ m1 = MessageMock.new('foo', 'foomsg')
32
+ m2 = MessageMock.new('bar', 'barmsg')
33
+ @t.sendmsg(m1)
34
+ assert_equal(m1.data, u.data)
35
+
36
+ u.data = ''
37
+ @t.sendmsg(m2)
38
+ assert_equal('', u.data)
39
+ end
40
+
41
+ def test_unsubscribe
42
+ u = UserMock.new
43
+ t = 'foo'
44
+ @t.subscribe(t, u)
45
+
46
+ m1 = MessageMock.new('foo', 'foomsg')
47
+ @t.sendmsg(m1)
48
+ assert_equal(m1.data, u.data)
49
+
50
+ @t.unsubscribe(t,u)
51
+ u.data = ''
52
+ @t.sendmsg(m1)
53
+ assert_equal('', u.data)
54
+ end
55
+
56
+ def test_sendmsg(msg)
57
+ u = UserMock.new
58
+ t = 'foo'
59
+ @t.subscribe(t, u)
60
+
61
+ m1 = MessageMock.new('foo', 'foomsg')
62
+ @t.sendmsg(m1)
63
+ assert_equal(m1.data, u.data)
64
+ assert_equal('MESSAGE', m1.command)
65
+ end
66
+
67
+ end
68
+
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: stompserver
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.9.1
7
+ date: 2006-10-16 00:00:00 -04:00
8
+ summary: A very light messaging server
9
+ require_paths:
10
+ - lib
11
+ - test
12
+ email: phurley@gmail.com
13
+ homepage: " by Patrick Hurley"
14
+ rubyforge_project: stompserver
15
+ description: "Don't want to install a JVM, but still want to use messaging? Me too, so I threw together this little server. All the hard work was done by Francis Cianfrocca (big thank you) in his event machine gem (which is required by this server). == FEATURES/PROBLEMS: Handles basic message queue processing Does not support any server to server messaging (although you could write a client to do this) Server Id is not being well initialized Quite a bit of polish is still required to make into a daemon/service and add command line handling. And oh yeah, I need to write some docs (see the tests for now)"
16
+ autorequire:
17
+ default_executable:
18
+ bindir: bin
19
+ has_rdoc: true
20
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
21
+ requirements:
22
+ - - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ post_install_message:
30
+ authors:
31
+ - Patrick Hurley
32
+ files:
33
+ - History.txt
34
+ - Manifest.txt
35
+ - README.txt
36
+ - Rakefile
37
+ - setup.rb
38
+ - bin/stompserver
39
+ - lib/frame_journal.rb
40
+ - lib/queue_manager.rb
41
+ - lib/stomp_frame.rb
42
+ - lib/stomp_server.rb
43
+ - lib/topic_manager.rb
44
+ - test/test_frame_journal.rb
45
+ - test/test_queue_manager.rb
46
+ - test/test_stomp_frame.rb
47
+ - test/test_stomp_server.rb
48
+ - test/test_topic_manager.rb
49
+ test_files: []
50
+
51
+ rdoc_options: []
52
+
53
+ extra_rdoc_files: []
54
+
55
+ executables:
56
+ - stompserver
57
+ extensions: []
58
+
59
+ requirements: []
60
+
61
+ dependencies:
62
+ - !ruby/object:Gem::Dependency
63
+ name: eventmachine
64
+ version_requirement:
65
+ version_requirements: !ruby/object:Gem::Version::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 5.0.0
70
+ version:
71
+ - !ruby/object:Gem::Dependency
72
+ name: madeleine
73
+ version_requirement:
74
+ version_requirements: !ruby/object:Gem::Version::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 0.7.3
79
+ version:
80
+ - !ruby/object:Gem::Dependency
81
+ name: hoe
82
+ version_requirement:
83
+ version_requirements: !ruby/object:Gem::Version::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: 1.1.1
88
+ version: