package com.intuit.tank.transform.scriptGenerator; /* * #%L * Common * %% * Copyright (C) 2011 - 2015 Intuit Inc. * %% * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * #L% */ import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import org.apache.commons.lang3.math.NumberUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.intuit.tank.harness.data.AssignmentData; import com.intuit.tank.harness.data.AuthenticationStep; import com.intuit.tank.harness.data.ClearCookiesStep; import com.intuit.tank.harness.data.CookieStep; import com.intuit.tank.harness.data.HDRequest; import com.intuit.tank.harness.data.HDResponse; import com.intuit.tank.harness.data.HDScript; import com.intuit.tank.harness.data.HDScriptGroup; import com.intuit.tank.harness.data.HDScriptUseCase; import com.intuit.tank.harness.data.HDTestPlan; import com.intuit.tank.harness.data.HDTestVariables; import com.intuit.tank.harness.data.HDWorkload; import com.intuit.tank.harness.data.Header; import com.intuit.tank.harness.data.LogicStep; import com.intuit.tank.harness.data.RequestStep; import com.intuit.tank.harness.data.ResponseData; import com.intuit.tank.harness.data.SleepTimeStep; import com.intuit.tank.harness.data.TestStep; import com.intuit.tank.harness.data.ThinkTimeStep; import com.intuit.tank.harness.data.TimerStep; import com.intuit.tank.harness.data.ValidationData; import com.intuit.tank.harness.data.VariableStep; import com.intuit.tank.http.AuthScheme; import com.intuit.tank.project.BaseJob; import com.intuit.tank.project.RequestData; import com.intuit.tank.project.Script; import com.intuit.tank.project.ScriptGroup; import com.intuit.tank.project.ScriptGroupStep; import com.intuit.tank.project.ScriptStep; import com.intuit.tank.project.TestPlan; import com.intuit.tank.project.Workload; import com.intuit.tank.script.RequestDataType; import com.intuit.tank.script.ScriptConstants; import com.intuit.tank.script.TimerAction; import com.intuit.tank.vm.api.enumerated.ValidationType; import com.intuit.tank.vm.settings.TankConfig; public class ConverterUtil { private static final Logger LOG = LogManager.getLogger(ConverterUtil.class); public static HDWorkload convertScriptToHdWorkload(Script script) { String name = "TestPlan for " + script.getName(); name += " (id_" + script.getId() + ")"; HDWorkload hdWorkload = new HDWorkload(); hdWorkload.setTankHttpClientClass(new TankConfig().getAgentConfig().getTankClientClassDefault()); hdWorkload.setDescription(name); hdWorkload.setName(name); HDTestPlan tp = new HDTestPlan(); hdWorkload.getPlans().add(tp); tp.setTestPlanName("Main"); tp.setUserPercentage(100); HDScriptGroup hdScriptGroup = new HDScriptGroup(); tp.getGroup().add(hdScriptGroup); hdScriptGroup.setLoop(1); hdScriptGroup.setName("Group-1"); hdScriptGroup.setDescription("autoGen"); HDScript testGroup = new HDScript(); hdScriptGroup.getGroupSteps().add(testGroup); testGroup.setName(script.getName()); testGroup.setLoop(1); testGroup.getUseCase().addAll(convertScript(script.getScriptSteps(), new StepCounter())); return hdWorkload; } public static HDWorkload convertWorkload(Workload workload, BaseJob job) { String name = "TestPlan for " + workload.getProject() != null ? " project " + workload.getProject().getName() : " workload " + workload.getName(); int id = workload.getProject() != null ? workload.getProject().getId() : workload.getId(); name += " (id" + id + ")"; HDWorkload hdWorkload = new HDWorkload(); hdWorkload.setTankHttpClientClass(job.getTankClientClass() != null ? job.getTankClientClass() : new TankConfig().getAgentConfig().getTankClientClassDefault()); hdWorkload.setDescription(name); hdWorkload.setName(name); hdWorkload.setVariables(new HDTestVariables(job.isAllowOverride(), job.getVariables())); for (TestPlan plan : workload.getTestPlans()) { HDTestPlan tp = new HDTestPlan(); tp.setTestPlanName(plan.getName()); tp.setUserPercentage(plan.getUserPercentage()); tp.getGroup().addAll(convertScriptGroups(plan.getScriptGroups(), new StepCounter())); hdWorkload.getPlans().add(tp); } return hdWorkload; } public static String getWorkloadXML(HDWorkload hdWorkload) { StringWriter sw; try { JAXBContext context = JAXBContext.newInstance(HDWorkload.class.getPackage().getName()); Marshaller createMarshaller = context.createMarshaller(); createMarshaller.setProperty("jaxb.formatted.output", Boolean.TRUE); sw = new StringWriter(); createMarshaller.marshal(hdWorkload, sw); sw.flush(); sw.close(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } return sw.toString(); } private static List<HDScriptGroup> convertScriptGroups(List<ScriptGroup> scriptGroups, StepCounter sc) { List<HDScriptGroup> hdScriptGroups = new ArrayList<HDScriptGroup>(); for (ScriptGroup scriptGroup : scriptGroups) { hdScriptGroups.add(convertScriptGroup(scriptGroup, sc)); } return hdScriptGroups; } private static HDScriptGroup convertScriptGroup(ScriptGroup scriptGroup, StepCounter sc) { HDScriptGroup hdScriptGroup = new HDScriptGroup(); hdScriptGroup.setName(scriptGroup.getName()); hdScriptGroup.setDescription(scriptGroup.getName()); hdScriptGroup.setLoop(scriptGroup.getLoop()); hdScriptGroup.getGroupSteps().addAll(convertScriptGroupSteps(scriptGroup.getScriptGroupSteps(), sc)); return hdScriptGroup; } private static List<HDScript> convertScriptGroupSteps(List<ScriptGroupStep> sgs, StepCounter sc) { List<HDScript> testGroupList = new ArrayList<HDScript>(); for (ScriptGroupStep scriptGroupStep : sgs) { testGroupList.add(convertScriptGroupStep(scriptGroupStep, sc)); } return testGroupList; } private static HDScript convertScriptGroupStep(ScriptGroupStep sgs, StepCounter sc) { HDScript testGroup = new HDScript(); testGroup.setName(sgs.getScript().getName()); testGroup.setLoop(sgs.getLoop()); Script script = sgs.getScript(); List<ScriptStep> steps = script.getScriptSteps(); testGroup.getUseCase().addAll(convertScript(steps, sc)); return testGroup; } private static List<HDScriptUseCase> convertScript(List<ScriptStep> scriptSteps, StepCounter sc) { List<HDScriptUseCase> useCaseList = new ArrayList<HDScriptUseCase>(); String currentGroup = null; HDScriptUseCase useCase = null; for (ScriptStep scriptStep : scriptSteps) { String group = scriptStep.getScriptGroupName(); if (group == null || group.length() == 0) { // test step has not group name, so generate one: group = "Group " + scriptStep.getStepIndex(); } if (!group.equals(currentGroup)) { useCaseList.add(useCase); useCase = new HDScriptUseCase(); currentGroup = group; } useCase.getScriptSteps().add(convertScriptStep(scriptStep, sc.getNextStepIndex())); } if (useCase != null) { useCaseList.add(useCase); } return useCaseList; } private static TestStep convertScriptStep(ScriptStep scriptStep, int stepIndex) { TestStep testStep = null; if (ScriptConstants.SLEEP.equals(scriptStep.getType())) { testStep = convertSleepStep(scriptStep); } else if (ScriptConstants.THINK_TIME.equals(scriptStep.getType())) { testStep = convertThinkStep(scriptStep); } else if (ScriptConstants.VARIABLE.equals(scriptStep.getType())) { testStep = convertVariableStep(scriptStep); } else if (ScriptConstants.AUTHENTICATION.equals(scriptStep.getType())) { testStep = convertAuthenticationStep(scriptStep); } else if (ScriptConstants.COOKIE.equals(scriptStep.getType())) { testStep = convertCookieStep(scriptStep); } else if (ScriptConstants.LOGIC.equals(scriptStep.getType())) { testStep = convertLogicStep(scriptStep); } else if (ScriptConstants.REQUEST.equals(scriptStep.getType())) { testStep = convertRequestStep(scriptStep); } else if (ScriptConstants.CLEAR.equals(scriptStep.getType())) { testStep = convertClearStep(scriptStep); } else if (ScriptConstants.TIMER.equals(scriptStep.getType())) { testStep = convertTimerStep(scriptStep); } testStep.setStepIndex(stepIndex); return testStep; } private static TestStep convertSleepStep(ScriptStep scriptStep) { SleepTimeStep sts = new SleepTimeStep(); Set<RequestData> data = scriptStep.getData(); for (RequestData requestData : data) { if (ScriptConstants.TIME.equals(requestData.getKey())) { sts.setValue(requestData.getValue()); break; } } return sts; } private static TestStep convertLogicStep(ScriptStep scriptStep) { LogicStep sts = new LogicStep(); sts.setName(scriptStep.getName()); sts.setScriptGroupName(scriptStep.getScriptGroupName()); Set<RequestData> data = scriptStep.getData(); for (RequestData requestData : data) { if (ScriptConstants.SCRIPT.equals(requestData.getKey())) { sts.setScript(requestData.getValue()); break; } } return sts; } private static TestStep convertCookieStep(ScriptStep scriptStep) { CookieStep sts = new CookieStep(); Set<RequestData> data = scriptStep.getData(); for (RequestData requestData : data) { if (ScriptConstants.COOKIE_NAME.equals(requestData.getKey())) { sts.setCookieName(requestData.getValue()); } if (ScriptConstants.COOKIE_VALUE.equals(requestData.getKey())) { sts.setCookieValue(requestData.getValue()); } if (ScriptConstants.COOKIE_DOMAIN.equals(requestData.getKey())) { sts.setCookieDomain(requestData.getValue()); } if (ScriptConstants.COOKIE_PATH.equals(requestData.getKey())) { sts.setCookiePath(requestData.getValue()); } } return sts; } private static TestStep convertClearStep(ScriptStep scriptStep) { ClearCookiesStep sts = new ClearCookiesStep(); // Set<RequestData> data = scriptStep.getData(); // for (RequestData requestData : data) { // if (ScriptConstants.TIME.equals(requestData.getKey())) { // sts.setValue(requestData.getValue()); // break; // } // } return sts; } private static TestStep convertTimerStep(ScriptStep scriptStep) { TimerStep sts = new TimerStep(); Set<RequestData> data = scriptStep.getData(); for (RequestData requestData : data) { if (ScriptConstants.LOGGING_KEY.equals(requestData.getKey())) { sts.setValue(requestData.getValue()); } else if (ScriptConstants.IS_START.equals(requestData.getKey())) { TimerAction action = TimerAction.valueOf(requestData.getValue()); sts.setStart(action == TimerAction.START); } } return sts; } private static TestStep convertRequestStep(ScriptStep scriptStep) { RequestStep rs = new RequestStep(); rs.setName(scriptStep.getName() + " (" + scriptStep.getStepIndex() + ")"); rs.setScriptGroupName(scriptStep.getScriptGroupName()); rs.setOnFail(scriptStep.getOnFail()); HDRequest hdRequest = new HDRequest(); hdRequest.setMethod(scriptStep.getMethod()); hdRequest.setReqFormat(scriptStep.getReqFormat()); hdRequest.setLoggingKey(scriptStep.getLoggingKey()); hdRequest.setPath(scriptStep.getSimplePath()); hdRequest.setProtocol(scriptStep.getProtocol()); hdRequest.setPayload(scriptStep.getPayload()); hdRequest.setLabel(scriptStep.getLabel()); String host = extractHost(scriptStep.getHostname()); String port = extractPort(scriptStep.getHostname()); hdRequest.setHost(host); hdRequest.setPort(port); hdRequest.setPostDatas(getPostData(scriptStep.getPostDatas())); hdRequest.setQueryString(getPostData(scriptStep.getQueryStrings())); hdRequest.setRequestHeaders(getRequestHeaders(scriptStep.getRequestheaders(), scriptStep.getRequestCookies())); HDResponse hdResponse = new HDResponse(scriptStep.getRespFormat()); hdResponse.getAssignment().getHeaderVariable() .addAll(getAssignments(RequestDataType.headerAssignment, scriptStep.getResponseData())); hdResponse.getAssignment().getCookieVariable() .addAll(getAssignments(RequestDataType.cookieAssignment, scriptStep.getResponseData())); hdResponse.getAssignment().getBodyVariable() .addAll(getAssignments(RequestDataType.bodyAssignment, scriptStep.getResponseData())); hdResponse.getValidation().getHeaderValidation() .addAll(getValidations(RequestDataType.headerValidation, scriptStep.getResponseData())); hdResponse.getValidation().getCookieValidation() .addAll(getValidations(RequestDataType.cookieValidation, scriptStep.getResponseData())); hdResponse.getValidation().getBodyValidation() .addAll(getValidations(RequestDataType.bodyValidation, scriptStep.getResponseData())); rs.setRequest(hdRequest); rs.setResponse(hdResponse); return rs; } /** * @param hostname * @return */ protected static String extractPort(String hostname) { int index = hostname.lastIndexOf(':'); String port = null; if (index != -1 && index + 1 < hostname.length()) { String candidate = hostname.substring(index + 1); if (NumberUtils.isDigits(candidate)) { port = candidate; } } return port; } /** * @param hostname * @return */ protected static String extractHost(String hostname) { int index = hostname.lastIndexOf(':'); if (index != -1) { try { String port = hostname.substring(index + 1); if (NumberUtils.isDigits(port)) { hostname = hostname.substring(0, index); } } catch (Exception e) { LOG.error("Error parsing host"); } } return hostname; } private static Collection<? extends AssignmentData> getAssignments(RequestDataType type, Set<RequestData> requestDatas) { List<AssignmentData> assignmentDataList = new ArrayList<AssignmentData>(); for (RequestData requestData : requestDatas) { if (isAssignment(requestData)) { if (type.name().equals(requestData.getType()) || (type == RequestDataType.bodyAssignment && requestData.getType().equals("responseData"))) { AssignmentData ad = new AssignmentData(); ad.setKey(requestData.getKey()); if (requestData.getValue().length() > 1 && requestData.getValue().startsWith("==")) { ad.setValue(requestData.getValue().substring(2)); } else { ad.setValue(requestData.getValue().substring(1)); } ad.setPhase(requestData.getPhase()); assignmentDataList.add(ad); } } } return assignmentDataList; } /** * @param value * @return */ public static boolean isAssignment(RequestData data) { if (data.getType().equals(RequestDataType.bodyAssignment.name()) || data.getType().equals(RequestDataType.cookieAssignment.name()) || data.getType().equals(RequestDataType.headerAssignment.name()) || (data.getType().equals("responseData") && data.getValue() != null && data.getValue().startsWith("=") && !data.getValue().startsWith("=="))) { return true; } return false; } private static Collection<? extends ValidationData> getValidations(RequestDataType type, Set<RequestData> requestDatas) { List<ValidationData> validationDataList = new ArrayList<ValidationData>(); for (RequestData requestData : requestDatas) { if (!isAssignment(requestData)) { if (type.name().equals(requestData.getType()) || (type == RequestDataType.bodyValidation && requestData.getType().equals("responseData"))) { ValidationData ad = new ValidationData(); ad.setKey(requestData.getKey()); ValidationType validationType = ValidationType.getValidationType(requestData.getValue()); ad.setCondition(validationType.getValue()); ad.setValue(stripValidationType(requestData.getValue(), validationType)); ad.setPhase(requestData.getPhase()); validationDataList.add(ad); } } } return validationDataList; } /** * @param value * @param validationType * @return */ private static String stripValidationType(String value, ValidationType validationType) { if (value.startsWith(validationType.getValue())) { return value.substring(validationType.getValue().length()); } return value; } private static TestStep convertVariableStep(ScriptStep scriptStep) { Set<RequestData> data = scriptStep.getData(); VariableStep vs = new VariableStep(); for (RequestData requestData : data) { vs.setKey(requestData.getKey()); vs.setValue(requestData.getValue()); break; } return vs; } private static TestStep convertAuthenticationStep(ScriptStep scriptStep) { Set<RequestData> data = scriptStep.getData(); AuthenticationStep as = new AuthenticationStep(); for (RequestData requestData : data) { if (ScriptConstants.AUTH_USER_NAME.equals(requestData.getKey())) { as.setUserName(requestData.getValue()); } else if (ScriptConstants.AUTH_PASSWORD.equals(requestData.getKey())) { as.setPassword(requestData.getValue()); } else if (ScriptConstants.AUTH_REALM.equals(requestData.getKey())) { as.setRealm(requestData.getValue()); } else if (ScriptConstants.AUTH_SCHEME.equals(requestData.getKey())) { as.setScheme(AuthScheme.getScheme(requestData.getValue())); } else if (ScriptConstants.AUTH_HOST.equals(requestData.getKey())) { as.setHost(requestData.getValue()); } else if (ScriptConstants.AUTH_PORT.equals(requestData.getKey())) { as.setPort(requestData.getValue()); } } return as; } private static TestStep convertThinkStep(ScriptStep scriptStep) { ThinkTimeStep tts = new ThinkTimeStep(); Set<RequestData> data = scriptStep.getData(); for (RequestData requestData : data) { if (ScriptConstants.MIN_TIME.equals(requestData.getKey())) { tts.setMinTime(requestData.getValue()); } else if (ScriptConstants.MAX_TIME.equals(requestData.getKey())) { tts.setMaxTime(requestData.getValue()); } } return tts; } public static List<Header> getPostData(Set<RequestData> postData) { List<Header> dataList = new ArrayList<Header>(); for (RequestData requestData : postData) { Header td = new Header(); td.setKey(requestData.getKey()); td.setValue(requestData.getValue()); dataList.add(td); } return dataList; } private static String getValidateValue(String value) { if (value.startsWith("==")) { return value.substring(2); } else if (value.startsWith("!=")) { return value.substring(2); } else if (value.startsWith("Contains")) { return value.substring("Contains".length()); } else if (value.startsWith("Does not contain")) { return value.substring("Does not contain".length()); } else if (value.startsWith("Empty")) { return value.substring("Empty".length()); } else if (value.startsWith("Not empty")) { return value.substring("Not empty".length()); } else return value; } private static String getCondition(String conditionStr) { if (conditionStr.startsWith("==")) { return ValidationType.equals.name(); } else if (conditionStr.startsWith("!=")) { return ValidationType.notequals.name(); } else if (conditionStr.startsWith("Contains")) { return ValidationType.contains.name(); } else if (conditionStr.startsWith("Does not contain")) { return ValidationType.doesnotcontain.name(); } else if (conditionStr.startsWith("Empty")) { return ValidationType.empty.name(); } else if (conditionStr.startsWith("Not empty")) { return ValidationType.notempty.name(); } else if (conditionStr.startsWith("Greater Than")) { return ValidationType.greaterthan.name(); } else if (conditionStr.startsWith("Less Than")) { return ValidationType.lessthan.name(); } return ""; } public static List<ResponseData> getResponseData(Set<RequestData> responseData) { List<ResponseData> dataList = new ArrayList<ResponseData>(); for (RequestData rd : responseData) { if (rd.getValue() != null) { if (rd.getValue().length() > 1 && rd.getValue().charAt(0) == '=' && rd.getValue().charAt(1) != '=') { AssignmentData data = new AssignmentData(); data.setKey(rd.getKey()); data.setValue(rd.getValue().substring(1)); dataList.add(data); data.setPhase(rd.getPhase()); } else { ValidationData vd = new ValidationData(); vd.setKey(rd.getKey()); vd.setCondition(getCondition(rd.getValue())); vd.setValue(getValidateValue(rd.getValue())); vd.setPhase(rd.getPhase()); dataList.add(vd); } } } return dataList; } public static List<Header> getResponseHeaders(Set<RequestData> responseHeaders, Set<RequestData> responseCookies) { List<Header> dataList = new ArrayList<Header>(); for (RequestData rd : responseHeaders) { if (rd.getValue() != null) { Header header = new Header(); header.setKey(rd.getKey()); if (rd.getValue().length() > 1 && rd.getValue().charAt(0) == '=' && rd.getValue().charAt(1) != '=') { header.setValue(rd.getValue().substring(1)); } dataList.add(header); } } for (RequestData sc : responseCookies) { if (sc.getValue() == null) continue; if (sc.getValue().startsWith("@")) { Header header = new Header(); header.setKey(sc.getValue().substring(1)); header.setValue(sc.getKey()); } } return dataList; } public static List<Header> getRequestHeaders(Set<RequestData> headers, Set<RequestData> cookies) { List<Header> dataList = new ArrayList<Header>(); Header testData = new Header(); testData.setKey("TEST"); testData.setValue("LoadTest"); dataList.add(testData); for (RequestData data : headers) { if (includedHeader(data.getKey())) { String key = data.getKey(); if (key.toLowerCase().startsWith("x-include-")) { key = key.substring(10); } Header td = new Header(); td.setKey(key); td.setValue(data.getValue()); dataList.add(td); } } if (null != cookies) { String cookieStr = ""; for (RequestData c : cookies) { // only add cookies for variables if (c.getValue().startsWith("@")) { cookieStr += "." + c.getKey().replace(".", "-dot-") + "=." + c.getValue() + ".;"; } /* * else { cookieStr += "." + c.getKey().replace(".", "-dot-") + "=." + c.getValue() + ".;"; } */ } if (!cookieStr.equals("")) { String cookieValue = "#function.string.concat" + cookieStr; Header cookieData = new Header(); cookieData.setKey("Cookie"); cookieData.setValue(cookieValue); dataList.add(cookieData); } } return dataList; } public static boolean includedHeader(String header) { if (header.startsWith("Accept") || (!header.equalsIgnoreCase("host") && !header.startsWith("Content") && !header.equalsIgnoreCase("Connection") && !header.equalsIgnoreCase("Authorization") && !header.equalsIgnoreCase("Cookie") && !header.equalsIgnoreCase("Referer") && !header.toLowerCase().startsWith("get ") && !header.toLowerCase().startsWith("post ") && !header.equalsIgnoreCase("If-None-Match") && !header.equalsIgnoreCase("If-Modified-Since"))) { return true; } return false; } private static class StepCounter { private int stepIndex = 0; private int getNextStepIndex() { return stepIndex++; } } }