cms/drupal/modules/simpletest/tests/filetransfer.test
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 
       
     4 class FileTranferTest extends DrupalWebTestCase {
       
     5   protected $hostname = 'localhost';
       
     6   protected $username = 'drupal';
       
     7   protected $password = 'password';
       
     8   protected $port = '42';
       
     9 
       
    10   public static function getInfo() {
       
    11     return array(
       
    12       'name' => 'FileTransfer unit tests',
       
    13       'description' => 'Test that the jail is respected and that protocols using recursive file move operations work.',
       
    14       'group' => 'System'
       
    15     );
       
    16   }
       
    17 
       
    18   function setUp() {
       
    19     parent::setUp();
       
    20     $this->testConnection = TestFileTransfer::factory(DRUPAL_ROOT, array('hostname' => $this->hostname, 'username' => $this->username, 'password' => $this->password, 'port' => $this->port));
       
    21   }
       
    22 
       
    23   function _getFakeModuleFiles() {
       
    24     $files = array(
       
    25       'fake.module',
       
    26       'fake.info',
       
    27       'theme' => array(
       
    28         'fake.tpl.php'
       
    29       ),
       
    30       'inc' => array(
       
    31         'fake.inc'
       
    32       )
       
    33     );
       
    34     return $files;
       
    35   }
       
    36 
       
    37   function _buildFakeModule() {
       
    38     $location = 'temporary://fake';
       
    39     if (is_dir($location)) {
       
    40       $ret = 0;
       
    41       $output = array();
       
    42       exec('rm -Rf ' . escapeshellarg($location), $output, $ret);
       
    43       if ($ret != 0) {
       
    44         throw new Exception('Error removing fake module directory.');
       
    45       }
       
    46     }
       
    47 
       
    48     $files = $this->_getFakeModuleFiles();
       
    49     $this->_writeDirectory($location, $files);
       
    50     return $location;
       
    51   }
       
    52 
       
    53   function _writeDirectory($base, $files = array()) {
       
    54     mkdir($base);
       
    55     foreach ($files as $key => $file) {
       
    56       if (is_array($file)) {
       
    57         $this->_writeDirectory($base . DIRECTORY_SEPARATOR . $key, $file);
       
    58       }
       
    59       else {
       
    60         //just write the filename into the file
       
    61         file_put_contents($base . DIRECTORY_SEPARATOR . $file, $file);
       
    62       }
       
    63     }
       
    64   }
       
    65 
       
    66   function testJail() {
       
    67     $source = $this->_buildFakeModule();
       
    68 
       
    69     // This convoluted piece of code is here because our testing framework does
       
    70     // not support expecting exceptions.
       
    71     $gotit = FALSE;
       
    72     try {
       
    73       $this->testConnection->copyDirectory($source, '/tmp');
       
    74     }
       
    75     catch (FileTransferException $e) {
       
    76       $gotit = TRUE;
       
    77     }
       
    78     $this->assertTrue($gotit, 'Was not able to copy a directory outside of the jailed area.');
       
    79 
       
    80     $gotit = TRUE;
       
    81     try {
       
    82       $this->testConnection->copyDirectory($source, DRUPAL_ROOT . '/'. variable_get('file_public_path', conf_path() . '/files'));
       
    83     }
       
    84     catch (FileTransferException $e) {
       
    85       $gotit = FALSE;
       
    86     }
       
    87     $this->assertTrue($gotit, 'Was able to copy a directory inside of the jailed area');
       
    88   }
       
    89 }
       
    90 
       
    91 /**
       
    92  * Mock FileTransfer object for test case.
       
    93  */
       
    94 class TestFileTransfer extends FileTransfer {
       
    95   protected $host = NULL;
       
    96   protected $username = NULL;
       
    97   protected $password = NULL;
       
    98   protected $port = NULL;
       
    99 
       
   100   /**
       
   101    * This is for testing the CopyRecursive logic.
       
   102    */
       
   103   public $shouldIsDirectoryReturnTrue = FALSE;
       
   104 
       
   105   function __construct($jail, $username, $password, $hostname = 'localhost', $port = 9999) {
       
   106     parent::__construct($jail, $username, $password, $hostname, $port);
       
   107   }
       
   108 
       
   109   static function factory($jail, $settings) {
       
   110     return new TestFileTransfer($jail, $settings['username'], $settings['password'], $settings['hostname'], $settings['port']);
       
   111   }
       
   112 
       
   113   function connect() {
       
   114     $parts = explode(':', $this->hostname);
       
   115     $port = (count($parts) == 2) ? $parts[1] : $this->port;
       
   116     $this->connection = new MockTestConnection();
       
   117     $this->connection->connectionString = 'test://' . urlencode($this->username) . ':' . urlencode($this->password) . "@$this->host:$this->port/";
       
   118   }
       
   119 
       
   120   function copyFileJailed($source, $destination) {
       
   121     $this->connection->run("copyFile $source $destination");
       
   122   }
       
   123 
       
   124   protected function removeDirectoryJailed($directory) {
       
   125     $this->connection->run("rmdir $directory");
       
   126   }
       
   127 
       
   128   function createDirectoryJailed($directory) {
       
   129     $this->connection->run("mkdir $directory");
       
   130   }
       
   131 
       
   132   function removeFileJailed($destination) {
       
   133     if (!ftp_delete($this->connection, $item)) {
       
   134       throw new FileTransferException('Unable to remove to file @file.', NULL, array('@file' => $item));
       
   135     }
       
   136   }
       
   137 
       
   138   function isDirectory($path) {
       
   139     return $this->shouldIsDirectoryReturnTrue;
       
   140   }
       
   141 
       
   142   function isFile($path) {
       
   143     return FALSE;
       
   144   }
       
   145 
       
   146   function chmodJailed($path, $mode, $recursive) {
       
   147     return;
       
   148   }
       
   149 }
       
   150 
       
   151 /**
       
   152  * Mock connection object for test case.
       
   153  */
       
   154 class MockTestConnection {
       
   155 
       
   156   var $commandsRun = array();
       
   157   var $connectionString;
       
   158 
       
   159   function run($cmd) {
       
   160     $this->commandsRun[] = $cmd;
       
   161   }
       
   162 
       
   163   function flushCommands() {
       
   164     $out = $this->commandsRun;
       
   165     $this->commandsRun = array();
       
   166     return $out;
       
   167   }
       
   168 }