message_bus 3.3.4 → 3.3.8

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +21 -0
  3. data/.github/workflows/ci.yml +99 -0
  4. data/.gitignore +2 -0
  5. data/.prettierrc +1 -0
  6. data/.rubocop.yml +3 -1
  7. data/CHANGELOG +30 -8
  8. data/DEV.md +7 -0
  9. data/Gemfile +0 -25
  10. data/LICENSE +1 -1
  11. data/README.md +34 -15
  12. data/Rakefile +13 -8
  13. data/assets/message-bus-ajax.js +4 -10
  14. data/assets/message-bus.js +69 -76
  15. data/bench/codecs/all_codecs.rb +39 -0
  16. data/bench/codecs/marshal.rb +11 -0
  17. data/bench/codecs/packed_string.rb +67 -0
  18. data/bench/codecs/string_hack.rb +47 -0
  19. data/bench/codecs_large_user_list.rb +29 -0
  20. data/bench/codecs_standard_message.rb +29 -0
  21. data/examples/bench/bench.lua +2 -2
  22. data/lib/message_bus/backends/base.rb +8 -5
  23. data/lib/message_bus/backends/memory.rb +6 -2
  24. data/lib/message_bus/backends/postgres.rb +27 -18
  25. data/lib/message_bus/backends/redis.rb +9 -6
  26. data/lib/message_bus/client.rb +6 -7
  27. data/lib/message_bus/codec/base.rb +18 -0
  28. data/lib/message_bus/codec/json.rb +15 -0
  29. data/lib/message_bus/codec/oj.rb +21 -0
  30. data/lib/message_bus/connection_manager.rb +1 -1
  31. data/lib/message_bus/distributed_cache.rb +3 -1
  32. data/lib/message_bus/http_client.rb +2 -2
  33. data/lib/message_bus/rack/diagnostics.rb +30 -8
  34. data/lib/message_bus/rack/middleware.rb +22 -16
  35. data/lib/message_bus/rack/thin_ext.rb +2 -1
  36. data/lib/message_bus/version.rb +1 -1
  37. data/lib/message_bus.rb +42 -22
  38. data/message_bus.gemspec +21 -3
  39. data/package-lock.json +3744 -0
  40. data/package.json +15 -8
  41. data/spec/assets/SpecHelper.js +6 -5
  42. data/spec/assets/message-bus.spec.js +9 -6
  43. data/spec/helpers.rb +23 -7
  44. data/spec/integration/http_client_spec.rb +1 -1
  45. data/spec/lib/fake_async_middleware.rb +1 -0
  46. data/spec/lib/message_bus/backend_spec.rb +13 -44
  47. data/spec/lib/message_bus/client_spec.rb +7 -6
  48. data/spec/lib/message_bus/connection_manager_spec.rb +4 -0
  49. data/spec/lib/message_bus/distributed_cache_spec.rb +5 -7
  50. data/spec/lib/message_bus/multi_process_spec.rb +19 -9
  51. data/spec/lib/message_bus/rack/middleware_spec.rb +18 -6
  52. data/spec/lib/message_bus_spec.rb +13 -8
  53. data/spec/spec_helper.rb +8 -9
  54. data/spec/support/jasmine-browser.json +16 -0
  55. data/vendor/assets/javascripts/message-bus-ajax.js +4 -10
  56. data/vendor/assets/javascripts/message-bus.js +69 -76
  57. metadata +231 -11
  58. data/.travis.yml +0 -17
  59. data/lib/message_bus/em_ext.rb +0 -6
  60. data/spec/assets/support/jasmine.yml +0 -126
  61. data/spec/assets/support/jasmine_helper.rb +0 -11
