deimos-ruby 1.11.2 → 1.12.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -2
- data/Gemfile.lock +8 -8
- data/README.md +96 -0
- data/deimos-ruby.gemspec +1 -1
- data/docs/CONFIGURATION.md +4 -0
- data/lib/deimos/active_record_consume/batch_consumption.rb +7 -9
- data/lib/deimos/active_record_consume/message_consumption.rb +4 -3
- data/lib/deimos/active_record_consumer.rb +2 -2
- data/lib/deimos/active_record_producer.rb +3 -0
- data/lib/deimos/config/configuration.rb +29 -0
- data/lib/deimos/consume/batch_consumption.rb +2 -2
- data/lib/deimos/consume/message_consumption.rb +2 -2
- data/lib/deimos/consumer.rb +10 -0
- data/lib/deimos/producer.rb +4 -3
- data/lib/deimos/schema_backends/avro_base.rb +64 -1
- data/lib/deimos/schema_backends/avro_schema_registry.rb +1 -1
- data/lib/deimos/schema_backends/base.rb +18 -2
- data/lib/deimos/schema_class/base.rb +67 -0
- data/lib/deimos/schema_class/enum.rb +24 -0
- data/lib/deimos/schema_class/record.rb +59 -0
- data/lib/deimos/shared_config.rb +5 -0
- data/lib/deimos/test_helpers.rb +43 -7
- data/lib/deimos/utils/schema_class.rb +29 -0
- data/lib/deimos/version.rb +1 -1
- data/lib/deimos.rb +3 -0
- data/lib/generators/deimos/schema_class/templates/schema_class.rb.tt +15 -0
- data/lib/generators/deimos/schema_class/templates/schema_enum.rb.tt +21 -0
- data/lib/generators/deimos/schema_class/templates/schema_record.rb.tt +65 -0
- data/lib/generators/deimos/schema_class_generator.rb +247 -0
- data/lib/tasks/deimos.rake +8 -0
- data/spec/active_record_batch_consumer_spec.rb +120 -110
- data/spec/active_record_consumer_spec.rb +97 -88
- data/spec/active_record_producer_spec.rb +38 -27
- data/spec/batch_consumer_spec.rb +37 -28
- data/spec/config/configuration_spec.rb +10 -3
- data/spec/consumer_spec.rb +94 -83
- data/spec/generators/active_record_generator_spec.rb +1 -0
- data/spec/generators/schema_class/my_schema_with_complex_types_spec.rb +206 -0
- data/spec/generators/schema_class_generator_spec.rb +186 -0
- data/spec/producer_spec.rb +110 -0
- data/spec/schema_classes/generated.rb +156 -0
- data/spec/schema_classes/my_nested_schema.rb +114 -0
- data/spec/schema_classes/my_schema.rb +53 -0
- data/spec/schema_classes/my_schema_key.rb +35 -0
- data/spec/schema_classes/my_schema_with_complex_types.rb +172 -0
- data/spec/schemas/com/my-namespace/Generated.avsc +6 -0
- data/spec/schemas/com/my-namespace/MySchemaWithComplexTypes.avsc +95 -0
- data/spec/spec_helper.rb +6 -1
- metadata +28 -4
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Wrapped in a module to prevent class leakage
|
4
4
|
module ActiveRecordBatchConsumerTest
|
5
|
-
describe Deimos::ActiveRecordConsumer do
|
5
|
+
describe Deimos::ActiveRecordConsumer, 'Batch Consumer' do
|
6
6
|
# Create ActiveRecord table and model
|
7
7
|
before(:all) do
|
8
8
|
ActiveRecord::Base.connection.create_table(:widgets, force: true) do |t|
|
@@ -68,133 +68,143 @@ module ActiveRecordBatchConsumerTest
|
|
68
68
|
test_consume_batch(MyBatchConsumer, payloads, keys: keys, call_original: true)
|
69
69
|
end
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
71
|
+
describe 'consume_batch' do
|
72
|
+
SCHEMA_CLASS_SETTINGS.each do |setting, use_schema_classes|
|
73
|
+
context "with Schema Class consumption #{setting}" do
|
74
|
+
before(:each) do
|
75
|
+
Deimos.configure { |config| config.schema.use_schema_classes = use_schema_classes }
|
76
|
+
end
|
74
77
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
{ key: 1,
|
79
|
-
payload: { test_id: 'abc', some_int: 3 } },
|
80
|
-
{ key: 2,
|
81
|
-
payload: { test_id: 'def', some_int: 4 } }
|
82
|
-
]
|
83
|
-
)
|
84
|
-
|
85
|
-
expect(all_widgets).
|
86
|
-
to match_array(
|
87
|
-
[
|
88
|
-
have_attributes(id: 1, test_id: 'abc', some_int: 3, updated_at: start, created_at: start),
|
89
|
-
have_attributes(id: 2, test_id: 'def', some_int: 4, updated_at: start, created_at: start)
|
90
|
-
]
|
91
|
-
)
|
92
|
-
end
|
78
|
+
it 'should handle an empty batch' do
|
79
|
+
expect { publish_batch([]) }.not_to raise_error
|
80
|
+
end
|
93
81
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
82
|
+
it 'should create records from a batch' do
|
83
|
+
publish_batch(
|
84
|
+
[
|
85
|
+
{ key: 1,
|
86
|
+
payload: { test_id: 'abc', some_int: 3 } },
|
87
|
+
{ key: 2,
|
88
|
+
payload: { test_id: 'def', some_int: 4 } }
|
89
|
+
]
|
90
|
+
)
|
101
91
|
|
102
|
-
|
103
|
-
|
92
|
+
expect(all_widgets).
|
93
|
+
to match_array(
|
94
|
+
[
|
95
|
+
have_attributes(id: 1, test_id: 'abc', some_int: 3, updated_at: start, created_at: start),
|
96
|
+
have_attributes(id: 2, test_id: 'def', some_int: 4, updated_at: start, created_at: start)
|
97
|
+
]
|
98
|
+
)
|
99
|
+
end
|
104
100
|
|
105
|
-
|
106
|
-
|
101
|
+
it 'should handle deleting a record that doesn\'t exist' do
|
102
|
+
publish_batch(
|
103
|
+
[
|
104
|
+
{ key: 1,
|
105
|
+
payload: nil }
|
106
|
+
]
|
107
|
+
)
|
107
108
|
|
108
|
-
|
109
|
-
|
110
|
-
{ key: 1,
|
111
|
-
payload: { test_id: 'abc', some_int: 3 } },
|
112
|
-
{ key: 1,
|
113
|
-
payload: nil }
|
114
|
-
]
|
115
|
-
)
|
109
|
+
expect(all_widgets).to be_empty
|
110
|
+
end
|
116
111
|
|
117
|
-
|
118
|
-
|
112
|
+
it 'should handle an update, followed by a delete in the correct order' do
|
113
|
+
Widget.create!(id: 1, test_id: 'abc', some_int: 2)
|
114
|
+
|
115
|
+
publish_batch(
|
116
|
+
[
|
117
|
+
{ key: 1,
|
118
|
+
payload: { test_id: 'abc', some_int: 3 } },
|
119
|
+
{ key: 1,
|
120
|
+
payload: nil }
|
121
|
+
]
|
122
|
+
)
|
119
123
|
|
120
|
-
|
121
|
-
|
124
|
+
expect(all_widgets).to be_empty
|
125
|
+
end
|
122
126
|
|
123
|
-
|
127
|
+
it 'should handle a delete, followed by an update in the correct order' do
|
128
|
+
Widget.create!(id: 1, test_id: 'abc', some_int: 2)
|
124
129
|
|
125
|
-
|
126
|
-
[
|
127
|
-
{ key: 1,
|
128
|
-
payload: nil },
|
129
|
-
{ key: 1,
|
130
|
-
payload: { test_id: 'abc', some_int: 3 } }
|
131
|
-
]
|
132
|
-
)
|
130
|
+
travel 1.day
|
133
131
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
132
|
+
publish_batch(
|
133
|
+
[
|
134
|
+
{ key: 1,
|
135
|
+
payload: nil },
|
136
|
+
{ key: 1,
|
137
|
+
payload: { test_id: 'abc', some_int: 3 } }
|
138
|
+
]
|
139
|
+
)
|
141
140
|
|
142
|
-
|
143
|
-
|
141
|
+
expect(all_widgets).
|
142
|
+
to match_array(
|
143
|
+
[
|
144
|
+
have_attributes(id: 1, test_id: 'abc', some_int: 3, updated_at: Time.zone.now, created_at: Time.zone.now)
|
145
|
+
]
|
146
|
+
)
|
147
|
+
end
|
144
148
|
|
145
|
-
|
149
|
+
it 'should handle a double update' do
|
150
|
+
Widget.create!(id: 1, test_id: 'abc', some_int: 2)
|
146
151
|
|
147
|
-
|
148
|
-
[
|
149
|
-
{ key: 1,
|
150
|
-
payload: { test_id: 'def', some_int: 3 } },
|
151
|
-
{ key: 1,
|
152
|
-
payload: { test_id: 'ghi', some_int: 4 } }
|
153
|
-
]
|
154
|
-
)
|
152
|
+
travel 1.day
|
155
153
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
154
|
+
publish_batch(
|
155
|
+
[
|
156
|
+
{ key: 1,
|
157
|
+
payload: { test_id: 'def', some_int: 3 } },
|
158
|
+
{ key: 1,
|
159
|
+
payload: { test_id: 'ghi', some_int: 4 } }
|
160
|
+
]
|
161
|
+
)
|
163
162
|
|
164
|
-
|
165
|
-
|
163
|
+
expect(all_widgets).
|
164
|
+
to match_array(
|
165
|
+
[
|
166
|
+
have_attributes(id: 1, test_id: 'ghi', some_int: 4, updated_at: Time.zone.now, created_at: start)
|
167
|
+
]
|
168
|
+
)
|
169
|
+
end
|
166
170
|
|
167
|
-
|
168
|
-
|
169
|
-
{ key: 1,
|
170
|
-
payload: nil },
|
171
|
-
{ key: 1,
|
172
|
-
payload: nil }
|
173
|
-
]
|
174
|
-
)
|
171
|
+
it 'should handle a double deletion' do
|
172
|
+
Widget.create!(id: 1, test_id: 'abc', some_int: 2)
|
175
173
|
|
176
|
-
|
177
|
-
|
174
|
+
publish_batch(
|
175
|
+
[
|
176
|
+
{ key: 1,
|
177
|
+
payload: nil },
|
178
|
+
{ key: 1,
|
179
|
+
payload: nil }
|
180
|
+
]
|
181
|
+
)
|
178
182
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
183
|
+
expect(all_widgets).to be_empty
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'should ignore default scopes' do
|
187
|
+
Widget.create!(id: 1, test_id: 'abc', some_int: 2, deleted: true)
|
188
|
+
Widget.create!(id: 2, test_id: 'def', some_int: 3, deleted: true)
|
189
|
+
|
190
|
+
publish_batch(
|
191
|
+
[
|
192
|
+
{ key: 1,
|
193
|
+
payload: nil },
|
194
|
+
{ key: 2,
|
195
|
+
payload: { test_id: 'def', some_int: 5 } }
|
196
|
+
]
|
197
|
+
)
|
198
|
+
|
199
|
+
expect(all_widgets).
|
200
|
+
to match_array(
|
201
|
+
[
|
202
|
+
have_attributes(id: 2, test_id: 'def', some_int: 5)
|
203
|
+
]
|
204
|
+
)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
198
208
|
end
|
199
209
|
|
200
210
|
describe 'compacted mode' do
|
@@ -5,7 +5,6 @@ require 'date'
|
|
5
5
|
# Wrapped in a module to prevent class leakage
|
6
6
|
module ActiveRecordConsumerTest
|
7
7
|
describe Deimos::ActiveRecordConsumer, 'Message Consumer' do
|
8
|
-
|
9
8
|
before(:all) do
|
10
9
|
ActiveRecord::Base.connection.create_table(:widgets, force: true) do |t|
|
11
10
|
t.string(:test_id)
|
@@ -61,94 +60,104 @@ module ActiveRecordConsumerTest
|
|
61
60
|
Time.zone = 'Eastern Time (US & Canada)'
|
62
61
|
end
|
63
62
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
63
|
+
describe 'consume' do
|
64
|
+
SCHEMA_CLASS_SETTINGS.each do |setting, use_schema_classes|
|
65
|
+
context "with Schema Class consumption #{setting}" do
|
66
|
+
before(:each) do
|
67
|
+
Deimos.configure { |config| config.schema.use_schema_classes = use_schema_classes }
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should receive events correctly' do
|
71
|
+
travel 1.day do
|
72
|
+
expect(Widget.count).to eq(0)
|
73
|
+
test_consume_message(MyConsumer, {
|
74
|
+
test_id: 'abc',
|
75
|
+
some_int: 3,
|
76
|
+
updated_at: 1.day.ago.to_i,
|
77
|
+
some_datetime_int: Time.zone.now.to_i,
|
78
|
+
timestamp: 2.minutes.ago.to_s
|
79
|
+
}, { call_original: true, key: 5 })
|
80
|
+
|
81
|
+
expect(Widget.count).to eq(1)
|
82
|
+
widget = Widget.last
|
83
|
+
expect(widget.id).to eq(5)
|
84
|
+
expect(widget.test_id).to eq('abc')
|
85
|
+
expect(widget.some_int).to eq(3)
|
86
|
+
expect(widget.some_datetime_int).to eq(Time.zone.now)
|
87
|
+
expect(widget.some_bool).to eq(false)
|
88
|
+
expect(widget.updated_at).to eq(Time.zone.now)
|
89
|
+
|
90
|
+
# test unscoped
|
91
|
+
widget.update_attribute(:some_bool, true)
|
92
|
+
|
93
|
+
# test update
|
94
|
+
test_consume_message(MyConsumer, {
|
95
|
+
test_id: 'abcd',
|
96
|
+
some_int: 3,
|
97
|
+
some_datetime_int: Time.zone.now.to_i,
|
98
|
+
timestamp: 2.minutes.ago.to_s
|
99
|
+
}, { call_original: true, key: 5 })
|
100
|
+
expect(Widget.unscoped.count).to eq(1)
|
101
|
+
widget = Widget.unscoped.last
|
102
|
+
expect(widget.id).to eq(5)
|
103
|
+
expect(widget.test_id).to eq('abcd')
|
104
|
+
expect(widget.some_int).to eq(3)
|
105
|
+
|
106
|
+
# test delete
|
107
|
+
test_consume_message(MyConsumer, nil, call_original: true, key: 5)
|
108
|
+
expect(Widget.count).to eq(0)
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should update only updated_at' do
|
115
|
+
travel_to Time.local(2020, 5, 5, 5, 5, 5)
|
116
|
+
widget1 = Widget.create!(test_id: 'id1', some_int: 3)
|
117
|
+
expect(widget1.updated_at.in_time_zone).to eq(Time.local(2020, 5, 5, 5, 5, 5))
|
118
|
+
|
119
|
+
travel 1.day
|
120
|
+
test_consume_message(MyCustomFetchConsumer, {
|
121
|
+
test_id: 'id1',
|
122
|
+
some_int: 3
|
123
|
+
}, { call_original: true })
|
124
|
+
expect(widget1.reload.updated_at.in_time_zone).
|
125
|
+
to eq(Time.local(2020, 5, 6, 5, 5, 5))
|
126
|
+
travel_back
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should find widgets by custom logic' do
|
130
|
+
widget1 = Widget.create!(test_id: 'id1')
|
131
|
+
expect(widget1.some_int).to be_nil
|
132
|
+
test_consume_message(MyCustomFetchConsumer, {
|
133
|
+
test_id: 'id1',
|
134
|
+
some_int: 3
|
135
|
+
}, { call_original: true })
|
136
|
+
expect(widget1.reload.some_int).to eq(3)
|
137
|
+
expect(Widget.count).to eq(1)
|
138
|
+
test_consume_message(MyCustomFetchConsumer, {
|
139
|
+
test_id: 'id2',
|
140
|
+
some_int: 4
|
141
|
+
}, { call_original: true })
|
142
|
+
expect(Widget.count).to eq(2)
|
143
|
+
expect(Widget.find_by_test_id('id1').some_int).to eq(3)
|
144
|
+
expect(Widget.find_by_test_id('id2').some_int).to eq(4)
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should not create record of process_message returns false' do
|
148
|
+
allow_any_instance_of(MyConsumer).to receive(:process_message?).and_return(false)
|
149
|
+
expect(Widget.count).to eq(0)
|
150
|
+
test_consume_message(MyConsumer, {
|
151
|
+
test_id: 'abc',
|
152
|
+
some_int: 3,
|
153
|
+
updated_at: 1.day.ago.to_i,
|
154
|
+
some_datetime_int: Time.zone.now.to_i,
|
155
|
+
timestamp: 2.minutes.ago.to_s
|
156
|
+
}, { call_original: true, key: 5 })
|
157
|
+
expect(Widget.count).to eq(0)
|
158
|
+
end
|
159
|
+
end
|
104
160
|
end
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'should update only updated_at' do
|
109
|
-
travel_to Time.local(2020, 5, 5, 5, 5, 5)
|
110
|
-
widget1 = Widget.create!(test_id: 'id1', some_int: 3)
|
111
|
-
expect(widget1.updated_at.in_time_zone).to eq(Time.local(2020, 5, 5, 5, 5, 5))
|
112
|
-
|
113
|
-
travel 1.day
|
114
|
-
test_consume_message(MyCustomFetchConsumer, {
|
115
|
-
test_id: 'id1',
|
116
|
-
some_int: 3
|
117
|
-
}, { call_original: true })
|
118
|
-
expect(widget1.reload.updated_at.in_time_zone).
|
119
|
-
to eq(Time.local(2020, 5, 6, 5, 5, 5))
|
120
|
-
travel_back
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'should find widgets by custom logic' do
|
124
|
-
widget1 = Widget.create!(test_id: 'id1')
|
125
|
-
expect(widget1.some_int).to be_nil
|
126
|
-
test_consume_message(MyCustomFetchConsumer, {
|
127
|
-
test_id: 'id1',
|
128
|
-
some_int: 3
|
129
|
-
}, { call_original: true })
|
130
|
-
expect(widget1.reload.some_int).to eq(3)
|
131
|
-
expect(Widget.count).to eq(1)
|
132
|
-
test_consume_message(MyCustomFetchConsumer, {
|
133
|
-
test_id: 'id2',
|
134
|
-
some_int: 4
|
135
|
-
}, { call_original: true })
|
136
|
-
expect(Widget.count).to eq(2)
|
137
|
-
expect(Widget.find_by_test_id('id1').some_int).to eq(3)
|
138
|
-
expect(Widget.find_by_test_id('id2').some_int).to eq(4)
|
139
|
-
end
|
140
|
-
|
141
|
-
it 'should not create record of process_message returns false' do
|
142
|
-
MyConsumer.any_instance.stub(:process_message?).and_return(false)
|
143
|
-
expect(Widget.count).to eq(0)
|
144
|
-
test_consume_message(MyConsumer, {
|
145
|
-
test_id: 'abc',
|
146
|
-
some_int: 3,
|
147
|
-
updated_at: 1.day.ago.to_i,
|
148
|
-
some_datetime_int: Time.zone.now.to_i,
|
149
|
-
timestamp: 2.minutes.ago.to_s
|
150
|
-
}, { call_original: true, key: 5 })
|
151
|
-
expect(Widget.count).to eq(0)
|
152
161
|
end
|
153
162
|
end
|
154
163
|
end
|
@@ -47,35 +47,46 @@ describe Deimos::ActiveRecordProducer do
|
|
47
47
|
stub_const('MyProducerWithUniqueID', producer_class)
|
48
48
|
end
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
describe 'produce' do
|
51
|
+
SCHEMA_CLASS_SETTINGS.each do |setting, use_schema_classes|
|
52
|
+
context "with Schema Class consumption #{setting}" do
|
53
|
+
before(:each) do
|
54
|
+
Deimos.configure { |config| config.schema.use_schema_classes = use_schema_classes }
|
55
|
+
end
|
54
56
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
57
|
+
it 'should send events correctly' do
|
58
|
+
MyProducer.send_event(Widget.new(test_id: 'abc', some_int: 3))
|
59
|
+
expect('my-topic').to have_sent(test_id: 'abc', some_int: 3)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should coerce values' do
|
63
|
+
MyProducer.send_event(Widget.new(test_id: 'abc', some_int: '3'))
|
64
|
+
MyProducer.send_event(Widget.new(test_id: 'abc', some_int: 4.5))
|
65
|
+
expect('my-topic').to have_sent(test_id: 'abc', some_int: 3)
|
66
|
+
expect('my-topic').to have_sent(test_id: 'abc', some_int: 4)
|
67
|
+
expect {
|
68
|
+
MyProducer.send_event(Widget.new(test_id: 'abc', some_int: nil))
|
69
|
+
}.to raise_error(Avro::SchemaValidator::ValidationError)
|
70
|
+
|
71
|
+
MyBooleanProducer.send_event(Widget.new(test_id: 'abc', some_bool: nil))
|
72
|
+
MyBooleanProducer.send_event(Widget.new(test_id: 'abc', some_bool: true))
|
73
|
+
expect('my-topic-with-boolean').to have_sent(test_id: 'abc', some_bool: false)
|
74
|
+
expect('my-topic-with-boolean').to have_sent(test_id: 'abc', some_bool: true)
|
75
|
+
end
|
69
76
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
77
|
+
it 'should be able to call the record' do
|
78
|
+
widget = Widget.create!(test_id: 'abc2', some_int: 3)
|
79
|
+
MyProducerWithID.send_event(id: widget.id, test_id: 'abc2', some_int: 3)
|
80
|
+
expect('my-topic-with-id').to have_sent(
|
81
|
+
test_id: 'abc2',
|
82
|
+
some_int: 3,
|
83
|
+
message_id: 'generated_id',
|
84
|
+
timestamp: anything
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
79
90
|
end
|
80
91
|
|
81
92
|
specify '#watched_attributes' do
|
data/spec/batch_consumer_spec.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
# :nodoc:
|
4
4
|
module ConsumerTest
|
5
5
|
describe Deimos::Consumer, 'Batch Consumer' do
|
6
|
-
|
7
6
|
prepend_before(:each) do
|
8
7
|
# :nodoc:
|
9
8
|
consumer_class = Class.new(described_class) do
|
@@ -30,40 +29,50 @@ module ConsumerTest
|
|
30
29
|
batch.concat([{ 'invalid' => 'key' }])
|
31
30
|
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
describe 'consume_batch' do
|
33
|
+
SCHEMA_CLASS_SETTINGS.each do |setting, use_schema_classes|
|
34
|
+
context "with Schema Class consumption #{setting}" do
|
35
|
+
before(:each) do
|
36
|
+
Deimos.configure { |config| config.schema.use_schema_classes = use_schema_classes }
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
it 'should provide backwards compatibility for BatchConsumer class' do
|
40
|
+
consumer_class = Class.new(Deimos::BatchConsumer) do
|
41
|
+
schema 'MySchema'
|
42
|
+
namespace 'com.my-namespace'
|
43
|
+
key_config field: 'test_id'
|
44
|
+
|
45
|
+
# :nodoc:
|
46
|
+
def consume_batch(_payloads, _metadata)
|
47
|
+
raise 'This should not be called unless call_original is set'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
stub_const('ConsumerTest::MyOldBatchConsumer', consumer_class)
|
51
|
+
|
52
|
+
test_consume_batch(MyOldBatchConsumer, batch) do |received, _metadata|
|
53
|
+
expect(received).to eq(batch)
|
54
|
+
end
|
55
|
+
end
|
45
56
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
57
|
+
it 'should consume a batch of messages' do
|
58
|
+
test_consume_batch(MyBatchConsumer, batch) do |received, _metadata|
|
59
|
+
expect(received).to eq(batch)
|
60
|
+
end
|
61
|
+
end
|
50
62
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
63
|
+
it 'should consume a message on a topic' do
|
64
|
+
test_consume_batch('my_batch_consume_topic', batch) do |received, _metadata|
|
65
|
+
expect(received).to eq(batch)
|
66
|
+
end
|
67
|
+
end
|
56
68
|
|
57
|
-
|
58
|
-
|
59
|
-
|
69
|
+
it 'should fail on an invalid message in the batch' do
|
70
|
+
test_consume_batch_invalid_message(MyBatchConsumer, batch.concat(invalid_payloads))
|
71
|
+
end
|
72
|
+
end
|
60
73
|
end
|
61
74
|
end
|
62
75
|
|
63
|
-
it 'should fail on an invalid message in the batch' do
|
64
|
-
test_consume_batch_invalid_message(MyBatchConsumer, batch.concat(invalid_payloads))
|
65
|
-
end
|
66
|
-
|
67
76
|
describe 'when reraising errors is disabled' do
|
68
77
|
before(:each) do
|
69
78
|
Deimos.configure { |config| config.consumers.reraise_errors = false }
|