* @copyright MMXIV Andreas Fischer * @license http://www.opensource.org/licenses/mit-license.html MIT License */ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase { 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.' ); } 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; } /** * @depends testChDirScratch */ public function testStatOnDir($sftp) { $this->assertNotSame( array(), $sftp->stat('.'), 'Failed asserting that the cwd has a non-empty stat.' ); return $sftp; } /** * @depends testStatOnDir */ 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; } /** * @depends testPutSizeGetFile */ 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; } /** * @depends testTouch */ 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 */ public function testChDirOnFile($sftp) { $this->assertFalse( $sftp->chdir('file1.txt'), 'Failed to assert that the cwd cannot be changed to a file' ); return $sftp; } /** * @depends testChDirOnFile */ 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( $sftp->file_exists('file4.txt'), 'Failed asserting that a nonexistent file does not exist.' ); $this->assertFalse( $sftp->is_file('file4.txt'), 'Failed asserting that is_file() on nonexistent file returns false.' ); $this->assertFalse( $sftp->is_dir('file4.txt'), 'Failed asserting that is_dir() on nonexistent file returns false.' ); return $sftp; } /** * @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'); $this->assertSame( $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'); $this->assertSame( $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; } /** * @depends testSortOrder */ 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'), 'Failed asserting that a symlink's target could be read' ); } /** * @depends testSortOrder */ 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 */ 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 */ 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().' ); } }