/**************************************************************** * 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.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; import com.meterware.httpunit.SubmitButton; import com.meterware.httpunit.WebConversation; import com.meterware.httpunit.WebForm; import com.meterware.httpunit.WebRequest; import com.meterware.httpunit.WebResponse; /** * @version * *

* View Source *

* * @author Fei Yang */ public class Call { private static final Logger log = Logger.getLogger(Call.class); private static final String HTTP = "http://"; private static final String GET = "GET "; private static final String POST = "POST "; private static final char COLON = ':'; private static final char SPACE = ' '; private static final String NON_HTTP_ERROR = "Check the log for the error message"; private WebConversation wc; // for WEB private AbstractTest test; private String description; @SuppressWarnings("unused") private String method; // for RMI and WS @SuppressWarnings("unused") private Map parameters; // for RMI or WS 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) { this.wc = wc; this.test = test; this.description = description; this.form = form; } 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; this.test = test; this.description = description; this.url = url; this.is = is; this.contentType = contentType; } public Call(WebConversation wc, AbstractTest test, String description, String url) { this.wc = wc; this.test = test; this.description = description; this.url = url; } public AbstractTest getTest() { return test; } /** * 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; long start = 0; long end = 0; try { WebResponse resp = null; if (form != null) { SubmitButton[] submitButtons = filterCancelButton(form.getSubmitButtons()); Call.log.debug(submitButtons.length + " non-cancel submit button(s) in the form"); WebRequest req = null; if (submitButtons.length <= 1) { req = form.getRequest(); } else { req = form.getRequest(submitButtons[TestUtil.generateRandomIndex(submitButtons.length)]); } callee = form.getMethod().toUpperCase() + Call.SPACE + form.getAction(); Call.log.debug(callee); start = System.currentTimeMillis(); resp = wc.getResponse(req); end = System.currentTimeMillis(); } else { String absoluteURL = getAbsoluteURL(url); WebRequest req; if (is == null) { callee = Call.GET + url; req = new GetMethodWebRequest(absoluteURL); } else { callee = Call.POST + url; req = new PostMethodWebRequest(absoluteURL, is, contentType); } Call.log.debug(callee); start = System.currentTimeMillis(); resp = wc.getResponse(req); end = System.currentTimeMillis(); } httpStatusCode = resp.getResponseCode(); message = resp.getResponseMessage(); /*if(callee.indexOf("passon.swf")==-1) log.debug(resp.getText());*/ if (resp.getResponseCode() >= 400) { Call.log.debug(resp.getText()); 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) { String cookieValue = headerFieldSplit[1]; Call.log.debug("Manually setting cookie: " + cookieName + "=" + cookieValue); wc.putCookie(cookieName, cookieValue); } } } } return resp; } catch (IOException e) { message = Call.NON_HTTP_ERROR; Call.log.debug(e.getMessage(), 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)); } } private SubmitButton[] filterCancelButton(SubmitButton[] sbmtBtns) { boolean found = false; int i = 0; for (; i < sbmtBtns.length; i++) { if (isCancelButton(sbmtBtns[i])) { found = true; break; } } if (found) { SubmitButton[] btns = new SubmitButton[sbmtBtns.length - 1]; int j = 0; for (int k = 0; k < sbmtBtns.length; k++) { if (k != i) { btns[j] = sbmtBtns[k]; j++; } } return btns; } else { return sbmtBtns; } } 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)) { 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() + context + withSlash; } else { return Call.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"; } } } }