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.
9 package com
.piclab
.wikitest
;
11 import com
.meterware
.httpunit
.*;
12 import java
.util
.prefs
.*;
13 import java
.util
.logging
.*;
16 public class WikiSuite
{
18 private static Preferences ms_uprefs
=
19 Preferences
.userNodeForPackage( WikiSuite
.class );
21 /* Settings loaded from preferences:
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;
30 /* Primary conversation for test suite; individual
31 * tests may also create their own if needed.
33 private WebConversation m_conv
;
35 private static Logger ms_logger
= Logger
.getLogger( "com.piclab.wikitest" );
38 /* Set logging level and properties:
40 ms_logger
.setUseParentHandlers( false );
41 Handler h
= new StreamHandler( System
.out
, new WikiLogFormatter() );
42 h
.setLevel( Level
.INFO
);
44 ms_logger
.addHandler( h
);
45 ms_logger
.setLevel( Level
.INFO
);
46 ms_logger
.setFilter( null );
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",
66 "Bracketvars", "Quotes", "Headings", "Blocklevels",
67 "ExternalLinks", "InternalLinks", "Magics", "Equations" };
69 /* Suite constructor: load the prefs to determine which
75 ms_uprefs
.importPreferences(new java
.io
.FileInputStream(
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
);
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" );
90 m_conv
= new WebConversation();
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
; }
102 * Logging/reporting routines:
105 public static void fatal( String msg
) {
106 ms_logger
.severe( msg
);
107 ms_logger
.getHandlers()[0].flush();
110 public static void error( String msg
) {
111 ms_logger
.severe( msg
);
112 ms_logger
.getHandlers()[0].flush();
115 public static void warning( String msg
) {
116 ms_logger
.warning( msg
);
117 ms_logger
.getHandlers()[0].flush();
120 public static void info( String msg
) {
121 ms_logger
.info( msg
);
122 ms_logger
.getHandlers()[0].flush();
125 public static void fine( String msg
) {
126 ms_logger
.fine( msg
);
127 ms_logger
.getHandlers()[0].flush();
130 public static void finer( String msg
) {
131 ms_logger
.finer( msg
);
132 ms_logger
.getHandlers()[0].flush();
135 public static Level
setLoggingLevel( Level newl
) {
136 Level oldl
= ms_logger
.getLevel();
138 ms_logger
.getHandlers()[0].setLevel( newl
);
139 ms_logger
.setLevel( newl
);
143 public static String
threeDecimals( double val
) {
144 String result
= "ERROR";
145 java
.text
.DecimalFormat df
=
146 (java
.text
.DecimalFormat
)(java
.text
.NumberFormat
.getInstance());
148 df
.applyPattern( "#######0.000" );
149 result
= df
.format( val
);
154 * Utility functions for loading and saving strings from/to a file.
157 public static void saveText( String text
, String filename
) {
159 PrintWriter pw
= new PrintWriter( new FileOutputStream( filename
) );
162 } catch( IOException e
) {
163 error( "Couldn't write to \"" + filename
+ "\"" );
166 fine( "Saved \"" + filename
+ "\"" );
169 public static String
loadText( String fname
)
171 FileInputStream fis
= null;
172 BufferedInputStream bis
;
175 fis
= new FileInputStream( fname
);
176 } catch (FileNotFoundException e
) {
177 error( "File \"" + fname
+ "\" not found." );
180 bis
= new BufferedInputStream( fis
);
183 StringBuffer result
= new StringBuffer( 2048 );
184 byte[] buf
= new byte[1024];
190 } catch (IOException e
) {
191 error( "I/O Error reading \"" + fname
+ "\"." );
197 result
.append( new String( buf
, 0, r
, "ISO8859_1" ) );
198 } catch ( java
.io
.UnsupportedEncodingException e
) {
199 result
.append( new String( buf
, 0, r
) );
205 } catch (IOException e
) {
206 warning( "I/O Error closing file \"" + fname
+ "\"." );
208 fine( "Loaded \"" + fname
+ "\"" );
209 return result
.toString();
213 * Start background threads that run while all the other
214 * tests are going on.
217 private WikiFetchThread m_wft
;
218 private WikiSearchThread m_wst
;
220 private void startBackgroundThreads() {
221 info( "Starting background threads." );
223 m_wft
= new WikiFetchThread();
226 m_wst
= new WikiSearchThread();
230 private void stopBackgroundThreads() {
231 synchronized (m_wft
) {
235 } catch ( InterruptedException e
) {
236 error( "Problem stopping background fetch thread." );
239 synchronized (m_wst
) {
243 } catch ( InterruptedException e
) {
244 error( "Problem stopping background search thread." );
247 info( "Stopped background threads." );
249 int fetches
= m_wft
.getFetches();
250 double time
= (double)(m_wft
.getTime()) / 1000.0;
251 double avtime
= time
/ (double)fetches
;
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() );
259 int searches
= m_wst
.getSearches();
260 time
= (double)(m_wst
.getTime()) / 1000.0;
261 avtime
= time
/ (double)fetches
;
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() );
271 * Main suite starts here. Interpret command line, load the
272 * database, then run the individual tests.
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;
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 ) ) ) {
284 } else if ( "-v".equals( params
[i
].substring( 0, 2 ) ) ) {
285 setLoggingLevel( Level
.ALL
);
286 } else if ( "-m".equals( params
[i
].substring( 0, 2 ) ) ) {
288 } else if ( "-b".equals( params
[i
].substring( 0, 2 ) ) ) {
289 f_nobackground
= true;
290 } else if ( "-o".equals( params
[i
].substring( 0, 2 ) ) ) {
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" );
303 WikiSuite ws
= new WikiSuite();
304 if ( ! f_skipload
) {
305 (new DBLoader()).initializeDatabase( ws
, f_overwrite
);
308 info( "Started Wikipedia Test Suite" );
309 long start_time
= System
.currentTimeMillis();
310 if ( ! f_nobackground
) { ws
.startBackgroundThreads(); }
313 * All the actual tests go here.
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
); }
325 * Tests are all done. Clean up and report.
327 if ( ! f_nobackground
) { ws
.stopBackgroundThreads(); }
328 info( "Finished Wikipedia Test Suite" );
330 long elapsed_time
= System
.currentTimeMillis() - start_time
;
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;
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() );