| <?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 ); |
| } |
| |
| public static function suite() |
| { |
| return new PHPUnit_Framework_TestSuite( __CLASS__ ); |
| } |
| } |
| ?> |