1# coding: US-ASCII 2# frozen_string_literal: false 3require 'test/unit' 4require 'logger' 5require 'tempfile' 6require 'tmpdir' 7 8class TestLogDevice < Test::Unit::TestCase 9 class LogExcnRaiser 10 def write(*arg) 11 raise 'disk is full' 12 end 13 14 def close 15 end 16 17 def stat 18 Object.new 19 end 20 end 21 22 def setup 23 @tempfile = Tempfile.new("logger") 24 @tempfile.close 25 @filename = @tempfile.path 26 File.unlink(@filename) 27 end 28 29 def teardown 30 @tempfile.close(true) 31 end 32 33 def d(log, opt = {}) 34 Logger::LogDevice.new(log, opt) 35 end 36 37 def test_initialize 38 logdev = d(STDERR) 39 assert_equal(STDERR, logdev.dev) 40 assert_nil(logdev.filename) 41 assert_raise(TypeError) do 42 d(nil) 43 end 44 # 45 logdev = d(@filename) 46 begin 47 assert_file.exist?(@filename) 48 assert_predicate(logdev.dev, :sync) 49 assert_equal(@filename, logdev.filename) 50 logdev.write('hello') 51 ensure 52 logdev.close 53 end 54 # create logfile whitch is already exist. 55 logdev = d(@filename) 56 begin 57 logdev.write('world') 58 logfile = File.read(@filename) 59 assert_equal(2, logfile.split(/\n/).size) 60 assert_match(/^helloworld$/, logfile) 61 ensure 62 logdev.close 63 end 64 end 65 66 def test_write 67 r, w = IO.pipe 68 logdev = d(w) 69 logdev.write("msg2\n\n") 70 IO.select([r], nil, nil, 0.1) 71 w.close 72 msg = r.read 73 r.close 74 assert_equal("msg2\n\n", msg) 75 # 76 logdev = d(LogExcnRaiser.new) 77 class << (stderr = '') 78 alias write concat 79 end 80 $stderr, stderr = stderr, $stderr 81 begin 82 assert_nothing_raised do 83 logdev.write('hello') 84 end 85 ensure 86 logdev.close 87 $stderr, stderr = stderr, $stderr 88 end 89 assert_equal "log writing failed. disk is full\n", stderr 90 end 91 92 def test_close 93 r, w = IO.pipe 94 logdev = d(w) 95 logdev.write("msg2\n\n") 96 IO.select([r], nil, nil, 0.1) 97 assert_not_predicate(w, :closed?) 98 logdev.close 99 assert_predicate(w, :closed?) 100 r.close 101 end 102 103 def test_reopen_io 104 logdev = d(STDERR) 105 old_dev = logdev.dev 106 logdev.reopen 107 assert_equal(STDERR, logdev.dev) 108 assert_not_predicate(old_dev, :closed?) 109 end 110 111 def test_reopen_io_by_io 112 logdev = d(STDERR) 113 old_dev = logdev.dev 114 logdev.reopen(STDOUT) 115 assert_equal(STDOUT, logdev.dev) 116 assert_not_predicate(old_dev, :closed?) 117 end 118 119 def test_reopen_io_by_file 120 logdev = d(STDERR) 121 old_dev = logdev.dev 122 logdev.reopen(@filename) 123 begin 124 assert_file.exist?(@filename) 125 assert_equal(@filename, logdev.filename) 126 assert_not_predicate(old_dev, :closed?) 127 ensure 128 logdev.close 129 end 130 end 131 132 def test_reopen_file 133 logdev = d(@filename) 134 old_dev = logdev.dev 135 136 logdev.reopen 137 begin 138 assert_file.exist?(@filename) 139 assert_equal(@filename, logdev.filename) 140 assert_predicate(old_dev, :closed?) 141 ensure 142 logdev.close 143 end 144 end 145 146 def test_reopen_file_by_io 147 logdev = d(@filename) 148 old_dev = logdev.dev 149 logdev.reopen(STDOUT) 150 assert_equal(STDOUT, logdev.dev) 151 assert_nil(logdev.filename) 152 assert_predicate(old_dev, :closed?) 153 end 154 155 def test_reopen_file_by_file 156 logdev = d(@filename) 157 old_dev = logdev.dev 158 159 tempfile2 = Tempfile.new("logger") 160 tempfile2.close 161 filename2 = tempfile2.path 162 File.unlink(filename2) 163 164 logdev.reopen(filename2) 165 begin 166 assert_file.exist?(filename2) 167 assert_equal(filename2, logdev.filename) 168 assert_predicate(old_dev, :closed?) 169 ensure 170 logdev.close 171 tempfile2.close(true) 172 end 173 end 174 175 def test_shifting_size 176 tmpfile = Tempfile.new([File.basename(__FILE__, '.*'), '_1.log']) 177 logfile = tmpfile.path 178 logfile0 = logfile + '.0' 179 logfile1 = logfile + '.1' 180 logfile2 = logfile + '.2' 181 logfile3 = logfile + '.3' 182 tmpfile.close(true) 183 File.unlink(logfile) if File.exist?(logfile) 184 File.unlink(logfile0) if File.exist?(logfile0) 185 File.unlink(logfile1) if File.exist?(logfile1) 186 File.unlink(logfile2) if File.exist?(logfile2) 187 logger = Logger.new(logfile, 4, 100) 188 logger.error("0" * 15) 189 assert_file.exist?(logfile) 190 assert_file.not_exist?(logfile0) 191 logger.error("0" * 15) 192 assert_file.exist?(logfile0) 193 assert_file.not_exist?(logfile1) 194 logger.error("0" * 15) 195 assert_file.exist?(logfile1) 196 assert_file.not_exist?(logfile2) 197 logger.error("0" * 15) 198 assert_file.exist?(logfile2) 199 assert_file.not_exist?(logfile3) 200 logger.error("0" * 15) 201 assert_file.not_exist?(logfile3) 202 logger.error("0" * 15) 203 assert_file.not_exist?(logfile3) 204 logger.close 205 File.unlink(logfile) 206 File.unlink(logfile0) 207 File.unlink(logfile1) 208 File.unlink(logfile2) 209 210 tmpfile = Tempfile.new([File.basename(__FILE__, '.*'), '_2.log']) 211 logfile = tmpfile.path 212 logfile0 = logfile + '.0' 213 logfile1 = logfile + '.1' 214 logfile2 = logfile + '.2' 215 logfile3 = logfile + '.3' 216 tmpfile.close(true) 217 logger = Logger.new(logfile, 4, 150) 218 logger.error("0" * 15) 219 assert_file.exist?(logfile) 220 assert_file.not_exist?(logfile0) 221 logger.error("0" * 15) 222 assert_file.not_exist?(logfile0) 223 logger.error("0" * 15) 224 assert_file.exist?(logfile0) 225 assert_file.not_exist?(logfile1) 226 logger.error("0" * 15) 227 assert_file.not_exist?(logfile1) 228 logger.error("0" * 15) 229 assert_file.exist?(logfile1) 230 assert_file.not_exist?(logfile2) 231 logger.error("0" * 15) 232 assert_file.not_exist?(logfile2) 233 logger.error("0" * 15) 234 assert_file.exist?(logfile2) 235 assert_file.not_exist?(logfile3) 236 logger.error("0" * 15) 237 assert_file.not_exist?(logfile3) 238 logger.error("0" * 15) 239 assert_file.not_exist?(logfile3) 240 logger.error("0" * 15) 241 assert_file.not_exist?(logfile3) 242 logger.close 243 File.unlink(logfile) 244 File.unlink(logfile0) 245 File.unlink(logfile1) 246 File.unlink(logfile2) 247 end 248 249 def test_shifting_age_variants 250 logger = Logger.new(@filename, 'daily') 251 logger.info('daily') 252 logger.close 253 logger = Logger.new(@filename, 'weekly') 254 logger.info('weekly') 255 logger.close 256 logger = Logger.new(@filename, 'monthly') 257 logger.info('monthly') 258 logger.close 259 end 260 261 def test_shifting_age 262 # shift_age other than 'daily', 'weekly', and 'monthly' means 'everytime' 263 yyyymmdd = Time.now.strftime("%Y%m%d") 264 filename1 = @filename + ".#{yyyymmdd}" 265 filename2 = @filename + ".#{yyyymmdd}.1" 266 filename3 = @filename + ".#{yyyymmdd}.2" 267 begin 268 logger = Logger.new(@filename, 'now') 269 assert_file.exist?(@filename) 270 assert_file.not_exist?(filename1) 271 assert_file.not_exist?(filename2) 272 assert_file.not_exist?(filename3) 273 logger.info("0" * 15) 274 assert_file.exist?(@filename) 275 assert_file.exist?(filename1) 276 assert_file.not_exist?(filename2) 277 assert_file.not_exist?(filename3) 278 logger.warn("0" * 15) 279 assert_file.exist?(@filename) 280 assert_file.exist?(filename1) 281 assert_file.exist?(filename2) 282 assert_file.not_exist?(filename3) 283 logger.error("0" * 15) 284 assert_file.exist?(@filename) 285 assert_file.exist?(filename1) 286 assert_file.exist?(filename2) 287 assert_file.exist?(filename3) 288 ensure 289 logger.close if logger 290 [filename1, filename2, filename3].each do |filename| 291 File.unlink(filename) if File.exist?(filename) 292 end 293 end 294 end 295 296 def test_shifting_period_suffix 297 # shift_age other than 'daily', 'weekly', and 'monthly' means 'everytime' 298 ['%Y%m%d', '%Y-%m-%d', '%Y'].each do |format| 299 if format == '%Y%m%d' # default 300 logger = Logger.new(@filename, 'now', 1048576) 301 else # config 302 logger = Logger.new(@filename, 'now', 1048576, shift_period_suffix: format) 303 end 304 begin 305 yyyymmdd = Time.now.strftime(format) 306 filename1 = @filename + ".#{yyyymmdd}" 307 filename2 = @filename + ".#{yyyymmdd}.1" 308 filename3 = @filename + ".#{yyyymmdd}.2" 309 logger.info("0" * 15) 310 logger.info("0" * 15) 311 logger.info("0" * 15) 312 assert_file.exist?(@filename) 313 assert_file.exist?(filename1) 314 assert_file.exist?(filename2) 315 assert_file.exist?(filename3) 316 ensure 317 logger.close if logger 318 [filename1, filename2, filename3].each do |filename| 319 File.unlink(filename) if File.exist?(filename) 320 end 321 end 322 end 323 end 324 325 def test_shifting_size_in_multiprocess 326 tmpfile = Tempfile.new([File.basename(__FILE__, '.*'), '_1.log']) 327 logfile = tmpfile.path 328 logfile0 = logfile + '.0' 329 logfile1 = logfile + '.1' 330 logfile2 = logfile + '.2' 331 tmpfile.close(true) 332 File.unlink(logfile) if File.exist?(logfile) 333 File.unlink(logfile0) if File.exist?(logfile0) 334 File.unlink(logfile1) if File.exist?(logfile1) 335 File.unlink(logfile2) if File.exist?(logfile2) 336 begin 337 stderr = run_children(2, [logfile], "#{<<-"begin;"}\n#{<<-'end;'}") 338 begin; 339 logger = Logger.new(ARGV[0], 4, 10) 340 10.times do 341 logger.info '0' * 15 342 end 343 end; 344 assert_no_match(/log shifting failed/, stderr) 345 assert_no_match(/log writing failed/, stderr) 346 assert_no_match(/log rotation inter-process lock failed/, stderr) 347 ensure 348 File.unlink(logfile) if File.exist?(logfile) 349 File.unlink(logfile0) if File.exist?(logfile0) 350 File.unlink(logfile1) if File.exist?(logfile1) 351 File.unlink(logfile2) if File.exist?(logfile2) 352 end 353 end 354 355 def test_shifting_age_in_multiprocess 356 yyyymmdd = Time.now.strftime("%Y%m%d") 357 begin 358 stderr = run_children(2, [@filename], "#{<<-"begin;"}\n#{<<-'end;'}") 359 begin; 360 logger = Logger.new(ARGV[0], 'now') 361 10.times do 362 logger.info '0' * 15 363 end 364 end; 365 assert_no_match(/log shifting failed/, stderr) 366 assert_no_match(/log writing failed/, stderr) 367 assert_no_match(/log rotation inter-process lock failed/, stderr) 368 ensure 369 Dir.glob("#{@filename}.#{yyyymmdd}{,.[1-9]*}") do |filename| 370 File.unlink(filename) if File.exist?(filename) 371 end 372 end 373 end 374 375 def test_open_logfile_in_multiprocess 376 tmpfile = Tempfile.new([File.basename(__FILE__, '.*'), '_1.log']) 377 logfile = tmpfile.path 378 tmpfile.close(true) 379 begin 380 20.times do 381 run_children(2, [logfile], "#{<<-"begin;"}\n#{<<-'end;'}") 382 begin; 383 logfile = ARGV[0] 384 logdev = Logger::LogDevice.new(logfile) 385 logdev.send(:open_logfile, logfile) 386 end; 387 assert_equal(1, File.readlines(logfile).grep(/# Logfile created on/).size) 388 File.unlink(logfile) 389 end 390 ensure 391 File.unlink(logfile) if File.exist?(logfile) 392 end 393 end 394 395 def test_shifting_size_not_rotate_too_much 396 logdev0 = d(@filename) 397 logdev0.__send__(:add_log_header, @tempfile) 398 header_size = @tempfile.size 399 message = "*" * 99 + "\n" 400 shift_size = header_size + message.size * 3 - 1 401 opt = {shift_age: 1, shift_size: shift_size} 402 403 Dir.mktmpdir do |tmpdir| 404 begin 405 log = File.join(tmpdir, "log") 406 logdev1 = d(log, opt) 407 logdev2 = d(log, opt) 408 409 assert_file.identical?(log, logdev1.dev) 410 assert_file.identical?(log, logdev2.dev) 411 412 3.times{logdev1.write(message)} 413 assert_file.identical?(log, logdev1.dev) 414 assert_file.identical?(log, logdev2.dev) 415 416 logdev1.write(message) 417 assert_file.identical?(log, logdev1.dev) 418 assert_file.identical?(log + ".0", logdev2.dev) 419 420 logdev2.write(message) 421 assert_file.identical?(log, logdev1.dev) 422 assert_file.identical?(log, logdev2.dev) 423 424 logdev1.write(message) 425 assert_file.identical?(log, logdev1.dev) 426 assert_file.identical?(log, logdev2.dev) 427 ensure 428 logdev1.close if logdev1 429 logdev2.close if logdev2 430 end 431 end 432 ensure 433 logdev0.close 434 end unless /mswin|mingw/ =~ RUBY_PLATFORM 435 436 def test_shifting_midnight 437 Dir.mktmpdir do |tmpdir| 438 assert_in_out_err([*%W"--disable=gems -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") 439 begin; 440 begin 441 module FakeTime 442 attr_accessor :now 443 end 444 445 class << Time 446 prepend FakeTime 447 end 448 449 log = "log" 450 File.open(log, "w") {} 451 File.utime(*[Time.mktime(2014, 1, 2, 0, 0, 0)]*2, log) 452 453 Time.now = Time.mktime(2014, 1, 2, 23, 59, 59, 999000) 454 dev = Logger::LogDevice.new(log, shift_age: 'daily') 455 dev.write("#{Time.now} hello-1\n") 456 File.utime(Time.now, Time.now, log) 457 458 Time.now = Time.mktime(2014, 1, 3, 1, 1, 1) 459 dev.write("#{Time.now} hello-2\n") 460 File.utime(Time.now, Time.now, log) 461 ensure 462 dev.close 463 end 464 end; 465 466 bug = '[GH-539]' 467 log = File.join(tmpdir, "log") 468 cont = File.read(log) 469 assert_match(/hello-2/, cont) 470 assert_not_match(/hello-1/, cont) 471 assert_file.for(bug).exist?(log+".20140102") 472 assert_match(/hello-1/, File.read(log+".20140102"), bug) 473 end 474 end 475 476 env_tz_works = /linux|darwin|freebsd/ =~ RUBY_PLATFORM # borrow from test/ruby/test_time_tz.rb 477 478 def test_shifting_weekly 479 Dir.mktmpdir do |tmpdir| 480 assert_in_out_err([{"TZ"=>"UTC"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") 481 begin; 482 begin 483 module FakeTime 484 attr_accessor :now 485 end 486 487 class << Time 488 prepend FakeTime 489 end 490 491 log = "log" 492 File.open(log, "w") {} 493 Time.now = Time.utc(2015, 12, 14, 0, 1, 1) 494 File.utime(Time.now, Time.now, log) 495 496 dev = Logger::LogDevice.new("log", shift_age: 'weekly') 497 498 Time.now = Time.utc(2015, 12, 19, 12, 34, 56) 499 dev.write("#{Time.now} hello-1\n") 500 File.utime(Time.now, Time.now, log) 501 502 Time.now = Time.utc(2015, 12, 20, 0, 1, 1) 503 dev.write("#{Time.now} hello-2\n") 504 File.utime(Time.now, Time.now, log) 505 ensure 506 dev.close if dev 507 end 508 end; 509 log = File.join(tmpdir, "log") 510 cont = File.read(log) 511 assert_match(/hello-2/, cont) 512 assert_not_match(/hello-1/, cont) 513 log = Dir.glob(log+".*") 514 assert_equal(1, log.size) 515 log, = *log 516 cont = File.read(log) 517 assert_match(/hello-1/, cont) 518 assert_equal("2015-12-19", cont[/^[-\d]+/]) 519 assert_equal("20151219", log[/\d+\z/]) 520 end 521 end if env_tz_works 522 523 def test_shifting_monthly 524 Dir.mktmpdir do |tmpdir| 525 assert_in_out_err([{"TZ"=>"UTC"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") 526 begin; 527 begin 528 module FakeTime 529 attr_accessor :now 530 end 531 532 class << Time 533 prepend FakeTime 534 end 535 536 log = "log" 537 File.open(log, "w") {} 538 Time.now = Time.utc(2015, 12, 14, 0, 1, 1) 539 File.utime(Time.now, Time.now, log) 540 541 dev = Logger::LogDevice.new("log", shift_age: 'monthly') 542 543 Time.now = Time.utc(2015, 12, 31, 12, 34, 56) 544 dev.write("#{Time.now} hello-1\n") 545 File.utime(Time.now, Time.now, log) 546 547 Time.now = Time.utc(2016, 1, 1, 0, 1, 1) 548 dev.write("#{Time.now} hello-2\n") 549 File.utime(Time.now, Time.now, log) 550 ensure 551 dev.close if dev 552 end 553 end; 554 log = File.join(tmpdir, "log") 555 cont = File.read(log) 556 assert_match(/hello-2/, cont) 557 assert_not_match(/hello-1/, cont) 558 log = Dir.glob(log+".*") 559 assert_equal(1, log.size) 560 log, = *log 561 cont = File.read(log) 562 assert_match(/hello-1/, cont) 563 assert_equal("2015-12-31", cont[/^[-\d]+/]) 564 assert_equal("20151231", log[/\d+\z/]) 565 end 566 end if env_tz_works 567 568 def test_shifting_dst_change 569 Dir.mktmpdir do |tmpdir| 570 assert_in_out_err([{"TZ"=>"Europe/London"}, *%W"--disable=gems -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") 571 begin; 572 begin 573 module FakeTime 574 attr_accessor :now 575 end 576 577 class << Time 578 prepend FakeTime 579 end 580 581 log = "log" 582 File.open(log, "w") {} 583 584 Time.now = Time.mktime(2014, 3, 30, 0, 1, 1) 585 File.utime(Time.now, Time.now, log) 586 587 dev = Logger::LogDevice.new(log, shift_age: 'daily') 588 dev.write("#{Time.now} hello-1\n") 589 File.utime(*[Time.mktime(2014, 3, 30, 0, 2, 3)]*2, log) 590 591 Time.now = Time.mktime(2014, 3, 31, 0, 1, 1) 592 dev.write("#{Time.now} hello-2\n") 593 File.utime(Time.now, Time.now, log) 594 ensure 595 dev.close 596 end 597 end; 598 599 log = File.join(tmpdir, "log") 600 cont = File.read(log) 601 assert_match(/hello-2/, cont) 602 assert_not_match(/hello-1/, cont) 603 assert_file.exist?(log+".20140330") 604 end 605 end if env_tz_works 606 607 def test_shifting_weekly_dst_change 608 Dir.mktmpdir do |tmpdir| 609 assert_separately([{"TZ"=>"Europe/London"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") 610 begin; 611 begin 612 module FakeTime 613 attr_accessor :now 614 end 615 616 class << Time 617 prepend FakeTime 618 end 619 620 log = "log" 621 File.open(log, "w") {} 622 Time.now = Time.mktime(2015, 10, 25, 0, 1, 1) 623 File.utime(Time.now, Time.now, log) 624 625 dev = Logger::LogDevice.new("log", shift_age: 'weekly') 626 dev.write("#{Time.now} hello-1\n") 627 File.utime(Time.now, Time.now, log) 628 ensure 629 dev.close if dev 630 end 631 end; 632 log = File.join(tmpdir, "log") 633 cont = File.read(log) 634 assert_match(/hello-1/, cont) 635 end 636 end if env_tz_works 637 638 def test_shifting_monthly_dst_change 639 Dir.mktmpdir do |tmpdir| 640 assert_separately([{"TZ"=>"Europe/London"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") 641 begin; 642 begin 643 module FakeTime 644 attr_accessor :now 645 end 646 647 class << Time 648 prepend FakeTime 649 end 650 651 log = "log" 652 File.open(log, "w") {} 653 Time.now = Time.utc(2016, 9, 1, 0, 1, 1) 654 File.utime(Time.now, Time.now, log) 655 656 dev = Logger::LogDevice.new("log", shift_age: 'monthly') 657 658 Time.now = Time.utc(2016, 9, 8, 7, 6, 5) 659 dev.write("#{Time.now} hello-1\n") 660 File.utime(Time.now, Time.now, log) 661 662 Time.now = Time.utc(2016, 10, 9, 8, 7, 6) 663 dev.write("#{Time.now} hello-2\n") 664 File.utime(Time.now, Time.now, log) 665 666 Time.now = Time.utc(2016, 10, 9, 8, 7, 7) 667 dev.write("#{Time.now} hello-3\n") 668 File.utime(Time.now, Time.now, log) 669 ensure 670 dev.close if dev 671 end 672 end; 673 log = File.join(tmpdir, "log") 674 cont = File.read(log) 675 assert_match(/hello-2/, cont) 676 assert_not_match(/hello-1/, cont) 677 log = Dir.glob(log+".*") 678 assert_equal(1, log.size) 679 log, = *log 680 cont = File.read(log) 681 assert_match(/hello-1/, cont) 682 assert_equal("2016-09-08", cont[/^[-\d]+/]) 683 assert_equal("20160930", log[/\d+\z/]) 684 end 685 end if env_tz_works 686 687 def test_shifting_midnight_exist_file 688 Dir.mktmpdir do |tmpdir| 689 assert_in_out_err([*%W"--disable=gems -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") 690 begin; 691 begin 692 module FakeTime 693 attr_accessor :now 694 end 695 696 class << Time 697 prepend FakeTime 698 end 699 700 log = "log" 701 File.open(log, "w") {} 702 File.utime(*[Time.mktime(2014, 1, 2, 0, 0, 0)]*2, log) 703 704 Time.now = Time.mktime(2014, 1, 2, 23, 59, 59, 999000) 705 dev = Logger::LogDevice.new(log, shift_age: 'daily') 706 dev.write("#{Time.now} hello-1\n") 707 dev.close 708 File.utime(Time.now, Time.now, log) 709 710 Time.now = Time.mktime(2014, 1, 3, 1, 1, 1) 711 dev = Logger::LogDevice.new(log, shift_age: 'daily') 712 dev.write("#{Time.now} hello-2\n") 713 File.utime(Time.now, Time.now, log) 714 ensure 715 dev.close 716 end 717 end; 718 719 bug = '[GH-539]' 720 log = File.join(tmpdir, "log") 721 cont = File.read(log) 722 assert_match(/hello-2/, cont) 723 assert_not_match(/hello-1/, cont) 724 assert_file.for(bug).exist?(log+".20140102") 725 assert_match(/hello-1/, File.read(log+".20140102"), bug) 726 end 727 end 728 729 env_tz_works = /linux|darwin|freebsd/ =~ RUBY_PLATFORM # borrow from test/ruby/test_time_tz.rb 730 731 def test_shifting_weekly_exist_file 732 Dir.mktmpdir do |tmpdir| 733 assert_in_out_err([{"TZ"=>"UTC"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") 734 begin; 735 begin 736 module FakeTime 737 attr_accessor :now 738 end 739 740 class << Time 741 prepend FakeTime 742 end 743 744 log = "log" 745 File.open(log, "w") {} 746 Time.now = Time.utc(2015, 12, 14, 0, 1, 1) 747 File.utime(Time.now, Time.now, log) 748 749 dev = Logger::LogDevice.new("log", shift_age: 'weekly') 750 751 Time.now = Time.utc(2015, 12, 19, 12, 34, 56) 752 dev.write("#{Time.now} hello-1\n") 753 dev.close 754 File.utime(Time.now, Time.now, log) 755 756 Time.now = Time.utc(2015, 12, 20, 0, 1, 1) 757 dev = Logger::LogDevice.new("log", shift_age: 'weekly') 758 dev.write("#{Time.now} hello-2\n") 759 File.utime(Time.now, Time.now, log) 760 ensure 761 dev.close if dev 762 end 763 end; 764 log = File.join(tmpdir, "log") 765 cont = File.read(log) 766 assert_match(/hello-2/, cont) 767 assert_not_match(/hello-1/, cont) 768 log = Dir.glob(log+".*") 769 assert_equal(1, log.size) 770 log, = *log 771 cont = File.read(log) 772 assert_match(/hello-1/, cont) 773 assert_equal("2015-12-19", cont[/^[-\d]+/]) 774 assert_equal("20151219", log[/\d+\z/]) 775 end 776 end if env_tz_works 777 778 def test_shifting_monthly_exist_file 779 Dir.mktmpdir do |tmpdir| 780 assert_in_out_err([{"TZ"=>"UTC"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") 781 begin; 782 begin 783 module FakeTime 784 attr_accessor :now 785 end 786 787 class << Time 788 prepend FakeTime 789 end 790 791 log = "log" 792 File.open(log, "w") {} 793 Time.now = Time.utc(2015, 12, 14, 0, 1, 1) 794 File.utime(Time.now, Time.now, log) 795 796 dev = Logger::LogDevice.new("log", shift_age: 'monthly') 797 798 Time.now = Time.utc(2015, 12, 31, 12, 34, 56) 799 dev.write("#{Time.now} hello-1\n") 800 dev.close 801 File.utime(Time.now, Time.now, log) 802 803 Time.now = Time.utc(2016, 1, 1, 0, 1, 1) 804 dev = Logger::LogDevice.new("log", shift_age: 'monthly') 805 dev.write("#{Time.now} hello-2\n") 806 File.utime(Time.now, Time.now, log) 807 ensure 808 dev.close if dev 809 end 810 end; 811 log = File.join(tmpdir, "log") 812 cont = File.read(log) 813 assert_match(/hello-2/, cont) 814 assert_not_match(/hello-1/, cont) 815 log = Dir.glob(log+".*") 816 assert_equal(1, log.size) 817 log, = *log 818 cont = File.read(log) 819 assert_match(/hello-1/, cont) 820 assert_equal("2015-12-31", cont[/^[-\d]+/]) 821 assert_equal("20151231", log[/\d+\z/]) 822 end 823 end if env_tz_works 824 825 private 826 827 def run_children(n, args, src) 828 r, w = IO.pipe 829 [w, *(1..n).map do 830 f = IO.popen([EnvUtil.rubybin, *%w[--disable=gems -rlogger -], *args], "w", err: w) 831 f.puts(src) 832 f 833 end].each(&:close) 834 stderr = r.read 835 r.close 836 stderr 837 end 838end 839