5
5
require 'time'
6
6
require 'timecop'
7
7
require 'zlib'
8
+ require 'zstd-ruby'
8
9
require 'fluent/file_wrapper'
9
10
10
11
class FileOutputTest < Test ::Unit ::TestCase
@@ -397,20 +398,32 @@ def create_driver(conf = CONFIG, opts = {})
397
398
end
398
399
end
399
400
400
- def check_gzipped_result ( path , expect )
401
+ def check_zipped_result ( path , expect , type : :gzip )
401
402
# Zlib::GzipReader has a bug of concatenated file: https://bugs.ruby-lang.org/issues/9790
402
403
# Following code from https://www.ruby-forum.com/topic/971591#979520
403
404
result = ''
404
- File . open ( path , "rb" ) { |io |
405
- loop do
406
- gzr = Zlib ::GzipReader . new ( StringIO . new ( io . read ) )
407
- result << gzr . read
408
- unused = gzr . unused
409
- gzr . finish
410
- break if unused . nil?
411
- io . pos -= unused . length
412
- end
413
- }
405
+ if type == :gzip || type == :gz
406
+ File . open ( path , "rb" ) { |io |
407
+ loop do
408
+ gzr = Zlib ::GzipReader . new ( StringIO . new ( io . read ) )
409
+ result << gzr . read
410
+ unused = gzr . unused
411
+ gzr . finish
412
+ break if unused . nil?
413
+ io . pos -= unused . length
414
+ end
415
+ }
416
+ elsif type == :zstd
417
+ File . open ( path , "rb" ) { |io |
418
+ loop do
419
+ reader = Zstd ::StreamReader . new ( StringIO . new ( io . read ) )
420
+ result << reader . read ( 1024 )
421
+ break if io . eof?
422
+ end
423
+ }
424
+ else
425
+ raise "Invalid compression type to check"
426
+ end
414
427
415
428
assert_equal expect , result
416
429
end
@@ -421,7 +434,7 @@ def check_result(path, expect)
421
434
end
422
435
423
436
sub_test_case 'write' do
424
- test 'basic case' do
437
+ test 'basic case with gz ' do
425
438
d = create_driver
426
439
427
440
assert_false File . exist? ( "#{ TMP_DIR } /out_file_test.20110102_0.log.gz" )
@@ -433,7 +446,29 @@ def check_result(path, expect)
433
446
end
434
447
435
448
assert File . exist? ( "#{ TMP_DIR } /out_file_test.20110102_0.log.gz" )
436
- check_gzipped_result ( "#{ TMP_DIR } /out_file_test.20110102_0.log.gz" , %[2011-01-02T13:14:15Z\t test\t {"a":1}#{ @default_newline } ] + %[2011-01-02T13:14:15Z\t test\t {"a":2}#{ @default_newline } ] )
449
+ check_zipped_result ( "#{ TMP_DIR } /out_file_test.20110102_0.log.gz" , %[2011-01-02T13:14:15Z\t test\t {"a":1}#{ @default_newline } ] + %[2011-01-02T13:14:15Z\t test\t {"a":2}#{ @default_newline } ] )
450
+ end
451
+
452
+ test 'write with zstd compression' do
453
+ d = create_driver %[
454
+ path #{ TMP_DIR } /out_file_test
455
+ compress zstd
456
+ utc
457
+ <buffer>
458
+ timekey_use_utc true
459
+ </buffer>
460
+ ]
461
+
462
+ assert_false File . exist? ( "#{ TMP_DIR } /out_file_test.20110102_0.log.zstd" )
463
+
464
+ time = event_time ( "2011-01-02 13:14:15 UTC" )
465
+ d . run ( default_tag : 'test' ) do
466
+ d . feed ( time , { "a" => 1 } )
467
+ d . feed ( time , { "a" => 2 } )
468
+ end
469
+
470
+ assert File . exist? ( "#{ TMP_DIR } /out_file_test.20110102_0.log.zstd" )
471
+ check_zipped_result ( "#{ TMP_DIR } /out_file_test.20110102_0.log.zstd" , %[2011-01-02T13:14:15Z\t test\t {"a":1}#{ @default_newline } ] + %[2011-01-02T13:14:15Z\t test\t {"a":2}#{ @default_newline } ] , type : :zstd )
437
472
end
438
473
end
439
474
@@ -481,7 +516,7 @@ def parse_system(text)
481
516
482
517
assert File . exist? ( "#{ TMP_DIR_WITH_SYSTEM } /out_file_test.20110102_0.log.gz" )
483
518
484
- check_gzipped_result ( "#{ TMP_DIR_WITH_SYSTEM } /out_file_test.20110102_0.log.gz" , %[2011-01-02T13:14:15Z\t test\t {"a":1}\n ] + %[2011-01-02T13:14:15Z\t test\t {"a":2}\n ] )
519
+ check_zipped_result ( "#{ TMP_DIR_WITH_SYSTEM } /out_file_test.20110102_0.log.gz" , %[2011-01-02T13:14:15Z\t test\t {"a":1}\n ] + %[2011-01-02T13:14:15Z\t test\t {"a":2}\n ] )
485
520
dir_mode = "%o" % File ::stat ( TMP_DIR_WITH_SYSTEM ) . mode
486
521
assert_equal ( OVERRIDE_DIR_PERMISSION , dir_mode [ -3 , 3 ] . to_i )
487
522
file_mode = "%o" % File ::stat ( "#{ TMP_DIR_WITH_SYSTEM } /out_file_test.20110102_0.log.gz" ) . mode
@@ -500,7 +535,7 @@ def parse_system(text)
500
535
end
501
536
502
537
path = d . instance . last_written_path
503
- check_gzipped_result ( path , %[#{ Yajl . dump ( { "a" => 1 , 'time' => time . to_i } ) } #{ @default_newline } ] + %[#{ Yajl . dump ( { "a" => 2 , 'time' => time . to_i } ) } #{ @default_newline } ] )
538
+ check_zipped_result ( path , %[#{ Yajl . dump ( { "a" => 1 , 'time' => time . to_i } ) } #{ @default_newline } ] + %[#{ Yajl . dump ( { "a" => 2 , 'time' => time . to_i } ) } #{ @default_newline } ] )
504
539
end
505
540
506
541
test 'ltsv' do
@@ -513,7 +548,7 @@ def parse_system(text)
513
548
end
514
549
515
550
path = d . instance . last_written_path
516
- check_gzipped_result ( path , %[a:1\t time:2011-01-02T13:14:15Z#{ @default_newline } ] + %[a:2\t time:2011-01-02T13:14:15Z#{ @default_newline } ] )
551
+ check_zipped_result ( path , %[a:1\t time:2011-01-02T13:14:15Z#{ @default_newline } ] + %[a:2\t time:2011-01-02T13:14:15Z#{ @default_newline } ] )
517
552
end
518
553
519
554
test 'single_value' do
@@ -526,7 +561,7 @@ def parse_system(text)
526
561
end
527
562
528
563
path = d . instance . last_written_path
529
- check_gzipped_result ( path , %[1#{ @default_newline } ] + %[2#{ @default_newline } ] )
564
+ check_zipped_result ( path , %[1#{ @default_newline } ] + %[2#{ @default_newline } ] )
530
565
end
531
566
end
532
567
@@ -547,23 +582,24 @@ def parse_system(text)
547
582
548
583
path = write_once . call
549
584
assert_equal "#{ TMP_DIR } /out_file_test.20110102_0.log.gz" , path
550
- check_gzipped_result ( path , formatted_lines )
585
+ check_zipped_result ( path , formatted_lines )
551
586
assert_equal 1 , Dir . glob ( "#{ TMP_DIR } /out_file_test.*" ) . size
552
587
553
588
path = write_once . call
554
589
assert_equal "#{ TMP_DIR } /out_file_test.20110102_1.log.gz" , path
555
- check_gzipped_result ( path , formatted_lines )
590
+ check_zipped_result ( path , formatted_lines )
556
591
assert_equal 2 , Dir . glob ( "#{ TMP_DIR } /out_file_test.*" ) . size
557
592
558
593
path = write_once . call
559
594
assert_equal "#{ TMP_DIR } /out_file_test.20110102_2.log.gz" , path
560
- check_gzipped_result ( path , formatted_lines )
595
+ check_zipped_result ( path , formatted_lines )
561
596
assert_equal 3 , Dir . glob ( "#{ TMP_DIR } /out_file_test.*" ) . size
562
597
end
563
598
564
599
data (
565
- "with compression" => true ,
566
- "without compression" => false ,
600
+ "without compression" => "text" ,
601
+ "with gzip compression" => "gz" ,
602
+ "with zstd compression" => "zstd"
567
603
)
568
604
test 'append' do |compression |
569
605
time = event_time ( "2011-01-02 13:14:15 UTC" )
@@ -578,8 +614,8 @@ def parse_system(text)
578
614
timekey_use_utc true
579
615
</buffer>
580
616
]
581
- if compression
582
- config << " compress gz "
617
+ if compression != :text
618
+ config << " compress #{ compression } "
583
619
end
584
620
d = create_driver ( config )
585
621
d . run ( default_tag : 'test' ) {
@@ -590,16 +626,16 @@ def parse_system(text)
590
626
}
591
627
592
628
log_file_name = "out_file_test.20110102.log"
593
- if compression
594
- log_file_name << ".gz "
629
+ if compression != "text"
630
+ log_file_name << ".#{ compression } "
595
631
end
596
632
597
633
1 . upto ( 3 ) do |i |
598
634
path = write_once . call
599
635
assert_equal "#{ TMP_DIR } /#{ log_file_name } " , path
600
636
expect = formatted_lines * i
601
- if compression
602
- check_gzipped_result ( path , expect )
637
+ if compression != "text"
638
+ check_zipped_result ( path , expect , type : compression . to_sym )
603
639
else
604
640
check_result ( path , expect )
605
641
end
@@ -630,15 +666,15 @@ def parse_system(text)
630
666
631
667
path = write_once . call
632
668
assert_equal "#{ TMP_DIR } /out_file_test.20110102.log.gz" , path
633
- check_gzipped_result ( path , formatted_lines )
669
+ check_zipped_result ( path , formatted_lines )
634
670
635
671
path = write_once . call
636
672
assert_equal "#{ TMP_DIR } /out_file_test.20110102.log.gz" , path
637
- check_gzipped_result ( path , formatted_lines * 2 )
673
+ check_zipped_result ( path , formatted_lines * 2 )
638
674
639
675
path = write_once . call
640
676
assert_equal "#{ TMP_DIR } /out_file_test.20110102.log.gz" , path
641
- check_gzipped_result ( path , formatted_lines * 3 )
677
+ check_zipped_result ( path , formatted_lines * 3 )
642
678
end
643
679
end
644
680
@@ -667,15 +703,15 @@ def parse_system(text)
667
703
path = write_once . call
668
704
# Rotated at 2011-01-02 17:00:00+02:00
669
705
assert_equal "#{ TMP_DIR } /out_file_test.20110103.log.gz" , path
670
- check_gzipped_result ( path , formatted_lines )
706
+ check_zipped_result ( path , formatted_lines )
671
707
672
708
path = write_once . call
673
709
assert_equal "#{ TMP_DIR } /out_file_test.20110103.log.gz" , path
674
- check_gzipped_result ( path , formatted_lines * 2 )
710
+ check_zipped_result ( path , formatted_lines * 2 )
675
711
676
712
path = write_once . call
677
713
assert_equal "#{ TMP_DIR } /out_file_test.20110103.log.gz" , path
678
- check_gzipped_result ( path , formatted_lines * 3 )
714
+ check_zipped_result ( path , formatted_lines * 3 )
679
715
end
680
716
end
681
717
@@ -871,6 +907,10 @@ def run_and_check(d, symlink_path)
871
907
test 'returns .gz for gzip' do
872
908
assert_equal '.gz' , @i . compression_suffix ( :gzip )
873
909
end
910
+
911
+ test 'returns .zstd for zstd' do
912
+ assert_equal '.zstd' , @i . compression_suffix ( :zstd )
913
+ end
874
914
end
875
915
876
916
sub_test_case '#generate_path_template' do
0 commit comments