Index: trunk/phpwiki/testsuite/com/piclab/wikitest/WikiTest.java |
— | — | @@ -12,84 +12,60 @@ |
13 | 13 | public class WikiTest { |
14 | 14 | |
15 | 15 | protected WikiSuite m_suite; |
16 | | -protected WebConversation m_conv; |
17 | | -protected WebResponse m_resp; |
18 | 16 | protected long m_start, m_stop; |
19 | 17 | |
20 | | -public WikiTest(WikiSuite s) { |
21 | | - m_suite = s; |
22 | | - m_conv = new WebConversation(); |
23 | | -} |
| 18 | +/* All subclasses of WikiTest should override testName() |
| 19 | + * to return a useful name and runTest() to perform the actual |
| 20 | + * tests. runTest() hould return true on success. You also |
| 21 | + * need to duplicate the constructor since that's not |
| 22 | + * inherited. |
| 23 | + */ |
24 | 24 | |
| 25 | +public WikiTest(WikiSuite s) { m_suite = s; } |
| 26 | + |
25 | 27 | public String testName() { return "Basic"; } |
26 | 28 | |
27 | | -protected boolean runTestInner() { |
28 | | - try { |
29 | | - m_resp = m_suite.fetchPage( m_conv, "" ); |
30 | | - WikiTest.showResponse( m_resp ); |
31 | | - } catch (Exception e) { |
32 | | - System.err.println( "Exception: " + e ); |
33 | | - return false; |
34 | | - } |
| 29 | +protected boolean runTest() throws Exception { |
35 | 30 | return true; |
36 | 31 | } |
37 | 32 | |
38 | | -public static void showResponse( WebResponse r ) { |
39 | | - try { |
40 | | - System.out.println( " Received \"" + r.getTitle() + "\": " + |
41 | | - r.getText().length() + " bytes of " + r.getContentType() ); |
42 | | - } catch (Exception e) { |
43 | | - System.err.println( "Exception: " + e ); |
44 | | - } |
45 | | -} |
| 33 | +/* You generally won't want to override run(), as it does |
| 34 | + * all the extra stuff around the actual test invocation. |
| 35 | + */ |
46 | 36 | |
47 | | -public boolean runTest() { |
48 | | - m_start = System.currentTimeMillis(); |
49 | | - boolean ret = runTestInner(); |
50 | | - m_stop = System.currentTimeMillis(); |
51 | | - m_conv = null; |
52 | | - return ret; |
53 | | -} |
| 37 | +public void run() { |
| 38 | + boolean result = false; |
54 | 39 | |
55 | | -public boolean runTestAndReport() { |
56 | | - if ( runTest() ) { |
57 | | - reportSuccess(); |
58 | | - return true; |
59 | | - } else { |
60 | | - reportFailure(); |
61 | | - } |
62 | | - return false; |
63 | | -} |
64 | | - |
65 | | -private void reportTime( boolean result ) { |
66 | 40 | StringBuffer sb = new StringBuffer(100); |
67 | 41 | java.text.DecimalFormat df = |
68 | 42 | (java.text.DecimalFormat)(java.text.NumberFormat.getInstance()); |
69 | 43 | |
| 44 | + m_start = System.currentTimeMillis(); |
| 45 | + |
70 | 46 | try { |
| 47 | + result = runTest(); |
| 48 | + } catch (Exception e) { |
| 49 | + WikiSuite.error( "Exception (" + e + ") running test \"" + |
| 50 | + testName() + "\"" ); |
| 51 | + result = false; |
| 52 | + } |
| 53 | + m_stop = System.currentTimeMillis(); |
| 54 | + |
| 55 | + try { |
71 | 56 | df.applyPattern( "#######0.000" ); |
72 | 57 | |
73 | | - sb.append( "*** ").append( testName() ) |
74 | | - .append( " " ); |
| 58 | + sb.append( "Test \"" ).append( testName() ) |
| 59 | + .append( "\" " ); |
75 | 60 | sb.setLength( 20 ); |
76 | 61 | sb.append( result ? "Succeeded" : "Failed " ).append( " (" ) |
77 | 62 | .append( df.format( (double)(m_stop - m_start) / 1000.0 ) ) |
78 | 63 | .append( " secs)" ); |
79 | 64 | |
80 | | - System.out.println( sb ); |
| 65 | + WikiSuite.info( sb.toString() ); |
81 | 66 | } catch (Exception e) { |
82 | | - System.err.println( "Exception: " + e ); |
| 67 | + WikiSuite.error( "Exception (" + e + ") running test \"" + |
| 68 | + testName() + "\"" ); |
83 | 69 | } |
84 | 70 | } |
85 | 71 | |
86 | | -public void reportSuccess() { reportTime( true ); } |
87 | | -public void reportFailure() { reportTime( false ); } |
88 | | - |
89 | | - |
90 | | -public static void main( String[] params ) { |
91 | | - WikiSuite ws = new WikiSuite(); |
92 | | - WikiTest wt = new WikiTest( ws ); |
93 | | - wt.runTestAndReport(); |
94 | 72 | } |
95 | | - |
96 | | -} |
Index: trunk/phpwiki/testsuite/com/piclab/wikitest/WikiSuiteFailureException.java |
— | — | @@ -0,0 +1,28 @@ |
| 2 | +/* |
| 3 | + * This exception is thrown on any general test failure. |
| 4 | + * It is usually fatal. |
| 5 | + */ |
| 6 | + |
| 7 | +package com.piclab.wikitest; |
| 8 | + |
| 9 | +public class WikiSuiteFailureException |
| 10 | +extends Exception { |
| 11 | + |
| 12 | +public WikiSuiteFailureException() { |
| 13 | + super(); |
| 14 | +} |
| 15 | + |
| 16 | +public WikiSuiteFailureException(Throwable t) { |
| 17 | + super(t); |
| 18 | +} |
| 19 | + |
| 20 | +public WikiSuiteFailureException(String m) { |
| 21 | + super(m); |
| 22 | +} |
| 23 | + |
| 24 | +public WikiSuiteFailureException(String m, Throwable t) { |
| 25 | + super(m, t); |
| 26 | +} |
| 27 | + |
| 28 | +} |
| 29 | + |
Property changes on: trunk/phpwiki/testsuite/com/piclab/wikitest/WikiSuiteFailureException.java |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 30 | + native |
Added: svn:keywords |
2 | 31 | + Author Date Id Revision |
Index: trunk/phpwiki/testsuite/com/piclab/wikitest/EditTest.java |
— | — | @@ -1,7 +1,6 @@ |
2 | 2 | |
3 | 3 | /* |
4 | | - * Test that basic navigation around the wiki with |
5 | | - * internal links is working. |
| 4 | + * Test that basic page editing is working. |
6 | 5 | */ |
7 | 6 | |
8 | 7 | package com.piclab.wikitest; |
— | — | @@ -15,28 +14,48 @@ |
16 | 15 | |
17 | 16 | public String testName() { return "Editing"; } |
18 | 17 | |
19 | | -protected boolean runTestInner() { |
20 | | - try { |
21 | | - m_resp = m_suite.editPage( m_conv, "Radio" ); |
22 | | - WikiTest.showResponse( m_resp ); |
| 18 | +protected boolean runTest() throws Exception { |
| 19 | + boolean result = true; |
23 | 20 | |
24 | | - WebForm f = m_suite.getFormByName( m_resp, "editform" ); |
25 | | - String text = f.getParameterValue( "wpTextbox1" ); |
| 21 | + WebResponse wr = m_suite.editPage( "Agriculture" ); |
| 22 | + WebForm editform = null; |
| 23 | + WebRequest req = null; |
26 | 24 | |
27 | | - PrintWriter w = new PrintWriter( new FileWriter("radio.txt") ); |
28 | | - w.println( text ); |
29 | | - w.close(); |
30 | | - } catch (Exception e) { |
31 | | - System.err.println( "Exception: " + e ); |
32 | | - return false; |
33 | | - } |
34 | | - return true; |
| 25 | + editform = WikiSuite.getFormByName( wr, "editform" ); |
| 26 | + req = editform.getRequest( "wpSave" ); |
| 27 | + String text = req.getParameter( "wpTextbox1" ); |
| 28 | + req.setParameter( "wpTextbox1", text + "\nEdited for testing." ); |
| 29 | + wr = m_suite.getResponse( req ); |
| 30 | + |
| 31 | + wr = m_suite.viewPage( "Special:Recentchanges" ); |
| 32 | + text = wr.getText(); |
| 33 | + if ( text.indexOf( "Agriculture" ) < 0 ) { result = false; } |
| 34 | + |
| 35 | + wr = m_suite.viewPage( "Omaha" ); /* Not preloaded */ |
| 36 | + text = wr.getText(); |
| 37 | + if ( text.indexOf( "no text in this page" ) < 0 ) { result = false; } |
| 38 | + |
| 39 | + WebLink l = wr.getFirstMatchingLink( WebLink.MATCH_CONTAINED_TEXT, |
| 40 | + "Edit this page" ); |
| 41 | + wr = l.click(); |
| 42 | + |
| 43 | + editform = WikiSuite.getFormByName( wr, "editform" ); |
| 44 | + req = editform.getRequest( "wpSave" ); |
| 45 | + req.setParameter( "wpTextbox1", "'''Omaha''' is a city in [[Nebraska]]" ); |
| 46 | + wr = m_suite.getResponse( req ); |
| 47 | + |
| 48 | + wr = m_suite.viewPage( "Omaha" ); |
| 49 | + text = wr.getText(); |
| 50 | + if ( text.indexOf( "no text in this page" ) >= 0 ) { result = false; } |
| 51 | + if ( text.indexOf( "Nebraska" ) < 0 ) { result = false; } |
| 52 | + |
| 53 | + return result; |
35 | 54 | } |
36 | 55 | |
37 | 56 | public static void main( String[] params ) { |
38 | 57 | WikiSuite ws = new WikiSuite(); |
39 | 58 | EditTest wt = new EditTest( ws ); |
40 | | - wt.runTestAndReport(); |
| 59 | + wt.run(); |
41 | 60 | } |
42 | 61 | |
43 | 62 | } |
Index: trunk/phpwiki/testsuite/com/piclab/wikitest/WikiFetchThread.java |
— | — | @@ -0,0 +1,57 @@ |
| 2 | + |
| 3 | +/* |
| 4 | + * WikiFetchThread is the background thread that fetches |
| 5 | + * pages from the preload list until the wuite is done. |
| 6 | + */ |
| 7 | + |
| 8 | +package com.piclab.wikitest; |
| 9 | + |
| 10 | +import com.meterware.httpunit.*; |
| 11 | + |
| 12 | +public class WikiFetchThread extends Thread { |
| 13 | + |
| 14 | +private WikiSuite m_suite; |
| 15 | +private WebConversation m_conv; |
| 16 | +private volatile boolean m_running; |
| 17 | + |
| 18 | +public WikiFetchThread(WikiSuite s) { |
| 19 | + m_suite = s; |
| 20 | + m_conv = new WebConversation(); |
| 21 | +} |
| 22 | + |
| 23 | +public void run() { |
| 24 | + int index = 0; |
| 25 | + |
| 26 | + WikiSuite.fine( "Started background page-fetch thread." ); |
| 27 | + m_running = true; |
| 28 | + |
| 29 | + while ( m_suite.stillRunning() ) { |
| 30 | + String url = WikiSuite.editUrl( WikiSuite.preloadedPages[index] ); |
| 31 | + try { |
| 32 | + WebResponse wr = m_conv.getResponse( url ); |
| 33 | + } catch (Exception e) { |
| 34 | + WikiSuite.warning( "Error (" + e + ") fetching \"" + |
| 35 | + WikiSuite.preloadedPages[index] + "\"" ); |
| 36 | + } |
| 37 | + |
| 38 | + WikiSuite.fine( "Fetched \"" + WikiSuite.preloadedPages[index] + "\"" ); |
| 39 | + if ( ++index >= WikiSuite.preloadedPages.length ) { index = 0; } |
| 40 | + } |
| 41 | + m_running = false; |
| 42 | + |
| 43 | + WikiSuite.fine( "Terminated background page-fetch thread." ); |
| 44 | +} |
| 45 | + |
| 46 | + |
| 47 | +/* |
| 48 | + * After suite sets stillRunning() to false, this thread will |
| 49 | + * eventually quit, but we have suite call this function to wait |
| 50 | + * for it so that we don't get fetches after the final report. |
| 51 | + */ |
| 52 | + |
| 53 | +public void waitfor() { |
| 54 | + do { |
| 55 | + } while (m_running); |
| 56 | +} |
| 57 | + |
| 58 | +} |
Property changes on: trunk/phpwiki/testsuite/com/piclab/wikitest/WikiFetchThread.java |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 59 | + native |
Added: svn:keywords |
2 | 60 | + Author Date Id Revision |
Index: trunk/phpwiki/testsuite/com/piclab/wikitest/WikiLogFormatter.java |
— | — | @@ -0,0 +1,38 @@ |
| 2 | + |
| 3 | +package com.piclab.wikitest; |
| 4 | + |
| 5 | +import java.util.logging.*; |
| 6 | + |
| 7 | +class WikiLogFormatter extends Formatter { |
| 8 | + |
| 9 | +java.text.DateFormat m_df; |
| 10 | + |
| 11 | +public WikiLogFormatter() { |
| 12 | + m_df = new java.text.SimpleDateFormat( "HH:mm:ss " ); |
| 13 | +} |
| 14 | + |
| 15 | +public String format( LogRecord rec ) { |
| 16 | + StringBuffer sb = new StringBuffer( 200 ); |
| 17 | + |
| 18 | + sb.append( m_df.format( new java.util.Date() ) ); |
| 19 | + |
| 20 | + Level l = rec.getLevel(); |
| 21 | + if ( l == Level.SEVERE ) { |
| 22 | + sb.append( "ERROR: " ); |
| 23 | + } else if ( l == Level.WARNING ) { |
| 24 | + sb.append( " WARN: " ); |
| 25 | + } else if ( l == Level.CONFIG ) { |
| 26 | + sb.append( " CONF: " ); |
| 27 | + } else if ( l == Level.INFO || l == Level.FINE || |
| 28 | + l == Level.FINER || l == Level.FINEST ) { |
| 29 | + sb.append( " INFO: " ); |
| 30 | + } else { |
| 31 | + sb.append( " " ); |
| 32 | + } |
| 33 | + sb.append( rec.getMessage() ).append( "\n" ); |
| 34 | + |
| 35 | + return sb.toString(); |
| 36 | +} |
| 37 | + |
| 38 | +} |
| 39 | + |
Property changes on: trunk/phpwiki/testsuite/com/piclab/wikitest/WikiLogFormatter.java |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 40 | + native |
Added: svn:keywords |
2 | 41 | + Author Date Id Revision |
Index: trunk/phpwiki/testsuite/com/piclab/wikitest/LinkTest.java |
— | — | @@ -14,31 +14,32 @@ |
15 | 15 | |
16 | 16 | public String testName() { return "Links"; } |
17 | 17 | |
18 | | -protected boolean runTestInner() { |
19 | | - try { |
20 | | - m_resp = m_suite.fetchPage( m_conv, "" ); |
21 | | - WikiTest.showResponse( m_resp ); |
| 18 | +protected boolean runTest() throws Exception { |
| 19 | + boolean result = true; |
| 20 | + WebResponse wr = m_suite.viewPage( "" ); /* Main page */ |
22 | 21 | |
23 | | - WebLink l = m_resp.getFirstMatchingLink( |
24 | | - WebLink.MATCH_CONTAINED_TEXT, "physics" ); |
25 | | - m_resp = l.click(); |
26 | | - WikiTest.showResponse( m_resp ); |
| 22 | + WebLink l = wr.getFirstMatchingLink( |
| 23 | + WebLink.MATCH_CONTAINED_TEXT, "game" ); |
| 24 | + wr = l.click(); |
| 25 | + WikiSuite.showResponseTitle( wr ); |
27 | 26 | |
28 | | - l = m_resp.getFirstMatchingLink( |
29 | | - WebLink.MATCH_CONTAINED_TEXT, "radio" ); |
30 | | - m_resp = l.click(); |
31 | | - WikiTest.showResponse( m_resp ); |
32 | | - } catch (Exception e) { |
33 | | - System.err.println( "Exception: " + e ); |
34 | | - return false; |
35 | | - } |
36 | | - return true; |
| 27 | + l = wr.getFirstMatchingLink( |
| 28 | + WebLink.MATCH_CONTAINED_TEXT, "card" ); |
| 29 | + wr = l.click(); |
| 30 | + WikiSuite.showResponseTitle( wr ); |
| 31 | + |
| 32 | + l = wr.getFirstMatchingLink( |
| 33 | + WebLink.MATCH_CONTAINED_TEXT, "poker" ); |
| 34 | + wr = l.click(); |
| 35 | + WikiSuite.showResponseTitle( wr ); |
| 36 | + |
| 37 | + return result; |
37 | 38 | } |
38 | 39 | |
39 | 40 | public static void main( String[] params ) { |
40 | 41 | WikiSuite ws = new WikiSuite(); |
41 | 42 | LinkTest wt = new LinkTest( ws ); |
42 | | - wt.runTestAndReport(); |
| 43 | + wt.run(); |
43 | 44 | } |
44 | 45 | |
45 | 46 | } |
Index: trunk/phpwiki/testsuite/com/piclab/wikitest/WikiSuite.java |
— | — | @@ -2,29 +2,75 @@ |
3 | 3 | /* |
4 | 4 | * WikiSuite is the driver class for the wiki test suite. |
5 | 5 | * It represents the location of the wiki, and provides |
6 | | - * some common routines for access. |
| 6 | + * some common static routines for access. When idividual |
| 7 | + * tests are instantiated, they are passed this object, |
| 8 | + * and they use its utility functions and result reporting. |
7 | 9 | */ |
8 | 10 | |
9 | 11 | package com.piclab.wikitest; |
| 12 | + |
10 | 13 | import com.meterware.httpunit.*; |
11 | 14 | import org.w3c.dom.*; |
12 | 15 | import java.util.prefs.*; |
| 16 | +import java.util.logging.*; |
| 17 | +import java.io.*; |
13 | 18 | |
14 | | - |
15 | 19 | public class WikiSuite { |
16 | 20 | |
17 | | -private static Preferences m_uprefs = |
| 21 | +private static Preferences ms_uprefs = |
18 | 22 | Preferences.userNodeForPackage( WikiSuite.class ); |
19 | 23 | |
20 | | -private String m_server; |
21 | | -private String m_script; |
22 | | -private String m_articlepath; |
23 | | -private String m_uploadpath; |
24 | | -private String m_mainpage; |
| 24 | +/* Settings loaded from preferences: |
| 25 | + */ |
| 26 | +private static String ms_server; |
| 27 | +private static String ms_script; |
| 28 | +private static String ms_articlepath; |
| 29 | +private static String ms_uploadpath; |
| 30 | +private static String ms_mainpage; |
25 | 31 | |
| 32 | +/* Primary conversation for test suite; individual |
| 33 | + * tests may also create their own if needed. |
| 34 | + */ |
| 35 | +private WebConversation m_conv; |
| 36 | + |
| 37 | +private static Logger ms_logger = Logger.getLogger( "com.piclab.wikitest" ); |
| 38 | + |
| 39 | +static { |
| 40 | + /* Set logging level and properties: |
| 41 | + */ |
| 42 | + ms_logger.setUseParentHandlers( false ); |
| 43 | + Handler h = new StreamHandler( System.out, new WikiLogFormatter() ); |
| 44 | + h.setLevel( Level.INFO ); |
| 45 | + |
| 46 | + ms_logger.addHandler( h ); |
| 47 | + ms_logger.setLevel( Level.INFO ); |
| 48 | + ms_logger.setFilter( null ); |
| 49 | +} |
| 50 | + |
| 51 | +static String preloadedPages[] = { "Agriculture", "Anthropology", |
| 52 | + "Archaeology", "Architecture", "Astronomy_and_astrophysics", |
| 53 | + "Biology", "Business_and_industry", "Card_game", "Chemistry", |
| 54 | + "Classics", "Communication", "Computer_Science", "Cooking", |
| 55 | + "Critical_theory", "Dance", "Earth_science", "Economics", |
| 56 | + "Education", "Engineering", "Entertainment", |
| 57 | + "Family_and_consumer_science", "Film", "Game", "Geography", |
| 58 | + "Handicraft", "Health_science", "History_of_science_and_technology", |
| 59 | + "History", "Hobby", "Language", "Law", |
| 60 | + "Library_and_information_science", "Linguistics", "Literature", |
| 61 | + "Main_Page", "Mathematics", "Music", "Opera", "Painting", |
| 62 | + "Philosophy", "Physics", "Poker", "Political_science", "Psychology", |
| 63 | + "Public_affairs", "Recreation", "Religion", "Sculpture", |
| 64 | + "Sociology", "Sport", "Statistics", "Technology", "Theater", |
| 65 | + "Tourism", "Transport", "Visual_arts_and_design", |
| 66 | + "World_Series_of_Poker" }; |
| 67 | + |
| 68 | +/* Suite constructor: load the prefs to determine which |
| 69 | + * wiki to test. |
| 70 | + */ |
| 71 | + |
26 | 72 | public WikiSuite() { |
27 | 73 | try { |
28 | | - m_uprefs.importPreferences(new java.io.FileInputStream( |
| 74 | + ms_uprefs.importPreferences(new java.io.FileInputStream( |
29 | 75 | "wikitest.prefs" )); |
30 | 76 | } catch (java.io.IOException e) { |
31 | 77 | /* File probably doesn't exist: no problem, use defaults */ |
— | — | @@ -32,19 +78,23 @@ |
33 | 79 | System.err.println( "Bad preferences file format: " + e ); |
34 | 80 | } |
35 | 81 | |
36 | | - m_server = m_uprefs.get( "server", "http://www.wikipedia.org" ); |
37 | | - m_script = m_uprefs.get( "script", "/w/wiki.phtml" ); |
38 | | - m_articlepath = m_uprefs.get( "articlepath", |
39 | | - "http://www.wikipedia.org/wiki" ); |
40 | | - m_uploadpath = m_uprefs.get( "uploadpath", |
41 | | - "http://www.wikipedia.org/upload/" ); |
42 | | - m_mainpage = m_uprefs.get( "mainpage", "Main Page" ); |
| 82 | + ms_server = ms_uprefs.get( "server", "http://localhost" ); |
| 83 | + ms_script = ms_uprefs.get( "script", "/wiki.phtml" ); |
| 84 | + ms_articlepath = ms_uprefs.get( "articlepath", "" ); |
| 85 | + ms_uploadpath = ms_uprefs.get( "uploadpath", "http://localhost/upload/" ); |
| 86 | + ms_mainpage = ms_uprefs.get( "mainpage", "Main Page" ); |
| 87 | + |
| 88 | + m_conv = new WebConversation(); |
43 | 89 | } |
44 | 90 | |
45 | | -public String titleToUrl( String title ) { |
| 91 | +/* Utility routine to munge page titles into URL form. |
| 92 | + * Should match the ruotines used by the wiki itself. |
| 93 | + */ |
| 94 | + |
| 95 | +public static String titleToUrl( String title ) { |
46 | 96 | StringBuffer sb = new StringBuffer( title.length() + 20 ); |
47 | 97 | |
48 | | - if ( "".equals( title ) ) { title = m_mainpage; } |
| 98 | + if ( "".equals( title ) ) { title = ms_mainpage; } |
49 | 99 | |
50 | 100 | for (int i=0; i<title.length(); ++i) { |
51 | 101 | char c = title.charAt(i); |
— | — | @@ -66,45 +116,155 @@ |
67 | 117 | return sb.toString(); |
68 | 118 | } |
69 | 119 | |
70 | | -public WebResponse fetchPage( WebConversation wc, String title ) { |
71 | | - WebResponse r = null; |
| 120 | +public static String viewUrl( String title ) { |
72 | 121 | StringBuffer url = new StringBuffer(200); |
| 122 | + String t = titleToUrl( title ); |
73 | 123 | |
74 | | - if ( "".equals( title ) ) { |
75 | | - url.append( m_server ); |
| 124 | + int p = ms_articlepath.indexOf( "$1" ); |
| 125 | + if ( p >= 0 ) { |
| 126 | + url.append( ms_articlepath ); |
| 127 | + url.replace( p, p+2, t ); |
76 | 128 | } else { |
77 | | - url.append( m_articlepath ).append( "/" ).append( |
78 | | - titleToUrl( title ) ); |
| 129 | + url.append( ms_server ).append( ms_script ). |
| 130 | + append( "?title=" ).append( t ); |
79 | 131 | } |
| 132 | + return url.toString(); |
| 133 | +} |
80 | 134 | |
| 135 | +public static String editUrl( String title ) { |
| 136 | + StringBuffer url = new StringBuffer( 200 ); |
| 137 | + String t = titleToUrl( title ); |
| 138 | + |
| 139 | + url.append( ms_server ).append( ms_script ).append( "?title=" ) |
| 140 | + .append( t ).append( "&action=edit" ); |
| 141 | + return url.toString(); |
| 142 | +} |
| 143 | + |
| 144 | +/* |
| 145 | + * Logging/reporting routines: |
| 146 | + */ |
| 147 | + |
| 148 | +public static void fatal( String msg ) { |
| 149 | + ms_logger.severe( msg ); |
| 150 | + ms_logger.getHandlers()[0].flush(); |
| 151 | +} |
| 152 | + |
| 153 | +public static void error( String msg ) { |
| 154 | + ms_logger.severe( msg ); |
| 155 | + ms_logger.getHandlers()[0].flush(); |
| 156 | +} |
| 157 | + |
| 158 | +public static void warning( String msg ) { |
| 159 | + ms_logger.warning( msg ); |
| 160 | + ms_logger.getHandlers()[0].flush(); |
| 161 | +} |
| 162 | + |
| 163 | +public static void info( String msg ) { |
| 164 | + ms_logger.info( msg ); |
| 165 | + ms_logger.getHandlers()[0].flush(); |
| 166 | +} |
| 167 | + |
| 168 | +public static void fine( String msg ) { |
| 169 | + ms_logger.fine( msg ); |
| 170 | +} |
| 171 | + |
| 172 | +/* |
| 173 | + * Utility functions to interact with the wiki: |
| 174 | + */ |
| 175 | + |
| 176 | +public WebResponse getResponse( String url ) { |
| 177 | + WebResponse r = null; |
| 178 | + |
81 | 179 | try { |
82 | | - r = wc.getResponse( url.toString() ); |
83 | | - } catch (Exception e) { |
84 | | - System.err.println( "Exception: " + e ); |
| 180 | + r = m_conv.getResponse( url ); |
| 181 | + } catch (org.xml.sax.SAXException e) { |
| 182 | + warning( "Error parsing received page \"" + url + "\"" ); |
| 183 | + } catch (java.net.MalformedURLException e) { |
| 184 | + fatal( "Badly formed URL \"" + url + "\"" ); |
| 185 | + } catch (java.io.IOException e) { |
| 186 | + warning( "I/O Error receiving page \"" + url + "\"" ); |
85 | 187 | } |
86 | 188 | return r; |
87 | 189 | } |
88 | 190 | |
89 | | -public WebResponse editPage( WebConversation wc, String title ) { |
| 191 | +public WebResponse getResponse( WebRequest req ) { |
90 | 192 | WebResponse r = null; |
| 193 | + |
| 194 | + try { |
| 195 | + r = m_conv.getResponse( req ); |
| 196 | + } catch (org.xml.sax.SAXException e) { |
| 197 | + warning( "Error parsing received page." ); |
| 198 | + } catch (java.io.IOException e) { |
| 199 | + warning( "I/O Error receiving page." ); |
| 200 | + } |
| 201 | + return r; |
| 202 | +} |
| 203 | + |
| 204 | +public static void showResponseTitle( WebResponse wr ) { |
| 205 | + try { |
| 206 | + fine( "Viewing \"" + wr.getTitle() + "\"" ); |
| 207 | + } catch (org.xml.sax.SAXException e) { |
| 208 | + error( "Exception (" + e + ")" ); |
| 209 | + } |
| 210 | +} |
| 211 | + |
| 212 | +public WebResponse viewPage( String title ) { |
| 213 | + WebResponse wr = getResponse( viewUrl( title ) ); |
| 214 | + showResponseTitle( wr ); |
| 215 | + return wr; |
| 216 | +} |
| 217 | + |
| 218 | +public WebResponse editPage( String title ) { |
| 219 | + WebResponse wr = getResponse( editUrl( title ) ); |
| 220 | + showResponseTitle( wr ); |
| 221 | + return wr; |
| 222 | +} |
| 223 | + |
| 224 | +public WebResponse loadPageFromFile( String title ) |
| 225 | +throws WikiSuiteFailureException { |
91 | 226 | StringBuffer url = new StringBuffer(200); |
| 227 | + String t = titleToUrl( title ); |
92 | 228 | |
93 | | - url.append( m_server ).append( m_script ).append( "?title=" ). |
94 | | - append( titleToUrl( title ) ).append( "&action=edit" ); |
| 229 | + url.append( "texts/" ).append( t ).append( ".txt" ); |
| 230 | + String text = loadFile( url.toString() ); |
95 | 231 | |
| 232 | + url.setLength( 0 ); |
| 233 | + url.append( ms_server ).append( ms_script ).append( "?title=" ) |
| 234 | + .append( t ).append( "&action=edit" ); |
| 235 | + |
| 236 | + WebResponse wr = getResponse( url.toString() ); |
| 237 | + WebForm editform = null; |
| 238 | + |
96 | 239 | try { |
97 | | - r = wc.getResponse( url.toString() ); |
98 | | - } catch (Exception e) { |
99 | | - System.err.println( "Exception: " + e ); |
| 240 | + editform = getFormByName( wr, "editform" ); |
| 241 | + } catch (org.xml.sax.SAXException e) { |
| 242 | + error( "Error parsing edit form for page \"" + title + "\"." ); |
| 243 | + throw new WikiSuiteFailureException( e.toString() ); |
100 | 244 | } |
101 | | - return r; |
| 245 | + WebRequest req = editform.getRequest( "wpSave" ); |
| 246 | + req.setParameter( "wpTextbox1", text ); |
| 247 | + |
| 248 | + WebResponse ret = null; |
| 249 | + try { |
| 250 | + ret = m_conv.getResponse( req ); |
| 251 | + } catch (org.xml.sax.SAXException e) { |
| 252 | + fatal( "Error parsing received page from form submission." ); |
| 253 | + throw new WikiSuiteFailureException( e.toString() ); |
| 254 | + } catch (java.net.MalformedURLException e) { |
| 255 | + fatal( "Badly formed URL from form submission." ); |
| 256 | + throw new WikiSuiteFailureException( e.toString() ); |
| 257 | + } catch (java.io.IOException e) { |
| 258 | + fatal( "I/O Error receiving page from form submission." ); |
| 259 | + throw new WikiSuiteFailureException( e.toString() ); |
| 260 | + } |
| 261 | + return ret; |
102 | 262 | } |
103 | 263 | |
104 | | -public WebForm getFormByName( WebResponse resp, String name ) |
| 264 | +public static WebForm getFormByName( WebResponse resp, String name ) |
105 | 265 | throws org.xml.sax.SAXException { |
106 | 266 | |
107 | 267 | WebForm[] forms = resp.getForms(); |
108 | | - for (int i=0; i < forms.length; i++) { |
| 268 | + for (int i=0; i < forms.length; ++i) { |
109 | 269 | Node formNode = forms[i].getDOMSubtree(); |
110 | 270 | NamedNodeMap nnm = formNode.getAttributes(); |
111 | 271 | Node nameNode = nnm.getNamedItem( "name" ); |
— | — | @@ -117,12 +277,136 @@ |
118 | 278 | return null; |
119 | 279 | } |
120 | 280 | |
| 281 | +/* |
| 282 | + * Some utility functions useful for testing and comparing things. |
| 283 | + */ |
| 284 | + |
| 285 | +public static String loadFile( String fname ) |
| 286 | +{ |
| 287 | + FileInputStream fis = null; |
| 288 | + BufferedInputStream bis; |
| 289 | + |
| 290 | + try { |
| 291 | + fis = new FileInputStream( fname ); |
| 292 | + } catch (FileNotFoundException e) { |
| 293 | + error( "File \"" + fname + "\" not found." ); |
| 294 | + } |
| 295 | + bis = new BufferedInputStream( fis ); |
| 296 | + |
| 297 | + int r; |
| 298 | + StringBuffer result = new StringBuffer( 2048 ); |
| 299 | + byte[] buf = new byte[1024]; |
| 300 | + |
| 301 | + while (true) { |
| 302 | + r = -1; |
| 303 | + try { |
| 304 | + r = bis.read( buf ); |
| 305 | + } catch (IOException e) { |
| 306 | + error( "I/O Error reading \"" + fname + "\"." ); |
| 307 | + break; |
| 308 | + } |
| 309 | + if ( r <= 0 ) break; |
| 310 | + |
| 311 | + try { |
| 312 | + result.append( new String( buf, 0, r, "ISO8859_1" ) ); |
| 313 | + } catch ( java.io.UnsupportedEncodingException e ) { |
| 314 | + result.append( new String( buf, 0, r ) ); |
| 315 | + } |
| 316 | + } |
| 317 | + try { |
| 318 | + bis.close(); |
| 319 | + fis.close(); |
| 320 | + } catch (IOException e) { |
| 321 | + warning( "I/O Error closing file \"" + fname + "\"." ); |
| 322 | + } |
| 323 | + return result.toString(); |
| 324 | +} |
| 325 | + |
| 326 | + |
| 327 | +/* |
| 328 | + * Load database with initial set of pages for testing. |
| 329 | + */ |
| 330 | +private void initializeDatabase() { |
| 331 | + |
| 332 | + WebResponse wr; |
| 333 | + |
| 334 | + fine( "Preloading database with test pages." ); |
| 335 | + for (int i = 0; i < preloadedPages.length; ++i) { |
| 336 | + wr = null; |
| 337 | + try { |
| 338 | + wr = loadPageFromFile( preloadedPages[i] ); |
| 339 | + } catch (WikiSuiteFailureException e) { |
| 340 | + warning( "Failed to load \"" + preloadedPages[i] + "\"" ); |
| 341 | + } |
| 342 | + if (wr != null) { |
| 343 | + fine( "Loaded \"" + preloadedPages[i] + "\"" ); |
| 344 | + } |
| 345 | + } |
| 346 | +} |
| 347 | + |
| 348 | +/* |
| 349 | + * Start a background thread which does regular fetches of |
| 350 | + * the preloaded page list while all the other tests are |
| 351 | + * going on. |
| 352 | + */ |
| 353 | + |
| 354 | +private boolean m_stillrunning = false; |
| 355 | +private WikiFetchThread m_wft; |
| 356 | + |
| 357 | +private void startBackgroundFetchThread() { |
| 358 | + m_stillrunning = true; |
| 359 | + m_wft = new WikiFetchThread( this ); |
| 360 | + m_wft.start(); |
| 361 | +} |
| 362 | + |
| 363 | +private synchronized void stopBackgroundFetchThread() { |
| 364 | + m_stillrunning = false; |
| 365 | + m_wft.waitfor(); |
| 366 | +} |
| 367 | + |
| 368 | +public boolean stillRunning() { |
| 369 | + return m_stillrunning; |
| 370 | +} |
| 371 | + |
| 372 | +/* |
| 373 | + * Main suite starts here. Interpret command line, load the |
| 374 | + * database, then run the individual tests. |
| 375 | + */ |
| 376 | + |
121 | 377 | public static void main( String[] params ) { |
122 | 378 | WikiSuite ws = new WikiSuite(); |
123 | 379 | |
124 | | - if (! (new WikiTest(ws)).runTestAndReport()) return; |
125 | | - if (! (new LinkTest(ws)).runTestAndReport()) return; |
126 | | - if (! (new EditTest(ws)).runTestAndReport()) return; |
| 380 | + long start_time = System.currentTimeMillis(); |
| 381 | + info( "Started Wikipedia Test Suite" ); |
| 382 | + |
| 383 | + ws.initializeDatabase(); |
| 384 | + ws.startBackgroundFetchThread(); |
| 385 | + |
| 386 | + /* |
| 387 | + * All the actual tests go here. |
| 388 | + */ |
| 389 | + |
| 390 | + (new LinkTest(ws)).run(); |
| 391 | + (new EditTest(ws)).run(); |
| 392 | + |
| 393 | + /* |
| 394 | + * Tests are all done. Clean up and report. |
| 395 | + */ |
| 396 | + |
| 397 | + ws.stopBackgroundFetchThread(); |
| 398 | + info( "Finished Wikipedia Test Suite" ); |
| 399 | + |
| 400 | + long elapsed_time = System.currentTimeMillis() - start_time; |
| 401 | + |
| 402 | + long t_hr = elapsed_time / 3600000; |
| 403 | + long t_min = (elapsed_time % 3600000) / 60000; |
| 404 | + double t_sec = (double)(elapsed_time % 60000) / 1000.0; |
| 405 | + |
| 406 | + StringBuffer sb = new StringBuffer(100); |
| 407 | + sb.append( "Total elapsed time: " ).append( t_hr ).append( " hr, " ) |
| 408 | + .append( t_min ).append( " min, " ).append( t_sec ).append( " sec." ); |
| 409 | + info( sb.toString() ); |
127 | 410 | } |
128 | 411 | |
| 412 | + |
129 | 413 | } |