PageRenderTime 44ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/jira-project/jira-components/jira-tests-parent/jira-tests-unit/src/test/java/com/atlassian/jira/index/TestQueueingIndex.java

https://bitbucket.org/ahmed_bilal_360factors/jira7-core
Java | 228 lines | 198 code | 24 blank | 6 comment | 0 complexity | 9dcf9490cff17aa7af6047fff4d276d4 MD5 | raw file
Possible License(s): Apache-2.0
  1. package com.atlassian.jira.index;
  2. import com.atlassian.jira.index.Index.UpdateMode;
  3. import com.atlassian.jira.index.QueueingIndex.CompositeOperation;
  4. import com.atlassian.jira.index.QueueingIndex.FutureOperation;
  5. import com.atlassian.jira.index.QueueingIndex.Task;
  6. import com.google.common.collect.Lists;
  7. import org.junit.Test;
  8. import javax.annotation.Nonnull;
  9. import java.io.IOException;
  10. import java.util.List;
  11. import java.util.concurrent.BlockingQueue;
  12. import java.util.concurrent.CountDownLatch;
  13. import java.util.concurrent.ThreadFactory;
  14. import java.util.concurrent.atomic.AtomicBoolean;
  15. import java.util.concurrent.atomic.AtomicReference;
  16. import static org.junit.Assert.assertArrayEquals;
  17. import static org.junit.Assert.assertEquals;
  18. import static org.junit.Assert.assertFalse;
  19. import static org.junit.Assert.assertNotNull;
  20. import static org.junit.Assert.assertTrue;
  21. import static org.junit.Assert.fail;
  22. public class TestQueueingIndex {
  23. @Test
  24. public void testNewSearcherAfterCreate() throws Exception {
  25. final AtomicBoolean ran = new AtomicBoolean();
  26. final MockOperation operation = new MockOperation() {
  27. @Override
  28. void perform(@Nonnull final Writer writer) throws IOException {
  29. ran.set(true);
  30. }
  31. };
  32. final Index index = new QueueingIndex("TestQueueingIndex", new MockCloseableIndex(), 100);
  33. index.perform(operation).await();
  34. assertTrue(ran.get());
  35. }
  36. @Test
  37. public void testThreadLifeCycle() throws Exception {
  38. final AtomicReference<Thread> thread = new AtomicReference<Thread>();
  39. final AtomicBoolean closed = new AtomicBoolean();
  40. final CloseableIndex index = new QueueingIndex(new ThreadFactory() {
  41. public Thread newThread(final Runnable r) {
  42. thread.set(new Thread(r));
  43. return thread.get();
  44. }
  45. }, new MockCloseableIndex() {
  46. @Override
  47. public void close() {
  48. closed.set(true);
  49. }
  50. }, 100);
  51. index.perform(new MockOperation());
  52. assertNotNull("thread should be created", thread.get());
  53. assertTrue("thread should be alive", thread.get().isAlive());
  54. index.close();
  55. assertTrue("delegate should be closed", closed.get());
  56. assertFalse("thread should be dead", thread.get().isAlive());
  57. // try again to make sure process is repeatable...
  58. thread.set(null);
  59. closed.set(false);
  60. index.perform(new MockOperation());
  61. assertNotNull("thread should be created", thread.get());
  62. assertTrue("thread should be alive", thread.get().isAlive());
  63. index.close();
  64. assertTrue("delegate should be closed", closed.get());
  65. assertFalse("thread should be dead", thread.get().isAlive());
  66. }
  67. @Test
  68. public void testThreadDeath() throws Exception {
  69. final AtomicReference<Thread> thread = new AtomicReference<Thread>();
  70. final AtomicBoolean closed = new AtomicBoolean();
  71. final CloseableIndex index = new QueueingIndex(new ThreadFactory() {
  72. public Thread newThread(final Runnable r) {
  73. thread.set(new Thread(r));
  74. return thread.get();
  75. }
  76. }, new MockCloseableIndex() {
  77. @Override
  78. public void close() {
  79. closed.set(true);
  80. }
  81. }, 100);
  82. index.perform(new MockOperation());
  83. assertNotNull("thread should be created", thread.get());
  84. assertTrue("thread should be alive", thread.get().isAlive());
  85. thread.get().interrupt();
  86. thread.get().join();
  87. assertFalse("delegate should not be closed", closed.get());
  88. assertFalse("thread should be dead", thread.get().isAlive());
  89. // try again to make sure process is repeatable...
  90. thread.set(null);
  91. index.perform(new MockOperation());
  92. assertNotNull("thread should be created", thread.get());
  93. assertTrue("thread should be alive", thread.get().isAlive());
  94. index.close();
  95. assertTrue("delegate should be closed", closed.get());
  96. assertFalse("thread should be dead", thread.get().isAlive());
  97. }
  98. @Test
  99. public void testTaskDrainsAll() throws Exception {
  100. final CloseableIndex delegate = new MockCloseableIndex();
  101. final QueueingIndex index = new QueueingIndex("TestQueueingIndex.testTaskDrainsAll", delegate, 100);
  102. final Task task = index.new Task();
  103. final BlockingQueue<FutureOperation> queue = index.queue;
  104. queue.add(new QueueingIndex.FutureOperation(new MockOperation()));
  105. queue.add(new QueueingIndex.FutureOperation(new MockOperation()));
  106. queue.add(new QueueingIndex.FutureOperation(new MockOperation()));
  107. queue.add(new QueueingIndex.FutureOperation(new MockOperation()));
  108. task.index();
  109. assertTrue("queue should be empty after run", queue.isEmpty());
  110. }
  111. @Test
  112. public void testTaskCompositeBatchModeOverrides() throws Exception {
  113. final List<FutureOperation> operations = Lists.newArrayList(new FutureOperation(new MockOperation()), new FutureOperation(new MockOperation(UpdateMode.BATCH)), new FutureOperation(new MockOperation()));
  114. final CompositeOperation operation = new CompositeOperation(operations);
  115. assertEquals(UpdateMode.BATCH, operation.mode());
  116. }
  117. @Test
  118. public void testTaskBlocksUntilOperationAvailable() throws Exception {
  119. final CloseableIndex delegate = new MockCloseableIndex();
  120. final CountDownLatch started = new CountDownLatch(1);
  121. final CountDownLatch finished = new CountDownLatch(1);
  122. final QueueingIndex index = new QueueingIndex("TestQueueingIndex.testTaskBlocksUntilOperationAvailable", delegate, 100);
  123. final BlockingQueue<FutureOperation> queue = index.queue;
  124. try {
  125. final Task task = index.new Task();
  126. new Thread(new Runnable() {
  127. public void run() {
  128. try {
  129. started.countDown();
  130. task.index();
  131. } catch (final InterruptedException e) {
  132. throw new RuntimeException(e);
  133. }
  134. finished.countDown();
  135. }
  136. }).start();
  137. started.await();
  138. assertEquals(1, finished.getCount());
  139. Thread.sleep(20);
  140. assertEquals(1, finished.getCount());
  141. final MockOperation operation = new MockOperation();
  142. final FutureOperation futureOp = new FutureOperation(operation);
  143. queue.add(futureOp);
  144. finished.await();
  145. futureOp.get();
  146. assertTrue("queue should be empty after run", queue.isEmpty());
  147. assertTrue("operation should have been performed", operation.isPerformed());
  148. } finally {
  149. index.close();
  150. }
  151. }
  152. @Test
  153. public void testNullName() {
  154. try {
  155. new QueueingIndex((String) null, new MockCloseableIndex(), 100);
  156. fail("IllegalArg expected");
  157. } catch (final IllegalArgumentException expected) {
  158. }
  159. }
  160. @Test
  161. public void testNullThreadFactory() {
  162. try {
  163. new QueueingIndex((ThreadFactory) null, new MockCloseableIndex(), 100);
  164. fail("IllegalArg expected");
  165. } catch (final IllegalArgumentException expected) {
  166. }
  167. }
  168. @Test
  169. public void testNullIndex() {
  170. try {
  171. new QueueingIndex("blah", null, 100);
  172. fail("IllegalArg expected");
  173. } catch (final IllegalArgumentException expected) {
  174. }
  175. }
  176. /**
  177. * Add a task that takes a second, perform the operation asynchronously and attempt to close midway through.
  178. * Task should not be interrupted (this would normally be Lucene doing I/O operations).
  179. */
  180. @Test
  181. public void testIndexTasksAreNotInterrupted() throws Exception {
  182. final CloseableIndex delegate = new MockCloseableIndex();
  183. final QueueingIndex index = new QueueingIndex("TestQueueingIndex.testIndexTasksAreNotInterrupted", delegate, 100);
  184. final Boolean[] indexed = {false};
  185. MockOperation operation = new MockOperation() {
  186. @Override
  187. void perform(@Nonnull Writer writer) throws IOException {
  188. try {
  189. Thread.sleep(1000L);
  190. super.perform(writer);
  191. indexed[0] = true;
  192. } catch (InterruptedException e) {
  193. throw new RuntimeException(e);
  194. }
  195. }
  196. };
  197. Index.Result result = index.perform(operation);
  198. Thread.sleep(500L); //Give task some time so spin up
  199. index.close();
  200. ;
  201. result.await();
  202. assertArrayEquals("should have finished index operation.", new Boolean[]{true}, indexed);
  203. }
  204. }