Initial revision
[lhc/web/wiklou.git] / testsuite / src / com / piclab / wikitest / WikiSuite.java
1 /*
2 * WikiSuite is the driver class for the wiki test suite.
3 * It represents the location of the wiki, and provides
4 * some common static routines for access. When idividual
5 * tests are instantiated, they are passed this object,
6 * and they use its utility functions and result reporting.
7 */
8
9 package com.piclab.wikitest;
10
11 import com.meterware.httpunit.*;
12 import java.util.prefs.*;
13 import java.util.logging.*;
14 import java.io.*;
15
16 public class WikiSuite {
17
18 private static Preferences ms_uprefs =
19 Preferences.userNodeForPackage( WikiSuite.class );
20
21 /* Settings loaded from preferences:
22 */
23 private static String ms_server = null;
24 private static String ms_script = null;
25 private static String ms_articlepath = null;
26 private static String ms_uploadpath = null;
27 private static String ms_mainpage = null;
28 private static String ms_sysoppass = null;
29
30 /* Primary conversation for test suite; individual
31 * tests may also create their own if needed.
32 */
33 private WebConversation m_conv;
34
35 private static Logger ms_logger = Logger.getLogger( "com.piclab.wikitest" );
36
37 static {
38 /* Set logging level and properties:
39 */
40 ms_logger.setUseParentHandlers( false );
41 Handler h = new StreamHandler( System.out, new WikiLogFormatter() );
42 h.setLevel( Level.INFO );
43
44 ms_logger.addHandler( h );
45 ms_logger.setLevel( Level.INFO );
46 ms_logger.setFilter( null );
47 }
48
49 public static String preloadedPages[] = { "Agriculture", "Anthropology",
50 "Archaeology", "Architecture", "Astronomy_and_astrophysics",
51 "Biology", "Business_and_industry", "Card_game", "Chemistry",
52 "Classics", "Communication", "Computer_Science", "Cooking",
53 "Critical_theory", "Dance", "Earth_science", "Economics",
54 "Education", "Engineering", "Entertainment",
55 "Family_and_consumer_science", "Film", "Game", "Geography",
56 "Handicraft", "Health_science", "History_of_science_and_technology",
57 "History", "Hobby", "Language", "Law",
58 "Library_and_information_science", "Linguistics", "Literature",
59 "Main_Page", "Mathematics", "Music", "Opera", "Painting",
60 "Philosophy", "Physics", "Poker", "Political_science", "Psychology",
61 "Public_affairs", "Recreation", "Religion", "Sculpture",
62 "Sociology", "Sport", "Statistics", "Technology", "Theater",
63 "Tourism", "Transport", "Visual_arts_and_design",
64 "World_Series_of_Poker",
65
66 "Bracketvars", "Quotes", "Headings", "Blocklevels",
67 "ExternalLinks", "InternalLinks", "Magics", "Equations" };
68
69 /* Suite constructor: load the prefs to determine which
70 * wiki to test.
71 */
72
73 public WikiSuite() {
74 try {
75 ms_uprefs.importPreferences(new java.io.FileInputStream(
76 "wikitest.prefs" ));
77 } catch (java.io.IOException e) {
78 /* File probably doesn't exist: no problem, use defaults */
79 } catch (InvalidPreferencesFormatException e) {
80 System.err.println( "Bad preferences file format: " + e );
81 }
82
83 ms_server = ms_uprefs.get( "server", "http://localhost" );
84 ms_script = ms_uprefs.get( "script", "/wiki.phtml" );
85 ms_articlepath = ms_uprefs.get( "articlepath", "" );
86 ms_uploadpath = ms_uprefs.get( "uploadpath", "http://localhost/upload/" );
87 ms_mainpage = ms_uprefs.get( "mainpage", "Main Page" );
88 ms_sysoppass = ms_uprefs.get( "sysoppass", "adminpass" );
89
90 m_conv = new WebConversation();
91 }
92
93 public WebConversation getConv() { return m_conv; }
94 public static String getServer() { return ms_server; }
95 public static String getScript() { return ms_script; }
96 public static String getArticlePath() { return ms_articlepath; }
97 public static String getUploadPath() { return ms_uploadpath; }
98 public static String getMainPage() { return ms_mainpage; }
99 public static String getSysopPass() { return ms_sysoppass; }
100
101 /*
102 * Logging/reporting routines:
103 */
104
105 public static void fatal( String msg ) {
106 ms_logger.severe( msg );
107 ms_logger.getHandlers()[0].flush();
108 }
109
110 public static void error( String msg ) {
111 ms_logger.severe( msg );
112 ms_logger.getHandlers()[0].flush();
113 }
114
115 public static void warning( String msg ) {
116 ms_logger.warning( msg );
117 ms_logger.getHandlers()[0].flush();
118 }
119
120 public static void info( String msg ) {
121 ms_logger.info( msg );
122 ms_logger.getHandlers()[0].flush();
123 }
124
125 public static void fine( String msg ) {
126 ms_logger.fine( msg );
127 ms_logger.getHandlers()[0].flush();
128 }
129
130 public static void finer( String msg ) {
131 ms_logger.finer( msg );
132 ms_logger.getHandlers()[0].flush();
133 }
134
135 public static Level setLoggingLevel( Level newl ) {
136 Level oldl = ms_logger.getLevel();
137
138 ms_logger.getHandlers()[0].setLevel( newl );
139 ms_logger.setLevel( newl );
140 return oldl;
141 }
142
143 public static String threeDecimals( double val ) {
144 String result = "ERROR";
145 java.text.DecimalFormat df =
146 (java.text.DecimalFormat)(java.text.NumberFormat.getInstance());
147
148 df.applyPattern( "#######0.000" );
149 result = df.format( val );
150 return result;
151 }
152
153 /*
154 * Utility functions for loading and saving strings from/to a file.
155 */
156
157 public static void saveText( String text, String filename ) {
158 try {
159 PrintWriter pw = new PrintWriter( new FileOutputStream( filename ) );
160 pw.write( text );
161 pw.close();
162 } catch( IOException e ) {
163 error( "Couldn't write to \"" + filename + "\"" );
164 return;
165 }
166 fine( "Saved \"" + filename + "\"" );
167 }
168
169 public static String loadText( String fname )
170 {
171 FileInputStream fis = null;
172 BufferedInputStream bis;
173
174 try {
175 fis = new FileInputStream( fname );
176 } catch (FileNotFoundException e) {
177 error( "File \"" + fname + "\" not found." );
178 return null;
179 }
180 bis = new BufferedInputStream( fis );
181
182 int r;
183 StringBuffer result = new StringBuffer( 2048 );
184 byte[] buf = new byte[1024];
185
186 while (true) {
187 r = -1;
188 try {
189 r = bis.read( buf );
190 } catch (IOException e) {
191 error( "I/O Error reading \"" + fname + "\"." );
192 break;
193 }
194 if ( r <= 0 ) break;
195
196 try {
197 result.append( new String( buf, 0, r, "ISO8859_1" ) );
198 } catch ( java.io.UnsupportedEncodingException e ) {
199 result.append( new String( buf, 0, r ) );
200 }
201 }
202 try {
203 bis.close();
204 fis.close();
205 } catch (IOException e) {
206 warning( "I/O Error closing file \"" + fname + "\"." );
207 }
208 fine( "Loaded \"" + fname + "\"" );
209 return result.toString();
210 }
211
212 /*
213 * Start background threads that run while all the other
214 * tests are going on.
215 */
216
217 private WikiFetchThread m_wft;
218 private WikiSearchThread m_wst;
219
220 private void startBackgroundThreads() {
221 info( "Starting background threads." );
222
223 m_wft = new WikiFetchThread();
224 m_wft.start();
225
226 m_wst = new WikiSearchThread();
227 m_wst.start();
228 }
229
230 private void stopBackgroundThreads() {
231 synchronized (m_wft) {
232 m_wft.requestStop();
233 try {
234 m_wft.wait( 30000 );
235 } catch ( InterruptedException e ) {
236 error( "Problem stopping background fetch thread." );
237 }
238 }
239 synchronized (m_wst) {
240 m_wst.requestStop();
241 try {
242 m_wst.wait( 30000 );
243 } catch ( InterruptedException e ) {
244 error( "Problem stopping background search thread." );
245 }
246 }
247 info( "Stopped background threads." );
248
249 int fetches = m_wft.getFetches();
250 double time = (double)(m_wft.getTime()) / 1000.0;
251 double avtime = time / (double)fetches;
252
253 StringBuffer sb = new StringBuffer(100);
254 sb.append( "Fetched " ).append( fetches ).append( " pages in " )
255 .append( threeDecimals( time ) ).append( " sec (" )
256 .append( threeDecimals( avtime ) ).append( " sec per fetch)." );
257 info( sb.toString() );
258
259 int searches = m_wst.getSearches();
260 time = (double)(m_wst.getTime()) / 1000.0;
261 avtime = time / (double)fetches;
262
263 sb.setLength(0);
264 sb.append( "Performed " ).append( searches ).append( " searches in " )
265 .append( threeDecimals( time ) ).append( " sec (" )
266 .append( threeDecimals( avtime ) ).append( " sec per search)." );
267 info( sb.toString() );
268 }
269
270 /*
271 * Main suite starts here. Interpret command line, load the
272 * database, then run the individual tests.
273 */
274
275 private static boolean f_skipload = false;
276 private static boolean f_nobackground = false;
277 private static boolean f_overwrite = false;
278 private static boolean f_skipmath = false;
279
280 public static void main( String[] params ) {
281 for ( int i = 0; i < params.length; ++i ) {
282 if ( "-p".equals( params[i].substring( 0, 2 ) ) ) {
283 f_skipload = true;
284 } else if ( "-v".equals( params[i].substring( 0, 2 ) ) ) {
285 setLoggingLevel( Level.ALL );
286 } else if ( "-m".equals( params[i].substring( 0, 2 ) ) ) {
287 f_skipmath = true;
288 } else if ( "-b".equals( params[i].substring( 0, 2 ) ) ) {
289 f_nobackground = true;
290 } else if ( "-o".equals( params[i].substring( 0, 2 ) ) ) {
291 f_overwrite = true;
292 } else if ( "-h".equals( params[i].substring( 0, 2 ) )
293 || "-?".equals( params[i].substring( 0, 2 ) ) ) {
294 System.out.println( "Usage: java WikiSuite [-povb]\n" +
295 " -p : Skip preload of database\n" +
296 " -m : Skip math test\n" +
297 " -o : Overwrite database\n" +
298 " -v : Verbose logging\n" +
299 " -b : No background thread\n" );
300 return;
301 }
302 }
303 WikiSuite ws = new WikiSuite();
304 if ( ! f_skipload ) {
305 (new DBLoader()).initializeDatabase( ws, f_overwrite );
306 }
307
308 info( "Started Wikipedia Test Suite" );
309 long start_time = System.currentTimeMillis();
310 if ( ! f_nobackground ) { ws.startBackgroundThreads(); }
311
312 /*
313 * All the actual tests go here.
314 */
315 (new LinkTest()).run(ws);
316 (new HTMLTest()).run(ws);
317 (new EditTest()).run(ws);
318 (new ParserTest()).run(ws);
319 (new SpecialTest()).run(ws);
320 (new UploadTest()).run(ws);
321 (new SearchTest()).run(ws);
322 if ( ! f_skipmath ) { (new MathTest()).run(ws); }
323
324 /*
325 * Tests are all done. Clean up and report.
326 */
327 if ( ! f_nobackground ) { ws.stopBackgroundThreads(); }
328 info( "Finished Wikipedia Test Suite" );
329
330 long elapsed_time = System.currentTimeMillis() - start_time;
331
332 long t_hr = elapsed_time / 3600000;
333 long t_min = (elapsed_time % 3600000) / 60000;
334 double t_sec = (double)(elapsed_time % 60000) / 1000.0;
335
336 StringBuffer sb = new StringBuffer(100);
337 sb.append( "Total elapsed time: " ).append( t_hr ).append( " hr, " )
338 .append( t_min ).append( " min, " )
339 .append( threeDecimals( t_sec ) ).append( " sec." );
340 info( sb.toString() );
341 }
342
343 }