1 19 20 package org.openide.nodes; 21 22 import java.lang.ref.Reference ; 23 import java.lang.ref.SoftReference ; 24 import java.util.*; 25 import junit.framework.AssertionFailedError; 26 import org.openide.ErrorManager; 27 28 import org.netbeans.junit.*; 29 import org.openide.util.RequestProcessor; 30 31 32 public class AddRemoveNotifyRaceConditionTest extends NbTestCase { 33 public AddRemoveNotifyRaceConditionTest(java.lang.String testName) { 34 super(testName); 35 } 36 37 protected void setUp () throws Exception { 38 System.setProperty("org.openide.util.Lookup", "org.openide.nodes.AddRemoveNotifyRaceConditionTest$Lkp"); 39 assertNotNull ("ErrManager has to be in lookup", org.openide.util.Lookup.getDefault ().lookup (ErrManager.class)); 40 ErrManager.messages.delete (0, ErrManager.messages.length ()); 41 } 42 43 44 protected void runTest () throws Throwable { 45 try { 46 super.runTest(); 47 } catch (Error err) { 48 AssertionFailedError newErr = new AssertionFailedError (err.getMessage () + "\n" + ErrManager.messages); 49 newErr.initCause (err); 50 throw newErr; 51 } 52 } 53 54 public void testChildrenCanBeSetToNullIfGCKicksIn () throws Exception { 55 Keys k = new Keys(); 56 AbstractNode n = new AbstractNode(k); 57 58 ErrorManager.getDefault().log("Initialize first array"); 59 Node[] arr = n.getChildren().getNodes(true); 60 assertEquals("Ok, one", 1, arr.length); 61 ErrorManager.getDefault().log("Array initialized"); 62 63 final Reference <Node> ref = new SoftReference <Node>(arr[0]); 64 arr = null; 65 66 class R implements Runnable { 67 public void run() { 68 ErrorManager.getDefault().log("Ready to GC"); 69 try { 70 assertGC("Node can go away in the worst possible moment", ref); 71 } catch (Throwable t) { 72 } 74 ErrorManager.getDefault().log("Gone"); 75 System.runFinalization(); 76 System.runFinalization(); 77 78 } 79 } 80 k.run = new R(); 81 82 ErrorManager.getDefault().log("Before getNodes(true)"); 83 int cnt = n.getChildren().getNodes(true).length; 84 ErrorManager.getDefault().log("After getNodes(true)"); 85 86 assertEquals("Count is really one", 1, cnt); 87 } 88 89 private static class Keys extends Children.Keys<Integer > implements Runnable { 90 private Runnable run; 91 private int removeNotify; 92 private RequestProcessor.Task task = new RequestProcessor("blbni").create(this); 93 94 @Override 95 protected void addNotify() { 96 task.schedule(0); 97 } 98 99 public void run() { 100 ErrorManager.getDefault().log("before setKeys"); 101 setKeys(Collections.singleton(1)); 102 ErrorManager.getDefault().log("after setKeys"); 103 if (run != null) { 104 ErrorManager.getDefault().log("running inner runnable"); 105 run.run(); 106 ErrorManager.getDefault().log("end of inner runnable"); 107 run = null; 108 return; 109 } 110 } 111 112 @Override 113 protected void removeNotify() { 114 ErrorManager.getDefault().log("removeNotify"); 115 setKeys(Collections.<Integer >emptyList()); 116 ErrorManager.getDefault().log("removeNotifyEnd"); 117 } 118 119 protected Node[] createNodes(Integer key) { 120 AbstractNode an = new AbstractNode(Children.LEAF); 121 an.setName(key.toString()); 122 return new Node[] { an }; 123 } 124 125 @Override 126 public Node[] getNodes(boolean optimalResult) { 127 Node[] res; 128 if (optimalResult) { 129 ErrorManager.getDefault().log("getNodes optimalResult"); 130 res = getNodes(); 131 task.schedule(0); 132 ErrorManager.getDefault().log("getNodes scheduled"); 133 task.waitFinished(); 134 ErrorManager.getDefault().log("wait finished"); 135 } 136 res = getNodes(); 137 return res; 139 } 140 } 141 142 143 public static final class Lkp extends org.openide.util.lookup.AbstractLookup { 144 public Lkp () { 145 this (new org.openide.util.lookup.InstanceContent ()); 146 } 147 148 private Lkp (org.openide.util.lookup.InstanceContent ic) { 149 super (ic); 150 ic.add (new ErrManager ()); 151 } 152 } 153 154 private static final class ErrManager extends org.openide.ErrorManager { 155 public static final StringBuffer messages = new StringBuffer (); 156 157 public Throwable annotate (Throwable t, int severity, String message, String localizedMessage, Throwable stackTrace, java.util.Date date) { 158 return t; 159 } 160 161 public Throwable attachAnnotations (Throwable t, org.openide.ErrorManager.Annotation[] arr) { 162 return t; 163 } 164 165 public org.openide.ErrorManager.Annotation[] findAnnotations (Throwable t) { 166 return null; 167 } 168 169 public org.openide.ErrorManager getInstance (String name) { 170 return this; 171 } 172 173 public void log (int severity, String s) { 174 messages.append ("THREAD: "); 175 messages.append (Thread.currentThread().getName()); 176 messages.append (" MSG: "); 177 messages.append (s); 178 messages.append ('\n'); 179 } 180 181 public void notify (int severity, Throwable t) { 182 messages.append (t.getMessage ()); 183 } 184 185 } 186 187 } | Popular Tags |