fluent-plugin-bigquery 0.4.4 → 0.5.0.beta1
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/.travis.yml +0 -1
- data/README.md +123 -127
- data/fluent-plugin-bigquery.gemspec +1 -4
- data/lib/fluent/plugin/bigquery/schema.rb +2 -4
- data/lib/fluent/plugin/bigquery/version.rb +1 -1
- data/lib/fluent/plugin/bigquery/writer.rb +2 -8
- data/lib/fluent/plugin/out_bigquery.rb +431 -440
- data/test/helper.rb +5 -1
- data/test/plugin/test_out_bigquery.rb +479 -708
- data/test/plugin/test_record_schema.rb +8 -24
- data/test/run_test.rb +9 -0
- metadata +8 -48
data/test/helper.rb
CHANGED
@@ -21,11 +21,15 @@ unless ENV.has_key?('VERBOSE')
|
|
21
21
|
$log = nulllogger
|
22
22
|
end
|
23
23
|
|
24
|
-
require 'fluent/buffer'
|
24
|
+
require 'fluent/plugin/buffer'
|
25
25
|
require 'fluent/plugin/buf_memory'
|
26
26
|
require 'fluent/plugin/buf_file'
|
27
|
+
require 'fluent/test/driver/output'
|
27
28
|
|
28
29
|
require 'fluent/plugin/out_bigquery'
|
30
|
+
require 'google/apis/bigquery_v2'
|
31
|
+
require 'google/api_client/auth/key_utils'
|
32
|
+
require 'googleauth'
|
29
33
|
|
30
34
|
require 'rr'
|
31
35
|
require 'test/unit/rr'
|
@@ -1,11 +1,4 @@
|
|
1
1
|
require 'helper'
|
2
|
-
require 'google/apis/bigquery_v2'
|
3
|
-
require 'google/api_client/auth/key_utils'
|
4
|
-
require 'googleauth'
|
5
|
-
require 'active_support/json'
|
6
|
-
require 'active_support/core_ext/hash'
|
7
|
-
require 'active_support/core_ext/object/json'
|
8
|
-
|
9
2
|
|
10
3
|
class BigQueryOutputTest < Test::Unit::TestCase
|
11
4
|
def setup
|
@@ -19,8 +12,10 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
19
12
|
project yourproject_id
|
20
13
|
dataset yourdataset_id
|
21
14
|
|
15
|
+
<inject>
|
22
16
|
time_format %s
|
23
|
-
|
17
|
+
time_key time
|
18
|
+
</inject>
|
24
19
|
|
25
20
|
schema [
|
26
21
|
{"name": "time", "type": "INTEGER"},
|
@@ -46,7 +41,7 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
46
41
|
API_SCOPE = "https://www.googleapis.com/auth/bigquery"
|
47
42
|
|
48
43
|
def create_driver(conf = CONFIG)
|
49
|
-
Fluent::Test::
|
44
|
+
Fluent::Test::Driver::Output.new(Fluent::Plugin::BigQueryOutput).configure(conf)
|
50
45
|
end
|
51
46
|
|
52
47
|
def stub_writer(driver)
|
@@ -55,21 +50,6 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
55
50
|
writer
|
56
51
|
end
|
57
52
|
|
58
|
-
# ref. https://github.com/GoogleCloudPlatform/google-cloud-ruby/blob/ea2be47beb32615b2bf69f8a846a684f86c8328c/google-cloud-bigquery/test/google/cloud/bigquery/table_insert_test.rb#L141
|
59
|
-
def failure_insert_errors(reason, error_count, insert_error_count)
|
60
|
-
error = Google::Apis::BigqueryV2::ErrorProto.new(
|
61
|
-
reason: reason
|
62
|
-
)
|
63
|
-
insert_error = Google::Apis::BigqueryV2::InsertAllTableDataResponse::InsertError.new(
|
64
|
-
errors: [].fill(error, 0, error_count)
|
65
|
-
)
|
66
|
-
|
67
|
-
res = Google::Apis::BigqueryV2::InsertAllTableDataResponse.new(
|
68
|
-
insert_errors: [].fill(insert_error, 0, insert_error_count)
|
69
|
-
)
|
70
|
-
return res
|
71
|
-
end
|
72
|
-
|
73
53
|
def test_configure_table
|
74
54
|
driver = create_driver
|
75
55
|
assert_equal driver.instance.table, 'foo'
|
@@ -77,7 +57,7 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
77
57
|
|
78
58
|
driver = create_driver(CONFIG.sub(/\btable\s+.*$/, 'tables foo,bar'))
|
79
59
|
assert_nil driver.instance.table
|
80
|
-
assert_equal driver.instance.tables, 'foo,bar'
|
60
|
+
assert_equal driver.instance.tables, ['foo' ,'bar']
|
81
61
|
|
82
62
|
assert_raise(Fluent::ConfigError, "'table' or 'tables' must be specified, and both are invalid") {
|
83
63
|
create_driver(CONFIG + "tables foo,bar")
|
@@ -240,116 +220,173 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
240
220
|
assert driver.instance.writer.client.is_a?(Google::Apis::BigqueryV2::BigqueryService)
|
241
221
|
end
|
242
222
|
|
243
|
-
def
|
244
|
-
now = Time.now
|
245
|
-
input =
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
223
|
+
def test_format
|
224
|
+
now = Fluent::EventTime.new(Time.now.to_i)
|
225
|
+
input = {
|
226
|
+
"status" => "1",
|
227
|
+
"bytes" => 3.0,
|
228
|
+
"vhost" => :bar,
|
229
|
+
"path" => "/path/to/baz",
|
230
|
+
"method" => "GET",
|
231
|
+
"protocol" => "HTTP/0.9",
|
232
|
+
"agent" => "libwww",
|
233
|
+
"referer" => "http://referer.example",
|
234
|
+
"requesttime" => (now - 1).to_f.to_s,
|
235
|
+
"bot_access" => true,
|
236
|
+
"loginsession" => false,
|
237
|
+
"something-else" => "would be ignored",
|
238
|
+
"yet-another" => {
|
239
|
+
"foo" => "bar",
|
240
|
+
"baz" => 1,
|
241
|
+
},
|
242
|
+
"remote" => {
|
243
|
+
"host" => "remote.example",
|
244
|
+
"ip" => "192.0.2.1",
|
245
|
+
"port" => 12345,
|
246
|
+
"user" => "tagomoris",
|
252
247
|
}
|
253
|
-
|
248
|
+
}
|
254
249
|
expected = {
|
255
|
-
"
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
250
|
+
"time" => now.to_i,
|
251
|
+
"status" => 1,
|
252
|
+
"bytes" => 3,
|
253
|
+
"vhost" => "bar",
|
254
|
+
"path" => "/path/to/baz",
|
255
|
+
"method" => "GET",
|
256
|
+
"protocol" => "HTTP/0.9",
|
257
|
+
"agent" => "libwww",
|
258
|
+
"referer" => "http://referer.example",
|
259
|
+
"requesttime" => (now - 1).to_f.to_s.to_f,
|
260
|
+
"bot_access" => true,
|
261
|
+
"loginsession" => false,
|
262
|
+
"something-else" => "would be ignored",
|
263
|
+
"yet-another" => {
|
264
|
+
"foo" => "bar",
|
265
|
+
"baz" => 1,
|
266
|
+
},
|
267
|
+
"remote" => {
|
268
|
+
"host" => "remote.example",
|
269
|
+
"ip" => "192.0.2.1",
|
270
|
+
"port" => 12345,
|
271
|
+
"user" => "tagomoris",
|
261
272
|
}
|
262
273
|
}
|
263
274
|
|
264
|
-
driver = create_driver(
|
265
|
-
|
266
|
-
|
267
|
-
private_key_path /path/to/key
|
268
|
-
project yourproject_id
|
269
|
-
dataset yourdataset_id
|
275
|
+
driver = create_driver(CONFIG)
|
276
|
+
buf = nil
|
277
|
+
driver.run { buf = driver.instance.format("my.tag", now, input) }
|
270
278
|
|
271
|
-
|
272
|
-
|
279
|
+
assert_equal expected, MultiJson.load(buf)
|
280
|
+
end
|
273
281
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
+
[
|
283
|
+
# <time_format>, <time field type>, <time expectation generator>, <assertion>
|
284
|
+
[
|
285
|
+
"%s.%6N", "field_float",
|
286
|
+
lambda{|t| t.strftime("%s.%6N").to_f },
|
287
|
+
lambda{|recv, expected, actual|
|
288
|
+
recv.assert_in_delta(expected, actual, Float::EPSILON / 10**3)
|
289
|
+
}
|
290
|
+
],
|
291
|
+
[
|
292
|
+
"%Y-%m-%dT%H:%M:%S%:z", "field_string",
|
293
|
+
lambda{|t| t.iso8601 },
|
294
|
+
:assert_equal.to_proc
|
295
|
+
],
|
296
|
+
].each do |format, type, expect_time, assert|
|
297
|
+
define_method("test_time_formats_#{format}") do
|
298
|
+
now = Fluent::Engine.now
|
299
|
+
input = {}
|
300
|
+
expected = { "time" => expect_time[Time.at(now.to_r)] }
|
282
301
|
|
283
|
-
|
284
|
-
|
285
|
-
|
302
|
+
driver = create_driver(<<-CONFIG)
|
303
|
+
table foo
|
304
|
+
email foo@bar.example
|
305
|
+
private_key_path /path/to/key
|
306
|
+
project yourproject_id
|
307
|
+
dataset yourdataset_id
|
308
|
+
|
309
|
+
<inject>
|
310
|
+
time_format #{format}
|
311
|
+
time_type string
|
312
|
+
time_key time
|
313
|
+
</inject>
|
314
|
+
#{type} time
|
315
|
+
|
316
|
+
schema [
|
317
|
+
{"name": "metadata", "type": "RECORD", "fields": [
|
318
|
+
{"name": "time", "type": "INTEGER"},
|
319
|
+
{"name": "node", "type": "STRING"}
|
320
|
+
]},
|
321
|
+
{"name": "log", "type": "STRING"}
|
322
|
+
]
|
323
|
+
CONFIG
|
324
|
+
|
325
|
+
buf = nil
|
326
|
+
driver.run { buf = driver.instance.format("my.tag", now, input) }
|
286
327
|
|
287
|
-
|
328
|
+
assert[self, expected["time"], MultiJson.load(buf)["time"]]
|
329
|
+
end
|
288
330
|
end
|
289
331
|
|
290
332
|
def test_format_with_schema
|
291
|
-
now = Time.now
|
292
|
-
input =
|
293
|
-
|
294
|
-
|
295
|
-
"
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
"
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
"
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
"
|
317
|
-
"
|
318
|
-
|
319
|
-
|
320
|
-
},
|
321
|
-
}
|
322
|
-
]
|
333
|
+
now = Fluent::EventTime.new(Time.now.to_i)
|
334
|
+
input = {
|
335
|
+
"request" => {
|
336
|
+
"vhost" => :bar,
|
337
|
+
"path" => "/path/to/baz",
|
338
|
+
"method" => "GET",
|
339
|
+
"protocol" => "HTTP/0.9",
|
340
|
+
"agent" => "libwww",
|
341
|
+
"referer" => "http://referer.example",
|
342
|
+
"time" => (now - 1).to_f,
|
343
|
+
"bot_access" => true,
|
344
|
+
"loginsession" => false,
|
345
|
+
},
|
346
|
+
"response" => {
|
347
|
+
"status" => "1",
|
348
|
+
"bytes" => 3.0,
|
349
|
+
},
|
350
|
+
"remote" => {
|
351
|
+
"host" => "remote.example",
|
352
|
+
"ip" => "192.0.2.1",
|
353
|
+
"port" => 12345,
|
354
|
+
"user" => "tagomoris",
|
355
|
+
},
|
356
|
+
"something-else" => "would be ignored",
|
357
|
+
"yet-another" => {
|
358
|
+
"foo" => "bar",
|
359
|
+
"baz" => 1,
|
360
|
+
},
|
361
|
+
}
|
323
362
|
expected = {
|
324
|
-
"
|
325
|
-
|
326
|
-
"
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
"
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
"
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
"
|
349
|
-
|
350
|
-
|
351
|
-
},
|
352
|
-
}
|
363
|
+
"time" => now.to_f,
|
364
|
+
"request" => {
|
365
|
+
"vhost" => "bar",
|
366
|
+
"path" => "/path/to/baz",
|
367
|
+
"method" => "GET",
|
368
|
+
"protocol" => "HTTP/0.9",
|
369
|
+
"agent" => "libwww",
|
370
|
+
"referer" => "http://referer.example",
|
371
|
+
"time" => (now - 1).to_f,
|
372
|
+
"bot_access" => true,
|
373
|
+
"loginsession" => false,
|
374
|
+
},
|
375
|
+
"remote" => {
|
376
|
+
"host" => "remote.example",
|
377
|
+
"ip" => "192.0.2.1",
|
378
|
+
"port" => 12345,
|
379
|
+
"user" => "tagomoris",
|
380
|
+
},
|
381
|
+
"response" => {
|
382
|
+
"status" => 1,
|
383
|
+
"bytes" => 3,
|
384
|
+
},
|
385
|
+
"something-else" => "would be ignored",
|
386
|
+
"yet-another" => {
|
387
|
+
"foo" => "bar",
|
388
|
+
"baz" => 1,
|
389
|
+
},
|
353
390
|
}
|
354
391
|
|
355
392
|
driver = create_driver(<<-CONFIG)
|
@@ -359,37 +396,34 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
359
396
|
project yourproject_id
|
360
397
|
dataset yourdataset_id
|
361
398
|
|
399
|
+
<inject>
|
362
400
|
time_format %s
|
363
|
-
|
401
|
+
time_key time
|
402
|
+
</inject>
|
364
403
|
|
365
404
|
schema_path #{File.join(File.dirname(__FILE__), "testdata", "apache.schema")}
|
366
405
|
schema [{"name": "time", "type": "INTEGER"}]
|
367
406
|
CONFIG
|
368
|
-
driver.instance.start
|
369
|
-
buf = driver.instance.format_stream("my.tag", [input])
|
370
|
-
driver.instance.shutdown
|
371
407
|
|
372
|
-
|
408
|
+
buf = nil
|
409
|
+
driver.run { buf = driver.instance.format("my.tag", now, input) }
|
410
|
+
|
411
|
+
assert_equal expected, MultiJson.load(buf)
|
373
412
|
end
|
374
413
|
|
375
414
|
def test_format_repeated_field_with_schema
|
376
|
-
now = Time.now
|
377
|
-
input =
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
384
|
-
}
|
385
|
-
]
|
415
|
+
now = Fluent::EventTime.new(Time.now.to_i)
|
416
|
+
input = {
|
417
|
+
"tty" => nil,
|
418
|
+
"pwd" => "/home/yugui",
|
419
|
+
"user" => "fluentd",
|
420
|
+
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
421
|
+
}
|
386
422
|
expected = {
|
387
|
-
"
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
392
|
-
}
|
423
|
+
"time" => now.to_f,
|
424
|
+
"pwd" => "/home/yugui",
|
425
|
+
"user" => "fluentd",
|
426
|
+
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
393
427
|
}
|
394
428
|
|
395
429
|
driver = create_driver(<<-CONFIG)
|
@@ -399,37 +433,34 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
399
433
|
project yourproject_id
|
400
434
|
dataset yourdataset_id
|
401
435
|
|
436
|
+
<inject>
|
402
437
|
time_format %s
|
403
|
-
|
438
|
+
time_key time
|
439
|
+
</inject>
|
404
440
|
|
405
441
|
schema_path #{File.join(File.dirname(__FILE__), "testdata", "sudo.schema")}
|
406
442
|
schema [{"name": "time", "type": "INTEGER"}]
|
407
443
|
CONFIG
|
408
|
-
driver.instance.start
|
409
|
-
buf = driver.instance.format_stream("my.tag", [input])
|
410
|
-
driver.instance.shutdown
|
411
444
|
|
412
|
-
|
445
|
+
buf = nil
|
446
|
+
driver.run { buf = driver.instance.format("my.tag", now, input) }
|
447
|
+
|
448
|
+
assert_equal expected, MultiJson.load(buf)
|
413
449
|
end
|
414
450
|
|
415
451
|
def test_format_fetch_from_bigquery_api
|
416
|
-
now = Time.now
|
417
|
-
input =
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
424
|
-
}
|
425
|
-
]
|
452
|
+
now = Fluent::EventTime.new(Time.now.to_i)
|
453
|
+
input = {
|
454
|
+
"tty" => nil,
|
455
|
+
"pwd" => "/home/yugui",
|
456
|
+
"user" => "fluentd",
|
457
|
+
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
458
|
+
}
|
426
459
|
expected = {
|
427
|
-
"
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
432
|
-
}
|
460
|
+
"time" => now.to_i,
|
461
|
+
"pwd" => "/home/yugui",
|
462
|
+
"user" => "fluentd",
|
463
|
+
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
433
464
|
}
|
434
465
|
|
435
466
|
driver = create_driver(<<-CONFIG)
|
@@ -439,8 +470,10 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
439
470
|
project yourproject_id
|
440
471
|
dataset yourdataset_id
|
441
472
|
|
473
|
+
<inject>
|
442
474
|
time_format %s
|
443
|
-
|
475
|
+
time_key time
|
476
|
+
</inject>
|
444
477
|
|
445
478
|
fetch_schema true
|
446
479
|
schema [{"name": "time", "type": "INTEGER"}]
|
@@ -450,52 +483,47 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
450
483
|
mock(writer).fetch_schema('yourproject_id', 'yourdataset_id', 'foo') do
|
451
484
|
sudo_schema_response.deep_stringify_keys["schema"]["fields"]
|
452
485
|
end
|
453
|
-
driver.instance.start
|
454
|
-
buf = driver.instance.format_stream("my.tag", [input])
|
455
|
-
driver.instance.shutdown
|
456
486
|
|
457
|
-
|
487
|
+
buf = nil
|
488
|
+
driver.run { buf = driver.instance.format("my.tag", now, input) }
|
489
|
+
|
490
|
+
assert_equal expected, MultiJson.load(buf)
|
458
491
|
|
459
|
-
|
460
|
-
assert
|
461
|
-
assert_equal :
|
462
|
-
assert_equal :
|
492
|
+
table_schema = driver.instance.instance_eval{ @fetched_schemas['yourproject_id.yourdataset_id.foo'] }
|
493
|
+
assert table_schema["time"]
|
494
|
+
assert_equal :timestamp, table_schema["time"].type
|
495
|
+
assert_equal :required, table_schema["time"].mode
|
463
496
|
|
464
|
-
assert
|
465
|
-
assert_equal :string,
|
466
|
-
assert_equal :nullable,
|
497
|
+
assert table_schema["tty"]
|
498
|
+
assert_equal :string, table_schema["tty"].type
|
499
|
+
assert_equal :nullable, table_schema["tty"].mode
|
467
500
|
|
468
|
-
assert
|
469
|
-
assert_equal :string,
|
470
|
-
assert_equal :required,
|
501
|
+
assert table_schema["pwd"]
|
502
|
+
assert_equal :string, table_schema["pwd"].type
|
503
|
+
assert_equal :required, table_schema["pwd"].mode
|
471
504
|
|
472
|
-
assert
|
473
|
-
assert_equal :string,
|
474
|
-
assert_equal :required,
|
505
|
+
assert table_schema["user"]
|
506
|
+
assert_equal :string, table_schema["user"].type
|
507
|
+
assert_equal :required, table_schema["user"].mode
|
475
508
|
|
476
|
-
assert
|
477
|
-
assert_equal :string,
|
478
|
-
assert_equal :repeated,
|
509
|
+
assert table_schema["argv"]
|
510
|
+
assert_equal :string, table_schema["argv"].type
|
511
|
+
assert_equal :repeated, table_schema["argv"].mode
|
479
512
|
end
|
480
513
|
|
481
|
-
def
|
482
|
-
now = Time.now
|
483
|
-
input =
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
490
|
-
}
|
491
|
-
]
|
514
|
+
def test_format_fetch_from_bigquery_api_with_fetch_schema_table
|
515
|
+
now = Fluent::EventTime.new(Time.now.to_i)
|
516
|
+
input = {
|
517
|
+
"tty" => nil,
|
518
|
+
"pwd" => "/home/yugui",
|
519
|
+
"user" => "fluentd",
|
520
|
+
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
521
|
+
}
|
492
522
|
expected = {
|
493
|
-
"
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
498
|
-
}
|
523
|
+
"time" => now.to_i,
|
524
|
+
"pwd" => "/home/yugui",
|
525
|
+
"user" => "fluentd",
|
526
|
+
"argv" => %w[ tail -f /var/log/fluentd/fluentd.log ]
|
499
527
|
}
|
500
528
|
|
501
529
|
driver = create_driver(<<-CONFIG)
|
@@ -505,57 +533,61 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
505
533
|
project yourproject_id
|
506
534
|
dataset yourdataset_id
|
507
535
|
|
536
|
+
<inject>
|
508
537
|
time_format %s
|
509
|
-
|
538
|
+
time_key time
|
539
|
+
</inject>
|
510
540
|
|
511
541
|
fetch_schema true
|
542
|
+
fetch_schema_table foo
|
512
543
|
schema [{"name": "time", "type": "INTEGER"}]
|
544
|
+
|
545
|
+
<buffer time>
|
546
|
+
timekey 1d
|
547
|
+
</buffer>
|
513
548
|
CONFIG
|
514
549
|
|
515
550
|
writer = stub_writer(driver)
|
516
|
-
mock(writer).fetch_schema('yourproject_id', 'yourdataset_id',
|
551
|
+
mock(writer).fetch_schema('yourproject_id', 'yourdataset_id', 'foo') do
|
517
552
|
sudo_schema_response.deep_stringify_keys["schema"]["fields"]
|
518
553
|
end
|
519
|
-
driver.instance.start
|
520
|
-
buf = driver.instance.format_stream("my.tag", [input])
|
521
|
-
driver.instance.shutdown
|
522
554
|
|
523
|
-
|
555
|
+
buf = nil
|
556
|
+
driver.run { buf = driver.instance.format("my.tag", now, input) }
|
557
|
+
|
558
|
+
assert_equal expected, MultiJson.load(buf)
|
524
559
|
|
525
|
-
|
526
|
-
assert
|
527
|
-
assert_equal :
|
528
|
-
assert_equal :
|
560
|
+
table_schema = driver.instance.instance_eval{ @fetched_schemas['yourproject_id.yourdataset_id.foo'] }
|
561
|
+
assert table_schema["time"]
|
562
|
+
assert_equal :timestamp, table_schema["time"].type
|
563
|
+
assert_equal :required, table_schema["time"].mode
|
529
564
|
|
530
|
-
assert
|
531
|
-
assert_equal :string,
|
532
|
-
assert_equal :nullable,
|
565
|
+
assert table_schema["tty"]
|
566
|
+
assert_equal :string, table_schema["tty"].type
|
567
|
+
assert_equal :nullable, table_schema["tty"].mode
|
533
568
|
|
534
|
-
assert
|
535
|
-
assert_equal :string,
|
536
|
-
assert_equal :required,
|
569
|
+
assert table_schema["pwd"]
|
570
|
+
assert_equal :string, table_schema["pwd"].type
|
571
|
+
assert_equal :required, table_schema["pwd"].mode
|
537
572
|
|
538
|
-
assert
|
539
|
-
assert_equal :string,
|
540
|
-
assert_equal :required,
|
573
|
+
assert table_schema["user"]
|
574
|
+
assert_equal :string, table_schema["user"].type
|
575
|
+
assert_equal :required, table_schema["user"].mode
|
541
576
|
|
542
|
-
assert
|
543
|
-
assert_equal :string,
|
544
|
-
assert_equal :repeated,
|
577
|
+
assert table_schema["argv"]
|
578
|
+
assert_equal :string, table_schema["argv"].type
|
579
|
+
assert_equal :repeated, table_schema["argv"].mode
|
545
580
|
end
|
546
581
|
|
547
|
-
def
|
548
|
-
now = Time.now
|
549
|
-
input =
|
550
|
-
|
551
|
-
|
552
|
-
"uuid" => "9ABFF756-0267-4247-847F-0895B65F0938",
|
553
|
-
}
|
554
|
-
]
|
582
|
+
def test__write_with_insert_id
|
583
|
+
now = Time.now.to_i
|
584
|
+
input = {
|
585
|
+
"uuid" => "9ABFF756-0267-4247-847F-0895B65F0938",
|
586
|
+
}
|
555
587
|
expected = {
|
556
|
-
|
557
|
-
|
558
|
-
|
588
|
+
insert_id: "9ABFF756-0267-4247-847F-0895B65F0938",
|
589
|
+
json: {
|
590
|
+
uuid: "9ABFF756-0267-4247-847F-0895B65F0938",
|
559
591
|
}
|
560
592
|
}
|
561
593
|
|
@@ -569,28 +601,24 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
569
601
|
insert_id_field uuid
|
570
602
|
schema [{"name": "uuid", "type": "STRING"}]
|
571
603
|
CONFIG
|
572
|
-
driver.instance.
|
573
|
-
buf = driver.instance.format_stream("my.tag", [input])
|
574
|
-
driver.instance.shutdown
|
604
|
+
mock(driver.instance).insert("yourproject_id", "yourdataset_id", "foo", [expected], instance_of(Fluent::BigQuery::RecordSchema), nil)
|
575
605
|
|
576
|
-
|
606
|
+
driver.run do
|
607
|
+
driver.feed('tag', now, input)
|
608
|
+
end
|
577
609
|
end
|
578
610
|
|
579
|
-
def
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
"uuid" => "809F6BA7-1C16-44CD-9816-4B20E2C7AA2A",
|
586
|
-
},
|
587
|
-
}
|
588
|
-
]
|
611
|
+
def test__write_with_nested_insert_id
|
612
|
+
input = {
|
613
|
+
"data" => {
|
614
|
+
"uuid" => "809F6BA7-1C16-44CD-9816-4B20E2C7AA2A",
|
615
|
+
},
|
616
|
+
}
|
589
617
|
expected = {
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
618
|
+
insert_id: "809F6BA7-1C16-44CD-9816-4B20E2C7AA2A",
|
619
|
+
json: {
|
620
|
+
data: {
|
621
|
+
uuid: "809F6BA7-1C16-44CD-9816-4B20E2C7AA2A",
|
594
622
|
}
|
595
623
|
}
|
596
624
|
}
|
@@ -607,63 +635,28 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
607
635
|
{"name": "uuid", "type": "STRING"}
|
608
636
|
]}]
|
609
637
|
CONFIG
|
610
|
-
driver.instance.start
|
611
|
-
buf = driver.instance.format_stream("my.tag", [input])
|
612
|
-
driver.instance.shutdown
|
613
|
-
|
614
|
-
assert_equal expected, MessagePack.unpack(buf)
|
615
|
-
end
|
616
|
-
|
617
|
-
def test_format_for_load
|
618
|
-
now = Time.now
|
619
|
-
input = [
|
620
|
-
now,
|
621
|
-
{
|
622
|
-
"uuid" => "9ABFF756-0267-4247-847F-0895B65F0938",
|
623
|
-
}
|
624
|
-
]
|
625
|
-
expected = MultiJson.dump({
|
626
|
-
"uuid" => "9ABFF756-0267-4247-847F-0895B65F0938",
|
627
|
-
}) + "\n"
|
628
638
|
|
629
|
-
driver
|
630
|
-
method load
|
631
|
-
table foo
|
632
|
-
email foo@bar.example
|
633
|
-
private_key_path /path/to/key
|
634
|
-
project yourproject_id
|
635
|
-
dataset yourdataset_id
|
636
|
-
|
637
|
-
schema [{"name": "uuid", "type": "STRING"}]
|
638
|
-
|
639
|
-
buffer_type memory
|
640
|
-
CONFIG
|
641
|
-
driver.instance.start
|
642
|
-
buf = driver.instance.format_stream("my.tag", [input])
|
643
|
-
driver.instance.shutdown
|
639
|
+
mock(driver.instance).insert("yourproject_id", "yourdataset_id", "foo", [expected], instance_of(Fluent::BigQuery::RecordSchema), nil)
|
644
640
|
|
645
|
-
|
641
|
+
driver.run do
|
642
|
+
driver.feed('tag', Fluent::EventTime.now, input)
|
643
|
+
end
|
646
644
|
end
|
647
645
|
|
648
646
|
def test_replace_record_key
|
649
|
-
now =
|
650
|
-
input =
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
"login-session" => false
|
657
|
-
}
|
658
|
-
]
|
647
|
+
now = Fluent::EventTime.now
|
648
|
+
input = {
|
649
|
+
"vhost" => :bar,
|
650
|
+
"@referer" => "http://referer.example",
|
651
|
+
"bot_access" => true,
|
652
|
+
"login-session" => false
|
653
|
+
}
|
659
654
|
expected = {
|
660
|
-
"
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
"login_session" => false
|
666
|
-
}
|
655
|
+
"time" => now.to_i,
|
656
|
+
"vhost" => "bar",
|
657
|
+
"referer" => "http://referer.example",
|
658
|
+
"bot_access" => true,
|
659
|
+
"login_session" => false
|
667
660
|
}
|
668
661
|
|
669
662
|
driver = create_driver(<<-CONFIG)
|
@@ -676,8 +669,10 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
676
669
|
replace_record_key true
|
677
670
|
replace_record_key_regexp1 - _
|
678
671
|
|
672
|
+
<inject>
|
679
673
|
time_format %s
|
680
|
-
|
674
|
+
time_key time
|
675
|
+
</inject>
|
681
676
|
|
682
677
|
schema [
|
683
678
|
{"name": "time", "type": "INTEGER"},
|
@@ -687,39 +682,34 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
687
682
|
{"name": "login_session", "type": "BOOLEAN"}
|
688
683
|
]
|
689
684
|
CONFIG
|
690
|
-
driver.instance.start
|
691
|
-
buf = driver.instance.format_stream("my.tag", [input])
|
692
|
-
driver.instance.shutdown
|
693
685
|
|
694
|
-
|
686
|
+
buf = nil
|
687
|
+
driver.run { buf = driver.instance.format("my.tag", now, input) }
|
688
|
+
|
689
|
+
assert_equal expected, MultiJson.load(buf)
|
695
690
|
end
|
696
691
|
|
697
692
|
def test_convert_hash_to_json
|
698
|
-
now =
|
699
|
-
input =
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
"
|
706
|
-
"
|
707
|
-
|
708
|
-
|
709
|
-
"port" => 12345,
|
710
|
-
"user" => "tagomoris",
|
711
|
-
}
|
693
|
+
now = Fluent::EventTime.now
|
694
|
+
input = {
|
695
|
+
"vhost" => :bar,
|
696
|
+
"referer" => "http://referer.example",
|
697
|
+
"bot_access" => true,
|
698
|
+
"loginsession" => false,
|
699
|
+
"remote" => {
|
700
|
+
"host" => "remote.example",
|
701
|
+
"ip" => "192.0.2.1",
|
702
|
+
"port" => 12345,
|
703
|
+
"user" => "tagomoris",
|
712
704
|
}
|
713
|
-
|
705
|
+
}
|
714
706
|
expected = {
|
715
|
-
"
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
"remote" => "{\"host\":\"remote.example\",\"ip\":\"192.0.2.1\",\"port\":12345,\"user\":\"tagomoris\"}"
|
722
|
-
}
|
707
|
+
"time" => now.to_i,
|
708
|
+
"vhost" => "bar",
|
709
|
+
"referer" => "http://referer.example",
|
710
|
+
"bot_access" => true,
|
711
|
+
"loginsession" => false,
|
712
|
+
"remote" => "{\"host\":\"remote.example\",\"ip\":\"192.0.2.1\",\"port\":12345,\"user\":\"tagomoris\"}"
|
723
713
|
}
|
724
714
|
|
725
715
|
driver = create_driver(<<-CONFIG)
|
@@ -731,8 +721,10 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
731
721
|
|
732
722
|
convert_hash_to_json true
|
733
723
|
|
724
|
+
<inject>
|
734
725
|
time_format %s
|
735
|
-
|
726
|
+
time_key time
|
727
|
+
</inject>
|
736
728
|
|
737
729
|
schema [
|
738
730
|
{"name": "time", "type": "INTEGER"},
|
@@ -742,21 +734,21 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
742
734
|
{"name": "loginsession", "type": "BOOLEAN"}
|
743
735
|
]
|
744
736
|
CONFIG
|
745
|
-
driver.instance.start
|
746
|
-
buf = driver.instance.format_stream("my.tag", [input])
|
747
|
-
driver.instance.shutdown
|
748
737
|
|
749
|
-
|
738
|
+
buf = nil
|
739
|
+
driver.run { buf = driver.instance.format("my.tag", now, input) }
|
740
|
+
|
741
|
+
assert_equal expected, MultiJson.load(buf)
|
750
742
|
end
|
751
743
|
|
752
744
|
def test_write
|
753
|
-
entry = {
|
745
|
+
entry = {a: "b"}
|
754
746
|
driver = create_driver
|
755
747
|
|
756
748
|
writer = stub_writer(driver)
|
757
|
-
mock.proxy(writer).insert_rows('yourproject_id', 'yourdataset_id', 'foo', entry, template_suffix: nil)
|
749
|
+
mock.proxy(writer).insert_rows('yourproject_id', 'yourdataset_id', 'foo', [{json: hash_including(entry)}], template_suffix: nil)
|
758
750
|
mock(writer.client).insert_all_table_data('yourproject_id', 'yourdataset_id', 'foo', {
|
759
|
-
rows: entry,
|
751
|
+
rows: [{json: hash_including(entry)}],
|
760
752
|
skip_invalid_rows: false,
|
761
753
|
ignore_unknown_values: false
|
762
754
|
}, {options: {timeout_sec: nil, open_timeout_sec: 60}}) do
|
@@ -765,18 +757,12 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
765
757
|
s
|
766
758
|
end
|
767
759
|
|
768
|
-
|
769
|
-
|
770
|
-
chunk << e.to_msgpack
|
760
|
+
driver.run do
|
761
|
+
driver.feed("tag", Time.now.to_i, {"a" => "b"})
|
771
762
|
end
|
772
|
-
|
773
|
-
driver.instance.start
|
774
|
-
driver.instance.write(chunk)
|
775
|
-
driver.instance.shutdown
|
776
763
|
end
|
777
764
|
|
778
765
|
def test_write_with_retryable_error
|
779
|
-
entry = {json: {a: "b"}}, {json: {b: "c"}}
|
780
766
|
data_input = [
|
781
767
|
{ "status_code" => 500 },
|
782
768
|
{ "status_code" => 502 },
|
@@ -792,60 +778,57 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
792
778
|
project yourproject_id
|
793
779
|
dataset yourdataset_id
|
794
780
|
|
781
|
+
<inject>
|
795
782
|
time_format %s
|
796
|
-
|
783
|
+
time_key time
|
784
|
+
</inject>
|
797
785
|
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
writer = stub_writer(driver)
|
825
|
-
mock(writer.client).insert_all_table_data('yourproject_id', 'yourdataset_id', 'foo', {
|
826
|
-
rows: entry,
|
827
|
-
skip_invalid_rows: false,
|
828
|
-
ignore_unknown_values: false
|
829
|
-
}, {options: {timeout_sec: nil, open_timeout_sec: 60}}) do
|
830
|
-
ex = Google::Apis::ServerError.new("error", status_code: d["status_code"])
|
831
|
-
raise ex
|
832
|
-
end
|
786
|
+
schema [
|
787
|
+
{"name": "time", "type": "INTEGER"},
|
788
|
+
{"name": "status", "type": "INTEGER"},
|
789
|
+
{"name": "bytes", "type": "INTEGER"},
|
790
|
+
{"name": "vhost", "type": "STRING"},
|
791
|
+
{"name": "path", "type": "STRING"},
|
792
|
+
{"name": "method", "type": "STRING"},
|
793
|
+
{"name": "protocol", "type": "STRING"},
|
794
|
+
{"name": "agent", "type": "STRING"},
|
795
|
+
{"name": "referer", "type": "STRING"},
|
796
|
+
{"name": "remote", "type": "RECORD", "fields": [
|
797
|
+
{"name": "host", "type": "STRING"},
|
798
|
+
{"name": "ip", "type": "STRING"},
|
799
|
+
{"name": "user", "type": "STRING"}
|
800
|
+
]},
|
801
|
+
{"name": "requesttime", "type": "FLOAT"},
|
802
|
+
{"name": "bot_access", "type": "BOOLEAN"},
|
803
|
+
{"name": "loginsession", "type": "BOOLEAN"}
|
804
|
+
]
|
805
|
+
<secondary>
|
806
|
+
type file
|
807
|
+
path error
|
808
|
+
utc
|
809
|
+
</secondary>
|
810
|
+
CONFIG
|
833
811
|
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
812
|
+
entry = {a: "b"}
|
813
|
+
writer = stub_writer(driver)
|
814
|
+
mock(writer.client).insert_all_table_data('yourproject_id', 'yourdataset_id', 'foo', {
|
815
|
+
rows: [{json: hash_including(entry)}],
|
816
|
+
skip_invalid_rows: false,
|
817
|
+
ignore_unknown_values: false
|
818
|
+
}, {options: {timeout_sec: nil, open_timeout_sec: 60}}) do
|
819
|
+
ex = Google::Apis::ServerError.new("error", status_code: d["status_code"])
|
820
|
+
raise ex
|
821
|
+
end
|
838
822
|
|
839
|
-
|
840
|
-
|
841
|
-
driver.
|
823
|
+
assert_raise(Fluent::BigQuery::RetryableError) do
|
824
|
+
driver.run do
|
825
|
+
driver.feed("tag", Time.now.to_i, {"a" => "b"})
|
842
826
|
end
|
843
|
-
driver.instance.shutdown
|
844
827
|
end
|
828
|
+
end
|
845
829
|
end
|
846
830
|
|
847
831
|
def test_write_with_not_retryable_error
|
848
|
-
entry = {json: {a: "b"}}, {json: {b: "c"}}
|
849
832
|
driver = create_driver(<<-CONFIG)
|
850
833
|
table foo
|
851
834
|
email foo@bar.example
|
@@ -853,8 +836,10 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
853
836
|
project yourproject_id
|
854
837
|
dataset yourdataset_id
|
855
838
|
|
839
|
+
<inject>
|
856
840
|
time_format %s
|
857
|
-
|
841
|
+
time_key time
|
842
|
+
</inject>
|
858
843
|
|
859
844
|
schema [
|
860
845
|
{"name": "time", "type": "INTEGER"},
|
@@ -882,9 +867,10 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
882
867
|
</secondary>
|
883
868
|
CONFIG
|
884
869
|
|
870
|
+
entry = {a: "b"}
|
885
871
|
writer = stub_writer(driver)
|
886
872
|
mock(writer.client).insert_all_table_data('yourproject_id', 'yourdataset_id', 'foo', {
|
887
|
-
rows: entry,
|
873
|
+
rows: [{json: hash_including(entry)}],
|
888
874
|
skip_invalid_rows: false,
|
889
875
|
ignore_unknown_values: false
|
890
876
|
}, {options: {timeout_sec: nil, open_timeout_sec: 60}}) do
|
@@ -895,158 +881,21 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
895
881
|
raise ex
|
896
882
|
end
|
897
883
|
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
884
|
+
driver.instance_start
|
885
|
+
tag, time, record = "tag", Time.now.to_i, {"a" => "b"}
|
886
|
+
metadata = driver.instance.metadata_for_test(tag, time, record)
|
887
|
+
chunk = driver.instance.buffer.generate_chunk(metadata).tap do |c|
|
888
|
+
c.append([driver.instance.format(tag, time, record)])
|
903
889
|
end
|
904
|
-
|
905
|
-
driver.instance.start
|
906
|
-
driver.instance.write(chunk)
|
907
|
-
driver.instance.shutdown
|
908
|
-
end
|
909
|
-
|
910
|
-
def test_write_with_retryable_insert_errors
|
911
|
-
data_input = [
|
912
|
-
{ "error_count" => 1, "insert_error_count" => 1 },
|
913
|
-
{ "error_count" => 10, "insert_error_count" => 1 },
|
914
|
-
{ "error_count" => 10, "insert_error_count" => 10 },
|
915
|
-
]
|
916
|
-
|
917
|
-
data_input.each do |d|
|
918
|
-
entry = {json: {a: "b"}}, {json: {b: "c"}}
|
919
|
-
allow_retry_insert_errors = true
|
920
|
-
driver = create_driver(<<-CONFIG)
|
921
|
-
table foo
|
922
|
-
email foo@bar.example
|
923
|
-
private_key_path /path/to/key
|
924
|
-
project yourproject_id
|
925
|
-
dataset yourdataset_id
|
926
|
-
|
927
|
-
allow_retry_insert_errors #{allow_retry_insert_errors}
|
928
|
-
|
929
|
-
time_format %s
|
930
|
-
time_field time
|
931
|
-
|
932
|
-
schema [
|
933
|
-
{"name": "time", "type": "INTEGER"},
|
934
|
-
{"name": "status", "type": "INTEGER"},
|
935
|
-
{"name": "bytes", "type": "INTEGER"},
|
936
|
-
{"name": "vhost", "type": "STRING"},
|
937
|
-
{"name": "path", "type": "STRING"},
|
938
|
-
{"name": "method", "type": "STRING"},
|
939
|
-
{"name": "protocol", "type": "STRING"},
|
940
|
-
{"name": "agent", "type": "STRING"},
|
941
|
-
{"name": "referer", "type": "STRING"},
|
942
|
-
{"name": "remote", "type": "RECORD", "fields": [
|
943
|
-
{"name": "host", "type": "STRING"},
|
944
|
-
{"name": "ip", "type": "STRING"},
|
945
|
-
{"name": "user", "type": "STRING"}
|
946
|
-
]},
|
947
|
-
{"name": "requesttime", "type": "FLOAT"},
|
948
|
-
{"name": "bot_access", "type": "BOOLEAN"},
|
949
|
-
{"name": "loginsession", "type": "BOOLEAN"}
|
950
|
-
]
|
951
|
-
<secondary>
|
952
|
-
type file
|
953
|
-
path error
|
954
|
-
utc
|
955
|
-
</secondary>
|
956
|
-
CONFIG
|
957
|
-
|
958
|
-
writer = stub_writer(driver)
|
959
|
-
mock(writer.client).insert_all_table_data('yourproject_id', 'yourdataset_id', 'foo', {
|
960
|
-
rows: entry,
|
961
|
-
skip_invalid_rows: false,
|
962
|
-
ignore_unknown_values: false
|
963
|
-
}, {options: {timeout_sec: nil, open_timeout_sec: 60}}) do
|
964
|
-
s = failure_insert_errors("timeout", d["error_count"], d["insert_error_count"])
|
965
|
-
s
|
966
|
-
end
|
967
|
-
|
968
|
-
chunk = Fluent::MemoryBufferChunk.new("my.tag")
|
969
|
-
entry.each do |e|
|
970
|
-
chunk << e.to_msgpack
|
971
|
-
end
|
972
|
-
|
973
|
-
driver.instance.start
|
974
|
-
assert_raise Fluent::BigQuery::RetryableError do
|
975
|
-
driver.instance.write(chunk)
|
976
|
-
end
|
977
|
-
driver.instance.shutdown
|
978
|
-
end
|
979
|
-
end
|
980
|
-
|
981
|
-
def test_write_with_not_retryable_insert_errors
|
982
|
-
data_input = [
|
983
|
-
{ "allow_retry_insert_errors" => false, "reason" => "timeout" },
|
984
|
-
{ "allow_retry_insert_errors" => true, "reason" => "stopped" },
|
985
|
-
]
|
986
|
-
data_input.each do |d|
|
987
|
-
entry = {json: {a: "b"}}, {json: {b: "c"}}
|
988
|
-
driver = create_driver(<<-CONFIG)
|
989
|
-
table foo
|
990
|
-
email foo@bar.example
|
991
|
-
private_key_path /path/to/key
|
992
|
-
project yourproject_id
|
993
|
-
dataset yourdataset_id
|
994
|
-
|
995
|
-
allow_retry_insert_errors #{d["allow_retry_insert_errors"]}
|
996
|
-
|
997
|
-
time_format %s
|
998
|
-
time_field time
|
999
|
-
|
1000
|
-
schema [
|
1001
|
-
{"name": "time", "type": "INTEGER"},
|
1002
|
-
{"name": "status", "type": "INTEGER"},
|
1003
|
-
{"name": "bytes", "type": "INTEGER"},
|
1004
|
-
{"name": "vhost", "type": "STRING"},
|
1005
|
-
{"name": "path", "type": "STRING"},
|
1006
|
-
{"name": "method", "type": "STRING"},
|
1007
|
-
{"name": "protocol", "type": "STRING"},
|
1008
|
-
{"name": "agent", "type": "STRING"},
|
1009
|
-
{"name": "referer", "type": "STRING"},
|
1010
|
-
{"name": "remote", "type": "RECORD", "fields": [
|
1011
|
-
{"name": "host", "type": "STRING"},
|
1012
|
-
{"name": "ip", "type": "STRING"},
|
1013
|
-
{"name": "user", "type": "STRING"}
|
1014
|
-
]},
|
1015
|
-
{"name": "requesttime", "type": "FLOAT"},
|
1016
|
-
{"name": "bot_access", "type": "BOOLEAN"},
|
1017
|
-
{"name": "loginsession", "type": "BOOLEAN"}
|
1018
|
-
]
|
1019
|
-
<secondary>
|
1020
|
-
type file
|
1021
|
-
path error
|
1022
|
-
utc
|
1023
|
-
</secondary>
|
1024
|
-
CONFIG
|
1025
|
-
|
1026
|
-
writer = stub_writer(driver)
|
1027
|
-
mock(writer.client).insert_all_table_data('yourproject_id', 'yourdataset_id', 'foo', {
|
1028
|
-
rows: entry,
|
1029
|
-
skip_invalid_rows: false,
|
1030
|
-
ignore_unknown_values: false
|
1031
|
-
}, {options: {timeout_sec: nil, open_timeout_sec: 60}}) do
|
1032
|
-
s = failure_insert_errors(d["reason"], 1, 1)
|
1033
|
-
s
|
1034
|
-
end
|
1035
|
-
|
1036
|
-
chunk = Fluent::MemoryBufferChunk.new("my.tag")
|
1037
|
-
entry.each do |e|
|
1038
|
-
chunk << e.to_msgpack
|
1039
|
-
end
|
1040
|
-
|
1041
|
-
driver.instance.start
|
890
|
+
assert_raise Fluent::BigQuery::UnRetryableError do
|
1042
891
|
driver.instance.write(chunk)
|
1043
|
-
driver.instance.shutdown
|
1044
892
|
end
|
893
|
+
assert_in_delta driver.instance.retry.secondary_transition_at , Time.now, 0.1
|
894
|
+
driver.instance_shutdown
|
1045
895
|
end
|
1046
896
|
|
1047
897
|
def test_write_for_load
|
1048
898
|
schema_path = File.join(File.dirname(__FILE__), "testdata", "sudo.schema")
|
1049
|
-
entry = {a: "b"}, {b: "c"}
|
1050
899
|
driver = create_driver(<<-CONFIG)
|
1051
900
|
method load
|
1052
901
|
table foo
|
@@ -1055,8 +904,10 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1055
904
|
project yourproject_id
|
1056
905
|
dataset yourdataset_id
|
1057
906
|
|
907
|
+
<inject>
|
1058
908
|
time_format %s
|
1059
|
-
|
909
|
+
time_key time
|
910
|
+
</inject>
|
1060
911
|
|
1061
912
|
schema_path #{schema_path}
|
1062
913
|
|
@@ -1065,9 +916,8 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1065
916
|
schema_fields = MultiJson.load(File.read(schema_path)).map(&:deep_symbolize_keys)
|
1066
917
|
|
1067
918
|
writer = stub_writer(driver)
|
1068
|
-
chunk = Fluent::MemoryBufferChunk.new("my.tag")
|
1069
919
|
io = StringIO.new("hello")
|
1070
|
-
mock(driver.instance).create_upload_source(
|
920
|
+
mock(driver.instance).create_upload_source(is_a(Fluent::Plugin::Buffer::Chunk)).yields(io)
|
1071
921
|
mock(writer).wait_load_job(is_a(String), "yourproject_id", "yourdataset_id", "dummy_job_id", "foo") { nil }
|
1072
922
|
mock(writer.client).insert_job('yourproject_id', {
|
1073
923
|
configuration: {
|
@@ -1094,18 +944,13 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1094
944
|
s
|
1095
945
|
end
|
1096
946
|
|
1097
|
-
|
1098
|
-
|
947
|
+
driver.run do
|
948
|
+
driver.feed("tag", Time.now.to_i, {"a" => "b"})
|
1099
949
|
end
|
1100
|
-
|
1101
|
-
driver.instance.start
|
1102
|
-
driver.instance.write(chunk)
|
1103
|
-
driver.instance.shutdown
|
1104
950
|
end
|
1105
951
|
|
1106
952
|
def test_write_for_load_with_prevent_duplicate_load
|
1107
953
|
schema_path = File.join(File.dirname(__FILE__), "testdata", "sudo.schema")
|
1108
|
-
entry = {a: "b"}, {b: "c"}
|
1109
954
|
driver = create_driver(<<-CONFIG)
|
1110
955
|
method load
|
1111
956
|
table foo
|
@@ -1114,8 +959,10 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1114
959
|
project yourproject_id
|
1115
960
|
dataset yourdataset_id
|
1116
961
|
|
962
|
+
<inject>
|
1117
963
|
time_format %s
|
1118
|
-
|
964
|
+
time_key time
|
965
|
+
</inject>
|
1119
966
|
|
1120
967
|
schema_path #{schema_path}
|
1121
968
|
prevent_duplicate_load true
|
@@ -1124,9 +971,8 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1124
971
|
CONFIG
|
1125
972
|
schema_fields = MultiJson.load(File.read(schema_path)).map(&:deep_symbolize_keys)
|
1126
973
|
|
1127
|
-
chunk = Fluent::MemoryBufferChunk.new("my.tag")
|
1128
974
|
io = StringIO.new("hello")
|
1129
|
-
mock(driver.instance).create_upload_source(
|
975
|
+
mock(driver.instance).create_upload_source(is_a(Fluent::Plugin::Buffer::Chunk)).yields(io)
|
1130
976
|
writer = stub_writer(driver)
|
1131
977
|
mock(writer).wait_load_job(is_a(String), "yourproject_id", "yourdataset_id", "dummy_job_id", "foo") { nil }
|
1132
978
|
mock(writer.client).insert_job('yourproject_id', {
|
@@ -1155,18 +1001,13 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1155
1001
|
s
|
1156
1002
|
end
|
1157
1003
|
|
1158
|
-
|
1159
|
-
|
1004
|
+
driver.run do
|
1005
|
+
driver.feed("tag", Time.now.to_i, {"a" => "b"})
|
1160
1006
|
end
|
1161
|
-
|
1162
|
-
driver.instance.start
|
1163
|
-
driver.instance.write(chunk)
|
1164
|
-
driver.instance.shutdown
|
1165
1007
|
end
|
1166
1008
|
|
1167
1009
|
def test_write_for_load_with_retryable_error
|
1168
1010
|
schema_path = File.join(File.dirname(__FILE__), "testdata", "sudo.schema")
|
1169
|
-
entry = {a: "b"}, {b: "c"}
|
1170
1011
|
driver = create_driver(<<-CONFIG)
|
1171
1012
|
method load
|
1172
1013
|
table foo
|
@@ -1175,8 +1016,10 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1175
1016
|
project yourproject_id
|
1176
1017
|
dataset yourdataset_id
|
1177
1018
|
|
1019
|
+
<inject>
|
1178
1020
|
time_format %s
|
1179
|
-
|
1021
|
+
time_key time
|
1022
|
+
</inject>
|
1180
1023
|
|
1181
1024
|
schema_path #{schema_path}
|
1182
1025
|
|
@@ -1184,7 +1027,13 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1184
1027
|
CONFIG
|
1185
1028
|
schema_fields = MultiJson.load(File.read(schema_path)).map(&:deep_symbolize_keys)
|
1186
1029
|
|
1187
|
-
|
1030
|
+
driver.instance_start
|
1031
|
+
tag, time, record = "tag", Time.now.to_i, {"a" => "b"}
|
1032
|
+
metadata = driver.instance.metadata_for_test(tag, time, record)
|
1033
|
+
chunk = driver.instance.buffer.generate_chunk(metadata).tap do |c|
|
1034
|
+
c.append([driver.instance.format(tag, time, record)])
|
1035
|
+
end
|
1036
|
+
|
1188
1037
|
io = StringIO.new("hello")
|
1189
1038
|
mock(driver.instance).create_upload_source(chunk).yields(io)
|
1190
1039
|
writer = stub_writer(driver)
|
@@ -1227,20 +1076,14 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1227
1076
|
s
|
1228
1077
|
end
|
1229
1078
|
|
1230
|
-
entry.each do |e|
|
1231
|
-
chunk << MultiJson.dump(e) + "\n"
|
1232
|
-
end
|
1233
|
-
|
1234
|
-
driver.instance.start
|
1235
1079
|
assert_raise Fluent::BigQuery::RetryableError do
|
1236
1080
|
driver.instance.write(chunk)
|
1237
1081
|
end
|
1238
|
-
driver.
|
1082
|
+
driver.instance_shutdown
|
1239
1083
|
end
|
1240
1084
|
|
1241
1085
|
def test_write_for_load_with_not_retryable_error
|
1242
1086
|
schema_path = File.join(File.dirname(__FILE__), "testdata", "sudo.schema")
|
1243
|
-
entry = {a: "b"}, {b: "c"}
|
1244
1087
|
driver = create_driver(<<-CONFIG)
|
1245
1088
|
method load
|
1246
1089
|
table foo
|
@@ -1249,8 +1092,10 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1249
1092
|
project yourproject_id
|
1250
1093
|
dataset yourdataset_id
|
1251
1094
|
|
1095
|
+
<inject>
|
1252
1096
|
time_format %s
|
1253
|
-
|
1097
|
+
time_key time
|
1098
|
+
</inject>
|
1254
1099
|
|
1255
1100
|
schema_path #{schema_path}
|
1256
1101
|
|
@@ -1263,7 +1108,13 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1263
1108
|
CONFIG
|
1264
1109
|
schema_fields = MultiJson.load(File.read(schema_path)).map(&:deep_symbolize_keys)
|
1265
1110
|
|
1266
|
-
|
1111
|
+
driver.instance_start
|
1112
|
+
tag, time, record = "tag", Time.now.to_i, {"a" => "b"}
|
1113
|
+
metadata = driver.instance.metadata_for_test(tag, time, record)
|
1114
|
+
chunk = driver.instance.buffer.generate_chunk(metadata).tap do |c|
|
1115
|
+
c.append([driver.instance.format(tag, time, record)])
|
1116
|
+
end
|
1117
|
+
|
1267
1118
|
io = StringIO.new("hello")
|
1268
1119
|
mock(driver.instance).create_upload_source(chunk).yields(io)
|
1269
1120
|
writer = stub_writer(driver)
|
@@ -1306,36 +1157,29 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1306
1157
|
s
|
1307
1158
|
end
|
1308
1159
|
|
1309
|
-
|
1310
|
-
|
1311
|
-
entry.each do |e|
|
1312
|
-
chunk << MultiJson.dump(e) + "\n"
|
1160
|
+
assert_raise Fluent::BigQuery::UnRetryableError do
|
1161
|
+
driver.instance.write(chunk)
|
1313
1162
|
end
|
1314
|
-
|
1315
|
-
driver.
|
1316
|
-
driver.instance.write(chunk)
|
1317
|
-
driver.instance.shutdown
|
1163
|
+
assert_in_delta driver.instance.retry.secondary_transition_at , Time.now, 0.1
|
1164
|
+
driver.instance_shutdown
|
1318
1165
|
end
|
1319
1166
|
|
1320
1167
|
def test_write_with_row_based_table_id_formatting
|
1321
1168
|
entry = [
|
1322
|
-
{json: {a: "b", created_at: Time.local(2014,8,20,9,0,0).
|
1323
|
-
{json: {b: "c", created_at: Time.local(2014,8,21,9,0,0).to_i}}
|
1169
|
+
{json: {a: "b", created_at: Time.local(2014,8,20,9,0,0).strftime("%Y_%m_%d")}},
|
1324
1170
|
]
|
1325
1171
|
driver = create_driver(<<-CONFIG)
|
1326
|
-
|
1172
|
+
<buffer created_at>
|
1173
|
+
</buffer>
|
1174
|
+
table foo_${created_at}
|
1327
1175
|
email foo@bar.example
|
1328
1176
|
private_key_path /path/to/key
|
1329
1177
|
project yourproject_id
|
1330
1178
|
dataset yourdataset_id
|
1331
1179
|
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
field_integer time,status,bytes
|
1336
|
-
field_string vhost,path,method,protocol,agent,referer,remote.host,remote.ip,remote.user
|
1337
|
-
field_float requesttime
|
1338
|
-
field_boolean bot_access,loginsession
|
1180
|
+
schema [
|
1181
|
+
{"name": "time", "type": "INTEGER"}
|
1182
|
+
]
|
1339
1183
|
CONFIG
|
1340
1184
|
|
1341
1185
|
writer = stub_writer(driver)
|
@@ -1345,107 +1189,36 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1345
1189
|
ignore_unknown_values: false
|
1346
1190
|
}, {options: {timeout_sec: nil, open_timeout_sec: 60}}) { stub!.insert_errors { nil } }
|
1347
1191
|
|
1348
|
-
|
1349
|
-
|
1350
|
-
skip_invalid_rows: false,
|
1351
|
-
ignore_unknown_values: false
|
1352
|
-
}, {options: {timeout_sec: nil, open_timeout_sec: 60}}) { stub!.insert_errors { nil } }
|
1353
|
-
|
1354
|
-
chunk = Fluent::MemoryBufferChunk.new("my.tag")
|
1355
|
-
entry.each do |object|
|
1356
|
-
chunk << object.to_msgpack
|
1357
|
-
end
|
1358
|
-
|
1359
|
-
driver.instance.start
|
1360
|
-
driver.instance.write(chunk)
|
1361
|
-
driver.instance.shutdown
|
1362
|
-
end
|
1363
|
-
|
1364
|
-
def test_generate_table_id_without_row
|
1365
|
-
driver = create_driver
|
1366
|
-
table_id_format = 'foo_%Y_%m_%d'
|
1367
|
-
time = Time.local(2014, 8, 11, 21, 20, 56)
|
1368
|
-
table_id = driver.instance.generate_table_id(table_id_format, time, nil)
|
1369
|
-
assert_equal 'foo_2014_08_11', table_id
|
1370
|
-
end
|
1371
|
-
|
1372
|
-
def test_generate_table_id_with_row
|
1373
|
-
driver = create_driver
|
1374
|
-
table_id_format = 'foo_%Y_%m_%d@created_at'
|
1375
|
-
time = Time.local(2014, 8, 11, 21, 20, 56)
|
1376
|
-
row = { json: { created_at: Time.local(2014,8,10,21,20,57).to_i } }
|
1377
|
-
table_id = driver.instance.generate_table_id(table_id_format, time, row)
|
1378
|
-
assert_equal 'foo_2014_08_10', table_id
|
1379
|
-
end
|
1380
|
-
|
1381
|
-
def test_generate_table_id_with_row_nested_attribute
|
1382
|
-
driver = create_driver
|
1383
|
-
table_id_format = 'foo_%Y_%m_%d@foo.bar.created_at'
|
1384
|
-
time = Time.local(2014, 8, 11, 21, 20, 56)
|
1385
|
-
row = { json: { foo: { bar: { created_at: Time.local(2014,8,10,21,20,57).to_i } } } }
|
1386
|
-
table_id = driver.instance.generate_table_id(table_id_format, time, row)
|
1387
|
-
assert_equal 'foo_2014_08_10', table_id
|
1388
|
-
end
|
1389
|
-
|
1390
|
-
def test_generate_table_id_with_time_sliced_format
|
1391
|
-
driver = create_driver
|
1392
|
-
table_id_format = 'foo_%{time_slice}'
|
1393
|
-
current_time = Time.now
|
1394
|
-
time = Time.local(2014, 8, 11, 21, 20, 56)
|
1395
|
-
row = { "json" => { "foo" => "bar", "time" => time.to_i } }
|
1396
|
-
chunk = Object.new
|
1397
|
-
mock(chunk).key { time.strftime("%Y%m%d") }
|
1398
|
-
table_id = driver.instance.generate_table_id(table_id_format, current_time, row, chunk)
|
1399
|
-
assert_equal 'foo_20140811', table_id
|
1400
|
-
end
|
1401
|
-
|
1402
|
-
def test_generate_table_id_with_attribute_replacement
|
1403
|
-
driver = create_driver
|
1404
|
-
table_id_format = 'foo_%Y_%m_%d_${baz}'
|
1405
|
-
current_time = Time.now
|
1406
|
-
time = Time.local(2014, 8, 11, 21, 20, 56)
|
1407
|
-
[
|
1408
|
-
[ { baz: 1234 }, 'foo_2014_08_11_1234' ],
|
1409
|
-
[ { baz: 'piyo' }, 'foo_2014_08_11_piyo' ],
|
1410
|
-
[ { baz: true }, 'foo_2014_08_11_true' ],
|
1411
|
-
[ { baz: nil }, 'foo_2014_08_11_' ],
|
1412
|
-
[ { baz: '' }, 'foo_2014_08_11_' ],
|
1413
|
-
[ { baz: "_X-Y.Z !\n" }, 'foo_2014_08_11__XYZ' ],
|
1414
|
-
[ { baz: { xyz: 1 } }, 'foo_2014_08_11_xyz1' ],
|
1415
|
-
].each do |attrs, expected|
|
1416
|
-
row = { json: { created_at: Time.local(2014,8,10,21,20,57).to_i }.merge(attrs) }
|
1417
|
-
table_id = driver.instance.generate_table_id(table_id_format, time, row)
|
1418
|
-
assert_equal expected, table_id
|
1192
|
+
driver.run do
|
1193
|
+
driver.feed("tag", Time.now.to_i, {"a" => "b", "created_at" => Time.local(2014,8,20,9,0,0).strftime("%Y_%m_%d")})
|
1419
1194
|
end
|
1420
1195
|
end
|
1421
1196
|
|
1422
1197
|
def test_auto_create_table_by_bigquery_api
|
1423
|
-
now = Time.now
|
1198
|
+
now = Time.at(Time.now.to_i)
|
1424
1199
|
message = {
|
1425
|
-
"
|
1426
|
-
|
1427
|
-
"
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
"
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
"
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
}
|
1448
|
-
}.deep_symbolize_keys
|
1200
|
+
"time" => now.to_i,
|
1201
|
+
"request" => {
|
1202
|
+
"vhost" => "bar",
|
1203
|
+
"path" => "/path/to/baz",
|
1204
|
+
"method" => "GET",
|
1205
|
+
"protocol" => "HTTP/1.0",
|
1206
|
+
"agent" => "libwww",
|
1207
|
+
"referer" => "http://referer.example",
|
1208
|
+
"time" => (now - 1).to_f,
|
1209
|
+
"bot_access" => true,
|
1210
|
+
"loginsession" => false,
|
1211
|
+
},
|
1212
|
+
"remote" => {
|
1213
|
+
"host" => "remote.example",
|
1214
|
+
"ip" => "192.168.1.1",
|
1215
|
+
"user" => "nagachika",
|
1216
|
+
},
|
1217
|
+
"response" => {
|
1218
|
+
"status" => 200,
|
1219
|
+
"bytes" => 72,
|
1220
|
+
},
|
1221
|
+
}
|
1449
1222
|
|
1450
1223
|
driver = create_driver(<<-CONFIG)
|
1451
1224
|
table foo
|
@@ -1454,25 +1227,25 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1454
1227
|
project yourproject_id
|
1455
1228
|
dataset yourdataset_id
|
1456
1229
|
|
1230
|
+
<inject>
|
1457
1231
|
time_format %s
|
1458
|
-
|
1232
|
+
time_key time
|
1233
|
+
</inject>
|
1459
1234
|
|
1460
1235
|
auto_create_table true
|
1461
1236
|
schema_path #{File.join(File.dirname(__FILE__), "testdata", "apache.schema")}
|
1462
1237
|
CONFIG
|
1463
1238
|
writer = stub_writer(driver)
|
1464
|
-
mock(writer).insert_rows('yourproject_id', 'yourdataset_id', 'foo', [message], template_suffix: nil)
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
chunk << message.to_msgpack
|
1469
|
-
|
1470
|
-
driver.instance.start
|
1239
|
+
mock(writer).insert_rows('yourproject_id', 'yourdataset_id', 'foo', [{json: message.deep_symbolize_keys}], template_suffix: nil) do
|
1240
|
+
raise Fluent::BigQuery::RetryableError.new(nil, Google::Apis::ServerError.new("Not found: Table yourproject_id:yourdataset_id.foo", status_code: 404, body: "Not found: Table yourproject_id:yourdataset_id.foo"))
|
1241
|
+
end
|
1242
|
+
mock(writer).create_table('yourproject_id', 'yourdataset_id', 'foo', driver.instance.instance_variable_get(:@table_schema))
|
1471
1243
|
|
1472
|
-
assert_raise(RuntimeError)
|
1473
|
-
driver.
|
1474
|
-
|
1475
|
-
|
1244
|
+
assert_raise(RuntimeError) do
|
1245
|
+
driver.run do
|
1246
|
+
driver.feed("tag", Fluent::EventTime.from_time(now), message)
|
1247
|
+
end
|
1248
|
+
end
|
1476
1249
|
end
|
1477
1250
|
|
1478
1251
|
def test_auto_create_partitioned_table_by_bigquery_api
|
@@ -1520,18 +1293,16 @@ class BigQueryOutputTest < Test::Unit::TestCase
|
|
1520
1293
|
time_partitioning_expiration 1h
|
1521
1294
|
CONFIG
|
1522
1295
|
writer = stub_writer(driver)
|
1523
|
-
mock(writer).insert_rows('yourproject_id', 'yourdataset_id', 'foo', [message], template_suffix: nil)
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
chunk << message.to_msgpack
|
1528
|
-
|
1529
|
-
driver.instance.start
|
1296
|
+
mock(writer).insert_rows('yourproject_id', 'yourdataset_id', 'foo', [message], template_suffix: nil) do
|
1297
|
+
raise Fluent::BigQuery::RetryableError.new(nil, Google::Apis::ServerError.new("Not found: Table yourproject_id:yourdataset_id.foo", status_code: 404, body: "Not found: Table yourproject_id:yourdataset_id.foo"))
|
1298
|
+
end
|
1299
|
+
mock(writer).create_table('yourproject_id', 'yourdataset_id', 'foo', driver.instance.instance_variable_get(:@table_schema))
|
1530
1300
|
|
1531
|
-
assert_raise(RuntimeError)
|
1532
|
-
driver.
|
1533
|
-
|
1534
|
-
|
1301
|
+
assert_raise(RuntimeError) do
|
1302
|
+
driver.run do
|
1303
|
+
driver.feed("tag", Fluent::EventTime.now, message[:json])
|
1304
|
+
end
|
1305
|
+
end
|
1535
1306
|
end
|
1536
1307
|
|
1537
1308
|
private
|