Merge pull request #10458 from owncloud/fix-tar-tests

temporarily disable TAR tests on travis
This commit is contained in:
Lukas Reschke 2014-08-21 10:07:05 +02:00
commit 691db8e26e
2 changed files with 140 additions and 115 deletions

View File

@ -8,10 +8,10 @@
require_once OC::$THIRDPARTYROOT . '/3rdparty/Archive/Tar.php'; require_once OC::$THIRDPARTYROOT . '/3rdparty/Archive/Tar.php';
class OC_Archive_TAR extends OC_Archive{ class OC_Archive_TAR extends OC_Archive {
const PLAIN=0; const PLAIN = 0;
const GZIP=1; const GZIP = 1;
const BZIP=2; const BZIP = 2;
private $fileList; private $fileList;
private $cachedHeaders; private $cachedHeaders;
@ -19,27 +19,28 @@ class OC_Archive_TAR extends OC_Archive{
/** /**
* @var Archive_Tar tar * @var Archive_Tar tar
*/ */
private $tar=null; private $tar = null;
private $path; private $path;
/** /**
* @param string $source * @param string $source
*/ */
function __construct($source) { function __construct($source) {
$types=array(null, 'gz', 'bz'); $types = array(null, 'gz', 'bz');
$this->path=$source; $this->path = $source;
$this->tar=new Archive_Tar($source, $types[self::getTarType($source)]); $this->tar = new Archive_Tar($source, $types[self::getTarType($source)]);
} }
/** /**
* try to detect the type of tar compression * try to detect the type of tar compression
*
* @param string $file * @param string $file
* @return integer * @return integer
*/ */
static public function getTarType($file) { static public function getTarType($file) {
if(strpos($file, '.')) { if (strpos($file, '.')) {
$extension=substr($file, strrpos($file, '.')); $extension = substr($file, strrpos($file, '.'));
switch($extension) { switch ($extension) {
case '.gz': case '.gz':
case '.tgz': case '.tgz':
return self::GZIP; return self::GZIP;
@ -51,79 +52,79 @@ class OC_Archive_TAR extends OC_Archive{
default: default:
return self::PLAIN; return self::PLAIN;
} }
}else{ } else {
return self::PLAIN; return self::PLAIN;
} }
} }
/** /**
* add an empty folder to the archive * add an empty folder to the archive
*
* @param string $path * @param string $path
* @return bool * @return bool
*/ */
function addFolder($path) { function addFolder($path) {
$tmpBase=OC_Helper::tmpFolder(); $tmpBase = OC_Helper::tmpFolder();
if(substr($path, -1, 1)!='/') { if (substr($path, -1, 1) != '/') {
$path.='/'; $path .= '/';
} }
if($this->fileExists($path)) { if ($this->fileExists($path)) {
return false; return false;
} }
$parts=explode('/', $path); $parts = explode('/', $path);
$folder=$tmpBase; $folder = $tmpBase;
foreach($parts as $part) { foreach ($parts as $part) {
$folder.='/'.$part; $folder .= '/' . $part;
if(!is_dir($folder)) { if (!is_dir($folder)) {
mkdir($folder); mkdir($folder);
} }
} }
$result=$this->tar->addModify(array($tmpBase.$path), '', $tmpBase); $result = $this->tar->addModify(array($tmpBase . $path), '', $tmpBase);
rmdir($tmpBase.$path); rmdir($tmpBase . $path);
$this->fileList=false; $this->fileList = false;
$this->cachedHeaders=false; $this->cachedHeaders = false;
return $result; return $result;
} }
/** /**
* add a file to the archive * add a file to the archive
*
* @param string $path * @param string $path
* @param string $source either a local file or string data * @param string $source either a local file or string data
* @return bool * @return bool
*/ */
function addFile($path, $source='') { function addFile($path, $source = '') {
if($this->fileExists($path)) { if ($this->fileExists($path)) {
$this->remove($path); $this->remove($path);
} }
if($source and $source[0]=='/' and file_exists($source)) { if ($source and $source[0] == '/' and file_exists($source)) {
$header=array(); $source = file_get_contents($source);
$dummy='';
$this->tar->_openAppend();
$result=$this->tar->_addfile($source, $header, $dummy, $dummy, $path);
}else{
$result=$this->tar->addString($path, $source);
} }
$this->fileList=false; $result = $this->tar->addString($path, $source);
$this->cachedHeaders=false; $this->fileList = false;
$this->cachedHeaders = false;
return $result; return $result;
} }
/** /**
* rename a file or folder in the archive * rename a file or folder in the archive
*
* @param string $source * @param string $source
* @param string $dest * @param string $dest
* @return bool * @return bool
*/ */
function rename($source, $dest) { function rename($source, $dest) {
//no proper way to delete, rename entire archive, rename file and remake archive //no proper way to delete, rename entire archive, rename file and remake archive
$tmp=OCP\Files::tmpFolder(); $tmp = OCP\Files::tmpFolder();
$this->tar->extract($tmp); $this->tar->extract($tmp);
rename($tmp.$source, $tmp.$dest); rename($tmp . $source, $tmp . $dest);
$this->tar=null; $this->tar = null;
unlink($this->path); unlink($this->path);
$types=array(null, 'gz', 'bz'); $types = array(null, 'gz', 'bz');
$this->tar=new Archive_Tar($this->path, $types[self::getTarType($this->path)]); $this->tar = new Archive_Tar($this->path, $types[self::getTarType($this->path)]);
$this->tar->createModify(array($tmp), '', $tmp.'/'); $this->tar->createModify(array($tmp), '', $tmp . '/');
$this->fileList=false; $this->fileList = false;
$this->cachedHeaders=false; $this->cachedHeaders = false;
return true; return true;
} }
@ -131,14 +132,15 @@ class OC_Archive_TAR extends OC_Archive{
* @param string $file * @param string $file
*/ */
private function getHeader($file) { private function getHeader($file) {
if ( ! $this->cachedHeaders ) { if (!$this->cachedHeaders) {
$this->cachedHeaders = $this->tar->listContent(); $this->cachedHeaders = $this->tar->listContent();
} }
foreach($this->cachedHeaders as $header) { foreach ($this->cachedHeaders as $header) {
if( $file == $header['filename'] if ($file == $header['filename']
or $file.'/' == $header['filename'] or $file . '/' == $header['filename']
or '/'.$file.'/' == $header['filename'] or '/' . $file . '/' == $header['filename']
or '/'.$file == $header['filename']) { or '/' . $file == $header['filename']
) {
return $header; return $header;
} }
} }
@ -147,186 +149,204 @@ class OC_Archive_TAR extends OC_Archive{
/** /**
* get the uncompressed size of a file in the archive * get the uncompressed size of a file in the archive
*
* @param string $path * @param string $path
* @return int * @return int
*/ */
function filesize($path) { function filesize($path) {
$stat=$this->getHeader($path); $stat = $this->getHeader($path);
return $stat['size']; return $stat['size'];
} }
/** /**
* get the last modified time of a file in the archive * get the last modified time of a file in the archive
*
* @param string $path * @param string $path
* @return int * @return int
*/ */
function mtime($path) { function mtime($path) {
$stat=$this->getHeader($path); $stat = $this->getHeader($path);
return $stat['mtime']; return $stat['mtime'];
} }
/** /**
* get the files in a folder * get the files in a folder
*
* @param string $path * @param string $path
* @return array * @return array
*/ */
function getFolder($path) { function getFolder($path) {
$files=$this->getFiles(); $files = $this->getFiles();
$folderContent=array(); $folderContent = array();
$pathLength=strlen($path); $pathLength = strlen($path);
foreach($files as $file) { foreach ($files as $file) {
if($file[0]=='/') { if ($file[0] == '/') {
$file=substr($file, 1); $file = substr($file, 1);
} }
if(substr($file, 0, $pathLength)==$path and $file!=$path) { if (substr($file, 0, $pathLength) == $path and $file != $path) {
$result=substr($file, $pathLength); $result = substr($file, $pathLength);
if($pos=strpos($result, '/')) { if ($pos = strpos($result, '/')) {
$result=substr($result, 0, $pos+1); $result = substr($result, 0, $pos + 1);
} }
if(array_search($result, $folderContent)===false) { if (array_search($result, $folderContent) === false) {
$folderContent[]=$result; $folderContent[] = $result;
} }
} }
} }
return $folderContent; return $folderContent;
} }
/** /**
* get all files in the archive * get all files in the archive
*
* @return array * @return array
*/ */
function getFiles() { function getFiles() {
if($this->fileList) { if ($this->fileList) {
return $this->fileList; return $this->fileList;
} }
if ( ! $this->cachedHeaders ) { if (!$this->cachedHeaders) {
$this->cachedHeaders = $this->tar->listContent(); $this->cachedHeaders = $this->tar->listContent();
} }
$files=array(); $files = array();
foreach($this->cachedHeaders as $header) { foreach ($this->cachedHeaders as $header) {
$files[]=$header['filename']; $files[] = $header['filename'];
} }
$this->fileList=$files; $this->fileList = $files;
return $files; return $files;
} }
/** /**
* get the content of a file * get the content of a file
*
* @param string $path * @param string $path
* @return string * @return string
*/ */
function getFile($path) { function getFile($path) {
return $this->tar->extractInString($path); return $this->tar->extractInString($path);
} }
/** /**
* extract a single file from the archive * extract a single file from the archive
*
* @param string $path * @param string $path
* @param string $dest * @param string $dest
* @return bool * @return bool
*/ */
function extractFile($path, $dest) { function extractFile($path, $dest) {
$tmp=OCP\Files::tmpFolder(); $tmp = OCP\Files::tmpFolder();
if(!$this->fileExists($path)) { if (!$this->fileExists($path)) {
return false; return false;
} }
if($this->fileExists('/'.$path)) { if ($this->fileExists('/' . $path)) {
$success=$this->tar->extractList(array('/'.$path), $tmp); $success = $this->tar->extractList(array('/' . $path), $tmp);
}else{ } else {
$success=$this->tar->extractList(array($path), $tmp); $success = $this->tar->extractList(array($path), $tmp);
} }
if($success) { if ($success) {
rename($tmp.$path, $dest); rename($tmp . $path, $dest);
} }
OCP\Files::rmdirr($tmp); OCP\Files::rmdirr($tmp);
return $success; return $success;
} }
/** /**
* extract the archive * extract the archive
*
* @param string $dest * @param string $dest
* @return bool * @return bool
*/ */
function extract($dest) { function extract($dest) {
return $this->tar->extract($dest); return $this->tar->extract($dest);
} }
/** /**
* check if a file or folder exists in the archive * check if a file or folder exists in the archive
*
* @param string $path * @param string $path
* @return bool * @return bool
*/ */
function fileExists($path) { function fileExists($path) {
$files=$this->getFiles(); $files = $this->getFiles();
if((array_search($path, $files)!==false) or (array_search($path.'/', $files)!==false)) { if ((array_search($path, $files) !== false) or (array_search($path . '/', $files) !== false)) {
return true; return true;
}else{ } else {
$folderPath=$path; $folderPath = $path;
if(substr($folderPath, -1, 1)!='/') { if (substr($folderPath, -1, 1) != '/') {
$folderPath.='/'; $folderPath .= '/';
} }
$pathLength=strlen($folderPath); $pathLength = strlen($folderPath);
foreach($files as $file) { foreach ($files as $file) {
if(strlen($file)>$pathLength and substr($file, 0, $pathLength)==$folderPath) { if (strlen($file) > $pathLength and substr($file, 0, $pathLength) == $folderPath) {
return true; return true;
} }
} }
} }
if($path[0]!='/') {//not all programs agree on the use of a leading / if ($path[0] != '/') { //not all programs agree on the use of a leading /
return $this->fileExists('/'.$path); return $this->fileExists('/' . $path);
}else{ } else {
return false; return false;
} }
} }
/** /**
* remove a file or folder from the archive * remove a file or folder from the archive
*
* @param string $path * @param string $path
* @return bool * @return bool
*/ */
function remove($path) { function remove($path) {
if(!$this->fileExists($path)) { if (!$this->fileExists($path)) {
return false; return false;
} }
$this->fileList=false; $this->fileList = false;
$this->cachedHeaders=false; $this->cachedHeaders = false;
//no proper way to delete, extract entire archive, delete file and remake archive //no proper way to delete, extract entire archive, delete file and remake archive
$tmp=OCP\Files::tmpFolder(); $tmp = OCP\Files::tmpFolder();
$this->tar->extract($tmp); $this->tar->extract($tmp);
OCP\Files::rmdirr($tmp.$path); OCP\Files::rmdirr($tmp . $path);
$this->tar=null; $this->tar = null;
unlink($this->path); unlink($this->path);
$this->reopen(); $this->reopen();
$this->tar->createModify(array($tmp), '', $tmp); $this->tar->createModify(array($tmp), '', $tmp);
return true; return true;
} }
/** /**
* get a file handler * get a file handler
*
* @param string $path * @param string $path
* @param string $mode * @param string $mode
* @return resource * @return resource
*/ */
function getStream($path, $mode) { function getStream($path, $mode) {
if(strrpos($path, '.')!==false) { if (strrpos($path, '.') !== false) {
$ext=substr($path, strrpos($path, '.')); $ext = substr($path, strrpos($path, '.'));
}else{ } else {
$ext=''; $ext = '';
} }
$tmpFile=OCP\Files::tmpFile($ext); $tmpFile = OCP\Files::tmpFile($ext);
if($this->fileExists($path)) { if ($this->fileExists($path)) {
$this->extractFile($path, $tmpFile); $this->extractFile($path, $tmpFile);
}elseif($mode=='r' or $mode=='rb') { } elseif ($mode == 'r' or $mode == 'rb') {
return false; return false;
} }
if($mode=='r' or $mode=='rb') { if ($mode == 'r' or $mode == 'rb') {
return fopen($tmpFile, $mode); return fopen($tmpFile, $mode);
}else{ } else {
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
self::$tempFiles[$tmpFile]=$path; self::$tempFiles[$tmpFile] = $path;
return fopen('close://'.$tmpFile, $mode); return fopen('close://' . $tmpFile, $mode);
} }
} }
private static $tempFiles=array(); private static $tempFiles = array();
/** /**
* write back temporary files * write back temporary files
*/ */
function writeBack($tmpFile) { function writeBack($tmpFile) {
if(isset(self::$tempFiles[$tmpFile])) { if (isset(self::$tempFiles[$tmpFile])) {
$this->addFile(self::$tempFiles[$tmpFile], $tmpFile); $this->addFile(self::$tempFiles[$tmpFile], $tmpFile);
unlink($tmpFile); unlink($tmpFile);
} }
@ -336,11 +356,11 @@ class OC_Archive_TAR extends OC_Archive{
* reopen the archive to ensure everything is written * reopen the archive to ensure everything is written
*/ */
private function reopen() { private function reopen() {
if($this->tar) { if ($this->tar) {
$this->tar->_close(); $this->tar->_close();
$this->tar=null; $this->tar = null;
} }
$types=array(null, 'gz', 'bz'); $types = array(null, 'gz', 'bz');
$this->tar=new Archive_Tar($this->path, $types[self::getTarType($this->path)]); $this->tar = new Archive_Tar($this->path, $types[self::getTarType($this->path)]);
} }
} }

View File

@ -8,8 +8,14 @@
require_once 'archive.php'; require_once 'archive.php';
if (!OC_Util::runningOnWindows()) {
class Test_Archive_TAR extends Test_Archive { class Test_Archive_TAR extends Test_Archive {
public function setUp() {
if (OC_Util::runningOnWindows()) {
$this->markTestSkipped('tar archives are not supported on windows');
}
parent::setUp();
}
protected function getExisting() { protected function getExisting() {
$dir = OC::$SERVERROOT . '/tests/data'; $dir = OC::$SERVERROOT . '/tests/data';
return new OC_Archive_TAR($dir . '/data.tar.gz'); return new OC_Archive_TAR($dir . '/data.tar.gz');
@ -19,4 +25,3 @@ class Test_Archive_TAR extends Test_Archive {
return new OC_Archive_TAR(OCP\Files::tmpFile('.tar.gz')); return new OC_Archive_TAR(OCP\Files::tmpFile('.tar.gz'));
} }
} }
}