1 24 package org.objectweb.speedo.runtime.collection; 25 26 import java.util.ArrayList ; 27 import java.util.Arrays ; 28 import java.util.Collection ; 29 import java.util.Collections ; 30 import java.util.List ; 31 import java.util.Properties ; 32 33 import javax.jdo.PersistenceManager; 34 import javax.jdo.PersistenceManagerFactory; 35 36 import org.objectweb.speedo.SpeedoTestHelper; 37 import org.objectweb.speedo.api.SpeedoProperties; 38 import org.objectweb.speedo.pobjects.collection.Group; 39 import org.objectweb.speedo.pobjects.collection.User; 40 import org.objectweb.util.monolog.api.BasicLevel; 41 42 47 public class TestThinLock extends SpeedoTestHelper { 48 49 52 public TestThinLock(String s) { 53 super(s); 54 } 55 56 59 protected String getLoggerName() { 60 return LOG_NAME + ".rt.collection.TestThinLock"; 61 } 62 63 68 public Properties getPMFProperties() { 69 Properties p = super.getPMFProperties(); 70 p.put(SpeedoProperties.TRANSACTION_LOCKING_LEVEL_ENABLETHIN, "true"); 71 p.put(SpeedoProperties.TRANSACTION_LOCKING_LEVEL + "(" 72 + Group.class.getName() + "#users)", 73 SpeedoProperties.TRANSACTION_LOCKING_LEVEL_FIELD); 74 return p; 75 } 76 77 public void testGroupUser2WithBarrier() { 78 testGroupUser(2,true); 79 } 80 public void testGroupUser20WithBarrier() { 81 testGroupUser(20,true); 82 } 83 public void testGroupUser20() { 84 testGroupUser(20,false); 85 } 86 public void testGroupUser50() { 87 testGroupUser(50,true); 88 } 89 public void testGroupUser100() { 90 testGroupUser(100,false); 91 } 92 93 97 public void testGroupUser(final int NB, final boolean withBarrier) { 98 logger.log(BasicLevel.INFO, "testGroupUser" + NB + 99 (withBarrier ? "WithBarrier" : "")); 100 final Waiter waiter = new Waiter(0, withBarrier); 101 final Group group = new Group("TestThinLock.testGroupUser.group1"); 102 final User[] users = new User[NB]; 103 for(int i=0; i<NB; i++) { 104 users[i] = new User("TestThinLock.testGroupUser.user" + i); 105 group.getUsers().add(users[i]); 106 } 107 PersistenceManager pm = pmf.getPersistenceManager(); 108 pm.currentTransaction().begin(); 109 pm.makePersistent(group); 110 pm.currentTransaction().commit(); 111 pm.close(); 112 Thread [] ths = new Thread [NB]; 113 for(int i=0; i<NB; i++) { 114 ths[i] = new Thread (new TestGroupUser(waiter, group, users[i], 115 new User("TestThinLock.testGroupUser.user" + (NB + i)), 116 pmf)); 117 } 118 for(int i=0; i<NB; i++) { 119 ths[i].start(); 120 } 121 Collection threads = Arrays.asList(ths); 122 List res = waiter.nextAction(threads, 1000); 123 assertTrue("Thread blocked on first point: " + res, res.isEmpty()); 124 res = waiter.nextAction(threads, 1000); 125 if (!res.isEmpty()) { 126 for(int i=0; i<ths.length; i++) { 127 if (ths[i].isAlive()) { 128 ths[i].interrupt(); 129 } 130 } 131 } 132 assertTrue("Thread blocked on second point: " + res, res.isEmpty()); 133 res = waiter.nextAction(threads, 1000); 134 for(int i=0; i<ths.length; i++) { 135 if (ths[i].isAlive()) { 136 try { 137 ths[i].join(1000); 138 } catch (InterruptedException e) { 139 e.printStackTrace(); 140 } 141 } 142 } 143 pm = pmf.getPersistenceManager(); 144 int size = group.getUsers().size(); 145 pm.currentTransaction().begin(); 146 pm.deletePersistentAll(group.getUsers()); 147 pm.deletePersistent(group); 148 pm.currentTransaction().commit(); 149 pm.close(); 150 assertEquals("Bad number of users", NB, size); 151 } 152 153 154 public static class Waiter { 155 int actionId; 156 ArrayList waiters = new ArrayList (); 157 boolean withBarrier; 158 public Waiter(int actionId, boolean withBarrier) { 159 this.actionId = actionId; 160 this.withBarrier = withBarrier; 161 } 162 public synchronized void waitAction(int aid) { 163 if (!withBarrier) { 164 return; 165 } 166 waiters.add(Thread.currentThread()); 167 notifyAll(); 168 while(actionId < aid) { 169 try { 170 wait(); 171 } catch (InterruptedException e) { 172 e.printStackTrace(); 173 } 174 } 175 } 176 public synchronized List nextAction(Collection threads, long time) { 177 if (!withBarrier) { 178 return Collections.EMPTY_LIST; 179 } 180 while(!waiters.containsAll(threads)) { 181 try { 182 wait(time); 183 } catch (InterruptedException e) { 184 e.printStackTrace(); 185 break; 186 } 187 } 188 if (waiters.containsAll(threads)) { 189 actionId++; 190 waiters.clear(); 191 notifyAll(); 192 return Collections.EMPTY_LIST; 193 } else { 194 return Collections.unmodifiableList( 195 new ArrayList (waiters)); 196 } 197 } 198 } 199 200 public static class TestGroupUser implements Runnable { 201 public Waiter waiter; 202 public Group group; 203 public User userToRemove; 204 public User userToAdd; 205 public PersistenceManagerFactory pmf; 206 207 public TestGroupUser(Waiter waiter, 208 Group group, 209 User userToRemove, 210 User userToAdd, 211 PersistenceManagerFactory pmf) { 212 super(); 213 this.waiter = waiter; 214 this.group = group; 215 this.userToRemove = userToRemove; 216 this.userToAdd = userToAdd; 217 this.pmf = pmf; 218 } 219 220 public void run() { 221 PersistenceManager pm = pmf.getPersistenceManager(); 222 pm.currentTransaction().begin(); 223 Collection users = group.getUsers(); 224 waiter.waitAction(1); 225 226 users.add(userToAdd); 227 users.remove(userToRemove); 228 pm.deletePersistent(userToRemove); 229 230 waiter.waitAction(2); 231 pm.currentTransaction().commit(); 232 pm.close(); 233 234 waiter.waitAction(3); 235 } 236 } 237 } 238 | Popular Tags |