avro_turf 0.7.1 → 0.10.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 +5 -5
- data/.circleci/config.yml +36 -0
- data/.github/workflows/ruby.yml +20 -0
- data/CHANGELOG.md +29 -0
- data/Gemfile +0 -3
- data/README.md +54 -16
- data/avro_turf.gemspec +13 -2
- data/lib/avro_turf.rb +14 -3
- data/lib/avro_turf/cached_confluent_schema_registry.rb +39 -0
- data/lib/avro_turf/cached_schema_registry.rb +4 -24
- data/lib/avro_turf/confluent_schema_registry.rb +106 -0
- data/lib/avro_turf/disk_cache.rb +83 -0
- data/lib/avro_turf/in_memory_cache.rb +38 -0
- data/lib/avro_turf/messaging.rb +77 -9
- data/lib/avro_turf/mutable_schema_store.rb +18 -0
- data/lib/avro_turf/schema_registry.rb +4 -77
- data/lib/avro_turf/schema_store.rb +36 -19
- data/lib/avro_turf/schema_to_avro_patch.rb +11 -0
- data/lib/avro_turf/test/fake_confluent_schema_registry_server.rb +141 -0
- data/lib/avro_turf/test/fake_schema_registry_server.rb +4 -82
- data/lib/avro_turf/version.rb +1 -1
- data/spec/cached_confluent_schema_registry_spec.rb +63 -0
- data/spec/confluent_schema_registry_spec.rb +9 -0
- data/spec/disk_cached_confluent_schema_registry_spec.rb +159 -0
- data/spec/messaging_spec.rb +208 -19
- data/spec/schema_store_spec.rb +36 -0
- data/spec/schema_to_avro_patch_spec.rb +42 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/{schema_registry_context.rb → confluent_schema_registry_context.rb} +72 -8
- data/spec/test/fake_confluent_schema_registry_server_spec.rb +40 -0
- metadata +49 -16
- data/circle.yml +0 -4
- data/spec/cached_schema_registry_spec.rb +0 -41
- data/spec/schema_registry_spec.rb +0 -9
data/spec/messaging_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'webmock/rspec'
|
2
2
|
require 'avro_turf/messaging'
|
3
|
-
require 'avro_turf/test/
|
3
|
+
require 'avro_turf/test/fake_confluent_schema_registry_server'
|
4
4
|
|
5
5
|
describe AvroTurf::Messaging do
|
6
6
|
let(:registry_url) { "http://registry.example.com" }
|
@@ -15,18 +15,8 @@ describe AvroTurf::Messaging do
|
|
15
15
|
}
|
16
16
|
|
17
17
|
let(:message) { { "full_name" => "John Doe" } }
|
18
|
-
|
19
|
-
|
20
|
-
FileUtils.mkdir_p("spec/schemas")
|
21
|
-
end
|
22
|
-
|
23
|
-
before do
|
24
|
-
stub_request(:any, /^#{registry_url}/).to_rack(FakeSchemaRegistryServer)
|
25
|
-
FakeSchemaRegistryServer.clear
|
26
|
-
end
|
27
|
-
|
28
|
-
before do
|
29
|
-
define_schema "person.avsc", <<-AVSC
|
18
|
+
let(:schema_json) do
|
19
|
+
<<-AVSC
|
30
20
|
{
|
31
21
|
"name": "person",
|
32
22
|
"type": "record",
|
@@ -39,8 +29,22 @@ describe AvroTurf::Messaging do
|
|
39
29
|
}
|
40
30
|
AVSC
|
41
31
|
end
|
32
|
+
let(:schema) { Avro::Schema.parse(schema_json) }
|
42
33
|
|
43
|
-
|
34
|
+
before do
|
35
|
+
FileUtils.mkdir_p("spec/schemas")
|
36
|
+
end
|
37
|
+
|
38
|
+
before do
|
39
|
+
stub_request(:any, /^#{registry_url}/).to_rack(FakeConfluentSchemaRegistryServer)
|
40
|
+
FakeConfluentSchemaRegistryServer.clear
|
41
|
+
end
|
42
|
+
|
43
|
+
before do
|
44
|
+
define_schema "person.avsc", schema_json
|
45
|
+
end
|
46
|
+
|
47
|
+
shared_examples_for "encoding and decoding with the schema from schema store" do
|
44
48
|
it "encodes and decodes messages" do
|
45
49
|
data = avro.encode(message, schema_name: "person")
|
46
50
|
expect(avro.decode(data)).to eq message
|
@@ -60,10 +64,69 @@ describe AvroTurf::Messaging do
|
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
63
|
-
|
67
|
+
shared_examples_for 'encoding and decoding with the schema from registry' do
|
68
|
+
before do
|
69
|
+
registry = AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger)
|
70
|
+
registry.register('person', schema)
|
71
|
+
registry.register('people', schema)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'encodes and decodes messages' do
|
75
|
+
data = avro.encode(message, subject: 'person', version: 1)
|
76
|
+
expect(avro.decode(data)).to eq message
|
77
|
+
end
|
78
|
+
|
79
|
+
it "allows specifying a reader's schema by subject and version" do
|
80
|
+
data = avro.encode(message, subject: 'person', version: 1)
|
81
|
+
expect(avro.decode(data, schema_name: 'person')).to eq message
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'raises AvroTurf::SchemaNotFoundError when the schema does not exist on registry' do
|
85
|
+
expect { avro.encode(message, subject: 'missing', version: 1) }.to raise_error(AvroTurf::SchemaNotFoundError)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'caches parsed schemas for decoding' do
|
89
|
+
data = avro.encode(message, subject: 'person', version: 1)
|
90
|
+
avro.decode(data)
|
91
|
+
allow(Avro::Schema).to receive(:parse).and_call_original
|
92
|
+
expect(avro.decode(data)).to eq message
|
93
|
+
expect(Avro::Schema).not_to have_received(:parse)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
shared_examples_for 'encoding and decoding with the schema_id from registry' do
|
98
|
+
before do
|
99
|
+
registry = AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger)
|
100
|
+
registry.register('person', schema)
|
101
|
+
registry.register('people', schema)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'encodes and decodes messages' do
|
105
|
+
data = avro.encode(message, schema_id: 1)
|
106
|
+
expect(avro.decode(data)).to eq message
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'raises AvroTurf::SchemaNotFoundError when the schema does not exist on registry' do
|
110
|
+
expect { avro.encode(message, schema_id: 5) }.to raise_error(AvroTurf::SchemaNotFoundError)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'caches parsed schemas for decoding' do
|
114
|
+
data = avro.encode(message, schema_id: 1)
|
115
|
+
avro.decode(data)
|
116
|
+
allow(Avro::Schema).to receive(:parse).and_call_original
|
117
|
+
expect(avro.decode(data)).to eq message
|
118
|
+
expect(Avro::Schema).not_to have_received(:parse)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it_behaves_like "encoding and decoding with the schema from schema store"
|
123
|
+
|
124
|
+
it_behaves_like 'encoding and decoding with the schema from registry'
|
125
|
+
|
126
|
+
it_behaves_like 'encoding and decoding with the schema_id from registry'
|
64
127
|
|
65
128
|
context "with a provided registry" do
|
66
|
-
let(:registry) { AvroTurf::
|
129
|
+
let(:registry) { AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger) }
|
67
130
|
|
68
131
|
let(:avro) do
|
69
132
|
AvroTurf::Messaging.new(
|
@@ -73,13 +136,24 @@ describe AvroTurf::Messaging do
|
|
73
136
|
)
|
74
137
|
end
|
75
138
|
|
76
|
-
it_behaves_like "encoding and decoding"
|
139
|
+
it_behaves_like "encoding and decoding with the schema from schema store"
|
140
|
+
|
141
|
+
it_behaves_like 'encoding and decoding with the schema from registry'
|
142
|
+
|
143
|
+
it_behaves_like 'encoding and decoding with the schema_id from registry'
|
77
144
|
|
78
145
|
it "uses the provided registry" do
|
79
146
|
allow(registry).to receive(:register).and_call_original
|
80
147
|
message = { "full_name" => "John Doe" }
|
81
148
|
avro.encode(message, schema_name: "person")
|
82
|
-
expect(registry).to have_received(:register)
|
149
|
+
expect(registry).to have_received(:register).with("person", anything)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "allows specifying a schema registry subject" do
|
153
|
+
allow(registry).to receive(:register).and_call_original
|
154
|
+
message = { "full_name" => "John Doe" }
|
155
|
+
avro.encode(message, schema_name: "person", subject: "people")
|
156
|
+
expect(registry).to have_received(:register).with("people", anything)
|
83
157
|
end
|
84
158
|
end
|
85
159
|
|
@@ -94,7 +168,7 @@ describe AvroTurf::Messaging do
|
|
94
168
|
)
|
95
169
|
end
|
96
170
|
|
97
|
-
it_behaves_like "encoding and decoding"
|
171
|
+
it_behaves_like "encoding and decoding with the schema from schema store"
|
98
172
|
|
99
173
|
it "uses the provided schema store" do
|
100
174
|
allow(schema_store).to receive(:find).and_call_original
|
@@ -102,4 +176,119 @@ describe AvroTurf::Messaging do
|
|
102
176
|
expect(schema_store).to have_received(:find).with("person", nil)
|
103
177
|
end
|
104
178
|
end
|
179
|
+
|
180
|
+
describe 'decoding with #decode_message' do
|
181
|
+
shared_examples_for "encoding and decoding with the schema from schema store" do
|
182
|
+
it "encodes and decodes messages" do
|
183
|
+
data = avro.encode(message, schema_name: "person")
|
184
|
+
result = avro.decode_message(data)
|
185
|
+
expect(result.message).to eq message
|
186
|
+
expect(result.schema_id).to eq 0
|
187
|
+
expect(result.writer_schema).to eq schema
|
188
|
+
expect(result.reader_schema).to eq nil
|
189
|
+
end
|
190
|
+
|
191
|
+
it "allows specifying a reader's schema" do
|
192
|
+
data = avro.encode(message, schema_name: "person")
|
193
|
+
result = avro.decode_message(data, schema_name: "person")
|
194
|
+
expect(result.message).to eq message
|
195
|
+
expect(result.writer_schema).to eq schema
|
196
|
+
expect(result.reader_schema).to eq schema
|
197
|
+
end
|
198
|
+
|
199
|
+
it "caches parsed schemas for decoding" do
|
200
|
+
data = avro.encode(message, schema_name: "person")
|
201
|
+
avro.decode_message(data)
|
202
|
+
allow(Avro::Schema).to receive(:parse).and_call_original
|
203
|
+
expect(avro.decode_message(data).message).to eq message
|
204
|
+
expect(Avro::Schema).not_to have_received(:parse)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
shared_examples_for 'encoding and decoding with the schema from registry' do
|
209
|
+
before do
|
210
|
+
registry = AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger)
|
211
|
+
registry.register('person', schema)
|
212
|
+
registry.register('people', schema)
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'encodes and decodes messages' do
|
216
|
+
data = avro.encode(message, subject: 'person', version: 1)
|
217
|
+
result = avro.decode_message(data)
|
218
|
+
expect(result.message).to eq message
|
219
|
+
expect(result.schema_id).to eq 0
|
220
|
+
end
|
221
|
+
|
222
|
+
it "allows specifying a reader's schema by subject and version" do
|
223
|
+
data = avro.encode(message, subject: 'person', version: 1)
|
224
|
+
expect(avro.decode_message(data, schema_name: 'person').message).to eq message
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'raises AvroTurf::SchemaNotFoundError when the schema does not exist on registry' do
|
228
|
+
expect { avro.encode(message, subject: 'missing', version: 1) }.to raise_error(AvroTurf::SchemaNotFoundError)
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'caches parsed schemas for decoding' do
|
232
|
+
data = avro.encode(message, subject: 'person', version: 1)
|
233
|
+
avro.decode_message(data)
|
234
|
+
allow(Avro::Schema).to receive(:parse).and_call_original
|
235
|
+
expect(avro.decode_message(data).message).to eq message
|
236
|
+
expect(Avro::Schema).not_to have_received(:parse)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
it_behaves_like "encoding and decoding with the schema from schema store"
|
241
|
+
|
242
|
+
it_behaves_like 'encoding and decoding with the schema from registry'
|
243
|
+
|
244
|
+
context "with a provided registry" do
|
245
|
+
let(:registry) { AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger) }
|
246
|
+
|
247
|
+
let(:avro) do
|
248
|
+
AvroTurf::Messaging.new(
|
249
|
+
registry: registry,
|
250
|
+
schemas_path: "spec/schemas",
|
251
|
+
logger: logger
|
252
|
+
)
|
253
|
+
end
|
254
|
+
|
255
|
+
it_behaves_like "encoding and decoding with the schema from schema store"
|
256
|
+
|
257
|
+
it_behaves_like 'encoding and decoding with the schema from registry'
|
258
|
+
|
259
|
+
it "uses the provided registry" do
|
260
|
+
allow(registry).to receive(:register).and_call_original
|
261
|
+
message = { "full_name" => "John Doe" }
|
262
|
+
avro.encode(message, schema_name: "person")
|
263
|
+
expect(registry).to have_received(:register).with("person", anything)
|
264
|
+
end
|
265
|
+
|
266
|
+
it "allows specifying a schema registry subject" do
|
267
|
+
allow(registry).to receive(:register).and_call_original
|
268
|
+
message = { "full_name" => "John Doe" }
|
269
|
+
avro.encode(message, schema_name: "person", subject: "people")
|
270
|
+
expect(registry).to have_received(:register).with("people", anything)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
context "with a provided schema store" do
|
275
|
+
let(:schema_store) { AvroTurf::SchemaStore.new(path: "spec/schemas") }
|
276
|
+
|
277
|
+
let(:avro) do
|
278
|
+
AvroTurf::Messaging.new(
|
279
|
+
registry_url: registry_url,
|
280
|
+
schema_store: schema_store,
|
281
|
+
logger: logger
|
282
|
+
)
|
283
|
+
end
|
284
|
+
|
285
|
+
it_behaves_like "encoding and decoding with the schema from schema store"
|
286
|
+
|
287
|
+
it "uses the provided schema store" do
|
288
|
+
allow(schema_store).to receive(:find).and_call_original
|
289
|
+
avro.encode(message, schema_name: "person")
|
290
|
+
expect(schema_store).to have_received(:find).with("person", nil)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
105
294
|
end
|
data/spec/schema_store_spec.rb
CHANGED
@@ -197,6 +197,42 @@ describe AvroTurf::SchemaStore do
|
|
197
197
|
schema = store.find("person")
|
198
198
|
expect(schema.fullname).to eq "person"
|
199
199
|
end
|
200
|
+
|
201
|
+
it "is thread safe" do
|
202
|
+
define_schema "address.avsc", <<-AVSC
|
203
|
+
{
|
204
|
+
"type": "record",
|
205
|
+
"name": "address",
|
206
|
+
"fields": []
|
207
|
+
}
|
208
|
+
AVSC
|
209
|
+
|
210
|
+
# Set a Thread breakpoint right in the core place of race condition
|
211
|
+
expect(Avro::Name)
|
212
|
+
.to receive(:add_name)
|
213
|
+
.and_wrap_original { |m, *args|
|
214
|
+
Thread.stop
|
215
|
+
m.call(*args)
|
216
|
+
}
|
217
|
+
|
218
|
+
# Run two concurring threads which both will trigger the same schema loading
|
219
|
+
threads = 2.times.map { Thread.new { store.find("address") } }
|
220
|
+
# Wait for the moment when both threads will reach the breakpoint
|
221
|
+
sleep 0.001 until threads.all?(&:stop?)
|
222
|
+
|
223
|
+
expect {
|
224
|
+
# Resume the threads evaluation, one after one
|
225
|
+
threads.each do |thread|
|
226
|
+
next unless thread.status == 'sleep'
|
227
|
+
|
228
|
+
thread.run
|
229
|
+
sleep 0.001 until thread.stop?
|
230
|
+
end
|
231
|
+
|
232
|
+
# Ensure that threads are finished
|
233
|
+
threads.each(&:join)
|
234
|
+
}.to_not raise_error
|
235
|
+
end
|
200
236
|
end
|
201
237
|
|
202
238
|
describe "#load_schemas!" do
|
@@ -22,3 +22,45 @@ describe Avro::Schema do
|
|
22
22
|
})
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
|
27
|
+
describe Avro::IO::DatumReader do
|
28
|
+
let(:writer_schema) do
|
29
|
+
Avro::Schema.parse <<-AVSC
|
30
|
+
{
|
31
|
+
"name": "no_default",
|
32
|
+
"type": "record",
|
33
|
+
"fields": [
|
34
|
+
{ "type": "string", "name": "one" }
|
35
|
+
]
|
36
|
+
}
|
37
|
+
AVSC
|
38
|
+
end
|
39
|
+
let(:reader_schema) do
|
40
|
+
Avro::Schema.parse <<-AVSC
|
41
|
+
{
|
42
|
+
"name": "no_default",
|
43
|
+
"type": "record",
|
44
|
+
"fields": [
|
45
|
+
{ "type": "string", "name": "one" },
|
46
|
+
{ "type": "string", "name": "two" }
|
47
|
+
]
|
48
|
+
}
|
49
|
+
AVSC
|
50
|
+
end
|
51
|
+
|
52
|
+
it "raises an error for missing fields without a default" do
|
53
|
+
stream = StringIO.new
|
54
|
+
writer = Avro::IO::DatumWriter.new(writer_schema)
|
55
|
+
encoder = Avro::IO::BinaryEncoder.new(stream)
|
56
|
+
writer.write({ 'one' => 'first' }, encoder)
|
57
|
+
encoded = stream.string
|
58
|
+
|
59
|
+
stream = StringIO.new(encoded)
|
60
|
+
decoder = Avro::IO::BinaryDecoder.new(stream)
|
61
|
+
reader = Avro::IO::DatumReader.new(writer_schema, reader_schema)
|
62
|
+
expect do
|
63
|
+
reader.read(decoder)
|
64
|
+
end.to raise_error(Avro::AvroError, 'Missing data for "string" with no default')
|
65
|
+
end
|
66
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -12,6 +12,14 @@ module Helpers
|
|
12
12
|
f.write(content)
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
def store_cache(path, hash)
|
17
|
+
File.write(File.join("spec/cache", path), JSON.generate(hash))
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_cache(path)
|
21
|
+
JSON.parse(File.read(File.join("spec/cache", path)))
|
22
|
+
end
|
15
23
|
end
|
16
24
|
|
17
25
|
RSpec.configure do |config|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# This shared example expects a registry variable to be defined
|
2
2
|
# with an instance of the registry class being tested.
|
3
|
-
shared_examples_for "a schema registry client" do
|
3
|
+
shared_examples_for "a confluent schema registry client" do
|
4
4
|
let(:logger) { Logger.new(StringIO.new) }
|
5
5
|
let(:registry_url) { "http://registry.example.com" }
|
6
6
|
let(:subject_name) { "some-subject" }
|
@@ -15,8 +15,8 @@ shared_examples_for "a schema registry client" do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
before do
|
18
|
-
stub_request(:any, /^#{registry_url}/).to_rack(
|
19
|
-
|
18
|
+
stub_request(:any, /^#{registry_url}/).to_rack(FakeConfluentSchemaRegistryServer)
|
19
|
+
FakeConfluentSchemaRegistryServer.clear
|
20
20
|
end
|
21
21
|
|
22
22
|
describe "#register and #fetch" do
|
@@ -88,16 +88,18 @@ shared_examples_for "a schema registry client" do
|
|
88
88
|
end
|
89
89
|
|
90
90
|
describe "#subject_version" do
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
91
|
+
let!(:schema_id1) do
|
92
|
+
registry.register(subject_name, { type: :record, name: "r0", fields: [] }.to_json)
|
93
|
+
end
|
94
|
+
let!(:schema_id2) do
|
95
|
+
registry.register(subject_name, { type: :record, name: "r1", fields: [] }.to_json)
|
96
96
|
end
|
97
|
+
|
97
98
|
let(:expected) do
|
98
99
|
{
|
99
100
|
name: subject_name,
|
100
101
|
version: 1,
|
102
|
+
id: schema_id1,
|
101
103
|
schema: { type: :record, name: "r0", fields: [] }.to_json
|
102
104
|
}.to_json
|
103
105
|
end
|
@@ -112,6 +114,7 @@ shared_examples_for "a schema registry client" do
|
|
112
114
|
{
|
113
115
|
name: subject_name,
|
114
116
|
version: 2,
|
117
|
+
id: schema_id2,
|
115
118
|
schema: { type: :record, name: "r1", fields: [] }.to_json
|
116
119
|
}.to_json
|
117
120
|
end
|
@@ -178,6 +181,67 @@ shared_examples_for "a schema registry client" do
|
|
178
181
|
end
|
179
182
|
end
|
180
183
|
|
184
|
+
describe "#global_config" do
|
185
|
+
let(:expected) do
|
186
|
+
{ compatibility: 'BACKWARD' }.to_json
|
187
|
+
end
|
188
|
+
|
189
|
+
it "returns the global configuration" do
|
190
|
+
expect(registry.global_config).to eq(JSON.parse(expected))
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "#update_global_config" do
|
195
|
+
let(:config) do
|
196
|
+
{ compatibility: 'FORWARD' }
|
197
|
+
end
|
198
|
+
let(:expected) { config.to_json }
|
199
|
+
|
200
|
+
it "updates the global configuration and returns it" do
|
201
|
+
expect(registry.update_global_config(config)).to eq(JSON.parse(expected))
|
202
|
+
expect(registry.global_config).to eq(JSON.parse(expected))
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe "#subject_config" do
|
207
|
+
let(:expected) do
|
208
|
+
{ compatibility: 'BACKWARD' }.to_json
|
209
|
+
end
|
210
|
+
|
211
|
+
context "when the subject config is not set" do
|
212
|
+
it "returns the global configuration" do
|
213
|
+
expect(registry.subject_config(subject_name)).to eq(JSON.parse(expected))
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context "when the subject config is set" do
|
218
|
+
let(:config) do
|
219
|
+
{ compatibility: 'FULL' }
|
220
|
+
end
|
221
|
+
let(:expected) { config.to_json }
|
222
|
+
|
223
|
+
before do
|
224
|
+
registry.update_subject_config(subject_name, config)
|
225
|
+
end
|
226
|
+
|
227
|
+
it "returns the subject config" do
|
228
|
+
expect(registry.subject_config(subject_name)).to eq(JSON.parse(expected))
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe "#update_subject_config" do
|
234
|
+
let(:config) do
|
235
|
+
{ compatibility: 'NONE' }
|
236
|
+
end
|
237
|
+
let(:expected) { config.to_json }
|
238
|
+
|
239
|
+
it "updates the subject config and returns it" do
|
240
|
+
expect(registry.update_subject_config(subject_name, config)).to eq(JSON.parse(expected))
|
241
|
+
expect(registry.subject_config(subject_name)).to eq(JSON.parse(expected))
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
181
245
|
# Monkey patch an Avro::Schema to simulate the presence of
|
182
246
|
# active_support/core_ext.
|
183
247
|
def break_to_json(avro_schema)
|