amq-protocol 2.3.3 → 2.8.0

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +85 -2
  3. data/LICENSE +1 -1
  4. data/README.md +2 -7
  5. data/lib/amq/bit_set.rb +2 -1
  6. data/lib/amq/endianness.rb +2 -0
  7. data/lib/amq/int_allocator.rb +3 -3
  8. data/lib/amq/pack.rb +33 -42
  9. data/lib/amq/protocol/channel_close.rb +24 -0
  10. data/lib/amq/protocol/client.rb +31 -40
  11. data/lib/amq/protocol/constants.rb +2 -0
  12. data/lib/amq/protocol/exceptions.rb +3 -1
  13. data/lib/amq/protocol/float_32bit.rb +2 -0
  14. data/lib/amq/protocol/frame.rb +16 -10
  15. data/lib/amq/protocol/table.rb +20 -17
  16. data/lib/amq/protocol/table_value_decoder.rb +49 -53
  17. data/lib/amq/protocol/table_value_encoder.rb +2 -1
  18. data/lib/amq/protocol/type_constants.rb +1 -0
  19. data/lib/amq/protocol/version.rb +1 -1
  20. data/lib/amq/protocol.rb +1 -0
  21. data/lib/amq/settings.rb +1 -0
  22. data/lib/amq/uri.rb +30 -17
  23. metadata +5 -45
  24. data/.github/ISSUE_TEMPLATE.md +0 -18
  25. data/.github/workflows/ci.yml +0 -31
  26. data/.gitignore +0 -18
  27. data/.gitmodules +0 -3
  28. data/.rspec +0 -1
  29. data/.travis.yml +0 -17
  30. data/Gemfile +0 -22
  31. data/Rakefile +0 -55
  32. data/amq-protocol.gemspec +0 -27
  33. data/benchmarks/int_allocator.rb +0 -34
  34. data/benchmarks/pure/body_framing_with_256k_payload.rb +0 -28
  35. data/benchmarks/pure/body_framing_with_2k_payload.rb +0 -28
  36. data/codegen/__init__.py +0 -0
  37. data/codegen/amqp_0.9.1_changes.json +0 -1
  38. data/codegen/codegen.py +0 -151
  39. data/codegen/codegen_helpers.py +0 -162
  40. data/codegen/protocol.rb.pytemplate +0 -320
  41. data/generate.rb +0 -24
  42. data/profiling/README.md +0 -9
  43. data/profiling/stackprof/body_framing_with_2k_payload.rb +0 -33
  44. data/spec/amq/bit_set_spec.rb +0 -227
  45. data/spec/amq/int_allocator_spec.rb +0 -113
  46. data/spec/amq/pack_spec.rb +0 -68
  47. data/spec/amq/protocol/basic_spec.rb +0 -325
  48. data/spec/amq/protocol/blank_body_encoding_spec.rb +0 -9
  49. data/spec/amq/protocol/channel_spec.rb +0 -127
  50. data/spec/amq/protocol/confirm_spec.rb +0 -41
  51. data/spec/amq/protocol/connection_spec.rb +0 -146
  52. data/spec/amq/protocol/constants_spec.rb +0 -10
  53. data/spec/amq/protocol/exchange_spec.rb +0 -106
  54. data/spec/amq/protocol/frame_spec.rb +0 -92
  55. data/spec/amq/protocol/method_spec.rb +0 -43
  56. data/spec/amq/protocol/queue_spec.rb +0 -126
  57. data/spec/amq/protocol/table_spec.rb +0 -259
  58. data/spec/amq/protocol/tx_spec.rb +0 -55
  59. data/spec/amq/protocol/value_decoder_spec.rb +0 -86
  60. data/spec/amq/protocol/value_encoder_spec.rb +0 -140
  61. data/spec/amq/protocol_spec.rb +0 -812
  62. data/spec/amq/settings_spec.rb +0 -22
  63. data/spec/amq/uri_parsing_spec.rb +0 -280
  64. data/spec/spec_helper.rb +0 -29