data/package.json CHANGED
@@ -1,20 +1,27 @@
1
1
  {
2
2
  "name": "message-bus-client",
3
- "version": "3.3.0",
3
+ "version": "0.0.0-version-placeholder",
4
4
  "description": "A message bus client in Javascript",
5
5
  "main": "assets/message-bus.js",
6
- "keywords": "es6, modules",
7
- "files": ["assets/message-bus.js"],
6
+ "keywords": [
7
+ "es6",
8
+ "modules"
9
+ ],
10
+ "files": [
11
+ "assets/message-bus.js"
12
+ ],
8
13
  "jsnext:main": "assets/message-bus.js",
9
14
  "module": "assets/message-bus.js",
10
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/discourse/message_bus.git"
13
- },
15
+ "repository": "https://github.com/discourse/message_bus",
14
16
  "author": "Sam Saffron, Robin Ward",
15
17
  "license": "MIT",
16
18
  "bugs": {
17
19
  "url": "https://github.com/discourse/message_bus/issues"
18
20
  },
19
- "homepage": "https://github.com/discourse/message_bus#readme"
21
+ "homepage": "https://github.com/discourse/message_bus#readme",
22
+ "devDependencies": {
23
+ "eslint": "^7.27.0",
24
+ "jasmine-browser-runner": "^0.10.0",
25
+ "jasmine-core": "^3.10.1"
26
+ }
20
27
  }
@@ -1,3 +1,5 @@
1
+ /* global beforeEach, afterEach, it, spyOn, MessageBus */
2
+
1
3
  var message_id = 1;
2
4
  var SEPARATOR = "\r\n|\r\n";
3
5
 
@@ -12,7 +14,7 @@ var encodeChunks = function(xhr, chunks) {
12
14
  }
