2014-04-02 14:23:22 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Andreas Fischer <bantu@phpbb.com>
|
|
|
|
* @copyright MMXIV Andreas Fischer
|
|
|
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
|
|
|
*/
|
|
|
|
|
2014-06-01 19:13:20 +00:00
|
|
|
class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
|
2014-04-02 14:23:22 +00:00
|
|
|
{
|
|
|
|
static protected $scratchDir;
|
|
|
|
static protected $exampleData;
|
|
|
|
static protected $exampleDataLength;
|
|
|
|
|
|
|
|
static public function setUpBeforeClass()
|
|
|
|
{
|
|
|
|
if (getenv('TRAVIS') && version_compare(PHP_VERSION, '5.3.3', '<=')) {
|
|
|
|
self::markTestIncomplete(
|
|
|
|
'This test hangs on Travis CI on PHP 5.3.3 and below.'
|
|
|
|
);
|
|
|
|
}
|
2014-05-21 15:29:08 +00:00
|
|
|
|
2014-04-02 14:23:22 +00:00
|
|
|
parent::setUpBeforeClass();
|
|
|
|
|
|
|
|
self::$scratchDir = uniqid('phpseclib-sftp-scratch-');
|
|
|
|
|
|
|
|
self::$exampleData = str_repeat('abcde12345', 1000);
|
|
|
|
self::$exampleDataLength = 10000;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testConstructor()
|
|
|
|
{
|
|
|
|
$sftp = new Net_SFTP($this->getEnv('SSH_HOSTNAME'));
|
|
|
|
|
|
|
|
$this->assertTrue(
|
|
|
|
is_object($sftp),
|
|
|
|
'Could not construct NET_SFTP object.'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testConstructor
|
|
|
|
*/
|
|
|
|
public function testPasswordLogin($sftp)
|
|
|
|
{
|
|
|
|
$username = $this->getEnv('SSH_USERNAME');
|
|
|
|
$password = $this->getEnv('SSH_PASSWORD');
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->login($username, $password),
|
|
|
|
'SSH2/SFTP login using password failed.'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testPasswordLogin
|
|
|
|
*/
|
|
|
|
public function testPwdHome($sftp)
|
|
|
|
{
|
|
|
|
$this->assertEquals(
|
|
|
|
$this->getEnv('SSH_HOME'),
|
|
|
|
$sftp->pwd(),
|
|
|
|
'Failed asserting that pwd() returns home directory after login.'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testPwdHome
|
|
|
|
*/
|
|
|
|
public function testMkDirScratch($sftp)
|
|
|
|
{
|
|
|
|
$dirname = self::$scratchDir;
|
|
|
|
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->mkdir($dirname),
|
|
|
|
"Failed asserting that a new scratch directory $dirname could " .
|
|
|
|
'be created.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertFalse(
|
|
|
|
$sftp->mkdir($dirname),
|
|
|
|
"Failed asserting that a new scratch directory $dirname could " .
|
|
|
|
'not be created (because it already exists).'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testMkDirScratch
|
|
|
|
*/
|
|
|
|
public function testChDirScratch($sftp)
|
|
|
|
{
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->chdir(self::$scratchDir),
|
|
|
|
sprintf(
|
|
|
|
'Failed asserting that working directory could be changed ' .
|
|
|
|
'to scratch directory %s.',
|
|
|
|
self::$scratchDir
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$pwd = $sftp->pwd();
|
|
|
|
|
|
|
|
$this->assertStringStartsWith(
|
|
|
|
$this->getEnv('SSH_HOME'),
|
|
|
|
$pwd,
|
|
|
|
'Failed asserting that the home directory is a prefix of the ' .
|
|
|
|
'current working directory.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertStringEndsWith(
|
|
|
|
self::$scratchDir,
|
|
|
|
$pwd,
|
|
|
|
'Failed asserting that the scratch directory name is a suffix ' .
|
|
|
|
'of the current working directory.'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
2014-05-21 15:29:08 +00:00
|
|
|
/**
|
|
|
|
* @depends testChDirScratch
|
|
|
|
*/
|
|
|
|
public function testStatOnDir($sftp)
|
|
|
|
{
|
2014-05-21 22:38:04 +00:00
|
|
|
$this->assertNotSame(
|
|
|
|
array(),
|
|
|
|
$sftp->stat('.'),
|
|
|
|
'Failed asserting that the cwd has a non-empty stat.'
|
2014-05-21 15:29:08 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
2014-04-02 14:23:22 +00:00
|
|
|
/**
|
2014-05-21 22:37:15 +00:00
|
|
|
* @depends testStatOnDir
|
2014-04-02 14:23:22 +00:00
|
|
|
*/
|
|
|
|
public function testPutSizeGetFile($sftp)
|
|
|
|
{
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->put('file1.txt', self::$exampleData),
|
|
|
|
'Failed asserting that example data could be successfully put().'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
self::$exampleDataLength,
|
|
|
|
$sftp->size('file1.txt'),
|
|
|
|
'Failed asserting that put example data has the expected length'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
self::$exampleData,
|
|
|
|
$sftp->get('file1.txt'),
|
|
|
|
'Failed asserting that get() returns expected example data.'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
2014-05-21 15:29:08 +00:00
|
|
|
/**
|
|
|
|
* @depends testPutSizeGetFile
|
|
|
|
*/
|
2014-06-09 14:22:30 +00:00
|
|
|
public function testTouch($sftp)
|
|
|
|
{
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->touch('file2.txt'),
|
|
|
|
'Failed asserting that touch() successfully ran.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->file_exists('file2.txt'),
|
|
|
|
'Failed asserting that touch()\'d file exists'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-06-09 14:46:31 +00:00
|
|
|
* @depends testTouch
|
2014-06-09 14:22:30 +00:00
|
|
|
*/
|
|
|
|
public function testTruncate($sftp)
|
|
|
|
{
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->touch('file3.txt'),
|
|
|
|
'Failed asserting that touch() successfully ran.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->truncate('file3.txt', 1024 * 1024),
|
|
|
|
'Failed asserting that touch() successfully ran.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
1024 * 1024,
|
|
|
|
$sftp->size('file3.txt'),
|
|
|
|
'Failed asserting that truncate()\'d file has the expected length'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testTruncate
|
|
|
|
*/
|
2014-05-21 15:29:08 +00:00
|
|
|
public function testChDirOnFile($sftp)
|
|
|
|
{
|
|
|
|
$this->assertFalse(
|
|
|
|
$sftp->chdir('file1.txt'),
|
|
|
|
'Failed to assert that the cwd cannot be changed to a file'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
2014-04-02 14:23:22 +00:00
|
|
|
/**
|
2014-05-21 22:37:15 +00:00
|
|
|
* @depends testChDirOnFile
|
2014-04-02 14:23:22 +00:00
|
|
|
*/
|
2014-05-13 23:11:19 +00:00
|
|
|
public function testFileExistsIsFileIsDirFile($sftp)
|
|
|
|
{
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->file_exists('file1.txt'),
|
|
|
|
'Failed asserting that file_exists() on example file returns true.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->is_file('file1.txt'),
|
|
|
|
'Failed asserting that is_file() on example file returns true.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertFalse(
|
|
|
|
$sftp->is_dir('file1.txt'),
|
|
|
|
'Failed asserting that is_dir() on example file returns false.'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testFileExistsIsFileIsDirFile
|
|
|
|
*/
|
|
|
|
public function testFileExistsIsFileIsDirFileNonexistent($sftp)
|
|
|
|
{
|
|
|
|
$this->assertFalse(
|
2014-06-09 14:22:30 +00:00
|
|
|
$sftp->file_exists('file4.txt'),
|
2014-05-13 23:11:19 +00:00
|
|
|
'Failed asserting that a nonexistent file does not exist.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertFalse(
|
2014-06-09 14:22:30 +00:00
|
|
|
$sftp->is_file('file4.txt'),
|
2014-05-13 23:11:19 +00:00
|
|
|
'Failed asserting that is_file() on nonexistent file returns false.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertFalse(
|
2014-06-09 14:22:30 +00:00
|
|
|
$sftp->is_dir('file4.txt'),
|
2014-05-13 23:11:19 +00:00
|
|
|
'Failed asserting that is_dir() on nonexistent file returns false.'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
2014-06-09 14:22:30 +00:00
|
|
|
/**
|
|
|
|
* @depends testFileExistsIsFileIsDirFileNonexistent
|
|
|
|
*/
|
|
|
|
public function testSortOrder($sftp)
|
|
|
|
{
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->mkdir('temp'),
|
|
|
|
"Failed asserting that a new scratch directory temp could " .
|
|
|
|
'be created.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$sftp->setListOrder('filename', SORT_DESC);
|
|
|
|
|
|
|
|
$list = $sftp->nlist();
|
|
|
|
$expected = array('.', '..', 'temp', 'file3.txt', 'file2.txt', 'file1.txt');
|
|
|
|
|
2014-06-09 14:42:07 +00:00
|
|
|
$this->assertSame(
|
2014-06-09 14:22:30 +00:00
|
|
|
$list,
|
|
|
|
$expected,
|
|
|
|
'Failed asserting that list sorted correctly.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$sftp->setListOrder('filename', SORT_ASC);
|
|
|
|
|
|
|
|
$list = $sftp->nlist();
|
|
|
|
$expected = array('.', '..', 'temp', 'file1.txt', 'file2.txt', 'file3.txt');
|
|
|
|
|
2014-06-09 14:42:07 +00:00
|
|
|
$this->assertSame(
|
2014-06-09 14:22:30 +00:00
|
|
|
$list,
|
|
|
|
$expected,
|
|
|
|
'Failed asserting that list sorted correctly.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$sftp->setListOrder('size', SORT_DESC);
|
|
|
|
|
|
|
|
$files = $sftp->nlist();
|
|
|
|
|
|
|
|
$last_size = 0x7FFFFFFF;
|
|
|
|
foreach ($files as $file) {
|
|
|
|
if ($sftp->is_file($file)) {
|
|
|
|
$cur_size = $sftp->size($file);
|
|
|
|
$this->assertLessThanOrEqual(
|
|
|
|
$last_size, $cur_size,
|
|
|
|
'Failed asserting that nlist() is in descending order'
|
|
|
|
);
|
|
|
|
$last_size = $cur_size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
2014-05-13 23:11:19 +00:00
|
|
|
/**
|
2014-06-09 16:33:17 +00:00
|
|
|
* @depends testSortOrder
|
2014-05-13 23:11:19 +00:00
|
|
|
*/
|
2014-06-19 14:00:23 +00:00
|
|
|
public function testSymlink($sftp)
|
|
|
|
{
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->symlink('symlink', 'file3.txt'),
|
|
|
|
'Failed asserting that a symlink could be created'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testSymlink
|
|
|
|
*/
|
|
|
|
public function testReadlink($sftp)
|
|
|
|
{
|
|
|
|
$this->assertInternalType('string', $sftp->readlink('symlink'),
|
2014-06-19 15:42:20 +00:00
|
|
|
'Failed asserting that a symlink\'s target could be read'
|
2014-06-19 14:00:23 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testSortOrder
|
|
|
|
*/
|
2014-04-02 14:23:22 +00:00
|
|
|
public function testChDirUpHome($sftp)
|
|
|
|
{
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->chdir('../'),
|
|
|
|
'Failed asserting that directory could be changed one level up.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
$this->getEnv('SSH_HOME'),
|
|
|
|
$sftp->pwd(),
|
|
|
|
'Failed asserting that pwd() returns home directory.'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testChDirUpHome
|
|
|
|
*/
|
2014-05-13 23:11:19 +00:00
|
|
|
public function testFileExistsIsFileIsDirDir($sftp)
|
|
|
|
{
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->file_exists(self::$scratchDir),
|
|
|
|
'Failed asserting that file_exists() on scratch dir returns true.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertFalse(
|
|
|
|
$sftp->is_file(self::$scratchDir),
|
|
|
|
'Failed asserting that is_file() on example file returns false.'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->is_dir(self::$scratchDir),
|
|
|
|
'Failed asserting that is_dir() on example file returns true.'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testFileExistsIsFileIsDirDir
|
|
|
|
*/
|
2014-04-02 14:23:22 +00:00
|
|
|
public function testRmDirScratch($sftp)
|
|
|
|
{
|
|
|
|
$this->assertFalse(
|
|
|
|
$sftp->rmdir(self::$scratchDir),
|
|
|
|
'Failed asserting that non-empty scratch directory could ' .
|
|
|
|
'not be deleted using rmdir().'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testRmDirScratch
|
|
|
|
*/
|
|
|
|
public function testDeleteRecursiveScratch($sftp)
|
|
|
|
{
|
|
|
|
$this->assertTrue(
|
|
|
|
$sftp->delete(self::$scratchDir),
|
|
|
|
'Failed asserting that non-empty scratch directory could ' .
|
|
|
|
'be deleted using recursive delete().'
|
|
|
|
);
|
|
|
|
|
|
|
|
return $sftp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testDeleteRecursiveScratch
|
|
|
|
*/
|
|
|
|
public function testRmDirScratchNonexistent($sftp)
|
|
|
|
{
|
|
|
|
$this->assertFalse(
|
|
|
|
$sftp->rmdir(self::$scratchDir),
|
|
|
|
'Failed asserting that nonexistent scratch directory could ' .
|
|
|
|
'not be deleted using rmdir().'
|
|
|
|
);
|
|
|
|
}
|
2014-06-09 14:44:27 +00:00
|
|
|
}
|