amqp 0.7.0 → 0.7.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.
Files changed (77) hide show
  1. data/.gitignore +3 -2
  2. data/CHANGELOG +25 -0
  3. data/Gemfile +4 -2
  4. data/README.md +2 -0
  5. data/{amqp.todo → TODO} +1 -3
  6. data/amqp.gemspec +3 -3
  7. data/bin/irb +2 -2
  8. data/bin/jenkins.sh +25 -0
  9. data/bin/set_test_suite_realms_up.sh +21 -0
  10. data/doc/EXAMPLE_01_PINGPONG +1 -1
  11. data/doc/EXAMPLE_02_CLOCK +1 -1
  12. data/doc/EXAMPLE_03_STOCKS +1 -1
  13. data/doc/EXAMPLE_04_MULTICLOCK +1 -1
  14. data/doc/EXAMPLE_05_ACK +1 -1
  15. data/doc/EXAMPLE_05_POP +1 -1
  16. data/doc/EXAMPLE_06_HASHTABLE +1 -1
  17. data/examples/{mq/ack.rb → ack.rb} +6 -6
  18. data/examples/{mq/automatic_binding_for_default_direct_exchange.rb → automatic_binding_for_default_direct_exchange.rb} +4 -4
  19. data/examples/{mq/callbacks.rb → callbacks.rb} +2 -2
  20. data/examples/{mq/clock.rb → clock.rb} +5 -5
  21. data/examples/{mq/hashtable.rb → hashtable.rb} +4 -4
  22. data/examples/{mq/internal.rb → internal.rb} +5 -5
  23. data/examples/{mq/logger.rb → logger.rb} +5 -5
  24. data/examples/{mq/multiclock.rb → multiclock.rb} +4 -4
  25. data/examples/{mq/pingpong.rb → pingpong.rb} +5 -5
  26. data/examples/{mq/pop.rb → pop.rb} +3 -3
  27. data/examples/{mq/primes-simple.rb → primes-simple.rb} +0 -0
  28. data/examples/{mq/primes.rb → primes.rb} +6 -6
  29. data/examples/{amqp/simple.rb → simple.rb} +1 -1
  30. data/examples/{mq/stocks.rb → stocks.rb} +5 -5
  31. data/lib/amqp.rb +8 -112
  32. data/lib/amqp/basic_client.rb +58 -0
  33. data/lib/amqp/channel.rb +937 -0
  34. data/lib/amqp/client.rb +72 -79
  35. data/lib/{mq → amqp}/collection.rb +12 -2
  36. data/lib/amqp/connection.rb +115 -0
  37. data/lib/amqp/exceptions.rb +18 -0
  38. data/lib/{mq → amqp}/exchange.rb +32 -34
  39. data/lib/{ext → amqp/ext}/em.rb +1 -1
  40. data/lib/{ext → amqp/ext}/emfork.rb +0 -0
  41. data/lib/amqp/frame.rb +3 -3
  42. data/lib/{mq → amqp}/header.rb +5 -11
  43. data/lib/{mq → amqp}/logger.rb +2 -2
  44. data/lib/amqp/protocol.rb +2 -2
  45. data/lib/{mq → amqp}/queue.rb +20 -17
  46. data/lib/{mq → amqp}/rpc.rb +20 -8
  47. data/lib/amqp/server.rb +1 -1
  48. data/lib/amqp/version.rb +1 -1
  49. data/lib/mq.rb +20 -964
  50. data/protocol/codegen.rb +1 -1
  51. data/research/api.rb +3 -3
  52. data/research/primes-forked.rb +5 -5
  53. data/research/primes-processes.rb +5 -5
  54. data/research/primes-threaded.rb +5 -5
  55. data/spec/integration/authentication_spec.rb +114 -0
  56. data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +13 -12
  57. data/spec/{unit/mq → integration}/channel_close_spec.rb +2 -2
  58. data/spec/{unit/mq → integration}/exchange_declaration_spec.rb +26 -14
  59. data/spec/{unit/mq → integration}/queue_declaration_spec.rb +4 -4
  60. data/spec/integration/queue_exclusivity_spec.rb +95 -0
  61. data/spec/integration/reply_queue_communication_spec.rb +63 -0
  62. data/spec/integration/store_and_forward_spec.rb +121 -0
  63. data/spec/integration/topic_subscription_spec.rb +193 -0
  64. data/spec/integration/workload_distribution_spec.rb +245 -0
  65. data/spec/spec_helper.rb +16 -32
  66. data/spec/unit/{mq/mq_basic_spec.rb → amqp/basic_spec.rb} +4 -4
  67. data/spec/unit/{mq → amqp}/collection_spec.rb +22 -7
  68. data/spec/unit/amqp/connection_spec.rb +116 -0
  69. data/spec/unit/amqp/frame_spec.rb +18 -18
  70. data/spec/unit/amqp/protocol_spec.rb +9 -11
  71. metadata +54 -49
  72. data/lib/ext/blankslate.rb +0 -9
  73. data/spec/mq_helper.rb +0 -70
  74. data/spec/unit/amqp/client_spec.rb +0 -472
  75. data/spec/unit/amqp/misc_spec.rb +0 -123
  76. data/spec/unit/mq/misc_spec.rb +0 -228
  77. data/spec/unit/mq/queue_spec.rb +0 -71
