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.

ConcurrencyTest.java 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Copyright 2011 James Moger.
  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.iciql.test;
  17. import static org.junit.Assert.assertEquals;
  18. import static org.junit.Assert.assertTrue;
  19. import java.util.List;
  20. import java.util.concurrent.atomic.AtomicInteger;
  21. import org.junit.After;
  22. import org.junit.Before;
  23. import org.junit.Test;
  24. import com.iciql.Db;
  25. import com.iciql.Query;
  26. import com.iciql.test.models.Product;
  27. import com.iciql.util.Utils;
  28. /**
  29. * Tests concurrency and alias instance sharing.
  30. */
  31. public class ConcurrencyTest {
  32. private Db db;
  33. private int numberOfTests = 200;
  34. @Before
  35. public void setUp() {
  36. db = Db.open("jdbc:h2:mem:", "sa", "sa");
  37. db.insertAll(Product.getList());
  38. }
  39. @After
  40. public void tearDown() {
  41. db.close();
  42. }
  43. @Test
  44. public void testAliasSharing() throws Exception {
  45. // Single-threaded example of why aliases can NOT be shared.
  46. Product p = new Product();
  47. Query<Product> query1 = db.from(p);
  48. Query<Product> query2 = db.from(p);
  49. // if you could share alias instances both counts should be equal
  50. long count1 = query1.where(p.category).is("Beverages").selectCount();
  51. long count2 = query2.where(p.category).is("Beverages").selectCount();
  52. // but they aren't
  53. assertEquals(0, count1);
  54. assertEquals(2, count2);
  55. assertTrue(count1 != count2);
  56. }
  57. @Test
  58. public void testConcurrencyFinal() throws Exception {
  59. // Multi-threaded example of why aliases can NOT be shared.
  60. //
  61. // This test looks like it _could_ work and you may find that it _can_
  62. // work, but you should also find that it _will_ fail.
  63. List<Thread> threads = Utils.newArrayList();
  64. final AtomicInteger failures = new AtomicInteger(0);
  65. final Product p = new Product();
  66. for (int i = 0; i < numberOfTests; i++) {
  67. final int testNumber = i;
  68. Thread t = new Thread(new Runnable() {
  69. public void run() {
  70. try {
  71. int testCase = testNumber % 10;
  72. test(testCase, p);
  73. } catch (Throwable rex) {
  74. failures.incrementAndGet();
  75. System.err.println("EXPECTED ERROR");
  76. rex.printStackTrace();
  77. }
  78. }
  79. }, "ICIQL-" + i);
  80. t.start();
  81. threads.add(t);
  82. }
  83. // wait till all threads complete
  84. for (Thread t : threads) {
  85. t.join();
  86. }
  87. assertTrue("This should fail. Try running a few more times.", failures.get() > 0);
  88. }
  89. @Test
  90. public void testConcurrencyThreadLocal() throws Exception {
  91. List<Thread> threads = Utils.newArrayList();
  92. final AtomicInteger failures = new AtomicInteger(0);
  93. final ThreadLocal<Product> tl = Utils.newThreadLocal(Product.class);
  94. for (int i = 0; i < numberOfTests; i++) {
  95. final int testNumber = i;
  96. Thread t = new Thread(new Runnable() {
  97. public void run() {
  98. try {
  99. int testCase = testNumber % 10;
  100. test(testCase, tl.get());
  101. } catch (Throwable rex) {
  102. failures.incrementAndGet();
  103. rex.printStackTrace();
  104. }
  105. }
  106. }, "ICIQL-" + i);
  107. t.start();
  108. threads.add(t);
  109. }
  110. // wait till all threads complete
  111. for (Thread t : threads) {
  112. t.join();
  113. }
  114. assertEquals("ThreadLocal should never fail!", 0, failures.get());
  115. }
  116. private void test(int testCase, Product p) throws AssertionError {
  117. List<Product> list;
  118. switch (testCase) {
  119. case 0:
  120. list = db.from(p).where(p.productName).is("Chai").select();
  121. assertEquals(1, list.size());
  122. assertEquals("Chai", list.get(0).productName);
  123. break;
  124. case 1:
  125. list = db.from(p).where(p.category).is("Condiments").select();
  126. assertEquals(5, list.size());
  127. break;
  128. case 3:
  129. list = db.from(p).where(p.productName).is("Aniseed Syrup").select();
  130. assertEquals(1, list.size());
  131. assertEquals("Aniseed Syrup", list.get(0).productName);
  132. break;
  133. case 4:
  134. list = db.from(p).where(p.productName).like("Chef%").select();
  135. assertEquals(2, list.size());
  136. assertTrue(list.get(0).productName.startsWith("Chef"));
  137. assertTrue(list.get(1).productName.startsWith("Chef"));
  138. break;
  139. case 6:
  140. list = db.from(p).where(p.unitsInStock).exceeds(0).select();
  141. assertEquals(9, list.size());
  142. break;
  143. case 7:
  144. list = db.from(p).where(p.unitsInStock).is(0).select();
  145. assertEquals(1, list.size());
  146. assertEquals("Chef Anton's Gumbo Mix", list.get(0).productName);
  147. break;
  148. case 9:
  149. list = db.from(p).where(p.productId).is(7).select();
  150. assertEquals(1, list.size());
  151. assertTrue(7 == list.get(0).productId);
  152. break;
  153. default:
  154. list = db.from(p).select();
  155. assertEquals(10, list.size());
  156. }
  157. }
  158. }