Conversion Error in JMeter through Java. What dependencies are missing? - java

From https://www.blazemeter.com/blog/5-ways-launch-jmeter-test-without-using-jmeter-gui, I have this test file:
public class JMeterTests {
StandardJMeterEngine jmeter;
HashTree testPlanTree;
#BeforeEach
void init() throws Exception {
// JMeter Engine
jmeter = new StandardJMeterEngine();
// Initialize Properties, logging, locale, etc.
JMeterUtils.loadJMeterProperties("src/test/java/com/tests/JMeterTests.java");
JMeterUtils.setJMeterHome("/usr/local/Cellar/jmeter/5.4.1");
JMeterUtils.initLocale();
// Initialize JMeter SaveService
SaveService.loadProperties();
// Load existing .jmx Test Plan
FileInputStream in = new FileInputStream("src/test/jmeter/my.jmx");
testPlanTree = SaveService.loadTree(in); // <-- testPlanTree is null, did not load
in.close();
}
#Test
void fromExistingJmx() throws MalformedURLException {
// Run JMeter Test
jmeter.configure(testPlanTree); // <-- Fails since testPlanTree is null
jmeter.run();
}
}
As a result, I get this error:
ERROR 2021-10-19 13:29:31.301 [jmeter.s] (): Conversion error com.thoughtworks.xstream.converters.ConversionException: org.apache.jmeter.extractor.json.jsonpath.JSONPostProcessor : org.apache.jmeter.extractor.json.jsonpath.JSONPostProcessor
---- Debugging information ----
message : org.apache.jmeter.extractor.json.jsonpath.JSONPostProcessor
cause-exception : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message : org.apache.jmeter.extractor.json.jsonpath.JSONPostProcessor
class : org.apache.jorphan.collections.ListedHashTree
required-type : org.apache.jorphan.collections.ListedHashTree
converter-type : org.apache.jmeter.save.converters.HashTreeConverter
path : /jmeterTestPlan/hashTree/hashTree/hashTree[4]/hashTree/JSONPostProcessor
line number : 207
I've already confirmed my.jmx works in GUI mode.

From https://www.blazemeter.com/blog/5-ways-launch-jmeter-test-without-using-jmeter-gui, you have the following statement:
Have the required JMeter jars from /lib and especially /lib/ext folders of your JMeter installation in your project or module class path.
If it is not clear enough get Apache JMeter Components » 5.4.1 library in your project classpath
Also you made a mistake in copying and pasting this line:
JMeterUtils.loadJMeterProperties("src/test/java/com/tests/JMeterTests.java");
it should point to jmeter.properties file, preferably the original one.

Related

How to create a XML report by executing a JAR

