1# $Id: test_fileutils.rb 41946 2013-07-13 14:32:56Z nagachika $ 2 3require 'fileutils' 4require_relative 'fileasserts' 5require 'pathname' 6require 'tmpdir' 7require 'test/unit' 8 9class TestFileUtils < Test::Unit::TestCase 10 TMPROOT = "#{Dir.tmpdir}/fileutils.rb.#{$$}" 11 include Test::Unit::FileAssertions 12end 13 14prevdir = Dir.pwd 15tmproot = TestFileUtils::TMPROOT 16Dir.mkdir tmproot unless File.directory?(tmproot) 17Dir.chdir tmproot 18 19def have_drive_letter? 20 /mswin(?!ce)|mingw|bcc|emx/ =~ RUBY_PLATFORM 21end 22 23def have_file_perm? 24 /mswin|mingw|bcc|emx/ !~ RUBY_PLATFORM 25end 26 27$fileutils_rb_have_symlink = nil 28 29def have_symlink? 30 if $fileutils_rb_have_symlink == nil 31 $fileutils_rb_have_symlink = check_have_symlink? 32 end 33 $fileutils_rb_have_symlink 34end 35 36def check_have_symlink? 37 File.symlink nil, nil 38rescue NotImplementedError 39 return false 40rescue 41 return true 42end 43 44$fileutils_rb_have_hardlink = nil 45 46def have_hardlink? 47 if $fileutils_rb_have_hardlink == nil 48 $fileutils_rb_have_hardlink = check_have_hardlink? 49 end 50 $fileutils_rb_have_hardlink 51end 52 53def check_have_hardlink? 54 File.link nil, nil 55rescue NotImplementedError 56 return false 57rescue 58 return true 59end 60 61begin 62 Dir.mkdir("\n") 63 Dir.rmdir("\n") 64 def lf_in_path_allowed? 65 true 66 end 67rescue 68 def lf_in_path_allowed? 69 false 70 end 71end 72 73Dir.chdir prevdir 74Dir.rmdir tmproot 75 76class TestFileUtils 77 78 include FileUtils 79 80 def check_singleton(name) 81 assert_respond_to ::FileUtils, name 82 end 83 84 def my_rm_rf(path) 85 if File.exist?('/bin/rm') 86 system %Q[/bin/rm -rf "#{path}"] 87 else 88 FileUtils.rm_rf path 89 end 90 end 91 92 def mymkdir(path) 93 Dir.mkdir path 94 File.chown nil, Process.gid, path if have_file_perm? 95 end 96 97 def setup 98 @prevdir = Dir.pwd 99 tmproot = TMPROOT 100 mymkdir tmproot unless File.directory?(tmproot) 101 Dir.chdir tmproot 102 my_rm_rf 'data'; mymkdir 'data' 103 my_rm_rf 'tmp'; mymkdir 'tmp' 104 prepare_data_file 105 end 106 107 def teardown 108 Dir.chdir @prevdir 109 my_rm_rf TMPROOT 110 end 111 112 113 TARGETS = %w( data/a data/all data/random data/zero ) 114 115 def prepare_data_file 116 File.open('data/a', 'w') {|f| 117 32.times do 118 f.puts 'a' * 50 119 end 120 } 121 122 all_chars = (0..255).map {|n| n.chr }.join('') 123 File.open('data/all', 'w') {|f| 124 32.times do 125 f.puts all_chars 126 end 127 } 128 129 random_chars = (0...50).map { rand(256).chr }.join('') 130 File.open('data/random', 'w') {|f| 131 32.times do 132 f.puts random_chars 133 end 134 } 135 136 File.open('data/zero', 'w') {|f| 137 ; 138 } 139 end 140 141 BIGFILE = 'data/big' 142 143 def prepare_big_file 144 File.open('data/big', 'w') {|f| 145 (4 * 1024 * 1024 / 256).times do # 4MB 146 f.print "aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa\n" 147 end 148 } 149 end 150 151 def prepare_time_data 152 File.open('data/old', 'w') {|f| f.puts 'dummy' } 153 File.open('data/newer', 'w') {|f| f.puts 'dummy' } 154 File.open('data/newest', 'w') {|f| f.puts 'dummy' } 155 t = Time.now 156 File.utime t-8, t-8, 'data/old' 157 File.utime t-4, t-4, 'data/newer' 158 end 159 160 def each_srcdest 161 TARGETS.each do |path| 162 yield path, "tmp/#{File.basename(path)}" 163 end 164 end 165 166 # 167 # Test Cases 168 # 169 170 def test_pwd 171 check_singleton :pwd 172 173 assert_equal Dir.pwd, pwd() 174 175 cwd = Dir.pwd 176 root = have_drive_letter? ? 'C:/' : '/' 177 cd(root) { 178 assert_equal root, pwd() 179 } 180 assert_equal cwd, pwd() 181 end 182 183 def test_cmp 184 check_singleton :cmp 185 186 TARGETS.each do |fname| 187 assert cmp(fname, fname), 'not same?' 188 end 189 assert_raise(ArgumentError) { 190 cmp TARGETS[0], TARGETS[0], :undefinedoption => true 191 } 192 193 # pathname 194 touch 'tmp/cmptmp' 195 assert_nothing_raised { 196 cmp Pathname.new('tmp/cmptmp'), 'tmp/cmptmp' 197 cmp 'tmp/cmptmp', Pathname.new('tmp/cmptmp') 198 cmp Pathname.new('tmp/cmptmp'), Pathname.new('tmp/cmptmp') 199 } 200 end 201 202 def test_cp 203 check_singleton :cp 204 205 each_srcdest do |srcpath, destpath| 206 cp srcpath, destpath 207 assert_same_file srcpath, destpath 208 209 cp srcpath, File.dirname(destpath) 210 assert_same_file srcpath, destpath 211 212 cp srcpath, File.dirname(destpath) + '/' 213 assert_same_file srcpath, destpath 214 215 cp srcpath, destpath, :preserve => true 216 assert_same_file srcpath, destpath 217 assert_same_entry srcpath, destpath 218 end 219 220 assert_raise(Errno::ENOENT) { 221 cp 'tmp/cptmp', 'tmp/cptmp_new' 222 } 223 assert_file_not_exist('tmp/cptmp_new') 224 225 # src==dest (1) same path 226 touch 'tmp/cptmp' 227 assert_raise(ArgumentError) { 228 cp 'tmp/cptmp', 'tmp/cptmp' 229 } 230 end 231 232 def test_cp_preserve_permissions 233 bug4507 = '[ruby-core:35518]' 234 touch 'tmp/cptmp' 235 chmod 0755, 'tmp/cptmp' 236 cp 'tmp/cptmp', 'tmp/cptmp2' 237 assert_equal(File.stat('tmp/cptmp').mode, 238 File.stat('tmp/cptmp2').mode, 239 bug4507) 240 end 241 242 def test_cp_preserve_permissions_dir 243 bug7246 = '[ruby-core:48603]' 244 mkdir 'tmp/cptmp' 245 mkdir 'tmp/cptmp/d1' 246 chmod 0745, 'tmp/cptmp/d1' 247 mkdir 'tmp/cptmp/d2' 248 chmod 0700, 'tmp/cptmp/d2' 249 cp_r 'tmp/cptmp', 'tmp/cptmp2', :preserve => true 250 assert_equal(File.stat('tmp/cptmp/d1').mode, 251 File.stat('tmp/cptmp2/d1').mode, 252 bug7246) 253 assert_equal(File.stat('tmp/cptmp/d2').mode, 254 File.stat('tmp/cptmp2/d2').mode, 255 bug7246) 256 end 257 258 def test_cp_symlink 259 touch 'tmp/cptmp' 260 # src==dest (2) symlink and its target 261 File.symlink 'cptmp', 'tmp/cptmp_symlink' 262 assert_raise(ArgumentError) { 263 cp 'tmp/cptmp', 'tmp/cptmp_symlink' 264 } 265 assert_raise(ArgumentError) { 266 cp 'tmp/cptmp_symlink', 'tmp/cptmp' 267 } 268 # src==dest (3) looped symlink 269 File.symlink 'symlink', 'tmp/symlink' 270 assert_raise(Errno::ELOOP) { 271 cp 'tmp/symlink', 'tmp/symlink' 272 } 273 end if have_symlink? 274 275 def test_cp_pathname 276 # pathname 277 touch 'tmp/cptmp' 278 assert_nothing_raised { 279 cp 'tmp/cptmp', Pathname.new('tmp/tmpdest') 280 cp Pathname.new('tmp/cptmp'), 'tmp/tmpdest' 281 cp Pathname.new('tmp/cptmp'), Pathname.new('tmp/tmpdest') 282 mkdir 'tmp/tmpdir' 283 cp ['tmp/cptmp', 'tmp/tmpdest'], Pathname.new('tmp/tmpdir') 284 } 285 end 286 287 def test_cp_r 288 check_singleton :cp_r 289 290 cp_r 'data', 'tmp' 291 TARGETS.each do |fname| 292 assert_same_file fname, "tmp/#{fname}" 293 end 294 295 cp_r 'data', 'tmp2', :preserve => true 296 TARGETS.each do |fname| 297 assert_same_entry fname, "tmp2/#{File.basename(fname)}" 298 assert_same_file fname, "tmp2/#{File.basename(fname)}" 299 end 300 301 # a/* -> b/* 302 mkdir 'tmp/cpr_src' 303 mkdir 'tmp/cpr_dest' 304 File.open('tmp/cpr_src/a', 'w') {|f| f.puts 'a' } 305 File.open('tmp/cpr_src/b', 'w') {|f| f.puts 'b' } 306 File.open('tmp/cpr_src/c', 'w') {|f| f.puts 'c' } 307 mkdir 'tmp/cpr_src/d' 308 cp_r 'tmp/cpr_src/.', 'tmp/cpr_dest' 309 assert_same_file 'tmp/cpr_src/a', 'tmp/cpr_dest/a' 310 assert_same_file 'tmp/cpr_src/b', 'tmp/cpr_dest/b' 311 assert_same_file 'tmp/cpr_src/c', 'tmp/cpr_dest/c' 312 assert_directory 'tmp/cpr_dest/d' 313 my_rm_rf 'tmp/cpr_src' 314 my_rm_rf 'tmp/cpr_dest' 315 316 bug3588 = '[ruby-core:31360]' 317 assert_nothing_raised(ArgumentError, bug3588) do 318 cp_r 'tmp', 'tmp2' 319 end 320 assert_directory 'tmp2/tmp' 321 assert_raise(ArgumentError, bug3588) do 322 cp_r 'tmp2', 'tmp2/new_tmp2' 323 end 324 end 325 326 def test_cp_r_symlink 327 # symlink in a directory 328 mkdir 'tmp/cpr_src' 329 ln_s 'SLdest', 'tmp/cpr_src/symlink' 330 cp_r 'tmp/cpr_src', 'tmp/cpr_dest' 331 assert_symlink 'tmp/cpr_dest/symlink' 332 assert_equal 'SLdest', File.readlink('tmp/cpr_dest/symlink') 333 334 # root is a symlink 335 ln_s 'cpr_src', 'tmp/cpr_src2' 336 cp_r 'tmp/cpr_src2', 'tmp/cpr_dest2' 337 assert_directory 'tmp/cpr_dest2' 338 assert_not_symlink 'tmp/cpr_dest2' 339 assert_symlink 'tmp/cpr_dest2/symlink' 340 assert_equal 'SLdest', File.readlink('tmp/cpr_dest2/symlink') 341 end if have_symlink? 342 343 def test_cp_r_symlink_preserve 344 mkdir 'tmp/cross' 345 mkdir 'tmp/cross/a' 346 mkdir 'tmp/cross/b' 347 touch 'tmp/cross/a/f' 348 touch 'tmp/cross/b/f' 349 ln_s '../a/f', 'tmp/cross/b/l' 350 ln_s '../b/f', 'tmp/cross/a/l' 351 assert_nothing_raised { 352 cp_r 'tmp/cross', 'tmp/cross2', :preserve => true 353 } 354 end if have_symlink? 355 356 def test_cp_r_pathname 357 # pathname 358 touch 'tmp/cprtmp' 359 assert_nothing_raised { 360 cp_r Pathname.new('tmp/cprtmp'), 'tmp/tmpdest' 361 cp_r 'tmp/cprtmp', Pathname.new('tmp/tmpdest') 362 cp_r Pathname.new('tmp/cprtmp'), Pathname.new('tmp/tmpdest') 363 } 364 end 365 366 def test_mv 367 check_singleton :mv 368 369 mkdir 'tmp/dest' 370 TARGETS.each do |fname| 371 cp fname, 'tmp/mvsrc' 372 mv 'tmp/mvsrc', 'tmp/mvdest' 373 assert_same_file fname, 'tmp/mvdest' 374 375 mv 'tmp/mvdest', 'tmp/dest/' 376 assert_same_file fname, 'tmp/dest/mvdest' 377 378 mv 'tmp/dest/mvdest', 'tmp' 379 assert_same_file fname, 'tmp/mvdest' 380 end 381 382 mkdir 'tmp/tmpdir' 383 mkdir_p 'tmp/dest2/tmpdir' 384 assert_raise(Errno::EEXIST) { 385 mv 'tmp/tmpdir', 'tmp/dest2' 386 } 387 mkdir 'tmp/dest2/tmpdir/junk' 388 assert_raise(Errno::EEXIST, "[ruby-talk:124368]") { 389 mv 'tmp/tmpdir', 'tmp/dest2' 390 } 391 392 # src==dest (1) same path 393 touch 'tmp/cptmp' 394 assert_raise(ArgumentError) { 395 mv 'tmp/cptmp', 'tmp/cptmp' 396 } 397 end 398 399 def test_mv_symlink 400 touch 'tmp/cptmp' 401 # src==dest (2) symlink and its target 402 File.symlink 'cptmp', 'tmp/cptmp_symlink' 403 assert_raise(ArgumentError) { 404 mv 'tmp/cptmp', 'tmp/cptmp_symlink' 405 } 406 assert_raise(ArgumentError) { 407 mv 'tmp/cptmp_symlink', 'tmp/cptmp' 408 } 409 # src==dest (3) looped symlink 410 File.symlink 'symlink', 'tmp/symlink' 411 assert_raise(Errno::ELOOP) { 412 mv 'tmp/symlink', 'tmp/symlink' 413 } 414 end if have_symlink? 415 416 def test_mv_pathname 417 # pathname 418 assert_nothing_raised { 419 touch 'tmp/mvtmpsrc' 420 mv Pathname.new('tmp/mvtmpsrc'), 'tmp/mvtmpdest' 421 touch 'tmp/mvtmpsrc' 422 mv 'tmp/mvtmpsrc', Pathname.new('tmp/mvtmpdest') 423 touch 'tmp/mvtmpsrc' 424 mv Pathname.new('tmp/mvtmpsrc'), Pathname.new('tmp/mvtmpdest') 425 } 426 end 427 428 def test_rm 429 check_singleton :rm 430 431 TARGETS.each do |fname| 432 cp fname, 'tmp/rmsrc' 433 rm 'tmp/rmsrc' 434 assert_file_not_exist 'tmp/rmsrc' 435 end 436 437 # pathname 438 touch 'tmp/rmtmp1' 439 touch 'tmp/rmtmp2' 440 touch 'tmp/rmtmp3' 441 assert_nothing_raised { 442 rm Pathname.new('tmp/rmtmp1') 443 rm [Pathname.new('tmp/rmtmp2'), Pathname.new('tmp/rmtmp3')] 444 } 445 assert_file_not_exist 'tmp/rmtmp1' 446 assert_file_not_exist 'tmp/rmtmp2' 447 assert_file_not_exist 'tmp/rmtmp3' 448 end 449 450 def test_rm_f 451 check_singleton :rm_f 452 453 TARGETS.each do |fname| 454 cp fname, 'tmp/rmsrc' 455 rm_f 'tmp/rmsrc' 456 assert_file_not_exist 'tmp/rmsrc' 457 end 458 end 459 460 def test_rm_symlink 461 File.open('tmp/lnf_symlink_src', 'w') {|f| f.puts 'dummy' } 462 File.symlink 'tmp/lnf_symlink_src', 'tmp/lnf_symlink_dest' 463 rm_f 'tmp/lnf_symlink_dest' 464 assert_file_not_exist 'tmp/lnf_symlink_dest' 465 assert_file_exist 'tmp/lnf_symlink_src' 466 467 rm_f 'notexistdatafile' 468 rm_f 'tmp/notexistdatafile' 469 my_rm_rf 'tmpdatadir' 470 Dir.mkdir 'tmpdatadir' 471 # rm_f 'tmpdatadir' 472 Dir.rmdir 'tmpdatadir' 473 end if have_symlink? 474 475 def test_rm_f_2 476 Dir.mkdir 'tmp/tmpdir' 477 File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' } 478 File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' } 479 rm_f ['tmp/tmpdir/a', 'tmp/tmpdir/b', 'tmp/tmpdir/c'] 480 assert_file_not_exist 'tmp/tmpdir/a' 481 assert_file_not_exist 'tmp/tmpdir/c' 482 Dir.rmdir 'tmp/tmpdir' 483 end 484 485 def test_rm_pathname 486 # pathname 487 touch 'tmp/rmtmp1' 488 touch 'tmp/rmtmp2' 489 touch 'tmp/rmtmp3' 490 touch 'tmp/rmtmp4' 491 assert_nothing_raised { 492 rm_f Pathname.new('tmp/rmtmp1') 493 rm_f [Pathname.new('tmp/rmtmp2'), Pathname.new('tmp/rmtmp3')] 494 } 495 assert_file_not_exist 'tmp/rmtmp1' 496 assert_file_not_exist 'tmp/rmtmp2' 497 assert_file_not_exist 'tmp/rmtmp3' 498 assert_file_exist 'tmp/rmtmp4' 499 500 # [ruby-dev:39345] 501 touch 'tmp/[rmtmp]' 502 FileUtils.rm_f 'tmp/[rmtmp]' 503 assert_file_not_exist 'tmp/[rmtmp]' 504 end 505 506 def test_rm_r 507 check_singleton :rm_r 508 509 my_rm_rf 'tmpdatadir' 510 511 Dir.mkdir 'tmpdatadir' 512 rm_r 'tmpdatadir' 513 assert_file_not_exist 'tmpdatadir' 514 515 Dir.mkdir 'tmpdatadir' 516 rm_r 'tmpdatadir/' 517 assert_file_not_exist 'tmpdatadir' 518 519 Dir.mkdir 'tmp/tmpdir' 520 rm_r 'tmp/tmpdir/' 521 assert_file_not_exist 'tmp/tmpdir' 522 assert_file_exist 'tmp' 523 524 Dir.mkdir 'tmp/tmpdir' 525 rm_r 'tmp/tmpdir' 526 assert_file_not_exist 'tmp/tmpdir' 527 assert_file_exist 'tmp' 528 529 Dir.mkdir 'tmp/tmpdir' 530 File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' } 531 File.open('tmp/tmpdir/b', 'w') {|f| f.puts 'dummy' } 532 File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' } 533 rm_r 'tmp/tmpdir' 534 assert_file_not_exist 'tmp/tmpdir' 535 assert_file_exist 'tmp' 536 537 Dir.mkdir 'tmp/tmpdir' 538 File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' } 539 File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' } 540 rm_r ['tmp/tmpdir/a', 'tmp/tmpdir/b', 'tmp/tmpdir/c'], :force => true 541 assert_file_not_exist 'tmp/tmpdir/a' 542 assert_file_not_exist 'tmp/tmpdir/c' 543 Dir.rmdir 'tmp/tmpdir' 544 end 545 546 def test_rm_r_symlink 547 # [ruby-talk:94635] a symlink to the directory 548 Dir.mkdir 'tmp/tmpdir' 549 File.symlink '..', 'tmp/tmpdir/symlink_to_dir' 550 rm_r 'tmp/tmpdir' 551 assert_file_not_exist 'tmp/tmpdir' 552 assert_file_exist 'tmp' 553 end if have_symlink? 554 555 def test_rm_r_pathname 556 # pathname 557 Dir.mkdir 'tmp/tmpdir1'; touch 'tmp/tmpdir1/tmp' 558 Dir.mkdir 'tmp/tmpdir2'; touch 'tmp/tmpdir2/tmp' 559 Dir.mkdir 'tmp/tmpdir3'; touch 'tmp/tmpdir3/tmp' 560 assert_nothing_raised { 561 rm_r Pathname.new('tmp/tmpdir1') 562 rm_r [Pathname.new('tmp/tmpdir2'), Pathname.new('tmp/tmpdir3')] 563 } 564 assert_file_not_exist 'tmp/tmpdir1' 565 assert_file_not_exist 'tmp/tmpdir2' 566 assert_file_not_exist 'tmp/tmpdir3' 567 end 568 569 def test_remove_entry_secure 570 check_singleton :remove_entry_secure 571 572 my_rm_rf 'tmpdatadir' 573 574 Dir.mkdir 'tmpdatadir' 575 remove_entry_secure 'tmpdatadir' 576 assert_file_not_exist 'tmpdatadir' 577 578 Dir.mkdir 'tmpdatadir' 579 remove_entry_secure 'tmpdatadir/' 580 assert_file_not_exist 'tmpdatadir' 581 582 Dir.mkdir 'tmp/tmpdir' 583 remove_entry_secure 'tmp/tmpdir/' 584 assert_file_not_exist 'tmp/tmpdir' 585 assert_file_exist 'tmp' 586 587 Dir.mkdir 'tmp/tmpdir' 588 remove_entry_secure 'tmp/tmpdir' 589 assert_file_not_exist 'tmp/tmpdir' 590 assert_file_exist 'tmp' 591 592 Dir.mkdir 'tmp/tmpdir' 593 File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' } 594 File.open('tmp/tmpdir/b', 'w') {|f| f.puts 'dummy' } 595 File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' } 596 remove_entry_secure 'tmp/tmpdir' 597 assert_file_not_exist 'tmp/tmpdir' 598 assert_file_exist 'tmp' 599 600 Dir.mkdir 'tmp/tmpdir' 601 File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' } 602 File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' } 603 remove_entry_secure 'tmp/tmpdir/a', true 604 remove_entry_secure 'tmp/tmpdir/b', true 605 remove_entry_secure 'tmp/tmpdir/c', true 606 assert_file_not_exist 'tmp/tmpdir/a' 607 assert_file_not_exist 'tmp/tmpdir/c' 608 Dir.rmdir 'tmp/tmpdir' 609 end 610 611 def test_remove_entry_secure_symlink 612 # [ruby-talk:94635] a symlink to the directory 613 Dir.mkdir 'tmp/tmpdir' 614 File.symlink '..', 'tmp/tmpdir/symlink_to_dir' 615 remove_entry_secure 'tmp/tmpdir' 616 assert_file_not_exist 'tmp/tmpdir' 617 assert_file_exist 'tmp' 618 end if have_symlink? 619 620 def test_remove_entry_secure_pathname 621 # pathname 622 Dir.mkdir 'tmp/tmpdir1'; touch 'tmp/tmpdir1/tmp' 623 assert_nothing_raised { 624 remove_entry_secure Pathname.new('tmp/tmpdir1') 625 } 626 assert_file_not_exist 'tmp/tmpdir1' 627 end 628 629 def test_with_big_file 630 prepare_big_file 631 632 cp BIGFILE, 'tmp/cpdest' 633 assert_same_file BIGFILE, 'tmp/cpdest' 634 assert cmp(BIGFILE, 'tmp/cpdest'), 'orig != copied' 635 636 mv 'tmp/cpdest', 'tmp/mvdest' 637 assert_same_file BIGFILE, 'tmp/mvdest' 638 assert_file_not_exist 'tmp/cpdest' 639 640 rm 'tmp/mvdest' 641 assert_file_not_exist 'tmp/mvdest' 642 end 643 644 def test_ln 645 TARGETS.each do |fname| 646 ln fname, 'tmp/lndest' 647 assert_same_file fname, 'tmp/lndest' 648 File.unlink 'tmp/lndest' 649 end 650 651 ln TARGETS, 'tmp' 652 TARGETS.each do |fname| 653 assert_same_file fname, 'tmp/' + File.basename(fname) 654 end 655 TARGETS.each do |fname| 656 File.unlink 'tmp/' + File.basename(fname) 657 end 658 659 # src==dest (1) same path 660 touch 'tmp/cptmp' 661 assert_raise(Errno::EEXIST) { 662 ln 'tmp/cptmp', 'tmp/cptmp' 663 } 664 end if have_hardlink? 665 666 def test_ln_symlink 667 touch 'tmp/cptmp' 668 # src==dest (2) symlink and its target 669 File.symlink 'cptmp', 'tmp/symlink' 670 assert_raise(Errno::EEXIST) { 671 ln 'tmp/cptmp', 'tmp/symlink' # normal file -> symlink 672 } 673 assert_raise(Errno::EEXIST) { 674 ln 'tmp/symlink', 'tmp/cptmp' # symlink -> normal file 675 } 676 # src==dest (3) looped symlink 677 File.symlink 'cptmp_symlink', 'tmp/cptmp_symlink' 678 begin 679 ln 'tmp/cptmp_symlink', 'tmp/cptmp_symlink' 680 rescue => err 681 assert_kind_of SystemCallError, err 682 end 683 end if have_symlink? 684 685 def test_ln_pathname 686 # pathname 687 touch 'tmp/lntmp' 688 assert_nothing_raised { 689 ln Pathname.new('tmp/lntmp'), 'tmp/lndesttmp1' 690 ln 'tmp/lntmp', Pathname.new('tmp/lndesttmp2') 691 ln Pathname.new('tmp/lntmp'), Pathname.new('tmp/lndesttmp3') 692 } 693 end if have_hardlink? 694 695 def test_ln_s 696 check_singleton :ln_s 697 698 TARGETS.each do |fname| 699 ln_s fname, 'tmp/lnsdest' 700 assert FileTest.symlink?('tmp/lnsdest'), 'not symlink' 701 assert_equal fname, File.readlink('tmp/lnsdest') 702 rm_f 'tmp/lnsdest' 703 end 704 assert_nothing_raised { 705 ln_s 'symlink', 'tmp/symlink' 706 } 707 assert_symlink 'tmp/symlink' 708 709 # pathname 710 touch 'tmp/lnsdest' 711 assert_nothing_raised { 712 ln_s Pathname.new('lnsdest'), 'tmp/symlink_tmp1' 713 ln_s 'lnsdest', Pathname.new('tmp/symlink_tmp2') 714 ln_s Pathname.new('lnsdest'), Pathname.new('tmp/symlink_tmp3') 715 } 716 end if have_symlink? 717 718 def test_ln_sf 719 check_singleton :ln_sf 720 721 TARGETS.each do |fname| 722 ln_sf fname, 'tmp/lnsdest' 723 assert FileTest.symlink?('tmp/lnsdest'), 'not symlink' 724 assert_equal fname, File.readlink('tmp/lnsdest') 725 ln_sf fname, 'tmp/lnsdest' 726 ln_sf fname, 'tmp/lnsdest' 727 end 728 assert_nothing_raised { 729 ln_sf 'symlink', 'tmp/symlink' 730 } 731 732 # pathname 733 touch 'tmp/lns_dest' 734 assert_nothing_raised { 735 ln_sf Pathname.new('lns_dest'), 'tmp/symlink_tmp1' 736 ln_sf 'lns_dest', Pathname.new('tmp/symlink_tmp2') 737 ln_sf Pathname.new('lns_dest'), Pathname.new('tmp/symlink_tmp3') 738 } 739 end if have_symlink? 740 741 def test_mkdir 742 check_singleton :mkdir 743 744 my_rm_rf 'tmpdatadir' 745 mkdir 'tmpdatadir' 746 assert_directory 'tmpdatadir' 747 Dir.rmdir 'tmpdatadir' 748 749 mkdir 'tmpdatadir/' 750 assert_directory 'tmpdatadir' 751 Dir.rmdir 'tmpdatadir' 752 753 mkdir 'tmp/mkdirdest' 754 assert_directory 'tmp/mkdirdest' 755 Dir.rmdir 'tmp/mkdirdest' 756 757 mkdir 'tmp/tmp', :mode => 0700 758 assert_directory 'tmp/tmp' 759 assert_equal 0700, (File.stat('tmp/tmp').mode & 0777) if have_file_perm? 760 Dir.rmdir 'tmp/tmp' 761 end 762 763 def test_mkdir_file_perm 764 mkdir 'tmp/tmp', :mode => 07777 765 assert_directory 'tmp/tmp' 766 assert_equal 07777, (File.stat('tmp/tmp').mode & 07777) 767 Dir.rmdir 'tmp/tmp' 768 end if have_file_perm? 769 770 def test_mkdir_lf_in_path 771 mkdir "tmp-first-line\ntmp-second-line" 772 assert_directory "tmp-first-line\ntmp-second-line" 773 Dir.rmdir "tmp-first-line\ntmp-second-line" 774 end if lf_in_path_allowed? 775 776 def test_mkdir_pathname 777 # pathname 778 assert_nothing_raised { 779 mkdir Pathname.new('tmp/tmpdirtmp') 780 mkdir [Pathname.new('tmp/tmpdirtmp2'), Pathname.new('tmp/tmpdirtmp3')] 781 } 782 end 783 784 def test_mkdir_p 785 check_singleton :mkdir_p 786 787 dirs = %w( 788 tmpdir/dir/ 789 tmpdir/dir/./ 790 tmpdir/dir/./.././dir/ 791 tmpdir/a 792 tmpdir/a/ 793 tmpdir/a/b 794 tmpdir/a/b/ 795 tmpdir/a/b/c/ 796 tmpdir/a/b/c 797 tmpdir/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a 798 tmpdir/a/a 799 ) 800 my_rm_rf 'tmpdir' 801 dirs.each do |d| 802 mkdir_p d 803 assert_directory d 804 assert_file_not_exist "#{d}/a" 805 assert_file_not_exist "#{d}/b" 806 assert_file_not_exist "#{d}/c" 807 my_rm_rf 'tmpdir' 808 end 809 dirs.each do |d| 810 mkdir_p d 811 assert_directory d 812 end 813 rm_rf 'tmpdir' 814 dirs.each do |d| 815 mkdir_p "#{Dir.pwd}/#{d}" 816 assert_directory d 817 end 818 rm_rf 'tmpdir' 819 820 mkdir_p 'tmp/tmp/tmp', :mode => 0700 821 assert_directory 'tmp/tmp' 822 assert_directory 'tmp/tmp/tmp' 823 assert_equal 0700, (File.stat('tmp/tmp').mode & 0777) if have_file_perm? 824 assert_equal 0700, (File.stat('tmp/tmp/tmp').mode & 0777) if have_file_perm? 825 rm_rf 'tmp/tmp' 826 827 mkdir_p 'tmp/tmp', :mode => 0 828 assert_directory 'tmp/tmp' 829 assert_equal 0, (File.stat('tmp/tmp').mode & 0777) if have_file_perm? 830 # DO NOT USE rm_rf here. 831 # (rm(1) try to chdir to parent directory, it fails to remove directory.) 832 Dir.rmdir 'tmp/tmp' 833 Dir.rmdir 'tmp' 834 end 835 836 def test_mkdir_p_file_perm 837 mkdir_p 'tmp/tmp/tmp', :mode => 07777 838 assert_directory 'tmp/tmp/tmp' 839 assert_equal 07777, (File.stat('tmp/tmp/tmp').mode & 07777) 840 Dir.rmdir 'tmp/tmp/tmp' 841 Dir.rmdir 'tmp/tmp' 842 end if have_file_perm? 843 844 def test_mkdir_p_pathname 845 # pathname 846 assert_nothing_raised { 847 mkdir_p Pathname.new('tmp/tmp/tmp') 848 } 849 end 850 851 def test_install 852 check_singleton :install 853 854 File.open('tmp/aaa', 'w') {|f| f.puts 'aaa' } 855 File.open('tmp/bbb', 'w') {|f| f.puts 'bbb' } 856 install 'tmp/aaa', 'tmp/bbb', :mode => 0600 857 assert_equal "aaa\n", File.read('tmp/bbb') 858 assert_equal 0600, (File.stat('tmp/bbb').mode & 0777) if have_file_perm? 859 860 t = File.mtime('tmp/bbb') 861 install 'tmp/aaa', 'tmp/bbb' 862 assert_equal "aaa\n", File.read('tmp/bbb') 863 assert_equal 0600, (File.stat('tmp/bbb').mode & 0777) if have_file_perm? 864 assert_equal_time t, File.mtime('tmp/bbb') 865 866 File.unlink 'tmp/aaa' 867 File.unlink 'tmp/bbb' 868 869 # src==dest (1) same path 870 touch 'tmp/cptmp' 871 assert_raise(ArgumentError) { 872 install 'tmp/cptmp', 'tmp/cptmp' 873 } 874 end 875 876 def test_install_symlink 877 touch 'tmp/cptmp' 878 # src==dest (2) symlink and its target 879 File.symlink 'cptmp', 'tmp/cptmp_symlink' 880 assert_raise(ArgumentError) { 881 install 'tmp/cptmp', 'tmp/cptmp_symlink' 882 } 883 assert_raise(ArgumentError) { 884 install 'tmp/cptmp_symlink', 'tmp/cptmp' 885 } 886 # src==dest (3) looped symlink 887 File.symlink 'symlink', 'tmp/symlink' 888 assert_raise(Errno::ELOOP) { 889 # File#install invokes open(2), always ELOOP must be raised 890 install 'tmp/symlink', 'tmp/symlink' 891 } 892 end if have_symlink? 893 894 def test_install_pathname 895 # pathname 896 assert_nothing_raised { 897 rm_f 'tmp/a'; touch 'tmp/a' 898 install 'tmp/a', Pathname.new('tmp/b') 899 rm_f 'tmp/a'; touch 'tmp/a' 900 install Pathname.new('tmp/a'), 'tmp/b' 901 rm_f 'tmp/a'; touch 'tmp/a' 902 install Pathname.new('tmp/a'), Pathname.new('tmp/b') 903 rm_f 'tmp/a' 904 touch 'tmp/a' 905 touch 'tmp/b' 906 mkdir 'tmp/dest' 907 install [Pathname.new('tmp/a'), Pathname.new('tmp/b')], 'tmp/dest' 908 my_rm_rf 'tmp/dest' 909 mkdir 'tmp/dest' 910 install [Pathname.new('tmp/a'), Pathname.new('tmp/b')], Pathname.new('tmp/dest') 911 } 912 end 913 914 def test_chmod 915 check_singleton :chmod 916 917 touch 'tmp/a' 918 chmod 0700, 'tmp/a' 919 assert_equal 0700, File.stat('tmp/a').mode & 0777 920 chmod 0500, 'tmp/a' 921 assert_equal 0500, File.stat('tmp/a').mode & 0777 922 end if have_file_perm? 923 924 def test_chmod_symbol_mode 925 check_singleton :chmod 926 927 touch 'tmp/a' 928 chmod "u=wrx,g=,o=", 'tmp/a' 929 assert_equal 0700, File.stat('tmp/a').mode & 0777 930 chmod "u=rx,go=", 'tmp/a' 931 assert_equal 0500, File.stat('tmp/a').mode & 0777 932 chmod "+wrx", 'tmp/a' 933 assert_equal 0777, File.stat('tmp/a').mode & 0777 934 chmod "u+s,o=s", 'tmp/a' 935 assert_equal 04770, File.stat('tmp/a').mode & 07777 936 chmod "u-w,go-wrx", 'tmp/a' 937 assert_equal 04500, File.stat('tmp/a').mode & 07777 938 chmod "+s", 'tmp/a' 939 assert_equal 06500, File.stat('tmp/a').mode & 07777 940 941 # FreeBSD ufs and tmpfs don't allow to change sticky bit against 942 # regular file. It's slightly strange. Anyway it's no effect bit. 943 # see /usr/src/sys/ufs/ufs/ufs_chmod() 944 # NetBSD, OpenBSD and Solaris also denies it. 945 if /freebsd|netbsd|openbsd|solaris/ !~ RUBY_PLATFORM 946 chmod "u+t,o+t", 'tmp/a' 947 assert_equal 07500, File.stat('tmp/a').mode & 07777 948 chmod "a-t,a-s", 'tmp/a' 949 assert_equal 0500, File.stat('tmp/a').mode & 07777 950 end 951 952 end if have_file_perm? 953 954 955 def test_chmod_R 956 check_singleton :chmod_R 957 958 mkdir_p 'tmp/dir/dir' 959 touch %w( tmp/dir/file tmp/dir/dir/file ) 960 chmod_R 0700, 'tmp/dir' 961 assert_equal 0700, File.stat('tmp/dir').mode & 0777 962 assert_equal 0700, File.stat('tmp/dir/file').mode & 0777 963 assert_equal 0700, File.stat('tmp/dir/dir').mode & 0777 964 assert_equal 0700, File.stat('tmp/dir/dir/file').mode & 0777 965 chmod_R 0500, 'tmp/dir' 966 assert_equal 0500, File.stat('tmp/dir').mode & 0777 967 assert_equal 0500, File.stat('tmp/dir/file').mode & 0777 968 assert_equal 0500, File.stat('tmp/dir/dir').mode & 0777 969 assert_equal 0500, File.stat('tmp/dir/dir/file').mode & 0777 970 chmod_R 0700, 'tmp/dir' # to remove 971 end if have_file_perm? 972 973 def test_chmod_symbol_mode_R 974 check_singleton :chmod_R 975 976 mkdir_p 'tmp/dir/dir' 977 touch %w( tmp/dir/file tmp/dir/dir/file ) 978 chmod_R "u=wrx,g=,o=", 'tmp/dir' 979 assert_equal 0700, File.stat('tmp/dir').mode & 0777 980 assert_equal 0700, File.stat('tmp/dir/file').mode & 0777 981 assert_equal 0700, File.stat('tmp/dir/dir').mode & 0777 982 assert_equal 0700, File.stat('tmp/dir/dir/file').mode & 0777 983 chmod_R "u=xr,g+X,o=", 'tmp/dir' 984 assert_equal 0510, File.stat('tmp/dir').mode & 0777 985 assert_equal 0500, File.stat('tmp/dir/file').mode & 0777 986 assert_equal 0510, File.stat('tmp/dir/dir').mode & 0777 987 assert_equal 0500, File.stat('tmp/dir/dir/file').mode & 0777 988 chmod_R 0700, 'tmp/dir' # to remove 989 end if have_file_perm? 990 991 def test_chmod_verbose 992 check_singleton :chmod 993 994 stderr_back = $stderr 995 read, $stderr = IO.pipe 996 th = Thread.new { read.read } 997 998 touch 'tmp/a' 999 chmod 0700, 'tmp/a', verbose: true 1000 assert_equal 0700, File.stat('tmp/a').mode & 0777 1001 chmod 0500, 'tmp/a', verbose: true 1002 assert_equal 0500, File.stat('tmp/a').mode & 0777 1003 1004 $stderr.close 1005 lines = th.value.lines.map {|l| l.chomp } 1006 assert_equal(["chmod 700 tmp/a", "chmod 500 tmp/a"], lines) 1007 ensure 1008 $stderr = stderr_back if stderr_back 1009 end if have_file_perm? 1010 1011 def test_s_chmod_verbose 1012 output_back = FileUtils.instance_variable_get(:@fileutils_output) 1013 read, write = IO.pipe 1014 FileUtils.instance_variable_set(:@fileutils_output, write) 1015 th = Thread.new { read.read } 1016 1017 touch 'tmp/a' 1018 FileUtils.chmod 0700, 'tmp/a', verbose: true 1019 assert_equal 0700, File.stat('tmp/a').mode & 0777 1020 1021 write.close 1022 lines = th.value.lines.map {|l| l.chomp } 1023 assert_equal(["chmod 700 tmp/a"], lines) 1024 ensure 1025 FileUtils.instance_variable_set(:@fileutils_output, output_back) if output_back 1026 end if have_file_perm? 1027 1028 # FIXME: How can I test this method? 1029 def test_chown 1030 check_singleton :chown 1031 end if have_file_perm? 1032 1033 # FIXME: How can I test this method? 1034 def test_chown_R 1035 check_singleton :chown_R 1036 end if have_file_perm? 1037 1038 def test_copy_entry 1039 check_singleton :copy_entry 1040 1041 each_srcdest do |srcpath, destpath| 1042 copy_entry srcpath, destpath 1043 assert_same_file srcpath, destpath 1044 assert_equal File.stat(srcpath).ftype, File.stat(destpath).ftype 1045 end 1046 end 1047 1048 def test_copy_entry_symlink 1049 # root is a symlink 1050 File.symlink 'somewhere', 'tmp/symsrc' 1051 copy_entry 'tmp/symsrc', 'tmp/symdest' 1052 assert_symlink 'tmp/symdest' 1053 assert_equal 'somewhere', File.readlink('tmp/symdest') 1054 1055 # content is a symlink 1056 mkdir 'tmp/dir' 1057 File.symlink 'somewhere', 'tmp/dir/sym' 1058 copy_entry 'tmp/dir', 'tmp/dirdest' 1059 assert_directory 'tmp/dirdest' 1060 assert_not_symlink 'tmp/dirdest' 1061 assert_symlink 'tmp/dirdest/sym' 1062 assert_equal 'somewhere', File.readlink('tmp/dirdest/sym') 1063 end if have_symlink? 1064 1065 def test_copy_file 1066 check_singleton :copy_file 1067 1068 each_srcdest do |srcpath, destpath| 1069 copy_file srcpath, destpath 1070 assert_same_file srcpath, destpath 1071 end 1072 end 1073 1074 def test_copy_stream 1075 check_singleton :copy_stream 1076 # IO 1077 each_srcdest do |srcpath, destpath| 1078 File.open(srcpath, 'rb') {|src| 1079 File.open(destpath, 'wb') {|dest| 1080 copy_stream src, dest 1081 } 1082 } 1083 assert_same_file srcpath, destpath 1084 end 1085 end 1086 1087 def test_copy_stream_duck 1088 check_singleton :copy_stream 1089 # duck typing test [ruby-dev:25369] 1090 each_srcdest do |srcpath, destpath| 1091 File.open(srcpath, 'rb') {|src| 1092 File.open(destpath, 'wb') {|dest| 1093 copy_stream Stream.new(src), Stream.new(dest) 1094 } 1095 } 1096 assert_same_file srcpath, destpath 1097 end 1098 end 1099 1100 def test_remove_file 1101 check_singleton :remove_file 1102 File.open('data/tmp', 'w') {|f| f.puts 'dummy' } 1103 remove_file 'data/tmp' 1104 assert_file_not_exist 'data/tmp' 1105 end 1106 1107 def test_remove_file_file_perm 1108 File.open('data/tmp', 'w') {|f| f.puts 'dummy' } 1109 File.chmod 0, 'data/tmp' 1110 remove_file 'data/tmp' 1111 assert_file_not_exist 'data/tmp' 1112 end if have_file_perm? 1113 1114 def test_remove_dir 1115 check_singleton :remove_dir 1116 Dir.mkdir 'data/tmpdir' 1117 File.open('data/tmpdir/a', 'w') {|f| f.puts 'dummy' } 1118 remove_dir 'data/tmpdir' 1119 assert_file_not_exist 'data/tmpdir' 1120 end 1121 1122 def test_remove_dir_file_perm 1123 Dir.mkdir 'data/tmpdir' 1124 File.chmod 0555, 'data/tmpdir' 1125 remove_dir 'data/tmpdir' 1126 assert_file_not_exist 'data/tmpdir' 1127 end if have_file_perm? 1128 1129 def test_compare_file 1130 check_singleton :compare_file 1131 # FIXME 1132 end 1133 1134 def test_compare_stream 1135 check_singleton :compare_stream 1136 # FIXME 1137 end 1138 1139 class Stream 1140 def initialize(f) 1141 @f = f 1142 end 1143 1144 def read(*args) 1145 @f.read(*args) 1146 end 1147 1148 def write(str) 1149 @f.write str 1150 end 1151 end 1152 1153 def test_uptodate? 1154 check_singleton :uptodate? 1155 prepare_time_data 1156 Dir.chdir('data') { 1157 assert( uptodate?('newest', %w(old newer notexist)) ) 1158 assert( ! uptodate?('newer', %w(old newest notexist)) ) 1159 assert( ! uptodate?('notexist', %w(old newest newer)) ) 1160 } 1161 1162 # pathname 1163 touch 'tmp/a' 1164 touch 'tmp/b' 1165 touch 'tmp/c' 1166 assert_nothing_raised { 1167 uptodate? Pathname.new('tmp/a'), ['tmp/b', 'tmp/c'] 1168 uptodate? 'tmp/a', [Pathname.new('tmp/b'), 'tmp/c'] 1169 uptodate? 'tmp/a', ['tmp/b', Pathname.new('tmp/c')] 1170 uptodate? Pathname.new('tmp/a'), [Pathname.new('tmp/b'), Pathname.new('tmp/c')] 1171 } 1172 # [Bug #6708] [ruby-core:46256] 1173 assert_raises_with_message(ArgumentError, "wrong number of arguments (3 for 2)") { 1174 uptodate?('new',['old', 'oldest'], {}) 1175 } 1176 end 1177 1178 def assert_raises_with_message(klass, message) 1179 begin 1180 yield 1181 flunk("Expected Exception #{klass} didn't raise") 1182 rescue klass => ex 1183 if message.kind_of? String 1184 flag = !!(ex.message == message) 1185 assert(flag, "Expected Exception(#{klass}) was raised, but the message doesn't match") 1186 elsif message.kind_of? Regexp 1187 flag = !!(ex.message =~ message) 1188 assert(flag, "Expected Exception(#{klass}) was raised, but the message doesn't match") 1189 else 1190 raise 1191 end 1192 end 1193 end 1194 private :assert_raises_with_message 1195 1196 def test_cd 1197 check_singleton :cd 1198 end 1199 1200 def test_chdir 1201 check_singleton :chdir 1202 end 1203 1204 def test_getwd 1205 check_singleton :getwd 1206 end 1207 1208 def test_identical? 1209 check_singleton :identical? 1210 end 1211 1212 def test_link 1213 check_singleton :link 1214 end 1215 1216 def test_makedirs 1217 check_singleton :makedirs 1218 end 1219 1220 def test_mkpath 1221 check_singleton :mkpath 1222 end 1223 1224 def test_move 1225 check_singleton :move 1226 end 1227 1228 def test_rm_rf 1229 check_singleton :rm_rf 1230 end 1231 1232 def test_rmdir 1233 check_singleton :rmdir 1234 end 1235 1236 def test_rmtree 1237 check_singleton :rmtree 1238 end 1239 1240 def test_safe_unlink 1241 check_singleton :safe_unlink 1242 end 1243 1244 def test_symlink 1245 check_singleton :symlink 1246 end 1247 1248 def test_touch 1249 check_singleton :touch 1250 end 1251 1252 def test_collect_methods 1253 end 1254 1255 def test_commands 1256 end 1257 1258 def test_have_option? 1259 end 1260 1261 def test_options 1262 end 1263 1264 def test_options_of 1265 end 1266 1267end 1268