fluent-plugin-scalyr 0.8.7 → 0.8.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Scalyr Output Plugin for Fluentd
3
5
  #
@@ -15,8 +17,6 @@
15
17
  # See the License for the specific language governing permissions and
16
18
  # limitations under the License.
17
19
 
18
-
19
-
20
20
  module Scalyr
21
21
  class ClientError < StandardError; end
22
22
  class Client4xxError < StandardError; end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Scalyr Output Plugin for Fluentd
5
+ #
6
+ # Copyright (C) 2020 Scalyr, Inc.
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+
20
+ module Scalyr
21
+ def sanitize_and_reencode_value(value)
22
+ # Method which recursively sanitizes the provided value and tries to re-encode all the strings as
23
+ # UTF-8 ignoring any bad unicode sequences
24
+ case value
25
+ when Hash
26
+ return sanitize_and_reencode_hash(value)
27
+ when Array
28
+ return sanitize_and_reencode_array(value)
29
+ when String
30
+ value = sanitize_and_reencode_string(value)
31
+ return value
32
+ end
33
+
34
+ # We only need to re-encode strings, for other value types (ints, nils,
35
+ # etc. no reencoding is needed)
36
+ value
37
+ end
38
+
39
+ def sanitize_and_reencode_array(array)
40
+ array.each_with_index do |value, index|
41
+ value = sanitize_and_reencode_value(value)
42
+ array[index] = value
43
+ end
44
+
45
+ array
46
+ end
47
+
48
+ def sanitize_and_reencode_hash(hash)
49
+ hash.each do |key, value|
50
+ hash[key] = sanitize_and_reencode_value(value)
51
+ end
52
+
53
+ hash
54
+ end
55
+
56
+ def sanitize_and_reencode_string(value)
57
+ # Function which sanitized the provided string value and tries to re-encode it as UTF-8
58
+ # ignoring any encoding error which could arise due to bad or partial unicode sequence
59
+ begin # rubocop:disable Style/RedundantBegin
60
+ value.encode("UTF-8", invalid: :replace, undef: :replace, replace: "<?>").force_encoding("UTF-8") # rubocop:disable Layout/LineLength, Lint/RedundantCopDisableDirective
61
+ rescue # rubocop:disable Style/RescueStandardError
62
+ "failed-to-reencode-as-utf8"
63
+ end
64
+ end
65
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Scalyr Output Plugin for Fluentd
3
5
  #
@@ -15,9 +17,13 @@
15
17
  # See the License for the specific language governing permissions and
16
18
  # limitations under the License.
17
19
 
20
+ require "fluent/test"
21
+ require "fluent/test/helpers"
22
+ require "fluent/test/log"
23
+ require "fluent/test/driver/output"
24
+ require "fluent/plugin/out_scalyr"
18
25
 
19
- require 'fluent/test'
20
- require 'fluent/plugin/out_scalyr'
26
+ include Fluent::Test::Helpers # rubocop:disable Style/MixinUsage
21
27
 
22
28
  module Scalyr
23
29
  class ScalyrOutTest < Test::Unit::TestCase
@@ -25,13 +31,13 @@ module Scalyr
25
31
  Fluent::Test.setup
26
32
  end
27
33
 
28
- CONFIG = %[
34
+ CONFIG = %(
29
35
  api_write_token test_token
30
36
  ssl_ca_bundle_path /etc/ssl/certs/ca-certificates.crt
31
- ]
37
+ )
32
38
 
33
- def create_driver( conf = CONFIG )
34
- Fluent::Test::BufferedOutputTestDriver.new( Scalyr::ScalyrOut ).configure( conf )
39
+ def create_driver(conf=CONFIG)
40
+ Fluent::Test::Driver::Output.new(Scalyr::ScalyrOut).configure(conf)
35
41
  end
36
42
  end
37
43
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Scalyr Output Plugin for Fluentd
3
5
  #
@@ -15,44 +17,45 @@
15
17
  # See the License for the specific language governing permissions and
16
18
  # limitations under the License.
17
19
 
20
+ require "helper"
21
+ require "socket"
18
22
 
