/Archive/tests/tar/v7_tar_test.php
PHP | 1143 lines | 787 code | 213 blank | 143 comment | 33 complexity | de030bc1fc7aff15f52341ca3a9f6429 MD5 | raw file
- <?php
- /**
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
- * @filesource
- * @package Archive
- * @version //autogen//
- * @subpackage Tests
- */
- require_once( dirname( __FILE__ ) . "/../archive_test_case.php" );
- /**
- * @package Archive
- * @version //autogen//
- * @subpackage Tests
- */
- class ezcArchiveV7TarTest extends ezcArchiveTestCase
- {
- protected $canWrite = true;
- protected $archive;
- protected $complexArchive;
- protected $file;
- protected $complexFile;
- protected $tarFormat;
- protected $tarMimeFormat;
- protected $usersGid;
- public function createTempFile( $file )
- {
- $original = dirname(__FILE__) . "/../data/$file";
- $tmpFile = $this->getTempDir() . "/$file";
- copy( $original, $tmpFile );
- return $tmpFile;
- }
- protected function setUp()
- {
- date_default_timezone_set( "UTC" );
- $this->tarFormat = "v7";
- $this->tarMimeFormat = ezcArchive::TAR_V7;
- $this->createTempDir( "ezcArchive_" );
- $this->file = $this->createTempFile( "tar_v7_2_textfiles.tar" );
- $blockFile = new ezcArchiveBlockFile( $this->file );
- $this->archive = new ezcArchiveV7Tar( $blockFile );
- unset( $blockFile );
- $this->complexFile = $this->createTempFile( "tar_v7_file_dir_symlink_link.tar" );
- $blockFile = new ezcArchiveBlockFile( $this->complexFile );
- $this->complexArchive = new ezcArchiveV7Tar( $blockFile );
- unset( $blockFile );
- $this->setUsersGid();
- }
- protected function setUsersGid()
- {
- // figure out the GID for "users" for tests
- $this->usersGid = 1000; // default
- if ( posix_geteuid() === 0 && function_exists( 'posix_getgrnam' ) )
- {
- $info = posix_getgrnam( 'users' );
- $this->usersGid = $info['gid'];
- }
- }
- protected function tearDown()
- {
- unset( $this->archive );
- unset( $this->complexArchive );
- $this->removeTempDir();
- }
- protected function isWindows()
- {
- return ( substr( php_uname( 's' ), 0, 7 ) == 'Windows' ) ? true : false;
- }
- // FIXME
- // Move method to the archiveTest.
- /*
- public function testGetEntryFromFile()
- {
- $this->archive->extractCurrent( $this->getTempDir() );
- $entry = ezcArchive::getEntryFromFile( $this->getTempDir() . "/file1.txt" );
- $this->assertEquals( $this->getTempDir() . "/file1.txt", $entry->getPath() );
- $this->assertTrue( $entry->isFile() );
- $this->assertFalse( $entry->isDirectory() );
- // Probably okay.
- }
- // FIXME
- // Move method to the archiveTest.
- public function testGetEntryFromFilesWithHardlink()
- {
- $dir = $this->getTempDir();
- $this->complexArchive->seek( 4 ); // File.
- $this->complexArchive->extractCurrent( $dir );
- $this->complexArchive->seek(8); // Hardlink
- $this->complexArchive->extractCurrent( $dir );
- $entries = ezcArchive::getEntryFromFile( array( $dir . "/files/bla/file3.txt", $dir . "/files/file4.txt" ) );
- $this->assertEquals( 2, sizeof( $entries ), "Sizeof the entries array doesn't match." );
- $this->assertFalse( $entries[0]->isLink() );
- $this->assertTrue( $entries[1]->isLink() );
- $this->assertEquals( "$dir/files/bla/file3.txt", $entries[1]->getLink() );
- }
- */
- // FIXME
- // Move method to the archiveTest.
- /*
- public function testRemovePrefix()
- {
- $dir = $this->getTempDir();
- $total = $dir . "/lisa/ekdahl/";
- $without = ezcArchive::removePrefix( $total, $dir );
- $this->assertEquals( "lisa/ekdahl/", $without );
- }
- */
- public function testOpenArchive()
- {
- $entry = $this->archive->current();
- $this->assertEquals( "file1.txt", $entry->getPath() );
- }
- public function testEmptyArchive()
- {
- $file = $this->getTempDir() . "/file_does_not_exist.tar";
- $blockFile = new ezcArchiveBlockFile( $file, true );
- $archive = new ezcArchiveV7Tar( $blockFile );
- $this->assertFalse( $archive->current(), "Archive should be empty, so no file info available" );
- $this->assertFalse( $archive->valid(), "Archive should be empty, so no file info available" );
- $this->assertFalse( $archive->next(), "Archive should be empty, so no file info available" );
- $this->assertFalse( $archive->next(), "Archive should be empty, so no file info available" );
- unset( $blockFile );
- unset( $archive );
- }
- public function testIteratorOperations()
- {
- $entry = $this->archive->current();
- $entry = $this->archive->current();
- $this->assertEquals( "file1.txt", $entry->getPath() );
- $this->assertTrue( $this->archive->valid(), "Expected a valid archive position." );
- $this->archive->rewind();
- $entry = $this->archive->current();
- $this->assertEquals( "file1.txt", $entry->getPath() );
- $this->assertEquals( 0, $this->archive->key() );
- $this->assertTrue( $this->archive->valid(), "Expected a valid archive position." );
- $this->assertTrue( $this->archive->next() !== false );
- $entry = $this->archive->current();
- $this->assertEquals( "file2.txt", $entry->getPath() );
- $this->assertEquals( 1, $this->archive->key() );
- $this->assertTrue( $this->archive->valid(), "Expected a valid archive position." );
- $this->assertFalse( $this->archive->next() );
- $this->assertFalse( $this->archive->current() );
- $this->assertFalse( $this->archive->valid() );
- $this->assertFalse( $this->archive->key() );
- $this->assertFalse( $this->archive->next() );
- $this->assertFalse( $this->archive->next() );
- }
- public function testForEaching()
- {
- for ( $i = 0; $i < 2; $i++ )
- {
- $loopNumber = 0;
- foreach ( $this->archive as $entryNumber => $entry )
- {
- if ( $loopNumber == 0 )
- {
- $this->assertEquals( "file1.txt", $entry->getPath() );
- $this->assertEquals( 0, $entryNumber );
- }
- else if ( $loopNumber == 1 )
- {
- $this->assertEquals( "file2.txt", $entry->getPath() );
- $this->assertEquals( 1, $entryNumber );
- }
- else
- {
- $this->fail( "Didn't expect another entry in the archive" );
- }
- $loopNumber++;
- }
- }
- }
- public function testExtractCurrent()
- {
- $targetDir = $this->getTempDir() . "/";
- $this->archive->extractCurrent( $targetDir );
- $file1 = $this->getTempDir() . "/file1.txt";
- $this->assertEquals( "Hello world.\nThe first file.\n", file_get_contents( $file1 ) );
- // Remove the file, and extract again.
- unlink( $file1 );
- // Check whether the file is really removed (paranoia?).
- $fp = @fopen( $file1, "r" );
- if ( $fp )
- {
- $this->assertFail( "No noo nooo. The file shouldn't be here." );
- }
- $this->archive->extractCurrent( $targetDir );
- $this->assertEquals( "Hello world.\nThe first file.\n", file_get_contents( $file1 ) );
- // Move on.
- $entry = $this->archive->next();
- $this->assertTrue( $this->archive->valid(), "Second file is expected here." );
- $this->archive->extractCurrent( $targetDir );
- $file2 = $this->getTempDir() . "/file2.txt";
- $this->assertEquals( "Hello world.\nThe second file.\n", file_get_contents( $file2 ) );
- $this->assertFalse( $this->archive->next(), "No more files in the archive" );
- }
- public function testExtractCurrentOverwriteFile()
- {
- // Normally it will overwrite the file, if possible.
- $targetDir = $this->getTempDir() . "/";
- $this->archive->extractCurrent( $targetDir );
- $file1 = $this->getTempDir() . "/file1.txt";
- $this->assertEquals( "Hello world.\nThe first file.\n", file_get_contents( $file1 ) );
- $fp = @fopen( $file1, "w" );
- fwrite( $fp, "Garbage" );
- fclose( $fp );
- $this->assertEquals( "Garbage", file_get_contents( $file1 ) );
- $this->archive->extractCurrent( $targetDir );
- $this->assertEquals( "Hello world.\nThe first file.\n", file_get_contents( $file1 ) );
- }
- public function testExtractCurrentKeepExistingFile()
- {
- // Normally it will overwrite the file, if possible.
- $targetDir = $this->getTempDir() . "/";
- $this->archive->extractCurrent( $targetDir, true );
- $file1 = $this->getTempDir() . "/file1.txt";
- $this->assertEquals( "Hello world.\nThe first file.\n", file_get_contents( $file1 ) );
- $fp = @fopen( $file1, "w" );
- fwrite( $fp, "Garbage" );
- fclose( $fp );
- $this->assertEquals( "Garbage", file_get_contents( $file1 ) );
- $this->archive->extractCurrent( $targetDir, true );
- $this->assertEquals( "Garbage", file_get_contents( $file1 ) );
- }
- public function testExtractComplexArchive()
- {
- $dir = $this->getTempDir();
- mkdir( $dir . "/php" );
- mkdir( $dir . "/gnu" );
- foreach ( $this->complexArchive as $entry )
- {
- $this->complexArchive->extractCurrent( $dir ."/php" );
- }
- exec( "tar -xf " . $this->complexFile . " -C $dir/gnu" );
- // make corrections that emulate symlink in Windows
- if ( $this->isWindows() )
- {
- exec( 'attrib -r ' . $dir . '\gnu\files\file3.txt.lnk' );
- exec( 'del "' . $dir . '\gnu\files\file3.txt.lnk"' );
- exec( 'copy "' . $dir . '\gnu\files\bla\file3.txt" "' . $dir . '\gnu\files\file3.txt"' );
- }
- $this->compareDirectories( "$dir/gnu", "$dir/php" );
- $stat = stat( "$dir/php/files/bla/file3.txt" );
- $this->assertEquals( 0644, $stat['mode'] & 07777 );
- $this->assertEquals( 1000, $stat['uid'] );
- $this->assertEquals( $this->usersGid, $stat['gid'] );
- }
- public function testExtractComplexArchiveModPerms()
- {
- $options = new ezcArchiveOptions;
- $options->extractCallback = new testExtractCallback;
- $this->complexArchive->setOptions( $options );
- $dir = $this->getTempDir();
- mkdir( $dir . "/php" );
- mkdir( $dir . "/gnu" );
- foreach ( $this->complexArchive as $entry )
- {
- $this->complexArchive->extractCurrent( $dir ."/php" );
- }
- exec( "tar -xf " . $this->complexFile . " -C $dir/gnu" );
- // make corrections that emulate symlink in Windows
- if ( $this->isWindows() )
- {
- exec( 'attrib -r ' . $dir . '\gnu\files\file3.txt.lnk' );
- exec( 'del "' . $dir . '\gnu\files\file3.txt.lnk"' );
- exec( 'copy "' . $dir . '\gnu\files\bla\file3.txt" "' . $dir . '\gnu\files\file3.txt"' );
- }
- $this->compareDirectories( "$dir/gnu", "$dir/php" );
- $options->extractCallback = null;
- $stat = stat( "$dir/php/files/bla/file3.txt" );
- $this->assertEquals( 0600, $stat['mode'] & 07777 );
- $this->assertEquals( 1000, $stat['uid'] );
- $this->assertEquals( $this->usersGid, $stat['gid'] );
- $stat = stat( "$dir/php/files/bla" );
- $this->assertEquals( 0700, $stat['mode'] & 07777 );
- $this->assertEquals( 1000, $stat['uid'] );
- $this->assertEquals( $this->usersGid, $stat['gid'] );
- }
- public function testInvalidChecksum()
- {
- // Correct checksum.
- $ustarFile = new ezcArchiveBlockFile( dirname( __FILE__) . "/../data/tar_v7_2_textfiles.tar" );
- $tar = new ezcArchiveV7Tar( $ustarFile );
- // Incorrect checksum.
- try
- {
- $ustarFile = new ezcArchiveBlockFile( dirname( __FILE__) . "/../data/tar_v7_invalid_checksum.tar" );
- $tar = new ezcArchiveV7Tar( $ustarFile );
- $tar->current();
- $this->fail("Expected the checksum to fail.");
- }
- catch ( ezcArchiveChecksumException $e )
- {
- }
- unset( $tar );
- unset( $ustarFile );
- }
- public function testSeekPositions()
- {
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/", $entry->getPath() );
- $this->complexArchive->seek( 2 ); // third file in archive.
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/bla/bin/", $entry->getPath() );
- $this->complexArchive->seek( 0 ); // first file in archive.
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/", $entry->getPath() );
- $this->complexArchive->seek( 6 );
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/file2.txt", $entry->getPath() );
- $this->complexArchive->seek( 8 );
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/file4.txt", $entry->getPath() );
- $this->complexArchive->seek( 9 );
- $this->assertFalse( $this->complexArchive->current() );
- $this->complexArchive->seek( 0 );
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/", $entry->getPath() );
- $this->complexArchive->seek( -1 );
- $this->assertFalse( $this->complexArchive->current() );
- }
- public function testSeekEndOfFile()
- {
- $this->complexArchive->seek( 0, SEEK_END ); // nineth and last file.
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/file4.txt", $entry->getPath() );
- $this->complexArchive->seek( -2, SEEK_END ); // seventh file
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/file2.txt", $entry->getPath() );
- $this->complexArchive->seek( -8, SEEK_END ); // first file
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/", $entry->getPath() );
- $this->complexArchive->seek( 1, SEEK_END ); // invalid
- $this->assertFalse( $this->complexArchive->current() );
- $this->complexArchive->seek( 0, SEEK_END ); // nineth and last file.
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/file4.txt", $entry->getPath() );
- $this->complexArchive->seek( -9, SEEK_END ); // invalid
- $this->assertFalse( $this->complexArchive->current() );
- }
- public function testSeekCur()
- {
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/", $entry->getPath() );
- $this->complexArchive->seek( 2, SEEK_CUR ); // third file in archive.
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/bla/bin/", $entry->getPath() );
- $this->complexArchive->seek( 0, SEEK_CUR ); // Third file in archive.
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/bla/bin/", $entry->getPath() );
- $this->complexArchive->seek( 4, SEEK_CUR ); // Seventh file in the archive.
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/file2.txt", $entry->getPath() );
- $this->complexArchive->seek( 2, SEEK_CUR ); // nineth and last.
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/file4.txt", $entry->getPath() );
- $this->complexArchive->seek( 1, SEEK_CUR );
- $this->assertFalse( $this->complexArchive->current() );
- $this->complexArchive->seek( 2 );
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/bla/bin/", $entry->getPath() );
- $this->complexArchive->seek( -2, SEEK_CUR ); // First file.
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/", $entry->getPath() );
- $this->complexArchive->seek( -1, SEEK_CUR ); // And invalid again.
- $this->assertFalse( $this->complexArchive->current() );
- }
- public function testExtractOneDirectory()
- {
- // The subdirectory should be created automatically.
- $this->complexArchive->seek( 1 );
- $targetDir = $this->getTempDir() ;
- $this->complexArchive->extractCurrent( $targetDir );
- $this->assertTrue( file_exists( $targetDir . "/files/bla/" ), "Cannot find the extracted directory." );
- }
- public function testExtractOneFile()
- {
- // The directory should be created automatically.
- $this->complexArchive->seek( 4 ); // 5th file.
- $targetDir = $this->getTempDir();
- $this->complexArchive->extractCurrent( $targetDir );
- $this->assertTrue( file_exists( $targetDir . "/files/bla/file3.txt" ), "Cannot find the extracted file." );
- $this->assertEquals( "Hello world.\nThe third file.\n", file_get_contents( $targetDir . "/files/bla/file3.txt" ) );
- }
- public function testExtractOneSymbolicLink()
- {
- // this test a bit different in Windows as symlinks
- // simulated by copying
- if ( $this->isWindows() )
- {
- // The directory should be created automatically.
- // There is both link and link target extracted
- // and there are both the same file.
- $targetDir = $this->getTempDir();
- // extract target
- $this->complexArchive->seek( 4 );
- $this->complexArchive->extractCurrent( $targetDir );
- // "extract" link i.e. copy target
- $this->complexArchive->seek( 7 );
- $this->complexArchive->extractCurrent( $targetDir );
- }
- else
- {
- // The directory should be created automatically.
- // The link points to an non existing file.
- $this->complexArchive->seek( 7 );
- $targetDir = $this->getTempDir();
- $this->complexArchive->extractCurrent( $targetDir );
- }
- $this->assertTrue( is_array ( lstat( $targetDir . "/files/file3.txt" ) ) );
- }
- public function testExtractOneHardLinkException()
- {
- // Should throw an exception.
- $this->complexArchive->seek( 8 );
- $targetDir = $this->getTempDir();
- try
- {
- $this->complexArchive->extractCurrent( $targetDir );
- $this->fail( "Expected an exception" );
- }
- catch ( ezcBaseFileNotFoundException $e )
- {
- }
- }
- public function testExtractOneHardLink()
- {
- $this->complexArchive->seek( 4 );
- $targetDir = $this->getTempDir();
- $this->complexArchive->extractCurrent( $targetDir );
- $this->complexArchive->seek( 8 );
- $this->complexArchive->extractCurrent( $targetDir );
- $this->assertTrue( file_exists( $targetDir . "/files/bla/file3.txt" ) );
- $this->assertTrue( file_exists( $targetDir . "/files/file4.txt" ) );
- }
- public function testExtractComplexArchiveOverwrite()
- {
- $dir = $this->getTempDir();
- mkdir( $dir . "/php" );
- mkdir( $dir . "/gnu" );
- // Extract once
- foreach ( $this->complexArchive as $entry )
- {
- $this->complexArchive->extractCurrent( $dir ."/php" );
- }
- // Extract with gnu tar.
- exec( "tar -xf " . $this->complexFile . " -C $dir/gnu" );
- // Truncate file1.txt
- $fp = fopen( $dir ."/php/files/file1.txt", "r+w" );
- ftruncate( $fp, 0 );
- fclose( $fp );
- // Change link.
- unlink( $dir . "/php/files/file3.txt" );
- if ( $this->isWindows() )
- {
- copy( $dir . "/php/files/file4.txt", $dir . "/php/files/file3.txt" );
- // make corrections of gnu tar output
- // replace .lnk file with copy of target file
- exec( 'attrib -r ' . $dir . '\gnu\files\file3.txt.lnk' );
- exec( 'del "' . $dir . '\gnu\files\file3.txt.lnk"' );
- exec( 'copy "' . $dir . '\gnu\files\bla\file3.txt" "' . $dir . '\gnu\files\file3.txt"' );
- }
- else
- {
- symlink( "file4.txt", $dir . "/php/files/file3.txt" );
- }
- // Truncate file4.txt (and also files/bla/file3.txt.
- $fp = fopen( $dir . "/php/files/file4.txt", "r+w" );
- ftruncate( $fp, 0 );
- fclose( $fp );
- foreach ( $this->complexArchive as $entry )
- {
- $this->complexArchive->extractCurrent( $dir . "/php" );
- }
- $this->compareDirectories( "$dir/gnu", "$dir/php" );
- }
- public function testExtractComplexArchiveKeepExisting()
- {
- $dir = $this->getTempDir();
- mkdir( $dir . "/php" );
- mkdir( $dir . "/gnu" );
- // Extract once
- foreach ( $this->complexArchive as $entry )
- {
- $this->complexArchive->extractCurrent( $dir ."/php" );
- }
- // Extract with gnu tar.
- exec( "tar -xf " . $this->complexFile . " -C $dir/gnu" );
- // Truncate file1.txt
- $fp = fopen( $dir . "/php/files/file1.txt", "r+w" );
- ftruncate( $fp, 0 );
- fclose( $fp );
- // Change link.
- unlink( $dir . "/php/files/file3.txt" );
- if ( $this->isWindows() )
- {
- copy( $dir . "/php/files/file4.txt", $dir . "/php/files/file3.txt" );
- // make corrections of gnu tar output
- // replace .lnk file with copy of target file
- exec( 'attrib -r ' . $dir . '\gnu\files\file3.txt.lnk' );
- exec( 'del "' . $dir . '\gnu\files\file3.txt.lnk"' );
- exec( 'copy "' . $dir . '\gnu\files\bla\file3.txt" "' . $dir . '\gnu\files\file3.txt"' );
- }
- else
- {
- symlink( "file4.txt", $dir."/php/files/file3.txt");
- }
- // Truncate file4.txt (and also files/bla/file3.txt.
- $fp = fopen( $dir . "/php/files/file4.txt", "r+w" );
- ftruncate( $fp, 0 );
- fclose( $fp );
- foreach ( $this->complexArchive as $entry )
- {
- $this->complexArchive->extractCurrent( $dir . "/php", true );
- }
- $this->assertEquals( "", file_get_contents( $dir . "/php/files/file1.txt" ) );
- $this->assertEquals( "", file_get_contents( $dir . "/php/files/file3.txt" ) );
- $this->assertEquals( "", file_get_contents( $dir . "/php/files/file4.txt" ) );
- $this->assertEquals( "", file_get_contents( $dir . "/php/files/bla/file3.txt" ) );
- }
- // Write methods.
- public function testTruncate()
- {
- if ( !$this->canWrite )
- {
- try
- {
- $this->complexArchive->truncate();
- $this->fail( "Cannot write exception expected" );
- }
- catch ( ezcBaseFilePermissionException $e )
- {
- // Okay, some exception thrown.
- }
- return;
- }
- $this->complexArchive->truncate();
- $this->assertFalse( $this->complexArchive->valid(), "Truncated archive shouldn't contain any elements" );
- $this->complexArchive->seek( 0 );
- $this->assertFalse( $this->complexArchive->valid(), "Truncated archive shouldn't contain any elements" );
- $this->complexArchive->seek( 2 );
- $this->assertFalse( $this->complexArchive->valid(), "Truncated archive shouldn't contain any elements" );
- }
- public function testTruncatePart()
- {
- if ( !$this->canWrite )
- {
- return;
- }
- $this->complexArchive->truncate( 4 );
- // Without rewind.. should work since we truncated after our position.
- $entry = $this->complexArchive->current();
- $this->assertEquals( "files/", $entry->getPath() );
- $entry = $this->complexArchive->next();
- $this->assertEquals( "files/bla/", $entry->getPath() );
- $entry = $this->complexArchive->next();
- $this->assertEquals( "files/bla/bin/", $entry->getPath() );
- $entry = $this->complexArchive->next();
- $this->assertEquals( "files/bla/bin/true", $entry->getPath() );
- $this->assertFalse( $this->complexArchive->next() );
- $this->complexArchive->seek( 6 );
- $this->assertFalse( $this->complexArchive->valid(), "Truncated archive shouldn't contain any elements" );
- }
- public function testTruncateLastFile()
- {
- if ( !$this->canWrite )
- {
- return;
- }
- // Truncate after the last file, but don't write the null blocks.
- $this->archive->truncate( 2, false );
- // File should have 4 blocks.
- $blockFile = new ezcArchiveBlockFile( $this->file );
- $i = 1;
- while ( $blockFile->next() )
- {
- $i++;
- }
- $this->assertEquals( 4, $i );
- unset( $blockFile );
- }
- public function testTruncateAmountOfBlocks()
- {
- if ( !$this->canWrite )
- {
- return;
- }
- $blockFile = new ezcArchiveBlockFile( $this->file );
- $i = 1;
- while ( $blockFile->next() ) $i++;
- $this->assertEquals( 20, $i, "Expected 20 blocks in the file." );
- $blockFile->seek( 2 );
- $this->assertFalse( $blockFile->isNullBlock(), "Didn't expect a null block." );
- $blockFile->seek( 3 );
- $this->assertFalse( $blockFile->isNullBlock(), "Didn't expect a null block." );
- $blockFile->seek( 4 );
- $this->assertTrue( $blockFile->isNullBlock(), "Expected a null block." );
- // Give the block File to the archive.
- $archive = new ezcArchiveV7Tar( $blockFile );
- $entry = $archive->current();
- // A non rewinded block file, does that work?
- $this->assertEquals( "file1.txt", $entry->getPath() );
- $archive->truncate( 1 ); // keep the first file.
- $archive->close();
- $blockFile = new ezcArchiveBlockFile( $this->file );
- // Should be 20 blocks..
- $i = 1;
- while ( $blockFile->next() )
- {
- $i++;
- }
- $this->assertEquals( 20, $i, "Expected 20 blocks in the file." );
- $blockFile->seek( 0 );
- $this->assertFalse( $blockFile->isNullBlock(), "Didn't expect a null block." );
- $blockFile->seek( 1 );
- $this->assertFalse( $blockFile->isNullBlock(), "Didn't expect a null block." );
- $blockFile->seek( 2 );
- $this->assertTrue( $blockFile->isNullBlock(), "Expected a null block." );
- unset( $blockFile );
- }
- public function testAppendToCurrentNonExistingFile()
- {
- if ( !$this->canWrite )
- {
- try
- {
- $this->complexArchive->truncate();
- $this->fail( "Cannot write exception expected" );
- }
- catch ( ezcBaseFilePermissionException $e )
- {
- // Okay, some exception thrown.
- }
- return;
- }
- try
- {
- $this->archive->appendToCurrent( "file_does_not_exist", "/" );
- $this->fail( "Expected a 'file does not exist' exception." );
- }
- catch ( ezcBaseFileNotFoundException $e )
- {
- }
- }
- public function testAppendToCurrentOnEmptyArchive()
- {
- if ( !$this->canWrite )
- {
- return;
- }
- $this->assertNotEquals( "\0\0a\0", "\0a\0\0", "Something wrong with the unit test system." );
- $this->archive->extractCurrent( $this->getTempDir() );
- $dir = $this->getTempDir();
- $emptyTar = "$dir/empty_archive.tar";
- $bf = new ezcArchiveBlockFile( $emptyTar, true );
- $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
- $this->assertFalse( $archive->valid() );
- $archive->appendToCurrent( "$dir/file1.txt", $dir );
- $archive->close();
- $this->assertEquals( 10240, strlen( file_get_contents( "$dir/empty_archive.tar" ) ), "Expected 20 blocks of 512 bytes" );
- // Do the same with gnu tar.
- exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file1.txt" );
- $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( "$dir/empty_archive.tar" ) );
- unset( $archive );
- unset( $bf );
- }
- public function testAppendToCurrentAtEndOfArchive()
- {
- if ( !$this->canWrite )
- {
- return;
- }
- $dir = $this->getTempDir();
- $bf = new ezcArchiveBlockFile( $this->file );
- $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
- $archive->extractCurrent( $dir );
- copy( $this->file, $dir."/gnutar.tar" );
- $archive->seek( 0, SEEK_END ); // File number two.
- $archive->appendToCurrent( "$dir/file1.txt", $dir );
- $archive->close();
- // Do the same with gnu tar.
- exec( "tar -rf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file1.txt" );
- $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $this->file ) );
- unset( $archive );
- unset( $bf );
- }
- public function testAppendToCurrentInArchive()
- {
- if ( !$this->canWrite )
- {
- return;
- }
- $dir = $this->getTempDir();
- $bf = new ezcArchiveBlockFile( $this->file );
- $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
- $archive->extractCurrent( $dir );
- copy( $this->file, $dir."/gnutar.tar" );
- $archive->seek( 0 ); // After file number one.
- $archive->appendToCurrent( "$dir/file1.txt", $dir );
- $archive->close();
- // Do the same with gnu tar.
- exec( "tar --delete -f $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file2.txt" );
- exec( "tar -rf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file1.txt" );
- $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $this->file ) );
- unset( $bf );
- }
- public function testAppendToCurrentMultipleTimes()
- {
- if ( !$this->canWrite )
- {
- return;
- }
- // Extract the archive.
- $dir = $this->getTempDir();
- $bf = new ezcArchiveBlockFile( $this->file );
- $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
- $archive->extractCurrent( $dir );
- $archive->next();
- $archive->extractCurrent( $dir );
- // Clear the archive.
- $archive->truncate();
- // Append the files again.
- $archive->appendToCurrent( $dir . "/file1.txt", $dir );
- // $this->assertTrue( $this->archive->next() !== false );
- $archive->appendToCurrent( $dir . "/file2.txt", $dir );
- $archive->close();
- // Do the same with gnu tar.
- exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file1.txt file2.txt" );
- // Compare
- $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents($this->file ) );
- $bf = new ezcArchiveBlockFile( $this->file );
- $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
- // Append another file.
- $archive->append( $dir . "/file1.txt", $dir );
- $archive->close();
- exec( "tar -rf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir file1.txt" );
- $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $this->file ) );
- }
- public function testAppendToCurrentDirectory()
- {
- if ( !$this->canWrite )
- {
- return;
- }
- $dir = $this->getTempDir();
- $this->complexArchive->extractCurrent( $dir );
- $emptyTar = "$dir/empty_archive.tar";
- $bf = new ezcArchiveBlockFile( $emptyTar, true );
- $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
- $archive->appendToCurrent( $dir . "/files", $dir );
- $archive->close();
- // Do the same with gnu tar.
- exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir files" );
- $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $emptyTar ) );
- unset( $bf );
- }
- public function testAppendToCurrentSymbolicLink()
- {
- if ( !$this->canWrite )
- {
- return;
- }
- if ( $this->isWindows() )
- {
- return; // there is no sense to test it in Windows as its the same as appending file.
- }
- $dir = $this->getTempDir();
- $this->complexArchive->seek( 7 );
- $this->complexArchive->extractCurrent( $dir );
- $emptyTar = "$dir/empty_archive.tar";
- $bf = new ezcArchiveBlockFile( $emptyTar, true );
- $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
- $archive->appendToCurrent( $dir . "/files/file3.txt", $dir );
- $archive->close();
- // Do the same with gnu tar.
- exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir files/file3.txt" );
- $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $emptyTar ) );
- unset( $bf );
- }
- public function testAppendToCurrentHardLink()
- {
- if ( !$this->canWrite )
- {
- return;
- }
- $dir = $this->getTempDir();
- $this->complexArchive->seek( 4 ); // File.
- $this->complexArchive->extractCurrent( $dir );
- $this->complexArchive->seek( 8 ); // Hardlink
- $this->complexArchive->extractCurrent( $dir );
- $emptyTar = "$dir/empty_archive.tar";
- $bf = new ezcArchiveBlockFile( $emptyTar, true );
- $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
- $archive->appendToCurrent( $dir . "/files/file4.txt", $dir );
- $archive->writeEnd();
- // Do the same with gnu tar.
- exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir files/file4.txt" );
- $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $emptyTar ) );
- // File was appended as a normal file.
- $archive->rewind();
- $archive->appendToCurrent( $dir . "/files/bla/file3.txt", $dir );
- $archive->close();
- // Do the same with gnu tar.
- exec( "tar -rf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir files/bla/file3.txt" );
- // Appended as two separated files.
- $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $emptyTar ) );
- unset( $bf );
- }
- public function testAppendToCurrentHardLinkedFiles()
- {
- if ( !$this->canWrite )
- {
- return;
- }
- $dir = $this->getTempDir();
- $this->complexArchive->seek( 4 ); // File.
- $this->complexArchive->extractCurrent( $dir );
- $this->complexArchive->seek( 8 ); // Hardlink
- $this->complexArchive->extractCurrent( $dir );
- exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $dir files/bla/file3.txt files/file4.txt" );
- $emptyTar = "$dir/empty_archive.tar";
- $bf = new ezcArchiveBlockFile( $emptyTar, true );
- $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
- $archive->appendToCurrent( array ( "$dir/files/bla/file3.txt", "$dir/files/file4.txt" ), $dir );
- $archive->close();
- $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $emptyTar ) );
- unset( $bf );
- }
- public function testAppendArchiveAtOnce()
- {
- if ( !$this->canWrite )
- {
- try
- {
- $this->complexArchive->truncate();
- $this->fail( "Cannot write exception expected" );
- }
- catch ( ezcBaseFilePermissionException $e )
- {
- // Okay, some exception thrown.
- }
- return;
- }
- $dir = $this->getTempDir();
- $src = $dir . "/src";
- mkdir ( $src );
- $files = array();
- do
- {
- $this->complexArchive->extractCurrent( $src );
- $files[] = $src . '/'. $this->complexArchive->current()->getPath();
- } while ( $this->complexArchive->next() );
- $mytar = "$dir/my_archive.tar";
- $bf = new ezcArchiveBlockFile( $mytar, true );
- $archive = ezcArchive::getTarInstance( $bf, $this->tarMimeFormat );
- $archive->appendToCurrent( $files, $src );
- $archive->close();
- exec( "tar -cf $dir/gnutar.tar --format=" . $this->tarFormat . " -C $src files" );
- $this->assertEquals( file_get_contents( "$dir/gnutar.tar" ), file_get_contents( $mytar ) );
- unset( $archive );
- unset( $bf );
- }
- /**
- * Test for issue ZETACOMP-8: Double extraction causes empty file
- *
- * The failure happens only with some tarballs. The easiest way to create
- * such failing one is to remove some of the nul characters which are
- * appended to the file's content to continue the block.
- */
- public function testDoubleExtraction()
- {
- $archive = ezcArchive::open( dirname( dirname( __FILE__ ) ) . "/data/tar_v7_truncated_block.tar" );
- $dir = $this->getTempDir();
- foreach ( $archive as $entry )
- {
- if ( $entry->getPath() === "file1" )
- {
- $archive->extractCurrent( $dir );
- // break intentionally omitted.
- }
- }
- $archive->extract( $dir );
- $this->assertEquals( 13, filesize( "$dir/file1" ) );
- }
- public static function suite()
- {
- return new PHPUnit_Framework_TestSuite( __CLASS__ );
- }
- }
- ?>