Search code examples
jmeterjmeter-pluginsjmeter-5.0jmeter-4.0jmeter-maven-plugin

Create JMeter JSR223 Sampler programmatically using Java code


I have filecopy code in java. I need to know the process to set the "script" property of jsr223 sampler. Please look at the following codes and let me know if anything wrong. FileCopy Code :-

copyFileUsingStream Method :-

package FileCopyHelper;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

 public class FileCopyGroup {
     public static void copyFileUsingStream(File source, File dest) {
          FileInputStream is = null;
          FileOutputStream os = null;
          try {
                 is = new FileInputStream(source);
                 os = new FileOutputStream(dest);
                 byte[] buffer = new byte[1024];
                 int length;
             while ((length = is.read(buffer)) > 0) {
             os.write(buffer, 0, length);
             }
           } catch (Exception ex) {
               System.out.println("Unable to copy file:" + ex.getMessage());
           } finally {
           try {
               is.close();
               os.close();
           } catch (Exception ex) {
          }
        }

        }
     }

Main Method:-

import java.io.File;


import static FileCopyHelper.FileCopyGroup.copyFileUsingStream;

public class SampleFileCopy {

public static void main(String[] args) {
    File source = new File("C:\\Users\\hp\\Downloads\\Invitation.pdf");
    File dest = new File("C:\\Users\\hp\\Desktop\\cpoied4.pdf"); 
          
    copyFileUsingStream(source,dest);

    }
  }

Created JSR223 Sampler Programmatically:-

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.config.gui.ArgumentsPanel;
import org.apache.jmeter.control.LoopController;
import org.apache.jmeter.control.gui.LoopControlPanel;
import org.apache.jmeter.control.gui.TestPlanGui;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.protocol.java.sampler.JSR223Sampler;
import org.apache.jmeter.reporters.ResultCollector;
import org.apache.jmeter.reporters.Summariser;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testbeans.gui.TestBeanGUI;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jmeter.threads.ThreadGroup;
import org.apache.jmeter.threads.gui.ThreadGroupGui;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.collections.HashTree;

import java.io.File;
import java.io.FileOutputStream;



public class JMeterFromScratch {

    public static void main(String[] argv) throws Exception {

        File jmeterHome = new File("C:\\Users\\hp\\Downloads\\apache-jmeter-5.5\\apache-jmeter-5.5");
        String slash = System.getProperty("file.separator");

        if (jmeterHome.exists()) {
            File jmeterProperties = new File(jmeterHome.getPath() + slash + "bin" + slash + "jmeter.properties");
            if (jmeterProperties.exists()) {
                //JMeter Engine
                StandardJMeterEngine jmeter = new StandardJMeterEngine();

                //JMeter initialization (properties, log levels, locale, etc)
                JMeterUtils.setJMeterHome(jmeterHome.getPath());
                JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
                //JMeterUtils.initLogging();// you can comment this line out to see extra log messages of i.e. DEBUG level
                JMeterUtils.initLocale();

                // JMeter Test Plan, basically JOrphan HashTree
                HashTree testPlanTree = new HashTree();

                // JSR223 Sampler

                JSR223Sampler jsr223Sampler = new JSR223Sampler();
                jsr223Sampler.setName("JSR223 Sampler");
                jsr223Sampler.setProperty("cacheKey", "true");
                jsr223Sampler.setProperty("script", "How-Set-the-FileCopy-Script");
                jsr223Sampler.setProperty("scriptLanguage", "java");
                jsr223Sampler.setProperty(TestElement.TEST_CLASS, JSR223Sampler.class.getName());
                jsr223Sampler.setProperty(TestElement.GUI_CLASS, TestBeanGUI.class.getName());


                // Loop Controller
                LoopController loopController = new LoopController();
                loopController.setLoops(1);
                loopController.setFirst(true);
                loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
                loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
                loopController.initialize();

                // Thread Group
                ThreadGroup threadGroup = new ThreadGroup();
                threadGroup.setName("Example Thread Group");
                threadGroup.setNumThreads(1);
                threadGroup.setRampUp(1);
                threadGroup.setSamplerController(loopController);
                threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
                threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());

                // Test Plan
                TestPlan testPlan = new TestPlan("Create JMeter Script From Java Code");
                testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
                testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
                testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());

                // Construct Test Plan from previously initialized elements
                testPlanTree.add(testPlan);
                HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
                threadGroupHashTree.add(jsr223Sampler);


                // save generated test plan to JMeter's .jmx file format
                SaveService.saveTree(testPlanTree, new FileOutputStream(jmeterHome + slash + "JSRSample2.jmx"));

                //add Summarizer output to get test progress in stdout like:
                // summary =      2 in   1.3s =    1.5/s Avg:   631 Min:   290 Max:   973 Err:     0 (0.00%)
                Summariser summer = null;
                String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
                if (summariserName.length() > 0) {
                    summer = new Summariser(summariserName);
                }


                // Store execution results into a .jtl file
                String logFile = jmeterHome + slash + "JSRSample2.jtl";
                ResultCollector logger = new ResultCollector(summer);
                logger.setFilename(logFile);
                testPlanTree.add(testPlanTree.getArray()[0], logger);

                // Run Test Plan
                jmeter.configure(testPlanTree);
                jmeter.run();

                System.out.println("Test completed. See " + jmeterHome + slash + "JSRSample2.jtl file for results");
                System.out.println("JMeter .jmx script is available at " + jmeterHome + slash + "JSRSample2.jmx");
                System.exit(0);

            }
        }

        System.err.println("jmeter.home property is not set or pointing to incorrect location");
        System.exit(1);


    }
}

Please suggest solutions for setting the filecopy script in the JSR223 sampler script property.


Solution

  • You need to change these lines:

    jsr223Sampler.setProperty("script", "How-Set-the-FileCopy-Script");
    jsr223Sampler.setProperty("scriptLanguage", "java");
    

    to these:

    jsr223Sampler.setProperty("script", "File source = new File(\"C:\\\\Users\\\\hp\\\\Downloads\\\\Invitation.pdf\");\n" +
            "File dest = new File(\"C:\\\\Users\\\\hp\\\\Desktop\\\\cpoied4.pdf\");\n" +
            "\n" +
            "copyFileUsingStream(source, dest);\n" +
            "\n" +
            "static void copyFileUsingStream(File source, File dest) {\n" +
            "    FileInputStream is = null;\n" +
            "    FileOutputStream os = null;\n" +
            "    try {\n" +
            "        is = new FileInputStream(source);\n" +
            "        os = new FileOutputStream(dest);\n" +
            "        byte[] buffer = new byte[1024];\n" +
            "        int length;\n" +
            "        while ((length = is.read(buffer)) > 0) {\n" +
            "            os.write(buffer, 0, length);\n" +
            "        }\n" +
            "    } catch (Exception ex) {\n" +
            "        System.out.println(\"Unable to copy file:\" + ex.getMessage());\n" +
            "    } finally {\n" +
            "        try {\n" +
            "            is.close();\n" +
            "            os.close();\n" +
            "        } catch (Exception ex) {\n" +
            "        }\n" +
            "    }\n" +
            "\n" +
            "}");
    jsr223Sampler.setProperty("scriptLanguage", "groovy");
    

    As if you want to provide the code via "Script" tab you need to put literally everything there:

    enter image description here

    Another option is to compile your FileCopyGroup class into a .jar and drop it to JMeter Classpath, this way you will be able to just import it and call the copyFileUsingStream function where required.

    Also be informed of the fact that when you choose java as the scripting language it's not "real" Java, it's Beanshell interpreter so I believe groovy would be a way better choice.