You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by pm...@apache.org on 2012/04/30 17:05:46 UTC

svn commit: r1332231 - in /jmeter/trunk: ./ src/core/org/apache/jmeter/resources/ src/protocol/native/ src/protocol/native/org/ src/protocol/native/org/apache/ src/protocol/native/org/apache/jmeter/ src/protocol/native/org/apache/jmeter/protocol/ src/p...

Author: pmouawad
Date: Mon Apr 30 15:05:46 2012
New Revision: 1332231

URL: http://svn.apache.org/viewvc?rev=1332231&view=rev
Log:
Bug 53164 - New System Sampler

Added:
    jmeter/trunk/src/protocol/native/
    jmeter/trunk/src/protocol/native/org/
    jmeter/trunk/src/protocol/native/org/apache/
    jmeter/trunk/src/protocol/native/org/apache/jmeter/
    jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/
    jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/
    jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/NativeCommand.java   (with props)
    jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/StreamGobbler.java   (with props)
    jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/SystemSampler.java   (with props)
    jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/gui/
    jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/gui/SystemSamplerGui.java   (with props)
Modified:
    jmeter/trunk/build.xml
    jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
    jmeter/trunk/xdocs/changes.xml

Modified: jmeter/trunk/build.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/build.xml?rev=1332231&r1=1332230&r2=1332231&view=diff
==============================================================================
--- jmeter/trunk/build.xml (original)
+++ jmeter/trunk/build.xml Mon Apr 30 15:05:46 2012
@@ -140,12 +140,14 @@
       <class location="${dest.jar}/ApacheJMeter_ldap.jar"/>
       <class location="${dest.jar}/ApacheJMeter_mail.jar"/>
       <class location="${dest.jar}/ApacheJMeter_monitors.jar"/>
+      <class location="${dest.jar}/ApacheJMeter_native.jar"/>
       <class location="${dest.jar}/ApacheJMeter_report.jar"/>
       <class location="${dest.jar}/ApacheJMeter_tcp.jar"/>
       <class location="${dest.jar.jmeter}/ApacheJMeter.jar" />
       <sourcePath path="${src.jorphan}" />
       <sourcePath path="${src.tcp}" />
       <sourcePath path="${src.jms}" />
+      <sourcePath path="${src.native}" />
       <sourcePath path="${src.report}" />
       		
       <auxClasspath>
@@ -208,6 +210,7 @@
   <property name="src.monitor.components" value="src/monitor/components"/>
   <property name="src.monitor.model" value="src/monitor/model"/>
   <property name="src.jms" value="src/protocol/jms"/>
+  <property name="src.native" value="src/protocol/native"/>
   <property name="src.report" value="src/reports"/>
 
   <!-- Where the documentation sources live -->
@@ -234,6 +237,7 @@
     <pathelement location="${src.monitor.components}"/>
     <pathelement location="${src.monitor.model}"/>
     <pathelement location="${src.jms}"/>
+    <pathelement location="${src.native}"/>
     <pathelement location="${src.report}"/>
   </path>
 
@@ -255,6 +259,7 @@
   <property name="build.monitor.components" value="build/monitor/components"/>
   <property name="build.monitor.model" value="build/monitor/model"/>
   <property name="build.jms" value="build/protocol/jms"/>
+  <property name="build.native" value="build/protocol/native"/>
   <property name="build.report" value="build/reports"/>
   <property name="build.test" value="build/test"/>
   <property name="build.res" value="build/res"/>
@@ -809,9 +814,23 @@
       </classpath>
     </javac>
   </target>
+	
+  <target name="compile-native" depends="compile-jorphan,compile-core,compile-components"
+        description="Compile components specific to Native sampling.">
+    <mkdir dir="${build.native}"/>
+    <javac srcdir="${src.native}" destdir="${build.native}" source="${src.java.version}" optimize="${optimize}" debug="on" target="${target.java.version}"
+           includeAntRuntime="${includeAntRuntime}" deprecation="${deprecation}" encoding="${encoding}">
+      <include name="**/*.java"/>
+      <classpath>
+        <pathelement location="${build.jorphan}"/>
+        <pathelement location="${build.core}"/>
+        <path refid="classpath"/>
+      </classpath>
+    </javac>
+  </target>
 
   <target name="compile"
-  depends="_message_3rdParty,compile-core,compile-components,compile-functions,compile-protocols,compile-rmi,compile-monitor,compile-junit,compile-jms,compile-report"
+  depends="_message_3rdParty,compile-core,compile-components,compile-functions,compile-protocols,compile-rmi,compile-monitor,compile-junit,compile-jms,compile-native, compile-report"
   description="Compile everything."/>
 
   <target name="run_gui" depends="package" description="Run the JMeter GUI off the jar files">
@@ -1075,6 +1094,18 @@ run JMeter unless all the JMeter jars ar
       <fileset dir="${src.jms}" includes="**/*.properties" />
     </jar>
 
+    <!-- native -->
+    <!-- Ensure that build dir exists, even if Native has not been built -->
+    <mkdir dir="${build.native}"/>
+    <jar jarfile="${dest.jar}/ApacheJMeter_native.jar" manifest="${build.dir}/MANIFEST_BIN.MF">
+      <zipfileset file="${resources.meta-inf}/default.notice"
+        fullpath="META-INF/NOTICE" />
+      <zipfileset file="${resources.meta-inf}/default.license"
+        fullpath="META-INF/LICENSE" />
+      <fileset dir="${build.native}" includes="**/*.class" />
+      <fileset dir="${src.native}" includes="**/*.properties" />
+    </jar>
+
     <jar jarfile="${lib.dir}/jorphan.jar" manifest="${build.dir}/MANIFEST_BIN.MF">
         <zipfileset file="${resources.meta-inf}/default.notice"
           fullpath="META-INF/NOTICE" />
@@ -1633,6 +1664,7 @@ run JMeter unless all the JMeter jars ar
     <deployfile stem="ApacheJMeter_ldap"/>
     <deployfile stem="ApacheJMeter_mail"/>
     <deployfile stem="ApacheJMeter_monitors"/>
+    <deployfile stem="ApacheJMeter_native"/>
     <deployfile stem="ApacheJMeter_report"/>
     <deployfile stem="ApacheJMeter_tcp"/>
   </target>

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=1332231&r1=1332230&r2=1332231&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Mon Apr 30 15:05:46 2012
@@ -95,6 +95,7 @@ analyze=Analyze Data File...
 anchor_modifier_title=HTML Link Parser
 appearance=Look and Feel
 argument_must_not_be_negative=The Argument must not be negative\!
+arguments_panel_title=System Call Parameters
 assertion_assume_success=Ignore Status
 assertion_body_resp=Response Body
 assertion_code_resp=Response Code
@@ -150,6 +151,7 @@ cancel_new_to_save=There are test items 
 cancel_revert_project=There are test items that have not been saved.  Do you wish to revert to the previously saved test plan?
 change_parent=Change Controller
 char_value=Unicode character number (decimal or 0xhex)
+check_return_code_title=Check Return Code
 choose_function=Choose a function
 choose_language=Choose Language
 clear=Clear
@@ -159,6 +161,8 @@ clear_cookies_per_iter=Clear cookies eac
 close=Close
 column_delete_disallowed=Deleting this column is not permitted
 column_number=Column number of CSV file | next | *alias
+command_config_box_title=Command to Execute
+command_field_title=Command: 
 compare=Compare
 comparefilt=Compare filter
 comparison_differ_content=Responses differ in content
@@ -216,6 +220,7 @@ deltest=Deletion test
 deref=Dereference aliases
 description=Description
 detail=Detail
+directory_field_title=Directory:
 disable=Disable
 distribution_graph_title=Distribution Graph (alpha)
 distribution_note1=The graph will update every 10 samples
@@ -249,6 +254,7 @@ evalvar_name_param=Name of variable
 example_data=Sample Data
 example_title=Example Sampler
 exit=Exit
+expected_return_code_title=Expected Return Code: 
 expiration=Expiration
 field_name=Field name
 file=File
@@ -748,6 +754,7 @@ resultsaver_success=Save Successful Resp
 resultsaver_title=Save Responses to a file
 resultsaver_variable=Variable Name:
 retobj=Return object
+return_code_config_box_title=Return Code Configuration
 reuseconnection=Re-use connection
 revert_project=Revert
 revert_project?=Revert project?
@@ -944,6 +951,7 @@ summariser_title=Generate Summary Result
 summary_report=Summary Report
 switch_controller_label=Switch Value
 switch_controller_title=Switch Controller
+system_sampler_title=System Call Sampler
 table_visualizer_bytes=Bytes
 table_visualizer_sample_num=Sample #
 table_visualizer_sample_time=Sample Time(ms)

Added: jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/NativeCommand.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/NativeCommand.java?rev=1332231&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/NativeCommand.java (added)
+++ jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/NativeCommand.java Mon Apr 30 15:05:46 2012
@@ -0,0 +1,87 @@
+/*
+ * 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.protocol.system;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Native Command 
+ */
+public class NativeCommand {
+
+	private StreamGobbler outputGobbler;
+    private File directory;
+
+	/**
+	 * 
+	 */
+	public NativeCommand(File directory) {
+		super();
+		this.directory = directory;
+	}
+
+	/**
+	 * @param arguments List<String>
+	 * @return return code
+	 * @throws InterruptedException
+	 * @throws IOException
+	 */
+	public int run(List<String> arguments) throws InterruptedException, IOException {
+		Process proc = null;
+		try
+		{
+		    ProcessBuilder procBuild = new ProcessBuilder(arguments);
+		    procBuild.directory(directory);
+            procBuild.redirectErrorStream(true);
+            proc = procBuild.start();
+            this.outputGobbler = new 
+                     StreamGobbler(proc.getInputStream());
+            outputGobbler.start();
+	                            
+			int exitVal = proc.waitFor();
+
+			outputGobbler.join();
+			return exitVal;
+		}
+		finally
+		{
+			if(proc != null)
+			{
+				try {
+					proc.destroy();
+				} catch (Throwable e) {
+					// NOOP
+				}
+			}
+		}
+	}
+
+	/**
+	 * @return Out/Err stream contents
+	 */
+	public String getOutResult() {
+	    if(outputGobbler != null) {    
+	        return outputGobbler.getResult();
+	    } else {
+	        return "";
+	    }
+	}
+}

Propchange: jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/NativeCommand.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/StreamGobbler.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/StreamGobbler.java?rev=1332231&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/StreamGobbler.java (added)
+++ jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/StreamGobbler.java Mon Apr 30 15:05:46 2012
@@ -0,0 +1,75 @@
+/*
+ * 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.protocol.system;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/**
+ * Thread that eats Output and Error Stream to avoid Deadlock on Windows Machines
+ */
+class StreamGobbler extends Thread {
+	private InputStream is;
+	private StringBuilder buffer = new StringBuilder();
+	/**
+	 * @param is {@link InputStream}
+	 */
+	StreamGobbler(InputStream is) {
+		this.is = is;
+	}
+
+	/**
+	 * @see java.lang.Thread#run()
+	 */
+	public void run() {
+		BufferedReader br = null;
+		try {
+			br = new BufferedReader(new InputStreamReader(is));
+			String line = null;
+			while ((line = br.readLine()) != null)
+			{
+				buffer.append(line);
+				buffer.append("\r\n");
+			}
+		} catch (IOException e) {
+			buffer.append(e.getMessage());
+		}
+		finally
+		{
+			if(br != null)
+			{
+				try {
+					br.close();
+				} catch (Throwable e) {
+					// NOOP
+				}
+			}
+		}
+	}
+	
+	/**
+	 * @return
+	 */
+	public String getResult()
+	{
+		return buffer.toString();
+	}
+}

Propchange: jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/StreamGobbler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/SystemSampler.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/SystemSampler.java?rev=1332231&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/SystemSampler.java (added)
+++ jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/SystemSampler.java Mon Apr 30 15:05:46 2012
@@ -0,0 +1,230 @@
+/*
+ * 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.protocol.system;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.jmeter.config.Argument;
+import org.apache.jmeter.config.Arguments;
+import org.apache.jmeter.samplers.AbstractSampler;
+import org.apache.jmeter.samplers.Entry;
+import org.apache.jmeter.samplers.SampleResult;
+import org.apache.jmeter.services.FileServer;
+import org.apache.jmeter.testelement.property.TestElementProperty;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.log.Logger;
+
+/**
+ * A sampler for executing a System function. 
+ */
+public class SystemSampler extends AbstractSampler {
+    private static final long serialVersionUID = 1;
+    
+    public static final String COMMAND = "SystemSampler.command";
+    
+    public static final String DIRECTORY = "SystemSampler.directory";
+
+    public static final String ARGUMENTS = "SystemSampler.arguments";
+    
+    public static final String CHECK_RETURN_CODE = "SystemSampler.checkReturnCode";
+    
+    public static final String EXPECTED_RETURN_CODE = "SystemSampler.expectedReturnCode";
+
+    /**
+     * Logging
+     */
+    private static final Logger log = LoggingManager.getLoggerForClass();
+
+    /**
+     * Create a SystemSampler.
+     */
+    public SystemSampler() {
+        super();
+    }
+    
+    /**
+     * Performs a test sample.
+     * 
+     * @param entry
+     *            the Entry for this sample
+     * @return test SampleResult
+     */
+    public SampleResult sample(Entry entry) {
+        SampleResult results = new SampleResult();
+        results.setDataType(SampleResult.TEXT);
+        
+        try {
+            String command = getCommand();
+            Arguments args = getArguments();
+            boolean checkReturnCode = getCheckReturnCode();
+            int expectedReturnCode = getExpectedReturnCode();
+            
+            List<String> cmds = new ArrayList<String>(args.getArgumentCount()+1);
+            StringBuilder cmdLine = new StringBuilder((null == command) ? "" : command);
+            cmds.add(command);
+            for (int i=0;i<args.getArgumentCount();i++) {
+                Argument arg = args.getArgument(i);
+                cmds.add(arg.getPropertyAsString(Argument.VALUE));
+                cmdLine.append(" ");
+                cmdLine.append(cmds.get(i+1));
+            }
+
+            results.setSamplerData(cmdLine.toString());
+            
+            File directory = null;
+            if(StringUtils.isEmpty(getDirectory())) {
+                directory = new File(FileServer.getDefaultBase());
+                if(log.isDebugEnabled()) {
+                    log.debug("Using default directory:"+directory.getAbsolutePath());
+                }
+            } else {
+                directory = new File(getDirectory());
+                if(log.isDebugEnabled()) {
+                    log.debug("Using configured directory:"+directory.getAbsolutePath());
+                }
+            }
+            NativeCommand nativeCommand = new NativeCommand(directory);
+            
+            String responseData = null;
+            try {
+                if(log.isDebugEnabled()) {
+                    log.debug("Will run :"+cmdLine);
+                }
+                results.sampleStart();
+                int returnCode = nativeCommand.run(cmds);   
+                results.sampleEnd();
+
+                if (checkReturnCode && (returnCode != expectedReturnCode)) {
+                    results.setSuccessful(false);
+                    responseData = "System did not return expected return code.  Expected ["+expectedReturnCode+"]. Returned ["+returnCode+"].";
+                    results.setSampleLabel("FAILED: " + getName());
+                } else {
+                    results.setSuccessful(true);
+                    responseData = "System Call Complete.";
+                    results.setSampleLabel(getName());
+                }
+            } catch (IOException ioe) {
+                results.setSuccessful(false);
+                responseData = "Exception occured whilst executing System Call: "+ioe;
+                results.setSampleLabel("ERROR: " + getName());
+            } catch (InterruptedException ie) {
+                results.setSuccessful(false);
+                responseData = "System Sampler Interupted whilst executing System Call: "+ie;
+                results.setSampleLabel("ERROR: " + getName());
+            }
+    
+            results.setResponseData((responseData+"\nProcess Output:\n"+nativeCommand.getOutResult()).getBytes());
+            
+        } catch (Exception e) {
+            results.setSuccessful(false);
+            results.setResponseData(("Unknown Exception caught: "+e).getBytes());
+            results.setSampleLabel("ERROR: " + getName());
+        }
+        return results;
+    }
+
+    /**
+     * 
+     * @return
+     */
+    public String getDirectory() {
+        return getPropertyAsString(DIRECTORY, FileServer.getDefaultBase());
+    }
+    
+    /**
+     * 
+     * @param directory
+     */
+    public void setDirectory(String directory) {
+        setProperty(DIRECTORY, directory, FileServer.getDefaultBase());
+    }
+
+    /**
+     * Sets the Command attribute of the JavaConfig object
+     * 
+     * @param command
+     *            the new Command value
+     */
+    public void setCommand(String command) {
+        setProperty(COMMAND, command);
+    }
+
+    /**
+     * Gets the Command attribute of the JavaConfig object
+     * 
+     * @return the Command value
+     */
+    public String getCommand() {
+        return getPropertyAsString(COMMAND);
+    }
+    
+    /**
+     * Set the arguments (parameters) for the JavaSamplerClient to be executed
+     * with.
+     * 
+     * @param args
+     *            the new arguments. These replace any existing arguments.
+     */
+    public void setArguments(Arguments args) {
+        setProperty(new TestElementProperty(ARGUMENTS, args));
+    }
+
+    /**
+     * Get the arguments (parameters) for the JavaSamplerClient to be executed
+     * with.
+     * 
+     * @return the arguments
+     */
+    public Arguments getArguments() {
+        return (Arguments) getProperty(ARGUMENTS).getObjectValue();
+    }
+    
+    /**
+     * @param checkit boolean indicates if we check or not return code
+     */
+    public void setCheckReturnCode(boolean checkit) {
+        setProperty(CHECK_RETURN_CODE, (new Boolean(checkit)).toString());
+    }
+    
+    /**
+     * @return boolean indicating if we check or not return code
+     */
+    public boolean getCheckReturnCode() {
+        return getPropertyAsBoolean(CHECK_RETURN_CODE);
+    }
+    
+    /**
+     * @param code expected return code
+     */
+    public void setExpectedReturnCode(int code) {
+        setProperty(EXPECTED_RETURN_CODE, Integer.toString(code));
+    }
+    
+    /**
+     * @return expected return code
+     */
+    public int getExpectedReturnCode() {
+        return getPropertyAsInt(EXPECTED_RETURN_CODE);
+    }
+
+}

