1 21 package com.db4o.test.replication.old; 22 23 import java.util.*; 24 25 import com.db4o.*; 26 import com.db4o.ext.*; 27 import com.db4o.query.*; 28 import com.db4o.replication.*; 29 import com.db4o.test.*; 30 31 public class ReplicationFeaturesMain { 32 33 private final Set _A = new HashSet(1); 34 private final Set _B = new HashSet(1); 35 private final Set _BOTH = new HashSet(2); 36 private final Set _NONE = Collections.EMPTY_SET; 37 38 private ObjectContainer _containerA; 39 private ObjectContainer _containerB; 40 41 private Set _direction; 42 private Set _containersToQueryFrom; 43 private Set _containersWithNewObjects; 44 private Set _containersWithChangedObjects; 45 private Set _objectsToPrevailInConflicts; 46 47 private int _errors; 48 private String _intermittentErrors = ""; 49 private int _testCombination; 50 51 52 public void configure(){ 53 Db4o.configure().generateUUIDs(Integer.MAX_VALUE); 54 Db4o.configure().generateVersionNumbers(Integer.MAX_VALUE); 55 } 56 57 public void test() { 58 59 reopenContainers(); 60 61 _A.add("A"); 62 _B.add("B"); 63 _BOTH.add("A"); 64 _BOTH.add("B"); 65 66 67 tstDirection(_BOTH); 69 tstDirection(_A); 70 tstDirection(_B); 71 72 73 if (_intermittentErrors.length() > 0) { 74 System.err.println("Intermittent errors found in test combinations:" + _intermittentErrors); 75 Test.ensure(false); 76 } 77 78 } 80 81 private void reopenContainers() { 82 _containerA = Test.reOpen(); 83 _containerB = Test.replica(); 84 } 85 86 87 private void tstDirection(Set direction) { 88 _direction = direction; 89 90 tstQueryingFrom(_BOTH); 91 tstQueryingFrom(_A); 92 tstQueryingFrom(_B); 93 } 94 95 private void tstQueryingFrom(Set containers) { 96 _containersToQueryFrom = containers; 97 98 tstWithNewObjectsIn(_BOTH); 99 tstWithNewObjectsIn(_A); 100 tstWithNewObjectsIn(_B); 101 tstWithNewObjectsIn(_NONE); 102 } 103 104 private void tstWithNewObjectsIn(Set containers) { 105 _containersWithNewObjects = containers; 106 107 System.out.print("."); 108 109 tstWithChangedObjectsIn(_BOTH); 110 tstWithChangedObjectsIn(_A); 111 tstWithChangedObjectsIn(_B); 112 tstWithChangedObjectsIn(_NONE); 113 } 114 115 private void tstWithChangedObjectsIn(Set containers) { 116 _containersWithChangedObjects = containers; 117 118 tstWithObjectsPrevailingConflicts(_A); 119 tstWithObjectsPrevailingConflicts(_B); 120 tstWithObjectsPrevailingConflicts(_NONE); 121 } 122 123 124 private void tstWithObjectsPrevailingConflicts(Set containers) { 125 _objectsToPrevailInConflicts = containers; 126 127 _testCombination++; 128 if (_testCombination < 0) return; 130 _errors = 0; 131 while (true) { 132 try { 133 doIt(); 134 break; 135 } catch (RuntimeException rx) { 136 _errors++; 137 if (_errors == 10) { 138 printCombination(); 139 throw rx; 140 } 141 } 142 } 143 if (_errors > 0) _intermittentErrors += "\n\t Combination: " + _testCombination + " (" + _errors +" errors)"; 144 } 145 146 private void printCombination() { 147 System.err.println("Direction: " + print(_direction)); 148 System.err.println("Querying From: " + print(_containersToQueryFrom)); 149 System.err.println("New Objects In: " + print(_containersWithNewObjects)); 150 System.err.println("Changed Objects In: " + print(_containersWithChangedObjects)); 151 System.err.println("Prevailing Conflicts: " + print(_objectsToPrevailInConflicts)); 152 } 153 154 private void doIt() { 155 initState(); 156 reopenContainers(); 157 158 performChanges(); 159 160 ReplicationProcess replication = _containerA.ext().replicationBegin(_containerB, new ReplicationConflictHandler() { 161 public Object resolveConflict(ReplicationProcess process, Object a, Object b) { 162 if (_objectsToPrevailInConflicts.isEmpty()) return null; 163 return _objectsToPrevailInConflicts.contains("A") ? a : b; 164 } 165 }); 166 167 if (_direction.size() == 1) { 168 if (_direction.contains("A")) {replication.setDirection(_containerB, _containerA);} 169 if (_direction.contains("B")) {replication.setDirection(_containerA, _containerB);} 170 } 171 172 173 if (_containersToQueryFrom.contains("A")) { 174 replicateQueryingFrom(replication, _containerA); 175 } 176 if (_containersToQueryFrom.contains("B")) { 177 replicateQueryingFrom(replication, _containerB); 178 } 179 180 replication.commit(); 181 182 checkNames(); 183 } 184 185 private void checkNames() { 186 checkNames("A", "A"); 187 checkNames("A", "B"); 188 checkNames("B", "A"); 189 checkNames("B", "B"); 190 } 191 192 private void checkNames(String origin, String inspected) { 193 checkName(container(inspected), "oldFrom" + origin, isOldNameExpected(inspected)); 194 checkName(container(inspected), "newFrom" + origin, isNewNameExpected(origin, inspected)); 195 checkName(container(inspected), "oldFromAChangedIn" + origin, isChangedNameExpected(origin, inspected)); 196 checkName(container(inspected), "oldFromBChangedIn" + origin, isChangedNameExpected(origin, inspected)); 197 } 198 199 private ObjectContainer container(String aOrB) { 200 return aOrB.equals("A") ? _containerA : _containerB; 201 } 202 203 private boolean isOldNameExpected(String inspected) { 204 if (isChangedNameExpected("A", inspected)) return false; 205 if (isChangedNameExpected("B", inspected)) return false; 206 return true; 207 } 208 209 private boolean isNewNameExpected(String origin, String inspected) { 210 if (!_containersWithNewObjects.contains(origin)) return false; 211 if (origin.equals(inspected)) return true; 212 if (!_containersToQueryFrom.contains(origin)) return false; 213 if (!_direction.contains(inspected)) return false; 214 return true; 215 } 216 217 private boolean isChangedNameExpected(String changed, String inspected) { 218 if (!hasChanges(changed)) return false; 219 220 String other = other(inspected); 221 if (prevailedInConflict(other)) return isChangedNameExpected(changed, other); 222 223 if (inspected.equals(changed)) return true; 224 if (hasChanges(inspected)) return false; 225 226 if (!_direction.contains(inspected)) return false; 227 if (!wasReplicationTriggered()) return false; 228 229 return true; 230 } 231 232 private boolean prevailedInConflict(String container) { 233 if (!_objectsToPrevailInConflicts.contains(container)) return false; 234 if (!_direction.contains(other(container))) return false; 235 if (!wasReplicationTriggered()) return false; 236 return true; 237 } 238 239 private boolean wasReplicationTriggered() { 240 Set containersToTriggerReplication = new HashSet(_containersToQueryFrom); 241 containersToTriggerReplication.retainAll(_containersWithChangedObjects); 242 return !containersToTriggerReplication.isEmpty(); 243 } 244 245 private boolean hasChanges(String container) { 246 return _containersWithChangedObjects.contains(container); 247 } 248 249 private String other(String aOrB) { 250 return aOrB.equals("A") ? "B" : "A"; 251 } 252 253 private void performChanges() { 254 255 if (_containersWithNewObjects.contains("A")) { 256 _containerA.set(new Replicated("newFromA")); 257 } 258 if (_containersWithNewObjects.contains("B")) { 259 _containerB.set(new Replicated("newFromB")); 260 } 261 262 if (_containersWithChangedObjects.contains("A")) { 263 changeObject(_containerA, "oldFromA", "oldFromAChangedInA"); 264 changeObject(_containerA, "oldFromB", "oldFromBChangedInA"); 265 } 266 if (_containersWithChangedObjects.contains("B")) { 267 changeObject(_containerB, "oldFromA", "oldFromAChangedInB"); 268 changeObject(_containerB, "oldFromB", "oldFromBChangedInB"); 269 } 270 271 _containerA.commit(); 272 _containerB.commit(); 273 } 274 275 private void changeObject(ObjectContainer container, String name, String newName) { 276 Replicated obj = find(container, name); 277 obj._name = newName; 278 container.set(obj); 279 } 280 281 private void checkName(ObjectContainer container, String name, boolean isExpected) { 282 Replicated obj = find(container, name); 283 if (isExpected) { 284 ensure(obj != null); 285 } else { 286 ensure(obj == null); 287 } 288 } 289 290 private Replicated find(ObjectContainer container, String name) { 291 Query q = container.query(); 292 q.constrain(Replicated.class); 293 q.descend("_name").constrain(name); 294 ObjectSet set = q.execute(); 295 ensure(set.size() < 2); 296 return (Replicated)set.next(); 297 } 298 299 private void initState() { 300 _containerA.commit(); 301 _containerB.commit(); 302 Test.deleteAll(_containerA); 303 Test.deleteAll(_containerB); 304 305 _containerA.set(new Replicated("oldFromA")); 306 _containerB.set(new Replicated("oldFromB")); 307 308 _containerA.commit(); 309 _containerB.commit(); 310 311 final ReplicationProcess replication = _containerA.ext().replicationBegin(_containerB, new ReplicationConflictHandler() { 312 public Object resolveConflict(ReplicationProcess process, Object a, Object b) { 313 return null; 314 } 315 }); 316 317 replicateQueryingFrom(replication, _containerA); 318 replicateQueryingFrom(replication, _containerB); 319 320 replication.commit(); 321 } 322 323 private static void replicateQueryingFrom(ReplicationProcess replication, ObjectContainer origin) { 324 ObjectSet set = objectsToReplicate(replication, origin); 325 while(set.hasNext()){ 326 Object next = set.next(); 327 replication.replicate(next); 328 } 329 } 330 331 private static ObjectSet objectsToReplicate(ReplicationProcess replication, ObjectContainer origin) { 332 Query q = origin.query(); 333 q.constrain(Replicated.class); 334 replication.whereModified(q); 335 return q.execute(); 336 } 337 338 private static void checkAllEqual(ExtObjectContainer con1, ExtObjectContainer con2){ 339 DeepCompare comparator = new DeepCompare(); 340 341 Query q = con1.query(); 342 q.constrain(Replicated.class); 343 ObjectSet all = q.execute(); 344 while(all.hasNext()){ 345 Object obj1 = all.next(); 346 con1.activate(obj1, Integer.MAX_VALUE); 347 348 Db4oUUID uuid = con1.getObjectInfo(obj1).getUUID(); 349 Object obj2 = con2.getByUUID(uuid); 350 con2.activate(obj2, Integer.MAX_VALUE); 351 352 ensure(comparator.isEqual(obj1, obj2)); 353 } 354 } 355 356 private static void ensure(boolean condition) { 357 if (!condition) throw new RuntimeException (); 358 } 359 360 private String print(Set containerSet) { 361 if (containerSet.isEmpty()) return "NONE"; 362 if (containerSet.size() == 2) return "BOTH"; 363 return (String )containerSet.iterator().next(); 364 } 365 366 367 } 368 | Popular Tags |