fluent-plugin-gcloud-pubsub-custom-compress-batches 1.3.4

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.
@@ -0,0 +1,308 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "zlib"
4
+
5
+ require_relative "../test_helper"
6
+ require "fluent/test/driver/output"
7
+ require "fluent/test/helpers"
8
+
9
+ class GcloudPubSubOutputTest < Test::Unit::TestCase
10
+ include Fluent::Test::Helpers
11
+
12
+ CONFIG = %(
13
+ project project-test
14
+ topic topic-test
15
+ key key-test
16
+ )
17
+
18
+ ReRaisedError = Class.new(RuntimeError)
19
+
20
+ def create_driver(conf = CONFIG)
21
+ Fluent::Test::Driver::Output.new(Fluent::Plugin::GcloudPubSubOutput).configure(conf)
22
+ end
23
+
24
+ setup do
25
+ Fluent::Test.setup
26
+ end
27
+
28
+ setup do
29
+ @time = event_time("2016-07-09 11:12:13 UTC")
30
+ end
31
+
32
+ sub_test_case "configure" do
33
+ test "default values are configured" do
34
+ d = create_driver(%(
35
+ project project-test
36
+ topic topic-test
37
+ key key-test
38
+ ))
39
+
40
+ assert_equal("project-test", d.instance.project)
41
+ assert_equal("topic-test", d.instance.topic)
42
+ assert_equal("key-test", d.instance.key)
43
+ assert_equal(false, d.instance.autocreate_topic)
44
+ assert_equal(1000, d.instance.max_messages)
45
+ assert_equal(9_800_000, d.instance.max_total_size)
46
+ assert_equal(4_000_000, d.instance.max_message_size)
47
+ end
48
+
49
+ test '"topic" must be specified' do
50
+ assert_raises Fluent::ConfigError do
51
+ create_driver(%(
52
+ project project-test
53
+ key key-test
54
+ ))
55
+ end
56
+ end
57
+
58
+ test '"autocreate_topic" can be specified' do
59
+ d = create_driver(%(
60
+ project project-test
61
+ topic topic-test
62
+ key key-test
63
+ autocreate_topic true
64
+ ))
65
+
66
+ assert_equal(true, d.instance.autocreate_topic)
67
+ end
68
+
69
+ test "'attribute_keys' cannot be used with 'compress_batches'" do
70
+ assert_raise(Fluent::ConfigError.new(":attribute_keys cannot be used when compression is enabled")) do
71
+ create_driver(%(
72
+ project project-test
73
+ topic topic-test
74
+ attribute_keys attr-test
75
+ compress_batches true
76
+ ))
77
+ end
78
+ end
79
+ end
80
+
81
+ sub_test_case "topic" do
82
+ setup do
83
+ @publisher = mock!
84
+ @pubsub_mock = mock!
85
+ stub(Google::Cloud::Pubsub).new { @pubsub_mock }
86
+ end
87
+
88
+ test '"autocreate_topic" is enabled' do
89
+ d = create_driver(%(
90
+ project project-test
91
+ topic topic-test
92
+ key key-test
93
+ autocreate_topic true
94
+ ))
95
+
96
+ @publisher.publish.once
97
+ @pubsub_mock.topic("topic-test").once { nil }
98
+ @pubsub_mock.create_topic("topic-test").once { @publisher }
99
+ d.run(default_tag: "test") do
100
+ d.feed(@time, { "a" => "b" })
101
+ end
102
+ end
103
+
104
+ test "40x error occurred on connecting to Pub/Sub" do
105
+ d = create_driver
106
+
107
+ @pubsub_mock.topic("topic-test").once do
108
+ raise Google::Cloud::NotFoundError, "TEST"
109
+ end
110
+
111
+ assert_raise Google::Cloud::NotFoundError do
112
+ d.run(default_tag: "test") do
113
+ d.feed(@time, { "a" => "b" })
114
+ end
115
+ end
116
+ end
117
+
118
+ test "50x error occurred on connecting to Pub/Sub" do
119
+ d = create_driver
120
+
121
+ @pubsub_mock.topic("topic-test").once do
122
+ raise Google::Cloud::UnavailableError, "TEST"
123
+ end
124
+
125
+ assert_raise Fluent::GcloudPubSub::RetryableError do
126
+ d.run(default_tag: "test") do
127
+ d.feed(@time, { "a" => "b" })
128
+ end
129
+ end
130
+ end
131
+
132
+ test "topic is nil" do
133
+ d = create_driver
134
+
135
+ @pubsub_mock.topic("topic-test").once { nil }
136
+
137
+ assert_raise Fluent::GcloudPubSub::Error do
138
+ d.run(default_tag: "test") do
139
+ d.feed(@time, { "a" => "b" })
140
+ end
141
+ end
142
+ end
143
+
144
+ test 'messages exceeding "max_message_size" are not published' do
145
+ d = create_driver(%(
146
+ project project-test
147
+ topic topic-test
148
+ key key-test
149
+ max_message_size 1000
150
+ ))
151
+
152
+ @publisher.publish.times(0)
153
+ d.run(default_tag: "test") do
154
+ d.feed(@time, { "a" => "a" * 1000 })
155
+ end
156
+ end
157
+ end
158
+
159
+ # Rubocop will erroneously correct the MessagePack.unpack call, for which there's no `unpack1` equivalent method.
160
+ # rubocop:disable Style/UnpackFirst
161
+ sub_test_case "publish" do
162
+ setup do
163
+ @publisher = mock!
164
+ @pubsub_mock = mock!.topic(anything) { @publisher }
165
+ stub(Google::Cloud::Pubsub).new { @pubsub_mock }
166
+ end
167
+
168
+ test 'messages are divided into "max_messages"' do
169
+ d = create_driver
170
+ @publisher.publish.times(2)
171
+ d.run(default_tag: "test") do
172
+ # max_messages is default 1000
173
+ 1001.times do |i|
174
+ d.feed(@time, { "a" => i })
175
+ end
176
+ end
177
+ end
178
+
179
+ test 'messages are divided into "max_total_size"' do
180
+ d = create_driver(%(
181
+ project project-test
182
+ topic topic-test
183
+ key key-test
184
+ max_messages 100000
185
+ max_total_size 1000
186
+ ))
187
+
188
+ @publisher.publish.times(2)
189
+ d.run(default_tag: "test") do
190
+ # 400 * 4 / max_total_size = twice
191
+ 4.times do
192
+ d.feed(@time, { "a" => "a" * 400 })
193
+ end
194
+ end
195
+ end
196
+
197
+ test 'accept "ASCII-8BIT" encoded multibyte strings' do
198
+ # on fluentd v0.14, all strings treated as "ASCII-8BIT" except specified encoding.
199
+ d = create_driver
200
+ @publisher.publish.once
201
+ d.run(default_tag: "test") do
202
+ d.feed(@time, { "a" => "あああ".dup.force_encoding("ASCII-8BIT") })
203
+ end
204
+ end
205
+
206
+ test "reraise unexpected errors" do
207
+ d = create_driver
208
+ @publisher.publish.once { raise ReRaisedError }
209
+ assert_raises ReRaisedError do
210
+ d.run(default_tag: "test") do
211
+ d.feed([{ "a" => 1, "b" => 2 }])
212
+ end
213
+ end
214
+ end
215
+
216
+ test "reraise RetryableError" do
217
+ d = create_driver
218
+ @publisher.publish.once { raise Google::Cloud::UnavailableError, "TEST" }
219
+ assert_raises Fluent::GcloudPubSub::RetryableError do
220
+ d.run(default_tag: "test") do
221
+ d.feed([{ "a" => 1, "b" => 2 }])
222
+ end
223
+ end
224
+ end
225
+
226
+ test "inject section" do
227
+ d = create_driver(%(
228
+ project project-test
229
+ topic topic-test
230
+ key key-test
231
+ <inject>
232
+ tag_key tag
233
+ </inject>
234
+ ))
235
+ @publisher.publish.once
236
+ d.run(default_tag: "test") do
237
+ d.feed({ "foo" => "bar" })
238
+ end
239
+ assert_equal({ "tag" => "test", "foo" => "bar" }, JSON.parse(MessagePack.unpack(d.formatted.first)[0]))
240
+ end
241
+
242
+ test "compressed batch" do
243
+ d = create_driver(%(
244
+ project project-test
245
+ topic topic-test
246
+ key key-test
247
+ compress_batches true
248
+ max_messages 2
249
+ ))
250
+
251
+ # This is a little hacky: we're doing assertions via matchers.
252
+ # The RR library doesn't seem to provide an easy alternative to this. The
253
+ # downside of this approach is that you will not receive a nice diff if
254
+ # the expectation fails.
255
+ first_batch = [
256
+ '{"foo":"bar"}' + "\n",
257
+ '{"foo":123}' + "\n",
258
+ ]
259
+ @publisher.publish(ZlibCompressedBatch.new(first_batch), { compression_algorithm: "zlib" }).once
260
+
261
+ second_batch = [
262
+ '{"msg":"last"}' + "\n",
263
+ ]
264
+ @publisher.publish(ZlibCompressedBatch.new(second_batch), { compression_algorithm: "zlib" }).once
265
+
266
+ d.run(default_tag: "test") do
267
+ d.feed({ "foo" => "bar" })
268
+ d.feed({ "foo" => 123 })
269
+ d.feed({ "msg" => "last" })
270
+ end
271
+ end
272
+ end
273
+ # rubocop:enable Style/UnpackFirst
274
+ end
275
+
276
+ private
277
+
278
+ # A matcher for a compressed batch of messages
279
+ # https://www.rubydoc.info/gems/rr/1.2.1/RR/WildcardMatchers
280
+ class ZlibCompressedBatch
281
+ attr_reader :expected_messages
282
+
283
+ def initialize(expected_messages)
284
+ @expected_messages = expected_messages
285
+ end
286
+
287
+ def wildcard_match?(other)
288
+ return true if self == other
289
+
290
+ return false unless other.is_a?(String)
291
+
292
+ decompressed = Zlib::Inflate.inflate(other)
293
+ other_messages = decompressed.split(30.chr)
294
+
295
+ other_messages == expected_messages
296
+ end
297
+
298
+ def ==(other)
299
+ other.is_a?(self.class) &&
300
+ other.expected_messages == expected_messages
301
+ end
302
+
303
+ alias eql? ==
304
+
305
+ def inspect
306
+ "contains compressed messages: #{expected_messages}"
307
+ end
308
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems"
4
+ require "bundler"
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ warn e.message
9
+ warn "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require "test/unit"
13
+ require "test/unit/rr"
14
+
15
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
16
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
17
+
18
+ require "fluent/test"
19
+ unless ENV.key?("VERBOSE")
20
+ nulllogger = Object.new
21
+ nulllogger.instance_eval do |_obj|
22
+ def method_missing(method, *args)
23
+ # pass
24
+ end
25
+ end
26
+ $log = nulllogger
27
+ end
28
+
29
+ require "fluent/plugin/in_gcloud_pubsub"
30
+ require "fluent/plugin/out_gcloud_pubsub"
31
+
32
+ class Test::Unit::TestCase
33
+ end
metadata ADDED
@@ -0,0 +1,208 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-gcloud-pubsub-custom-compress-batches
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.4
5
+ platform: ruby
6
+ authors:
7
+ - Calvin Aditya
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.14.15
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.14.15
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
33
+ - !ruby/object:Gem::Dependency
34
+ name: google-cloud-pubsub
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 0.30.0
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.30.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: prometheus-client
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "<"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.10'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.10'
61
+ - !ruby/object:Gem::Dependency
62
+ name: bundler
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: pry
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: pry-byebug
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rake
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rubocop
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '0.83'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '0.83'
131
+ - !ruby/object:Gem::Dependency
132
+ name: test-unit
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: test-unit-rr
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ description: Google Cloud Pub/Sub input/output plugin for Fluentd event collector
160
+ - with payload compression. Forked from https://github.com/gocardless/fluent-plugin-gcloud-pubsub-custom
161
+ email: calvin.aditya95@gmail.com
162
+ executables: []
163
+ extensions: []
164
+ extra_rdoc_files: []
165
+ files:
166
+ - ".gitignore"
167
+ - ".rubocop.yml"
168
+ - ".rubocop_todo.yml"
169
+ - ".ruby-version"
170
+ - ".travis.yml"
171
+ - CHANGELOG.md
172
+ - Gemfile
173
+ - LICENSE
174
+ - README.md
175
+ - Rakefile
176
+ - fluent-plugin-gcloud-pubsub-custom.gemspec
177
+ - lib/fluent/plugin/gcloud_pubsub/client.rb
178
+ - lib/fluent/plugin/gcloud_pubsub/metrics.rb
179
+ - lib/fluent/plugin/in_gcloud_pubsub.rb
180
+ - lib/fluent/plugin/out_gcloud_pubsub.rb
181
+ - test/plugin/test_in_gcloud_pubsub.rb
182
+ - test/plugin/test_out_gcloud_pubsub.rb
183
+ - test/test_helper.rb
184
+ homepage: https://github.com/calvinaditya95/fluent-plugin-gcloud-pubsub-custom
185
+ licenses:
186
+ - MIT
187
+ metadata: {}
188
+ post_install_message:
189
+ rdoc_options: []
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: '0'
197
+ required_rubygems_version: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ requirements: []
203
+ rubygems_version: 3.1.2
204
+ signing_key:
205
+ specification_version: 4
206
+ summary: Google Cloud Pub/Sub input/output plugin for Fluentd event collector - with
207
+ payload compression
208
+ test_files: []