avro_turf 1.19.0 → 1.20.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/.github/workflows/ruby.yml +20 -11
- data/CHANGELOG.md +6 -0
- data/Gemfile +5 -2
- data/Rakefile +2 -1
- data/avro_turf.gemspec +16 -16
- data/lib/avro_turf/cached_confluent_schema_registry.rb +9 -8
- data/lib/avro_turf/cached_schema_registry.rb +3 -1
- data/lib/avro_turf/confluent_schema_registry.rb +23 -17
- data/lib/avro_turf/core_ext/date.rb +2 -0
- data/lib/avro_turf/core_ext/enumerable.rb +2 -0
- data/lib/avro_turf/core_ext/false_class.rb +2 -0
- data/lib/avro_turf/core_ext/hash.rb +4 -2
- data/lib/avro_turf/core_ext/nil_class.rb +2 -0
- data/lib/avro_turf/core_ext/numeric.rb +2 -0
- data/lib/avro_turf/core_ext/string.rb +2 -0
- data/lib/avro_turf/core_ext/symbol.rb +2 -0
- data/lib/avro_turf/core_ext/time.rb +2 -0
- data/lib/avro_turf/core_ext/true_class.rb +2 -0
- data/lib/avro_turf/core_ext.rb +12 -10
- data/lib/avro_turf/disk_cache.rb +13 -12
- data/lib/avro_turf/in_memory_cache.rb +2 -0
- data/lib/avro_turf/messaging.rb +22 -14
- data/lib/avro_turf/mutable_schema_store.rb +25 -4
- data/lib/avro_turf/schema_registry.rb +3 -1
- data/lib/avro_turf/schema_store.rb +3 -2
- data/lib/avro_turf/schema_to_avro_patch.rb +14 -12
- data/lib/avro_turf/test/fake_confluent_schema_registry_server.rb +24 -23
- data/lib/avro_turf/test/fake_prefixed_confluent_schema_registry_server.rb +12 -10
- data/lib/avro_turf/test/fake_schema_registry_server.rb +3 -1
- data/lib/avro_turf/version.rb +3 -1
- data/lib/avro_turf.rb +15 -13
- data/perf/encoding_size.rb +4 -2
- data/perf/encoding_speed.rb +4 -2
- data/spec/avro_turf_spec.rb +24 -23
- data/spec/cached_confluent_schema_registry_spec.rb +9 -7
- data/spec/confluent_schema_registry_spec.rb +31 -10
- data/spec/core_ext/date_spec.rb +2 -0
- data/spec/core_ext/enumerable_spec.rb +2 -0
- data/spec/core_ext/false_class_spec.rb +2 -0
- data/spec/core_ext/hash_spec.rb +3 -1
- data/spec/core_ext/nil_class_spec.rb +2 -0
- data/spec/core_ext/numeric_spec.rb +2 -0
- data/spec/core_ext/string_spec.rb +2 -0
- data/spec/core_ext/symbol_spec.rb +2 -0
- data/spec/core_ext/time_spec.rb +2 -0
- data/spec/core_ext/true_class_spec.rb +2 -0
- data/spec/disk_cached_confluent_schema_registry_spec.rb +23 -21
- data/spec/messaging_spec.rb +124 -99
- data/spec/mutable_schema_store_spec.rb +134 -0
- data/spec/schema_store_spec.rb +23 -21
- data/spec/schema_to_avro_patch_spec.rb +8 -7
- data/spec/spec_helper.rb +9 -9
- data/spec/support/authorized_fake_confluent_schema_registry_server.rb +4 -2
- data/spec/support/authorized_fake_prefixed_confluent_schema_registry_server.rb +4 -2
- data/spec/support/confluent_schema_registry_context.rb +32 -30
- data/spec/test/fake_confluent_schema_registry_server_spec.rb +97 -94
- metadata +5 -26
data/spec/messaging_spec.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "webmock/rspec"
|
4
|
+
require "avro_turf/messaging"
|
3
5
|
|
4
6
|
describe AvroTurf::Messaging do
|
5
7
|
let(:registry_url) { "http://registry.example.com" }
|
@@ -19,7 +21,7 @@ describe AvroTurf::Messaging do
|
|
19
21
|
)
|
20
22
|
}
|
21
23
|
|
22
|
-
let(:message) { {
|
24
|
+
let(:message) { {"full_name" => "John Doe"} }
|
23
25
|
let(:schema_json) do
|
24
26
|
<<-AVSC
|
25
27
|
{
|
@@ -35,7 +37,7 @@ describe AvroTurf::Messaging do
|
|
35
37
|
AVSC
|
36
38
|
end
|
37
39
|
|
38
|
-
let(:city_message) { {
|
40
|
+
let(:city_message) { {"name" => "Paris"} }
|
39
41
|
let(:city_schema_json) do
|
40
42
|
<<-AVSC
|
41
43
|
{
|
@@ -88,39 +90,39 @@ describe AvroTurf::Messaging do
|
|
88
90
|
end
|
89
91
|
end
|
90
92
|
|
91
|
-
shared_examples_for
|
93
|
+
shared_examples_for "encoding and decoding with the schema from registry" do
|
92
94
|
before do
|
93
95
|
registry = AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger, path_prefix: path_prefix)
|
94
|
-
registry.register(
|
95
|
-
registry.register(
|
96
|
+
registry.register("person", schema)
|
97
|
+
registry.register("people", schema)
|
96
98
|
end
|
97
99
|
|
98
|
-
it
|
99
|
-
data = avro.encode(message, subject:
|
100
|
+
it "encodes and decodes messages" do
|
101
|
+
data = avro.encode(message, subject: "person", version: 1)
|
100
102
|
expect(avro.decode(data)).to eq message
|
101
103
|
end
|
102
104
|
|
103
105
|
it "allows specifying a reader's schema by subject and version" do
|
104
|
-
data = avro.encode(message, subject:
|
105
|
-
expect(avro.decode(data, schema_name:
|
106
|
+
data = avro.encode(message, subject: "person", version: 1)
|
107
|
+
expect(avro.decode(data, schema_name: "person")).to eq message
|
106
108
|
end
|
107
109
|
|
108
|
-
it
|
109
|
-
expect { avro.encode(message, subject:
|
110
|
+
it "raises AvroTurf::SchemaNotFoundError when the schema does not exist on registry" do
|
111
|
+
expect { avro.encode(message, subject: "missing", version: 1) }.to raise_error(AvroTurf::SchemaNotFoundError)
|
110
112
|
end
|
111
113
|
|
112
|
-
it
|
113
|
-
expect { avro.encode(city_message, schema_name:
|
114
|
-
to raise_error(AvroTurf::SchemaNotFoundError, "Schema with structure: #{city_schema} not found on registry")
|
114
|
+
it "raises AvroTurf::SchemaNotFoundError when the schema does not exist on registry and register_schemas false" do
|
115
|
+
expect { avro.encode(city_message, schema_name: "city", register_schemas: false) }
|
116
|
+
.to raise_error(AvroTurf::SchemaNotFoundError, "Schema with structure: #{city_schema} not found on registry")
|
115
117
|
end
|
116
118
|
|
117
|
-
it
|
118
|
-
data = avro.encode(message, schema_name:
|
119
|
-
expect(avro.decode(data, schema_name:
|
119
|
+
it "encodes with register_schemas false when the schema exists on the registry" do
|
120
|
+
data = avro.encode(message, schema_name: "person", register_schemas: false)
|
121
|
+
expect(avro.decode(data, schema_name: "person")).to eq message
|
120
122
|
end
|
121
123
|
|
122
|
-
it
|
123
|
-
data = avro.encode(message, subject:
|
124
|
+
it "caches parsed schemas for decoding" do
|
125
|
+
data = avro.encode(message, subject: "person", version: 1)
|
124
126
|
avro.decode(data)
|
125
127
|
allow(Avro::Schema).to receive(:parse).and_call_original
|
126
128
|
expect(avro.decode(data)).to eq message
|
@@ -128,23 +130,23 @@ describe AvroTurf::Messaging do
|
|
128
130
|
end
|
129
131
|
end
|
130
132
|
|
131
|
-
shared_examples_for
|
133
|
+
shared_examples_for "encoding and decoding with the schema_id from registry" do
|
132
134
|
before do
|
133
135
|
registry = AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger, path_prefix: path_prefix)
|
134
|
-
registry.register(
|
135
|
-
registry.register(
|
136
|
+
registry.register("person", schema)
|
137
|
+
registry.register("people", schema)
|
136
138
|
end
|
137
139
|
|
138
|
-
it
|
140
|
+
it "encodes and decodes messages" do
|
139
141
|
data = avro.encode(message, schema_id: 0)
|
140
142
|
expect(avro.decode(data)).to eq message
|
141
143
|
end
|
142
144
|
|
143
|
-
it
|
145
|
+
it "raises AvroTurf::SchemaNotFoundError when the schema does not exist on registry" do
|
144
146
|
expect { avro.encode(message, schema_id: 5) }.to raise_error(AvroTurf::SchemaNotFoundError)
|
145
147
|
end
|
146
148
|
|
147
|
-
it
|
149
|
+
it "caches parsed schemas for decoding" do
|
148
150
|
data = avro.encode(message, schema_id: 0)
|
149
151
|
avro.decode(data)
|
150
152
|
allow(Avro::Schema).to receive(:parse).and_call_original
|
@@ -155,9 +157,9 @@ describe AvroTurf::Messaging do
|
|
155
157
|
|
156
158
|
it_behaves_like "encoding and decoding with the schema from schema store"
|
157
159
|
|
158
|
-
it_behaves_like
|
160
|
+
it_behaves_like "encoding and decoding with the schema from registry"
|
159
161
|
|
160
|
-
it_behaves_like
|
162
|
+
it_behaves_like "encoding and decoding with the schema_id from registry"
|
161
163
|
|
162
164
|
context "with a provided registry" do
|
163
165
|
let(:registry) { AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger) }
|
@@ -172,20 +174,20 @@ describe AvroTurf::Messaging do
|
|
172
174
|
|
173
175
|
it_behaves_like "encoding and decoding with the schema from schema store"
|
174
176
|
|
175
|
-
it_behaves_like
|
177
|
+
it_behaves_like "encoding and decoding with the schema from registry"
|
176
178
|
|
177
|
-
it_behaves_like
|
179
|
+
it_behaves_like "encoding and decoding with the schema_id from registry"
|
178
180
|
|
179
181
|
it "uses the provided registry" do
|
180
182
|
allow(registry).to receive(:register).and_call_original
|
181
|
-
message = {
|
183
|
+
message = {"full_name" => "John Doe"}
|
182
184
|
avro.encode(message, schema_name: "person")
|
183
185
|
expect(registry).to have_received(:register).with("person", anything)
|
184
186
|
end
|
185
187
|
|
186
188
|
it "allows specifying a schema registry subject" do
|
187
189
|
allow(registry).to receive(:register).and_call_original
|
188
|
-
message = {
|
190
|
+
message = {"full_name" => "John Doe"}
|
189
191
|
avro.encode(message, schema_name: "person", subject: "people")
|
190
192
|
expect(registry).to have_received(:register).with("people", anything)
|
191
193
|
end
|
@@ -211,7 +213,7 @@ describe AvroTurf::Messaging do
|
|
211
213
|
end
|
212
214
|
end
|
213
215
|
|
214
|
-
describe
|
216
|
+
describe "decoding with #decode_message" do
|
215
217
|
shared_examples_for "encoding and decoding with the schema from schema store" do
|
216
218
|
it "encodes and decodes messages" do
|
217
219
|
data = avro.encode(message, schema_name: "person")
|
@@ -239,31 +241,31 @@ describe AvroTurf::Messaging do
|
|
239
241
|
end
|
240
242
|
end
|
241
243
|
|
242
|
-
shared_examples_for
|
244
|
+
shared_examples_for "encoding and decoding with the schema from registry" do
|
243
245
|
before do
|
244
246
|
registry = AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger)
|
245
|
-
registry.register(
|
246
|
-
registry.register(
|
247
|
+
registry.register("person", schema)
|
248
|
+
registry.register("people", schema)
|
247
249
|
end
|
248
250
|
|
249
|
-
it
|
250
|
-
data = avro.encode(message, subject:
|
251
|
+
it "encodes and decodes messages" do
|
252
|
+
data = avro.encode(message, subject: "person", version: 1)
|
251
253
|
result = avro.decode_message(data)
|
252
254
|
expect(result.message).to eq message
|
253
255
|
expect(result.schema_id).to eq 0
|
254
256
|
end
|
255
257
|
|
256
258
|
it "allows specifying a reader's schema by subject and version" do
|
257
|
-
data = avro.encode(message, subject:
|
258
|
-
expect(avro.decode_message(data, schema_name:
|
259
|
+
data = avro.encode(message, subject: "person", version: 1)
|
260
|
+
expect(avro.decode_message(data, schema_name: "person").message).to eq message
|
259
261
|
end
|
260
262
|
|
261
|
-
it
|
262
|
-
expect { avro.encode(message, subject:
|
263
|
+
it "raises AvroTurf::SchemaNotFoundError when the schema does not exist on registry" do
|
264
|
+
expect { avro.encode(message, subject: "missing", version: 1) }.to raise_error(AvroTurf::SchemaNotFoundError)
|
263
265
|
end
|
264
266
|
|
265
|
-
it
|
266
|
-
data = avro.encode(message, subject:
|
267
|
+
it "caches parsed schemas for decoding" do
|
268
|
+
data = avro.encode(message, subject: "person", version: 1)
|
267
269
|
avro.decode_message(data)
|
268
270
|
allow(Avro::Schema).to receive(:parse).and_call_original
|
269
271
|
expect(avro.decode_message(data).message).to eq message
|
@@ -273,7 +275,7 @@ describe AvroTurf::Messaging do
|
|
273
275
|
|
274
276
|
it_behaves_like "encoding and decoding with the schema from schema store"
|
275
277
|
|
276
|
-
it_behaves_like
|
278
|
+
it_behaves_like "encoding and decoding with the schema from registry"
|
277
279
|
|
278
280
|
context "with a provided registry" do
|
279
281
|
let(:registry) { AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger) }
|
@@ -288,18 +290,18 @@ describe AvroTurf::Messaging do
|
|
288
290
|
|
289
291
|
it_behaves_like "encoding and decoding with the schema from schema store"
|
290
292
|
|
291
|
-
it_behaves_like
|
293
|
+
it_behaves_like "encoding and decoding with the schema from registry"
|
292
294
|
|
293
295
|
it "uses the provided registry" do
|
294
296
|
allow(registry).to receive(:register).and_call_original
|
295
|
-
message = {
|
297
|
+
message = {"full_name" => "John Doe"}
|
296
298
|
avro.encode(message, schema_name: "person")
|
297
299
|
expect(registry).to have_received(:register).with("person", anything)
|
298
300
|
end
|
299
301
|
|
300
302
|
it "allows specifying a schema registry subject" do
|
301
303
|
allow(registry).to receive(:register).and_call_original
|
302
|
-
message = {
|
304
|
+
message = {"full_name" => "John Doe"}
|
303
305
|
avro.encode(message, schema_name: "person", subject: "people")
|
304
306
|
expect(registry).to have_received(:register).with("people", anything)
|
305
307
|
end
|
@@ -327,26 +329,26 @@ describe AvroTurf::Messaging do
|
|
327
329
|
end
|
328
330
|
|
329
331
|
context "validating" do
|
330
|
-
subject(:encode){ avro.encode(message, schema_name: "person", validate: true) }
|
332
|
+
subject(:encode) { avro.encode(message, schema_name: "person", validate: true) }
|
331
333
|
|
332
334
|
context "for correct message" do
|
333
335
|
it { expect { encode }.not_to raise_error }
|
334
336
|
end
|
335
337
|
|
336
338
|
context "when message has wrong type" do
|
337
|
-
let(:message) { {
|
339
|
+
let(:message) { {"full_name" => 123} }
|
338
340
|
|
339
341
|
it { expect { encode }.to raise_error(Avro::SchemaValidator::ValidationError, /\.full_name expected type string, got int/) }
|
340
342
|
end
|
341
343
|
|
342
344
|
context "when message contains extra fields (typo in key)" do
|
343
|
-
let(:message) { {
|
345
|
+
let(:message) { {"fulll_name" => "John Doe"} }
|
344
346
|
|
345
347
|
it { expect { encode }.to raise_error(Avro::SchemaValidator::ValidationError, /extra field 'fulll_name'/) }
|
346
348
|
end
|
347
349
|
end
|
348
350
|
|
349
|
-
context
|
351
|
+
context "fetching and registering schema" do
|
350
352
|
let(:schema_store) { AvroTurf::SchemaStore.new(path: "spec/schemas") }
|
351
353
|
|
352
354
|
let(:registry) { AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger) }
|
@@ -361,28 +363,28 @@ describe AvroTurf::Messaging do
|
|
361
363
|
|
362
364
|
let(:schema_id) { 234 }
|
363
365
|
|
364
|
-
context
|
366
|
+
context "using fetch_schema" do
|
365
367
|
subject { avro.fetch_schema(subject: subj, version: version) }
|
366
368
|
|
367
|
-
let(:subj) {
|
369
|
+
let(:subj) { "subject" }
|
368
370
|
|
369
|
-
let(:version) {
|
371
|
+
let(:version) { "version" }
|
370
372
|
|
371
|
-
let(:response) { {
|
373
|
+
let(:response) { {"id" => schema_id, "schema" => schema_json} }
|
372
374
|
|
373
375
|
before do
|
374
376
|
allow(registry).to receive(:subject_version).with(subj, version).and_return(response)
|
375
377
|
end
|
376
378
|
|
377
|
-
it
|
379
|
+
it "gets schema from registry" do
|
378
380
|
expect(subject).to eq([schema, schema_id])
|
379
381
|
end
|
380
382
|
|
381
383
|
context "with an incompatible schema type" do
|
382
|
-
let(:response) { {
|
383
|
-
let(:schema_type) {
|
384
|
+
let(:response) { {"id" => schema_id, "schema" => "blah", "schemaType" => schema_type} }
|
385
|
+
let(:schema_type) { "PROTOBUF" }
|
384
386
|
|
385
|
-
it
|
387
|
+
it "raises IncompatibleSchemaError" do
|
386
388
|
expect { subject }.to raise_error(
|
387
389
|
AvroTurf::IncompatibleSchemaError,
|
388
390
|
"The #{schema_type} schema for #{subj} is incompatible."
|
@@ -391,22 +393,22 @@ describe AvroTurf::Messaging do
|
|
391
393
|
end
|
392
394
|
end
|
393
395
|
|
394
|
-
context
|
396
|
+
context "using fetch_schema_by_id" do
|
395
397
|
subject { avro.fetch_schema_by_id(schema_id) }
|
396
398
|
|
397
399
|
before do
|
398
400
|
allow(registry).to receive(:fetch).with(schema_id).and_return(schema_json)
|
399
401
|
end
|
400
402
|
|
401
|
-
it
|
403
|
+
it "gets schema from registry" do
|
402
404
|
expect(subject).to eq([schema, schema_id])
|
403
405
|
end
|
404
406
|
end
|
405
407
|
|
406
|
-
context
|
407
|
-
let(:subject_name) {
|
408
|
-
let(:schema_name) {
|
409
|
-
let(:namespace) {
|
408
|
+
context "using fetch_schema_by_body" do
|
409
|
+
let(:subject_name) { "city" }
|
410
|
+
let(:schema_name) { "city" }
|
411
|
+
let(:namespace) { "namespace" }
|
410
412
|
let(:city_schema_id) { 125 }
|
411
413
|
let(:city_schema_data) do
|
412
414
|
{
|
@@ -426,50 +428,50 @@ describe AvroTurf::Messaging do
|
|
426
428
|
allow(registry).to receive(:check).with(subject_name, city_schema).and_return(city_schema_data)
|
427
429
|
end
|
428
430
|
|
429
|
-
it
|
431
|
+
it "gets schema from registry" do
|
430
432
|
expect(fetch_schema_by_body).to eq([city_schema, city_schema_id])
|
431
433
|
end
|
432
434
|
end
|
433
435
|
|
434
|
-
context
|
435
|
-
let(:schema_name) {
|
436
|
+
context "using register_schema" do
|
437
|
+
let(:schema_name) { "schema_name" }
|
436
438
|
|
437
|
-
let(:namespace) {
|
439
|
+
let(:namespace) { "namespace" }
|
438
440
|
|
439
441
|
before do
|
440
442
|
allow(schema_store).to receive(:find).with(schema_name, namespace).and_return(schema)
|
441
443
|
end
|
442
444
|
|
443
|
-
context
|
445
|
+
context "when subject is not set" do
|
444
446
|
subject { avro.register_schema(schema_name: schema_name, namespace: namespace) }
|
445
447
|
|
446
448
|
before do
|
447
449
|
allow(registry).to receive(:register).with(schema.fullname, schema).and_return(schema_id)
|
448
450
|
end
|
449
451
|
|
450
|
-
it
|
452
|
+
it "registers schema in registry" do
|
451
453
|
expect(subject).to eq([schema, schema_id])
|
452
454
|
end
|
453
455
|
end
|
454
456
|
|
455
|
-
context
|
457
|
+
context "when subject is set" do
|
456
458
|
subject { avro.register_schema(schema_name: schema_name, namespace: namespace, subject: subj) }
|
457
459
|
|
458
|
-
let(:subj) {
|
460
|
+
let(:subj) { "subject" }
|
459
461
|
|
460
462
|
before do
|
461
463
|
allow(registry).to receive(:register).with(subj, schema).and_return(schema_id)
|
462
464
|
end
|
463
465
|
|
464
|
-
it
|
466
|
+
it "registers schema in registry" do
|
465
467
|
expect(subject).to eq([schema, schema_id])
|
466
468
|
end
|
467
469
|
end
|
468
470
|
end
|
469
471
|
end
|
470
472
|
|
471
|
-
context
|
472
|
-
let(:path_prefix) {
|
473
|
+
context "with a registry path prefix" do
|
474
|
+
let(:path_prefix) { "/prefix" }
|
473
475
|
|
474
476
|
let(:avro) {
|
475
477
|
AvroTurf::Messaging.new(
|
@@ -489,11 +491,11 @@ describe AvroTurf::Messaging do
|
|
489
491
|
end
|
490
492
|
|
491
493
|
it_behaves_like "encoding and decoding with the schema from schema store"
|
492
|
-
it_behaves_like
|
493
|
-
it_behaves_like
|
494
|
+
it_behaves_like "encoding and decoding with the schema from registry"
|
495
|
+
it_behaves_like "encoding and decoding with the schema_id from registry"
|
494
496
|
end
|
495
497
|
|
496
|
-
context
|
498
|
+
context "with a connect timeout" do
|
497
499
|
let(:avro) {
|
498
500
|
AvroTurf::Messaging.new(
|
499
501
|
registry_url: registry_url,
|
@@ -507,16 +509,16 @@ describe AvroTurf::Messaging do
|
|
507
509
|
}
|
508
510
|
|
509
511
|
it_behaves_like "encoding and decoding with the schema from schema store"
|
510
|
-
it_behaves_like
|
511
|
-
it_behaves_like
|
512
|
+
it_behaves_like "encoding and decoding with the schema from registry"
|
513
|
+
it_behaves_like "encoding and decoding with the schema_id from registry"
|
512
514
|
|
513
|
-
it
|
515
|
+
it "passes the connect timeout setting to Excon" do
|
514
516
|
expect(Excon).to receive(:new).with(anything, hash_including(connect_timeout: 10)).and_call_original
|
515
517
|
avro
|
516
518
|
end
|
517
519
|
end
|
518
520
|
|
519
|
-
context
|
521
|
+
context "with a connect timeout" do
|
520
522
|
let(:avro) {
|
521
523
|
AvroTurf::Messaging.new(
|
522
524
|
registry_url: registry_url,
|
@@ -530,17 +532,17 @@ describe AvroTurf::Messaging do
|
|
530
532
|
}
|
531
533
|
|
532
534
|
it_behaves_like "encoding and decoding with the schema from schema store"
|
533
|
-
it_behaves_like
|
534
|
-
it_behaves_like
|
535
|
+
it_behaves_like "encoding and decoding with the schema from registry"
|
536
|
+
it_behaves_like "encoding and decoding with the schema_id from registry"
|
535
537
|
|
536
|
-
it
|
538
|
+
it "passes the connect timeout setting to Excon" do
|
537
539
|
expect(Excon).to receive(:new).with(anything, hash_including(retry_limit: 5)).and_call_original
|
538
540
|
avro
|
539
541
|
end
|
540
542
|
end
|
541
543
|
|
542
|
-
context
|
543
|
-
let(:proxy_url) {
|
544
|
+
context "with a proxy" do
|
545
|
+
let(:proxy_url) { "http://proxy.example.com" }
|
544
546
|
let(:avro) {
|
545
547
|
AvroTurf::Messaging.new(
|
546
548
|
registry_url: registry_url,
|
@@ -554,18 +556,17 @@ describe AvroTurf::Messaging do
|
|
554
556
|
}
|
555
557
|
|
556
558
|
it_behaves_like "encoding and decoding with the schema from schema store"
|
557
|
-
it_behaves_like
|
558
|
-
it_behaves_like
|
559
|
+
it_behaves_like "encoding and decoding with the schema from registry"
|
560
|
+
it_behaves_like "encoding and decoding with the schema_id from registry"
|
559
561
|
|
560
|
-
it
|
562
|
+
it "passes the proxy setting to Excon" do
|
561
563
|
expect(Excon).to receive(:new).with(anything, hash_including(proxy: proxy_url)).and_call_original
|
562
564
|
avro
|
563
565
|
end
|
564
566
|
end
|
565
567
|
|
566
|
-
|
567
|
-
|
568
|
-
let(:resolv_resolver) { Resolv.new([Resolv::Hosts.new, Resolv::DNS.new(nameserver: ['127.0.0.1', '127.0.0.1'])]) }
|
568
|
+
context "with a custom domain name resolver" do
|
569
|
+
let(:resolv_resolver) { Resolv.new([Resolv::Hosts.new, Resolv::DNS.new(nameserver: ["127.0.0.1", "127.0.0.1"])]) }
|
569
570
|
let(:avro) {
|
570
571
|
AvroTurf::Messaging.new(
|
571
572
|
registry_url: registry_url,
|
@@ -579,12 +580,36 @@ describe AvroTurf::Messaging do
|
|
579
580
|
}
|
580
581
|
|
581
582
|
it_behaves_like "encoding and decoding with the schema from schema store"
|
582
|
-
it_behaves_like
|
583
|
-
it_behaves_like
|
583
|
+
it_behaves_like "encoding and decoding with the schema from registry"
|
584
|
+
it_behaves_like "encoding and decoding with the schema_id from registry"
|
584
585
|
|
585
|
-
it
|
586
|
+
it "passes the domain name resolver setting to Excon" do
|
586
587
|
expect(Excon).to receive(:new).with(anything, hash_including(resolv_resolver: resolv_resolver)).and_call_original
|
587
588
|
avro
|
588
589
|
end
|
589
590
|
end
|
591
|
+
|
592
|
+
context "with a cert chain" do
|
593
|
+
let(:client_chain) { "test client chain" }
|
594
|
+
let(:avro) {
|
595
|
+
AvroTurf::Messaging.new(
|
596
|
+
registry_url: registry_url,
|
597
|
+
schemas_path: "spec/schemas",
|
598
|
+
logger: logger,
|
599
|
+
client_cert: client_cert,
|
600
|
+
client_chain: client_chain,
|
601
|
+
client_key: client_key,
|
602
|
+
client_key_pass: client_key_pass
|
603
|
+
)
|
604
|
+
}
|
605
|
+
|
606
|
+
it_behaves_like "encoding and decoding with the schema from schema store"
|
607
|
+
it_behaves_like "encoding and decoding with the schema from registry"
|
608
|
+
it_behaves_like "encoding and decoding with the schema_id from registry"
|
609
|
+
|
610
|
+
it "passes the client chain to Excon" do
|
611
|
+
expect(Excon).to receive(:new).with(anything, hash_including(client_chain: client_chain)).and_call_original
|
612
|
+
avro
|
613
|
+
end
|
614
|
+
end
|
590
615
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "avro_turf/mutable_schema_store"
|
4
|
+
|
5
|
+
describe AvroTurf::MutableSchemaStore do
|
6
|
+
let(:store) { AvroTurf::MutableSchemaStore.new(path: "spec/schemas") }
|
7
|
+
|
8
|
+
describe "#add_schema" do
|
9
|
+
it "adds a schema to the store" do
|
10
|
+
schema_hash = {
|
11
|
+
"name" => "person",
|
12
|
+
"namespace" => "test.people",
|
13
|
+
"type" => "record",
|
14
|
+
"fields" => [
|
15
|
+
{
|
16
|
+
"type" => "string",
|
17
|
+
"name" => "name"
|
18
|
+
}
|
19
|
+
]
|
20
|
+
}
|
21
|
+
|
22
|
+
schema = store.add_schema(schema_hash)
|
23
|
+
expect(schema.fullname).to eq "test.people.person"
|
24
|
+
expect(store.schemas["test.people.person"]).to eq schema
|
25
|
+
end
|
26
|
+
|
27
|
+
# This test would fail under avro_turf <= v0.19.0
|
28
|
+
it "does NOT cache *nested* schemas in memory" do
|
29
|
+
schema_hash = {
|
30
|
+
"name" => "person",
|
31
|
+
"namespace" => "test",
|
32
|
+
"type" => "record",
|
33
|
+
"fields" => [
|
34
|
+
{
|
35
|
+
"name" => "address",
|
36
|
+
"type" => {
|
37
|
+
"name" => "address",
|
38
|
+
"type" => "record",
|
39
|
+
"fields" => [
|
40
|
+
{"name" => "addr1", "type" => "string"},
|
41
|
+
{"name" => "addr2", "type" => "string"},
|
42
|
+
{"name" => "city", "type" => "string"},
|
43
|
+
{"name" => "zip", "type" => "string"}
|
44
|
+
]
|
45
|
+
}
|
46
|
+
}
|
47
|
+
]
|
48
|
+
}
|
49
|
+
|
50
|
+
schema = store.add_schema(schema_hash)
|
51
|
+
expect(schema.fullname).to eq "test.person"
|
52
|
+
expect(store.schemas["test.person"]).to eq schema
|
53
|
+
|
54
|
+
expect { store.find("address", "test") }
|
55
|
+
.to raise_error(AvroTurf::SchemaNotFoundError)
|
56
|
+
end
|
57
|
+
|
58
|
+
# This test would fail under avro_turf <= v1.19.0
|
59
|
+
it "allows two different schemas to define nested sub-schemas with the same fullname" do
|
60
|
+
person_schema = {
|
61
|
+
"name" => "person",
|
62
|
+
"namespace" => "test",
|
63
|
+
"type" => "record",
|
64
|
+
"fields" => [
|
65
|
+
{
|
66
|
+
"name" => "location",
|
67
|
+
"type" => {
|
68
|
+
"name" => "location",
|
69
|
+
"type" => "record",
|
70
|
+
"fields" => [
|
71
|
+
{"name" => "city", "type" => "string"},
|
72
|
+
{"name" => "zipcode", "type" => "string"}
|
73
|
+
]
|
74
|
+
}
|
75
|
+
}
|
76
|
+
]
|
77
|
+
}
|
78
|
+
|
79
|
+
company_schema = {
|
80
|
+
"name" => "company",
|
81
|
+
"namespace" => "test",
|
82
|
+
"type" => "record",
|
83
|
+
"fields" => [
|
84
|
+
{
|
85
|
+
"name" => "headquarters",
|
86
|
+
"type" => {
|
87
|
+
"name" => "location",
|
88
|
+
"type" => "record",
|
89
|
+
"fields" => [
|
90
|
+
{"name" => "city", "type" => "string"},
|
91
|
+
{"name" => "postcode", "type" => "string"}
|
92
|
+
]
|
93
|
+
}
|
94
|
+
}
|
95
|
+
]
|
96
|
+
}
|
97
|
+
|
98
|
+
person = store.add_schema(person_schema)
|
99
|
+
|
100
|
+
# This should *NOT* raise the error:
|
101
|
+
# #<Avro::SchemaParseError: The name "test.location" is already in use.>
|
102
|
+
expect { store.add_schema(company_schema) }.not_to raise_error
|
103
|
+
|
104
|
+
company = store.schemas["test.company"]
|
105
|
+
|
106
|
+
person_location_field = person.fields_hash["location"]
|
107
|
+
expect(person_location_field.type.name).to eq("location")
|
108
|
+
expect(person_location_field.type.fields_hash).to include("zipcode")
|
109
|
+
expect(person_location_field.type.fields_hash).not_to include("postcode")
|
110
|
+
|
111
|
+
company_headquarters_field = company.fields_hash["headquarters"]
|
112
|
+
expect(company_headquarters_field.type.name).to eq("location")
|
113
|
+
expect(company_headquarters_field.type.fields_hash).to include("postcode")
|
114
|
+
expect(company_headquarters_field.type.fields_hash).not_to include("zipcode")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "#schemas" do
|
119
|
+
it "provides access to the internal schemas hash" do
|
120
|
+
expect(store.schemas).to be_a(Hash)
|
121
|
+
expect(store.schemas).to be_empty
|
122
|
+
|
123
|
+
schema_hash = {
|
124
|
+
"name" => "test",
|
125
|
+
"type" => "record",
|
126
|
+
"fields" => []
|
127
|
+
}
|
128
|
+
|
129
|
+
store.add_schema(schema_hash)
|
130
|
+
expect(store.schemas.size).to eq 1
|
131
|
+
expect(store.schemas["test"]).to be_a(Avro::Schema::RecordSchema)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|