stompserver 0.9.1

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.
@@ -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: