Author: pmouawad
Date: Fri Feb 1 22:51:17 2019
New Revision: 1852776
URL: http://svn.apache.org/viewvc?rev=1852776&view=rev
Log:
Bug 63101 - Propose a menu item to generate readable overview of Test Plan
Bugzilla Id: 63101
Added:
jmeter/trunk/src/core/org/apache/jmeter/gui/action/SchematicView.java
(with props)
jmeter/trunk/src/core/org/apache/jmeter/gui/action/schematic.xsl (with
props)
Modified:
jmeter/trunk/build.xml
jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java
jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java
jmeter/trunk/xdocs/changes.xml
jmeter/trunk/xdocs/usermanual/properties_reference.xml
Modified: jmeter/trunk/build.xml
URL:
http://svn.apache.org/viewvc/jmeter/trunk/build.xml?rev=1852776&r1=1852775&r2=1852776&view=diff
==============================================================================
--- jmeter/trunk/build.xml (original)
+++ jmeter/trunk/build.xml Fri Feb 1 22:51:17 2019
@@ -1147,6 +1147,7 @@ run JMeter unless all the JMeter jars ar
<exclude name="*eucJP*"/>
</fileset>
<fileset dir="${src.core}" includes="**/*.xml" />
+ <fileset dir="${src.core}" includes="**/*.xsl" />
<fileset dir="${src.core}" includes="**/*.dtd" />
<!-- This file is used by the jmeter -h option -->
<fileset dir="${src.core}" includes="org/apache/jmeter/help.txt"/>
Modified: jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java
URL:
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java?rev=1852776&r1=1852775&r2=1852776&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java
(original)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java Fri Feb
1 22:51:17 2019
@@ -116,7 +116,8 @@ public final class ActionNames {
public static final String VALIDATE_TG = "validate_tg"; //$NON-NLS-1$
public static final String ZOOM_IN = "zoom_in"; //$NON-NLS-1$
public static final String ZOOM_OUT = "zoom_out"; //$NON-NLS-1$
- public static final String PARSE_CURL = "parse_curl"; ////$NON-NLS-1$
+ public static final String PARSE_CURL = "parse_curl"; //$NON-NLS-1$
+ public static final String SCHEMATIC_VIEW = "schematic_view";
//$NON-NLS-1$
// Prevent instantiation
private ActionNames() {}
Added: jmeter/trunk/src/core/org/apache/jmeter/gui/action/SchematicView.java
URL:
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/action/SchematicView.java?rev=1852776&view=auto
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/action/SchematicView.java
(added)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/action/SchematicView.java Fri
Feb 1 22:51:17 2019
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jmeter.gui.action;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.text.MessageFormat;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.JFileChooser;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.MenuElement;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.jmeter.gui.GuiPackage;
+import org.apache.jmeter.gui.plugin.MenuCreator;
+import org.apache.jmeter.gui.tree.JMeterTreeNode;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.collections.HashTree;
+import org.apache.jorphan.collections.HashTreeTraverser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Schematic view of Test Plan
+ * @since 5.1
+ */
+public class SchematicView extends AbstractAction implements MenuCreator,
HashTreeTraverser {
+ private static final Logger log =
LoggerFactory.getLogger(SchematicView.class);
+ private static final String DEFAULT_XSL_FILE =
+ JMeterUtils.getProperty("docgeneration.schematic_xsl");
//$NON-NLS-1$
+
+ private static final MessageFormat GENERATION_SUCCESS_MSG = new
MessageFormat(JMeterUtils.getResString("schematic_view_generation_ok"));
+
+ @FunctionalInterface
+ public interface SchematicViewGenerator {
+ void generate(HashTree testPlan, File testPlanFile, OutputStream
outputStream) throws Exception;
+ }
+
+ private static final class XslSchematicViewGenerator implements
SchematicViewGenerator {
+ @Override
+ public void generate(HashTree testPlan, File testPlanFile,
OutputStream outputStream)
+ throws Exception {
+ TransformerFactory factory = TransformerFactory.newInstance(
+ "net.sf.saxon.BasicTransformerFactory",
Thread.currentThread().getContextClassLoader());
+ Source xslt = null;
+ if (StringUtils.isEmpty(DEFAULT_XSL_FILE)) {
+ log.info("Will use file {}Â for Schematic View generation",
DEFAULT_XSL_FILE);
+ xslt = new StreamSource(new File(DEFAULT_XSL_FILE));
+ } else {
+ xslt = new
StreamSource(SchematicView.class.getResourceAsStream("/org/apache/jmeter/gui/action/schematic.xsl"));
+ }
+ Transformer transformer = factory.newTransformer(xslt);
+ Source text = new StreamSource(testPlanFile);
+ transformer.transform(text, new StreamResult(outputStream));
+ }
+
+ }
+
+ private static final Set<String> commands = new HashSet<>();
+
+ static {
+ commands.add(ActionNames.SCHEMATIC_VIEW);
+ }
+
+ public SchematicView() {
+ super();
+ }
+
+ /**
+ * @see Command#doAction(ActionEvent)
+ */
+ @Override
+ public void doAction(ActionEvent e) {
+ try {
+ String updateFile = GuiPackage.getInstance().getTestPlanFile();
+ if (updateFile != null) {
+ ActionRouter.getInstance().doActionNow(new
ActionEvent(e.getSource(), e.getID(), ActionNames.CHECK_DIRTY));
+ JFileChooser jFileChooser = new JFileChooser();
+
jFileChooser.setDialogTitle(JMeterUtils.getResString("schematic_view_outputfile"));
+ jFileChooser.setCurrentDirectory(new
File(updateFile).getParentFile());
+ jFileChooser.setSelectedFile(new File(updateFile+".html"));
+ int retVal =
jFileChooser.showSaveDialog(GuiPackage.getInstance().getMainFrame());
+ if (retVal == JFileChooser.APPROVE_OPTION) {
+ File outputFile = jFileChooser.getSelectedFile();
+ if (outputFile.exists()) {
+ int response =
JOptionPane.showConfirmDialog(GuiPackage.getInstance().getMainFrame(),
+
JMeterUtils.getResString("save_overwrite_existing_file"), // $NON-NLS-1$
+ JMeterUtils.getResString("save?"), //
$NON-NLS-1$
+ JOptionPane.YES_NO_OPTION,
+ JOptionPane.QUESTION_MESSAGE);
+ if (response == JOptionPane.CLOSED_OPTION || response
== JOptionPane.NO_OPTION) {
+ return; // Do not save, user does not want to
overwrite
+ }
+ }
+
GuiPackage.getInstance().getCurrentSubTree().traverse(this);
+ try (FileOutputStream fileOutputStream = new
FileOutputStream(outputFile);
+ BufferedOutputStream bufferedOutputStream = new
BufferedOutputStream(fileOutputStream)) {
+ new
XslSchematicViewGenerator().generate(GuiPackage.getInstance().getCurrentSubTree(),
+ new File(updateFile), bufferedOutputStream);
+ }
+ JMeterUtils.reportInfoToUser(
+ GENERATION_SUCCESS_MSG.format(new
Object[]{outputFile.getAbsolutePath()}),
+ JMeterUtils.getResString("schematic_view_info"));
+ }
+ } else {
+
JMeterUtils.reportInfoToUser(JMeterUtils.getResString("schematic_view_no_plan"),
JMeterUtils.getResString("schematic_view_info"));
+ }
+ } catch (Exception ex) {
+
JMeterUtils.reportErrorToUser(JMeterUtils.getResString("schematic_view_errors"),
ex);
+ }
+ }
+
+
+ /**
+ * @see Command#getActionNames()
+ */
+ @Override
+ public Set<String> getActionNames() {
+ return commands;
+ }
+
+ @Override
+ public JMenuItem[] getMenuItemsAtLocation(MENU_LOCATION location) {
+ if (location == MENU_LOCATION.TOOLS) {
+
+ JMenuItem menuItem = new JMenuItem(
+ JMeterUtils.getResString("schematic_view_menu"),
KeyEvent.VK_UNDEFINED);
+ menuItem.setName(ActionNames.SCHEMATIC_VIEW);
+ menuItem.setActionCommand(ActionNames.SCHEMATIC_VIEW);
+ menuItem.setAccelerator(null);
+ menuItem.addActionListener(ActionRouter.getInstance());
+
+ return new JMenuItem[]{menuItem};
+ }
+ return new JMenuItem[0];
+ }
+
+ @Override
+ public JMenu[] getTopLevelMenus() {
+ return new JMenu[0];
+ }
+
+ @Override
+ public boolean localeChanged(MenuElement menu) {
+ return false;
+ }
+
+ @Override
+ public void localeChanged() {
+ // NOOP
+ }
+
+ @Override
+ public void addNode(Object node, HashTree subTree) {
+ //
+ JMeterTreeNode treeNode = (JMeterTreeNode) node;
+ Object userObject = treeNode.getUserObject();
+ System.out.println(userObject);
+ }
+
+ @Override
+ public void subtractNode() {
+ System.out.println();
+ }
+
+ @Override
+ public void processPath() {
+ // NOOP
+ }
+}
Propchange:
jmeter/trunk/src/core/org/apache/jmeter/gui/action/SchematicView.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
jmeter/trunk/src/core/org/apache/jmeter/gui/action/SchematicView.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jmeter/trunk/src/core/org/apache/jmeter/gui/action/schematic.xsl
URL:
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/action/schematic.xsl?rev=1852776&view=auto
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/action/schematic.xsl (added)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/action/schematic.xsl Fri Feb 1
22:51:17 2019
@@ -0,0 +1,689 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:jmeter="http://jmeter.apache.org/"
+>
+
+<xsl:strip-space elements="*"/>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ Stylesheet to display details of a JMX test plan for HTTP
+-->
+<xsl:template match="jmeterTestPlan">
+ <html>
+ <title>Schematic view of Test Plan</title>
+ <head>
+ <style>
+ul.tree, ul.tree ul {
+ list-style-type: none;
+ background:
url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAKAQMAAABPHKYJAAAAA1BMVEWIiIhYZW6zAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1ggGExMZBky19AAAAAtJREFUCNdjYMAEAAAUAAHlhrBKAAAAAElFTkSuQmCC')
repeat-y;
+ margin: 0;
+ padding: 0;
+}
+ul.tree ul {
+ margin-left: 10px;
+}
+ul.tree li {
+ margin: 0;
+ padding: 0 12px;
+ line-height: 20px;
+ background:
url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAUAQMAAACK1e4oAAAABlBMVEUAAwCIiIgd2JB2AAAAAXRSTlMAQObYZgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YIBhQIJYVaFGwAAAARSURBVAjXY2hgQIf/GTDFGgDSkwqATqpCHAAAAABJRU5ErkJggg==')
no-repeat;
+ color: #369;
+}
+ul.tree li:last-child {
+ background: #fff
url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAUAQMAAACK1e4oAAAABlBMVEUAAwCIiIgd2JB2AAAAAXRSTlMAQObYZgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YIBhQIIhs+gc8AAAAQSURBVAjXY2hgQIf/GbAAAKCTBYBUjWvCAAAAAElFTkSuQmCC')
no-repeat;
+}
+</style>
+</head>
+<body>
+ <xsl:apply-templates/>
+</body>
+</html>
+</xsl:template>
+
+<!-- Remove empty nodes -->
+<xsl:template match="hashTree[count(child::*) = 0]">
+</xsl:template>
+
+<xsl:template match="jmeterTestPlan/hashTree[1]">
+ <ul class="tree" id="tree">
+ <xsl:apply-templates/>
+ </ul>
+</xsl:template>
+
+<xsl:template match="hashTree">
+ <li><ul><xsl:apply-templates /></ul></li>
+</xsl:template>
+
+<xsl:template match="TestPlan">
+ <li>
+ <xsl:call-template name="header"/>
+ (globalVars:[<xsl:for-each select='elementProp/collectionProp/elementProp'>
+ "<xsl:value-of select='stringProp[@name="Argument.name"]'/>"
+ <xsl:value-of select='stringProp[@name="Argument.metadata"]'/>
+ "<xsl:value-of select='stringProp[@name="Argument.value"]'/>"
+ <xsl:if test="position() != last()">,</xsl:if>
+ </xsl:for-each>],
+ executeTearDownThreadsOnShutdown: <xsl:value-of
select='boolProp[@name="TestPlan.tearDown_on_shutdown"]'/>)
+ <xsl:call-template name="comment"/>
+ </li>
+</xsl:template>
+
+<xsl:template match="Arguments">
+ <li>
+ <xsl:call-template name="header"/>
+ ([<xsl:for-each select='collectionProp/elementProp'>
+ "<xsl:value-of select='stringProp[@name="Argument.name"]'/>"
+ <xsl:value-of select='stringProp[@name="Argument.metadata"]'/>
+ "<xsl:value-of select='stringProp[@name="Argument.value"]'/>"
+ <xsl:if test="position() != last()">,</xsl:if>
+ </xsl:for-each>])
+ <xsl:call-template name="comment"/>
+ </li>
+</xsl:template>
+
+<xsl:template match="ThreadGroup|SetupThreadGroup|PostThreadGroup">
+<li>
+ <xsl:call-template name="header"/>
+ (
+ threads: "<xsl:value-of
select='stringProp[@name="ThreadGroup.num_threads"]'/>",
+ loops: "<xsl:value-of
select='elementProp/*[@name="LoopController.loops"]'/>",
+ ramp-up: "<xsl:value-of
select='stringProp[@name="ThreadGroup.ramp_time"]'/>"
+ )
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="CSVDataSet">
+<li>
+ <xsl:call-template name="header"/>
+ (file: "<xsl:value-of select='stringProp[@name="filename"]'/>",
+ vars:"<xsl:value-of select='stringProp[@name="variableNames"]'/>",
+ sharing:"<xsl:value-of select='stringProp[@name="shareMode"]'/>",
+ recycleOnEof:<xsl:value-of select='boolProp[@name="recycle"]'/>,
+ stopThreadOnEof:<xsl:value-of select='boolProp[@name="stopThread"]'/>
+ )
+ <xsl:call-template name="comment"/>
+ <br/>
+</li>
+</xsl:template>
+
+<xsl:template match="ThroughputController">
+<li>
+ <xsl:call-template name="header"/>
+ (pct: "<xsl:value-of
select='stringProp[@name="ThroughputController.percentThroughput"]'/>%")
+ <xsl:call-template name="comment"/>
+ <br/>
+</li>
+</xsl:template>
+
+<xsl:template match="IfController">
+<li>
+ <xsl:call-template name="header"/>
+ (condition: "<xsl:value-of
select='stringProp[@name="IfController.condition"]'/>")
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="HTTPSamplerProxy">
+<li>
+ <xsl:call-template name="header"/>
+ (method: "<xsl:value-of select='stringProp[@name="HTTPSampler.method"]'/>",
+ url: "
+ <xsl:value-of select='stringProp[@name="HTTPSampler.protocol"]'/>
+ <xsl:text>://</xsl:text>
+ <xsl:value-of select='stringProp[@name="HTTPSampler.domain"]'/>
+ <xsl:text>:</xsl:text>
+ <xsl:value-of select='stringProp[@name="HTTPSampler.port"]'/>
+ <xsl:text>/</xsl:text>
+ <xsl:value-of select='stringProp[@name="HTTPSampler.path"]'/>",
+ <xsl:choose>
+ <xsl:when test='boolProp[@name="HTTPSampler.postBodyRaw"] = "true"'>
+ body: "<xsl:value-of
select='elementProp/collectionProp/elementProp[@elementType="HTTPArgument"][1]/stringProp[@name="Argument.value"]'/>"
+ </xsl:when>
+ <xsl:otherwise>
+ body: [
+ <xsl:for-each
select='elementProp[@name="HTTPsampler.Arguments"]/collectionProp/elementProp'>
+ "<xsl:value-of select='stringProp[@name="Argument.name"]'/>"=
+ "<xsl:value-of select='stringProp[@name="Argument.value"]'/>"
+ <xsl:if test="position() != last()">,</xsl:if>
+ </xsl:for-each>
+ ]
+ </xsl:otherwise>
+ </xsl:choose>,
+ upload-files: [
+ <xsl:for-each
select='elementProp[@name="HTTPsampler.Files"]/collectionProp/elementProp'>
+ {param="<xsl:value-of
select='stringProp[@name="File.paramname"]'/>",
+ path="<xsl:value-of select='stringProp[@name="File.path"]'/>",
+ mime-type="<xsl:value-of
select='stringProp[@name="File.mimetype"]'/>"}
+ <xsl:if test="position() != last()">,</xsl:if>
+ </xsl:for-each>
+ ]
+ )
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="CacheManager">
+<li>
+ <xsl:call-template name="header"/>
+ (clearOnEachIteration: <xsl:value-of
select='boolProp[@name="clearEachIteration"]'/>,
+ useCacheControlAndExpires: <xsl:value-of
select='boolProp[@name="useExpires"]'/>,
+ maxSize: <xsl:value-of select='intProp[@name="maxSize"]'/>
+ )
+ <xsl:call-template name="comment"/>
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+<xsl:template match="ConfigTestElement[@guiclass='HttpDefaultsGui']">
+<li>
+ <xsl:call-template name="header"/>
+ (protocol: "<xsl:value-of
select='stringProp[@name="HTTPSampler.protocol"]'/>",
+ domain: "<xsl:value-of select='stringProp[@name="HTTPSampler.domain"]'/>",
+ port: "<xsl:value-of select='stringProp[@name="HTTPSampler.port"]'/>",
+ path: "<xsl:value-of select='stringProp[@name="HTTPSampler.path"]'/>",
+ connectTimeout: "<xsl:value-of
select='stringProp[@name="HTTPSampler.connect_timeout"]'/>"ms,
+ responseTimeout: "<xsl:value-of
select='stringProp[@name="HTTPSampler.response_timeout"]'/>"ms
+ )
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="ResultCollector">
+<li>
+ <xsl:call-template name="header"/>
+ <xsl:if test='stringProp[@name="filename"]!=""'>
+ (filename: "<xsl:value-of select='stringProp[@name="filename"]'/>",
+ xml: <xsl:value-of select='objProp/value/xml'/>,
+ errorsOnly: <xsl:value-of
select='boolProp[@name="ResultCollector.error_logging"]'/>,
+ successOnly: <xsl:value-of
select='boolProp[@name="ResultCollector.success_only_logging"]'/>)
+ </xsl:if>
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="ResponseAssertion">
+<li>
+ <xsl:call-template name="header"/>
+ <b> that (<xsl:value-of
select='substring(stringProp[@name="Assertion.test_field"], 11)'/>)</b>
+ <b>
+ <xsl:choose>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 1'>
+ matches
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 2'>
+ contains
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 5'>
+ does not match
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 6'>
+ does not contain
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 8'>
+ is equal to
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 12'>
+ is not equal to
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 16'>
+ contains
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 20'>
+ does not contain as substring
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 37'>
+ does not matches one of
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 38'>
+ does not contain one of
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 44'>
+ is not equal to one of
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 48'>
+ contains one of
+ </xsl:when>
+ <xsl:when test='intProp[@name="Assertion.test_type"] = 52'>
+ does not contain as substring one of
+ </xsl:when>
+ </xsl:choose>
+ </b>
+ [
+ <xsl:for-each
select='collectionProp[@name="Asserion.test_strings"]/stringProp'>
+ "<xsl:value-of select='.'/>"
+ <xsl:if test="position() != last()">,</xsl:if>
+ </xsl:for-each>
+ ])
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="TestAction">
+<li>
+ <xsl:call-template name="header"/>
+ <b>
+ <xsl:choose>
+ <xsl:when test='intProp[@name="ActionProcessor.action"] = 0'>
+ stop
+ </xsl:when>
+ <xsl:when test='intProp[@name="ActionProcessor.action"] = 1'>
+ pause for <xsl:value-of
select='stringProp[@name="ActionProcessor.duration"]'/>ms
+ </xsl:when>
+ <xsl:when test='intProp[@name="ActionProcessor.action"] = 2'>
+ stop now
+ </xsl:when>
+ <xsl:when test='intProp[@name="ActionProcessor.action"] = 3'>
+ go to next iteration of thread loop
+ </xsl:when>
+ <xsl:when test='intProp[@name="ActionProcessor.action"] = 4'>
+ go to next iteration of current loop
+ </xsl:when>
+ <xsl:when test='intProp[@name="ActionProcessor.action"] = 5'>
+ break current loop
+ </xsl:when>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test='intProp[@name="ActionProcessor.target"] = 0'>
+ current thread
+ </xsl:when>
+ <xsl:when test='intProp[@name="ActionProcessor.target"] = 2'>
+ test
+ </xsl:when>
+ </xsl:choose>
+ </b>
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="ResultAction">
+<li>
+ <xsl:call-template name="header"/>
+ <b>
+ <xsl:choose>
+ <xsl:when test='intProp[@name="OnError.action"] = 0'>
+ continue
+ </xsl:when>
+ <xsl:when test='intProp[@name="OnError.action"] = 1'>
+ stop thread now
+ </xsl:when>
+ <xsl:when test='intProp[@name="OnError.action"] = 2'>
+ shutdown test
+ </xsl:when>
+ <xsl:when test='intProp[@name="OnError.action"] = 3'>
+ stop test now
+ </xsl:when>
+ <xsl:when test='intProp[@name="OnError.action"] = 4'>
+ go to next iteration of thread loop
+ </xsl:when>
+ <xsl:when test='intProp[@name="OnError.action"] = 5'>
+ go to next iteration of current loop
+ </xsl:when>
+ <xsl:when test='intProp[@name="OnError.action"] = 6'>
+ break current loop
+ </xsl:when>
+ </xsl:choose>
+ </b>
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="UserParameters">
+<li>
+ <xsl:call-template name="header"/>
+ (names=[
+ <xsl:for-each
select='collectionProp[@name="UserParameters.names"]/stringProp'>
+ "<xsl:value-of select='.'/>"
+ <xsl:if test="position() != last()">,</xsl:if>
+ </xsl:for-each>],values=[
+ <xsl:for-each
select='collectionProp[@name="UserParameters.thread_values"]/collectionProp/stringProp'>
+ "<xsl:value-of select='.'/>"
+ <xsl:if test="position() != last()">,</xsl:if>
+ </xsl:for-each>]
+ )
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="ModuleController">
+<li>
+ <xsl:call-template name="header"/>
+ (
+ <xsl:for-each select='collectionProp/stringProp'>
+ <xsl:if test="position()!=1 and position() != last()">
+ <xsl:value-of select='.'/>
+ </xsl:if>
+ <xsl:if test="position() = last()">
+ <a><xsl:attribute name="href">#<xsl:value-of
select='.'/></xsl:attribute><xsl:value-of select='.'/></a>
+ </xsl:if>
+ <xsl:if test="position()!=1 and position() != last()">
+ >
+ </xsl:if>
+ </xsl:for-each>
+ )
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="CookieManager">
+<li>
+ <xsl:call-template name="header"/>
+ (clearOnEachIteration: <xsl:value-of
select='boolProp[@name="CookieManager.clearEachIteration"]'/>,
+ policy: "<xsl:value-of
select='stringProp[@name="CookieManager.policy"]'/>",
+ cookies: [
+ <xsl:for-each
select='collectionProp[@name="CookieManager.cookies"]/elementProp[@elementType="Cookie"]'>
+ { name:"<xsl:value-of select='@name'/>",
+ value:"<xsl:value-of select='stringProp[@name="Cookie.value"]'/>",
+ domain:"<xsl:value-of select='stringProp[@name="Cookie.domain"]'/>",
+ path:"<xsl:value-of select='stringProp[@name="Cookie.path"]'/>",
+ secure:<xsl:value-of select='boolProp[@name="Cookie.secury"]'/>}
+ <xsl:if test="position() != last()">,</xsl:if>
+ </xsl:for-each>])
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="HeaderManager">
+<li>
+ <xsl:call-template name="header"/>
+ (headers:[
+ <xsl:for-each
select='collectionProp[@name="HeaderManager.headers"]/elementProp'>
+ {"<xsl:value-of select='stringProp[@name="Header.name"]'/>"=
+ "<xsl:value-of select='stringProp[@name="Header.value"]'/>"
+ <xsl:if test="position() != last()">,</xsl:if>
+ </xsl:for-each>])
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:function name="jmeter:showScope">
+ <xsl:param name="scope"/>
+ <xsl:choose>
+ <xsl:when test="$scope = 'true'">
+ using response headers
+ </xsl:when>
+ <xsl:when test="$scope = 'false'">
+ using response body
+ </xsl:when>
+ <xsl:when test="$scope = 'request_headers'">
+ using request headers
+ </xsl:when>
+ <xsl:when test="$scope = 'unescaped'">
+ using response body unescaped
+ </xsl:when>
+ <xsl:when test="$scope = 'URL'">
+ using URL
+ </xsl:when>
+ <xsl:when test="$scope = 'code'">
+ using response code
+ </xsl:when>
+ <xsl:when test="$scope = 'message'">
+ using response message
+ </xsl:when>
+ </xsl:choose>
+</xsl:function>
+
+<xsl:template match="XPath2Extractor">
+<li>
+ <xsl:call-template name="header"/>
+ <b>using response body</b>
+ (exportedVar: "<xsl:value-of
select='stringProp[@name="XPathExtractor2.refname"]'/>",
+ xpathQuery: "<xsl:value-of
select='stringProp[@name="XPathExtractor2.xpathQuery"]'/>",
+ fragment: "<xsl:value-of
select='stringProp[@name="XPathExtractor2.fragment"]'/>",
+ default: "<xsl:value-of
select='stringProp[@name="XPathExtractor2.default"]'/>",
+ matchNr: "<xsl:value-of
select='stringProp[@name="XPathExtractor2.matchNumber"]'/>")
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="XPathExtractor">
+<li>
+ <xsl:call-template name="header"/>
+ <b>using response body</b>
+ (exportedVar: "<xsl:value-of
select='stringProp[@name="XPathExtractor.refname"]'/>",
+ xpathQuery: "<xsl:value-of
select='stringProp[@name="XPathExtractor.xpathQuery"]'/>",
+ fragment: "<xsl:value-of
select='stringProp[@name="XPathExtractor.fragment"]'/>",
+ default: "<xsl:value-of
select='stringProp[@name="XPathExtractor.default"]'/>",
+ matchNr: "<xsl:value-of
select='stringProp[@name="XPathExtractor.matchNumber"]'/>")
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="HtmlExtractor">
+<li>
+ <xsl:call-template name="header"/>
+ <b>using response body</b>
+ (exportedVar: "<xsl:value-of
select='stringProp[@name="HtmlExtractor.refname"]'/>",
+ selector: "<xsl:value-of
select='stringProp[@name="HtmlExtractor.expr"]'/>",
+ attribute: "<xsl:value-of
select='stringProp[@name="HtmlExtractor.attribute"]'/>",
+ default: "<xsl:value-of
select='stringProp[@name="HtmlExtractor.default"]'/>",
+ matchNr: "<xsl:value-of
select='stringProp[@name="HtmlExtractor.match_number"]'/>")
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="JSONPostProcessor">
+<li>
+ <xsl:call-template name="header"/>
+ <b>using response body</b>
+ (exportedVar: "<xsl:value-of
select='stringProp[@name="JSONPostProcessor.referenceNames"]'/>",
+ jsonPaths: "<xsl:value-of
select='stringProp[@name="JSONPostProcessor.jsonPathExprs"]'/>",
+ default: "<xsl:value-of
select='stringProp[@name="JSONPostProcessor.defaultValues"]'/>",
+ matchNr: "<xsl:value-of
select='stringProp[@name="JSONPostProcessor.match_numbers"]'/>")
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="BoundaryExtractor">
+<li>
+ <xsl:call-template name="header"/>
+ <b><xsl:value-of
select='jmeter:showScope(stringProp[@name="BoundaryExtractor.useHeaders"])'/></b>
+ (exportedVar: "<xsl:value-of
select='stringProp[@name="BoundaryExtractor.refname"]'/>",
+ lboundary: "<xsl:value-of
select='stringProp[@name="BoundaryExtractor.lboundary"]'/>",
+ rboundary: "<xsl:value-of
select='stringProp[@name="BoundaryExtractor.rboundary"]'/>",
+ default: "<xsl:value-of
select='stringProp[@name="BoundaryExtractor.default"]'/>",
+ matchNr: "<xsl:value-of
select='stringProp[@name="BoundaryExtractor.match_number"]'/>")
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="RegexExtractor">
+<li>
+ <xsl:call-template name="header"/>
+ <b><xsl:value-of
select='jmeter:showScope(stringProp[@name="RegexExtractor.useHeaders"])'/></b>
+ (exportedVar: "<xsl:value-of
select='stringProp[@name="RegexExtractor.refname"]'/>"
+ regex: "<xsl:value-of
select='stringProp[@name="BoundaryExtractor.regex"]'/>",
+ template: "<xsl:value-of
select='stringProp[@name="BoundaryExtractor.template"]'/>",
+ default: "<xsl:value-of
select='stringProp[@name="BoundaryExtractor.default"]'/>",
+ matchNr: "<xsl:value-of
select='stringProp[@name="BoundaryExtractor.match_number"]'/>")
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="ConstantTimer">
+<li>
+ <xsl:call-template name="header"/>
+ (const:<xsl:value-of select='stringProp[@name="ConstantTimer.delay"]'/>ms)
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template
match="UniformRandomTimer|GaussianRandomTimer|PoissonRandomTimer">
+<li>
+ <xsl:call-template name="header"/>
+ (const:<xsl:value-of select='stringProp[@name="ConstantTimer.delay"]'/>ms,
+ variation:<xsl:value-of select='stringProp[@name="RandomTimer.range"]'/>ms)
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template match="*">
+<li>
+ <xsl:call-template name="header"/>
+ <xsl:call-template name="comment"/>
+</li>
+</xsl:template>
+
+<xsl:template name="comment">
+ <xsl:if test='stringProp/@name="TestPlan.comments"'>
+ <br/>
+    Comments: <i style="color:green">
+ <xsl:value-of select='stringProp[@name="TestPlan.comments"]'/>
+ </i>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template name="header">
+ <xsl:choose>
+ <xsl:when test="name() = 'GenericController'">
+ <a>
+ <xsl:attribute name="id">
+ <xsl:value-of select="@testname"/>
+ </xsl:attribute>
+ <b>container</b></a>
+ </xsl:when>
+ <xsl:when test="name() = 'HTTPSamplerProxy'">
+ <b>http request</b>
+ </xsl:when>
+ <xsl:when test="name() = 'SetupThreadGroup'">
+ <b>run before</b>
+ </xsl:when>
+ <xsl:when test="name() = 'ThreadGroup'">
+ <b>run</b>
+ </xsl:when>
+ <xsl:when test="name() = 'PostThreadGroup'">
+ <b>run after</b>
+ </xsl:when>
+ <xsl:when test="name() = 'TestFragmentController'">
+ <b>declare reusable Elements</b>
+ </xsl:when>
+ <xsl:when test="name() = 'ResponseAssertion'">
+ <b>assert as</b>
+ </xsl:when>
+ <xsl:when test="name() = 'TransactionController'">
+ <a>
+ <xsl:attribute name="id">
+ <xsl:value-of select="@testname"/>
+ </xsl:attribute>
+ <b>transaction</b></a>
+ </xsl:when>
+ <xsl:when test="name() = 'ModuleController'">
+ <b>reuse controller</b>
+ </xsl:when>
+ <xsl:when test="name() = 'UserParameters'">
+ <b>set variables for thread</b>
+ </xsl:when>
+ <xsl:when test="name() = 'RandomController'">
+ <a>
+ <xsl:attribute name="id">
+ <xsl:value-of select="@testname"/>
+ </xsl:attribute>
+ <b>randomly run children</b></a>
+ </xsl:when>
+ <xsl:when test="name() = 'ThroughputController'">
+ <a>
+ <xsl:attribute name="id">
+ <xsl:value-of select="@testname"/>
+ </xsl:attribute>
+ <b>run at percentage</b></a>
+ </xsl:when>
+ <xsl:when test="name() = 'IfController'">
+ <a>
+ <xsl:attribute name="id">
+ <xsl:value-of select="@testname"/>
+ </xsl:attribute>
+ <b>if</b></a>
+ </xsl:when>
+ <xsl:when test="name() = 'ResultCollector'">
+ <b>write samples</b>
+ </xsl:when>
+ <xsl:when test="name() = 'ConstantTimer'">
+ <b>think-time Constant</b>
+ </xsl:when>
+ <xsl:when test="name() = 'UniformRandomTimer'
+ or name() = 'GaussianRandomTimer'
+ or name() = 'PoissonRandomTimer'">
+ <b>think-time <xsl:value-of
select="substring-before(name(),'RandomTimer')" /></b>
+ </xsl:when>
+ <xsl:when test="name() = 'JSR223Sampler'">
+ <b>jsr223 sampler</b>
+ </xsl:when>
+ <xsl:when test="name() = 'JSR223PreProcessor'">
+ <b>jsr223 pre-process</b>
+ </xsl:when>
+ <xsl:when test="name() = 'JSR223PostProcessor'">
+ <b>jsr223 post-process</b>
+ </xsl:when>
+ <xsl:when test="name() = 'CSVDataSet'">
+ <b>read csv into vars</b>
+ </xsl:when>
+ <xsl:when test="name() = 'HeaderManager'">
+ <b>add headers</b>
+ </xsl:when>
+ <xsl:when test="name() = 'CookieManager'">
+ <b>handle cookies</b>
+ </xsl:when>
+ <xsl:when test="name() = 'Arguments'">
+ <b>globalVars</b>
+ </xsl:when>
+ <xsl:when test="name() = 'TestAction'">
+ <b>flow control</b>
+ </xsl:when>
+ <xsl:when test="name() = 'ResultAction'">
+ <b>action after sampler error </b>
+ </xsl:when>
+ <xsl:when test="name() = 'ConfigTestElement' and @guiclass =
'HttpDefaultsGui'">
+ <b>http defaults</b>
+ </xsl:when>
+ <xsl:when test="name() = 'CacheManager'">
+ <b>simulate browser cache</b>
+ </xsl:when>
+ <xsl:when test="name() = 'RegexExtractor'">
+ <b>extract-regexp </b>
+ </xsl:when>
+ <xsl:when test="name() = 'BoundaryExtractor'">
+ <b>extract-boundary </b>
+ </xsl:when>
+ <xsl:when test="name() = 'HtmlExtractor'">
+ <b>extract-css-selector </b>
+ </xsl:when>
+ <xsl:when test="name() = 'XPathExtractor'">
+ <b>extract-xpath </b>
+ </xsl:when>
+ <xsl:when test="name() = 'XPath2Extractor'">
+ <b>extract-xpath2 </b>
+ </xsl:when>
+ <xsl:when test="name() = 'JSONPostProcessor'">
+ <b>extract-jsonpath </b>
+ </xsl:when>
+ <xsl:when test="name() = 'TestPlan'">
+ <b>load test </b>
+ </xsl:when>
+ <xsl:otherwise>
+ <b><xsl:value-of select="name()"/></b>
+ </xsl:otherwise>
+ </xsl:choose>
+ "<xsl:value-of select="@testname"/>" <xsl:call-template
name="disabledElement"/>
+</xsl:template>
+
+<xsl:template name="disabledElement">
+ <xsl:if test="@enabled = 'false'">
+ <del>(disabled)</del> 
+ </xsl:if>
+</xsl:template>
+</xsl:stylesheet>
\ No newline at end of file
Propchange: jmeter/trunk/src/core/org/apache/jmeter/gui/action/schematic.xsl
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jmeter/trunk/src/core/org/apache/jmeter/gui/action/schematic.xsl
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL:
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1852776&r1=1852775&r2=1852776&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
(original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Fri
Feb 1 22:51:17 2019
@@ -1039,6 +1039,12 @@ save_workbench=Save WorkBench
sbind=Single bind/unbind
scheduler=Scheduler
scheduler_configuration=Scheduler Configuration
+schematic_view_errors=Error on generation of schematic view
+schematic_view_generation_ok=Successful generation of schematic view in {0}
+schematic_view_info=Information
+schematic_view_menu=Generate Schematic View (alpha)
+schematic_view_no_plan=No plan opened
+schematic_view_outputfile=Save output file to ?
scope=Scope
search=Search
search_base=Search base
Modified:
jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
URL:
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1852776&r1=1852775&r2=1852776&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
(original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
Fri Feb 1 22:51:17 2019
@@ -1028,6 +1028,12 @@ save_workbench=Sauvegarder le plan de tr
sbind=Simple connexion/déconnexion
scheduler=Programmateur de démarrage
scheduler_configuration=Configuration du programmateur
+schematic_view_errors=Erreur lors de la génération de la vue schématique
+schematic_view_generation_ok=Génération réussie de la vue schématique dans
{0}.
+schematic_view_info=Information
+schematic_view_menu=Générer une vue schématique (alpha)
+schematic_view_no_plan=Pas de plan ouvert
+schematic_view_outputfile=Enregistrer le fichier de sortie dans ?
scope=Portée
search=Rechercher\:
search_base=Base de recherche
Modified: jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java
URL:
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java?rev=1852776&r1=1852775&r2=1852776&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java Fri Feb 1
22:51:17 2019
@@ -898,6 +898,29 @@ public class JMeterUtils implements Unit
log.warn("reportErrorToUser(\"{}\") caused", errorMsg, e);
}
}
+
+ /**
+ * Report an information through a dialog box in GUI mode
+ *
+ * @param msg - the information message.
+ * @param titleMsg - title string
+ */
+ public static void reportInfoToUser(String msg, String titleMsg) {
+ GuiPackage instance = GuiPackage.getInstance();
+ if (instance == null) {
+ log.info(msg);
+ System.out.println(msg); // NOSONAR intentional
+ return; // Done
+ }
+ try {
+ JOptionPane.showMessageDialog(instance.getMainFrame(),
+ formatMessage(msg),
+ titleMsg,
+ JOptionPane.INFORMATION_MESSAGE);
+ } catch (HeadlessException e) {
+ log.warn("reportInfoToUser(\"{}\") caused", msg, e);
+ }
+ }
private static JScrollPane formatMessage(String errorMsg) {
JTextArea ta = new JTextArea(10, 50);
Modified: jmeter/trunk/xdocs/changes.xml
URL:
http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1852776&r1=1852775&r2=1852776&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Fri Feb 1 22:51:17 2019
@@ -150,6 +150,7 @@ containing a fix to this issue, we decid
<li><bug>61486</bug>Make jmeter-server and non GUI mode run headless</li>
<li><bug>63093</bug>Add <code>Compile JSR223 Test Elements</code> menu
item. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
<li><bug>63094</bug>Introduce a new Tools menu</li>
+ <li><bug>63101</bug>Propose a menu item to generate readable overview of
Test Plan</li>
</ul>
<ch_section>Non-functional changes</ch_section>
Modified: jmeter/trunk/xdocs/usermanual/properties_reference.xml
URL:
http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/properties_reference.xml?rev=1852776&r1=1852775&r2=1852776&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/properties_reference.xml (original)
+++ jmeter/trunk/xdocs/usermanual/properties_reference.xml Fri Feb 1 22:51:17
2019
@@ -1910,6 +1910,16 @@ JMETER-SERVER</source>
Defaults to: <code>100</code></property>
</properties>
</section>
+
+<section name="§-num;.45 Documentation generation" anchor="docgeneration">
+<description>Advanced properties for documentation generation</description>
+<properties>
+ <property name="docgeneration.schematic_xsl">
+ Path to XSL file used to generate Schematic View of Test Plan.<br/>
+ When empty, JMeter will use the embedded one in
src/core/org/apache/jmeter/gui/action/schematic.xsl<br/>
+ No default value</property>
+</properties>
+</section>
<!--
<section name="§-num;.10 Reports" anchor="Reports">
<description>