19
- require 'helper'
20
-
21
- class ConfigTest < Scalyr::ScalyrOutTest
22
-
23
- def test_default_params
24
- d = create_driver
25
- assert_nil( d.instance.server_attributes, "Default server_attributes not nil" )
26
- assert( d.instance.ssl_verify_peer, "Default ssl_verify_peer should be true" )
23
+ # rubocop:disable Layout/LineLength
24
+ class ConfigTest < Scalyr::ScalyrOutTest
25
+ def test_custom_serverhost_not_overwritten
26
+ hostname = "customHost"
27
+ d = create_driver CONFIG + "server_attributes { \"serverHost\":\"#{hostname}\" }\nuse_hostname_for_serverhost true"
28
+ assert_equal(hostname, d.instance.server_attributes["serverHost"], "Custom serverHost should not be overwritten")
29
+ end
27
30
 
28
- #check default buffer limits because they are set outside of the config_set_default
29
- assert_equal( 100*1024, d.instance.buffer.buffer_chunk_limit, "Buffer chunk limit should be 100k" )
30
- assert_equal( 1024, d.instance.buffer.buffer_queue_limit, "Buffer queue limit should be 1024" )
31
+ def test_configure_use_hostname_for_serverhost
32
+ d = create_driver CONFIG + "use_hostname_for_serverhost false"
33
+ assert_nil(d.instance.server_attributes, "Default server_attributes should be nil")
31
34
  end
32
35
 
33
36
  def test_configure_ssl_verify_peer
34
- d = create_driver CONFIG + 'ssl_verify_peer false'
35
- assert( !d.instance.ssl_verify_peer, "Config failed to set ssl_verify_peer" )
37
+ d = create_driver CONFIG + "ssl_verify_peer false"
38
+ assert(!d.instance.ssl_verify_peer, "Config failed to set ssl_verify_peer")
36
39
  end
37
40
 
38
41
  def test_scalyr_server_adding_trailing_slash
39
- d = create_driver CONFIG + 'scalyr_server http://www.example.com'
40
- assert_equal( "http://www.example.com/", d.instance.scalyr_server, "Missing trailing slash for scalyr_server" )
42
+ d = create_driver CONFIG + "scalyr_server http://www.example.com"
43
+ assert_equal("http://www.example.com/", d.instance.scalyr_server, "Missing trailing slash for scalyr_server")
41
44
  end
42
45
 
43
46
  def test_configure_ssl_ca_bundle_path
44
- d = create_driver CONFIG + 'ssl_ca_bundle_path /test/ca-bundle.crt'
45
- assert_equal( "/test/ca-bundle.crt", d.instance.ssl_ca_bundle_path, "Config failed to set ssl_ca_bundle_path" )
47
+ d = create_driver CONFIG + "ssl_ca_bundle_path /test/ca-bundle.crt"
48
+ assert_equal("/test/ca-bundle.crt", d.instance.ssl_ca_bundle_path, "Config failed to set ssl_ca_bundle_path")
46
49
  end
47
50
 
48
51
  def test_configure_ssl_verify_depth
49
- d = create_driver CONFIG + 'ssl_verify_depth 10'
50
- assert_equal( 10, d.instance.ssl_verify_depth, "Config failed to set ssl_verify_depth" )
52
+ d = create_driver CONFIG + "ssl_verify_depth 10"
53
+ assert_equal(10, d.instance.ssl_verify_depth, "Config failed to set ssl_verify_depth")
51
54
  end
52
55
 
53
56
  def test_configure_server_attributes
54
57
  d = create_driver CONFIG + 'server_attributes { "test":"value" }'
55
- assert_equal( "value", d.instance.server_attributes["test"], "Config failed to set server_attributes" )
58
+ assert_equal("value", d.instance.server_attributes["test"], "Config failed to set server_attributes")
56
59
  end
57
60
  end
58
-
61
+ # rubocop:enable Layout/LineLength
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Scalyr Output Plugin for Fluentd
3
5
  #
@@ -15,234 +17,316 @@
15
17
  # See the License for the specific language governing permissions and
16
18
  # limitations under the License.
17
19
 
18
-
19
- require 'helper'
20
- require 'fluent/event'
20
+ require "helper"
21
+ require "flexmock/test_unit"
22
+ require "fluent/event"
21
23
 
22
24
  class EventsTest < Scalyr::ScalyrOutTest