I want to develop a stand-alone test-solution delivered as a jar that can be used in a CI/CD environment without being recompiled all the time. Therefore I packed a fat-jar from a multi-maven-module containing a few libaries, a Spring Boot application and a submodule called test-runner.
Executing the fat-jar from within GitLab CI/CD works, but I think that was only the first half of it. I want to produce a JUnit XML report to output the test-results. What I understood from my research is that I would have to implement my own reporter. Is there a more complete example out there?
The test runner
public class Runner {
SummaryGeneratingListener listener = new SummaryGeneratingListener();
public void runOne() {
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(selectClass(MyTest.class)).build();
Launcher launcher = LauncherFactory.create();
TestPlan testPlan = launcher.discover(request);
launcher.registerTestExecutionListeners(listener);
launcher.execute(testPlan);
}
public static void resultReport(Result result) {
System.out.println("Finished. Result: Failures: " + result.getFailureCount() + ". Ignored: "
+ result.getIgnoreCount() + ". Tests run: " + result.getRunCount() + ". Time: "
+ result.getRunTime() + "ms.");
}
public static void main(String[] args) {
Runner runner = new Runner();
runner.runOne();
TestExecutionSummary summary = runner.listener.getSummary();
summary.printTo(new PrintWriter(System.out));
}
}
Background:
My test-solution is generic and uses a configuration file to parameterize the tests. All tests run in parallel versus a system-under-test. So before this attempt all gitlab-jobs called mvn test to execute the tests and generate the reports, but it recompiled everything every run. I thought about speeding things up.
To generate XML reports, you can use the LegacyXmlReportGeneratingListener with a path to save your reports to as first argument:
LegacyXmlReportGeneratingListener xmlListener = new LegacyXmlReportGeneratingListener(Paths.get("reports"), new PrintWriter(System.out));
In your runOne() method, you need to register your listener accordingly:
public void runOne() {
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(selectClass(MyTest.class)).build();
Launcher launcher = LauncherFactory.create();
TestPlan testPlan = launcher.discover(request);
launcher.registerTestExecutionListeners(listener);
launcher.registerTestExecutionListeners(xmlListener);
launcher.execute(testPlan);
}
This will generate one XML file per test root in the folder you passed to the listener during initialization.
More information can be found in the JavaDoc
You can use Console launcher to geneate Junit5 xml reports
java -jar junit-platform-console-standalone-1.6.2.jar #junitArgs.txt --reports-dir=reports
junitArgs.txt file has following info:
-classpath fat jar path
--scan-classpath

Java file setWritable in JVM with privileges

I'm building Apache Flink from source using Gitlab CI with image java:8u111-jdk, and find that tests on file permissions failed because file permissions are not respected.
One of the unit tests is like:
#Test
public void testDeleteDirectory() throws Exception {
// deleting a non-existent file should not cause an error
File doesNotExist = new File(tmp.newFolder(), "abc");
FileUtils.deleteDirectory(doesNotExist);
// deleting a write protected file should throw an error
File cannotDeleteParent = tmp.newFolder();
File cannotDeleteChild = new File(cannotDeleteParent, "child");
try {
assumeTrue(cannotDeleteChild.createNewFile());
assumeTrue(cannotDeleteParent.setWritable(false));
assumeTrue(cannotDeleteChild.setWritable(false));
FileUtils.deleteDirectory(cannotDeleteParent);
fail("this should fail with an exception");
}
catch (AccessDeniedException ignored) {
// this is expected
}
finally {
//noinspection ResultOfMethodCallIgnored
cannotDeleteParent.setWritable(true);
//noinspection ResultOfMethodCallIgnored
cannotDeleteChild.setWritable(true);
}
}
And the test result is:
testDeleteDirectory(org.apache.flink.util.FileUtilsTest) Time elapsed: 0.022 sec <<< FAILURE!
java.lang.AssertionError: this should fail with an exception
at org.junit.Assert.fail(Assert.java:88)
at org.apache.flink.util.FileUtilsTest.testDeleteDirectory(FileUtilsTest.java:129)
When I dug deeper into the codes, I found the following statements in java.io.File :
On some platforms it may be possible to start the Java virtual machine with special privileges that allow it to modify files that disallow write operations.
So I suspect it's something wrong with the CI environment. How can I further debug the problem? Thanks!
Environment:
docker image: java:8u111-jdk
OS kernel: Linux 4.9.0-8-amd64 x86_64
distribution: Debian 8
JDK version: openjdk 1.8.0_111
The problem is that we run this code as root user, so we are able to delete write protected files.

Initialization Error expected a file cucumber to run a .jar

