Index: TestHarness4LAMS2/.classpath =================================================================== diff -u -r8e1ed196bfc1c28860729d8b0a23878bb3ecf1e7 -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/.classpath (.../.classpath) (revision 8e1ed196bfc1c28860729d8b0a23878bb3ecf1e7) +++ TestHarness4LAMS2/.classpath (.../.classpath) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -14,5 +14,5 @@ - + Index: TestHarness4LAMS2/.cvsignore =================================================================== diff -u --- TestHarness4LAMS2/.cvsignore (revision 0) +++ TestHarness4LAMS2/.cvsignore (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -0,0 +1 @@ +build Index: TestHarness4LAMS2/adminTest1.properties =================================================================== diff -u -r37d07da894922569d79ce4f517c45f8cbed4c452 -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/adminTest1.properties (.../adminTest1.properties) (revision 37d07da894922569d79ce4f517c45f8cbed4c452) +++ TestHarness4LAMS2/adminTest1.properties (.../adminTest1.properties) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -1,25 +1,5 @@ -#------------------------------------------------------ -# CallType has 3 valid values: RMI,WS and WEB -# RMI means Remote Method Invocation call; EJB remote interface call is an example. -# WS means Web Service call. -# WEB means URL call. -#------------------------------------------------------- -CallType = WEB -#CallType = WS -#CallType = RMI - -#----------------------------------------------------------------------- -# The value of RMIRegistryName is used when CallType is RMI. -#----------------------------------------------------------------------- -# RMIRegistryName = UserManagementService - -#----------------------------------------------------------------- -# This WebServiceAddress value is used when CallType is WS. #----------------------------------------------------------------- -# WebServiceAddress = /services/UserManagementService - -#----------------------------------------------------------------- -# 2 URLs to be used have to be defined if CallType is WEB +# 2 URLs to be used have to be defined # Don't change %orgId% as the part to be replaced with the real course Id #----------------------------------------------------------------- CreateCourseURL = /admin/organisation.do?method=edit&typeId=2&parentId=1&parentName=Root Index: TestHarness4LAMS2/authorTest1.properties =================================================================== diff -u -r37d07da894922569d79ce4f517c45f8cbed4c452 -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/authorTest1.properties (.../authorTest1.properties) (revision 37d07da894922569d79ce4f517c45f8cbed4c452) +++ TestHarness4LAMS2/authorTest1.properties (.../authorTest1.properties) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -1,26 +1,6 @@ -#------------------------------------------------------ -# CallType has 3 valid values: RMI,WS and WEB -# RMI means Remote Method Invocation call; EJB remote interface call is an example. -# WS means Web Service call. -# WEB means URL call. -#------------------------------------------------------- -CallType = WEB -#CallType = WS -#CallType = RMI - -#----------------------------------------------------------------------- -# The value of RMIRegistryName is used when CallType is RMI. -#----------------------------------------------------------------------- -# RMIRegistryName = AuthorService - -#----------------------------------------------------------------- -# This WebServiceAddress value is used when CallType is WS. #----------------------------------------------------------------- -# WebServiceAddress = /services/LearningDesignService - +# This LearningDesignUploadURL value #----------------------------------------------------------------- -# This LearningDesignUploadURL value is used when CallType is WEB. -#----------------------------------------------------------------- LearningDesignUploadURL = /authoring/importToolContent.do?method=import #----------------------------------------------------------------- @@ -34,7 +14,7 @@ # All the settings above will be ignored # This property is used to test against an existing learning design #----------------------------------------------------------------- -# LearningDesignId = 1 +# LearningDesignId = 14 #------------------------------------------------------------------ # Set the base name of the author Index: TestHarness4LAMS2/build.xml =================================================================== diff -u -r8e1ed196bfc1c28860729d8b0a23878bb3ecf1e7 -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/build.xml (.../build.xml) (revision 8e1ed196bfc1c28860729d8b0a23878bb3ecf1e7) +++ TestHarness4LAMS2/build.xml (.../build.xml) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -1,6 +1,7 @@ - + + Index: TestHarness4LAMS2/learnerTest1.properties =================================================================== diff -u -redb66df9b559061de9a252ff2ae6fab47bde754f -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/learnerTest1.properties (.../learnerTest1.properties) (revision edb66df9b559061de9a252ff2ae6fab47bde754f) +++ TestHarness4LAMS2/learnerTest1.properties (.../learnerTest1.properties) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -1,25 +1,5 @@ -#------------------------------------------------------ -# CallType has 3 valid values: RMI,WS and WEB -# RMI means Remote Method Invocation call; EJB remote interface call is an example. -# WS means Web Service call. -# WEB means URL call. -#------------------------------------------------------- -CallType = WEB -#CallType = WS -#CallType = RMI - -#----------------------------------------------------------------------- -# The value of RMIRegistryName is used when CallType is RMI. -#----------------------------------------------------------------------- -# RMIRegistryName = LearnerService - -#----------------------------------------------------------------- -# This WebServiceAddress value is used when CallType is WS. -#----------------------------------------------------------------- -# WebServiceAddress = /services/LearnerService - #------------------------------------------------------------------- -# A bunch of URLs to be used have to be defined if CallType is WEB +# A bunch of URLs to be used have to be defined #------------------------------------------------------------------- GetLessonURL = /learning/learner.do?method=getLesson&lessonID=%lsId% GetLearningDesignURL = /authoring/author.do?method=getLearningDesignDetails&learningDesignID=%ldId% Index: TestHarness4LAMS2/monitorTest1.properties =================================================================== diff -u -r86f8f142891162680c6f7ed66a8c4edf574df991 -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/monitorTest1.properties (.../monitorTest1.properties) (revision 86f8f142891162680c6f7ed66a8c4edf574df991) +++ TestHarness4LAMS2/monitorTest1.properties (.../monitorTest1.properties) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -1,30 +1,10 @@ -#------------------------------------------------------ -# CallType has 3 valid values: RMI,WS and WEB -# RMI means Remote Method Invocation call; EJB remote interface call is an example. -# WS means Web Service call. -# WEB means URL call. -#------------------------------------------------------- -CallType = WEB -# CallType = WS -# CallType = RMI - #----------------------------------------------------------------------- -# The value of RMIRegistryName is used CallType is RMI. -#----------------------------------------------------------------------- -# RMIRegistryName = StaffService - -#----------------------------------------------------------------- -# This WebServiceAddress value is used when CallType is WS. -#----------------------------------------------------------------- -# WebServiceAddress = /services/LearningSessionService - -#----------------------------------------------------------------------- # If not specified, "Lesson" will be used #----------------------------------------------------------------------- # LessonName = BenchmarkLesson #----------------------------------------------------------------- -# A few URLs have to be defined when CallType is WEB. +# A few URLs have to be defined #----------------------------------------------------------------- InitLessonURL = /monitoring/monitoring.do?method=initializeLesson&learningDesignID=%ldId%&organisationID=%orgId%&userID=%uid%&lessonName=%name% CreateLessonClassURL = /monitoring/monitoring.do?method=createLessonClass&userID=%uid% Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/AbstractTest.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/AbstractTest.java (.../AbstractTest.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/AbstractTest.java (.../AbstractTest.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -23,122 +23,72 @@ package org.lamsfoundation.testharness; import org.apache.log4j.Logger; -import org.lamsfoundation.testharness.Call.CallType; - /** - * @version - * - *

- * View Source - *

- * - * @author Fei Yang + * @author Fei Yang, Marcin Cieslak */ -public abstract class AbstractTest -{ +public abstract class AbstractTest { + private static final Logger log = Logger.getLogger(AbstractTest.class); - private static final Logger log = Logger.getLogger(AbstractTest.class); - - protected TestSuite testSuite; protected final String testName; - protected final CallType callType; - protected String rmiRegistryName; - protected String webServiceAddress; protected final Integer minDelay; protected final Integer maxDelay; + + protected TestSuite testSuite; protected MockUser[] users; protected boolean finished = false; - protected AbstractTest(String name, CallType type, String rmiRegistryName, String address, Integer minDelay, Integer maxDelay) { - this.testName = name; - this.callType = type; - this.rmiRegistryName = rmiRegistryName; - this.webServiceAddress = address; - this.minDelay = minDelay==null? 0 : minDelay; - this.maxDelay = maxDelay==null? 0 : maxDelay; + protected AbstractTest(String name, Integer minDelay, Integer maxDelay) { + this.testName = name; + this.minDelay = minDelay == null ? 0 : minDelay; + this.maxDelay = maxDelay == null ? 0 : maxDelay; } - public final void start(){ - try{ - log.info("Starting "+testName+"..."); - switch (callType) { - case WEB: - startWEB(); - break; - case WS: - startWS(); - break; - case RMI: - startRMI(); - break; - default: - break; - } - finished = true; - log.info(testName+" is finished"); - }catch(RuntimeException e){ - log.info(testName+" aborted"); - //Since latter tests depend on precedent tests in a test suite, - //propagate the exception to let the test suite stop executing the latter tests - throw e; - } + public final Integer getMaxDelay() { + return maxDelay; } - protected abstract void startWEB(); + public final Integer getMinDelay() { + return minDelay; + } - protected abstract void startWS(); + public final String getTestName() { + return testName; + } - protected abstract void startRMI(); - - /** - * @return Returns the testSuite. - */ public final TestSuite getTestSuite() { - return testSuite; + return testSuite; } - /** - * @param testSuite The testSuite to set. - */ - public final void setTestSuite(TestSuite testSuite) { - this.testSuite = testSuite; + public final MockUser[] getUsers() { + return users; } - public final MockUser[] getUsers() { - return users; - } + public final boolean isFinished() { + return finished; + } - public final void setUsers(MockUser[] users) { - this.users = users; - } + public final void setTestSuite(TestSuite testSuite) { + this.testSuite = testSuite; + } - public final CallType getCallType() { - return callType; - } + public final void setUsers(MockUser[] users) { + this.users = users; + } - public final String getRmiRegistryName() { - return rmiRegistryName; + protected final void start() { + try { + AbstractTest.log.info("Starting " + testName); + startTest(); + finished = true; + AbstractTest.log.info(testName + " is finished"); + } catch (RuntimeException e) { + AbstractTest.log.info(testName + " aborted"); + // Since latter tests depend on precedent tests in a test suite, + // propagate the exception to let the test suite stop executing the latter tests + throw e; } + } - public final String getTestName() { - return testName; - } - - public final String getWebServiceAddress() { - return webServiceAddress; - } - - public final Integer getMaxDelay() { - return maxDelay; - } - - public final Integer getMinDelay() { - return minDelay; - } - - public final boolean isFinished() { - return finished; - } - -} + protected abstract void startTest(); +} \ No newline at end of file Fisheye: Tag 41955af92f3e17f2f11c07d94ae1a5f92b0d998f refers to a dead (removed) revision in file `TestHarness4LAMS2/src/org/lamsfoundation/testharness/AbstractTestManager.java'. Fisheye: No comparison available. Pass `N' to diff? Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/Call.java =================================================================== diff -u -r8e1ed196bfc1c28860729d8b0a23878bb3ecf1e7 -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/Call.java (.../Call.java) (revision 8e1ed196bfc1c28860729d8b0a23878bb3ecf1e7) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/Call.java (.../Call.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -22,14 +22,11 @@ */ package org.lamsfoundation.testharness; -import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.Map; import org.apache.log4j.Logger; -import org.xml.sax.SAXException; import com.meterware.httpunit.GetMethodWebRequest; import com.meterware.httpunit.PostMethodWebRequest; @@ -40,64 +37,85 @@ import com.meterware.httpunit.WebResponse; /** - * @version - * - *

- * View Source - *

- * - * @author Fei Yang + * @author Fei Yang, Marcin Cieslak */ public class Call { - private static final Logger log = Logger.getLogger(Call.class); + static class CallRecord { + private int suiteIndex; + private String testName; + private String callee; + private String description; + private String snapShotTime; + private long timeInMillis; + private Integer httpStatusCode; + private String message; - private static final String HTTP = "http://"; + public CallRecord() { + } - private static final String GET = "GET "; + public CallRecord(int suiteIndex, String testName, String callee, String description, String snapShotTime, + long timeInMillis, Integer httpStatusCode, String message) { + this.suiteIndex = suiteIndex; + this.testName = testName; + this.callee = callee; + this.description = description; + this.snapShotTime = snapShotTime; + this.timeInMillis = timeInMillis; + this.httpStatusCode = httpStatusCode; + this.message = message; + } - private static final String POST = "POST "; + public String getCallee() { + return callee; + } - private static final char COLON = ':'; + public String getDescription() { + return description; + } - private static final char SPACE = ' '; + public final Integer getHttpStatusCode() { + return httpStatusCode; + } - private static final String NON_HTTP_ERROR = "Check the log for the error message"; + public String getMessage() { + return message; + } - private WebConversation wc; // for WEB + public String getSnapShotTime() { + return snapShotTime; + } - private AbstractTest test; + public int getSuiteIndex() { + return suiteIndex; + } - private String description; + public String getTestName() { + return testName; + } - @SuppressWarnings("unused") - private String method; // for RMI and WS + public long getTimeInMillis() { + return timeInMillis; + } + } - @SuppressWarnings("unused") - private Map parameters; // for RMI or WS + private static final Logger log = Logger.getLogger(Call.class); + private WebConversation wc; + private AbstractTest test; + private String description; + private String url; + private WebForm form; + private InputStream is; - private String url; // for WEB - - private WebForm form; // for WEB - - private InputStream is; // for WEB POST method - private String contentType; // for WEB POST method - public Call(WebConversation wc, AbstractTest test, String description, WebForm form) { + public Call(WebConversation wc, AbstractTest test, String description, String url) { this.wc = wc; this.test = test; this.description = description; - this.form = form; + this.url = url; } - public Call(AbstractTest test, String description, String method, Map parameters) { - this.test = test; - this.description = description; - this.method = method; - this.parameters = parameters; - } - public Call(WebConversation wc, AbstractTest test, String description, String url, InputStream is, String contentType) { this.wc = wc; @@ -108,34 +126,20 @@ this.contentType = contentType; } - public Call(WebConversation wc, AbstractTest test, String description, String url) { + public Call(WebConversation wc, AbstractTest test, String description, WebForm form) { this.wc = wc; this.test = test; this.description = description; - this.url = url; + this.form = form; } - public AbstractTest getTest() { - return test; + private static boolean isCancelButton(SubmitButton button) { + return button.getName().contains("CANCEL") || button.getName().contains("Cancel") + || button.getName().contains("cancel") || button.getValue().contains("cancel") + || button.getValue().contains("Cancel") || button.getValue().contains("CANCEL"); } - /** - * need add CallRecord to TestReporter - */ public Object execute() { - switch (test.callType) { - case RMI: - return executeRMI(); - case WS: - return executeWS(); - case WEB: - return executeHttpRequest(); - default: - return null; - } - } - - private Object executeHttpRequest() { String message = null; String callee = null; Integer httpStatusCode = null; @@ -145,14 +149,14 @@ WebResponse resp = null; if (form != null) { SubmitButton[] submitButtons = filterCancelButton(form.getSubmitButtons()); - Call.log.debug(submitButtons.length + " non-cancel submit button(s) in the form"); + Call.log.debug(submitButtons.length + " non-cancel submit buttons in the form"); WebRequest req = null; if (submitButtons.length <= 1) { req = form.getRequest(); } else { - req = form.getRequest(submitButtons[TestUtil.generateRandomIndex(submitButtons.length)]); + req = form.getRequest(submitButtons[TestUtil.generateRandomNumber(submitButtons.length)]); } - callee = form.getMethod().toUpperCase() + Call.SPACE + form.getAction(); + callee = form.getMethod().toUpperCase() + " " + form.getAction(); Call.log.debug(callee); start = System.currentTimeMillis(); resp = wc.getResponse(req); @@ -161,10 +165,10 @@ String absoluteURL = getAbsoluteURL(url); WebRequest req; if (is == null) { - callee = Call.GET + url; + callee = "GET " + url; req = new GetMethodWebRequest(absoluteURL); } else { - callee = Call.POST + url; + callee = "POST " + url; req = new PostMethodWebRequest(absoluteURL, is, contentType); } Call.log.debug(callee); @@ -180,15 +184,15 @@ if (resp.getResponseCode() >= 400) { Call.log.debug(resp.getText()); - throw new TestHarnessException(test.testName + " Got http error code " + httpStatusCode); + throw new TestHarnessException(test.testName + " got http error code " + httpStatusCode); } for (String headerFieldName : resp.getHeaderFieldNames()) { if (headerFieldName.equalsIgnoreCase("SET-COOKIE")) { for (String headerFieldValue : resp.getHeaderFields(headerFieldName)) { String[] headerFieldSplit = headerFieldValue.split("=|;"); String cookieName = headerFieldSplit[0]; - if ("JSESSIONID".equalsIgnoreCase(cookieName) && wc.getCookieValue(cookieName) == null) { + if ("JSESSIONID".equalsIgnoreCase(cookieName) && (wc.getCookieValue(cookieName) == null)) { String cookieValue = headerFieldSplit[1]; Call.log.debug("Manually setting cookie: " + cookieName + "=" + cookieValue); wc.putCookie(cookieName, cookieValue); @@ -198,26 +202,20 @@ } return resp; - } catch (IOException e) { - message = Call.NON_HTTP_ERROR; - Call.log.debug(e.getMessage(), e); + } catch (Exception e) { throw new RuntimeException(e); - } catch (SAXException e) { - message = Call.NON_HTTP_ERROR; - Call.log.debug(e.getMessage(), e); - throw new RuntimeException(e); } finally { - TestReporter.addCallRecord(new CallRecord(test.getTestSuite().getSuiteIndex(), test.testName, test.callType - .getName(), callee, description, new SimpleDateFormat("HH:mm:ss SSS").format(new Date(end)), end - - start, httpStatusCode, message)); + TestReporter.addCallRecord(new CallRecord(test.getTestSuite().getSuiteIndex(), test.testName, callee, + description, new SimpleDateFormat("HH:mm:ss SSS").format(new Date(end)), end - start, + httpStatusCode, message)); } } private SubmitButton[] filterCancelButton(SubmitButton[] sbmtBtns) { boolean found = false; int i = 0; for (; i < sbmtBtns.length; i++) { - if (isCancelButton(sbmtBtns[i])) { + if (Call.isCancelButton(sbmtBtns[i])) { found = true; break; } @@ -237,142 +235,19 @@ } } - private boolean isCancelButton(SubmitButton button) { - return button.getName().contains("CANCEL") || button.getName().contains("Cancel") - || button.getName().contains("cancel") || button.getValue().contains("cancel") - || button.getValue().contains("Cancel") || button.getValue().contains("CANCEL"); - } - - /** - * TODO implement me - * - * @param - * @return - */ - private Object executeWS() { - return null; - } - - /** - * TODO implement me - * - * @param - * @return - */ - private Object executeRMI() { - return null; - } - private String getAbsoluteURL(String url) { - if (url.startsWith(Call.HTTP)) { + if (url.startsWith("http://")) { return url; } String withSlash = url.startsWith("/") ? url : "/" + url; String context = url.startsWith(test.getTestSuite().getContextRoot()) ? "" : test.getTestSuite() .getContextRoot(); if (test.getTestSuite().getHttpPort() != 80) { - return Call.HTTP + test.getTestSuite().getTargetServer() + Call.COLON + test.getTestSuite().getHttpPort() + return "http://" + test.getTestSuite().getTargetServer() + ":" + test.getTestSuite().getHttpPort() + context + withSlash; } else { - return Call.HTTP + test.getTestSuite().getTargetServer() + context + withSlash; + return "http://" + test.getTestSuite().getTargetServer() + context + withSlash; } } - - protected static class CallRecord { - - private int suiteIndex; - private String testName; - private String type; - private String callee; - private String description; - private String snapShotTime; - private long timeInMillis; - private Integer httpStatusCode;// for Web Call only - private String message; - - public CallRecord() { - // empty constructor - } - - public CallRecord(int suiteIndex, String testName, String type, String callee, String description, - String snapShotTime, long timeInMillis, Integer httpStatusCode, String message) { - this.suiteIndex = suiteIndex; - this.testName = testName; - this.type = type; - this.callee = callee; - this.description = description; - this.snapShotTime = snapShotTime; - this.timeInMillis = timeInMillis; - this.httpStatusCode = httpStatusCode; - this.message = message; - } - - public String getMessage() { - return message; - } - - public String getSnapShotTime() { - return snapShotTime; - } - - public long getTimeInMillis() { - return timeInMillis; - } - - public String getCallee() { - return callee; - } - - public String getType() { - return type; - } - - public String getTestName() { - return testName; - } - - public int getSuiteIndex() { - return suiteIndex; - } - - public String getDescription() { - return description; - } - - public final Integer getHttpStatusCode() { - return httpStatusCode; - } - } - - public enum CallType { - - RMI, WS, WEB, UNKNOWN; - - public static CallType get(String value) { - if (value.equals("RMI")) { - return CallType.RMI; - } else if (value.equals("WS")) { - return CallType.WS; - } else if (value.equals("WEB")) { - return CallType.WEB; - } else { - return CallType.UNKNOWN; - } - } - - public String getName() { - switch (this) { - case RMI: - return "RMI"; - case WS: - return "WS"; - case WEB: - return "WEB"; - default: - return "Unknown"; - } - } - } - -} +} \ No newline at end of file Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/Main.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/Main.java (.../Main.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/Main.java (.../Main.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -29,47 +29,40 @@ import com.meterware.httpunit.HttpUnitOptions; /** - * @version - * - *

- * View Source - *

- * - * @author Fei Yang - * + * @author Fei Yang, Marcin Cieslak + * */ public class Main { - static { - // configure log4j - PropertyConfigurator.configure("log.properties"); - // configure HttpUnit - // stops the unsupported javascript stuff from throwing an exception - HttpUnitOptions.setExceptionsThrownOnScriptError(false); - //WebClient.getResponse does not throw an exception when it receives an error status. - HttpUnitOptions.setExceptionsThrownOnErrorStatus(false); - } + private static final Logger log = Logger.getLogger(Main.class); + + static { + // configure log4j + PropertyConfigurator.configure("log.properties"); + // configure HttpUnit + // stops the unsupported javascript stuff from throwing an exception + HttpUnitOptions.setExceptionsThrownOnScriptError(false); + // WebClient.getResponse does not throw an exception when it receives an error status. + HttpUnitOptions.setExceptionsThrownOnErrorStatus(false); + } - private static final Logger log = Logger.getLogger(Main.class); - - /** - * @param args - */ - public static void main(String[] args) { - log.info("Starting..."); - if (args.length == 0) { - log.error("No argument supplied! Please refer to readme.txt"); - System.exit(1); - } - // create test manager and hand over the control to him. - AbstractTestManager manager = new PropertyFileTestManager(args[0]); - try{ - manager.kickOff(); - TestReporter.generateReport(manager); - log.info("It's done, anyway"); - }catch(Exception e){ - log.error(e.getMessage(),e); - System.exit(1); - } + public static void main(String[] args) { + Main.log.info("Starting..."); + if (args.length == 0) { + Main.log.error("No argument supplied! Please refer to readme.txt"); + System.exit(1); } -} + + // create test manager and hand over the control to him. + TestManager manager = new TestManager(args[0]); + try { + manager.start(); + TestReporter.generateReportLog(manager); + TestReporter.generateReportFile(manager); + Main.log.info("Test suite finished"); + } catch (Exception e) { + Main.log.error("Error in tests", e); + System.exit(1); + } + } +} \ No newline at end of file Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/MockUser.java =================================================================== diff -u -r7f004df92bf884af26247547f7a05978a6504041 -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/MockUser.java (.../MockUser.java) (revision 7f004df92bf884af26247547f7a05978a6504041) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/MockUser.java (.../MockUser.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -39,13 +39,7 @@ import com.meterware.httpunit.protocol.UploadFileSpec; /** - * @version - * - *

- * View Source - *

- * - * @author Fei Yang + * @author Fei Yang, Marcin Cieslak */ public class MockUser { @@ -75,29 +69,51 @@ this.userId = userId; } - public static final void setIndexPage(String indexPageURL) { + public static void setIndexPage(String indexPageURL) { MockUser.indexPage = indexPageURL; } + private static String sha1(String plaintext) throws NoSuchAlgorithmException { + MessageDigest md = MessageDigest.getInstance("SHA1"); + return new String(Hex.encodeHex(md.digest(plaintext.getBytes()))); + } + + protected static boolean checkPageContains(WebResponse resp, String flag) throws IOException { + return resp.getText().indexOf(flag) != -1; + } + + public final String getPassword() { + return password; + } + + public final String getUserId() { + return userId; + } + + public final String getUsername() { + return username; + } + /** * Login to the system. * - * @exception TestHarnessException:failure + * @exception TestHarnessException + * :failure */ - public final void login() { + public void login() { try { wc = new WebConversation(); WebResponse resp = (WebResponse) new Call(wc, test, username + " fetch index page", MockUser.indexPage) .execute(); - if (!checkPageContains(resp, MockUser.LOGIN_PAGE_FLAG)) { + if (!MockUser.checkPageContains(resp, MockUser.LOGIN_PAGE_FLAG)) { MockUser.log.debug(resp.getText()); - throw new TestHarnessException(username + " didn't get login page when hitting LAMS the first time!"); + throw new TestHarnessException(username + " didn't get login page when hitting LAMS the first time"); } Map params = new HashMap(); params.put(MockUser.USERNAME, username); - params.put(MockUser.PASSWORD, HashUtil.sha1(password)); + params.put(MockUser.PASSWORD, MockUser.sha1(password)); resp = (WebResponse) new Call(wc, test, "User login", fillForm(resp, 0, params)).execute(); - if (!checkPageContains(resp, MockUser.INDEX_PAGE_FLAG)) { + if (!MockUser.checkPageContains(resp, MockUser.INDEX_PAGE_FLAG)) { MockUser.log.debug(resp.getText()); throw new TestHarnessException(username + " failed to login with password " + password); } @@ -110,13 +126,37 @@ } } - protected final WebForm fillForm(WebResponse resp, int formIndex, Map params) throws SAXException, + public final void setUserId(String userId) { + this.userId = userId; + } + + protected void delay() { + try { + int seconds = 0; + if (test.getMaxDelay() <= test.getMinDelay()) {// to avoid IllegalArgumentException in nextInt method on + // Random object + seconds = test.getMinDelay(); + } else { + seconds = test.getMinDelay() + + TestUtil.generateRandomNumber((test.getMaxDelay() - test.getMinDelay()) + 1); + } + if (seconds > 0) { + MockUser.log.info(username + + MockUser.DELAY_MESSAGES[TestUtil.generateRandomNumber(MockUser.DELAY_MESSAGES.length)] + + seconds + " seconds"); + Thread.sleep(seconds * 1000); + } + } catch (InterruptedException e) { + MockUser.log.error("Interrupted exception"); + } + } + + protected WebForm fillForm(WebResponse resp, int formIndex, Map params) throws SAXException, IOException { WebForm[] forms = resp.getForms(); - if (forms == null || forms.length <= formIndex) { + if ((forms == null) || (forms.length <= formIndex)) { MockUser.log.debug(resp.getText()); - throw new TestHarnessException(username + " cannot find the form whose index is " + formIndex - + " in the page"); + throw new TestHarnessException(username + " cannot find a form with index " + formIndex); } WebForm form = forms[formIndex]; if (params != null) { @@ -138,63 +178,4 @@ } return form; } - - protected final boolean checkPageContains(WebResponse resp, String flag) throws IOException { - return resp.getText().indexOf(flag) != -1; - } - - protected final void delay() { - try { - int seconds; - if (test.getMaxDelay() <= test.getMinDelay()) {// to avoid IllegalArgumentException in nextInt method on - // Random object - seconds = test.getMinDelay(); - } else { - seconds = test.getMinDelay() - + TestUtil.generateRandomIndex(test.getMaxDelay() - test.getMinDelay() + 1); - } - if (seconds > 0) { - MockUser.log.info(composeDelayInfo(seconds)); - Thread.sleep(seconds * 1000); - } - } catch (InterruptedException e) { - // ignore - } - } - - private String composeDelayInfo(int seconds) { - return username + MockUser.DELAY_MESSAGES[TestUtil.generateRandomIndex(MockUser.DELAY_MESSAGES.length)] - + seconds + (seconds == 1 ? " second" : " seconds"); - } - - private static class HashUtil { - - static String sha1(String plaintext) throws NoSuchAlgorithmException { - MessageDigest md = MessageDigest.getInstance("SHA1"); - return new String(Hex.encodeHex(md.digest(plaintext.getBytes()))); - } - - static String md5(String plaintext) throws NoSuchAlgorithmException { - MessageDigest md = MessageDigest.getInstance("MD5"); - return new String(Hex.encodeHex(md.digest(plaintext.getBytes()))); - } - - } - - public final String getPassword() { - return password; - } - - public final String getUsername() { - return username; - } - - public final String getUserId() { - return userId; - } - - public final void setUserId(String userId) { - this.userId = userId; - } - -} +} \ No newline at end of file Fisheye: Tag 41955af92f3e17f2f11c07d94ae1a5f92b0d998f refers to a dead (removed) revision in file `TestHarness4LAMS2/src/org/lamsfoundation/testharness/PropertyFileTestManager.java'. Fisheye: No comparison available. Pass `N' to diff? Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestHarnessException.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestHarnessException.java (.../TestHarnessException.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestHarnessException.java (.../TestHarnessException.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -23,48 +23,42 @@ package org.lamsfoundation.testharness; /** - * @version - * - *

- * View Source - *

- * - * @author Fei Yang + * @author Fei Yang */ public class TestHarnessException extends RuntimeException { - private static final long serialVersionUID = 6481839981681761094L; + /** + * Constructor for TestHarnessException. + */ + public TestHarnessException() { + super(); + } - /** - * Constructor for TestHarnessException. - */ - public TestHarnessException() { - super(); - } + /** + * Constructor for TestHarnessException. + * + * @param message + */ + public TestHarnessException(String message) { + super(message); + } - /** - * Constructor for TestHarnessException. - * @param message - */ - public TestHarnessException(String message) { - super(message); - } + /** + * Constructor for TestHarnessException. + * + * @param message + * @param cause + */ + public TestHarnessException(String message, Throwable cause) { + super(message, cause); + } - /** - * Constructor for TestHarnessException. - * @param message - * @param cause - */ - public TestHarnessException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructor for TestHarnessException. - * @param cause - */ - public TestHarnessException(Throwable cause) { - super(cause); - } - -} + /** + * Constructor for TestHarnessException. + * + * @param cause + */ + public TestHarnessException(Throwable cause) { + super(cause); + } +} \ No newline at end of file Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestManager.java =================================================================== diff -u --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestManager.java (revision 0) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestManager.java (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -0,0 +1,424 @@ +/**************************************************************** + * Copyright (C) 2006 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ +package org.lamsfoundation.testharness; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.CountDownLatch; + +import org.apache.log4j.Logger; +import org.lamsfoundation.testharness.admin.AdminTest; +import org.lamsfoundation.testharness.admin.MockAdmin; +import org.lamsfoundation.testharness.author.AuthorTest; +import org.lamsfoundation.testharness.author.MockAuthor; +import org.lamsfoundation.testharness.learner.LearnerTest; +import org.lamsfoundation.testharness.learner.MockLearner; +import org.lamsfoundation.testharness.monitor.MockMonitor; +import org.lamsfoundation.testharness.monitor.MonitorTest; + +/** + * @author Fei Yang, Marcin Cieslak + */ +class TestManager { + private static final Logger log = Logger.getLogger(TestManager.class); + + List testSuites = new LinkedList(); + CountDownLatch allDoneSignal; + private String testPropertyFileName; + + private static final int MAX_USERNAME_LENGTH = 20; + // property keys of the master property file + private static final String REPORT_FILE_NAME = "ReportFileName"; + private static final String REPORT_FILE_TEMPLATE = "ReportFileTemplate"; + private static final String INDEX_PAGE_URL = "IndexPageURL"; + private static final String NUMBER_OF_TEST_SUITES = "NumberOfTestSuites"; + private static final String TARGET_SERVER = "TargetServer"; + private static final String CONTEXT_ROOT = "ContextRoot"; + private static final String HTTP_PORT = "HttpPort"; + private static final String ADMIN_PROPERTY_FILE = "AdminTestPropertyFile"; + private static final String AUTHOR_PROPERTY_FILE = "AuthorTestPropertyFile"; + private static final String MONITOR_PROPERTY_FILE = "MonitorTestPropertyFile"; + private static final String LEARNER_PROPERTY_FILE = "LearnerTestPropertyFile"; + + // common property keys of all the single tests(admin test, author test, monitor test, learner test) + private static final String MIN_DELAY = "MinDelay"; + private static final String MAX_DELAY = "MaxDelay"; + + // property keys of admin test + private static final String CREATE_COURSE_URL = "CreateCourseURL"; + private static final String CREATE_USER_URL = "CreateUserURL"; + private static final String COURSE_NAME = "CourseName"; + private static final String COURSE_ID = "CourseId"; + private static final String USER_CREATED = "UserCreated"; + private static final String SYSADMIN_USERNAME = "SysadminUsername"; + private static final String SYSADMIN_PASSWORD = "SysadminPassword"; + + // property keys of author test + private static final String LEARNING_DESIGN_UPLOAD_URL = "LearningDesignUploadURL"; + private static final String LEARNING_DESIGN_FILE = "LearningDesignFile"; + private static final String LEARNING_DESIGN_ID = "LearningDesignId"; + private static final String BASE_AUTHOR_NAME = "BaseAuthorName"; + + // property keys of monitor test + private static final String INIT_LESSON_URL = "InitLessonURL"; + private static final String CREATE_LESSON_CLASS_URL = "CreateLessonClassURL"; + private static final String START_LESSON_URL = "StartLessonURL"; + private static final String LESSON_ID = "LessonId"; + private static final String LESSON_NAME = "LessonName"; + private static final String USER_ID = "UserId"; + private static final String BASE_MONITOR_NAME = "BaseMonitorName"; + private static final String GET_LESSON_DETAILS_URL = "GetLessonDetailsURL"; + private static final String GET_CA_URL = "GetContributeActivitiesURL"; + private static final String GET_LD_DETAILS_URL = "GetLearningDesignDetailsURL"; + private static final String GET_ALL_PROGRESS_URL = "GetAllLearnersProgressURL"; + + // property keys of learner test + private static final String NUMBER_LEARNERS = "NumberOfLearners"; + private static final String LEARNER_OFFSET = "LearnerOffset"; + private static final String BASE_LEARNER_NAME = "BaseLearnerName"; + private static final String GET_LESSON_URL = "GetLessonURL"; + private static final String GET_LD_URL = "GetLearningDesignURL"; + private static final String JOIN_LESSON_URL = "JoinLessonURL"; + private static final String GET_PROGRESS_URL = "GetFlashProgressDataURL"; + private static final String LESSON_ENTRY_URL = "LessonEntryURL"; + private static final String FILES_TO_UPLOAD = "FilesToUpload"; + private static final String USER_ID_OFFSET = "UserIdOffset"; + + public TestManager(String name) { + this.testPropertyFileName = name; + } + + private static String buildPropertyKey(String basePropertyKey, int suiteIndex) { + return basePropertyKey + "." + suiteIndex; + } + + private static String extractTestName(String propertyFileName) { + return propertyFileName.substring(0, propertyFileName.indexOf(".properties")); + } + + private static Integer getIntegerProperty(String propertyFileName, Properties properties, String key, + boolean nullable) { + String value = TestManager.getStringProperty(propertyFileName, properties, key, nullable); + try { + if (value == null) { + return null; + } else { + Integer number = new Integer(value); + if (number <= 0) { + throw new TestHarnessException(key + " is not specified as a positive number in file: " + + propertyFileName); + } + return number; + } + } catch (NumberFormatException e) { + throw new TestHarnessException(key + " is not specified as a number in file: " + propertyFileName, e); + } + } + + private static String getStringProperty(String properyFileName, Properties properties, String key, boolean optional) { + String value = properties.getProperty(key); + if (value != null) { + value = value.trim(); + } + if (!optional) { + if ((value == null) || (value.length() == 0)) { + throw new TestHarnessException(key + " is not specified in file: " + properyFileName); + } + } + return (value != null) && (value.length() == 0) ? null : value; + } + + private static Properties loadProperties(String propertyFileName) { + InputStream propFile = null; + try { + propFile = new FileInputStream(propertyFileName); + Properties props = new Properties(); + props.load(propFile); + return props; + } catch (FileNotFoundException e) { + throw new TestHarnessException("File \"" + propertyFileName + "\" was not found", e); + } catch (IOException e) { + throw new TestHarnessException("IO error occured during loading file " + propertyFileName, e); + } finally { + if (propFile != null) { + try { + propFile.close(); + } catch (IOException e) { + throw new TestHarnessException("Error while closing properties file handler", e); + } + } + } + } + + int countAborted() { + int amount = 0; + for (TestSuite suite : testSuites) { + if (!suite.isFinished()) { + amount++; + } + } + return amount; + } + + void start() { + init(); + + if (!TestReporter.initialized()) { + throw new TestHarnessException("TestReport class is not initialized"); + } + TestManager.log.info("Running " + testSuites.size() + " test suites"); + + if (testSuites.size() > 0) { + allDoneSignal = new CountDownLatch(testSuites.size()); + for (TestSuite testSuite : testSuites) { + new Thread(testSuite, "TestSuite-" + testSuite.getSuiteIndex()).start(); + } + try { + allDoneSignal.await(); + } catch (InterruptedException e) { + TestManager.log.error(e); + } + } + + int abortedCount = countAborted(); + int finishedCount = testSuites.size() - abortedCount; + TestManager.log.info(finishedCount + " test suites finished and " + abortedCount + " aborted"); + } + + private AdminTest createAdminTest(String adminTestPropertyFileName) { + String testName = TestManager.extractTestName(adminTestPropertyFileName); + TestManager.log.info("Creating admin test " + testName); + + Properties adminTestProperties = TestManager.loadProperties(adminTestPropertyFileName); + Integer courseId = TestManager.getIntegerProperty(adminTestPropertyFileName, adminTestProperties, + TestManager.COURSE_ID, true); + Boolean userCreated = new Boolean(TestManager.getStringProperty(adminTestPropertyFileName, adminTestProperties, + TestManager.USER_CREATED, true)); + Integer minDelay = TestManager.getIntegerProperty(adminTestPropertyFileName, adminTestProperties, + TestManager.MIN_DELAY, true); + Integer maxDelay = TestManager.getIntegerProperty(adminTestPropertyFileName, adminTestProperties, + TestManager.MAX_DELAY, true); + String createCourseURL = TestManager.getStringProperty(adminTestPropertyFileName, adminTestProperties, + TestManager.CREATE_COURSE_URL, courseId != null); + String createUserURL = TestManager.getStringProperty(adminTestPropertyFileName, adminTestProperties, + TestManager.CREATE_USER_URL, userCreated); + String courseName = TestManager.getStringProperty(adminTestPropertyFileName, adminTestProperties, + TestManager.COURSE_NAME, true); + String sysadminUsername = TestManager.getStringProperty(adminTestPropertyFileName, adminTestProperties, + TestManager.SYSADMIN_USERNAME, false); + String sysadminPassword = TestManager.getStringProperty(adminTestPropertyFileName, adminTestProperties, + TestManager.SYSADMIN_PASSWORD, false); + + AdminTest test = new AdminTest(testName, minDelay, maxDelay, createCourseURL, createUserURL, + courseId == null ? null : courseId.toString(), userCreated, courseName); + + test.setUsers(new MockAdmin[] { new MockAdmin(test, sysadminUsername, sysadminPassword, null) }); + + TestManager.log.info("Finished creating admin test " + testName); + return test; + } + + private AuthorTest createAuthorTest(String authorTestPropertyFileName) { + String testName = TestManager.extractTestName(authorTestPropertyFileName); + TestManager.log.info("Creating author test " + testName); + + Properties authorTestProperties = TestManager.loadProperties(authorTestPropertyFileName); + Integer ldId = TestManager.getIntegerProperty(authorTestPropertyFileName, authorTestProperties, + TestManager.LEARNING_DESIGN_ID, true); + Integer minDelay = TestManager.getIntegerProperty(authorTestPropertyFileName, authorTestProperties, + TestManager.MIN_DELAY, true); + Integer maxDelay = TestManager.getIntegerProperty(authorTestPropertyFileName, authorTestProperties, + TestManager.MAX_DELAY, true); + String learningDesignUploadURL = TestManager.getStringProperty(authorTestPropertyFileName, + authorTestProperties, TestManager.LEARNING_DESIGN_UPLOAD_URL, ldId != null); + String learningDesignFile = TestManager.getStringProperty(authorTestPropertyFileName, authorTestProperties, + TestManager.LEARNING_DESIGN_FILE, ldId != null); + String baseAuthorName = TestManager.getStringProperty(authorTestPropertyFileName, authorTestProperties, + TestManager.BASE_AUTHOR_NAME, true); + + AuthorTest test = new AuthorTest(testName, minDelay, maxDelay, learningDesignUploadURL, learningDesignFile, + ldId == null ? null : ldId.toString()); + + baseAuthorName = baseAuthorName == null ? MockAuthor.DEFAULT_NAME : baseAuthorName; + String username = TestUtil.buildName(testName, baseAuthorName, TestManager.MAX_USERNAME_LENGTH); + test.setUsers(new MockAuthor[] { new MockAuthor(test, username, username, null) }); + + TestManager.log.info("Finished creating author test " + testName); + return test; + } + + private LearnerTest createLearnerTest(String learnerTestPropertyFileName) { + String testName = TestManager.extractTestName(learnerTestPropertyFileName); + TestManager.log.info("Creating learner test:" + testName); + + Properties learnerTestProperties = TestManager.loadProperties(learnerTestPropertyFileName); + Integer minDelay = TestManager.getIntegerProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.MIN_DELAY, true); + Integer maxDelay = TestManager.getIntegerProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.MAX_DELAY, true); + Integer numberOfLearners = TestManager.getIntegerProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.NUMBER_LEARNERS, true); + numberOfLearners = numberOfLearners == null ? 1 : numberOfLearners; + Integer learnerOffset = TestManager.getIntegerProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.LEARNER_OFFSET, true); + learnerOffset = learnerOffset == null ? 1 : learnerOffset; + String baseLearnerName = TestManager.getStringProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.BASE_LEARNER_NAME, true); + String getLessonURL = TestManager.getStringProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.GET_LESSON_URL, false); + String getLearningDesignURL = TestManager.getStringProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.GET_LD_URL, false); + String joinLessonURL = TestManager.getStringProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.JOIN_LESSON_URL, false); + String getProgressURL = TestManager.getStringProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.GET_PROGRESS_URL, false); + String lessonEntryURL = TestManager.getStringProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.LESSON_ENTRY_URL, false); + String filesToUpload = TestManager.getStringProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.FILES_TO_UPLOAD, false); + Integer userIdOffset = TestManager.getIntegerProperty(learnerTestPropertyFileName, learnerTestProperties, + TestManager.USER_ID_OFFSET, true); + + LearnerTest test = new LearnerTest(testName, minDelay, maxDelay, getLessonURL, getLearningDesignURL, + joinLessonURL, getProgressURL, lessonEntryURL, filesToUpload == null ? null : filesToUpload.split(";")); + + if (userIdOffset != null) { + userIdOffset--; + } + MockLearner[] learners = new MockLearner[numberOfLearners]; + for (int i = 0; i < numberOfLearners; i++) { + baseLearnerName = baseLearnerName == null ? MockLearner.DEFAULT_NAME : baseLearnerName; + String username = TestUtil.buildName(testName, baseLearnerName + (learnerOffset + i), + TestManager.MAX_USERNAME_LENGTH); + + String userId = userIdOffset == null ? null : (++userIdOffset).toString(); + learners[i] = new MockLearner(test, username, username, userId); + } + test.setUsers(learners); + + TestManager.log.info("Finished creating learner test " + testName); + return test; + } + + private MonitorTest createMonitorTest(String monitorTestPropertyFileName) { + String testName = TestManager.extractTestName(monitorTestPropertyFileName); + TestManager.log.info("Creating monitor test " + testName); + + Properties monitorTestProperties = TestManager.loadProperties(monitorTestPropertyFileName); + Integer lsId = TestManager.getIntegerProperty(monitorTestPropertyFileName, monitorTestProperties, + TestManager.LESSON_ID, true); + Integer minDelay = TestManager.getIntegerProperty(monitorTestPropertyFileName, monitorTestProperties, + TestManager.MIN_DELAY, true); + Integer maxDelay = TestManager.getIntegerProperty(monitorTestPropertyFileName, monitorTestProperties, + TestManager.MAX_DELAY, true); + String initLessonURL = TestManager.getStringProperty(monitorTestPropertyFileName, monitorTestProperties, + TestManager.INIT_LESSON_URL, lsId != null); + String createLessonClassURL = TestManager.getStringProperty(monitorTestPropertyFileName, monitorTestProperties, + TestManager.CREATE_LESSON_CLASS_URL, lsId != null); + String startLessonURL = TestManager.getStringProperty(monitorTestPropertyFileName, monitorTestProperties, + TestManager.START_LESSON_URL, lsId != null); + String getLessonDetailsURL = TestManager.getStringProperty(monitorTestPropertyFileName, monitorTestProperties, + TestManager.GET_LESSON_DETAILS_URL, lsId != null); + String getContributeActivitiesURL = TestManager.getStringProperty(monitorTestPropertyFileName, + monitorTestProperties, TestManager.GET_CA_URL, lsId != null); + String getLearningDesignDetailsURL = TestManager.getStringProperty(monitorTestPropertyFileName, + monitorTestProperties, TestManager.GET_LD_DETAILS_URL, lsId != null); + String getAllLearnersProgressURL = TestManager.getStringProperty(monitorTestPropertyFileName, + monitorTestProperties, TestManager.GET_ALL_PROGRESS_URL, lsId != null); + String lsName = TestManager.getStringProperty(monitorTestPropertyFileName, monitorTestProperties, + TestManager.LESSON_NAME, true); + String baseMonitorName = TestManager.getStringProperty(monitorTestPropertyFileName, monitorTestProperties, + TestManager.BASE_MONITOR_NAME, true); + Integer userId = TestManager.getIntegerProperty(monitorTestPropertyFileName, monitorTestProperties, + TestManager.USER_ID, true); + + MonitorTest test = new MonitorTest(testName, minDelay, maxDelay, initLessonURL, createLessonClassURL, + startLessonURL, getLessonDetailsURL, getContributeActivitiesURL, getLearningDesignDetailsURL, + getAllLearnersProgressURL, lsName, lsId == null ? null : lsId.toString()); + + baseMonitorName = baseMonitorName == null ? MockMonitor.DEFAULT_NAME : baseMonitorName; + String username = TestUtil.buildName(testName, baseMonitorName, TestManager.MAX_USERNAME_LENGTH); + test.setUsers(new MockMonitor[] { new MockMonitor(test, username, username, userId == null ? null : userId + .toString()) }); + + TestManager.log.info("Finished creating monitor test " + testName); + return test; + } + + private TestSuite createTestSuite(Properties testProperties, int suiteIndex) { + TestManager.log.info("Creating test suite " + suiteIndex); + String targetServer = TestManager.getStringProperty(testPropertyFileName, testProperties, + TestManager.buildPropertyKey(TestManager.TARGET_SERVER, suiteIndex), true); + String contextRoot = TestManager.getStringProperty(testPropertyFileName, testProperties, + TestManager.buildPropertyKey(TestManager.CONTEXT_ROOT, suiteIndex), true); + Integer httpPort = TestManager.getIntegerProperty(testPropertyFileName, testProperties, + TestManager.buildPropertyKey(TestManager.HTTP_PORT, suiteIndex), true); + String adminTestPropertyFileName = TestManager.getStringProperty(testPropertyFileName, testProperties, + TestManager.buildPropertyKey(TestManager.ADMIN_PROPERTY_FILE, suiteIndex), true); + AdminTest adminTest = adminTestPropertyFileName == null ? null : createAdminTest(adminTestPropertyFileName); + String authorTestPropertyFileName = TestManager.getStringProperty(testPropertyFileName, testProperties, + TestManager.buildPropertyKey(TestManager.AUTHOR_PROPERTY_FILE, suiteIndex), true); + AuthorTest authorTest = authorTestPropertyFileName == null ? null + : createAuthorTest(authorTestPropertyFileName); + String monitorTestPropertyFileName = TestManager.getStringProperty(testPropertyFileName, testProperties, + TestManager.buildPropertyKey(TestManager.MONITOR_PROPERTY_FILE, suiteIndex), true); + MonitorTest monitorTest = monitorTestPropertyFileName == null ? null + : createMonitorTest(monitorTestPropertyFileName); + String learnerTestPropertyFileName = TestManager.getStringProperty(testPropertyFileName, testProperties, + TestManager.buildPropertyKey(TestManager.LEARNER_PROPERTY_FILE, suiteIndex), true); + LearnerTest learnerTest = learnerTestPropertyFileName == null ? null + : createLearnerTest(learnerTestPropertyFileName); + + TestSuite suite = new TestSuite(this, suiteIndex, targetServer, contextRoot, httpPort, adminTest, authorTest, + monitorTest, learnerTest); + + TestManager.log.info("Finished creating test suite " + suite.toString()); + return suite; + } + + private void init() { + TestManager.log.info("Initializing"); + + Properties testProperties = TestManager.loadProperties(testPropertyFileName); + TestReporter.setFileName(TestManager.getStringProperty(testPropertyFileName, testProperties, + TestManager.REPORT_FILE_NAME, false)); + MockUser.setIndexPage(TestManager.getStringProperty(testPropertyFileName, testProperties, + TestManager.INDEX_PAGE_URL, false)); + String fileTemplate = TestManager.getStringProperty(testPropertyFileName, testProperties, + TestManager.REPORT_FILE_TEMPLATE, false); + TestReporter.setFileTemplate(fileTemplate); + + int numberOfTestSuites = TestManager.getIntegerProperty(testPropertyFileName, testProperties, + TestManager.NUMBER_OF_TEST_SUITES, false); + for (int suiteIndex = 1; suiteIndex < (numberOfTestSuites + 1); suiteIndex++) { + testSuites.add(createTestSuite(testProperties, suiteIndex)); + } + + TestManager.log.info("Finished initialization"); + } +} \ No newline at end of file Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestReporter.java =================================================================== diff -u -r3b5329cc6c0b5ce4f52badee7c371eb317ac98ee -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestReporter.java (.../TestReporter.java) (revision 3b5329cc6c0b5ce4f52badee7c371eb317ac98ee) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestReporter.java (.../TestReporter.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -22,17 +22,16 @@ */ package org.lamsfoundation.testharness; +import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import java.io.BufferedReader; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.net.MalformedURLException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; @@ -45,356 +44,135 @@ import org.lamsfoundation.testharness.learner.LearnerTest; import edu.stanford.ejalbert.BrowserLauncher; -import edu.stanford.ejalbert.exception.BrowserLaunchingExecutionException; -import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException; -import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException; /** - * @version - * - *

- * View Source - *

- * - * @author Fei Yang + * @author Fei Yang, Marcin Cieslak */ public class TestReporter { - - private static final Logger log = Logger.getLogger(TestReporter.class); - - private static List callRecords = new LinkedList(); - - private static String fileName; - - private static String fileTemplate; - - public static boolean initialized() { - return ((fileName != null) && (fileTemplate != null)); - } - - public static List getCallRecords() { - return callRecords; - } - - public static void setCallRecords(List callRecords) { - TestReporter.callRecords = callRecords; - } - - public static String getFileName() { - return fileName; - } - - public static void setFileName(String fileName) { - TestReporter.fileName = fileName; - } - - public static String getFileTemplate() { - return fileTemplate; - } - - public static void setFileTemplate(String fileTemplate) { - TestReporter.fileTemplate = fileTemplate; - } - - public static synchronized void addCallRecord(CallRecord callRecord) { - callRecords.add(callRecord); - } - - public static void report(AbstractTestManager manager) { - final String NEW_LINE = "\n* "; - final String NEW_LINE_INDENT = "\n* "; - StringBuilder report = new StringBuilder(); - report - .append("See below\n\n**********************************Brief Report*******************************************"); - - // disclaimer - report.append(NEW_LINE); - report.append(NEW_LINE).append("Disclaimer:"); - report.append(NEW_LINE_INDENT).append( - "This program is created in the hope that it will help estimate how many concurrent"); - report.append(NEW_LINE_INDENT).append( - "users a LAMS 2.x server can handle, but WITHOUT ANY GARANTEE the server can support"); - report.append(NEW_LINE_INDENT).append("that number of users in service use."); - report.append(NEW_LINE); - report.append(NEW_LINE_INDENT).append("This program is more a load test tool than a functional test tool, "); - report.append(NEW_LINE_INDENT).append( - "so it does NOT GARANTEE there is no functional bug in the target server."); - report.append(NEW_LINE); - - report.append(NEW_LINE).append("Test Result Summary:"); - report.append(NEW_LINE_INDENT).append(manager.testSuites.size()).append(" test suite(s) launched. "); - report.append(manager.testSuites.size() - manager.countAborted()).append(" test suite(s) finished, and ") - .append(manager.countAborted()).append(" test suite(s) aborted."); - for (TestSuite testSuite : manager.testSuites) { - report.append(NEW_LINE_INDENT).append("Test Suite ").append(testSuite.getSuiteIndex()).append( - testSuite.isFinished() ? " finished" : " aborted").append(", in which"); - report.append(NEW_LINE_INDENT); - AbstractTest[] tests = new AbstractTest[] { testSuite.getAdminTest(), testSuite.getAuthorTest(), - testSuite.getMonitorTest(), testSuite.getLearnerTest() }; - boolean first = true; - for (AbstractTest test : tests) { - if (test != null) { - if (!first) - report.append(", "); - report.append(test.getTestName()).append(test.isFinished() ? " finished" : " aborted"); - first = false; - } - } - report.append(NEW_LINE_INDENT); - LearnerTest learnerTest = testSuite.getLearnerTest(); - report.append("In ").append(learnerTest.getTestName()).append(", "); - report.append(learnerTest.countLearners()).append(" learner(s) attended, "); - report.append(learnerTest.countLearners() - learnerTest.countAborted()).append(" finished and "); - report.append(learnerTest.countAborted()).append(" aborted."); - report.append(NEW_LINE); - } - report.append(NEW_LINE).append("Refer to the formal test report document for the details."); - report.append(NEW_LINE).append( - "\n*****************************************************************************************\n"); - log.info(report.toString()); - } - - public static void generateReport(AbstractTestManager manager) { - report(manager); - log.info("Generating the formal test report document..."); - TemplateCompiler.init(manager.testSuites, callRecords); - String filename = generateFileName(); - BufferedWriter out = null; - try { - String report = TemplateCompiler.compile(TemplateCompiler.load()); - out = new BufferedWriter(new FileWriter(filename)); - out.write(report); - out.close(); - BrowserLauncher launcher = new BrowserLauncher(null); - launcher.openURLinBrowser(new File(filename).toURL().toString()); - } catch (MalformedURLException e) { - log.debug(e.getMessage(), e); - } catch (IOException e) { - log.debug(e.getMessage(), e); - } catch (BrowserLaunchingInitializingException e) { - log.debug(e.getMessage(), e); - } catch (UnsupportedOperatingSystemException e) { - log.debug(e.getMessage(), e); - } catch (BrowserLaunchingExecutionException e) { - log.debug(e.getMessage(), e); - } finally { - if (out != null) { - try { - out.close(); - } catch (IOException e) { - log.debug(e.getMessage(), e); - } - } - } - } - - private static String generateFileName() { - return fileName + "_" + new SimpleDateFormat("MMM-d-HH'h-'mm'm'").format(new Date()) + ".html"; - } - - public static void main(String[] args) { - String[] results = "testSuite.suiteIndex".split("\\."); - System.out.println(results.length); - } - private static class TemplateCompiler { - static Map context; + private static Map context; + private static final int LIST_FIRST = 0; + private static final int IF_FIRST = 1; + private static final int EL_FIRST = 2; + private static final int TEXT_FIRST = 3; + private static final String EL_START = "${"; + private static final char EL_END = '}'; + private static final String LIST_START = "<#list"; + private static final String LIST_AS = "as"; + private static final String LIST_END = ""; + private static final String IF_START = "<#if"; + private static final String IF_ELSE = "<#else>"; + private static final String IF_END = ""; + private static final char TAG_END = '>'; - static final int LIST_FIRST = 0; - - static final int IF_FIRST = 1; - - static final int EL_FIRST = 2; - - static final int TEXT_FIRST = 3; - - static final String EL_START = "${"; - - static final char EL_END = '}'; - - static final String LIST_START = "<#list"; - - static final String LIST_AS = "as"; - - // static final String LIST_GROUP_BY = "group by"; - static final String LIST_END = ""; - - static final String IF_START = "<#if"; - - static final String IF_ELSE = "<#else>"; - - static final String IF_END = ""; - - static final char TAG_END = '>'; - - // static final String AVG = "avg"; - // static final String SUM = "sum"; - // static final String COUNT = "count"; - // static final char PARAM_START = '('; - // static final char PARAM_END = ')'; - - static void init(List testSuites, List callRecords) { - context = new HashMap(); - context.put("callRecords", callRecords); - context.put("testSuites", testSuites); - context.put("time", new SimpleDateFormat("HH:mm:ss dd MMM yyyy").format(new Date())); - long total = 0; - long count = 0; - long joinLessonTotal = 0; - long joinLessonCount = 0; - for (CallRecord r : callRecords) { - if (r.getHttpStatusCode() != null && r.getHttpStatusCode().equals(new Integer("200"))) { - total += r.getTimeInMillis(); - count++; - // learning/learner.do?method=joinLesson - if (r.getCallee().indexOf("learner.do?method=joinLesson") > 0) { - joinLessonTotal += r.getTimeInMillis(); - joinLessonCount++; - } - } - } - log.info("Total response time: "+total / 1000.0+" seconds"); - log.info("Average response time: "+total / 1000.0 /count+" seconds"); - log.info("Average response time of joinLesson calls: "+joinLessonTotal / 1000.0 / joinLessonCount+" seconds"); - context.put("totalResponseTime", total / 1000.0); - context.put("averageResponseTime", total / 1000.0 / count); - context.put("joinLessonAverageResponseTime", joinLessonTotal / 1000.0 / joinLessonCount); - } - - static String load() throws IOException { - BufferedReader bReader = null; - try { - StringBuilder source = new StringBuilder(); - bReader = new BufferedReader(new FileReader(fileTemplate)); - String line = bReader.readLine(); - while (line != null) { - source.append(line).append('\n'); - line = bReader.readLine(); - } - return source.toString(); - } finally { - if (bReader != null) { - bReader.close(); - } - } - } - + @SuppressWarnings("unchecked") private static String compile(String source) { - int listStartIndex = source.indexOf(LIST_START); - int ifStartIndex = source.indexOf(IF_START); - int elStartIndex = source.indexOf(EL_START); - switch (whichFirst(convert(listStartIndex, source), convert(ifStartIndex, source), convert(elStartIndex, - source), source.length())) { + int listStartIndex = source.indexOf(TemplateCompiler.LIST_START); + int ifStartIndex = source.indexOf(TemplateCompiler.IF_START); + int elStartIndex = source.indexOf(TemplateCompiler.EL_START); + switch (TemplateCompiler.whichFirst(TemplateCompiler.convert(listStartIndex, source), + TemplateCompiler.convert(ifStartIndex, source), TemplateCompiler.convert(elStartIndex, source), + source.length())) { case LIST_FIRST: - int listEndIndex = source.indexOf(LIST_END, listStartIndex); - int listStartTagIndex = source.indexOf(TAG_END, listStartIndex); - int listAsIndex = source.indexOf(LIST_AS, listStartIndex); - if (listStartTagIndex == -1) + int listEndIndex = source.indexOf(TemplateCompiler.LIST_END, listStartIndex); + int listStartTagIndex = source.indexOf(TemplateCompiler.TAG_END, listStartIndex); + int listAsIndex = source.indexOf(TemplateCompiler.LIST_AS, listStartIndex); + if (listStartTagIndex == -1) { throw new TestHarnessException("'list' tag missing '>'"); - if (listAsIndex == -1) + } + if (listAsIndex == -1) { throw new TestHarnessException("'as' is required for 'list'"); - if (listEndIndex == -1) + } + if (listEndIndex == -1) { throw new TestHarnessException("'list' tag unclosed"); + } StringBuilder middle = new StringBuilder(); String middlePart = source.substring(listStartTagIndex + 1, listEndIndex); - String collection = extract(source.substring(listStartIndex + LIST_START.length(), listAsIndex)); - String element = extract(source.substring(listAsIndex + LIST_AS.length(), listStartTagIndex)).trim(); - for (Object o : (List) compileEL(collection)) { + String collection = TemplateCompiler.extract(source.substring(listStartIndex + + TemplateCompiler.LIST_START.length(), listAsIndex)); + String element = TemplateCompiler.extract( + source.substring(listAsIndex + TemplateCompiler.LIST_AS.length(), listStartTagIndex)).trim(); + for (Object o : (List) TemplateCompiler.compileEL(collection)) { // log.debug("Put " + o + " into context as "+element); - context.put(element, o); - middle.append(compile(middlePart)); + TemplateCompiler.context.put(element, o); + middle.append(TemplateCompiler.compile(middlePart)); } String frontEnd = source.substring(0, listStartIndex); - String backEnd = source.substring(listEndIndex + LIST_END.length()); - return compile(frontEnd) + middle.toString() + compile(backEnd); + String backEnd = source.substring(listEndIndex + TemplateCompiler.LIST_END.length()); + return TemplateCompiler.compile(frontEnd) + middle.toString() + TemplateCompiler.compile(backEnd); case IF_FIRST: - int ifEndIndex = source.indexOf(IF_END, ifStartIndex); - int ifStartTagIndex = source.indexOf(TAG_END, ifStartIndex); - int elseIndex = source.indexOf(IF_ELSE, ifStartIndex); - if (ifStartTagIndex == -1) + int ifEndIndex = source.indexOf(TemplateCompiler.IF_END, ifStartIndex); + int ifStartTagIndex = source.indexOf(TemplateCompiler.TAG_END, ifStartIndex); + int elseIndex = source.indexOf(TemplateCompiler.IF_ELSE, ifStartIndex); + if (ifStartTagIndex == -1) { throw new TestHarnessException("'if' tag missing '>'"); - if (ifEndIndex == -1) + } + if (ifEndIndex == -1) { throw new TestHarnessException("'if' tag unclosed"); - String condition = extract(source.substring(ifStartIndex + IF_START.length(), ifStartTagIndex)); - Boolean b = (Boolean) compileEL(condition); + } + String condition = TemplateCompiler.extract(source.substring( + ifStartIndex + TemplateCompiler.IF_START.length(), ifStartTagIndex)); + Boolean b = (Boolean) TemplateCompiler.compileEL(condition); String ifBlock; if (elseIndex != -1) { String middlePart1 = source.substring(ifStartTagIndex + 1, elseIndex); - String middlePart2 = source.substring(elseIndex + IF_ELSE.length(), ifEndIndex); + String middlePart2 = source.substring(elseIndex + TemplateCompiler.IF_ELSE.length(), ifEndIndex); ifBlock = b ? middlePart1 : middlePart2; } else { String middlePart1 = source.substring(ifStartTagIndex + 1, ifEndIndex); ifBlock = b ? middlePart1 : ""; } String ifFrontEnd = source.substring(0, ifStartIndex); - String ifBackEnd = source.substring(ifEndIndex + IF_END.length()); - return compile(ifFrontEnd) + compile(ifBlock) + compile(ifBackEnd); + String ifBackEnd = source.substring(ifEndIndex + TemplateCompiler.IF_END.length()); + return TemplateCompiler.compile(ifFrontEnd) + TemplateCompiler.compile(ifBlock) + + TemplateCompiler.compile(ifBackEnd); case EL_FIRST: - int elEndIndex = source.indexOf(EL_END, elStartIndex); - if (elEndIndex == -1) + int elEndIndex = source.indexOf(TemplateCompiler.EL_END, elStartIndex); + if (elEndIndex == -1) { throw new TestHarnessException("'}' expected"); - String elBlock = compileEL(source.substring(elStartIndex + EL_START.length(), elEndIndex)).toString(); + } + String elBlock = TemplateCompiler.compileEL( + source.substring(elStartIndex + TemplateCompiler.EL_START.length(), elEndIndex)).toString(); String elFrontEnd = source.substring(0, elStartIndex); String elBackEnd = source.substring(elEndIndex + 1); - return compile(elFrontEnd) + elBlock + compile(elBackEnd); + return TemplateCompiler.compile(elFrontEnd) + elBlock + TemplateCompiler.compile(elBackEnd); case TEXT_FIRST: return source; default: - throw new TestHarnessException("unexpected error happened!"); + throw new TestHarnessException("Unknown error"); } } - private static int whichFirst(int listStartIndex, int ifStartIndex, int elStartIndex, int textIndex) { - int[] indexes = { listStartIndex, ifStartIndex, elStartIndex, textIndex }; - return whichMinimum(indexes); - } - - private static int whichMinimum(int[] nums) { - if (nums.length == 0) { - return -1; - } - int min = nums[0]; - int minIndex = 0; - for (int i = 1; i < nums.length; i++) { - if (nums[i] < min) { - min = nums[i]; - minIndex = i; - } - } - return minIndex; - } - - private static int convert(int index, String source) { - return index == -1 ? source.length() + 1 : index; - } - private static Object compileEL(String el) { - // log.debug("EL is " + el); String[] references = el.split("\\."); if (references.length == 0) { references = new String[] { el.trim() }; } - Object result = context.get(references[0].trim()); - // log.debug("Retrieve "+references[0].trim()+" from context and - // got "+result); + Object result = TemplateCompiler.context.get(references[0].trim()); for (int i = 1; i < references.length; i++) { - result = getFieldOrInvokeMethod(result, references[i].trim()); + result = TemplateCompiler.getFieldOrInvokeMethod(result, references[i].trim()); } return result; } + private static int convert(int index, String source) { + return index == -1 ? source.length() + 1 : index; + } + private static String extract(String el) { return el.substring(el.indexOf("${") + 2, el.indexOf('}')).trim(); } + @SuppressWarnings({ "rawtypes", "unchecked" }) private static Object getFieldOrInvokeMethod(Object obj, String reference) { // log.debug("Reference is "+reference); Object result = null; Class clazz = obj.getClass(); if (clazz.isArray()) { - if (reference.equalsIgnoreCase("length")) + if (reference.equalsIgnoreCase("length")) { return Array.getLength(obj); + } } try { Field field = null; @@ -419,20 +197,21 @@ result = method.invoke(obj); } if (result == null) {// the last resort - method = getReadMethod(field, reference, obj.getClass()); + method = TemplateCompiler.getReadMethod(field, reference, obj.getClass()); if (method != null) { result = method.invoke(obj); } } } } catch (Exception e) { - log.debug(e.getMessage(), e); + TestReporter.log.debug(e.getMessage(), e); // ignore } // log.debug("Result is "+result); return result; } + @SuppressWarnings({ "unchecked", "rawtypes" }) private static Method getReadMethod(Field field, String fieldName, Class clazz) throws Exception { String convertedName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method method = null; @@ -453,6 +232,189 @@ return method; } + private static void init(List testSuites, List callRecords) { + TemplateCompiler.context = new HashMap(); + TemplateCompiler.context.put("callRecords", callRecords); + TemplateCompiler.context.put("testSuites", testSuites); + TemplateCompiler.context.put("time", new SimpleDateFormat("HH:mm:ss dd MMM yyyy").format(new Date())); + long total = 0; + long count = 0; + long joinLessonTotal = 0; + long joinLessonCount = 0; + for (CallRecord r : callRecords) { + if ((r.getHttpStatusCode() != null) && r.getHttpStatusCode().equals(200)) { + total += r.getTimeInMillis(); + count++; + if (r.getCallee().indexOf("learner.do?method=joinLesson") > 0) { + joinLessonTotal += r.getTimeInMillis(); + joinLessonCount++; + } + } + } + TestReporter.log.info("Total response time: " + (total / 1000.0) + " seconds"); + TestReporter.log.info("Average response time: " + (total / 1000.0 / count) + " seconds"); + TestReporter.log.info("Average response time of joinLesson calls: " + + (joinLessonTotal / 1000.0 / joinLessonCount) + " seconds"); + TemplateCompiler.context.put("totalResponseTime", total / 1000.0); + TemplateCompiler.context.put("averageResponseTime", total / 1000.0 / count); + TemplateCompiler.context.put("joinLessonAverageResponseTime", joinLessonTotal / 1000.0 / joinLessonCount); + } + + private static String load() throws IOException { + BufferedReader bReader = null; + try { + StringBuilder source = new StringBuilder(); + bReader = new BufferedReader(new FileReader(TestReporter.fileTemplate)); + String line = bReader.readLine(); + while (line != null) { + source.append(line).append('\n'); + line = bReader.readLine(); + } + return source.toString(); + } finally { + if (bReader != null) { + bReader.close(); + } + } + } + + private static int whichFirst(int listStartIndex, int ifStartIndex, int elStartIndex, int textIndex) { + int[] indexes = { listStartIndex, ifStartIndex, elStartIndex, textIndex }; + return TemplateCompiler.whichMinimum(indexes); + } + + private static int whichMinimum(int[] nums) { + if (nums.length == 0) { + return -1; + } + int min = nums[0]; + int minIndex = 0; + for (int i = 1; i < nums.length; i++) { + if (nums[i] < min) { + min = nums[i]; + minIndex = i; + } + } + return minIndex; + } + } -} + private static final Logger log = Logger.getLogger(TestReporter.class); + private static final String NEW_LINE = "\n* "; + private static final String NEW_LINE_INDENT = "\n* "; + private static final String REPORT_HEADER = new StringBuilder() + .append("See below\n\n**********************************Brief Report*******************************************") + .append(TestReporter.NEW_LINE).append(TestReporter.NEW_LINE).append("Disclaimer:") + .append(TestReporter.NEW_LINE_INDENT) + .append("This program is created in the hope that it will help estimate how many concurrent") + .append(TestReporter.NEW_LINE_INDENT) + .append("users a LAMS 2.x server can handle, but WITHOUT ANY GARANTEE the server can support") + .append(TestReporter.NEW_LINE_INDENT).append("that number of users in service use.") + .append(TestReporter.NEW_LINE).append(TestReporter.NEW_LINE_INDENT) + .append("This program is more a load test tool than a functional test tool, ") + .append(TestReporter.NEW_LINE_INDENT) + .append("so it does NOT GARANTEE there is no functional bug in the target server.") + .append(TestReporter.NEW_LINE).append(TestReporter.NEW_LINE).append("Test Result Summary:").toString(); + + private static final String REPORT_FOOTER = new StringBuilder().append(TestReporter.NEW_LINE) + .append("Refer to the formal test report document for the details.").append(TestReporter.NEW_LINE) + .append("\n*****************************************************************************************\n") + .toString(); + private static List callRecords = new LinkedList(); + private static String fileName; + + private static String fileTemplate; + + public static synchronized void addCallRecord(CallRecord callRecord) { + TestReporter.callRecords.add(callRecord); + } + + public static void generateReportFile(TestManager manager) { + TestReporter.log.info("Generating the formal test report document"); + TemplateCompiler.init(manager.testSuites, TestReporter.callRecords); + String filename = TestReporter.fileName + "_" + new SimpleDateFormat("MMM-d-HH'h-'mm'm'").format(new Date()) + + ".html"; + BufferedWriter out = null; + try { + String report = TemplateCompiler.compile(TemplateCompiler.load()); + out = new BufferedWriter(new FileWriter(filename)); + out.write(report); + BrowserLauncher launcher = new BrowserLauncher(null); + launcher.openURLinBrowser(new File(filename).toURI().toURL().toString()); + } catch (Exception e) { + TestReporter.log.error("Error when generating report file", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + TestReporter.log.warn("Error when generating report file", e); + } + } + } + } + + public static void generateReportLog(TestManager manager) { + StringBuilder report = new StringBuilder(TestReporter.REPORT_HEADER); + report.append(TestReporter.NEW_LINE_INDENT).append(manager.testSuites.size()).append(" test suites launched. "); + report.append(manager.testSuites.size() - manager.countAborted()).append(" test suites finished and ") + .append(manager.countAborted()).append(" test suites aborted."); + + for (TestSuite testSuite : manager.testSuites) { + report.append(TestReporter.NEW_LINE_INDENT).append("Test Suite ").append(testSuite.getSuiteIndex()) + .append(testSuite.isFinished() ? " finished" : " aborted").append(", in which"); + report.append(TestReporter.NEW_LINE_INDENT); + AbstractTest[] tests = new AbstractTest[] { testSuite.getAdminTest(), testSuite.getAuthorTest(), + testSuite.getMonitorTest(), testSuite.getLearnerTest() }; + boolean first = true; + for (AbstractTest test : tests) { + if (test != null) { + if (!first) { + report.append(", "); + } + report.append(test.getTestName()).append(test.isFinished() ? " finished" : " aborted"); + first = false; + } + } + report.append(TestReporter.NEW_LINE_INDENT); + LearnerTest learnerTest = testSuite.getLearnerTest(); + report.append("In ").append(learnerTest.getTestName()).append(", "); + report.append(learnerTest.countLearners()).append(" learners attended, "); + report.append(learnerTest.countLearners() - learnerTest.countAborted()).append(" finished and "); + report.append(learnerTest.countAborted()).append(" aborted."); + report.append(TestReporter.NEW_LINE); + } + + report.append(TestReporter.REPORT_FOOTER); + TestReporter.log.info(report.toString()); + } + + public static List getCallRecords() { + return TestReporter.callRecords; + } + + public static String getFileName() { + return TestReporter.fileName; + } + + public static String getFileTemplate() { + return TestReporter.fileTemplate; + } + + public static boolean initialized() { + return ((TestReporter.fileName != null) && (TestReporter.fileTemplate != null)); + } + + public static void setCallRecords(List callRecords) { + TestReporter.callRecords = callRecords; + } + + public static void setFileName(String fileName) { + TestReporter.fileName = fileName; + } + + public static void setFileTemplate(String fileTemplate) { + TestReporter.fileTemplate = fileTemplate; + } +} \ No newline at end of file Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestSuite.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestSuite.java (.../TestSuite.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestSuite.java (.../TestSuite.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -31,148 +31,139 @@ import org.lamsfoundation.testharness.monitor.MonitorTest; /** - * @version - * - *

- * View Source - *

- * - * @author Fei Yang + * @author Fei Yang, Marcin Cieslak */ public class TestSuite implements Runnable { - private static final Logger log = Logger.getLogger(TestSuite.class); - - private AbstractTestManager manager; - private int suiteIndex; - private String targetServer; - private String contextRoot; - private Integer rmiRegistryServicePort; - private Integer httpPort; - private AdminTest adminTest; - private AuthorTest authorTest; - private MonitorTest monitorTest; - private LearnerTest learnerTest; - private boolean finished = false; + private static final Logger log = Logger.getLogger(TestSuite.class); - public TestSuite(AbstractTestManager manager, int suiteIndex, String targetServer, String contextRoot, Integer rmiRegistryServicePort, Integer httpPort, AdminTest adminTest, AuthorTest authorTest, MonitorTest monitorTest, - LearnerTest learnerTest) { - this.manager = manager; - this.suiteIndex = suiteIndex; - this.targetServer = targetServer == null ? "localhost" : targetServer; - this.contextRoot = contextRoot == null || contextRoot.equals("/") ? "" : contextRoot; - this.rmiRegistryServicePort = rmiRegistryServicePort == null ? 1099 : rmiRegistryServicePort; - this.httpPort = httpPort == null ? 80 : httpPort; - this.adminTest = adminTest; - adminTest.setTestSuite(this); - this.authorTest = authorTest; - authorTest.setTestSuite(this); - this.monitorTest = monitorTest; - monitorTest.setTestSuite(this); - this.learnerTest = learnerTest; - learnerTest.setTestSuite(this); - } + private TestManager manager; + private int suiteIndex; + private String targetServer; + private String contextRoot; + private Integer httpPort; + private AdminTest adminTest; + private AuthorTest authorTest; + private MonitorTest monitorTest; + private LearnerTest learnerTest; + private boolean finished = false; - /** - * The order is important, not to be changed - */ - public void run() { - try{ - log.info("Starting test suite " + suiteIndex + "..."); - if (adminTest != null) - adminTest.start(); - if (authorTest != null) - authorTest.start(); - if (monitorTest != null) - monitorTest.start(); - if ((learnerTest != null)&&(monitorTest != null)) - learnerTest.start(); - if(monitorTest != null){ - CountDownLatch stopSignal = new CountDownLatch(1); - monitorTest.notifyMonitorToStop(stopSignal); - stopSignal.await(); - } - finished = true; - log.info("Finished test suite "+suiteIndex); - } catch(Exception e) {//All the exceptions which happened during test stop propagation here - log.debug(e.getMessage(),e); - log.info("Test suite " + suiteIndex + " aborted"); - //Exception is not propagated so that other testsuite will not be affected - }finally{ - manager.allDoneSignal.countDown(); - } - } + public TestSuite(TestManager manager, int suiteIndex, String targetServer, String contextRoot, Integer httpPort, + AdminTest adminTest, AuthorTest authorTest, MonitorTest monitorTest, LearnerTest learnerTest) { + this.manager = manager; + this.suiteIndex = suiteIndex; + this.targetServer = targetServer == null ? "localhost" : targetServer; + this.contextRoot = (contextRoot == null) || contextRoot.equals("/") ? "" : contextRoot; + this.httpPort = httpPort == null ? 80 : httpPort; + + this.adminTest = adminTest; + adminTest.setTestSuite(this); + this.authorTest = authorTest; + authorTest.setTestSuite(this); + this.monitorTest = monitorTest; + monitorTest.setTestSuite(this); + this.learnerTest = learnerTest; + learnerTest.setTestSuite(this); + } - public final int getSuiteIndex() { - return suiteIndex; - } + /** + * @return Returns the adminTest. + */ + public final AdminTest getAdminTest() { + return adminTest; + } - /** - * @return Returns the adminTest. - */ - public final AdminTest getAdminTest() { - return adminTest; - } + /** + * @return Returns the authorTest. + */ + public final AuthorTest getAuthorTest() { + return authorTest; + } - /** - * @return Returns the authorTest. - */ - public final AuthorTest getAuthorTest() { - return authorTest; - } + public final String getContextRoot() { + return contextRoot; + } - /** - * @return Returns the httpPort. - */ - public final int getHttpPort() { - return httpPort; - } + /** + * @return Returns the httpPort. + */ + public final int getHttpPort() { + return httpPort; + } - /** - * @return Returns the learnerTest. - */ - public final LearnerTest getLearnerTest() { - return learnerTest; - } + /** + * @return Returns the learnerTest. + */ + public final LearnerTest getLearnerTest() { + return learnerTest; + } - /** - * @return Returns the rmiRegistryServicePort. - */ - public final int getRmiRegistryServicePort() { - return rmiRegistryServicePort; - } + public final TestManager getManager() { + return manager; + } - /** - * @return Returns the monitorTest. - */ - public final MonitorTest getMonitorTest() { - return monitorTest; - } + /** + * @return Returns the monitorTest. + */ + public final MonitorTest getMonitorTest() { + return monitorTest; + } - /** - * @return Returns the targetServer. - */ - public final String getTargetServer() { - return targetServer; - } + public final int getSuiteIndex() { + return suiteIndex; + } - public final String getContextRoot() { - return contextRoot; - } + /** + * @return Returns the targetServer. + */ + public final String getTargetServer() { + return targetServer; + } - public final void setContextRoot(String contextRoot) { - this.contextRoot = contextRoot; - } - - public String toString(){ - return "suiteIndex:"+suiteIndex+" targetServer:"+targetServer; - } + public final boolean isFinished() { + return finished; + } - public final AbstractTestManager getManager() { - return manager; + /** + * The order is important, not to be changed + */ + @Override + public void run() { + try { + TestSuite.log.info("Starting test suite " + suiteIndex); + if (adminTest != null) { + adminTest.start(); + } + if (authorTest != null) { + authorTest.start(); + } + if (monitorTest != null) { + monitorTest.start(); + } + if ((learnerTest != null) && (monitorTest != null)) { + learnerTest.start(); + } + if (monitorTest != null) { + CountDownLatch stopSignal = new CountDownLatch(1); + monitorTest.notifyMonitorToStop(stopSignal); + stopSignal.await(); + } + finished = true; + TestSuite.log.info("Finished test suite " + suiteIndex); + } catch (Exception e) {// All the exceptions which happened during test stop propagation here + TestSuite.log.error("Test suite " + suiteIndex + " aborted", e); + // Exception is not propagated so that other testsuite will not be affected + } finally { + manager.allDoneSignal.countDown(); } + } - public final boolean isFinished() { - return finished; - } -} + public final void setContextRoot(String contextRoot) { + this.contextRoot = contextRoot; + } + + @Override + public String toString() { + return "suiteIndex:" + suiteIndex + " targetServer:" + targetServer; + } +} \ No newline at end of file Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestUtil.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestUtil.java (.../TestUtil.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/TestUtil.java (.../TestUtil.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -37,100 +37,91 @@ import com.allaire.wddx.WddxSerializer; /** - * @version - * - *

- * View Source - *

- * - * @author Fei Yang + * @author Fei Yang, Marcin Cieslak */ public class TestUtil { + private static final Logger log = Logger.getLogger(TestUtil.class); + protected static final char NAME_SEPERATOR = '_'; - private static final Logger log = Logger.getLogger(TestUtil.class); - - private static String machineName; + private static String machineName; - protected static final char NAME_SEPERATOR = '_'; + public static String buildName(String testName, String simpleName) { + return TestUtil.getMachineName() + TestUtil.NAME_SEPERATOR + testName + TestUtil.NAME_SEPERATOR + simpleName; + } - public static String getMachineName() { - try { - if (machineName == null) - return machineName = InetAddress.getLocalHost().getHostName(); - else - return machineName; - } catch (UnknownHostException e) { - return "UnknownHost"; - } + public static String buildName(String testName, String simpleName, int maxLength) { + return TestUtil.truncate(TestUtil.buildName(TestUtil.truncate(testName, 1, true), simpleName), maxLength, true); + } - } + public static Object deserialize(String wddxPacket) throws WddxDeserializationException { - public static String serialize(Object data) throws IOException { - WddxSerializer tempws = new WddxSerializer(); - StringWriter tempsw = new StringWriter(); - tempws.serialize(data, tempsw); - return tempsw.toString(); - } + TestUtil.log.debug("WDDX packet from the server:" + wddxPacket); - public static Object deserialize(String wddxPacket) throws WddxDeserializationException { - - log.debug("WDDX packet from the server:"+wddxPacket); - - // Create an input source (org.xml.sax.InputSource) bound to the packet - InputSource tempSource = new InputSource(new StringReader(wddxPacket)); + // Create an input source (org.xml.sax.InputSource) bound to the packet + InputSource tempSource = new InputSource(new StringReader(wddxPacket)); - // Create a WDDX deserializer (com.allaire.wddx.WddxDeserializer) - WddxDeserializer tempDeserializer = new WddxDeserializer("org.apache.xerces.parsers.SAXParser"); + // Create a WDDX deserializer (com.allaire.wddx.WddxDeserializer) + WddxDeserializer tempDeserializer = new WddxDeserializer("org.apache.xerces.parsers.SAXParser"); - // Deserialize the WDDX packet - Object result; - try { - result = tempDeserializer.deserialize(tempSource); - log.debug("Object deserialized from the WDDX packet:"+result); - } catch (IOException e) { - throw new WddxDeserializationException(e); - } - - return result; + // Deserialize the WDDX packet + Object result; + try { + result = tempDeserializer.deserialize(tempSource); + TestUtil.log.debug("Object deserialized from the WDDX packet:" + result); + } catch (IOException e) { + throw new WddxDeserializationException(e); } - public static String buildName(String testName, String simpleName) { - return TestUtil.getMachineName() + NAME_SEPERATOR + testName + NAME_SEPERATOR + simpleName; - } + return result; + } - public static String buildName(String testName, String simpleName, int maxLength) { - return truncate(buildName(truncate(testName,1,true),simpleName), maxLength, true); + public static String extractString(String text, String startFlag, char endFlag) { + String target = null; + try { + int index = text.indexOf(startFlag); + if (index != -1) { + int startIndex = index + startFlag.length(); + int endIndex = text.indexOf(endFlag, startIndex); + target = text.substring(startIndex, endIndex); + } + } catch (IndexOutOfBoundsException e) { + TestUtil.log.error("Index out of bounds. StartFlag: " + startFlag + ", endFlag: " + endFlag + ", text: " + + text); } + return target; + } - private static String truncate(String name, int length, boolean leftToRight) { - if(name.length()<=length) - return name; - if(leftToRight) - return name.substring(name.length()-length); - else - return name.substring(0,length); - } + public static int generateRandomNumber(int length) { + return new Random().nextInt(length); + } - public static String extractString(String text, String startFlag, char endFlag){ - String target = null; - try{ - int index = text.indexOf(startFlag); - if(index!=-1){ - int startIndex = index + startFlag.length(); - int endIndex = text.indexOf(endFlag, startIndex); - target = text.substring(startIndex, endIndex); - } - }catch(IndexOutOfBoundsException e){ - log.debug(e.getMessage()); - log.debug("startFlag: "+startFlag+" endFlag: "+endFlag); - log.debug(text); - } - return target; + public static String getMachineName() { + try { + if (TestUtil.machineName == null) { + return TestUtil.machineName = InetAddress.getLocalHost().getHostName(); + } else { + return TestUtil.machineName; + } + } catch (UnknownHostException e) { + return "UnknownHost"; } + } - public static int generateRandomIndex(int length){ - return new Random().nextInt(length); - } - + public static String serialize(Object data) throws IOException { + WddxSerializer tempws = new WddxSerializer(); + StringWriter tempsw = new StringWriter(); + tempws.serialize(data, tempsw); + return tempsw.toString(); + } + private static String truncate(String name, int length, boolean leftToRight) { + if (name.length() <= length) { + return name; + } + if (leftToRight) { + return name.substring(name.length() - length); + } else { + return name.substring(0, length); + } + } } \ No newline at end of file Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/admin/AdminTest.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/admin/AdminTest.java (.../AdminTest.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/admin/AdminTest.java (.../AdminTest.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -24,106 +24,85 @@ import org.lamsfoundation.testharness.AbstractTest; import org.lamsfoundation.testharness.TestUtil; -import org.lamsfoundation.testharness.Call.CallType; /** * @version - * - *

- * View Source - *

- * + * + *

+ * View Source + *

+ * * @author Fei Yang */ public class AdminTest extends AbstractTest { - - private static final String DEFAULT_COURSE_NAME = "Course"; - - private String createCourseURL; - private String createUserURL; - private Boolean userCreated; - private String courseName; + + private static final String DEFAULT_COURSE_NAME = "Course"; + + private String createCourseURL; + private String createUserURL; + private Boolean userCreated; + private String courseName; private String courseId; - /** - * @param testName - * @param callType - * @param adminRMIRegistryName - * @param webServiceAddress - * @param userCreated - * @param courseName - * @param courseId - */ - public AdminTest(String testName, CallType callType, String adminRMIRegistryName, String webServiceAddress, Integer minDelay, Integer maxDelay, String createCourseURL, String createUserURL, String courseId, Boolean userCreated, String courseName) { - - super(testName,callType,adminRMIRegistryName, webServiceAddress, minDelay, maxDelay); - this.createCourseURL = createCourseURL; - this.createUserURL = createUserURL; - this.courseName = courseName==null? TestUtil.buildName(testName,DEFAULT_COURSE_NAME):TestUtil.buildName(testName,courseName); - this.courseId = courseId; - this.userCreated = userCreated; + public AdminTest(String testName, Integer minDelay, Integer maxDelay, String createCourseURL, String createUserURL, + String courseId, Boolean userCreated, String courseName) { + super(testName, minDelay, maxDelay); + this.createCourseURL = createCourseURL; + this.createUserURL = createUserURL; + this.courseName = courseName == null ? TestUtil.buildName(testName, AdminTest.DEFAULT_COURSE_NAME) : TestUtil + .buildName(testName, courseName); + this.courseId = courseId; + this.userCreated = userCreated; } - /** - * let MockAdmin do what he should do - * login, create course and then create users - * - * @exception TestHarnessExcepton - * @exception RuntimeException - */ - protected void startWEB(){ - if((courseId!=null)&&userCreated) - return; - MockAdmin admin = (MockAdmin) users[0]; - admin.login(); - if(courseId == null){ - setCourseId(admin.createCourse(createCourseURL, courseName)); - } - admin.createUsers(createUserURL, courseId); - } + public final String getCourseId() { + return courseId; + } - @Override - protected void startWS(){ - //TODO implement me - } + public final String getCourseName() { + return courseName; + } - @Override - protected void startRMI(){ - //TODO implement me - } + public final String getCreateCourseURL() { + return createCourseURL; + } - public final void setCourseName(String courseName) { - this.courseName = courseName; - } - - public final String getCourseName() { - return courseName; - } + public final String getCreateUserURL() { + return createUserURL; + } + public final Boolean getUserCreated() { + return userCreated; + } - public final String getCreateCourseURL() { - return createCourseURL; - } + public final void setCourseId(String courseId) { + this.courseId = courseId; + } + public final void setCourseName(String courseName) { + this.courseName = courseName; + } - public final String getCreateUserURL() { - return createUserURL; - } + public final void setUserCreated(Boolean userCreated) { + this.userCreated = userCreated; + } - public final String getCourseId() { - return courseId; + /** + * let MockAdmin do what he should do login, create course and then create users + * + * @exception TestHarnessExcepton + * @exception RuntimeException + */ + @Override + protected void startTest() { + if ((courseId != null) && userCreated) { + return; } - - public final void setCourseId(String courseId) { - this.courseId = courseId; + MockAdmin admin = (MockAdmin) users[0]; + admin.login(); + if (courseId == null) { + setCourseId(admin.createCourse(createCourseURL, courseName)); } - - public final Boolean getUserCreated() { - return userCreated; - } - - public final void setUserCreated(Boolean userCreated) { - this.userCreated = userCreated; - } - -} + admin.createUsers(createUserURL, courseId); + } +} \ No newline at end of file Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/admin/MockAdmin.java =================================================================== diff -u -rc6ee15a5f86cbe315af4e6c2a933275fb8a1d41e -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/admin/MockAdmin.java (.../MockAdmin.java) (revision c6ee15a5f86cbe315af4e6c2a933275fb8a1d41e) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/admin/MockAdmin.java (.../MockAdmin.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -23,7 +23,9 @@ package org.lamsfoundation.testharness.admin; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.log4j.Logger; @@ -43,191 +45,187 @@ /** * @version - * - *

- * View Source - *

- * + * + *

+ * View Source + *

+ * * @author Fei Yang */ public class MockAdmin extends MockUser { - - private static final Logger log = Logger.getLogger(MockAdmin.class); - private static final String COURSE_FORM_FLAG = "OrganisationForm"; - private static final String COURSE_NAME = "name"; - private static final String COURSE_ID_PATTERN = "%orgId%"; - private static final String USER_FORM_FLAG = "UserForm"; - private static final String LOGIN = "login"; - private static final String PASSWORD = "password"; - private static final String PASSWORD2 = "password2"; - private static final String FIRST_NAME = "firstName"; - private static final String LAST_NAME = "lastName"; - private static final String EMAIL = "email"; - private static final String COMMON_LAST_NAME = "Testharness"; - private static final String ROLES = "roles"; - private static final String AUTHOR_ROLE = "3"; - private static final String MONITOR_ROLE = "4"; - private static final String LEARNER_ROLE = "5"; - private static final String USER_ID_START_FLAG = "userId="; - private static final char USER_ID_END_FLAG = '&'; - private static final String LOGIN_TAKEN_ERROR ="Login is already taken."; - + private static class MockUserWithRoles { + MockUser user; + String role; - public MockAdmin(AbstractTest test, String username, String password, String userId) { - super(test, username, password, userId); - + public MockUserWithRoles(MockUser user, String roles) { + this.user = user; + this.role = roles; } + } - public String createCourse(String createCourseURL, String courseName){ - try{ - delay(); - WebResponse resp = (WebResponse)new Call(wc, test,"Creating Course:"+courseName,createCourseURL).execute(); - if(!checkPageContains(resp,COURSE_FORM_FLAG)){ - log.debug(resp.getText()); - throw new TestHarnessException(username+" did not get course creation page with the url:"+createCourseURL); - } - Map params = new HashMap(); - params.put(COURSE_NAME,courseName); - //fill the form and submit it and return the course id - resp = (WebResponse)new Call(wc, test,"Submit Course Creation Form",fillForm(resp,0,params)).execute(); - WebTable[] tables = resp.getTables(); - if((tables==null)||(tables.length==0)){ - log.debug(resp.getText()); - throw new TestHarnessException(username + " failed to get an course table after submitting course creation form"); - } - WebTable table = tables[0]; - String idAsString = null; - for (int i = table.getRowCount()-1; i >= 0; i--){ - if(table.getCellAsText(i,1).indexOf(courseName)!=-1){//found the organisation created just now - idAsString = table.getCellAsText(i,0); - break; - } - } - if(idAsString == null){ - log.debug(resp.getText()); - throw new TestHarnessException("Failed to get the course id for "+courseName); - } - log.info(username + " created course "+courseName+" and the id is "+idAsString); - return idAsString; - }catch(IOException e){ - throw new RuntimeException(e); - }catch(SAXException e){ - throw new RuntimeException(e); - } - } + private static final Logger log = Logger.getLogger(MockAdmin.class); + private static final String COURSE_FORM_FLAG = "OrganisationForm"; + private static final String COURSE_NAME = "name"; + private static final String COURSE_ID_PATTERN = "%orgId%"; + private static final String USER_FORM_FLAG = "UserForm"; + private static final String LOGIN = "login"; + private static final String PASSWORD = "password"; + private static final String PASSWORD2 = "password2"; + private static final String FIRST_NAME = "firstName"; + private static final String LAST_NAME = "lastName"; + private static final String EMAIL = "email"; + private static final String COMMON_LAST_NAME = "Testharness"; + private static final String ROLES = "roles"; + private static final String AUTHOR_ROLE = "3"; + private static final String MONITOR_ROLE = "4"; + private static final String LEARNER_ROLE = "5"; + private static final String USER_ID_START_FLAG = "userId="; + private static final char USER_ID_END_FLAG = '&'; - public void createUsers(String createUserURL, String courseId){ - try{ - String url = createUserURL.replace(COURSE_ID_PATTERN,courseId.toString()); - AuthorTest authorTest = test.getTestSuite().getAuthorTest(); - MonitorTest monitorTest = test.getTestSuite().getMonitorTest(); - LearnerTest learnerTest = test.getTestSuite().getLearnerTest(); - AbstractTest[] tests = new AbstractTest[]{authorTest, monitorTest, learnerTest}; - MockUserWithRoles[] users = getMockUsersWithRoles(tests); - - for(int i=0; i < users.length; i++){ - delay(); - - // create the user - String name = users[i].user.getUsername(); - log.info(username+" creating user "+name); - WebResponse resp = (WebResponse)new Call(wc, test, username + " creating user "+name,url).execute(); - if(!checkPageContains(resp,USER_FORM_FLAG)){ - log.debug(resp.getText()); - throw new TestHarnessException(username+" did not get user creation page with the url "+url); - } - Map params = new HashMap(); - params.put(LOGIN,name); - params.put(PASSWORD,name); - params.put(PASSWORD2,name); - params.put(FIRST_NAME,name); - params.put(LAST_NAME,COMMON_LAST_NAME); - params.put(EMAIL, name+"@"+COMMON_LAST_NAME+"."+COMMON_LAST_NAME.toLowerCase()); - resp = (WebResponse)new Call(wc, test, username + " submit user creation form",fillForm(resp,0,params)).execute(); + private static final String LOGIN_TAKEN_ERROR = "Login is already taken."; - // add the roles - if ( resp.getText().indexOf(LOGIN_TAKEN_ERROR)!=-1) { - throw new TestHarnessException("Login "+name+" already taken."); - } - - log.info(username+" adding roles to user "+name); - params = new HashMap(); - params.put(ROLES,users[i].roles); - resp = (WebResponse)new Call(wc, test, username + " submit user rolesform",fillForm(resp,0,params)).execute(); - WebTable[] tables = resp.getTables(); - if((tables==null)||(tables.length<2)){ - log.debug(resp.getText()); - throw new TestHarnessException(username + " failed to get an user table after submitting user role form"); - } - - WebTable table = tables[1]; - String idAsString = null; - for(int j = table.getRowCount()-1; j >= 0; j--){ - log.debug("1:"+table.getCellAsText(j,0)); - log.debug("4:"+table.getCellAsText(j,4)); - if(table.getCellAsText(j,0).indexOf(name)!=-1){ - TableCell cell = table.getTableCell(j,4); - WebLink link = cell.getLinks()[0]; - String cellText = link.getAttribute("href"); - int startIndex = cellText.indexOf(USER_ID_START_FLAG); - int endIndex = cellText.indexOf(USER_ID_END_FLAG,startIndex); - idAsString = cellText.substring(startIndex+USER_ID_START_FLAG.length(),endIndex); - break; - } - } - if(idAsString == null){ - log.debug(resp.getText()); - throw new TestHarnessException("Failed to get the user id for "+name); - } - log.info(username + " created user "+name+" and the id is "+idAsString); - users[i].user.setUserId(idAsString); - } - }catch(IOException e){ - throw new RuntimeException(e); - } catch (SAXException e) { - throw new RuntimeException(e); + public MockAdmin(AbstractTest test, String username, String password, String userId) { + super(test, username, password, userId); + } + + private static MockUserWithRoles[] getMockUsersWithRoles(AbstractTest[] tests) { + List users = new ArrayList(); + for (AbstractTest test : tests) { + if (test != null) { + MockUser[] mockUsers = test.getUsers(); + String role; + if (test instanceof AuthorTest) { + role = MockAdmin.AUTHOR_ROLE; + } else if (test instanceof MonitorTest) { + role = MockAdmin.MONITOR_ROLE; + } else { + role = MockAdmin.LEARNER_ROLE; } - } - - private int getUserAmount(AbstractTest[] tests){ - int amount = 0; - for(AbstractTest test: tests){ - amount += test==null? 0 : test.getUsers().length; + for (MockUser mockUser : mockUsers) { + users.add(new MockUserWithRoles(mockUser, role)); } - return amount; + } } - - private MockUserWithRoles[] getMockUsersWithRoles(AbstractTest[] tests){ - MockUserWithRoles[] users = new MockUserWithRoles[getUserAmount(tests)]; - int i = 0; - for(AbstractTest test: tests){ - if( test != null){ - MockUser[] mockUsers = test.getUsers(); - String[] roles; - if(test instanceof AuthorTest){ - roles = new String[]{AUTHOR_ROLE}; - }else if(test instanceof MonitorTest){ - roles = new String[]{MONITOR_ROLE}; - }else{ - roles = new String[]{LEARNER_ROLE}; - } - for(MockUser mockUser: mockUsers){ - users[i] = new MockUserWithRoles(mockUser,roles); - i++; - } - } + return users.toArray(new MockUserWithRoles[] {}); + } + + public String createCourse(String createCourseURL, String courseName) { + try { + delay(); + WebResponse resp = (WebResponse) new Call(wc, test, "Creating Course:" + courseName, createCourseURL) + .execute(); + if (!MockUser.checkPageContains(resp, MockAdmin.COURSE_FORM_FLAG)) { + MockAdmin.log.debug(resp.getText()); + throw new TestHarnessException(username + " did not get course creation page with the url:" + + createCourseURL); + } + Map params = new HashMap(); + params.put(MockAdmin.COURSE_NAME, courseName); + // fill the form and submit it and return the course id + resp = (WebResponse) new Call(wc, test, "Submit Course Creation Form", fillForm(resp, 0, params)).execute(); + WebTable[] tables = resp.getTables(); + if ((tables == null) || (tables.length == 0)) { + MockAdmin.log.debug(resp.getText()); + throw new TestHarnessException(username + + " failed to get an course table after submitting course creation form"); + } + WebTable table = tables[0]; + String idAsString = null; + for (int i = table.getRowCount() - 1; i >= 0; i--) { + if (table.getCellAsText(i, 1).indexOf(courseName) != -1) {// found the organisation created just now + idAsString = table.getCellAsText(i, 0); + break; } - return users; + } + if (idAsString == null) { + MockAdmin.log.debug(resp.getText()); + throw new TestHarnessException("Failed to get the course id for " + courseName); + } + MockAdmin.log.info(username + " created course " + courseName + " and the id is " + idAsString); + return idAsString; + } catch (IOException e) { + throw new RuntimeException(e); + } catch (SAXException e) { + throw new RuntimeException(e); } - - private static class MockUserWithRoles{ - MockUser user; - String[] roles; - - public MockUserWithRoles(MockUser user, String[] roles) { - this.user = user; - this.roles = roles; + } + + public void createUsers(String createUserURL, String courseId) { + try { + String url = createUserURL.replace(MockAdmin.COURSE_ID_PATTERN, courseId.toString()); + AuthorTest authorTest = test.getTestSuite().getAuthorTest(); + MonitorTest monitorTest = test.getTestSuite().getMonitorTest(); + LearnerTest learnerTest = test.getTestSuite().getLearnerTest(); + AbstractTest[] tests = new AbstractTest[] { authorTest, monitorTest, learnerTest }; + MockUserWithRoles[] mockUsers = MockAdmin.getMockUsersWithRoles(tests); + + for (MockUserWithRoles mockUser : mockUsers) { + delay(); + + // create the user + String name = mockUser.user.getUsername(); + MockAdmin.log.info(username + " creating user " + name); + WebResponse resp = (WebResponse) new Call(wc, test, username + " creating user " + name, url).execute(); + if (!MockUser.checkPageContains(resp, MockAdmin.USER_FORM_FLAG)) { + MockAdmin.log.debug(resp.getText()); + throw new TestHarnessException(username + " did not get user creation page with the url " + url); } + Map params = new HashMap(); + params.put(MockAdmin.LOGIN, name); + params.put(MockAdmin.PASSWORD, name); + params.put(MockAdmin.PASSWORD2, name); + params.put(MockAdmin.FIRST_NAME, name); + params.put(MockAdmin.LAST_NAME, MockAdmin.COMMON_LAST_NAME); + params.put(MockAdmin.EMAIL, + name + "@" + MockAdmin.COMMON_LAST_NAME + "." + MockAdmin.COMMON_LAST_NAME.toLowerCase()); + resp = (WebResponse) new Call(wc, test, username + " submit user creation form", fillForm(resp, 0, + params)).execute(); + + // add the roles + if (resp.getText().indexOf(MockAdmin.LOGIN_TAKEN_ERROR) != -1) { + log.warn("Login " + name + " already taken."); + continue; + } + + MockAdmin.log.info(username + " adding roles to user " + name); + params = new HashMap(); + params.put(MockAdmin.ROLES, new String[] { mockUser.role }); + resp = (WebResponse) new Call(wc, test, username + " submit user rolesform", fillForm(resp, 0, params)) + .execute(); + WebTable[] tables = resp.getTables(); + if ((tables == null) || (tables.length < 2)) { + MockAdmin.log.debug(resp.getText()); + throw new TestHarnessException(username + + " failed to get an user table after submitting user role form"); + } + + WebTable table = tables[1]; + String idAsString = null; + for (int j = table.getRowCount() - 1; j >= 0; j--) { + MockAdmin.log.debug("1:" + table.getCellAsText(j, 0)); + MockAdmin.log.debug("4:" + table.getCellAsText(j, 4)); + if (table.getCellAsText(j, 0).indexOf(name) != -1) { + TableCell cell = table.getTableCell(j, 4); + WebLink link = cell.getLinks()[0]; + String cellText = link.getAttribute("href"); + int startIndex = cellText.indexOf(MockAdmin.USER_ID_START_FLAG); + int endIndex = cellText.indexOf(MockAdmin.USER_ID_END_FLAG, startIndex); + idAsString = cellText.substring(startIndex + MockAdmin.USER_ID_START_FLAG.length(), endIndex); + break; + } + } + if (idAsString == null) { + MockAdmin.log.debug(resp.getText()); + throw new TestHarnessException("Failed to get the user id for " + name); + } + MockAdmin.log.info(username + " created user " + name + " and the id is " + idAsString); + mockUser.user.setUserId(idAsString); + } + } catch (IOException e) { + throw new RuntimeException(e); + } catch (SAXException e) { + throw new RuntimeException(e); } -} + } +} \ No newline at end of file Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/author/AuthorTest.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/author/AuthorTest.java (.../AuthorTest.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/author/AuthorTest.java (.../AuthorTest.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -25,23 +25,22 @@ import java.io.File; import org.lamsfoundation.testharness.AbstractTest; -import org.lamsfoundation.testharness.Call.CallType; /** * @version - * - *

- * View Source - *

- * + * + *

+ * View Source + *

+ * * @author Fei Yang */ public class AuthorTest extends AbstractTest { - + private String learningDesignUploadURL; - + private String learningDesignFile; - + private String ldId; /** @@ -55,55 +54,45 @@ * @param learningDesignFile * @param ldId */ - public AuthorTest(String testName, CallType callType, String rmiRegistryName, String webServiceAddress, Integer minDelay, Integer maxDelay, String learningDesignUploadURL, String learningDesignFile, String ldId) { - super(testName,callType,rmiRegistryName,webServiceAddress, minDelay, maxDelay); - this.learningDesignUploadURL = learningDesignUploadURL; - this.learningDesignFile = learningDesignFile; - this.ldId = ldId; + public AuthorTest(String testName, Integer minDelay, Integer maxDelay, String learningDesignUploadURL, + String learningDesignFile, String ldId) { + super(testName, minDelay, maxDelay); + this.learningDesignUploadURL = learningDesignUploadURL; + this.learningDesignFile = learningDesignFile; + this.ldId = ldId; } - @Override - protected void startWEB(){ - if(ldId==null){ - MockAuthor author = (MockAuthor) users[0]; - author.login(); - File file = new File(learningDesignFile); - ldId = author.importLearningDesign(learningDesignUploadURL,file); - } + public final String getLdId() { + return ldId; } - @Override - protected void startWS(){ - //TODO implement me - } + public final String getLearningDesignFile() { + return learningDesignFile; + } - @Override - protected void startRMI(){ - //TODO implement me - } + public final String getLearningDesignUploadURL() { + return learningDesignUploadURL; + } - public final String getLearningDesignFile() { - return learningDesignFile; - } + public final void setLdId(String ldId) { + this.ldId = ldId; + } - public final void setLearningDesignFile(String learningDesignFile) { - this.learningDesignFile = learningDesignFile; - } + public final void setLearningDesignFile(String learningDesignFile) { + this.learningDesignFile = learningDesignFile; + } - public final String getLearningDesignUploadURL() { - return learningDesignUploadURL; - } + public final void setLearningDesignUploadURL(String learningDesignUploadURL) { + this.learningDesignUploadURL = learningDesignUploadURL; + } - public final void setLearningDesignUploadURL(String learningDesignUploadURL) { - this.learningDesignUploadURL = learningDesignUploadURL; + @Override + protected void startTest() { + if (ldId == null) { + MockAuthor author = (MockAuthor) users[0]; + author.login(); + File file = new File(learningDesignFile); + ldId = author.importLearningDesign(learningDesignUploadURL, file); } - - public final String getLdId() { - return ldId; - } - - public final void setLdId(String ldId) { - this.ldId = ldId; - } - -} + } +} \ No newline at end of file Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/author/MockAuthor.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/author/MockAuthor.java (.../MockAuthor.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/author/MockAuthor.java (.../MockAuthor.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -37,60 +37,63 @@ /** * @version - * - *

- * View Source - *

- * + * + *

+ * View Source + *

+ * * @author Fei Yang */ public class MockAuthor extends MockUser { - - private static final Logger log = Logger.getLogger(MockAuthor.class); - - public static final String DEFAULT_NAME = "Author"; - - private static final String IMPORT_FORM_FLAG = "UPLOAD_FILE"; - private static final String UPLOAD_FILE_PARAM = "UPLOAD_FILE"; - private static final String IMPORT_SUCCESS_FLAG = "movie"; - private static final String LD_START_TAG = "learningDesignID="; - private static final char LD_END_TAG = '&'; - /** - * MockAuthor Constructor - * - * @param - */ - public MockAuthor(AuthorTest test, String username, String password, String userId) { - super(test, username, password, userId); - } + private static final Logger log = Logger.getLogger(MockAuthor.class); - public String importLearningDesign(String learningDesignUploadURL, File file){ - try{ - delay(); - WebResponse resp = (WebResponse)new Call(wc, test,"Import Learning Design", learningDesignUploadURL).execute(); - if(!checkPageContains(resp,IMPORT_FORM_FLAG)){ - log.debug(resp.getText()); - throw new TestHarnessException(username+" did not get learning design import page with the url:"+learningDesignUploadURL); - } - Map params = new HashMap(); - params.put(UPLOAD_FILE_PARAM,file); - resp = (WebResponse)new Call(wc, test,"Submit Learning Design Import Form", fillForm(resp,0,params)).execute(); - if(!checkPageContains(resp,IMPORT_SUCCESS_FLAG)){ - log.debug(resp.getText()); - throw new TestHarnessException(username+" failed to upload file:"+file.getAbsolutePath()); - } - String text = resp.getText(); - int startIndex = text.indexOf(LD_START_TAG); - int endIndex = text.indexOf(LD_END_TAG,startIndex); - String idAsString = text.substring(startIndex+LD_START_TAG.length(),endIndex); - log.info(username + " imported learning design " + file.getName()+" and the id is " + idAsString); - return idAsString; - }catch(IOException e){ - throw new RuntimeException(e); - } catch (SAXException e) { - throw new RuntimeException(e); - } - } + public static final String DEFAULT_NAME = "Author"; -} + private static final String IMPORT_FORM_FLAG = "UPLOAD_FILE"; + private static final String UPLOAD_FILE_PARAM = "UPLOAD_FILE"; + private static final String IMPORT_SUCCESS_FLAG = "movie"; + private static final String LD_START_TAG = "learningDesignID="; + private static final char LD_END_TAG = '&'; + + /** + * MockAuthor Constructor + * + * @param + */ + public MockAuthor(AuthorTest test, String username, String password, String userId) { + super(test, username, password, userId); + } + + public String importLearningDesign(String learningDesignUploadURL, File file) { + try { + delay(); + WebResponse resp = (WebResponse) new Call(wc, test, "Import Learning Design", learningDesignUploadURL) + .execute(); + if (!MockUser.checkPageContains(resp, MockAuthor.IMPORT_FORM_FLAG)) { + MockAuthor.log.debug(resp.getText()); + throw new TestHarnessException(username + " did not get learning design import page with the url:" + + learningDesignUploadURL); + } + Map params = new HashMap(); + params.put(MockAuthor.UPLOAD_FILE_PARAM, file); + resp = (WebResponse) new Call(wc, test, "Submit Learning Design Import Form", fillForm(resp, 0, params)) + .execute(); + if (!MockUser.checkPageContains(resp, MockAuthor.IMPORT_SUCCESS_FLAG)) { + MockAuthor.log.debug(resp.getText()); + throw new TestHarnessException(username + " failed to upload file:" + file.getAbsolutePath()); + } + String text = resp.getText(); + int startIndex = text.indexOf(MockAuthor.LD_START_TAG); + int endIndex = text.indexOf(MockAuthor.LD_END_TAG, startIndex); + String idAsString = text.substring(startIndex + MockAuthor.LD_START_TAG.length(), endIndex); + MockAuthor.log.info(username + " imported learning design " + file.getName() + " and the id is " + + idAsString); + return idAsString; + } catch (IOException e) { + throw new RuntimeException(e); + } catch (SAXException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file Index: TestHarness4LAMS2/src/org/lamsfoundation/testharness/learner/LearnerTest.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r41955af92f3e17f2f11c07d94ae1a5f92b0d998f --- TestHarness4LAMS2/src/org/lamsfoundation/testharness/learner/LearnerTest.java (.../LearnerTest.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ TestHarness4LAMS2/src/org/lamsfoundation/testharness/learner/LearnerTest.java (.../LearnerTest.java) (revision 41955af92f3e17f2f11c07d94ae1a5f92b0d998f) @@ -26,115 +26,108 @@ import org.apache.log4j.Logger; import org.lamsfoundation.testharness.AbstractTest; -import org.lamsfoundation.testharness.Call.CallType; /** * @version - * - *

- * View Source - *

- * + * + *

+ * View Source + *

+ * * @author Fei Yang */ public class LearnerTest extends AbstractTest { - - private static final Logger log = Logger.getLogger(LearnerTest.class); + private static final Logger log = Logger.getLogger(LearnerTest.class); + protected String getLessonURL; protected String getLearningDesignURL; protected String joinLessonURL; protected String getFlashProgressDataURL; protected String lessonEntryURL; protected String[] filesToUpload; - protected String subContextRoot; // usually "/learning/", this is set to figure out passon.swf url + protected String subContextRoot; // usually "/learning/", this is set to figure out passon.swf url protected CountDownLatch allDoneSignal; - + /** * LearnerTest Constructor - * + * */ - public LearnerTest(String testName, CallType callType, String rmiRegistryName, String webServiceAddress, Integer minDelay, Integer maxDelay, String getLessonURL, String getLearningDesignURL, String joinLessonURL, String getFlashProgressDataURL, String lessonEntryURL, String[] filesToUpload) { - super(testName,callType,rmiRegistryName,webServiceAddress, minDelay, maxDelay); - this.getLessonURL = getLessonURL; - this.getLearningDesignURL = getLearningDesignURL; - this.joinLessonURL = joinLessonURL; - this.getFlashProgressDataURL = getFlashProgressDataURL; - this.lessonEntryURL = lessonEntryURL; - this.subContextRoot = '/'+ getLessonURL.split("/")[1] + '/'; - this.filesToUpload = filesToUpload; + public LearnerTest(String testName, + Integer minDelay, Integer maxDelay, String getLessonURL, String getLearningDesignURL, String joinLessonURL, + String getFlashProgressDataURL, String lessonEntryURL, String[] filesToUpload) { + super(testName, minDelay, maxDelay); + this.getLessonURL = getLessonURL; + this.getLearningDesignURL = getLearningDesignURL; + this.joinLessonURL = joinLessonURL; + this.getFlashProgressDataURL = getFlashProgressDataURL; + this.lessonEntryURL = lessonEntryURL; + this.subContextRoot = '/' + getLessonURL.split("/")[1] + '/'; + this.filesToUpload = filesToUpload; } - @Override - protected void startWEB(){ - log.info(users.length+(users.length==1? " learner begins studying..." : " learners begin studying...")); - allDoneSignal = new CountDownLatch(users.length); - for(int i=0; i - *
  • fetch entry url
  • - *
  • get passon.swf url and the next activity url
  • - *
  • fetch the next activity url and get activity page with form
  • - *
  • fill the form and submit it - *
  • - *
  • repeat step 2-4 until lesson completed or error happened
  • - * - * - * Note: httpunit will automatically redirect url if there is a redirect http header in response. In this case, the - * redirect url won't be recorded in access log or testharness log. - * - * @param lessonEntryURL - * @param lsId - * @return void - * @throws IOException - * @throws SAXException - */ - private void progressThroughActivities(String lessonEntryURL, String lsId) throws SAXException, IOException { - delay(); - WebResponse resp = (WebResponse) new Call(wc, test, username + " enters lesson", lessonEntryURL.replace( - MockLearner.LESSON_ID_PATTERN, lsId)).execute(); - String nextURL = parseOutNextURL(resp); - boolean lessonFinished = false; - while (!lessonFinished) { - if (nextURL != null) { - resp = takeActivity(nextURL); - nextURL = parseOutNextURL(resp); - } else { - if (isOptionalActivity(resp)) { - resp = handleActivity(resp); - nextURL = parseOutNextURL(resp); + private String[] chooseArbitraryValues(String[] values) { + int length = 1; // + TestUtil.generateRandomIndex(values.length); + String[] answers = new String[length]; + for (int i = 0; i < length; i++) { + answers[i] = values[TestUtil.generateRandomNumber(values.length)]; + } + return answers; + } + + private String composeArbitraryText() { + int length = 1 + TestUtil.generateRandomNumber(MockLearner.ARBITRARY_TEXT_ALPHABET.length()); + StringBuilder text = new StringBuilder(length); + for (int i = 0; i < length; i++) { + text.append(MockLearner.ARBITRARY_TEXT_ALPHABET.charAt(TestUtil + .generateRandomNumber(MockLearner.ARBITRARY_TEXT_ALPHABET.length()))); + } + return text.toString(); + } + + private WebForm fillFormArbitrarily(WebForm form) throws IOException, SAXException { + String[] params = form.getParameterNames(); + if ((params != null) && (params.length > 0)) { + for (String param : params) { + if (!form.isDisabledParameter(param) && !form.isHiddenParameter(param) + && !form.isReadOnlyParameter(param)) { + if (form.isTextParameter(param)) { + String text = composeArbitraryText(); + form.setParameter(param, text); + MockLearner.log.debug(username + " input " + text + " for form field " + param); + } else if (form.isFileParameter(param)) { + File file = selectArbitraryFile(((LearnerTest) test).getFilesToUpload()); + form.setParameter(param, file); + MockLearner.log.debug(username + " uploaded file " + file.getName() + " for form field " + + param); + } else if (form.isMultiValuedParameter(param)) { + String[] values = chooseArbitraryValues(form.getOptionValues(param)); + form.setParameter(param, values); + MockLearner.log.debug(username + " set " + values.length + " value(s) for form field " + param); + MockLearner.log.debug(values); + } else { + MockLearner.log.debug(param + " may be a radio button. Current value is " + + form.getParameterValue(param)); + if (form.getParameterValue(param) == null) { + String[] candidateValues = form.getOptionValues(param); + if ((candidateValues != null) && (candidateValues.length > 0)) { + String value = candidateValues[TestUtil.generateRandomNumber(candidateValues.length)]; + MockLearner.log.debug("Setting param to " + value); + form.setParameter(param, value); + } + } + } } else { - lessonFinished = true; + MockLearner.log.debug("disabled or hidden or readonly parameter " + param); } } + } + Map> buttonGroups = groupButtonsByName(form.getButtons(), FormControl.RADIO_BUTTON_TYPE); + for (Map.Entry> entry : buttonGroups.entrySet()) { + entry.getValue().get(TestUtil.generateRandomNumber(entry.getValue().size())).click(); + MockLearner.log.debug(username + " clicked a radio button " + entry.getKey()); } + return form; } - private boolean isOptionalActivity(WebResponse resp) throws IOException { - return resp.getText().indexOf(MockLearner.OPTIONAL_ACTIVITY_FLAG) != -1; + private WebResponse findAnAbsoluteURLOnPage(String respAsText) throws SAXException, IOException { + // Probably safest to get the last http address on the page, make sure we don't accidently + // go to http://www.w3c.org/ + int index = respAsText.lastIndexOf("\"http"); + while (index != -1) { + int indexEnd = respAsText.indexOf("\"", index + 1); + if (indexEnd != -1) { + String httpString = respAsText.substring(index + 1, indexEnd); + if ((httpString.indexOf("www.w3.org") == -1) && !httpString.endsWith(".js") + && !httpString.endsWith(".css")) { + MockLearner.log.debug("Forwarding user " + username + " to discovered link " + httpString); + return (WebResponse) new Call(wc, test, "", httpString).execute(); + } + } + index = index > 0 ? respAsText.lastIndexOf("\"http", index - 1) : -1; + } + throw new TestHarnessException("Unable to find a link to go to on page" + respAsText); } - /** - * Retrieve the toolURL and play with it - * - * @param toolURL - * @return WebResponse - */ - private WebResponse takeActivity(String toolURL) { - try { - WebResponse resp = (WebResponse) new Call(wc, test, "", toolURL).execute(); - delay(); - return handleActivity(resp); - } catch (Exception e) { - throw new TestHarnessException(e.getMessage(), e); + private String findURLInAHREF(WebResponse resp, String linkSubstring) throws SAXException { + WebLink[] links = resp.getLinks(); + if (links != null) { + for (WebLink link : links) { + MockLearner.log.debug("Checking link " + link.getURLString()); + if (link.getURLString().indexOf(linkSubstring) != -1) { + return link.getURLString(); + } + } } + return null; } + private String findURLInLocationHref(WebResponse resp, String linkSubstring) throws SAXException, IOException { + String respAsText = resp.getText(); + String lowercaseRespAsText = respAsText.toLowerCase(); + int stringLength = lowercaseRespAsText.length(); + + int index = lowercaseRespAsText.indexOf("location.href"); + while (index != -1) { + index++; + while ((index < stringLength) + && !((lowercaseRespAsText.charAt(index) == '\'') || (lowercaseRespAsText.charAt(index) == '\"'))) { + index++; + } + if (index < (stringLength - 1)) { + char quote = lowercaseRespAsText.charAt(index); + int indexEnd = lowercaseRespAsText.indexOf(quote, index + 1); + String httpString = respAsText.substring(index + 1, indexEnd); + MockLearner.log.debug("Discovered link " + httpString); + if (httpString.indexOf(linkSubstring) != -1) { + MockLearner.log.debug("Matched to " + linkSubstring); + return httpString; + } + } + MockLearner.log.debug("Index was " + index); + index = (index < stringLength) && (index > 0) ? lowercaseRespAsText.indexOf("location.href", index + 1) + : -1; + MockLearner.log.debug("New index is " + index); + } + return null; + } + + private void getFlashProgessData(String getFlashProgressDataURL, String lsId) { + delay(); + String url = getFlashProgressDataURL.replace(MockLearner.LESSON_ID_PATTERN, lsId); + new Call(wc, test, username + " get flash progress data", url).execute(); + } + + private void getLearningDesign(String getLearningDesignURL, String ldId) { + delay(); + String url = getLearningDesignURL.replace(MockLearner.LD_ID_PATTERN, ldId); + new Call(wc, test, username + " get learning design", url).execute(); + } + + @SuppressWarnings("rawtypes") + private String getLesson(String getLessonURL, String lsId) throws WddxDeserializationException, IOException { + delay(); + String url = getLessonURL.replace(MockLearner.LESSON_ID_PATTERN, lsId); + WebResponse resp = (WebResponse) new Call(wc, test, username + " get lesson", url).execute(); + Hashtable hashtable = (Hashtable) TestUtil.deserialize(resp.getText()); + hashtable = (Hashtable) hashtable.get(MockLearner.MESSAGE_VALUE_KEY); + return new Integer(((Double) hashtable.get(MockLearner.LD_ID_KEY)).intValue()).toString(); + } + + private Map> groupButtonsByName(Button[] btns, String buttonType) { + MockLearner.log.debug(btns.length); + Map> buttonGroups = new HashMap>(); + if (btns != null) { + for (Button btn : btns) { + if (buttonType.equals(btn.getType())) { + String name = btn.getName(); + MockLearner.log.debug("Got " + buttonType + " " + name + " and its value is " + btn.getValue()); + if (!buttonGroups.containsKey(name)) { + buttonGroups.get(name).add(btn); + } else { + List