PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/external/guava/guava-tests/test/com/google/common/collect/QueuesTest.java

https://gitlab.com/brian0218/rk3066_r-box_android4.2.2_sdk
Java | 307 lines | 215 code | 46 blank | 46 comment | 14 complexity | a42cf73d5318bcc8727a8fe5d14772e1 MD5 | raw file
  1. /*
  2. * Copyright (C) 2011 The Guava Authors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.google.common.collect;
  17. import com.google.common.util.concurrent.Uninterruptibles;
  18. import junit.framework.TestCase;
  19. import java.util.Collection;
  20. import java.util.List;
  21. import java.util.concurrent.ArrayBlockingQueue;
  22. import java.util.concurrent.BlockingQueue;
  23. import java.util.concurrent.ExecutorService;
  24. import java.util.concurrent.Executors;
  25. import java.util.concurrent.Future;
  26. import java.util.concurrent.LinkedBlockingQueue;
  27. import java.util.concurrent.PriorityBlockingQueue;
  28. import java.util.concurrent.SynchronousQueue;
  29. import java.util.concurrent.TimeUnit;
  30. /**
  31. * Tests for {@link Queues}.
  32. *
  33. * @author Dimitris Andreou
  34. */
  35. public class QueuesTest extends TestCase {
  36. /*
  37. * All the following tests relate to BlockingQueue methods in Queues.
  38. */
  39. public static List<BlockingQueue<Object>> blockingQueues() {
  40. return ImmutableList.<BlockingQueue<Object>>of(
  41. new LinkedBlockingQueue<Object>(),
  42. new LinkedBlockingQueue<Object>(10),
  43. new SynchronousQueue<Object>(),
  44. new ArrayBlockingQueue<Object>(10),
  45. new PriorityBlockingQueue<Object>(10, Ordering.arbitrary()));
  46. }
  47. private ExecutorService threadPool;
  48. @Override
  49. public void setUp() {
  50. threadPool = Executors.newCachedThreadPool();
  51. }
  52. @Override
  53. public void tearDown() throws InterruptedException {
  54. // notice that if a Producer is interrupted (a bug), the Producer will go into an infinite
  55. // loop, which will be noticed here
  56. threadPool.shutdown();
  57. assertTrue("Some worker didn't finish in time",
  58. threadPool.awaitTermination(1, TimeUnit.SECONDS));
  59. }
  60. private static <T> int drain(BlockingQueue<T> q, Collection<? super T> buffer, int maxElements,
  61. long timeout, TimeUnit unit, boolean interruptibly) throws InterruptedException {
  62. return interruptibly
  63. ? Queues.drain(q, buffer, maxElements, timeout, unit)
  64. : Queues.drainUninterruptibly(q, buffer, maxElements, timeout, unit);
  65. }
  66. public void testMultipleProducers() throws Exception {
  67. for (BlockingQueue<Object> q : blockingQueues()) {
  68. testMultipleProducers(q);
  69. }
  70. }
  71. private void testMultipleProducers(BlockingQueue<Object> q)
  72. throws InterruptedException {
  73. for (boolean interruptibly : new boolean[] { true, false }) {
  74. threadPool.submit(new Producer(q, 20));
  75. threadPool.submit(new Producer(q, 20));
  76. threadPool.submit(new Producer(q, 20));
  77. threadPool.submit(new Producer(q, 20));
  78. threadPool.submit(new Producer(q, 20));
  79. List<Object> buf = Lists.newArrayList();
  80. int elements = drain(q, buf, 100, Long.MAX_VALUE, TimeUnit.NANOSECONDS, interruptibly);
  81. assertEquals(100, elements);
  82. assertEquals(100, buf.size());
  83. assertDrained(q);
  84. }
  85. }
  86. public void testDrainTimesOut() throws Exception {
  87. for (BlockingQueue<Object> q : blockingQueues()) {
  88. testDrainTimesOut(q);
  89. }
  90. }
  91. private void testDrainTimesOut(BlockingQueue<Object> q) throws Exception {
  92. for (boolean interruptibly : new boolean[] { true, false }) {
  93. assertEquals(0, Queues.drain(q, ImmutableList.of(), 1, 10, TimeUnit.MILLISECONDS));
  94. // producing one, will ask for two
  95. Future<?> submitter = threadPool.submit(new Producer(q, 1));
  96. // make sure we time out
  97. long startTime = System.nanoTime();
  98. int drained = drain(q, Lists.newArrayList(), 2, 10, TimeUnit.MILLISECONDS, interruptibly);
  99. assertTrue(drained <= 1);
  100. assertTrue((System.nanoTime() - startTime) >= TimeUnit.MILLISECONDS.toNanos(10));
  101. // If even the first one wasn't there, clean up so that the next test doesn't see an element.
  102. submitter.get();
  103. if (drained == 0) {
  104. assertNotNull(q.poll());
  105. }
  106. }
  107. }
  108. public void testZeroElements() throws Exception {
  109. for (BlockingQueue<Object> q : blockingQueues()) {
  110. testZeroElements(q);
  111. }
  112. }
  113. private void testZeroElements(BlockingQueue<Object> q) throws InterruptedException {
  114. for (boolean interruptibly : new boolean[] { true, false }) {
  115. // asking to drain zero elements
  116. assertEquals(0, drain(q, ImmutableList.of(), 0, 10, TimeUnit.MILLISECONDS, interruptibly));
  117. }
  118. }
  119. public void testEmpty() throws Exception {
  120. for (BlockingQueue<Object> q : blockingQueues()) {
  121. testEmpty(q);
  122. }
  123. }
  124. private void testEmpty(BlockingQueue<Object> q) {
  125. assertDrained(q);
  126. }
  127. public void testNegativeMaxElements() throws Exception {
  128. for (BlockingQueue<Object> q : blockingQueues()) {
  129. testNegativeMaxElements(q);
  130. }
  131. }
  132. private void testNegativeMaxElements(BlockingQueue<Object> q) throws InterruptedException {
  133. threadPool.submit(new Producer(q, 1));
  134. List<Object> buf = Lists.newArrayList();
  135. int elements = Queues.drain(q, buf, -1, Long.MAX_VALUE, TimeUnit.NANOSECONDS);
  136. assertEquals(elements, 0);
  137. assertTrue(buf.isEmpty());
  138. // Clean up produced element to free the producer thread, otherwise it will complain
  139. // when we shutdown the threadpool.
  140. Queues.drain(q, buf, 1, Long.MAX_VALUE, TimeUnit.NANOSECONDS);
  141. }
  142. public void testDrain_throws() throws Exception {
  143. for (BlockingQueue<Object> q : blockingQueues()) {
  144. testDrain_throws(q);
  145. }
  146. }
  147. private void testDrain_throws(BlockingQueue<Object> q) {
  148. threadPool.submit(new Interrupter(Thread.currentThread()));
  149. try {
  150. Queues.drain(q, ImmutableList.of(), 100, Long.MAX_VALUE, TimeUnit.NANOSECONDS);
  151. fail();
  152. } catch (InterruptedException expected) {
  153. }
  154. }
  155. public void testDrainUninterruptibly_doesNotThrow() throws Exception {
  156. for (BlockingQueue<Object> q : blockingQueues()) {
  157. testDrainUninterruptibly_doesNotThrow(q);
  158. }
  159. }
  160. private void testDrainUninterruptibly_doesNotThrow(final BlockingQueue<Object> q) {
  161. final Thread mainThread = Thread.currentThread();
  162. threadPool.submit(new Runnable() {
  163. public void run() {
  164. new Producer(q, 50).run();
  165. new Interrupter(mainThread).run();
  166. new Producer(q, 50).run();
  167. }
  168. });
  169. List<Object> buf = Lists.newArrayList();
  170. int elements =
  171. Queues.drainUninterruptibly(q, buf, 100, Long.MAX_VALUE, TimeUnit.NANOSECONDS);
  172. // so when this drains all elements, we know the thread has also been interrupted in between
  173. assertTrue(Thread.interrupted());
  174. assertEquals(100, elements);
  175. assertEquals(100, buf.size());
  176. }
  177. public void testNewLinkedBlockingQueueCapacity() {
  178. try {
  179. Queues.newLinkedBlockingQueue(0);
  180. fail("Should have thrown IllegalArgumentException");
  181. } catch (IllegalArgumentException expected) {
  182. // any capacity less than 1 should throw IllegalArgumentException
  183. }
  184. assertEquals(1, Queues.newLinkedBlockingQueue(1).remainingCapacity());
  185. assertEquals(11, Queues.newLinkedBlockingQueue(11).remainingCapacity());
  186. }
  187. /**
  188. * Checks that #drain() invocations behave correctly for a drained (empty) queue.
  189. */
  190. private void assertDrained(BlockingQueue<Object> q) {
  191. assertNull(q.peek());
  192. assertInterruptibleDrained(q);
  193. assertUninterruptibleDrained(q);
  194. }
  195. private void assertInterruptibleDrained(BlockingQueue<Object> q) {
  196. // nothing to drain, thus this should wait doing nothing
  197. try {
  198. assertEquals(0, Queues.drain(q, ImmutableList.of(), 0, 10, TimeUnit.MILLISECONDS));
  199. } catch (InterruptedException e) {
  200. throw new AssertionError();
  201. }
  202. // but does the wait actually occurs?
  203. threadPool.submit(new Interrupter(Thread.currentThread()));
  204. try {
  205. // if waiting works, this should get stuck
  206. Queues.drain(q, Lists.newArrayList(), 1, Long.MAX_VALUE, TimeUnit.NANOSECONDS);
  207. fail();
  208. } catch (InterruptedException expected) {
  209. // we indeed waited; a slow thread had enough time to interrupt us
  210. }
  211. }
  212. // same as above; uninterruptible version
  213. private void assertUninterruptibleDrained(BlockingQueue<Object> q) {
  214. assertEquals(0,
  215. Queues.drainUninterruptibly(q, ImmutableList.of(), 0, 10, TimeUnit.MILLISECONDS));
  216. // but does the wait actually occurs?
  217. threadPool.submit(new Interrupter(Thread.currentThread()));
  218. long startTime = System.nanoTime();
  219. Queues.drainUninterruptibly(
  220. q, Lists.newArrayList(), 1, 10, TimeUnit.MILLISECONDS);
  221. assertTrue((System.nanoTime() - startTime) >= TimeUnit.MILLISECONDS.toNanos(10));
  222. // wait for interrupted status and clear it
  223. while (!Thread.interrupted()) { Thread.yield(); }
  224. }
  225. private static class Producer implements Runnable {
  226. final BlockingQueue<Object> q;
  227. final int elements;
  228. Producer(BlockingQueue<Object> q, int elements) {
  229. this.q = q;
  230. this.elements = elements;
  231. }
  232. @Override public void run() {
  233. try {
  234. for (int i = 0; i < elements; i++) {
  235. q.put(new Object());
  236. }
  237. } catch (InterruptedException e) {
  238. // TODO(user): replace this when there is a better way to spawn threads in tests and
  239. // have threads propagate their errors back to the test thread.
  240. e.printStackTrace();
  241. // never returns, so that #tearDown() notices that one worker isn't done
  242. Uninterruptibles.sleepUninterruptibly(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
  243. }
  244. }
  245. }
  246. private static class Interrupter implements Runnable {
  247. final Thread threadToInterrupt;
  248. Interrupter(Thread threadToInterrupt) {
  249. this.threadToInterrupt = threadToInterrupt;
  250. }
  251. @Override public void run() {
  252. try {
  253. Thread.sleep(100);
  254. } catch (InterruptedException e) {
  255. throw new AssertionError();
  256. } finally {
  257. threadToInterrupt.interrupt();
  258. }
  259. }
  260. }
  261. }