23
-
24
25
  def test_format
25
26
  d = create_driver
26
- response = flexmock( Net::HTTPResponse, :code => '200', :body =>'{ "status":"success" }' )
27
- mock = flexmock( d.instance )
28
- mock.should_receive( :post_request ).with_any_args.and_return( response )
29
-
30
- time = Time.parse("2015-04-01 10:00:00 UTC").to_i
31
- d.emit( { "a" => 1 }, time )
32
- d.expect_format [ "test", time, { "a" => 1 } ].to_msgpack
33
- d.run
27
+
28
+ time = event_time("2015-04-01 10:00:00 UTC")
29
+
30
+ response = flexmock(Net::HTTPResponse, code: "200", body: '{ "status":"success" }')
31
+ mock = flexmock(d.instance)
32
+ mock.should_receive(:post_request).with_any_args.and_return(response)
33
+
34
+ d.run(default_tag: "test") do
35
+ d.feed(time, {"a" => 1})
36
+ end
37
+
38
+ expected = [
39
+ ["test", time.sec, time.nsec, {"a" => 1}].to_msgpack
40
+ ]
41
+
42
+ assert_equal(expected, d.formatted)
34
43
  end
35
44
 
36
45
  def test_build_add_events_body_basic_values
37
46
  d = create_driver
38
- response = flexmock( Net::HTTPResponse, :code => '200', :body =>'{ "status":"success" }' )
39
- mock = flexmock( d.instance )
40
47
 
41
- time = Time.parse("2015-04-01 10:00:00 UTC").to_i
42
- attrs = { "a" => 1 }
43
- d.emit( attrs, time )
48
+ time = event_time("2015-04-01 10:00:00 UTC")
49
+ attrs = {"a" => 1}
50
+ attrs["logfile"] = "/fluentd/test"
44
51
 
45
- attrs["logfile"] = "/fluentd/test";
52
+ response = flexmock(Net::HTTPResponse, code: "200", body: '{ "status":"success" }')
53
+ mock = flexmock(d.instance)
46
54
 