@@ -4,7 +4,7 @@ require 'rubygems'
4
4
  require 'json'
5
5
 
6
6
  name = 'amqp-0.8.json'
7
- path = File.dirname(__FILE__)+'/'+name
7
+ path = File.join(File.dirname(__FILE__), name)
8
8
  s = JSON.parse(File.read(path))
9
9
 
10
10
  # require 'pp'
@@ -31,11 +31,11 @@ AMQP.start do |amqp|
31
31
  end
32
32
  end
33
33
 
34
- def MQ.method_missing meth, *args, &blk
35
- (Thread.current[:mq] ||= MQ.new).__send__(meth, *args, &blk)
34
+ def AMQP::Channel.method_missing meth, *args, &blk
35
+ (Thread.current[:mq] ||= AMQP::Channel.new).__send__(meth, *args, &blk)
36
36
  end
37
37
 
38
- mq = MQ.new
38
+ mq = AMQP::Channel.new
39
39
  mq.direct.publish('alkjsdf', :key => 'name')
40
40
  mq.topic # 'amq.topic'
41
41
  mq.topic('test').publish('some data', :key => 'stock.usd.*')
@@ -23,7 +23,7 @@ def log(*args)
23
23
  p args
24
24
  end
25
25
 
26
- # MQ.logging = true
26
+ # AMQP::Channel.logging = true
27
27
 
28
28
  # worker
29
29
 
@@ -39,10 +39,10 @@ end
39
39
  end
40
40
  end
41
41
 
42
- MQ.queue('prime checker').subscribe { |info, num|
42
+ AMQP::Channel.queue('prime checker').subscribe { |info, num|
43
43
  log "prime checker #{Process.pid}", :prime?, num
44
44
  if Integer(num).prime?
45
- MQ.queue(info.reply_to).publish(num, :reply_to => Process.pid)
45
+ AMQP::Channel.queue(info.reply_to).publish(num, :reply_to => Process.pid)
46
46
  end
47
47
  }
48
48
  }
@@ -51,7 +51,7 @@ end
51
51
  # controller
52
52
 