Propchange: jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/SystemSampler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/gui/SystemSamplerGui.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/gui/SystemSamplerGui.java?rev=1332231&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/gui/SystemSamplerGui.java (added)
+++ jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/gui/SystemSamplerGui.java Mon Apr 30 15:05:46 2012
@@ -0,0 +1,186 @@
+/*
+ * 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.protocol.system.gui;
+
+import java.awt.BorderLayout;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JCheckBox;
+import javax.swing.JPanel;
+
+import org.apache.jmeter.config.Arguments;
+import org.apache.jmeter.config.gui.ArgumentsPanel;
+import org.apache.jmeter.gui.util.VerticalPanel;
+import org.apache.jmeter.protocol.system.SystemSampler;
+import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
+import org.apache.jmeter.testelement.TestElement;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.gui.JLabeledTextField;
+
+/**
+ * GUI for {@link SystemSampler}
+ */
+public class SystemSamplerGui extends AbstractSamplerGui implements ItemListener {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -2413845772703695934L;
+    
+    private JCheckBox checkReturnCode;
+    private JLabeledTextField desiredReturnCode;
+    private JLabeledTextField directory;
+    private JLabeledTextField command;
+    private ArgumentsPanel argsPanel;
+    
+    /**
+     * Constructor for JavaTestSamplerGui
+     */
+    public SystemSamplerGui() {
+        super();
+        init();
+    }
+
+    public String getLabelResource() {
+        return "system_sampler_title";
+    }
+
+    public String getStaticLabel() {
+        return JMeterUtils.getResString(getLabelResource());
+    }
+
+    /**
+     * Initialize the GUI components and layout.
+     */
+    private void init() {
+        setLayout(new BorderLayout());
+        setBorder(makeBorder());
+
+        add(makeTitlePanel(), BorderLayout.NORTH);
+       
+        JPanel panelb = new VerticalPanel();
+        panelb.add(makeReturnCodePanel());
+        panelb.add(Box.createVerticalStrut(5));
+        panelb.add(makeCommandPanel(), BorderLayout.CENTER);
+        
+        add(panelb, BorderLayout.CENTER);
+    }
+
+    /* Implements JMeterGuiComponent.createTestElement() */
+    public TestElement createTestElement() {
+        SystemSampler sampler = new SystemSampler();
+        modifyTestElement(sampler);
+        return sampler;
+    }
+
+    public void modifyTestElement(TestElement sampler) {
+        super.configureTestElement(sampler);
+        sampler.setProperty(SystemSampler.CHECK_RETURN_CODE, Boolean.toString(checkReturnCode.isSelected()));
+        if(checkReturnCode.isSelected()) {
+            sampler.setProperty(SystemSampler.EXPECTED_RETURN_CODE, desiredReturnCode.getText());
+        } else {
+            sampler.setProperty(SystemSampler.EXPECTED_RETURN_CODE, "");
+        }
+        sampler.setProperty(SystemSampler.COMMAND, command.getText());
+        ((SystemSampler)sampler).setArguments((Arguments)argsPanel.createTestElement());
+        sampler.setProperty(SystemSampler.DIRECTORY, directory.getText());
+    }
+
+    /* Overrides AbstractJMeterGuiComponent.configure(TestElement) */
+    @Override
+    public void configure(TestElement el) {
+        super.configure(el);
+        checkReturnCode.setSelected(el.getPropertyAsBoolean(SystemSampler.CHECK_RETURN_CODE));
+        desiredReturnCode.setText(el.getPropertyAsString(SystemSampler.EXPECTED_RETURN_CODE));
+        desiredReturnCode.setEnabled(checkReturnCode.isSelected());
+        command.setText(el.getPropertyAsString(SystemSampler.COMMAND));
+        argsPanel.configure((Arguments)el.getProperty(SystemSampler.ARGUMENTS).getObjectValue());
+        directory.setText(el.getPropertyAsString(SystemSampler.DIRECTORY));
+    }
+
+    /**
+     * @return JPanel return code config
+     */
+    private JPanel makeReturnCodePanel() {
+        JPanel panel = new JPanel();
+        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
+        panel.setBorder(BorderFactory.createTitledBorder(JMeterUtils.getResString("return_code_config_box_title")));
+        checkReturnCode = new JCheckBox(JMeterUtils.getResString("check_return_code_title"));
+        checkReturnCode.addItemListener(this);
+        desiredReturnCode = new JLabeledTextField(JMeterUtils.getResString("expected_return_code_title"));
+        desiredReturnCode.setSize(desiredReturnCode.getSize().height, 30);
+        panel.add(checkReturnCode);
+        panel.add(Box.createHorizontalStrut(5));
+        panel.add(desiredReturnCode);
+        checkReturnCode.setSelected(true);
+        return panel;
+    }
+    
+    /**
+     * @return JPanel Command + directory
+     */
+    private JPanel makeCommandPanel() {
+        JPanel panel = new JPanel(new BorderLayout());
+        panel.setBorder(BorderFactory.createTitledBorder(JMeterUtils.getResString("command_config_box_title")));
+        
+        JPanel cmdPanel = new JPanel();
+        cmdPanel.setLayout(new BoxLayout(cmdPanel, BoxLayout.X_AXIS));
+        
+        directory = new JLabeledTextField(JMeterUtils.getResString("directory_field_title"));
+        cmdPanel.add(directory);
+        cmdPanel.add(Box.createHorizontalStrut(5));
+        command = new JLabeledTextField(JMeterUtils.getResString("command_field_title"));
+        cmdPanel.add(command);
+        panel.add(cmdPanel, BorderLayout.NORTH);
+        panel.add(makeArgumentsPanel(), BorderLayout.CENTER);
+        return panel;
+    }
+    
+    /**
+     * @return JPanel Arguments Panel
+     */
+    private JPanel makeArgumentsPanel() {
+        argsPanel = new ArgumentsPanel(JMeterUtils.getResString("arguments_panel_title"), true);
+        return argsPanel;
+    }
+
+    /**
+     * @see org.apache.jmeter.gui.AbstractJMeterGuiComponent#clearGui()
+     */
+    @Override
+    public void clearGui() {
+        super.clearGui();
+        directory.setText("");
+        command.setText("");
+        argsPanel.clearGui();
+        desiredReturnCode.setText("");
+        checkReturnCode.setSelected(false);
+        desiredReturnCode.setEnabled(false);
+    }
+
+    public void itemStateChanged(ItemEvent e) {
+        if(e.getSource()==checkReturnCode) {
+            desiredReturnCode.setEnabled(e.getStateChange() == ItemEvent.SELECTED);
+        }
+    }
+}
\ No newline at end of file

Propchange: jmeter/trunk/src/protocol/native/org/apache/jmeter/protocol/system/gui/SystemSamplerGui.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1332231&r1=1332230&r2=1332231&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml (original)
+++ jmeter/trunk/xdocs/changes.xml Mon Apr 30 15:05:46 2012
@@ -41,6 +41,7 @@ Plugin writers : New interface org.apach
 public boolean applies(ConfigTestElement configElement);
 </p>
 
+<p>New System Sampler that can be used to execute commands on the local machine.</p>
 <!--  =================== Known bugs =================== -->
 
 <h2>Known bugs</h2>
@@ -168,6 +169,7 @@ Graph Full Results Listener has been rem
 <li>Bug 52938 - Webservice Sampler : Add a jmeter property soap.document_cache to control size of Document Cache</li>
 <li>Bug 52939 - Webservice Sampler : Make MaintainSession configurable</li>
 <li>Bug 53073 - Allow to assign the OUT result of a JDBC CALLABLE to JMeter variables</li>
+<li>Bug 53164 - New System Sampler</li>
 </ul>
 
 <h3>Controllers</h3>