You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RepairLegacyStoragesTest.php 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. <?php
  2. /**
  3. * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace Test\Repair;
  9. use OC\Files\Cache\Cache;
  10. use OC\Files\Cache\Storage;
  11. use OCP\Migration\IOutput;
  12. use PHPUnit_Framework_MockObject_MockObject;
  13. use Test\TestCase;
  14. /**
  15. * Tests for the converting of legacy storages to home storages.
  16. *
  17. * @group DB
  18. *
  19. * @see \OC\Repair\RepairLegacyStorages
  20. */
  21. class RepairLegacyStoragesTest extends TestCase {
  22. /** @var \OCP\IDBConnection */
  23. private $connection;
  24. /** @var \OCP\IConfig */
  25. private $config;
  26. private $user;
  27. /** @var \OC\Repair\RepairLegacyStorages */
  28. private $repair;
  29. private $dataDir;
  30. private $oldDataDir;
  31. private $legacyStorageId;
  32. private $newStorageId;
  33. /** @var IOutput | PHPUnit_Framework_MockObject_MockObject */
  34. private $outputMock;
  35. protected function setUp() {
  36. parent::setUp();
  37. $this->config = \OC::$server->getConfig();
  38. $this->connection = \OC::$server->getDatabaseConnection();
  39. $this->oldDataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/');
  40. $this->repair = new \OC\Repair\RepairLegacyStorages($this->config, $this->connection);
  41. $this->outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
  42. ->disableOriginalConstructor()
  43. ->getMock();
  44. }
  45. protected function tearDown() {
  46. $user = \OC::$server->getUserManager()->get($this->user);
  47. if ($user) {
  48. $user->delete();
  49. }
  50. $sql = 'DELETE FROM `*PREFIX*storages`';
  51. $this->connection->executeQuery($sql);
  52. $sql = 'DELETE FROM `*PREFIX*filecache`';
  53. $this->connection->executeQuery($sql);
  54. $this->config->setSystemValue('datadirectory', $this->oldDataDir);
  55. $this->config->setAppValue('core', 'repairlegacystoragesdone', 'no');
  56. parent::tearDown();
  57. }
  58. /**
  59. * @param string $dataDir
  60. * @param string $userId
  61. * @throws \Exception
  62. */
  63. function prepareSettings($dataDir, $userId) {
  64. // hard-coded string as we want a predictable fixed length
  65. // no data will be written there
  66. $this->dataDir = $dataDir;
  67. $this->config->setSystemValue('datadirectory', $this->dataDir);
  68. $this->user = $userId;
  69. $this->legacyStorageId = 'local::' . $this->dataDir . $this->user . '/';
  70. $this->newStorageId = 'home::' . $this->user;
  71. \OC::$server->getUserManager()->createUser($this->user, $this->user);
  72. }
  73. /**
  74. * Create a storage entry
  75. *
  76. * @param string $storageId
  77. * @return int
  78. */
  79. private function createStorage($storageId) {
  80. $sql = 'INSERT INTO `*PREFIX*storages` (`id`)'
  81. . ' VALUES (?)';
  82. $storageId = Storage::adjustStorageId($storageId);
  83. $numRows = $this->connection->executeUpdate($sql, array($storageId));
  84. $this->assertSame(1, $numRows);
  85. return (int)\OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*storages');
  86. }
  87. /**
  88. * Create dummy data in the filecache for the given storage numeric id
  89. *
  90. * @param string $storageId storage id
  91. */
  92. private function createData($storageId) {
  93. $cache = new Cache($storageId);
  94. $cache->put(
  95. 'dummyfile.txt',
  96. array('size' => 5, 'mtime' => 12, 'mimetype' => 'text/plain')
  97. );
  98. }
  99. /**
  100. * Test that existing home storages are left alone when valid.
  101. *
  102. * @dataProvider settingsProvider
  103. *
  104. * @param string $dataDir
  105. * @param string $userId
  106. */
  107. public function testNoopWithExistingHomeStorage($dataDir, $userId) {
  108. $this->prepareSettings($dataDir, $userId);
  109. $newStorageNumId = $this->createStorage($this->newStorageId);
  110. $this->repair->run($this->outputMock);
  111. $this->assertNull(Storage::getNumericStorageId($this->legacyStorageId));
  112. $this->assertSame($newStorageNumId, Storage::getNumericStorageId($this->newStorageId));
  113. }
  114. /**
  115. * Test that legacy storages are converted to home storages when
  116. * the latter does not exist.
  117. *
  118. * @dataProvider settingsProvider
  119. *
  120. * @param string $dataDir
  121. * @param string $userId
  122. */
  123. public function testConvertLegacyToHomeStorage($dataDir, $userId) {
  124. $this->prepareSettings($dataDir, $userId);
  125. $legacyStorageNumId = $this->createStorage($this->legacyStorageId);
  126. $this->repair->run($this->outputMock);
  127. $this->assertNull(Storage::getNumericStorageId($this->legacyStorageId));
  128. $this->assertSame($legacyStorageNumId, Storage::getNumericStorageId($this->newStorageId));
  129. }
  130. /**
  131. * Test that legacy storages are converted to home storages
  132. * when home storage already exists but has no data.
  133. *
  134. * @dataProvider settingsProvider
  135. *
  136. * @param string $dataDir
  137. * @param string $userId
  138. */
  139. public function testConvertLegacyToExistingEmptyHomeStorage($dataDir, $userId) {
  140. $this->prepareSettings($dataDir, $userId);
  141. $legacyStorageNumId = $this->createStorage($this->legacyStorageId);
  142. $this->createStorage($this->newStorageId);
  143. $this->createData($this->legacyStorageId);
  144. $this->repair->run($this->outputMock);
  145. $this->assertNull(Storage::getNumericStorageId($this->legacyStorageId));
  146. $this->assertSame($legacyStorageNumId, Storage::getNumericStorageId($this->newStorageId));
  147. }
  148. /**
  149. * Test that legacy storages are converted to home storages
  150. * when home storage already exists and the legacy storage
  151. * has no data.
  152. *
  153. * @dataProvider settingsProvider
  154. *
  155. * @param string $dataDir
  156. * @param string $userId
  157. */
  158. public function testConvertEmptyLegacyToHomeStorage($dataDir, $userId) {
  159. $this->prepareSettings($dataDir, $userId);
  160. $this->createStorage($this->legacyStorageId);
  161. $newStorageNumId = $this->createStorage($this->newStorageId);
  162. $this->createData($this->newStorageId);
  163. $this->repair->run($this->outputMock);
  164. $this->assertNull(Storage::getNumericStorageId($this->legacyStorageId));
  165. $this->assertSame($newStorageNumId, Storage::getNumericStorageId($this->newStorageId));
  166. }
  167. /**
  168. * Test that nothing is done when both conflicting legacy
  169. * and home storage have data.
  170. *
  171. * @dataProvider settingsProvider
  172. *
  173. * @param string $dataDir
  174. * @param string $userId
  175. */
  176. public function testConflictNoop($dataDir, $userId) {
  177. $this->prepareSettings($dataDir, $userId);
  178. $legacyStorageNumId = $this->createStorage($this->legacyStorageId);
  179. $newStorageNumId = $this->createStorage($this->newStorageId);
  180. $this->createData($this->legacyStorageId);
  181. $this->createData($this->newStorageId);
  182. $this->outputMock->expects($this->exactly(2))->method('warning');
  183. $this->repair->run($this->outputMock);
  184. // storages left alone
  185. $this->assertSame($legacyStorageNumId, Storage::getNumericStorageId($this->legacyStorageId));
  186. $this->assertSame($newStorageNumId, Storage::getNumericStorageId($this->newStorageId));
  187. // do not set the done flag
  188. $this->assertNotEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));
  189. }
  190. /**
  191. * Test that the data dir local entry is left alone
  192. *
  193. * @dataProvider settingsProvider
  194. *
  195. * @param string $dataDir
  196. * @param string $userId
  197. */
  198. public function testDataDirEntryNoop($dataDir, $userId) {
  199. $this->prepareSettings($dataDir, $userId);
  200. $storageId = 'local::' . $this->dataDir;
  201. $numId = $this->createStorage($storageId);
  202. $this->repair->run($this->outputMock);
  203. $this->assertSame($numId, Storage::getNumericStorageId($storageId));
  204. }
  205. /**
  206. * Test that external local storages are left alone
  207. *
  208. * @dataProvider settingsProvider
  209. *
  210. * @param string $dataDir
  211. * @param string $userId
  212. */
  213. public function testLocalExtStorageNoop($dataDir, $userId) {
  214. $this->prepareSettings($dataDir, $userId);
  215. $storageId = 'local::/tmp/somedir/' . $this->user;
  216. $numId = $this->createStorage($storageId);
  217. $this->repair->run($this->outputMock);
  218. $this->assertSame($numId, Storage::getNumericStorageId($storageId));
  219. }
  220. /**
  221. * Test that other external storages are left alone
  222. *
  223. * @dataProvider settingsProvider
  224. *
  225. * @param string $dataDir
  226. * @param string $userId
  227. */
  228. public function testExtStorageNoop($dataDir, $userId) {
  229. $this->prepareSettings($dataDir, $userId);
  230. $storageId = 'smb::user@password/tmp/somedir/' . $this->user;
  231. $numId = $this->createStorage($storageId);
  232. $this->repair->run($this->outputMock);
  233. $this->assertSame($numId, Storage::getNumericStorageId($storageId));
  234. }
  235. /**
  236. * Provides data dir and user name
  237. */
  238. function settingsProvider() {
  239. return array(
  240. // regular data dir
  241. array(
  242. '/tmp/oc-autotest/datadir/',
  243. $this->getUniqueID('user_'),
  244. ),
  245. // long datadir / short user
  246. array(
  247. '/tmp/oc-autotest/datadir01234567890123456789012345678901234567890123456789END/',
  248. $this->getUniqueID('user_'),
  249. ),
  250. // short datadir / long user
  251. array(
  252. '/tmp/oc-autotest/datadir/',
  253. 'u123456789012345678901234567890123456789012345678901234567890END', // 64 chars
  254. ),
  255. );
  256. }
  257. /**
  258. * Only run the repair once
  259. */
  260. public function testOnlyRunOnce() {
  261. $this->outputMock->expects($this->exactly(1))->method('info');
  262. $this->prepareSettings('/tmp/oc-autotest/datadir', $this->getUniqueID('user_'));
  263. $this->assertNotEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));
  264. $this->repair->run($this->outputMock);
  265. $this->assertEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));
  266. $this->outputMock->expects($this->never())->method('info');
  267. $this->repair->run($this->outputMock);
  268. $this->assertEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));
  269. }
  270. }