protected void runTest() throws Throwable { int n = barrier.barrier(); if (n == 0) { runCreateNode(); } else { runFaultNode(); } }
private void runFaultNode() throws Exception { barrier.barrier(); final Map faultedRoot; // fault the root under the same lock it was modified under // this avoids a ConcurrentModificationException synchronized (barrier) { faultedRoot = root; } for (Iterator i = faultedRoot.entrySet().iterator(); i.hasNext(); ) { Map.Entry entry = (Entry) i.next(); Object key = entry.getKey(); System.out.println(key); Object value = entry.getValue(); System.out.println(value); if (value instanceof Ref) { Object ref = ((Ref) value).getRef(); System.out.println(ref); } } // unblock the create node barrier.barrier(); // wait for the create node to commit it's change barrier.barrier(); // make sure the delta is in there synchronized (faultedRoot) { Object o = faultedRoot.get("delta"); Assert.assertEquals("non-null", o); Assert.assertEquals(5, faultedRoot.size()); } }
private void runCreateNode() throws Throwable { final SynchronizedRef error = new SynchronizedRef(null); // create root in this node only root = new HashMap(); final Object newObj = new Object(); final Ref newRefToOtherNewObject = new Ref(new Object()); synchronized (root) { root.put("delta", null); root.put("new object", newObj); root.put("new ref to new obj", newRefToOtherNewObject); Runnable otherTxn = new Runnable() { public void run() { try { synchronized (barrier) { root.put("ref to new with ref to created", new Ref(newObj)); root.put("ref to created with ref to created", newRefToOtherNewObject); } } catch (Throwable err) { error.set(err); } } }; Thread t1 = new Thread(otherTxn); t1.start(); t1.join(); checkError(error); // unblock the "fault" nodes. Need to do this in another thread so that the // TXN the current thread is in doesn't commit() Runnable doBarrier = new Runnable() { public void run() { try { barrier.barrier(); } catch (Throwable err) { error.set(err); } } }; Thread t2 = new Thread(doBarrier); t2.start(); t2.join(); checkError(error); // block at least until the other node(s) cause the problematic fault. This also needs to be // done in another // thread so that this thread's TXN does not commit Thread t3 = new Thread(doBarrier); t3.start(); t3.join(); checkError(error); // create a change (ie. delta DNA) in the original transaction root.put("delta", "non-null"); barrier.barrier(); } }