47
- mock.should_receive( :post_request ).with(
55
+ mock_called = false
56
+
57
+ mock.should_receive(:post_request).with(
48
58
  URI,
49
- on { |request_body|
50
- body = JSON.parse( request_body )
51
- assert( body.key?( "token" ), "Missing token field" )
52
- assert( body.key?( "client_timestamp" ), "Missing client_timestamp field" )
53
- assert( body.key?( "session" ), "Missing session field" )
54
- assert( !body.key?( "sessionInfo"), "sessionInfo field set, but no sessionInfo" )
55
- assert( body.key?( "events" ), "missing events field" )
56
- assert( body.key?( "threads" ), "missing threads field" )
57
- assert_equal( 1, body['events'].length, "Only expecting 1 event" )
58
- assert_equal( d.instance.to_nanos( time ), body['events'][0]['ts'].to_i, "Event timestamp differs" )
59
- assert_equal( attrs, body['events'][0]['attrs'], "Value of attrs differs from log" )
60
- true
59
+ on {|request_body|
60
+ body = JSON.parse(request_body)
61
+ assert(body.key?("token"), "Missing token field")
62
+ assert(body.key?("client_timestamp"), "Missing client_timestamp field")
63
+ assert(body.key?("sessionInfo"), "sessionInfo field set, but no sessionInfo")
64
+ assert(body.key?("events"), "missing events field")
65
+ assert(body.key?("threads"), "missing threads field")
66
+ assert_equal(1, body["events"].length, "Only expecting 1 event")
67
+ assert_equal(time.sec * 1_000_000_000, body["events"][0]["ts"].to_i,
68
+ "Event timestamp differs")
69
+ assert_equal(attrs, body["events"][0]["attrs"], "Value of attrs differs from log")
70
+ mock_called = true
61
71
  }
62
- ).and_return( response )
72
+ ).once.and_return(response)
63
73
 
64
- d.run
74
+ d.run(default_tag: "test") do
75
+ d.feed(time, attrs)
76
+ end
77
+
78
+ assert_equal(mock_called, true, "mock method was never called!")
65
79
  end
66
80
 
67
81
  def test_build_add_events_body_dont_override_logfile_field
68
82
  d = create_driver
69
- response = flexmock( Net::HTTPResponse, :code => '200', :body =>'{ "status":"success" }' )
70
- mock = flexmock( d.instance )
71
83
 
72
- time = Time.parse("2015-04-01 10:00:00 UTC").to_i
73
- attrs = { "a" => 1 }
74
- attrs["logfile"] = "/some/log/file";
75
- d.emit( attrs, time )
84
+ time = event_time("2015-04-01 10:00:00 UTC")
85
+ attrs = {"a" => 1}
86
+ attrs["logfile"] = "/some/log/file"
87
+
88
+ response = flexmock(Net::HTTPResponse, code: "200", body: '{ "status":"success" }')
89
+ mock = flexmock(d.instance)
76
90
 
77
- mock.should_receive( :post_request ).with(
91
+ mock_called = false
92
+
93
+ mock.should_receive(:post_request).with(
78
94
  URI,
79
- on { |request_body|
80
- body = JSON.parse( request_body )
81
- assert_equal( attrs, body['events'][0]['attrs'], "Value of attrs differs from log" )
95
+ on {|request_body|
96
+ body = JSON.parse(request_body)
97
+ assert_equal(attrs, body["events"][0]["attrs"], "Value of attrs differs from log")
98
+ mock_called = true
82
99
  true
83
100
  }
84
- ).and_return( response )
101
+ ).once.and_return(response)
102
+
103
+ d.run(default_tag: "test") do
104
+ d.feed(time, attrs)
105
+ end
85
106
 
86
- d.run
107
+ assert_equal(mock_called, true, "mock method was never called!")
87
108
  end
88
109
 
89
110
  def test_build_add_events_body_with_server_attributes
90
111
  d = create_driver CONFIG + 'server_attributes { "test":"value" }'
91
112
 
92
- response = flexmock( Net::HTTPResponse, :code => '200', :body =>'{ "status":"success" }' )
93
- mock = flexmock( d.instance )
113
+ time = event_time("2015-04-01 10:00:00 UTC")
114
+ attrs = {"a" => 1}
115
+
116
+ response = flexmock(Net::HTTPResponse, code: "200", body: '{ "status":"success" }')
117
+ mock = flexmock(d.instance)
94
118
 
95
- time = Time.parse("2015-04-01 10:00:00 UTC").to_i
96
- attrs = { "a" => 1 }
97
- d.emit( attrs, time )
119
+ mock_called = false
98
120
 
99
- mock.should_receive( :post_request ).with(
121
+ mock.should_receive(:post_request).with(
100
122
  URI,
101
- on { |request_body|
102
- body = JSON.parse( request_body )
103
- assert( body.key?( "sessionInfo"), "sessionInfo field set, but no sessionInfo" )
104
- assert_equal( "value", body["sessionInfo"]["test"] )
123
+ on {|request_body|
124
+ body = JSON.parse(request_body)
125
+ assert(body.key?("sessionInfo"), "sessionInfo field set, but no sessionInfo")
126
+ assert_equal("value", body["sessionInfo"]["test"])
127
+ mock_called = true
105
128
  true
106
129
  }
107
- ).and_return( response )
130
+ ).once.and_return(response)
108
131
 
109
- d.run
132
+ d.run(default_tag: "test") do
133
+ d.feed(time, attrs)
134
+ end
135
+
136
+ assert_equal(mock_called, true, "mock method was never called!")
110
137
  end
111
138
 
112
139
  def test_build_add_events_body_incrementing_timestamps
113
140
  d = create_driver
114
- response = flexmock( Net::HTTPResponse, :code => '200', :body =>'{ "status":"success" }' )
115
- mock = flexmock( d.instance )
116
-
117
- time = Time.parse("2015-04-01 10:00:00 UTC").to_i
118
- d.emit( { "a" => 1 }, time )
119
- d.emit( { "a" => 2 }, time )
120
141
 
121
- time = Time.parse("2015-04-01 09:59:00 UTC").to_i
122
- d.emit( { "a" => 3 }, time )
142
+ time1 = event_time("2015-04-01 10:00:00 UTC")
143
+ time2 = event_time("2015-04-01 09:59:00 UTC")
123
144
 
124
- mock.should_receive( :post_request ).with(
125
- URI,
126
- on { |request_body|
127
- body = JSON.parse( request_body )
128
- events = body['events']
129
- assert_equal( 3, events.length, "Expecting 3 events" )
130
- #test equal timestamps are increased
131
- assert events[1]['ts'].to_i > events[0]['ts'].to_i, "Event timestamps must increase"
145
+ response = flexmock(Net::HTTPResponse, code: "200", body: '{ "status":"success" }')
146
+ mock = flexmock(d.instance)
132
147
 
133
- #test earlier timestamps are increased
134
- assert events[2]['ts'].to_i > events[1]['ts'].to_i, "Event timestamps must increase"
148
+ mock_called = false
135
149
 
150
+ mock.should_receive(:post_request).with(
151
+ URI,
152
+ on {|request_body|
153
+ body = JSON.parse(request_body)
154
+ events = body["events"]
155
+ assert_equal(3, events.length, "Expecting 3 events")
156
+ # Since 0.8.10 timestamps dont need to increase anymore
157
+ assert events[1]["ts"].to_i == events[0]["ts"].to_i, "Event timestamps must be the same"
158
+ assert events[2]["ts"].to_i < events[0]["ts"].to_i, "Event timestamps must be less"
159
+ mock_called = true
136
160
  true
137
161
  }
138
- ).and_return( response )
162
+ ).once.and_return(response)
139
163
 
140
- d.run
164
+ d.run(default_tag: "test") do
165
+ d.feed(time1, {"a" => 1})
166
+ d.feed(time1, {"a" => 2})
167
+ d.feed(time2, {"a" => 3})
168
+ end
169
+
170
+ assert_equal(mock_called, true, "mock method was never called!")
141
171
  end
142
172
 
143
- def test_build_add_events_body_thread_ids
173
+ def test_build_add_events_body_non_json_serializable_value
144
174
  d = create_driver
145
- response = flexmock( Net::HTTPResponse, :code => '200', :body =>'{ "status":"success" }' )
146
- mock = flexmock( d.instance )
147
175
 
148
- entries = []
176
+ time = event_time("2015-04-01 10:00:00 UTC")
177
+ attrs = {"a" => 1}
178
+ attrs["int1"] = 1_601_923_119
179
+ attrs["int2"] = Integer(1_601_923_119)
180
+ attrs["int3"] = Integer(9_223_372_036_854_775_807)
181
+ attrs["int4"] = Integer(-1)
182
+ attrs["nil"] = nil
183
+ attrs["array"] = [1, 2, "a", "b", nil]
184
+ attrs["hash"] = {
185
+ "a" => "1",
186
+ "b" => "c"
187
+ }
188
+ attrs["logfile"] = "/some/log/file"
189
+
190
+ # This partial unicode sequence will fail encoding so we make sure it doesn't break the plugin
191
+ # and we correctly cast it to a value which we can send to the API
192
+ attrs["partial_unicode_sequence"] = "\xC2"
193
+ attrs["array_with_partial_unicode_sequence"] = [1, 2, "a", "b", nil, "7", "\xC2"]
194
+ attrs["nested_array_with_partial_unicode_sequence"] = [1, 2, "a", "b", nil, "7",
195
+ [8, 9, [10, "\xC2"]],
196
+ {"a" => 1, "b" => "\xC2"}]
197
+ attrs["hash_with_partial_unicode_sequence"] = {
198
+ "a" => "1",
199
+ "b" => "\xC2",
200
+ "c" => nil
201
+ }
202
+ attrs["nested_hash_with_partial_unicode_sequence"] = {
203
+ "a" => "1",
204
+ "b" => {
205
+ "c" => "\xC2",
206
+ "d" => "e",
207
+ "f" => nil,
208
+ "g" => {
209
+ "h" => "\xC2",
210
+ "b" => 3
211
+ }
212
+ }
213
+ }
214
+
215
+ response = flexmock(Net::HTTPResponse, code: "200", body: '{ "status":"success" }')
216
+ mock = flexmock(d.instance)
149
217
 
150
- time = Time.parse("2015-04-01 10:00:00 UTC").to_i
151
- entries << [time, { "a" => 1 }]
218
+ mock_called = false
152
219
 
153
- es = Fluent::ArrayEventStream.new(entries)
154
- buffer = d.instance.format_stream("test1", es)
220
+ # NOTE: We need to perform a deep clone / copy
221
+ expected_attrs = Marshal.load(Marshal.dump(attrs))
155
222
 
156
- chunk = d.instance.buffer.new_chunk('')
157
- chunk << buffer
223
+ expected_attrs["partial_unicode_sequence"] = "<?>"
224
+ expected_attrs["array_with_partial_unicode_sequence"][-1] = "<?>"
225
+ expected_attrs["nested_array_with_partial_unicode_sequence"][-2][-1][-1] = "<?>"
226
+ expected_attrs["nested_array_with_partial_unicode_sequence"][-1]["b"] = "<?>"
227
+ expected_attrs["hash_with_partial_unicode_sequence"]["b"] = "<?>"
228
+ expected_attrs["nested_hash_with_partial_unicode_sequence"]["b"]["c"] = "<?>"
229
+ expected_attrs["nested_hash_with_partial_unicode_sequence"]["b"]["g"]["h"] = "<?>"
158
230
 
159
- buffer = d.instance.format_stream("test2", es)
160
- chunk << buffer
231
+ # Verify that clone / copy was correct and the original object wasn't modified
232
+ assert_not_equal(expected_attrs, attrs, "Objects are the same but should be different")
233
+ assert_not_equal(Marshal.load(Marshal.dump(attrs)), Marshal.load(Marshal.dump(expected_attrs)))
234
+ assert_equal(attrs["partial_unicode_sequence"], "\xC2")
235
+ assert_equal(attrs["array_with_partial_unicode_sequence"][-1], "\xC2")
236
+ assert_equal(attrs["nested_hash_with_partial_unicode_sequence"]["b"]["g"]["h"], "\xC2")
161
237
 
162
- mock.should_receive( :post_request ).with(
238
+ mock.should_receive(:post_request).with(
163
239
  URI,
164
- on { |request_body|
165
- body = JSON.parse( request_body )
166
- events = body['events']
167
- threads = body['threads']
168
-
169
- assert_equal( 2, threads.length, "Expecting 2 threads, #{threads.length} found" )
170
- assert_equal( 2, events.length, "Expecting 2 events, #{events.length} found" )
171
- assert_equal( events[0]['thread'], threads[0]['id'].to_s, "thread id should match event thread id" )
172
- assert_equal( events[1]['thread'], threads[1]['id'].to_s, "thread id should match event thread id" )
240
+ on {|request_body|
241
+ body = JSON.parse(request_body)
242
+ assert_equal(expected_attrs, body["events"][0]["attrs"], "Value of attrs differs from log")
243
+ mock_called = true
173
244
  true
174
245
  }
175
- ).at_least.once.and_return( response )
246
+ ).once.and_return(response)
247
+
248
+ d.run(default_tag: "test") do
249
+ d.feed(time, attrs)
250
+ end
176
251
 
177
- d.instance.start
178
- d.instance.write( chunk )
179
- d.instance.shutdown
252
+ assert_equal(mock_called, true, "mock method was never called!")
180
253
  end
181
254
 
182
255
  def test_default_message_field
183
256
  d = create_driver CONFIG
184
257
 
185
- response = flexmock( Net::HTTPResponse, :code => '200', :body =>'{ "status":"success" }' )
186
- mock = flexmock( d.instance )
258
+ time = event_time("2015-04-01 10:00:00 UTC")
259
+ attrs = {"log" => "this is a test", "logfile" => "/fluentd/test"}
187
260
 
188
- time = Time.parse("2015-04-01 10:00:00 UTC").to_i
189
- attrs = { "log" => "this is a test", "logfile" => "/fluentd/test" }
190
- d.emit( attrs, time )
261
+ response = flexmock(Net::HTTPResponse, code: "200", body: '{ "status":"success" }')
262
+ mock = flexmock(d.instance)
191
263
 
192
- mock.should_receive( :post_request ).with(
264
+ mock_called = false
265
+
266
+ mock.should_receive(:post_request).with(
193
267
  URI,
194
- on { |request_body|
195
- body = JSON.parse( request_body )
196
- events = body['events']
197
- assert_equal( attrs, body['events'][0]['attrs'], "Value of attrs differs from log" )
268
+ on {|request_body|
269
+ body = JSON.parse(request_body)
270
+ assert_equal(attrs, body["events"][0]["attrs"], "Value of attrs differs from log")
271
+ mock_called = true
198
272
  true
199
273
  }
200
- ).and_return( response )
274
+ ).once.and_return(response)
275
+
276
+ d.run(default_tag: "test") do
277
+ d.feed(time, attrs)
278
+ end
201
279
 
202
- d.run
280
+ assert_equal(mock_called, true, "mock method was never called!")
203
281
  end
204
282
 
205
283
  def test_different_message_field
206
- d = create_driver CONFIG + 'message_field log'
284
+ d = create_driver CONFIG + "message_field log"
207
285
 
208
- response = flexmock( Net::HTTPResponse, :code => '200', :body =>'{ "status":"success" }' )
209
- mock = flexmock( d.instance )
286
+ time = event_time("2015-04-01 10:00:00 UTC")
287
+ attrs = {"log" => "this is a test"}
210
288
 
211
- time = Time.parse("2015-04-01 10:00:00 UTC").to_i
212
- attrs = { "log" => "this is a test" }
213
- d.emit( attrs, time )
289
+ response = flexmock(Net::HTTPResponse, code: "200", body: '{ "status":"success" }')
290
+ mock = flexmock(d.instance)
214
291
 
215
- mock.should_receive( :post_request ).with(
292
+ mock_called = false
293
+
294
+ mock.should_receive(:post_request).with(
216
295
  URI,
217
- on { |request_body|
218
- body = JSON.parse( request_body )
219
- events = body['events']
220
- assert( events[0]['attrs'].key?( 'message'), "'message' field not found in event" )
221
- assert_equal( "this is a test", events[0]['attrs']['message'], "'message' field incorrect" )
222
- assert( !events[0]['attrs'].key?( 'log' ), "'log' field should no longer exist in event" )
296
+ on {|request_body|
297
+ body = JSON.parse(request_body)
298
+ events = body["events"]
299
+ assert(events[0]["attrs"].key?("message"), "'message' field not found in event")
300
+ assert_equal("this is a test", events[0]["attrs"]["message"], "'message' field incorrect")
301
+ assert(!events[0]["attrs"].key?("log"), "'log' field should no longer exist in event")
302
+ mock_called = true
223
303
  true
224
304
  }
225
- ).and_return( response )
305
+ ).once.and_return(response)
306
+
307
+ d.run(default_tag: "test") do
308
+ d.feed(time, attrs)
309
+ end
226
310
 
227
- d.run
311
+ assert_equal(mock_called, true, "mock method was never called!")
228
312
  end
229
313
 
230
314
  def test_different_message_field_message_already_exists
231
- d = create_driver CONFIG + 'message_field log'
315
+ d = create_driver CONFIG + "message_field log"
232
316
 
233
- response = flexmock( Net::HTTPResponse, :code => '200', :body =>'{ "status":"success" }' )
234
- mock = flexmock( d.instance )
235
- mock.should_receive( :post_request ).and_return( response )
317
+ time = event_time("2015-04-01 10:00:00 UTC")
318
+ attrs = {"log" => "this is a test", "message" => "uh oh"}
236
319
 
237
- time = Time.parse("2015-04-01 10:00:00 UTC").to_i
238
- attrs = { "log" => "this is a test", "message" => "uh oh" }
239
- d.emit( attrs, time )
320
+ response = flexmock(Net::HTTPResponse, code: "200", body: '{ "status":"success" }')
321
+ mock = flexmock(d.instance)
240
322
 
241
- logger = flexmock( $log )
242
- logger.should_receive( :warn ).with( /overwriting log record field 'message'/i ).at_least().once()
323
+ mock.should_receive(:post_request).once.and_return(response)
243
324
 
244
- d.run
245
- end
325
+ logger = flexmock($log)
326
+ logger.should_receive(:warn).with(/overwriting log record field 'message'/i).at_least.once
246
327
 
328
+ d.run(default_tag: "test") do
329
+ d.feed(time, attrs)
330
+ end
331
+ end
247
332
  end
248
-