package jsystem.framework.scenario.flow_control; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import jsystem.framework.FrameworkOptions; import jsystem.framework.JSystemProperties; import jsystem.framework.common.CommonResources; import jsystem.framework.scenario.JTest; import jsystem.framework.scenario.JTestContainer; import jsystem.framework.scenario.Parameter; import jsystem.framework.scenario.Parameter.ParameterType; import jsystem.framework.scenario.RunnerTest; import jsystem.framework.scenario.ScenarioHelpers; import jsystem.framework.scenario.flow_control.datadriven.CsvDataProvider; import jsystem.framework.scenario.flow_control.datadriven.DataProvider; import jsystem.utils.StringUtils; import jsystem.utils.XmlUtils; import jsystem.utils.beans.BeanUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Presentation of the data driven action in the scenario * * @author Itai_Agmon * */ public class AntDataDriven extends AntFlowControl { private static final String OPTIONS_SECTION = "Options"; private Parameter dataSourceFile = new Parameter(); private Parameter dataSourceParam = new Parameter(); private Parameter dataSourceLineIndexes = new Parameter(); private Parameter dataSourceShuffle = new Parameter(); private Parameter dataSourceShuffleSeed = new Parameter(); private Parameter dataSourceReverseOrder = new Parameter(); private Parameter dataSourceType = new Parameter(); public static String XML_TAG = CommonResources.JSYSTEM_DATADRIVEN; public static String XML_CONTAINER_TAG = "sequential"; protected RunnerTest runnerTest; public AntDataDriven() { this(null, null); } public AntDataDriven(JTestContainer parent, String id) { super("DataDriven", parent, id); dataSourceType.setType(ParameterType.STRING); dataSourceType.setAsOptions(true); dataSourceType.setOptions(fetchProviderTypes().toArray()); final String dataProviderClasses = JSystemProperties.getInstance().getPreferenceOrDefault( FrameworkOptions.DATA_PROVIDER_CLASSES); DataProvider provider = null; if (!StringUtils.isEmpty(dataProviderClasses)) { provider = BeanUtils.createInstanceFromClassName(dataProviderClasses.split(";")[0], DataProvider.class); } dataSourceType.setValue(provider != null ? provider.getName() : ""); dataSourceType.setName("Type"); dataSourceType.setDescription("Data Provider Type"); dataSourceType.setSection(getComment()); addParameter(dataSourceType); dataSourceFile.setType(Parameter.ParameterType.FILE); dataSourceFile.setValue(""); dataSourceFile.setName("File"); dataSourceFile.setDescription("Data Source File"); // TODO: sync section with comment/name addParameter(dataSourceFile); dataSourceParam.setType(Parameter.ParameterType.STRING); dataSourceParam.setValue(""); dataSourceParam.setName("Parameter"); dataSourceParam.setDescription("Free data provider parameter"); addParameter(dataSourceParam); dataSourceLineIndexes.setType(Parameter.ParameterType.STRING); dataSourceLineIndexes.setValue(""); dataSourceLineIndexes.setSection("Options"); dataSourceLineIndexes.setName("LineIndexes"); dataSourceLineIndexes .setDescription("One-based, comma separated list of the required line indexes. You can use '-' for ranges"); addParameter(dataSourceLineIndexes); dataSourceShuffle.setType(ParameterType.BOOLEAN); dataSourceShuffle.setValue(false); dataSourceShuffle.setName("Shuffle"); dataSourceShuffle.setSection(OPTIONS_SECTION); dataSourceShuffle.setDescription("Data will be provided in pseudorandom order using the specified seed"); addParameter(dataSourceShuffle); dataSourceShuffleSeed.setType(ParameterType.LONG); dataSourceShuffleSeed.setValue(0); dataSourceShuffleSeed.setName("ShuffleSeed"); dataSourceShuffleSeed.setSection(OPTIONS_SECTION); dataSourceShuffleSeed.setDescription("Random seed. Use '0' for default"); addParameter(dataSourceShuffleSeed); dataSourceReverseOrder.setType(ParameterType.BOOLEAN); dataSourceReverseOrder.setValue(false); dataSourceReverseOrder.setSection(OPTIONS_SECTION); dataSourceReverseOrder.setName("ReverseOrder"); dataSourceReverseOrder.setDescription("Data will be providerd in reverse order"); addParameter(dataSourceReverseOrder); setTestComment(defaultComment()); } private List<String> fetchProviderTypes() { final List<String> options = new ArrayList<>(); final String[] providersClassName = JSystemProperties.getInstance() .getPreferenceOrDefault(FrameworkOptions.DATA_PROVIDER_CLASSES).split(";"); for (int i = 0; i < providersClassName.length; i++) { final DataProvider provider = BeanUtils.createInstanceFromClassName(providersClassName[i], DataProvider.class); if (null == provider) { log.log(Level.WARNING, "Fail to init provider: " + providersClassName[i]); continue; } options.add(((DataProvider) provider).getName()); } if (options.size() == 0) { log.log(Level.WARNING, "No data providers specified - Using only the default CSV provider"); options.add(new CsvDataProvider().getName()); } return options; } public Element addExecutorXml(Element targetScenario, Document doc) { Element dataDrivenElement = doc.createElement(XML_TAG); // ITAI: The actual values are set in the properties file and not in the // XML file dataDrivenElement.setAttribute("delimiter", CommonResources.DELIMITER); addPropertiesToElement(dataDrivenElement); appendAdditionalData(dataDrivenElement); /* * Create and add the sequential tag and content */ // TODO: since we need to add the echo into the sequential - // we can't use JTestContainer.addExecutorXml... // ----------------------------------------------- Element containerElement = doc.createElement(getXmlContainerTag()); Element echo2 = doc.createElement("echo"); echo2.setAttribute("message", "Data Driven"); containerElement.appendChild(echo2); Element setAntProperties = doc.createElement(CommonResources.SET_ANT_PROPERTIES); XmlUtils.appendComment(setAntProperties, "Task for updating the ant parameters file - used for reference parameters"); containerElement.appendChild(setAntProperties); /* * Create and add the container content */ // go over all tests append a target that invokes them // to the ant script and add an antcall to the test in the execute // scenario target for (JTest jtest : rootTests) { jtest.addExecutorXml(containerElement, doc); } dataDrivenElement.appendChild(containerElement); // ----------------------------------------------- targetScenario.appendChild(dataDrivenElement); return dataDrivenElement; } @Override public AntDataDriven cloneTest() throws Exception { AntDataDriven test = new AntDataDriven(getParent(), getTestId()); test.rootTests = cloneRootTests(test); return test; } @Override public String defaultComment() { return "Data driven "; } @Override public String getXmlContainerTag() { return XML_CONTAINER_TAG; } @Override protected void loadParameters() { setDataSourceFile(ScenarioHelpers.getParameterValueFromProperties(this, getFlowFullUUID(), "File", dataSourceFile.getValue() == null ? null : dataSourceFile.getValue().toString())); setDataSourceParam(ScenarioHelpers.getParameterValueFromProperties(this, getFlowFullUUID(), "Parameter", dataSourceParam.getValue() == null ? null : dataSourceParam.getValue().toString())); setDataSourceLineIndexes(ScenarioHelpers.getParameterValueFromProperties(this, getFlowFullUUID(), "LineIndexes", dataSourceLineIndexes.getValue() == null ? null : dataSourceLineIndexes.getValue() .toString())); setDataSourceShuffle(Boolean.valueOf(ScenarioHelpers.getParameterValueFromProperties(this, getFlowFullUUID(), "Shuffle", dataSourceShuffle.getValue() == null ? null : dataSourceShuffle.getValue().toString()))); setDataSourceShuffleSeed(Integer.valueOf(ScenarioHelpers.getParameterValueFromProperties(this, getFlowFullUUID(), "ShuffleSeed", dataSourceShuffleSeed.getValue() == null ? null : dataSourceShuffleSeed.getValue().toString()))); setDataSourceReverseOrder(Boolean.valueOf(ScenarioHelpers.getParameterValueFromProperties(this, getFlowFullUUID(), "ReverseOrder", dataSourceReverseOrder.getValue() == null ? null : dataSourceReverseOrder.getValue().toString()))); setDataSourceType(ScenarioHelpers.getParameterValueFromProperties(this, getFlowFullUUID(), "Type", dataSourceType.getValue() == null ? null : dataSourceType.getValue().toString())); loadAndSetUserDocumentation(); } @Override public Element getContainerElement(Element xmlDefinition) { Element container = null; NodeList nodes = xmlDefinition.getElementsByTagName(getXmlContainerTag()); Node node = nodes.item(0); if ((node instanceof Element) && (((Element) node).getTagName().equals(getXmlContainerTag()))) { container = (Element) node; } return container; } public static JTestContainer fromElement(JTestContainer parent, Element element) { AntDataDriven newContainer = new AntDataDriven(parent, null); deserializeAdditionalData(newContainer, element); newContainer.setTestComment(newContainer.defaultComment()); return newContainer; } public void setDataSourceFile(String dataSourceFileValue) { this.dataSourceFile.setValue(dataSourceFileValue); } public void setDataSourceParam(String dataSourceParamValue) { this.dataSourceParam.setValue(dataSourceParamValue); } public void setDataSourceLineIndexes(String dataSourceLineIndexesValue) { this.dataSourceLineIndexes.setValue(dataSourceLineIndexesValue); } public void setDataSourceShuffle(boolean dataSourceShuffleValue) { this.dataSourceShuffle.setValue(dataSourceShuffleValue); } public void setDataSourceShuffleSeed(long dataSourceShuffleSeedValue) { this.dataSourceShuffleSeed.setValue(dataSourceShuffleSeedValue); } public void setDataSourceReverseOrder(boolean dataSourceReverseOrderValue) { this.dataSourceReverseOrder.setValue(dataSourceReverseOrderValue); } public void setDataSourceType(String dataSourceTypeValue) { this.dataSourceType.setValue(dataSourceTypeValue); } }