I have an automation test that I use Cucumber, Junit and I can run with Java Application.
Runner Class:
#RunWith(Cucumber.class)
#CucumberOptions(strict = false, features = "src/main/java/FaixaVS_NaoCadastrado/FaixaVS_NaoCadastrado/FaixaVS_NaoCadastrado.feature", glue = { "StepDefinition" }, format = { "pretty",
"json:C:/Automação Receba Em Casa/Evidências/FVS_NaoCadastrado/Relatório/cucumber.json" }, tags = { "~#ignore" })
public class Runner {
}
Jar Class:
public class Jar {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(Runner.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
}
}
I can run it inside Eclipse as Java Application, but when I Export it like a Runnable jar and run it I receive the follow massage from CMD:
C:\Users\c.guiao.de.oliveira>java -jar
C:\Users\c.guiao.de.oliveira\Desktop\FVS_NaoCadastrado.jar
initializationError(FaixaVS_NaoCadastrado.FaixaVS_NaoCadastrado.Runner):
Expected a file URL:rsrc:cucumber-java-1.2.3.jar
Can you help me?
Few options:
Verify that the path you are using to get resource is correct. I
encounter tests that IntelliJ (that is not case sensitive when it
comes to resource path) executed successfully and maven clean
install failed.
Verify that cucumber dependencies are part of the jar. It can work in IntelliJ if you mistakenly added it to the classpath instead of adding it to the pom.xml file.

Launch jmeter from junit test

Is there any way to integrate a recorded jmeter script( which tests the load exerted by a recorded series of actions executed by multiple users) in a selenium/junit test case). such that i just execute that selenium/junit test case with java, and it gives me the performance results of the junit report?
I have found posts telling how to integrate selenium webdriver into jmeter, but not the other way around.
You can execute existing JMeter test using JMeter Java API, example code would look like:
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.reporters.ResultCollector;
import org.apache.jmeter.reporters.Summariser;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.collections.HashTree;
import java.io.File;
public class JMeterFromCode {
public static void main(String[] args) throws Exception {
// JMeter Engine
StandardJMeterEngine jmeter = new StandardJMeterEngine();
// Initialize Properties, logging, locale, etc.
JMeterUtils.loadJMeterProperties("/tmp/jmeter/bin/jmeter.properties");
JMeterUtils.setJMeterHome("/tmp/jmeter");
JMeterUtils.initLogging();// you can comment this line out to see extra log messages of i.e. DEBUG level
JMeterUtils.initLocale();
// Initialize JMeter SaveService
SaveService.loadProperties();
// Load Test Plan
HashTree testPlanTree = SaveService.loadTree(new File("/tmp/jmeter/bin/test.jmx"));
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 = "/tmp/jmeter/bin/test.jtl";
ResultCollector logger = new ResultCollector(summer);
logger.setFilename(logFile);
testPlanTree.add(testPlanTree.getArray()[0], logger);
// Run JMeter Test
jmeter.configure(testPlanTree);
jmeter.run();
}
}
Replace:
all occurrences of /tmp/jmeter - with path to your JMeter installation
/tmp/jmeter/bin/test.jmx - with path to the .jmx file, containing the recorded JMeter script
/tmp/jmeter/bin/test.jtl - with the desired location of the .jtl results file
See Five Ways To Launch a JMeter Test without Using the JMeter GUI article for more information on the possibilities of executing a JMeter test, maybe you will find an easier integration solution as JMeter tests can be executed via Maven plugin or Ant Task along with Selenium tests.

How can I read the MANIFEST.MF file during the test execution?

I am trying to automate acceptance test using TestLink, Cucumber, Jenkins and Maven. To do that, I am asking to read the MANIFEST.MF file created by Maven. I have to do it during the test execution.
I found out this example of code :
`public static String readVersion() throws IOException {
InputStream in = VersionUtil.class.getResourceAsStream("/META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(in);
// Lire la propriété "Implementation-Version" du Manifest
String version = manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
return version;
}`
But I am getting a NullPointerException when trying to execute it... Do you have any idea why ?
I am launching Maven with the simple command : mvn package test.
I think the problem comes from the moment when this code is launching, I should launch it after the package phase, is there any way to do that ?
Thank you !
I think you can try the code below, since most classloader can be cast to URLClassLoader
URLClassLoader cl = (URLClassLoader) getClass().getClassLoader();
try {
URL url = cl.findResource("META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(url.openStream());
...
} catch (IOException E) {
// handle
}

Categories