eZ components PHP Cross Reference Developer Tools

Source: /Archive/tests/tar/v7_tar_test.php - 1101 lines - 37151 bytes - Summary - Text - Print

   1  <?php
   2  /**
   3   * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
   4   * @license http://ez.no/licenses/new_bsd New BSD License
   5   * @filesource
   6   * @package Archive
   7   * @version 1.4.1
   8   * @subpackage Tests
   9   */
  10  
  11  require_once( dirname( __FILE__ ) . "/../archive_test_case.php" );
  12  
  13  /**
  14   * @package Archive
  15   * @version 1.4.1
  16   * @subpackage Tests
  17   */
  18  class ezcArchiveV7TarTest extends ezcArchiveTestCase
  19  {
  20      protected $canWrite = true;
  21  
  22      protected $archive;
  23      protected $complexArchive;
  24  
  25      protected $file;
  26      protected $complexFile;
  27      protected $tarFormat;
  28      protected $tarMimeFormat;
  29      protected $usersGid;
  30  
  31      public function createTempFile( $file )
  32      {
  33          $original = dirname(__FILE__) . "/../data/$file";
  34  
  35          $tmpFile = $this->getTempDir() . "/$file";
  36          copy( $original, $tmpFile );
  37  
  38          return $tmpFile;
  39      }
  40  
  41      protected function setUp()
  42      {
  43          date_default_timezone_set( "UTC" );
  44          $this->tarFormat = "v7";
  45          $this->tarMimeFormat = ezcArchive::TAR_V7;
  46  
  47          $this->createTempDir( "ezcArchive_" );
  48  
  49          $this->file = $this->createTempFile( "tar_v7_2_textfiles.tar" );
  50          $blockFile = new ezcArchiveBlockFile( $this->file );
  51          $this->archive = new ezcArchiveV7Tar( $blockFile );
  52          unset( $blockFile );
  53  
  54          $this->complexFile = $this->createTempFile( "tar_v7_file_dir_symlink_link.tar" );
  55          $blockFile = new ezcArchiveBlockFile( $this->complexFile );
  56          $this->complexArchive = new ezcArchiveV7Tar( $blockFile );
  57          unset( $blockFile );
  58  
  59          $this->setUsersGid();
  60      }
  61  
  62      protected function setUsersGid()
  63      {
  64          // figure out the GID for "users" for tests
  65          $this->usersGid = 1000; // default
  66          if ( posix_geteuid() === 0 && function_exists( 'posix_getgrnam' ) )
  67          {
  68              $info = posix_getgrnam( 'users' );
  69              $this->usersGid = $info['gid'];
  70          }
  71      }
  72  
  73      protected function tearDown()
  74      {
  75          unset( $this->archive );
  76          unset( $this->complexArchive );
  77          $this->removeTempDir();
  78      }
  79  
  80      protected function isWindows()
  81      {
  82          return ( substr( php_uname( 's' ), 0, 7 ) == 'Windows' ) ? true : false;
  83      }
  84  
  85      // FIXME
  86      // Move method to the archiveTest.
  87      /*
  88      public function testGetEntryFromFile()
  89      {
  90          $this->archive->extractCurrent( $this->getTempDir() );
  91          $entry = ezcArchive::getEntryFromFile( $this->getTempDir() . "/file1.txt" );
  92  
  93          $this->assertEquals( $this->getTempDir() . "/file1.txt", $entry->getPath() );
  94          $this->assertTrue( $entry->isFile() );
  95          $this->assertFalse( $entry->isDirectory() );
  96          // Probably okay.
  97      }
  98  
  99      // FIXME
 100      // Move method to the archiveTest.
 101      public function testGetEntryFromFilesWithHardlink()
 102      {
 103          $dir = $this->getTempDir();
 104          $this->complexArchive->seek( 4 ); // File.
 105          $this->complexArchive->extractCurrent( $dir );
 106  
 107          $this->complexArchive->seek(8); // Hardlink
 108          $this->complexArchive->extractCurrent( $dir );
 109  
 110          $entries = ezcArchive::getEntryFromFile( array( $dir . "/files/bla/file3.txt", $dir . "/files/file4.txt" ) );
 111  
 112          $this->assertEquals( 2, sizeof( $entries ), "Sizeof the entries array doesn't match." );
 113          $this->assertFalse( $entries[0]->isLink() );
 114          $this->assertTrue( $entries[1]->isLink() );
 115  
 116          $this->assertEquals( "$dir/files/bla/file3.txt", $entries[1]->getLink() );
 117      }
 118      */
 119  
 120      // FIXME
 121      // Move method to the archiveTest.
 122      /*
 123      public function testRemovePrefix()
 124      {
 125          $dir = $this->getTempDir();
 126          $total = $dir . "/lisa/ekdahl/";
 127  
 128          $without = ezcArchive::removePrefix( $total, $dir );
 129          $this->assertEquals( "lisa/ekdahl/", $without );
 130      }
 131      */
 132  
 133      public function testOpenArchive()
 134      {
 135          $entry = $this->archive->current();
 136          $this->assertEquals( "file1.txt", $entry->getPath() );
 137      }
 138  
 139      public function testEmptyArchive()
 140      {
 141          $file = $this->getTempDir() . "/file_does_not_exist.tar";
 142          $blockFile = new ezcArchiveBlockFile( $file, true );
 143          $archive = new ezcArchiveV7Tar( $blockFile );
 144  
 145          $this->assertFalse( $archive->current(), "Archive should be empty, so no file info available" );
 146          $this->assertFalse( $archive->valid(), "Archive should be empty, so no  file info available" );
 147          $this->assertFalse( $archive->next(), "Archive should be empty, so no file info available" );
 148          $this->assertFalse( $archive->next(), "Archive should be empty, so no file info available" );
 149  
 150          unset( $blockFile );
 151          unset( $archive );
 152      }
 153  
 154      public function testIteratorOperations()
 155      {
 156          $entry = $this->archive->current();
 157          $entry = $this->archive->current();
 158          $this->assertEquals( "file1.txt", $entry->getPath() );
 159          $this->assertTrue( $this->archive->valid(), "Expected a valid archive position." );
 160  
 161          $this->archive->rewind();
 162          $entry = $this->archive->current();
 163          $this->assertEquals( "file1.txt", $entry->getPath() );
 164          $this->assertEquals( 0, $this->archive->key() );
 165          $this->assertTrue( $this->archive->valid(), "Expected a valid archive position." );
 166  
 167          $this->assertTrue( $this->archive->next() !== false );
 168          $entry = $this->archive->current();
 169          $this->assertEquals( "file2.txt", $entry->getPath() );
 170          $this->assertEquals( 1, $this->archive->key() );
 171          $this->assertTrue( $this->archive->valid(), "Expected a valid archive position." );
 172  
 173          $this->assertFalse( $this->archive->next() );
 174          $this->assertFalse( $this->archive->current() );
 175          $this->assertFalse( $this->archive->valid() );
 176          $this->assertFalse( $this->archive->key() );
 177  
 178          $this->assertFalse( $this->archive->next() );
 179          $this->assertFalse( $this->archive->next() );
 180      }
 181  
 182      public function testForEaching()
 183      {
 184          for ( $i = 0; $i < 2; $i++ )
 185          {
 186              $loopNumber = 0;
 187              foreach ( $this->archive as $entryNumber => $entry )
 188              {
 189                  if ( $loopNumber == 0 )
 190                  {
 191                      $this->assertEquals( "file1.txt", $entry->getPath() );
 192                      $this->assertEquals( 0, $entryNumber );
 193                  }
 194                  else if ( $loopNumber == 1 )
 195                  {
 196                      $this->assertEquals( "file2.txt", $entry->getPath() );
 197                      $this->assertEquals( 1, $entryNumber );
 198                  }
 199                  else
 200                  {
 201                      $this->fail( "Didn't expect another entry in the archive" );
 202                  }
 203  
 204                  $loopNumber++;
 205              }
 206          }
 207      }
 208  
 209      public function testExtractCurrent()
 210      {
 211          $targetDir = $this->getTempDir() . "/";
 212          $this->archive->extractCurrent( $targetDir );
 213  
 214          $file1 = $this->getTempDir() . "/file1.txt";
 215          $this->assertEquals( "Hello world.\nThe first file.\n", file_get_contents( $file1 ) );
 216  
 217          // Remove the file, and extract again.
 218          unlink( $file1 );
 219  
 220          // Check whether the file is really removed (paranoia?).
 221          $fp = @fopen( $file1, "r" );
 222          if ( $fp )
 223          {
 224              $this->assertFail( "No noo nooo. The file shouldn't be here." );
 225          }
 226  
 227          $this->archive->extractCurrent( $targetDir );
 228          $this->assertEquals( "Hello world.\nThe first file.\n", file_get_contents( $file1 ) );
 229  
 230          // Move on.
 231          $entry = $this->archive->next();
 232          $this->assertTrue( $this->archive->valid(), "Second file is expected here." );
 233  
 234          $this->archive->extractCurrent( $targetDir );
 235          $file2 = $this->getTempDir() . "/file2.txt";
 236          $this->assertEquals( "Hello world.\nThe second file.\n", file_get_contents( $file2 ) );
 237  
 238          $this->assertFalse( $this->archive->next(), "No more files in the archive" );
 239      }
 240  
 241      public function testExtractCurrentOverwriteFile()
 242      {
 243          // Normally it will overwrite the file, if possible.
 244          $targetDir = $this->getTempDir() . "/";
 245          $this->archive->extractCurrent( $targetDir );
 246  
 247          $file1 = $this->getTempDir() . "/file1.txt";
 248          $this->assertEquals( "Hello world.\nThe first file.\n", file_get_contents( $file1 ) );
 249  
 250          $fp = @fopen( $file1, "w" );
 251          fwrite( $fp, "Garbage" );
 252          fclose( $fp );
 253  
 254          $this->assertEquals( "Garbage", file_get_contents( $file1 ) );
 255  
 256          $this->archive->extractCurrent( $targetDir );
 257          $this->assertEquals( "Hello world.\nThe first file.\n", file_get_contents( $file1 ) );
 258      }
 259  
 260      public function testExtractCurrentKeepExistingFile()
 261      {
 262          // Normally it will overwrite the file, if possible.
 263          $targetDir = $this->getTempDir() . "/";
 264          $this->archive->extractCurrent( $targetDir, true );
 265  
 266          $file1 = $this->getTempDir() . "/file1.txt";
 267          $this->assertEquals( "Hello world.\nThe first file.\n", file_get_contents( $file1 ) );
 268  
 269          $fp = @fopen( $file1, "w" );
 270          fwrite( $fp, "Garbage" );
 271          fclose( $fp );
 272  
 273          $this->assertEquals( "Garbage", file_get_contents( $file1 ) );
 274  
 275          $this->archive->extractCurrent( $targetDir, true );
 276          $this->assertEquals( "Garbage", file_get_contents( $file1 ) );
 277      }
 278  
 279      public function testExtractComplexArchive()
 280      {
 281          $dir =  $this->getTempDir();
 282          mkdir( $dir . "/php" );
 283          mkdir( $dir . "/gnu" );
 284  
 285          foreach ( $this->complexArchive as $entry )
 286          {
 287              $this->complexArchive->extractCurrent( $dir ."/php" );
 288          }
 289  
 290          exec( "tar -xf " . $this->complexFile . " -C $dir/gnu" );
 291  
 292          // make corrections that emulate symlink in Windows
 293          if ( $this->isWindows() )
 294          {
 295              exec( 'attrib -r ' . $dir . '\gnu\files\file3.txt.lnk' );
 296              exec( 'del "' . $dir . '\gnu\files\file3.txt.lnk"' );
 297              exec( 'copy "' . $dir . '\gnu\files\bla\file3.txt" "' . $dir . '\gnu\files\file3.txt"' );
 298          }
 299          $this->compareDirectories( "$dir/gnu", "$dir/php" );
 300  
 301          $stat = stat( "$dir/php/files/bla/file3.txt" );
 302          $this->assertEquals( 0644, $stat['mode'] & 07777 );
 303          $this->assertEquals( 1000, $stat['uid'] );
 304          $this->assertEquals( $this->usersGid, $stat['gid'] );
 305      }
 306  
 307      public function testExtractComplexArchiveModPerms()
 308      {
 309          $options = new ezcArchiveOptions;
 310          $options->extractCallback = new testExtractCallback;
 311  
 312          $this->complexArchive->setOptions( $options );
 313          $dir =  $this->getTempDir();
 314          mkdir( $dir . "/php" );
 315          mkdir( $dir . "/gnu" );
 316  
 317          foreach ( $this->complexArchive as $entry )
 318          {
 319              $this->complexArchive->extractCurrent( $dir ."/php" );
 320          }
 321  
 322          exec( "tar -xf " . $this->complexFile . " -C $dir/gnu" );
 323  
 324          // make corrections that emulate symlink in Windows
 325          if ( $this->isWindows() )
 326          {
 327              exec( 'attrib -r ' . $dir . '\gnu\files\file3.txt.lnk' );
 328              exec( 'del "' . $dir . '\gnu\files\file3.txt.lnk"' );
 329              exec( 'copy "' . $dir . '\gnu\files\bla\file3.txt" "' . $dir . '\gnu\files\file3.txt"' );
 330          }
 331          $this->compareDirectories( "$dir/gnu", "$dir/php" );
 332          $options->extractCallback = null;
 333  
 334          $stat = stat( "$dir/php/files/bla/file3.txt" );
 335          $this->assertEquals( 0600, $stat['mode'] & 07777 );
 336          $this->assertEquals( 1000, $stat['uid'] );
 337          $this->assertEquals( $this->usersGid, $stat['gid'] );
 338  
 339          $stat = stat( "$dir/php/files/bla" );
 340          $this->assertEquals( 0700, $stat['mode'] & 07777 );
 341          $this->assertEquals( 1000, $stat['uid'] );
 342          $this->assertEquals( $this->usersGid, $stat['gid'] );
 343      }
 344  
 345      public function testInvalidChecksum()
 346      {
 347          // Correct checksum.
 348          $ustarFile = new ezcArchiveBlockFile( dirname( __FILE__) . "/../data/tar_v7_2_textfiles.tar" );
 349          $tar = new ezcArchiveV7Tar( $ustarFile );
 350  
 351          // Incorrect checksum.
 352          try
 353          {
 354              $ustarFile = new ezcArchiveBlockFile( dirname( __FILE__) . "/../data/tar_v7_invalid_checksum.tar" );
 355              $tar = new ezcArchiveV7Tar( $ustarFile );
 356              $tar->current();
 357  
 358              $this->fail("Expected the checksum to fail.");
 359          }
 360          catch ( ezcArchiveChecksumException $e )
 361          {
 362          }
 363  
 364          unset( $tar );
 365          unset( $ustarFile );
 366      }
 367  
 368      public function testSeekPositions()
 369      {
 370          $entry = $this->complexArchive->current();
 371          $this->assertEquals( "files/", $entry->getPath() );
 372  
 373          $this->complexArchive->seek( 2 ); // third file in archive.
 374          $entry = $this->complexArchive->current();
 375          $this->assertEquals( "files/bla/bin/", $entry->getPath() );
 376  
 377          $this->complexArchive->seek( 0 ); // first file in archive.
 378          $entry = $this->complexArchive->current();
 379          $this->assertEquals( "files/", $entry->getPath() );
 380  
 381          $this->complexArchive->seek( 6 );
 382          $entry = $this->complexArchive->current();
 383          $this->assertEquals( "files/file2.txt", $entry->getPath() );
 384  
 385          $this->complexArchive->seek( 8 );
 386          $entry = $this->complexArchive->current();
 387          $this->assertEquals( "files/file4.txt", $entry->getPath() );
 388  
 389          $this->complexArchive->seek( 9 );
 390          $this->assertFalse( $this->complexArchive->current() );
 391  
 392          $this->complexArchive->seek( 0 );
 393          $entry = $this->complexArchive->current();
 394          $this->assertEquals( "files/", $entry->getPath() );
 395  
 396          $this->complexArchive->seek( -1 );
 397          $this->assertFalse( $this->complexArchive->current() );
 398      }
 399  
 400      public function testSeekEndOfFile()
 401      {
 402          $this->complexArchive->seek( 0, SEEK_END ); // nineth and last file.
 403          $entry = $this->complexArchive->current();
 404          $this->assertEquals( "files/file4.txt", $entry->getPath() );
 405  
 406          $this->complexArchive->seek( -2, SEEK_END ); // seventh file
 407          $entry = $this->complexArchive->current();
 408          $this->assertEquals( "files/file2.txt", $entry->getPath() );
 409  
 410          $this->complexArchive->seek( -8, SEEK_END ); // first file
 411          $entry = $this->complexArchive->current();
 412          $this->assertEquals( "files/", $entry->getPath() );
 413  
 414          $this->complexArchive->seek( 1, SEEK_END );  // invalid
 415          $this->assertFalse( $this->complexArchive->current() );
 416  
 417          $this->complexArchive->seek( 0, SEEK_END ); // nineth and last file.
 418          $entry = $this->complexArchive->current();
 419          $this->assertEquals( "files/file4.txt", $entry->getPath() );
 420  
 421          $this->complexArchive->seek( -9, SEEK_END );  // invalid
 422          $this->assertFalse( $this->complexArchive->current() );
 423      }
 424  
 425      public function testSeekCur()
 426      {
 427          $entry = $this->complexArchive->current();
 428          $this->assertEquals( "files/", $entry->getPath() );
 429  
 430          $this->complexArchive->seek( 2, SEEK_CUR ); // third file in archive.
 431          $entry = $this->complexArchive->current();
 432          $this->assertEquals( "files/bla/bin/", $entry->getPath() );
 433  
 434          $this->complexArchive->seek( 0, SEEK_CUR ); // Third file in archive.
 435          $entry = $this->complexArchive->current();
 436          $this->assertEquals( "files/bla/bin/", $entry->getPath() );
 437  
 438          $this->complexArchive->seek( 4, SEEK_CUR ); // Seventh file in the archive.
 439          $entry = $this->complexArchive->current();
 440          $this->assertEquals( "files/file2.txt", $entry->getPath() );
 441  
 442          $this->complexArchive->seek( 2, SEEK_CUR );  // nineth and last.
 443          $entry = $this->complexArchive->current();
 444          $this->assertEquals( "files/file4.txt", $entry->getPath() );
 445  
 446          $this->complexArchive->seek( 1, SEEK_CUR );
 447          $this->assertFalse( $this->complexArchive->current() );
 448  
 449          $this->complexArchive->seek( 2 );
 450          $entry = $this->complexArchive->current();
 451          $this->assertEquals( "files/bla/bin/", $entry->getPath() );
 452  
 453          $this->complexArchive->seek( -2, SEEK_CUR ); // First file.
 454          $entry = $this->complexArchive->current();
 455          $this->assertEquals( "files/", $entry->getPath() );
 456  
 457          $this->complexArchive->seek( -1, SEEK_CUR );  // And invalid again.
 458          $this->assertFalse( $this->complexArchive->current() );
 459      }
 460  
 461      public function testExtractOneDirectory()
 462      {
 463          // The subdirectory should be created automatically.
 464          $this->complexArchive->seek( 1 );
 465          $targetDir = $this->getTempDir() ;
 466          $this->complexArchive->extractCurrent( $targetDir );
 467  
 468          $this->assertTrue( file_exists( $targetDir . "/files/bla/" ), "Cannot find the extracted directory." );
 469      }
 470  
 471      public function testExtractOneFile()
 472      {
 473          // The directory should be created automatically.
 474          $this->complexArchive->seek( 4 ); // 5th file.
 475          $targetDir = $this->getTempDir();
 476          $this->complexArchive->extractCurrent( $targetDir );
 477  
 478          $this->assertTrue( file_exists( $targetDir . "/files/bla/file3.txt" ), "Cannot find the extracted file." );
 479          $this->assertEquals( "Hello world.\nThe third file.\n", file_get_contents( $targetDir . "/files/bla/file3.txt" ) );
 480      }
 481  
 482      public function testExtractOneSymbolicLink()
 483      {
 484          // this test a bit different in Windows as symlinks
 485          // simulated by copying
 486          if ( $this->isWindows() )
 487          {
 488              // The directory should be created automatically.
 489              // There is both link and link target extracted
 490              // and there are both the same file.
 491              $targetDir = $this->getTempDir();
 492  
 493              // extract target
 494              $this->complexArchive->seek( 4 );
 495              $this->complexArchive->extractCurrent( $targetDir );
 496  
 497              // "extract" link i.e. copy target
 498              $this->complexArchive->seek( 7 );
 499              $this->complexArchive->extractCurrent( $targetDir );
 500          }
 501          else
 502          {
 503              // The directory should be created automatically.
 504              // The link points to an non existing file.
 505              $this->complexArchive->seek( 7 );
 506  
 507              $targetDir = $this->getTempDir();
 508  
 509              $this->complexArchive->extractCurrent( $targetDir );
 510          }
 511  
 512          $this->assertTrue( is_array ( lstat( $targetDir . "/files/file3.txt" ) ) );
 513      }
 514  
 515      public function testExtractOneHardLinkException()
 516      {
 517          // Should throw an exception.
 518          $this->complexArchive->seek( 8 );
 519          $targetDir = $this->getTempDir();
 520  
 521          try
 522          {
 523              $this->complexArchive->extractCurrent( $targetDir );
 524              $this->fail( "Expected an exception" );
 525          }
 526          catch ( ezcBaseFileNotFoundException $e )
 527          {
 528          }
 529      }
 530  
 531      public function testExtractOneHardLink()
 532      {
 533          $this->complexArchive->seek( 4 );
 534  
 535          $targetDir = $this->getTempDir();
 536  
 537          $this->complexArchive->extractCurrent( $targetDir );
 538  
 539          $this->complexArchive->seek( 8 );
 540          $this->complexArchive->extractCurrent( $targetDir );
 541  
 542          $this->assertTrue( file_exists( $targetDir . "/files/bla/file3.txt" ) );
 543          $this->assertTrue( file_exists( $targetDir . "/files/file4.txt" ) );
 544      }
 545  
 546      public function testExtractComplexArchiveOverwrite()
 547      {
 548          $dir =  $this->getTempDir();
 549          mkdir( $dir . "/php" );
 550          mkdir( $dir . "/gnu" );
 551  
 552          // Extract once
 553          foreach ( $this->complexArchive as $entry )
 554          {
 555              $this->complexArchive->extractCurrent( $dir ."/php" );
 556          }
 557  
 558          // Extract with gnu tar.
 559          exec( "tar -xf " . $this->complexFile . " -C $dir/gnu" );
 560  
 561          // Truncate file1.txt
 562          $fp = fopen( $dir ."/php/files/file1.txt", "r+w" );
 563          ftruncate( $fp, 0 );
 564          fclose( $fp );
 565  
 566          // Change link.
 567          unlink( $dir . "/php/files/file3.txt" );
 568  
 569          if ( $this->isWindows() )
 570          {
 571              copy( $dir . "/php/files/file4.txt", $dir . "/php/files/file3.txt" );
 572  
 573              // make corrections of gnu tar output
 574              // replace .lnk file with copy of target file
 575              exec( 'attrib -r ' . $dir . '\gnu\files\file3.txt.lnk' );
 576              exec( 'del "' . $dir . '\gnu\files\file3.txt.lnk"' );
 577              exec( 'copy "' . $dir . '\gnu\files\bla\file3.txt" "' . $dir . '\gnu\files\file3.txt"' );
 578          }
 579          else
 580          {
 581              symlink( "file4.txt", $dir . "/php/files/file3.txt" );
 582          }
 583  
 584          // Truncate file4.txt (and also files/bla/file3.txt.
 585          $fp = fopen( $dir . "/php/files/file4.txt", "r+w" );
 586          ftruncate( $fp, 0 );
 587          fclose( $fp );
 588  
 589          foreach ( $this->complexArchive as $entry )
 590          {
 591              $this->complexArchive->extractCurrent( $dir . "/php" );
 592          }
 593  
 594          $this->compareDirectories( "$dir/gnu", "$dir/php" );
 595      }
 596  
 597      public function testExtractComplexArchiveKeepExisting()
 598      {
 599          $dir =  $this->getTempDir();
 600          mkdir( $dir . "/php" );
 601          mkdir( $dir . "/gnu" );
 602  
 603          // Extract once
 604          foreach ( $this->complexArchive as $entry )
 605          {
 606              $this->complexArchive->extractCurrent( $dir ."/php" );
 607          }
 608  
 609          // Extract with gnu tar.
 610          exec( "tar -xf " . $this->complexFile . " -C $dir/gnu" );
 611  
 612          // Truncate file1.txt
 613          $fp = fopen( $dir . "/php/files/file1.txt", "r+w" );
 614          ftruncate( $fp, 0 );
 615          fclose( $fp );
 616  
 617          // Change link.
 618          unlink( $dir . "/php/files/file3.txt" );
 619  
 620          if ( $this->isWindows() )
 621          {
 622              copy( $dir . "/php/files/file4.txt", $dir . "/php/files/file3.txt" );
 623  
 624              // make corrections of gnu tar output
 625              // replace .lnk file with copy of target file
 626              exec( 'attrib -r ' . $dir . '\gnu\files\file3.txt.lnk' );
 627              exec( 'del "' . $dir . '\gnu\files\file3.txt.lnk"' );
 628              exec( 'copy "' . $dir . '\gnu\files\bla\file3.txt" "' . $dir . '\gnu\files\file3.txt"' );
 629          }
 630          else
 631          {
 632              symlink( "file4.txt", $dir."/php/files/file3.txt");
 633          }
 634  
 635          // Truncate file4.txt (and also files/bla/file3.txt.
 636          $fp = fopen( $dir . "/php/files/file4.txt", "r+w" );
 637          ftruncate( $fp, 0 );
 638          fclose( $fp );
 639  
 640          foreach ( $this->complexArchive as $entry )
 641          {
 642              $this->complexArchive->extractCurrent( $dir . "/php", true );
 643          }
 644  
 645          $this->assertEquals( "", file_get_contents( $dir . "/php/files/file1.txt" ) );
 646          $this->assertEquals( "", file_get_contents( $dir . "/php/files/file3.txt" ) );
 647          $this->assertEquals( "", file_get_contents( $dir . "/php/files/file4.txt" ) );
 648          $this->assertEquals( "", file_get_contents( $dir . "/php/files/bla/file3.txt" ) );
 649      }
 650  
 651      // Write methods.
 652  
 653      public function testTruncate()
 654      {
 655          if ( !$this->canWrite )
 656          {
 657              try
 658              {
 659                  $this->complexArchive->truncate();
 660                  $this->fail( "Cannot write exception expected" );
 661              }
 662              catch ( ezcBaseFilePermissionException $e )
 663              {
 664                  // Okay, some exception thrown.
 665              }
 666  
 667              return;
 668          }
 669  
 670          $this->complexArchive->truncate();
 671          $this->assertFalse( $this->complexArchive->valid(), "Truncated archive shouldn't contain any elements" );
 672  
 673          $this->complexArchive->seek( 0 );
 674          $this->assertFalse( $this->complexArchive->valid(), "Truncated archive shouldn't contain any elements" );
 675  
 676          $this->complexArchive->seek( 2 );
 677          $this->assertFalse( $this->complexArchive->valid(), "Truncated archive shouldn't contain any elements" );
 678      }
 679  
 680      public function testTruncatePart()
 681      {
 682          if ( !$this->canWrite )
 683          {
 684              return;
 685          }
 686  
 687          $this->complexArchive->truncate( 4 );
 688  
 689          // Without rewind.. should work since we truncated after our position.
 690          $entry = $this->complexArchive->current();
 691          $this->assertEquals( "files/", $entry->getPath() );
 692  
 693          $entry = $this->complexArchive->next();
 694          $this->assertEquals( "files/bla/", $entry->getPath() );
 695  
 696          $entry = $this->complexArchive->next();
 697          $this->assertEquals( "files/bla/bin/", $entry->getPath() );
 698  
 699          $entry = $this->complexArchive->next();
 700          $this->assertEquals( "files/bla/bin/true", $entry->getPath() );
 701  
 702          $this->assertFalse( $this->complexArchive->next() );
 703  
 704          $this->complexArchive->seek( 6 );
 705          $this->assertFalse( $this->complexArchive->valid(), "Truncated archive shouldn't contain any elements" );
 706      }
 707  
 708      public function testTruncateLastFile()
 709      {
 710          if ( !$this->canWrite )
 711          {
 712              return;
 713          }
 714  
 715          // Truncate after the last file, but don't write the null blocks.
 716          $this->archive->truncate( 2, false );
 717  
 718          // File should have 4 blocks.
 719          $blockFile = new ezcArchiveBlockFile( $this->file );
 720          $i = 1;
 721          while ( $blockFile->next() )
 722          {
 723              $i++;
 724          }
 725  
 726          $this->assertEquals( 4, $i );
 727  
 728          unset( $blockFile );
 729      }
 730  
 731      public function testTruncateAmountOfBlocks()
 732      {
 733          if ( !$this->canWrite )
 734          {
 735              return;
 736          }
 737  
 738          $blockFile = new ezcArchiveBlockFile( $this->file );
 739  
 740          $i = 1;
 741          while ( $blockFile->next() ) $i++;
 742          $this->assertEquals( 20, $i, "Expected 20 blocks in the file." );
 743  
 744          $blockFile->seek( 2 );
 745          $this->assertFalse( $blockFile->isNullBlock(), "Didn't expect a null block." );
 746  
 747          $blockFile->seek( 3 );
 748          $this->assertFalse( $blockFile->isNullBlock(), "Didn't expect a null block." );
 749  
 750          $blockFile->seek( 4 );
 751          $this->assertTrue( $blockFile->isNullBlock(), "Expected a null block." );
 752  
 753          // Give the block File to the archive.
 754          $archive =  new ezcArchiveV7Tar( $blockFile );
 755          $entry = $archive->current();
 756  
 757          // A non rewinded block file, does that work?
 758          $this->assertEquals( "file1.txt", $entry->getPath() );
 759  
 760          $archive->truncate( 1 ); // keep the first file.
 761          $archive->close();
 762  
 763          $blockFile = new ezcArchiveBlockFile( $this->file );
 764  
 765          // Should be 20 blocks..
 766          $i = 1;
 767          while ( $blockFile->next() )
 768          {
 769              $i++;
 770          }
 771  
 772          $this->assertEquals( 20, $i, "Expected 20 blocks in the file." );
 773  
 774          $blockFile->seek( 0 );
 775          $this->assertFalse( $blockFile->isNullBlock(), "Didn't expect a null block." );
 776  
 777          $blockFile->seek( 1 );
 778          $this->assertFalse( $blockFile->isNullBlock(), "Didn't expect a null block." );
 779  
 780          $blockFile->seek( 2 );
 781          $this->assertTrue( $blockFile->isNullBlock(), "Expected a null block." );
 782  
 783          unset( $blockFile );
 784      }
 785  
 786      public function testAppendToCurrentNonExistingFile()
 787      {
 788          if ( !$this->canWrite )
 789          {
 790              try
 791              {
 792                  $this->complexArchive->truncate();
 793                  $this->fail( "Cannot write exception expected" );
 794              }
 795              catch ( ezcBaseFilePermissionException $e )
 796              {
 797                  // Okay, some exception thrown.
 798              }
 799  
 800              return;
 801          }
 802  
 803          try
 804          {
 805              $this->archive->appendToCurrent( "file_does_not_exist", "/" );
 806              $this->fail( "Expected a 'file does not exist' exception." );
 807          }
 808          catch ( ezcBaseFileNotFoundException $e )
 809          {
 810          }
 811      }
 812  
 813      public function testAppendToCurrentOnEmptyArchive()
 814      {
 815          if ( !$this->canWrite )
 816          {
 817              return;
 818          }
 819  
 820          $this->assertNotEquals( "\0\0a\0", "\0a\0\0", "Something wrong with the unit test system." );
 821  
 822          $this->archive->extractCurrent( $this->getTempDir() );
 823  
 824          $dir = $this->getTempDir();
 825          $emptyTar = "$dir/empty_archive.tar";
 826          $bf = new ezcArchiveBlockFile( $emptyTar, true );
 827          $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
 828          $this->assertFalse( $archive->valid() );
 829          $archive->appendToCurrent( "$dir/file1.txt", $dir );
 830          $archive->close();
 831  
 832          $this->assertEquals( 10240, strlen( file_get_contents( "$dir/empty_archive.tar" ) ), "Expected 20 blocks of 512 bytes" );
 833  
 834          // Do the same with gnu tar.
 835          exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file1.txt" );
 836  
 837          $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( "$dir/empty_archive.tar" ) );
 838  
 839          unset( $archive );
 840          unset( $bf );
 841      }
 842  
 843      public function testAppendToCurrentAtEndOfArchive()
 844      {
 845          if ( !$this->canWrite )
 846          {
 847              return;
 848          }
 849  
 850          $dir = $this->getTempDir();
 851  
 852          $bf = new ezcArchiveBlockFile( $this->file );
 853          $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
 854          $archive->extractCurrent( $dir );
 855  
 856          copy( $this->file, $dir."/gnutar.tar" );
 857  
 858          $archive->seek( 0, SEEK_END ); // File number two.
 859          $archive->appendToCurrent( "$dir/file1.txt", $dir );
 860          $archive->close();
 861  
 862          // Do the same with gnu tar.
 863          exec( "tar -rf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file1.txt" );
 864  
 865          $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $this->file ) );
 866  
 867          unset( $archive );
 868          unset( $bf );
 869      }
 870  
 871      public function testAppendToCurrentInArchive()
 872      {
 873          if ( !$this->canWrite )
 874          {
 875              return;
 876          }
 877  
 878          $dir = $this->getTempDir();
 879  
 880          $bf = new ezcArchiveBlockFile( $this->file );
 881          $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
 882          $archive->extractCurrent( $dir );
 883  
 884          copy( $this->file, $dir."/gnutar.tar" );
 885  
 886          $archive->seek( 0 ); // After file number one.
 887          $archive->appendToCurrent( "$dir/file1.txt", $dir );
 888          $archive->close();
 889  
 890          // Do the same with gnu tar.
 891          exec( "tar --delete -f $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file2.txt" );
 892          exec( "tar -rf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file1.txt" );
 893  
 894          $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $this->file ) );
 895  
 896          unset( $bf );
 897      }
 898  
 899      public function testAppendToCurrentMultipleTimes()
 900      {
 901          if ( !$this->canWrite )
 902          {
 903              return;
 904          }
 905  
 906          // Extract the archive.
 907          $dir = $this->getTempDir();
 908  
 909          $bf = new ezcArchiveBlockFile( $this->file );
 910          $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
 911          $archive->extractCurrent( $dir );
 912          $archive->next();
 913          $archive->extractCurrent( $dir );
 914  
 915          // Clear the archive.
 916          $archive->truncate();
 917  
 918          // Append the files again.
 919          $archive->appendToCurrent( $dir . "/file1.txt", $dir );
 920          // $this->assertTrue( $this->archive->next() !== false );
 921          $archive->appendToCurrent( $dir . "/file2.txt", $dir );
 922          $archive->close();
 923  
 924          // Do the same with gnu tar.
 925          exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file1.txt file2.txt" );
 926  
 927          // Compare
 928          $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents($this->file ) );
 929  
 930          $bf = new ezcArchiveBlockFile( $this->file );
 931          $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
 932  
 933          // Append another file.
 934          $archive->append( $dir . "/file1.txt", $dir );
 935          $archive->close();
 936  
 937          exec( "tar -rf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file1.txt" );
 938  
 939          $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $this->file ) );
 940      }
 941  
 942      public function testAppendToCurrentDirectory()
 943      {
 944          if ( !$this->canWrite )
 945          {
 946              return;
 947          }
 948  
 949          $dir = $this->getTempDir();
 950          $this->complexArchive->extractCurrent( $dir );
 951  
 952          $emptyTar = "$dir/empty_archive.tar";
 953          $bf = new ezcArchiveBlockFile( $emptyTar, true );
 954          $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
 955          $archive->appendToCurrent( $dir . "/files", $dir );
 956          $archive->close();
 957  
 958          // Do the same with gnu tar.
 959          exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir files" );
 960          $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $emptyTar ) );
 961          unset( $bf );
 962      }
 963  
 964      public function testAppendToCurrentSymbolicLink()
 965      {
 966          if ( !$this->canWrite )
 967          {
 968              return;
 969          }
 970  
 971          if ( $this->isWindows() )
 972          {
 973              return; // there is no sense to test it in Windows as its the same as appending file.
 974          }
 975  
 976          $dir = $this->getTempDir();
 977          $this->complexArchive->seek( 7 );
 978          $this->complexArchive->extractCurrent( $dir );
 979  
 980          $emptyTar = "$dir/empty_archive.tar";
 981          $bf = new ezcArchiveBlockFile( $emptyTar, true );
 982          $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
 983          $archive->appendToCurrent( $dir . "/files/file3.txt", $dir );
 984          $archive->close();
 985  
 986          // Do the same with gnu tar.
 987          exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir files/file3.txt" );
 988          $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $emptyTar ) );
 989          unset( $bf );
 990      }
 991  
 992      public function testAppendToCurrentHardLink()
 993      {
 994          if ( !$this->canWrite )
 995          {
 996              return;
 997          }
 998  
 999          $dir = $this->getTempDir();
1000          $this->complexArchive->seek( 4 ); // File.
1001          $this->complexArchive->extractCurrent( $dir );
1002  
1003          $this->complexArchive->seek( 8 ); // Hardlink
1004          $this->complexArchive->extractCurrent( $dir );
1005  
1006          $emptyTar = "$dir/empty_archive.tar";
1007          $bf = new ezcArchiveBlockFile( $emptyTar, true );
1008          $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
1009          $archive->appendToCurrent( $dir . "/files/file4.txt", $dir );
1010          $archive->writeEnd();
1011  
1012          // Do the same with gnu tar.
1013          exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir files/file4.txt" );
1014          $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $emptyTar ) );
1015  
1016          // File was appended as a normal file.
1017          $archive->rewind();
1018          $archive->appendToCurrent( $dir . "/files/bla/file3.txt", $dir );
1019          $archive->close();
1020  
1021          // Do the same with gnu tar.
1022          exec( "tar -rf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir files/bla/file3.txt" );
1023  
1024          // Appended as two separated files.
1025          $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $emptyTar ) );
1026          unset( $bf );
1027      }
1028  
1029      public function testAppendToCurrentHardLinkedFiles()
1030      {
1031          if ( !$this->canWrite )
1032          {
1033              return;
1034          }
1035  
1036          $dir = $this->getTempDir();
1037          $this->complexArchive->seek( 4 ); // File.
1038          $this->complexArchive->extractCurrent( $dir );
1039  
1040          $this->complexArchive->seek( 8 ); // Hardlink
1041          $this->complexArchive->extractCurrent( $dir );
1042  
1043          exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir files/bla/file3.txt files/file4.txt" );
1044  
1045          $emptyTar = "$dir/empty_archive.tar";
1046          $bf = new ezcArchiveBlockFile( $emptyTar, true );
1047  
1048          $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
1049          $archive->appendToCurrent( array ( "$dir/files/bla/file3.txt", "$dir/files/file4.txt" ), $dir );
1050          $archive->close();
1051  
1052          $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $emptyTar ) );
1053          unset( $bf );
1054      }
1055  
1056      public function testAppendArchiveAtOnce()
1057      {
1058          if ( !$this->canWrite )
1059          {
1060              try
1061              {
1062                  $this->complexArchive->truncate();
1063                  $this->fail( "Cannot write exception expected" );
1064              }
1065              catch ( ezcBaseFilePermissionException $e )
1066              {
1067                  // Okay, some exception thrown.
1068              }
1069  
1070              return;
1071          }
1072  
1073          $dir = $this->getTempDir();
1074          $src = $dir . "/src";
1075          mkdir ( $src );
1076  
1077          $files = array();
1078          do
1079          {
1080              $this->complexArchive->extractCurrent( $src );
1081              $files[] =  $src . '/'. $this->complexArchive->current()->getPath();
1082          } while ( $this->complexArchive->next() );
1083  
1084          $mytar = "$dir/my_archive.tar";
1085          $bf = new ezcArchiveBlockFile( $mytar, true );
1086          $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
1087          $archive->appendToCurrent( $files, $src );
1088          $archive->close();
1089          exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $src files" );
1090  
1091          $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $mytar ) );
1092          unset( $archive );
1093          unset( $bf );
1094      }
1095  
1096      public static function suite()
1097      {
1098          return new PHPUnit_Framework_TestSuite( __CLASS__ );
1099      }
1100  }
1101  ?>

title

Description

title

Description

title

Description

title

title

Body