53
53
  EM.run {
54
- MQ.queue('prime collector').subscribe { |info, prime|
54
+ AMQP::Channel.queue('prime collector').subscribe { |info, prime|
55
55
  log 'prime collector', :received, prime, :from, info.reply_to
56
56
  (@primes ||= []) << Integer(prime)
57
57
  EM.stop_event_loop if prime == '499'
@@ -59,7 +59,7 @@ end
59
59
 
60
60
  MAX.times do |i|
61
61
  EM.next_tick do
62
- MQ.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
62
+ AMQP::Channel.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
63
63
  end
64
64
  end
65
65
  }
@@ -11,7 +11,7 @@ EM.run {
11
11
  p args
12
12
  end
13
13
 
14
- # MQ.logging = true
14
+ # AMQP::Channel.logging = true
15
15
 
16
16
  if ARGV[0] == 'worker'
17
17
 
@@ -23,24 +23,24 @@ EM.run {
23
23
  end
24
24
  end
25
25
 
26
- MQ.queue('prime checker').subscribe { |info, num|
26
+ AMQP::Channel.queue('prime checker').subscribe { |info, num|
27
27
  log "prime checker #{Process.pid}", :prime?, num
28
28
  if Integer(num).prime?
29
- MQ.queue(info.reply_to).publish(num, :reply_to => Process.pid)
29
+ AMQP::Channel.queue(info.reply_to).publish(num, :reply_to => Process.pid)
30
30
  EM.stop_event_loop if num == (MAX-1).to_s
31
31
  end
32
32
  }
33
33
 
34
34
  elsif ARGV[0] == 'controller'
35
35
 
36
- MQ.queue('prime collector').subscribe { |info, prime|
36
+ AMQP::Channel.queue('prime collector').subscribe { |info, prime|
37
37
  log 'prime collector', :received, prime, :from, info.reply_to
38
38
  (@primes ||= []) << Integer(prime)
39
39
  }
40
40
 
41
41
  MAX.times do |i|
42
42
  EM.next_tick do
43
- MQ.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
43
+ AMQP::Channel.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
44
44
  end
45
45
  end
46
46
 
@@ -9,7 +9,7 @@ def log(*args)
9
9
  p args
10
10
  end
11
11
 
12
- # MQ.logging = true
12
+ # AMQP::Channel.logging = true
13
13
 
14
14
  EM.run {
15
15
 
@@ -23,12 +23,12 @@ EM.run {
23
23
  end
24
24
  end
25
25
 
26
- MQ.queue('prime checker').subscribe { |info, num|
26
+ AMQP::Channel.queue('prime checker').subscribe { |info, num|
27
27
  EM.defer(proc {
28
28
 
29
29
  log "prime checker #{Process.pid}-#{Thread.current.object_id}", :prime?, num
30
30
  if Integer(num).prime?
31
- MQ.queue(info.reply_to).publish(num, :reply_to => "#{Process.pid}-#{Thread.current.object_id}")
31
+ AMQP::Channel.queue(info.reply_to).publish(num, :reply_to => "#{Process.pid}-#{Thread.current.object_id}")
32
32
  EM.stop_event_loop if num == '499'
33
33
  end
34
34
 
@@ -37,14 +37,14 @@ EM.run {
37
37
 
38
38
  # controller
39
39
 
40
- MQ.queue('prime collector').subscribe { |info, prime|
40
+ AMQP::Channel.queue('prime collector').subscribe { |info, prime|
41
41
  log 'prime collector', :received, prime, :from, info.reply_to
42
42
  (@primes ||= []) << Integer(prime)
43
43
  }
44
44
 
45
45
  MAX.times do |i|
46
46
  EM.next_tick do
47
- MQ.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
47
+ AMQP::Channel.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
48
48
  end
49
49
  end
50
50
 
@@ -0,0 +1,114 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "spec_helper"
3
+
4
+ describe "Authentication attempt" do
5
+
6
+ #
7
+ # Environment
8
+ #
9
+
10
+ include AMQP::Spec
11
+ include AMQP::SpecHelper
12
+
13
+ em_before { AMQP.cleanup_state }
14
+ em_after { AMQP.cleanup_state }
15
+
16
+ describe "with default connection parameters" do
17
+
18
+ #
19
+ # Examples
20
+ #
21
+
22
+ # assuming there is an account guest with password of "guest" that has
23
+ # access to / (default vhost)
24
+ context "when guest/guest has access to /" do
25
+ after :all do
26
+ done
27
+ end
28
+
29
+ it "succeeds" do
30
+ connection = AMQP.connect
31
+
32
+ done(0.3) {
33
+ connection.should be_connected
34
+ connection.close
35
+ }
36
+ end # it
37
+ end # context
38
+ end # describe
39
+
40
+
41
+ describe "with explicitly given connection parameters" do
42
+
43
+ #
44
+ # Examples
45
+ #
46
+
47
+ # assuming there is an account amqp_gem with password of "amqp_gem_password" that has
48
+ # access to /amqp_gem_testbed
49
+ context "when amqp_gem/amqp_gem_testbed has access to /amqp_gem_testbed" do
50
+ after :all do
51
+ done
52
+ end
53
+
54
+ context "and provided credentials are correct" do
55
+ it "succeeds" do
56
+ connection = AMQP.connect :username => "amqp_gem", :password => "amqp_gem_password", :vhost => "/amqp_gem_testbed"
57
+
58
+ done(0.3) {
59
+ connection.should be_connected
60
+ connection.close
61
+ }
62
+ end # it
63
+ end # context
64
+
65
+ context "and provided credentials ARE INCORRECT" do
66
+ it "fails" do
67
+ connection = AMQP.connect :user => "amqp_gem", :pass => Time.now.to_i.to_s, :vhost => "/amqp_gem_testbed"
68
+
69
+ done(0.5) {
70
+ connection.should_not be_connected
71
+ }
72
+ end # it
73
+ end
74
+ end # context
75
+ end
76
+
77
+
78
+ describe "with connection string" do
79
+
80
+ #
81
+ # Examples
82
+ #
83
+
84
+ # assuming there is an account amqp_gem with password of "amqp_gem_password" that has
85
+ # access to /amqp_gem_testbed
86
+ context "when amqp_gem/amqp_gem_testbed has access to /amqp_gem_testbed" do
87
+ after :all do
88
+ done
89
+ end
90
+
91
+ context "and provided credentials are correct" do
92
+ it "succeeds" do
93
+ connection = AMQP.connect "amqp://amqp_gem:amqp_gem_password@localhost/amqp_gem_testbed"
94
+
95
+ done(0.3) {
96
+ connection.should be_connected
97
+ connection.close
98
+ }
99
+ end # it
100
+ end # context
101
+
102
+ context "and provided credentials ARE INCORRECT" do
103
+ it "succeeds" do
104
+ connection = AMQP.connect "amqp://amqp_gem:#{Time.now.to_i}@localhost/amqp_gem_testbed"
105
+
106
+ done(0.5) {
107
+ connection.should_not be_connected
108
+ connection.close
109
+ }
110
+ end # it
111
+ end # context
112
+ end # context
113
+ end # describe
114
+ end # describe "Authentication attempt"
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # -*- coding: utf-8 -*-
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -10,25 +10,30 @@ describe "Queue that was bound to default direct exchange thanks to Automatic Mo
10
10
 
11
11
  include AMQP::Spec
12
12
 
13
- default_timeout 10
13
+ default_timeout 2
14
14
 
15
15
  amqp_before do
16
- @channel = MQ.new
16
+ @channel = AMQP::Channel.new
17
+ @channel.should be_open
17
18
 
18
19
  @queue1 = @channel.queue("queue1")
19
20
  @queue2 = @channel.queue("queue2")
20
21
 
21
22
  # Rely on default direct exchange binding, see section 2.1.2.4 Automatic Mode in AMQP 0.9.1 spec.
22
- @exchange = MQ::Exchange.default
23
+ @exchange = AMQP::Exchange.default(@channel)
23
24
  end
24
25
 
25
26
 
27
+ default_options AMQP_OPTS
28
+
26
29
 
27
30
  #
28
31
  # Examples
29
32
  #
30
33
 
31
34
  it "receives messages with routing key equals it's name" do
35
+ @exchange.channel.should == @channel
36
+
32
37
  number_of_received_messages = 0
33
38
  expected_number_of_messages = 3
34
39
  dispatched_data = "to be received by queue1"
@@ -36,14 +41,6 @@ describe "Queue that was bound to default direct exchange thanks to Automatic Mo
36
41
  @queue1.subscribe do |payload|
37
42
  number_of_received_messages += 1
38
43
  payload.should == dispatched_data
39
-
40
- if number_of_received_messages == expected_number_of_messages
41
- $stdout.puts "Got all the messages I expected, wrapping up..."
42
- done
43
- else
44
- n = expected_number_of_messages - number_of_received_messages
45
- $stdout.puts "Still waiting for #{n} more message(s)"
46
- end
47
44
  end # subscribe
48
45
 
49
46
  4.times do
@@ -57,5 +54,9 @@ describe "Queue that was bound to default direct exchange thanks to Automatic Mo
57
54
  4.times do
58
55
  @exchange.publish("some white noise", :routing_key => "killa key")
59
56
  end
57
+
58
+ done(0.2) {
59
+ number_of_received_messages.should == expected_number_of_messages
60
+ }
60
61
  end # it
61
62
  end # describe
@@ -2,13 +2,13 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe MQ, "#close(&callback)" do
5
+ describe AMQP, "#close(&callback)" do
6
6
  include AMQP::EMSpec
7
7
 
8
8
  default_timeout 5
9
9
 
10
10
  it "takes a callback which will run when we get back Channel.Close-Ok" do
11
- MQ.new.close do |amq|
11
+ AMQP::Channel.new.close do |amq|
12
12
  done
13
13
  end
14
14
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe MQ do
5
+ describe AMQP do
6
6
 
7
7
  #
8
8
  # Environment
@@ -13,7 +13,7 @@ describe MQ do
13
13
  default_timeout 10
14
14
 
15
15
  amqp_before do
16
- @channel = MQ.new
16
+ @channel = AMQP::Channel.new
17
17
  end
18
18
 
19
19
 
@@ -156,7 +156,7 @@ describe MQ do
156
156
 
157
157
  expect {
158
158
  @channel.direct("previously.declared.durable.direct.exchange", :durable => false)
159
- }.to raise_error(MQ::IncompatibleOptionsError)
159
+ }.to raise_error(AMQP::IncompatibleOptionsError)
160
160
 
161
161
  done
162
162
  end # it
@@ -275,7 +275,7 @@ describe MQ do
275
275
 
276
276
  expect {
277
277
  @channel.fanout("previously.declared.durable.topic.exchange", :durable => false)
278
- }.to raise_error(MQ::IncompatibleOptionsError)
278
+ }.to raise_error(AMQP::IncompatibleOptionsError)
279
279
 
280
280
  done
281
281
  end # it
@@ -388,12 +388,19 @@ describe MQ do
388
388
 
389
389
 
390
390
  context "when exchange is re-declared with parameters different from original declaration" do
391
- xit "raises an exception" do
392
- @channel.topic("previously.declared.durable.topic.exchange", :durable => true)
391
+ amqp_after do
392
+ done
393
+ end
394
+
395
+ it "raises an exception" do
396
+ channel = AMQP::Channel.new
397
+
398
+ channel.topic("previously.declared.durable.topic.exchange", :durable => true)
399
+ channel.should be_open
393
400
 
394
401
  expect {
395
- @channel.topic("previously.declared.durable.topic.exchange", :durable => false)
396
- }.to raise_error(MQ::IncompatibleOptionsError)
402
+ channel.topic("previously.declared.durable.topic.exchange", :durable => false)
403
+ }.to raise_error(AMQP::IncompatibleOptionsError)
397
404
 
398
405
  done
399
406
  end # it
@@ -417,9 +424,11 @@ describe MQ do
417
424
  end # context
418
425
 
419
426
  context "when exchange name is omitted" do
420
- xit "uses amq.match" do
421
- pending "Times out. MK."
427
+ amqp_after do
428
+ done
429
+ end
422
430
 
431
+ it "uses amq.match" do
423
432
  exchange = @channel.headers
424
433
  exchange.name.should == "amq.match"
425
434
  exchange.name.should_not == "amq.headers"
@@ -509,16 +518,19 @@ describe MQ do
509
518
 
510
519
 
511
520
  context "when exchange is re-declared with parameters different from original declaration" do
512
- xit "raises an exception" do
513
- pending "Times out. MK."
521
+ amqp_after do
522
+ done
523
+ end
524
+
525
+ it "raises an exception" do
514
526
  @channel.headers("previously.declared.durable.topic.exchange", :durable => true)
515
527
 
516
528
  expect {
517
529
  @channel.headers("previously.declared.durable.topic.exchange", :durable => false)
518
- }.to raise_error(MQ::IncompatibleOptionsError)
530
+ }.to raise_error(AMQP::IncompatibleOptionsError)
519
531
 
520
532
  done
521
533
  end # it
522
534
  end # context
523
535
  end # describe
524
- end # describe MQ
536
+ end # describe AMQP
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe MQ do
5
+ describe AMQP do
6
6
 
7
7
  #
8
8
  # Environment
@@ -13,7 +13,7 @@ describe MQ do
13
13
  default_timeout 5
14
14
 
15
15
  amqp_before do
16
- @channel = MQ.new
16
+ @channel = AMQP::Channel.new
17
17
  end
18
18
 
19
19
 
@@ -88,10 +88,10 @@ describe MQ do
88
88
 
89
89
  expect {
90
90
  @channel.queue("previously.declared.durable.queue", :durable => false)
91
- }.to raise_error(MQ::IncompatibleOptionsError)
91
+ }.to raise_error(AMQP::IncompatibleOptionsError)
92
92
 
93
93
  done
94
94
  end # it
95
95
  end # context
96
96
  end # describe
97
- end # describe MQ
97
+ end # describe AMQP