1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.jetspeed.cache.file;
19  
20  import java.io.BufferedInputStream;
21  import java.io.File;
22  import java.io.FileInputStream;
23  import java.util.Date;
24  import java.util.Iterator;
25  
26  import junit.framework.Test;
27  import junit.framework.TestCase;
28  import junit.framework.TestSuite;
29  
30  import org.apache.commons.io.StreamUtils;
31  import org.apache.commons.lang.exception.ExceptionUtils;
32  
33  
34  /***
35   * Unit test for FileCache 
36   * 
37   * @author <a href="mailto:david@bluesunrise.com">David Sean Taylor</a>
38   * @version $Id: TestFileCache.java 516448 2007-03-09 16:25:47Z ate $
39   */
40  
41  public class TestFileCache extends TestCase implements FileCacheEventListener
42  {    
43      protected static final String TEST_DIRECTORY = "./testdata";
44      protected static final int CACHE_SIZE = 20;
45      protected static final int SCAN_RATE = 10;
46      String refreshedEntry = null;
47  
48  
49   
50      /***
51       * Creates the test suite.
52       *
53       * @return a test suite (<code>TestSuite</code>) that includes all methods
54       *         starting with "test"
55       */
56       public static Test suite()
57      {
58          // All methods starting with "test" will be executed in the test suite.
59          return new TestSuite(TestFileCache.class);
60      }
61      
62         
63      private FileCache cache = null;
64      
65      protected void setUp() throws Exception
66      {
67          super.setUp();
68          
69          cache = new FileCache(SCAN_RATE, CACHE_SIZE);
70      }    
71      
72      /***
73       * @see junit.framework.TestCase#tearDown()
74       */
75      public void tearDown() throws Exception
76      {
77          super.tearDown();
78          removeTestFiles();
79      }
80  
81       /***
82       * Tests loading the cache
83       * @throws Exception
84       */
85  
86      public void testLoadCache() throws Exception 
87      {        
88          String templateFile = TEST_DIRECTORY+"/default.psml";
89          try
90          {
91              File file = new File(templateFile);            
92              assertTrue(file.exists());
93  
94              createTestFiles(templateFile);
95  
96              // create the Cache  wake up after 10 seconds, cache size 20
97              // FileCache cache = new FileCache(10, 20);
98  
99              // load the Cache
100             File directory = new File(TEST_DIRECTORY);
101             File[] files = directory.listFiles();
102             for (int ix=0; ix < files.length; ix++)
103             {
104                 if (files[ix].isDirectory() || files[ix].getName().equals(".cvsignore"))
105                 {
106                     continue;
107                 }
108                 String testData = readFile(files[ix]);                
109                 cache.put(files[ix], testData);
110             }
111 
112             assertTrue(cache.getSize() == 31);
113 
114             dumpCache(cache.getIterator());
115 
116             cache.addListener(this);
117 
118             // start the cache's scanner
119             cache.startFileScanner();
120 
121             Thread.sleep(2000);
122 
123             assertTrue(cache.getSize() == 20);
124 
125             dumpCache(cache.getIterator());
126 
127             // Reload files array to get the files back in the correct order
128             // because the cache CAN have reordered them while evicting.
129             // This can happen if test files where left over from a previous 
130             // test which then will have an older timestamp.
131             // In that case it is NOT garanteed that files[18] below will still
132             // be in the cache!
133             // Note: this is only an issue for the test itself and not for the
134             // cache as such. 
135 
136             Iterator it = cache.getIterator();
137             for ( int ix = 0; it.hasNext(); ix++ )
138             {
139                 FileCacheEntry entry = (FileCacheEntry) it.next();
140                 files[ix] = entry.getFile();
141             }
142 
143             String stuff = (String) cache.getDocument(files[18].getCanonicalPath());
144             assertNotNull(stuff);
145 
146             files[18].setLastModified(new Date().getTime());
147 
148             Thread.sleep(9000);
149 
150             assertNotNull(refreshedEntry);
151             System.out.println("refreshed entry = " + refreshedEntry);
152 
153             cache.stopFileScanner();
154 
155             // evict all from cache
156             cache.evictAll();
157             assertTrue(cache.getSize() == 0);
158 
159             removeTestFiles();
160         }
161         catch (Exception e)
162         {
163             fail(ExceptionUtils.getStackTrace(e));
164         }
165 
166         System.out.println("Completed loadCache Test OK ");
167 
168     }
169 
170     private void createTestFiles(String templateFile)
171         throws java.io.IOException
172     {
173         for (int ix=1; ix < 31; ix++)
174         {
175             String testFile = TEST_DIRECTORY+"/testFile-" + ix + ".psml";
176             FileCopy.copy(templateFile, testFile);
177         }
178     }
179 
180     private void removeTestFiles()
181     {
182         for (int ix=1; ix < 31; ix++)
183         {
184             String testFile = TEST_DIRECTORY+"/testFile-" + ix + ".psml";
185             File file = new File(testFile);
186             if ( file.exists() )
187                 file.delete();
188         }
189     }
190 
191     private String readFile(File file)
192         throws java.io.IOException, java.io.FileNotFoundException
193     {
194         BufferedInputStream input;
195 
196         input = new BufferedInputStream(new FileInputStream(file));
197         String result = StreamUtils.streamAsString(input);
198         input.close();
199         return result;
200     }
201 
202     /***
203      * Refresh event, called when the entry is being refreshed from file system.
204      *
205      * @param entry the entry being refreshed.
206      */
207     public void refresh(FileCacheEntry entry)
208     {
209         System.out.println("entry is refreshing: " + entry.getFile().getName());
210         this.refreshedEntry = entry.getFile().getName();
211     }
212 
213     /***
214      * Evict event, called when the entry is being evicted out of the cache
215      *
216      * @param entry the entry being refreshed.
217      */
218     public void evict(FileCacheEntry entry)
219     {
220         System.out.println("entry is evicting: " + entry.getFile().getName());
221     }
222 
223     private void dumpCache(Iterator it)
224     {
225         for ( ; it.hasNext(); )
226         {
227             FileCacheEntry entry = (FileCacheEntry) it.next();
228             System.out.println(entry.getFile().getName());
229         }
230     }
231             
232 }
233 
234 
235 
236 
237 
238