lockingprovider.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. /**
  3. * @author Robin Appelman <icewind@owncloud.com>
  4. *
  5. * @copyright Copyright (c) 2015, ownCloud, Inc.
  6. * @license AGPL-3.0
  7. *
  8. * This code is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License, version 3,
  10. * as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Affero General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Affero General Public License, version 3,
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>
  19. *
  20. */
  21. namespace Test\Lock;
  22. use OCP\Lock\ILockingProvider;
  23. use OCP\Lock\LockedException;
  24. use Test\TestCase;
  25. abstract class LockingProvider extends TestCase {
  26. /**
  27. * @var \OCP\Lock\ILockingProvider
  28. */
  29. protected $instance;
  30. /**
  31. * @return \OCP\Lock\ILockingProvider
  32. */
  33. abstract protected function getInstance();
  34. protected function setUp() {
  35. parent::setUp();
  36. $this->instance = $this->getInstance();
  37. }
  38. public function testExclusiveLock() {
  39. $this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  40. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
  41. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  42. }
  43. public function testSharedLock() {
  44. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  45. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
  46. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  47. }
  48. public function testDoubleSharedLock() {
  49. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  50. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
  51. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  52. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  53. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  54. }
  55. public function testReleaseSharedLock() {
  56. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  57. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
  58. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  59. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  60. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  61. $this->instance->releaseLock('foo', ILockingProvider::LOCK_SHARED);
  62. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  63. $this->instance->releaseLock('foo', ILockingProvider::LOCK_SHARED);
  64. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  65. }
  66. /**
  67. * @expectedException \OCP\Lock\LockedException
  68. */
  69. public function testDoubleExclusiveLock() {
  70. $this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  71. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
  72. $this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  73. }
  74. public function testReleaseExclusiveLock() {
  75. $this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  76. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
  77. $this->instance->releaseLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  78. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
  79. $this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  80. }
  81. /**
  82. * @expectedException \OCP\Lock\LockedException
  83. */
  84. public function testExclusiveLockAfterShared() {
  85. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  86. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  87. $this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  88. }
  89. public function testExclusiveLockAfterSharedReleased() {
  90. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  91. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  92. $this->instance->releaseLock('foo', ILockingProvider::LOCK_SHARED);
  93. $this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  94. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
  95. }
  96. public function testReleaseAll() {
  97. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  98. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  99. $this->instance->acquireLock('bar', ILockingProvider::LOCK_SHARED);
  100. $this->instance->acquireLock('asd', ILockingProvider::LOCK_EXCLUSIVE);
  101. $this->instance->releaseAll();
  102. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  103. $this->assertFalse($this->instance->isLocked('bar', ILockingProvider::LOCK_SHARED));
  104. $this->assertFalse($this->instance->isLocked('asd', ILockingProvider::LOCK_EXCLUSIVE));
  105. }
  106. public function testReleaseAllAfterChange() {
  107. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  108. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  109. $this->instance->acquireLock('bar', ILockingProvider::LOCK_SHARED);
  110. $this->instance->acquireLock('asd', ILockingProvider::LOCK_EXCLUSIVE);
  111. $this->instance->changeLock('bar', ILockingProvider::LOCK_EXCLUSIVE);
  112. $this->instance->releaseAll();
  113. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  114. $this->assertFalse($this->instance->isLocked('bar', ILockingProvider::LOCK_SHARED));
  115. $this->assertFalse($this->instance->isLocked('bar', ILockingProvider::LOCK_EXCLUSIVE));
  116. $this->assertFalse($this->instance->isLocked('asd', ILockingProvider::LOCK_EXCLUSIVE));
  117. }
  118. public function testReleaseAllAfterUnlock() {
  119. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  120. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  121. $this->instance->acquireLock('bar', ILockingProvider::LOCK_SHARED);
  122. $this->instance->acquireLock('asd', ILockingProvider::LOCK_EXCLUSIVE);
  123. $this->instance->releaseLock('bar', ILockingProvider::LOCK_SHARED);
  124. $this->instance->releaseAll();
  125. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  126. $this->assertFalse($this->instance->isLocked('asd', ILockingProvider::LOCK_EXCLUSIVE));
  127. }
  128. public function testReleaseAfterReleaseAll() {
  129. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  130. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  131. $this->instance->releaseAll();
  132. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  133. $this->instance->releaseLock('foo', ILockingProvider::LOCK_SHARED);
  134. }
  135. /**
  136. * @expectedException \OCP\Lock\LockedException
  137. */
  138. public function testSharedLockAfterExclusive() {
  139. $this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  140. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
  141. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  142. }
  143. public function testLockedExceptionHasPathForShared() {
  144. try {
  145. $this->testSharedLockAfterExclusive();
  146. $this->fail('Expected locked exception');
  147. } catch (LockedException $e) {
  148. $this->assertEquals('foo', $e->getPath());
  149. }
  150. }
  151. public function testLockedExceptionHasPathForExclusive() {
  152. try {
  153. $this->testExclusiveLockAfterShared();
  154. $this->fail('Expected locked exception');
  155. } catch (LockedException $e) {
  156. $this->assertEquals('foo', $e->getPath());
  157. }
  158. }
  159. public function testChangeLockToExclusive() {
  160. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  161. $this->instance->changeLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  162. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  163. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
  164. }
  165. public function testChangeLockToShared() {
  166. $this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  167. $this->instance->changeLock('foo', ILockingProvider::LOCK_SHARED);
  168. $this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
  169. $this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
  170. }
  171. /**
  172. * @expectedException \OCP\Lock\LockedException
  173. */
  174. public function testChangeLockToExclusiveDoubleShared() {
  175. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  176. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  177. $this->instance->changeLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  178. }
  179. /**
  180. * @expectedException \OCP\Lock\LockedException
  181. */
  182. public function testChangeLockToExclusiveNoShared() {
  183. $this->instance->changeLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  184. }
  185. /**
  186. * @expectedException \OCP\Lock\LockedException
  187. */
  188. public function testChangeLockToExclusiveFromExclusive() {
  189. $this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  190. $this->instance->changeLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
  191. }
  192. /**
  193. * @expectedException \OCP\Lock\LockedException
  194. */
  195. public function testChangeLockToSharedNoExclusive() {
  196. $this->instance->changeLock('foo', ILockingProvider::LOCK_SHARED);
  197. }
  198. /**
  199. * @expectedException \OCP\Lock\LockedException
  200. */
  201. public function testChangeLockToSharedFromShared() {
  202. $this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
  203. $this->instance->changeLock('foo', ILockingProvider::LOCK_SHARED);
  204. }
  205. }