1   /*
2    *  TestBumpyStack.java
3    *
4    *  Copyright (c) 1998-2005, The University of Sheffield.
5    *
6    *  This file is part of GATE (see http://gate.ac.uk/), and is free
7    *  software, licenced under the GNU Library General Public License,
8    *  Version 2, June 1991 (in the distribution as file licence.html,
9    *  and also available at http://gate.ac.uk/gate/licence.html).
10   *
11   *  Hamish Cunningham, 10/June/00
12   *
13   *  $Id: TestBumpyStack.java,v 1.12 2005/01/11 13:51:37 ian Exp $
14   */
15  
16  package gate.util;
17  
18  import java.util.Collection;
19  
20  import junit.framework.*;
21  
22  import gate.*;
23  import gate.creole.ResourceData;
24  
25  /** BumpyStack test class.
26    */
27  public class TestBumpyStack extends TestCase
28  {
29    /** Debug flag */
30    private static final boolean DEBUG = false;
31  
32    /** Construction */
33    public TestBumpyStack(String name) { super(name); }
34  
35    /** Fixture set up */
36    public void setUp() {
37    } // setUp
38  
39    /** Test suite routine for the test runner */
40    public static Test suite() {
41      return new TestSuite(TestBumpyStack.class);
42    } // suite
43  
44    public static void callGC(){
45      Runtime runtime = Runtime.getRuntime();
46      long memory;
47      do {
48        memory = runtime.totalMemory() - runtime.freeMemory();
49        runtime.gc();
50        try {
51          Thread.currentThread().wait(300);
52        } catch (Exception e) {}
53        runtime.gc();
54      } while (memory < runtime.totalMemory() - runtime.freeMemory());
55    }
56  
57    /** Test the bumpiness of the thing. */
58    public void testBumpiness() throws Exception {
59      WeakBumpyStack bumper = new WeakBumpyStack();
60  
61      String s1 = new String("s1");
62      String s2 = new String("s2");
63      String s3 = new String("s3");
64  
65      bumper.push(s3);
66      bumper.push(s2);
67      bumper.push(s1);
68  
69      assertTrue(
70        "managed to bump non-existent element",
71        ! bumper.bump(new String("something"))
72      );
73  
74      assertTrue("stack wrong length (I): " + bumper.size(), bumper.size() == 3);
75      assertTrue("couldn't bump s2", bumper.bump(s2));
76      assertTrue("s2 not front of stack", ((String) bumper.pop()).equals("s2"));
77      assertTrue("stack wrong length (II)" + bumper.size(), bumper.size() == 2);
78    } // testBumpiness()
79  
80    /**
81     * Tests whether the CreoleRegisterImpl keeps unreacheable resourecs alive.
82     * <B>WARNING: see notes on WeakBumptyStack</B>.
83     */
84    public void testSelfCleaning() throws Exception {
85      //count instances
86      Collection instances = ((ResourceData)
87                             Gate.getCreoleRegister().
88                             get("gate.corpora.DocumentImpl")).
89                             getInstantiations();
90      int docCnt = instances == null ? 0: instances.size();
91  
92      instances = ((ResourceData)
93                    Gate.getCreoleRegister().
94                    get("gate.corpora.CorpusImpl")).
95                    getInstantiations();
96      int corpusCnt = instances == null ? 0: instances.size();
97  
98      instances = ((ResourceData)
99                    Gate.getCreoleRegister().
100                   get("gate.creole.tokeniser.DefaultTokeniser")).
101                   getInstantiations();
102     int tokCnt = instances == null ? 0: instances.size();
103 
104     instances = ((ResourceData)
105                   Gate.getCreoleRegister().
106                   get("gate.creole.ANNIETransducer")).
107                   getInstantiations();
108     int japeCnt = instances == null ? 0: instances.size();
109 
110     instances = ((ResourceData)
111                   Gate.getCreoleRegister().
112                   get("gate.creole.SerialController")).
113                   getInstantiations();
114     int serctlCnt = instances == null ? 0: instances.size();
115 
116     instances = null;
117     //create some unreacheable resources
118     //LRs
119 
120     Resource res = Factory.newCorpus("corpus1");
121     res.getFeatures().put("large", new byte[500000]);
122     res = Factory.newCorpus("corpus2");
123     res.getFeatures().put("large", new byte[500000]);
124     res = Factory.newCorpus("corpus3");
125     res.getFeatures().put("large", new byte[500000]);
126 
127     res = Factory.newDocument("content");
128     res.getFeatures().put("large", new byte[500000]);
129     res = Factory.newDocument(Gate.getUrl("tests/doc0.html"));
130     res.getFeatures().put("large", new byte[500000]);
131     res = Factory.newDocument(Gate.getUrl("tests/doc0.html"));
132     res.getFeatures().put("large", new byte[500000]);
133     res = Factory.newDocument(Gate.getUrl("tests/doc0.html"));
134     res.getFeatures().put("large", new byte[500000]);
135 
136     //PRs
137     res = Factory.createResource("gate.creole.tokeniser.DefaultTokeniser");
138     res.getFeatures().put("large", new byte[500000]);
139     res = Factory.createResource("gate.creole.tokeniser.DefaultTokeniser");
140     res.getFeatures().put("large", new byte[500000]);
141     res = Factory.createResource("gate.creole.tokeniser.DefaultTokeniser");
142     res.getFeatures().put("large", new byte[500000]);
143 
144     res = Factory.createResource("gate.creole.ANNIETransducer");
145     res.getFeatures().put("large", new byte[500000]);
146 
147     //Controllers
148     res = Factory.createResource("gate.creole.SerialController");
149     res.getFeatures().put("large", new byte[500000]);
150     res = Factory.createResource("gate.creole.SerialController");
151     res.getFeatures().put("large", new byte[500000]);
152     res = Factory.createResource("gate.creole.SerialController");
153     res.getFeatures().put("large", new byte[500000]);
154     res = null;
155 
156 
157     //force GC
158     callGC();
159 
160     //check instances count
161     int newDocCnt = ((ResourceData)
162                   Gate.getCreoleRegister().
163                   get("gate.corpora.DocumentImpl")).
164                   getInstantiations().size();
165 
166     int newCorpusCnt = ((ResourceData)
167                   Gate.getCreoleRegister().
168                   get("gate.corpora.CorpusImpl")).
169                   getInstantiations().size();
170     int newTokCnt = ((ResourceData)
171                   Gate.getCreoleRegister().
172                   get("gate.creole.tokeniser.DefaultTokeniser")).
173                   getInstantiations().size();
174     int newJapeCnt = ((ResourceData)
175                   Gate.getCreoleRegister().
176                   get("gate.creole.ANNIETransducer")).
177                   getInstantiations().size();
178     int newSerctlCnt = ((ResourceData)
179                   Gate.getCreoleRegister().
180                   get("gate.creole.SerialController")).
181                   getInstantiations().size();
182 
183     String message =
184           "\nWARNING: testSelfCleaning: GC didn't run:" +
185           "\nDocs expected: " + docCnt + ", got: " + newDocCnt +
186           "\nCorpora expected: " + corpusCnt + ", got: " + newCorpusCnt +
187           "\nTokenisers expected: " + tokCnt + ", got: " + newTokCnt +
188           "\nJapes expected: " + japeCnt + ", got: " + newJapeCnt +
189           "\nSerCtls expected: " + serctlCnt + ", got: " + newSerctlCnt;
190 
191     // ordinarily the following "if" would be an assert, and if the
192     // conditions failed then the test would fail. see notes on
193     // WeakBumptyStack
194     if(! (
195       docCnt + 4 > newDocCnt &&
196       corpusCnt + 3 > newCorpusCnt &&
197       tokCnt + 3 > newTokCnt &&
198       japeCnt + 1 > newJapeCnt &&
199       serctlCnt + 3 > newSerctlCnt
200     ) && DEBUG)
201       Err.prln(message);
202   }
203 } // class TestBumpyStack
204