TempManagerTest.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test;
  8. use bantu\IniGetWrapper\IniGetWrapper;
  9. use OCP\IConfig;
  10. use Psr\Log\LoggerInterface;
  11. class TempManagerTest extends \Test\TestCase {
  12. protected $baseDir = null;
  13. protected function setUp(): void {
  14. parent::setUp();
  15. $this->baseDir = $this->getManager()->getTempBaseDir() . $this->getUniqueID('/oc_tmp_test');
  16. if (!is_dir($this->baseDir)) {
  17. mkdir($this->baseDir);
  18. }
  19. }
  20. protected function tearDown(): void {
  21. if ($this->baseDir !== null) {
  22. \OC_Helper::rmdirr($this->baseDir);
  23. }
  24. $this->baseDir = null;
  25. parent::tearDown();
  26. }
  27. /**
  28. * @param ?LoggerInterface $logger
  29. * @param ?IConfig $config
  30. * @return \OC\TempManager
  31. */
  32. protected function getManager($logger = null, $config = null) {
  33. if (!$logger) {
  34. $logger = $this->createMock(LoggerInterface::class);
  35. }
  36. if (!$config) {
  37. $config = $this->createMock(IConfig::class);
  38. $config->method('getSystemValue')
  39. ->with('tempdirectory', null)
  40. ->willReturn('/tmp');
  41. }
  42. $iniGetWrapper = $this->createMock(IniGetWrapper::class);
  43. $manager = new \OC\TempManager($logger, $config, $iniGetWrapper);
  44. if ($this->baseDir) {
  45. $manager->overrideTempBaseDir($this->baseDir);
  46. }
  47. return $manager;
  48. }
  49. public function testGetFile(): void {
  50. $manager = $this->getManager();
  51. $file = $manager->getTemporaryFile('txt');
  52. $this->assertStringEndsWith('.txt', $file);
  53. $this->assertTrue(is_file($file));
  54. $this->assertTrue(is_writable($file));
  55. file_put_contents($file, 'bar');
  56. $this->assertEquals('bar', file_get_contents($file));
  57. }
  58. public function testGetFolder(): void {
  59. $manager = $this->getManager();
  60. $folder = $manager->getTemporaryFolder();
  61. $this->assertStringEndsWith('/', $folder);
  62. $this->assertTrue(is_dir($folder));
  63. $this->assertTrue(is_writable($folder));
  64. file_put_contents($folder . 'foo.txt', 'bar');
  65. $this->assertEquals('bar', file_get_contents($folder . 'foo.txt'));
  66. }
  67. public function testCleanFiles(): void {
  68. $manager = $this->getManager();
  69. $file1 = $manager->getTemporaryFile('txt');
  70. $file2 = $manager->getTemporaryFile('txt');
  71. $this->assertTrue(file_exists($file1));
  72. $this->assertTrue(file_exists($file2));
  73. $manager->clean();
  74. $this->assertFalse(file_exists($file1));
  75. $this->assertFalse(file_exists($file2));
  76. }
  77. public function testCleanFolder(): void {
  78. $manager = $this->getManager();
  79. $folder1 = $manager->getTemporaryFolder();
  80. $folder2 = $manager->getTemporaryFolder();
  81. touch($folder1 . 'foo.txt');
  82. touch($folder1 . 'bar.txt');
  83. $this->assertTrue(file_exists($folder1));
  84. $this->assertTrue(file_exists($folder2));
  85. $this->assertTrue(file_exists($folder1 . 'foo.txt'));
  86. $this->assertTrue(file_exists($folder1 . 'bar.txt'));
  87. $manager->clean();
  88. $this->assertFalse(file_exists($folder1));
  89. $this->assertFalse(file_exists($folder2));
  90. $this->assertFalse(file_exists($folder1 . 'foo.txt'));
  91. $this->assertFalse(file_exists($folder1 . 'bar.txt'));
  92. }
  93. public function testCleanOld(): void {
  94. $manager = $this->getManager();
  95. $oldFile = $manager->getTemporaryFile('txt');
  96. $newFile = $manager->getTemporaryFile('txt');
  97. $folder = $manager->getTemporaryFolder();
  98. $nonOcFile = $this->baseDir . '/foo.txt';
  99. file_put_contents($nonOcFile, 'bar');
  100. $past = time() - 2 * 3600;
  101. touch($oldFile, $past);
  102. touch($folder, $past);
  103. touch($nonOcFile, $past);
  104. $manager2 = $this->getManager();
  105. $manager2->cleanOld();
  106. $this->assertFalse(file_exists($oldFile));
  107. $this->assertFalse(file_exists($folder));
  108. $this->assertTrue(file_exists($nonOcFile));
  109. $this->assertTrue(file_exists($newFile));
  110. }
  111. public function testLogCantCreateFile(): void {
  112. $this->markTestSkipped('TODO: Disable because fails on drone');
  113. $logger = $this->createMock(LoggerInterface::class);
  114. $manager = $this->getManager($logger);
  115. chmod($this->baseDir, 0500);
  116. $logger->expects($this->once())
  117. ->method('warning')
  118. ->with($this->stringContains('Can not create a temporary file in directory'));
  119. $this->assertFalse($manager->getTemporaryFile('txt'));
  120. }
  121. public function testLogCantCreateFolder(): void {
  122. $this->markTestSkipped('TODO: Disable because fails on drone');
  123. $logger = $this->createMock(LoggerInterface::class);
  124. $manager = $this->getManager($logger);
  125. chmod($this->baseDir, 0500);
  126. $logger->expects($this->once())
  127. ->method('warning')
  128. ->with($this->stringContains('Can not create a temporary folder in directory'));
  129. $this->assertFalse($manager->getTemporaryFolder());
  130. }
  131. public function testBuildFileNameWithPostfix(): void {
  132. $logger = $this->createMock(LoggerInterface::class);
  133. $tmpManager = self::invokePrivate(
  134. $this->getManager($logger),
  135. 'buildFileNameWithSuffix',
  136. ['/tmp/myTemporaryFile', 'postfix']
  137. );
  138. $this->assertEquals('/tmp/myTemporaryFile-.postfix', $tmpManager);
  139. }
  140. public function testBuildFileNameWithoutPostfix(): void {
  141. $logger = $this->createMock(LoggerInterface::class);
  142. $tmpManager = self::invokePrivate(
  143. $this->getManager($logger),
  144. 'buildFileNameWithSuffix',
  145. ['/tmp/myTemporaryFile', '']
  146. );
  147. $this->assertEquals('/tmp/myTemporaryFile', $tmpManager);
  148. }
  149. public function testBuildFileNameWithSuffixPathTraversal(): void {
  150. $logger = $this->createMock(LoggerInterface::class);
  151. $tmpManager = self::invokePrivate(
  152. $this->getManager($logger),
  153. 'buildFileNameWithSuffix',
  154. ['foo', '../Traversal\\../FileName']
  155. );
  156. $this->assertStringEndsNotWith('./Traversal\\../FileName', $tmpManager);
  157. $this->assertStringEndsWith('.Traversal..FileName', $tmpManager);
  158. }
  159. public function testGetTempBaseDirFromConfig(): void {
  160. $dir = $this->getManager()->getTemporaryFolder();
  161. $config = $this->createMock(IConfig::class);
  162. $config->expects($this->once())
  163. ->method('getSystemValue')
  164. ->with('tempdirectory', null)
  165. ->willReturn($dir);
  166. $this->baseDir = null; // prevent override
  167. $tmpManager = $this->getManager(null, $config);
  168. $this->assertEquals($dir, $tmpManager->getTempBaseDir());
  169. }
  170. }