@@ -1,259 +0,0 @@
1
- require 'time'
2
-
3
- module AMQ
4
- module Protocol
5
- RSpec.describe Table do
6
- timestamp = Time.utc(2010, 12, 31, 23, 58, 59)
7
- bigdecimal_1 = BigDecimal("1.0")
8
- bigdecimal_2 = BigDecimal("5E-3")
9
-
10
- DATA = {
11
- {} => "\x00\x00\x00\x00",
12
- {"test" => 1} => "\x00\x00\x00\x0E\x04testl\x00\x00\x00\x00\x00\x00\x00\x01",
13
- {"float" => 1.92} => "\x00\x00\x00\x0F\x05floatd?\xFE\xB8Q\xEB\x85\x1E\xB8",
14
- {"test" => "string"} => "\x00\x00\x00\x10\x04testS\x00\x00\x00\x06string",
15
- {"test" => {}} => "\x00\x00\x00\n\x04testF\x00\x00\x00\x00",
16
- {"test" => bigdecimal_1} => "\x00\x00\x00\v\x04testD\x00\x00\x00\x00\x01",
17
- {"test" => bigdecimal_2} => "\x00\x00\x00\v\x04testD\x03\x00\x00\x00\x05",
18
- {"test" => timestamp} => "\x00\x00\x00\x0e\x04testT\x00\x00\x00\x00M\x1enC"
19
- }
20
-
21
- describe ".encode" do
22
- it "should return \"\x00\x00\x00\x00\" for nil" do
23
- encoded_value = "\x00\x00\x00\x00"
24
-
25
- expect(Table.encode(nil)).to eql(encoded_value)
26
- end
27
-
28
- it "should serialize { :test => true }" do
29
- expect(Table.encode(:test => true)).
30
- to eql("\x00\x00\x00\a\x04testt\x01".force_encoding(Encoding::ASCII_8BIT))
31
- end
32
-
33
- it "should serialize { :test => false }" do
34
- expect(Table.encode(:test => false)).
35
- to eql("\x00\x00\x00\a\x04testt\x00".force_encoding(Encoding::ASCII_8BIT))
36
- end
37
-
38
- it "should serialize { :coordinates => { :latitude => 59.35 } }" do
39
- expect(Table.encode(:coordinates => { :latitude => 59.35 })).
40
- to eql("\x00\x00\x00#\vcoordinatesF\x00\x00\x00\x12\blatituded@M\xAC\xCC\xCC\xCC\xCC\xCD".force_encoding(Encoding::ASCII_8BIT))
41
- end
42
-
43
- it "should serialize { :coordinates => { :longitude => 18.066667 } }" do
44
- expect(Table.encode(:coordinates => { :longitude => 18.066667 })).
45
- to eql("\x00\x00\x00$\vcoordinatesF\x00\x00\x00\x13\tlongituded@2\x11\x11\x16\xA8\xB8\xF1".force_encoding(Encoding::ASCII_8BIT))
46
- end
47
-
48
- it "should serialize long UTF-8 strings and symbols" do
49
- long_utf8 = "à" * 192
50
- long_ascii8 = long_utf8.dup.force_encoding(::Encoding::ASCII_8BIT)
51
-
52
- input = { "utf8_string" => long_utf8, "utf8_symbol" => long_utf8.to_sym }
53
- output = { "utf8_string" => long_ascii8, "utf8_symbol" => long_ascii8 }
54
-
55
- expect(Table.decode(Table.encode(input))).to eq(output)
56
- end
57
-
58
- DATA.each do |data, encoded|
59
- it "should return #{encoded.inspect} for #{data.inspect}" do
60
- expect(Table.encode(data)).to eql(encoded.force_encoding(Encoding::ASCII_8BIT))
61
- end
62
- end
63
- end
64
-
65
- describe ".decode" do
66
- DATA.each do |data, encoded|
67
- it "should return #{data.inspect} for #{encoded.inspect}" do
68
- expect(Table.decode(encoded)).to eql(data)
69
- end
70
-
71
- it "is capable of decoding what it encodes" do
72
- expect(Table.decode(Table.encode(data))).to eq(data)
73
- end
74
- end # DATA.each
75
-
76
-
77
- it "is capable of decoding boolean table values" do
78
- input1 = { "boolval" => true }
79
- expect(Table.decode(Table.encode(input1))).to eq(input1)
80
-
81
-
82
- input2 = { "boolval" => false }
83
- expect(Table.decode(Table.encode(input2))).to eq(input2)
84
- end
85
-
86
-
87
- it "is capable of decoding nil table values" do
88
- input = { "nilval" => nil }
89
- expect(Table.decode(Table.encode(input))).to eq(input)
90
- end
91
-
92
- it "is capable of decoding nil table in nested hash/map values" do
93
- input = { "hash" => {"nil" => nil} }
94
- expect(Table.decode(Table.encode(input))).to eq(input)
95
- end
96
-
97
- it "is capable of decoding string table values" do
98
- input = { "stringvalue" => "string" }
99
- expect(Table.decode(Table.encode(input))).to eq(input)
100
-
101
- expect(Table.decode("\x00\x00\x00\x17\vstringvalueS\x00\x00\x00\x06string")).to eq(input)
102
- end
103
-
104
- it "is capable of decoding byte array table values (as Ruby strings)" do
105
- expect(Table.decode("\x00\x00\x00\x17\vstringvaluex\x00\x00\x00\x06string")).to eq({"stringvalue" => "string"})
106
- end
107
-
108
- it "is capable of decoding string table values with UTF-8 characters" do
109
- input = {
110
- "строка".force_encoding(::Encoding::ASCII_8BIT) => "значение".force_encoding(::Encoding::ASCII_8BIT)
111
- }
112
- expect(Table.decode(Table.encode(input))).to eq(input)
113
- end
114
-
115
-
116
- it "is capable of decoding integer table values" do
117
- input = { "intvalue" => 10 }
118
- expect(Table.decode(Table.encode(input))).to eq(input)
119
- end
120
-
121
-
122
- it "is capable of decoding signed integer table values" do
123
- input = { "intvalue" => -10 }
124
- expect(Table.decode(Table.encode(input))).to eq(input)
125
- end
126
-
127
-
128
- it "is capable of decoding long table values" do
129
- input = { "longvalue" => 912598613 }
130
- expect(Table.decode(Table.encode(input))).to eq(input)
131
- end
132
-
133
-
134
-
135
- it "is capable of decoding float table values" do
136
- input = { "floatvalue" => 100.0 }
137
- expect(Table.decode(Table.encode(input))).to eq(input)
138
- end
139
-
140
-
141
-
142
- it "is capable of decoding time table values" do
143
- input = { "intvalue" => Time.parse("2011-07-14 01:17:46 +0400") }
144
- expect(Table.decode(Table.encode(input))).to eq(input)
145
- end
146
-
147
-
148
-
149
- it "is capable of decoding empty hash table values" do
150
- input = { "hashvalue" => Hash.new }
151
- expect(Table.decode(Table.encode(input))).to eq(input)
152
- end
153
-
154
-
155
-
156
- it "is capable of decoding empty array table values" do
157
- input = { "arrayvalue" => Array.new }
158
- expect(Table.decode(Table.encode(input))).to eq(input)
159
- end
160
-
161
-
162
- it "is capable of decoding single string value array table values" do
163
- input = { "arrayvalue" => ["amq-protocol"] }
164
- expect(Table.decode(Table.encode(input))).to eq(input)
165
- end
166
-
167
-
168
-
169
- it "is capable of decoding simple nested hash table values" do
170
- input = { "hashvalue" => { "a" => "b" } }
171
- expect(Table.decode(Table.encode(input))).to eq(input)
172
- end
173
-
174
-
175
-
176
- it "is capable of decoding nil table values" do
177
- input = { "nil" => nil }
178
- expect(Table.decode(Table.encode(input))).to eq(input)
179
- end
180
-
181
- it 'is capable of decoding 8bit signed integers' do
182
- output = TableValueDecoder.decode_byte("\xC0",0).first
183
- expect(output).to eq(192)
184
- end
185
-
186
- it 'is capable of decoding 16bit signed integers' do
187
- output = TableValueDecoder.decode_short("\x06\x8D", 0).first
188
- expect(output).to eq(1677)
189
- end
190
-
191
- it "is capable of decoding tables" do
192
- input = {
193
- "boolval" => true,
194
- "intval" => 1,
195
- "strval" => "Test",
196
- "timestampval" => Time.parse("2011-07-14 01:17:46 +0400"),
197
- "floatval" => 3.14,
198
- "longval" => 912598613,
199
- "hashval" => { "protocol" => "AMQP091", "true" => true, "false" => false, "nil" => nil }
200
- }
201
- expect(Table.decode(Table.encode(input))).to eq(input)
202
- end
203
-
204
-
205
-
206
- it "is capable of decoding deeply nested tables" do
207
- input = {
208
- "hashval" => {
209
- "protocol" => {
210
- "name" => "AMQP",
211
- "major" => 0,
212
- "minor" => "9",
213
- "rev" => 1.0,
214
- "spec" => {
215
- "url" => "http://bit.ly/hw2ELX",
216
- "utf8" => "à bientôt"
217
- }
218
- },
219
- "true" => true,
220
- "false" => false,
221
- "nil" => nil
222
- }
223
- }
224
- expect(Table.decode(Table.encode(input))).to eq(input.tap { |r| r["hashval"]["protocol"]["spec"]["utf8"].force_encoding(::Encoding::ASCII_8BIT) })
225
- end
226
-
227
-
228
-
229
- it "is capable of decoding array values in tables" do
230
- input1 = {
231
- "arrayval1" => [198, 3, 77, 8.0, ["inner", "array", { "oh" => "well", "it" => "should work", "3" => 6 }], "two", { "a" => "value", "is" => nil }],
232
- "arrayval2" => [198, 3, 77, "two", { "a" => "value", "is" => nil }, 8.0, ["inner", "array", { "oh" => "well", "it" => "should work", "3" => 6 }]]
233
- }
234
- expect(Table.decode(Table.encode(input1))).to eq(input1)
235
-
236
- now = Time.now
237
- input2 = {
238
- "coordinates" => {
239
- "latitude" => 59.35,
240
- "longitude" => 18.066667
241
- },
242
- "participants" => 11,
243
- "venue" => "Stockholm",
244
- "true_field" => true,
245
- "false_field" => false,
246
- "nil_field" => nil,
247
- "ary_field" => ["one", 2.0, 3]
248
- }
249
-
250
- expect(Table.decode(Table.encode(input2))).to eq(input2)
251
-
252
- input3 = { "timely" => { "now" => now } }
253
- expect(Table.decode(Table.encode(input3))["timely"]["now"].to_i).to eq(now.to_i)
254
- end
255
-
256
- end # describe
257
- end
258
- end
259
- end
@@ -1,55 +0,0 @@
1
- # encoding: binary
2
-
3
- module AMQ
4
- module Protocol
5
- class Tx
6
- RSpec.describe Select do
7
- describe '.encode' do
8
- it 'encodes the parameters into a MethodFrame' do
9
- channel = 1
10
- method_frame = Select.encode(channel)
11
- expect(method_frame.payload).to eq("\000Z\000\n")
12
- expect(method_frame.channel).to eq(1)
13
- end
14
- end
15
- end
16
-
17
- # RSpec.describe SelectOk do
18
- # describe '.decode' do
19
- # end
20
- # end
21
-
22
- RSpec.describe Commit do
23
- describe '.encode' do
24
- it 'encodes the parameters into a MethodFrame' do
25
- channel = 1
26
- method_frame = Commit.encode(channel)
27
- expect(method_frame.payload).to eq("\000Z\000\024")
28
- expect(method_frame.channel).to eq(1)
29
- end
30
- end
31
- end
32
-
33
- # RSpec.describe CommitOk do
34
- # describe '.decode' do
35
- # end
36
- # end
37
-
38
- RSpec.describe Rollback do
39
- describe '.encode' do
40
- it 'encodes the parameters into a MethodFrame' do
41
- channel = 1
42
- method_frame = Rollback.encode(channel)
43
- expect(method_frame.payload).to eq("\000Z\000\036")
44
- expect(method_frame.channel).to eq(1)
45
- end
46
- end
47
- end
48
-
49
- # RSpec.describe RollbackOk do
50
- # describe '.decode' do
51
- # end
52
- # end
53
- end
54
- end
55
- end
@@ -1,86 +0,0 @@
1
- require 'time'
2
- require "amq/protocol/table_value_decoder"
3
-
4
- module AMQ
5
- module Protocol
6
- RSpec.describe TableValueDecoder do
7
-
8
- it "is capable of decoding basic arrays TableValueEncoder encodes" do
9
- input1 = [1, 2, 3]
10
-
11
- value, _offset = described_class.decode_array(TableValueEncoder.encode(input1), 1)
12
- expect(value.size).to eq(3)
13
- expect(value.first).to eq(1)
14
- expect(value).to eq(input1)
15
-
16
-
17
-
18
- input2 = ["one", 2, "three"]
19
-
20
- value, _offset = described_class.decode_array(TableValueEncoder.encode(input2), 1)
21
- expect(value.size).to eq(3)
22
- expect(value.first).to eq("one")
23
- expect(value).to eq(input2)
24
-
25
-
26
-
27
- input3 = ["one", 2, "three", 4.0, 5000000.0]
28
-
29
- value, _offset = described_class.decode_array(TableValueEncoder.encode(input3), 1)
30
- expect(value.size).to eq(5)
31
- expect(value.last).to eq(5000000.0)
32
- expect(value).to eq(input3)
33
- end
34
-
35
-
36
-
37
- it "is capable of decoding arrays TableValueEncoder encodes" do
38
- input1 = [{ "one" => 2 }, 3]
39
- data1 = TableValueEncoder.encode(input1)
40
-
41
- # puts(TableValueEncoder.encode({ "one" => 2 }).inspect)
42
- # puts(TableValueEncoder.encode(input1).inspect)
43
-
44
-
45
- value, _offset = described_class.decode_array(data1, 1)
46
- expect(value.size).to eq(2)
47
- expect(value.first).to eq(Hash["one" => 2])
48
- expect(value).to eq(input1)
49
-
50
-
51
-
52
- input2 = ["one", 2, { "three" => { "four" => 5.0 } }]
53
-
54
- value, _offset = described_class.decode_array(TableValueEncoder.encode(input2), 1)
55
- expect(value.size).to eq(3)
56
- expect(value.last["three"]["four"]).to eq(5.0)
57
- expect(value).to eq(input2)
58
- end
59
-
60
- it "is capable of decoding 32 bit float values" do
61
- input = Float32Bit.new(10.0)
62
- data = TableValueEncoder.encode(input)
63
-
64
- value = described_class.decode_32bit_float(data, 1)[0]
65
- expect(value).to eq(10.0)
66
- end
67
-
68
- context "8bit/byte decoding" do
69
- let(:examples) {
70
- {
71
- 0x00 => "\x00",
72
- 0x01 => "\x01",
73
- 0x10 => "\x10",
74
- 255 => "\xFF" # not -1
75
- }
76
- }
77
-
78
- it "is capable of decoding byte values" do
79
- examples.each do |key, value|
80
- expect(described_class.decode_byte(value, 0).first).to eq(key)
81
- end
82
- end
83
- end
84
- end
85
- end
86
- end
@@ -1,140 +0,0 @@
1
- require 'time'
2
- require "amq/protocol/table_value_encoder"
3
- require "amq/protocol/float_32bit"
4
-
5
- module AMQ
6
- module Protocol
7
- RSpec.describe TableValueEncoder do
8
-
9
- it "calculates size of string field values" do
10
- expect(described_class.field_value_size("amqp")).to eq(9)
11
- expect(described_class.encode("amqp").bytesize).to eq(9)
12
-
13
- expect(described_class.field_value_size("amq-protocol")).to eq(17)
14
- expect(described_class.encode("amq-protocol").bytesize).to eq(17)
15
-
16
- expect(described_class.field_value_size("à bientôt")).to eq(16)
17
- expect(described_class.encode("à bientôt").bytesize).to eq(16)
18
- end
19
-
20
- it "calculates size of integer field values" do
21
- expect(described_class.field_value_size(10)).to eq(9)
22
- expect(described_class.encode(10).bytesize).to eq(9)
23
- end
24
-
25
- it "calculates size of float field values (considering them to be 64-bit)" do
26
- expect(described_class.field_value_size(10.0)).to eq(9)
27
- expect(described_class.encode(10.0).bytesize).to eq(9)
28
-
29
- expect(described_class.field_value_size(120000.0)).to eq(9)
30
- expect(described_class.encode(120000.0).bytesize).to eq(9)
31
- end
32
-
33
- it "calculates size of float field values (boxed as 32-bit)" do
34
- expect(described_class.encode(AMQ::Protocol::Float32Bit.new(10.0)).bytesize).to eq(5)
35
- expect(described_class.encode(AMQ::Protocol::Float32Bit.new(120000.0)).bytesize).to eq(5)
36
- end
37
-
38
- it "calculates size of boolean field values" do
39
- expect(described_class.field_value_size(true)).to eq(2)
40
- expect(described_class.encode(true).bytesize).to eq(2)
41
-
42
- expect(described_class.field_value_size(false)).to eq(2)
43
- expect(described_class.encode(false).bytesize).to eq(2)
44
- end
45
-
46
- it "calculates size of void field values" do
47
- expect(described_class.field_value_size(nil)).to eq(1)
48
- expect(described_class.encode(nil).bytesize).to eq(1)
49
- end
50
-
51
- it "calculates size of time field values" do
52
- t = Time.parse("2011-07-14 01:17:46 +0400")
53
-
54
- expect(described_class.field_value_size(t)).to eq(9)
55
- expect(described_class.encode(t).bytesize).to eq(9)
56
- end
57
-
58
-
59
- it "calculates size of basic table field values" do
60
- input1 = { "key" => "value" }
61
- expect(described_class.field_value_size(input1)).to eq(19)
62
- expect(described_class.encode(input1).bytesize).to eq(19)
63
-
64
-
65
- input2 = { "intval" => 1 }
66
- expect(described_class.field_value_size(input2)).to eq(21)
67
- expect(described_class.encode(input2).bytesize).to eq(21)
68
-
69
-
70
- input3 = { "intval" => 1, "key" => "value" }
71
- expect(described_class.field_value_size(input3)).to eq(35)
72
- expect(described_class.encode(input3).bytesize).to eq(35)
73
- end
74
-
75
-
76
- it "calculates size of table field values" do
77
- input1 = {
78
- "hashval" => {
79
- "protocol" => {
80
- "name" => "AMQP",
81
- "major" => 0,
82
- "minor" => "9",
83
- "rev" => 1.0,
84
- "spec" => {
85
- "url" => "http://bit.ly/hw2ELX",
86
- "utf8" => "à bientôt".force_encoding(::Encoding::ASCII_8BIT)
87
- }
88
- },
89
- "true" => true,
90
- "false" => false,
91
- "nil" => nil
92
- }
93
- }
94
-
95
- expect(described_class.field_value_size(input1)).to eq(166)
96
- # puts(described_class.encode(input1).inspect)
97
- expect(described_class.encode(input1).bytesize).to eq(166)
98
-
99
-
100
-
101
- input2 = {
102
- "boolval" => true,
103
- "intval" => 1,
104
- "strval" => "Test",
105
- "timestampval" => Time.parse("2011-07-14 01:17:46 +0400"),
106
- "floatval" => 3.14,
107
- "longval" => 912598613,
108
- "hashval" => { "protocol" => "AMQP091", "true" => true, "false" => false, "nil" => nil }
109
- }
110
-
111
- expect(described_class.field_value_size(input2)).to eq(158)
112
- expect(described_class.encode(input2).bytesize).to eq(158)
113
- end
114
-
115
- it "calculates size of basic array field values" do
116
- input1 = [1, 2, 3]
117
-
118
- expect(described_class.field_value_size(input1)).to eq(32)
119
- expect(described_class.encode(input1).bytesize).to eq(32)
120
-
121
-
122
- input2 = ["one", "two", "three"]
123
- expect(described_class.field_value_size(input2)).to eq(31)
124
- expect(described_class.encode(input2).bytesize).to eq(31)
125
-
126
-
127
- input3 = ["one", 2, "three"]
128
- expect(described_class.field_value_size(input3)).to eq(32)
129
- expect(described_class.encode(input3).bytesize).to eq(32)
130
-
131
-
132
- input4 = ["one", 2, "three", ["four", 5, [6.0]]]
133
- expect(described_class.field_value_size(input4)).to eq(69)
134
- expect(described_class.encode(input4).bytesize).to eq(69)
135
- end
136
-
137
-
138
- end # TableValueEncoder
139
- end # Protocol
140
- end # AMQ