13
15
  if (xhr.onprogress){ // using longPoll if onprogress is set
14
16
  var responses = []
15
- for (var i=0;i<chunks.length;i++) {
17
+ for (var j=0;j<chunks.length;j++) {
16
18
  responses.push( JSON.stringify([chunk]) );
17
19
  }
18
20
  return responses.join(SEPARATOR) + SEPARATOR;
@@ -26,7 +28,7 @@ beforeEach(function () {
26
28
 
27
29
  function MockedXMLHttpRequest(){
28
30
  this.headers = {};
29
- };
31
+ }
30
32
 
31
33
  MockedXMLHttpRequest.prototype.send = function(){
32
34
  this.readyState = 4
@@ -75,8 +77,8 @@ window.testMB = function(description, testFn, path, data){
75
77
  {channel: path || '/test', data: data || {password: 'MessageBusRocks!'}}
76
78
  ];
77
79
  it(description, function(done){
78
- spec = this;
79
- promisy = {
80
+ var spec = this;
81
+ var promisy = {
80
82
  finally: function(fn){
81
83
  this.resolve = fn;
82
84
  }
@@ -105,4 +107,3 @@ window.testMB = function(description, testFn, path, data){
105
107
  });
106
108
 
107
109
  }
108
-
@@ -1,3 +1,5 @@
1
+ /* global describe, it, spyOn, MessageBus, expect, jasmine, testMB */
2
+
1
3
  describe("Messagebus", function() {
2
4
 
3
5
  it("submits change requests", function(done){
@@ -6,10 +8,11 @@ describe("Messagebus", function() {
6
8
  MessageBus.subscribe('/test', function(){
7
9
  expect(spec.MockedXMLHttpRequest.prototype.send)
8
10
  .toHaveBeenCalled()
9
- var req = JSON.parse(spec.MockedXMLHttpRequest.prototype.send.calls.argsFor(0)[0]);
10
- expect(req['/test']).toEqual(-1)
11
- expect(req['__seq']).not.toBeUndefined();
12
- done()
11
+ var data = spec.MockedXMLHttpRequest.prototype.send.calls.argsFor(0)[0];
12
+ var params = new URLSearchParams(data);
13
+ expect(params.get("/test")).toEqual("-1");
14
+ expect(params.get("__seq")).toMatch(/\d+/);
15
+ done();
13
16
  });
14
17
  });
15
18
 
@@ -57,7 +60,7 @@ describe("Messagebus", function() {
57
60
  });
58
61
  });
59
62
 
60
- testMB('sets dlp paramater when longPolling is disabled', function(){
63
+ testMB('sets dlp parameter when longPolling is disabled', function(){
61
64
  MessageBus.enableLongPolling = false
62
65
  this.perform(function(message, xhr){
63
66
  expect(xhr.url).toMatch("dlp=t");
@@ -87,7 +90,7 @@ describe("Messagebus", function() {
87
90
  expect(xhr.headers).toEqual({
88
91
  'X-SILENCE-LOGGER': 'true',
89
92
  'X-MB-TEST-VALUE': '42',
90
- 'Content-Type': 'application/json'
93
+ 'Content-Type': 'application/x-www-form-urlencoded'
91
94
  });
92
95
  }).finally(function(){
93
96
  MessageBus.headers = {};
data/spec/helpers.rb CHANGED
@@ -1,20 +1,36 @@
1
1
  # frozen_string_literal: true
2
- def wait_for(timeout_milliseconds = 2000)
3
- timeout = (timeout_milliseconds + 0.0) / 1000
2
+
3
+ require 'logger'
4
+ require 'method_source'
5
+
6
+ def wait_for(timeout_milliseconds = 2000, &blk)
7
+ timeout = timeout_milliseconds / 1000.0
4
8
  finish = Time.now + timeout
9
+ result = nil
5
10
 
6
- Thread.new do
7
- sleep(0.001) while Time.now < finish && !yield
8
- end.join
11
+ while Time.now < finish && !(result = blk.call)
12
+ sleep(0.001)
13
+ end
14
+
15
+ flunk("wait_for timed out:\n#{blk.source}") if !result
9
16
  end
10
17
 
11
18
  def test_config_for_backend(backend)
12
- config = { backend: backend }
19
+ config = {
20
+ backend: backend,
21
+ logger: Logger.new(IO::NULL),
22
+ }
23
+
13
24
  case backend
14
25
  when :redis
15
26
  config[:url] = ENV['REDISURL']
16
27
  when :postgres
17
- config[:backend_options] = { host: ENV['PGHOST'], user: ENV['PGUSER'] || ENV['USER'], password: ENV['PGPASSWORD'], dbname: ENV['PGDATABASE'] || 'message_bus_test' }
28
+ config[:backend_options] = {
29
+ host: ENV['PGHOST'],
30
+ user: ENV['PGUSER'] || ENV['USER'],
31
+ password: ENV['PGPASSWORD'],
32
+ dbname: ENV['PGDATABASE'] || 'message_bus_test'
33
+ }
18
34
  end
19
35
  config
20
36
  end
@@ -71,7 +71,7 @@ describe MessageBus::HTTPClient do
71
71
  # that we sleep for the right interval after failure
72
72
  sleep 0.5
73
73
 
74
- assert_equal(1, fake.string.scan("Errno::ECONNREFUSED").size)
74
+ assert_match(/Errno::ECONNREFUSED|SocketError/, fake.string)
75
75
  ensure
76
76
  $stderr = original_stderr
77
77
  end
@@ -7,6 +7,7 @@ class FakeAsyncMiddleware
7
7
  @simulate_thin_async = false
8
8
  @simulate_hijack = false
9
9
  @in_async = false
10
+ @allow_chunked = false
10
11
  end
11
12
 
12
13
  def app
@@ -4,18 +4,18 @@ require_relative '../../spec_helper'
4
4
  require 'message_bus'
5
5
 
6
6
  describe PUB_SUB_CLASS do
7
- def new_test_bus
8
- PUB_SUB_CLASS.new(MESSAGE_BUS_CONFIG)
7
+ before do
8
+ @bus = PUB_SUB_CLASS.new(test_config_for_backend(CURRENT_BACKEND))
9
9
  end
10
10
 
11
- before do
12
- @bus = new_test_bus
11
+ after do
13
12
  @bus.reset!
13
+ @bus.destroy
14
14
  end
15
15
 
16
16
  describe "API parity" do
17
17
  it "has the same public methods as the base class" do
18
- @bus.public_methods.sort.must_equal MessageBus::Backends::Base.new(MESSAGE_BUS_CONFIG).public_methods.sort
18
+ @bus.public_methods.sort.must_equal MessageBus::Backends::Base.new(test_config_for_backend(CURRENT_BACKEND)).public_methods.sort
19
19
  end
20
20
  end
21
21
 
@@ -77,7 +77,7 @@ describe PUB_SUB_CLASS do
77
77
  end
78
78
 
79
79
  threads.each(&:join)
80
- @bus.backlog("/foo").length == 100
80
+ @bus.backlog("/foo").length.must_equal 100
81
81
  end
82
82
 
83
83
  it "should be able to encode and decode messages properly" do
@@ -91,37 +91,6 @@ describe PUB_SUB_CLASS do
91
91
  @bus.last_id("/foo").must_equal 1
92
92
  end
93
93
 
94
- describe "readonly" do
95
- after do
96
- @bus.pub_redis.slaveof "no", "one"
97
- end
98
-
99
- it "should be able to store messages in memory for a period while in read only" do
100
- test_only :redis
101
- skip "This spec changes redis behavior that in turn means other specs run slow"
102
-
103
- @bus.pub_redis.slaveof "127.0.0.80", "666"
104
- @bus.max_in_memory_publish_backlog = 2
105
-
106
- current_threads = Thread.list
107
- current_threads_length = current_threads.count
108
-
109
- 3.times do
110
- result = @bus.publish "/foo", "bar"
111
- assert_nil result
112
- Thread.list.length.must_equal(current_threads_length + 1)
113
- end
114
-
115
- @bus.pub_redis.slaveof "no", "one"
116
- sleep 0.01
117
-
118
- (Thread.list - current_threads).each(&:join)
119
- Thread.list.length.must_equal current_threads_length
120
-
121
- @bus.backlog("/foo", 0).map(&:data).must_equal ["bar", "bar"]
122
- end
123
- end
124
-
125
94
  it "can set backlog age" do
126
95
  @bus.max_backlog_age = 1
127
96
 
@@ -137,7 +106,7 @@ describe PUB_SUB_CLASS do
137
106
  sleep 1.25 # Should now be at time =~ 1.25s. Our backlog should have expired by now.
138
107
  expected_backlog_size = 0
139
108
 
140
- case MESSAGE_BUS_CONFIG[:backend]
109
+ case CURRENT_BACKEND
141
110
  when :postgres
142
111
  # Force triggering backlog expiry: postgres backend doesn't expire backlogs on a timer, but at publication time.
143
112
  @bus.global_backlog.length.wont_equal expected_backlog_size
@@ -161,7 +130,7 @@ describe PUB_SUB_CLASS do
161
130
  @bus.publish "/foo", "baz" # Publish something else to ward off another expiry
162
131
  expected_backlog_size += 1
163
132
 
164
- case MESSAGE_BUS_CONFIG[:backend]
133
+ case CURRENT_BACKEND
165
134
  when :postgres
166
135
  # Postgres expires individual messages that have lived longer than the TTL, not whole backlogs
167
136
  expected_backlog_size -= 1
@@ -189,7 +158,7 @@ describe PUB_SUB_CLASS do
189
158
  sleep 1.25 # Should now be at time =~ 1.25s. Our backlog should have expired by now.
190
159
  expected_backlog_size = 0
191
160
 
192
- case MESSAGE_BUS_CONFIG[:backend]
161
+ case CURRENT_BACKEND
193
162
  when :postgres
194
163
  # Force triggering backlog expiry: postgres backend doesn't expire backlogs on a timer, but at publication time.
195
164
  @bus.global_backlog.length.wont_equal expected_backlog_size
@@ -204,7 +173,7 @@ describe PUB_SUB_CLASS do
204
173
 
205
174
  # for the time being we can give pg a pass here
206
175
  # TODO: make the implementation here consistent
207
- if MESSAGE_BUS_CONFIG[:backend] != :postgres
176
+ if CURRENT_BACKEND != :postgres
208
177
  # ids are not opaque we expect them to be reset on our channel if it
209
178
  # got cleared due to an expire, the reason for this is cause we will leak entries due to tracking
210
179
  # this in turn can bloat storage for the backend
@@ -222,7 +191,7 @@ describe PUB_SUB_CLASS do
222
191
  @bus.publish "/foo", "baz", max_backlog_age: 1 # Publish something else to ward off another expiry
223
192
  expected_backlog_size += 1
224
193
 
225
- case MESSAGE_BUS_CONFIG[:backend]
194
+ case CURRENT_BACKEND
226
195
  when :postgres
227
196
  # Postgres expires individual messages that have lived longer than the TTL, not whole backlogs
228
197
  expected_backlog_size -= 1
@@ -249,7 +218,7 @@ describe PUB_SUB_CLASS do
249
218
  @bus.publish "/foo", "baz"
250
219
  @bus.publish "/hello", "planet"
251
220
 
252
- expected_messages = case MESSAGE_BUS_CONFIG[:backend]
221
+ expected_messages = case CURRENT_BACKEND
253
222
  when :redis
254
223
  # Redis has channel-specific message IDs
255
224
  [
@@ -277,7 +246,7 @@ describe PUB_SUB_CLASS do
277
246
  @bus.publish "/bar", "a1"
278
247
  @bus.publish "/bar", "b1"
279
248
 
280
- expected_messages = case MESSAGE_BUS_CONFIG[:backend]
249
+ expected_messages = case CURRENT_BACKEND
281
250
  when :redis
282
251
  # Redis has channel-specific message IDs
283
252
  [
@@ -11,11 +11,12 @@ describe MessageBus::Client do
11
11
 
12
12
  before do
13
13
  @bus = MessageBus::Instance.new
14
- @bus.configure(MESSAGE_BUS_CONFIG)
14
+ @bus.configure(test_config_for_backend(CURRENT_BACKEND))
15
15
  @client = setup_client('abc')
16
16
  end
17
17
 
18
18
  after do
19
+ @client.close
19
20
  @bus.reset!
20
21
  @bus.destroy
21
22
  end
@@ -98,7 +99,7 @@ describe MessageBus::Client do
98
99
  chunk2.length.must_equal 0
99
100
  end
100
101
 
101
- it "does not bleed data accross sites" do
102
+ it "does not bleed data across sites" do
102
103
  @client.site_id = "test"
103
104
 
104
105
  @client.subscribe('/hello', nil)
@@ -107,7 +108,7 @@ describe MessageBus::Client do
107
108
  log.length.must_equal 0
108
109
  end
109
110
 
110
- it "does not bleed status accross sites" do
111
+ it "does not bleed status across sites" do
111
112
  @client.site_id = "test"
112
113
 
113
114
  @client.subscribe('/hello', -1)
@@ -190,7 +191,7 @@ describe MessageBus::Client do
190
191
  @client.allowed?(@message).must_equal true
191
192
  end
192
193
 
193
- describe 'targetted at user' do
194
+ describe 'targeted at user' do
194
195
  before do
195
196
  @message = MessageBus::Message.new(1, 2, '/test', 'hello')
196
197
  @message.user_ids = [1, 2, 3]
@@ -241,7 +242,7 @@ describe MessageBus::Client do
241
242
  end
242
243
  end
243
244
 
244
- describe "targetted at group" do
245
+ describe "targeted at group" do
245
246
  before do
246
247
  @message = MessageBus::Message.new(1, 2, '/test', 'hello')
247
248
  @message.group_ids = [1, 2, 3]
@@ -291,7 +292,7 @@ describe MessageBus::Client do
291
292
  end
292
293
  end
293
294
 
294
- describe 'targetted at group and user' do
295
+ describe 'targeted at group and user' do
295
296
  before do
296
297
  @message = MessageBus::Message.new(1, 2, '/test', 'hello')
297
298
  @message.group_ids = [1, 2, 3]
@@ -6,6 +6,10 @@ require 'message_bus'
6
6
  class FakeAsync
7
7
  attr_accessor :cleanup_timer
8
8
 
9
+ def initialize
10
+ @sent = nil
11
+ end
12
+
9
13
  def <<(val)
10
14
  sleep 0.01 # simulate IO
11
15
  @sent ||= +""
@@ -6,13 +6,16 @@ require 'message_bus'
6
6
  require 'message_bus/distributed_cache'
7
7
 
8
8
  describe MessageBus::DistributedCache do
9
- before :all do
9
+ before do
10
10
  @bus = MessageBus::Instance.new
11
11
  @bus.configure(backend: :memory)
12
12
  @manager = MessageBus::DistributedCache::Manager.new(@bus)
13
+ @cache1 = cache(cache_name)
14
+ @cache2 = cache(cache_name)
13
15
  end
14
16
 
15
- after :all do
17
+ after do
18
+ @bus.reset!
16
19
  @bus.destroy
17
20
  end
18
21
 
@@ -24,11 +27,6 @@ describe MessageBus::DistributedCache do
24
27
  SecureRandom.hex
25
28
  end
26
29
 
27
- before do
28
- @cache1 = cache(cache_name)
29
- @cache2 = cache(cache_name)
30
- end
31
-
32
30
  it 'supports arrays with hashes' do
33
31
  c1 = cache("test1")
34
32
  c2 = cache("test1")
@@ -13,18 +13,20 @@ describe PUB_SUB_CLASS do
13
13
  end
14
14
 
15
15
  def new_bus
16
- PUB_SUB_CLASS.new(MESSAGE_BUS_CONFIG.merge(db: 10))
16
+ PUB_SUB_CLASS.new(test_config_for_backend(CURRENT_BACKEND).merge(db: 10))
17
17
  end
18
18
 
19
19
  def work_it
20
20
  bus = new_bus
21
- $stdout.reopen("/dev/null", "w")
22
- $stderr.reopen("/dev/null", "w")
23
- # subscribe blocks, so we need a new bus to transmit
24
- new_bus.subscribe("/echo", 0) do |msg|
25
- bus.publish("/response", "#{msg.data}-#{Process.pid.to_s}")
21
+ bus.subscribe("/echo", 0) do |msg|
22
+ if msg.data == "done"
23
+ bus.global_unsubscribe
24
+ else
25
+ bus.publish("/response", "#{msg.data}-#{Process.pid.to_s}")
26
+ end
26
27
  end
27
28
  ensure
29
+ bus.destroy
28
30
  exit!(0)
29
31
  end
30
32
 
@@ -44,12 +46,14 @@ describe PUB_SUB_CLASS do
44
46
  test_never :memory
45
47
  skip("previous error") if self.class.error?
46
48
  GC.start
47
- new_bus.reset!
49
+ bus = new_bus
50
+ bus.reset!
51
+
48
52
  begin
49
53
  pids = (1..10).map { spawn_child }
50
54
  expected_responses = pids.map { |x| (0...10).map { |i| "0#{i}-#{x}" } }.flatten
51
55
  unexpected_responses = []
52
- bus = new_bus
56
+
53
57
  t = Thread.new do
54
58
  bus.subscribe("/response", 0) do |msg|
55
59
  if expected_responses.include?(msg.data)
@@ -59,10 +63,14 @@ describe PUB_SUB_CLASS do
59
63
  end
60
64
  end
61
65
  end
66
+
62
67
  10.times { |i| bus.publish("/echo", "0#{i}") }
63
- wait_for 4000 do
68
+
69
+ wait_for(2000) do
64
70
  expected_responses.empty?
65
71
  end
72
+
73
+ bus.publish("/echo", "done")
66
74
  bus.global_unsubscribe
67
75
  t.join
68
76
 
@@ -81,7 +89,9 @@ describe PUB_SUB_CLASS do
81
89
  Process.wait(pid)
82
90
  end
83
91
  end
92
+
84
93
  bus.global_unsubscribe
94
+ bus.destroy
85
95
  end
86
96
  end
87
97
  end
@@ -12,7 +12,7 @@ describe MessageBus::Rack::Middleware do
12
12
 
13
13
  before do
14
14
  bus = @bus = MessageBus::Instance.new
15
- @bus.configure(MESSAGE_BUS_CONFIG)
15
+ @bus.configure(test_config_for_backend(CURRENT_BACKEND))
16
16
  @bus.long_polling_enabled = false
17
17
  @bus.base_route = base_route if base_route
18
18
 
@@ -26,7 +26,6 @@ describe MessageBus::Rack::Middleware do
26
26
 
27
27
  @async_middleware = builder.to_app
28
28
  @message_bus_middleware = @async_middleware.app
29
- @bus.reset!
30
29
  end
31
30
 
32
31
  after do
@@ -84,7 +83,7 @@ describe MessageBus::Rack::Middleware do
84
83
  { "FOO" => "BAR" }
85
84
  end
86
85
 
87
- Thread.new do
86
+ t = Thread.new do
88
87
  wait_for(2000) { middleware.in_async? }
89
88
  bus.publish "/foo", "םוֹלשָׁ"
90
89
  end
@@ -97,6 +96,7 @@ describe MessageBus::Rack::Middleware do
97
96
  parsed[0]["data"].must_equal "םוֹלשָׁ"
98
97
 
99
98
  last_response.headers["FOO"].must_equal "BAR"
99
+ t.join
100
100
  end
101
101
 
102
102
  it "should timeout within its alloted slot" do
@@ -143,13 +143,12 @@ describe MessageBus::Rack::Middleware do
143
143
  end
144
144
 
145
145
  describe "diagnostics" do
146
- it "should return a 403 if a user attempts to get at the _diagnostics path" do
146
+ it "should return a 403 if an unauthorized user attempts to get at the _diagnostics path" do
147
147
  get "/message-bus/_diagnostics"
148
148
  last_response.status.must_equal 403
149
149
  end
150
150
 
151
151
  it "should get a 200 with html for an authorized user" do
152
-
153
152
  def @bus.is_admin_lookup
154
153
  proc { |_| true }
155
154
  end
@@ -172,7 +171,6 @@ describe MessageBus::Rack::Middleware do
172
171
  end
173
172
 
174
173
  it "should get the script it asks for" do
175
-
176
174
  def @bus.is_admin_lookup
177
175
  proc { |_| true }
178
176
  end
@@ -181,6 +179,15 @@ describe MessageBus::Rack::Middleware do
181
179
  last_response.status.must_equal 200
182
180
  last_response.content_type.must_equal "application/javascript;charset=UTF-8"
183
181
  end
182
+
183
+ it "should return 404 for invalid assets path" do
184
+ def @bus.is_admin_lookup
185
+ proc { |_| true }
186
+ end
187
+
188
+ get "/message-bus/_diagnostics/assets/../Gemfile"
189
+ last_response.status.must_equal 404
190
+ end
184
191
  end
185
192
 
186
193
  describe "polling" do
@@ -414,6 +421,11 @@ describe MessageBus::Rack::Middleware do
414
421
  JSON.parse(last_response.body).first["data"].must_equal('json' => true)
415
422
  end
416
423
 
424
+ it "should tell Rack to skip committing the session" do
425
+ post "/message-bus/1234", {}, { "rack.session.options" => {} }
426
+ last_request.env["rack.session.options"][:skip].must_equal true
427
+ end
428
+
417
429
  describe "on_middleware_error handling" do
418
430
  it "allows error handling of middleware failures" do
419
431
  @bus.on_middleware_error do |_env, err|
@@ -2,7 +2,6 @@
2
2
 
3
3
  require_relative '../spec_helper'
4
4
  require 'message_bus'
5
- require 'redis'
6
5
 
7
6
  describe MessageBus do
8
7
  before do
@@ -10,7 +9,7 @@ describe MessageBus do
10
9
  @bus.site_id_lookup do
11
10
  "magic"
12
11
  end
13
- @bus.configure(MESSAGE_BUS_CONFIG)
12
+ @bus.configure(test_config_for_backend(CURRENT_BACKEND))
14
13
  end
15
14
 
16
15
  after do
@@ -24,7 +23,8 @@ describe MessageBus do
24
23
  @bus.off?.must_equal true
25
24
  end
26
25
 
27
- it "can call destroy twice" do
26
+ it "can call destroy multiple times" do
27
+ @bus.destroy
28
28
  @bus.destroy
29
29
  @bus.destroy
30
30
  end
@@ -98,7 +98,7 @@ describe MessageBus do
98
98
  client_ids.must_equal ['a', 'b']
99
99
  end
100
100
 
101
- it "should recover from a redis flush" do
101
+ it "should recover from a reset" do
102
102
  data = nil
103
103
  @bus.subscribe("/chuck") do |msg|
104
104
  data = msg.data
@@ -162,7 +162,7 @@ describe MessageBus do
162
162
  data.must_equal 'norris'
163
163
  site_id.must_equal 'magic'
164
164
  channel.must_equal '/chuck'
165
- user_ids.must_equal [1, 2, 3]
165
+ user_ids.to_a.must_equal [1, 2, 3]
166
166
  end
167
167
 
168
168
  it "should get global messages if it subscribes to them" do
@@ -307,7 +307,7 @@ describe MessageBus do
307
307
  end
308
308
  end
309
309
 
310
- it "should support forking properly do" do
310
+ it "should support forking properly" do
311
311
  test_never :memory
312
312
 
313
313
  data = []
@@ -316,7 +316,7 @@ describe MessageBus do
316
316
  end
317
317
 
318
318
  @bus.publish("/hello", "pre-fork")
319
- wait_for(2000) { data.length > 0 }
319
+ wait_for(2000) { data.length == 1 }
320
320
 
321
321
  if child = Process.fork
322
322
  # The child was forked and we received its PID
@@ -328,6 +328,7 @@ describe MessageBus do
328
328
  else
329
329
  begin
330
330
  @bus.after_fork
331
+ GC.start
331
332
  @bus.publish("/hello", "from-fork")
332
333
  ensure
333
334
  exit!(0)
@@ -336,7 +337,11 @@ describe MessageBus do
336
337
 
337
338
  wait_for(2000) { data.length == 3 }
338
339
 
339
- data.must_equal(["pre-fork", "from-fork", "continuation"])
340
+ @bus.publish("/hello", "after-fork")
341
+
342
+ wait_for(2000) { data.length == 4 }
343
+
344
+ data.must_equal(["pre-fork", "from-fork", "continuation", "after-fork"])
340
345
  end
341
346
 
342
347
  describe '#register_client_message_filter' do
data/spec/spec_helper.rb CHANGED
@@ -11,18 +11,17 @@ require 'minitest/global_expectations'
11
11
 
12
12
  require_relative "helpers"
13
13
 
14
- backend = (ENV['MESSAGE_BUS_BACKEND'] || :redis).to_sym
15
- MESSAGE_BUS_CONFIG = test_config_for_backend(backend)
16
- require "message_bus/backends/#{backend}"
17
- PUB_SUB_CLASS = MessageBus::BACKENDS.fetch(backend)
18
- puts "Running with backend: #{backend}"
14
+ CURRENT_BACKEND = (ENV['MESSAGE_BUS_BACKEND'] || :redis).to_sym
15
+
16
+ require "message_bus/backends/#{CURRENT_BACKEND}"
17
+ PUB_SUB_CLASS = MessageBus::BACKENDS.fetch(CURRENT_BACKEND)
18
+
19
+ puts "Running with backend: #{CURRENT_BACKEND}"
19
20
 
20
21
  def test_only(*backends)
21
- backend = MESSAGE_BUS_CONFIG[:backend]
22
- skip "Test doesn't apply to #{backend}" unless backends.include?(backend)
22
+ skip "Test doesn't apply to #{CURRENT_BACKEND}" unless backends.include?(CURRENT_BACKEND)
23
23
  end
24
24
 
25
25
  def test_never(*backends)
26
- backend = MESSAGE_BUS_CONFIG[:backend]
27
- skip "Test doesn't apply to #{backend}" if backends.include?(backend)
26
+ skip "Test doesn't apply to #{CURRENT_BACKEND}" if backends.include?(CURRENT_BACKEND)
28
27
  end