Localhost connection refused when integrating WireMock and JMeter - jmeter

I'm trying to integrate Wiremock into a Jmeter test plan so that every time I execute the test plan it will start up an instance of WireMock in the beginning and then run tests I have outlined. I followed this answer (https://stackoverflow.com/a/49130518/12912945) but the problem I am having is that I always get the error:
Response message:Non HTTP response message: Connect to localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
From what I can see, the Wiremock server never starts even though I have the following code in a JSR223 Sampler at the beginning of the test plan:
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
public class WireMockTest {
public static void main(String[] args) {
WireMockServer wireMockServer = new WireMockServer();
configureFor("127.0.0.1", 8080);
wireMockServer.start();
StubMapping foo = stubFor(get(urlEqualTo("/some/thing"))
.willReturn(aResponse()
.withStatus(200)
.withBody("Hello World")));
wireMockServer.addStubMapping(foo);
}
}
Could anyone point me in the right direction of how to correctly integrate the two, I have tried adding to the classpath but I feel like I have not done this correctly or I'm missing something
Thank you!

You're defining the main function but I failed to see where you're executing it. In other words your Wiremock initialization code isn't getting executed at all.
You need to explicitly call this main function in order to get your code executed, to get this done add the next line to the end of your script:
WireMockTest.main()
Once done the JSR223 Sampler will invoke the code inside the main function and the Wiremock server will be started.
Another option is to remove these class and function declarations and just use
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
WireMockServer wireMockServer = new WireMockServer();
configureFor("127.0.0.1", 8080);
wireMockServer.start();
StubMapping foo = stubFor(get(urlEqualTo("/some/thing"))
.willReturn(aResponse()
.withStatus(200)
.withBody("Hello World")));
wireMockServer.addStubMapping(foo);
as the script you define in the JSR223 Test elements don't require an entry point
Check out Apache Groovy - Why and How You Should Use It article for more information about Groovy scripting in JMeter tests.

Related

Getting 404 Not Found for basic spring rest api tutorial - 'hello world'

I am trying to create a rest api web application that can be eventually deployed into a container environment. I downloaded quite a few tutorials from spring.io to other websites as well but each time I use the exact repos I get a 404 error for the simple request.
To simplify it further I reduced it to 2 classes in one package:
project hierarchy
Main class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
Controller Class:
#RestController
#RequestMapping("/")
public class RESTController {
private final AtomicLong counter = new AtomicLong();
private static final String template = "Hello, %s!";
/*
* REST API Test Methods
*/
#RequestMapping( "/greeting" )
public String greeting() {
return "It's working...!";
}
And of course the actual request:
http://localhost:8080/test_rest_api/greeting
HTTP Status 404 – Not Found
Type Status Report
Message /test_rest_api/greeting
Description The origin server did not find a current representation for the target resource or is not
willing to disclose that one exists.
Apache Tomcat/8.5.43
That is running on server by Run As - ; if I select Run as java application and select springboot the following error occurs:
java.lang.IllegalArgumentException: Sources must not be empty at
org.springframework.util.Assert.notEmpty(Assert.java:467)
I finally figured it out and it was a stupid mistake. I added the name of the project as part of the domain of the request url.
http://localhost:8080/test_rest_api/greeting
vs
http://localhost:8080/greeting

How to set port for client call in Spring boot Integration Test using RestAssured?

I am struggling to write a proper Integration Test for my application. I use rest assured and also maven failsafe plugin.
Currently I get an exception like this:
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost/api/deactivate/1": Connect to localhost:80 [localhost/127.0.0.1] failed: Connection refused (Connection refused); nested exception is org.apache.http.conn.HttpHostConnectException: Connect to localhost:80 [localhost/127.0.0.1] failed: Connection refused (Connection refused)
My assumption is that there is a problem with missing port (8080) in url. However I do not know why.
I have two modules, one is calling another. The first one is running on port 8081 and the second one 8080.
This is test config for module 1 (module 2 config is similar but another port). My tests extend this class:
public abstract class AbstractDeactivationIT {
#BeforeAll
public static void configureRestAssured() {
RestAssured.port = Integer.parseInt(System.getProperty("it.deactivation.port", "8081"));
System.out.println("RestAssured: using port " + RestAssured.port);
// authentication config
...
var mapper = ObjectMapperFactory.defaultConfig().build();
RestAssured.config = RestAssured.config()
.logConfig(logConfig().enableLoggingOfRequestAndResponseIfValidationFails())
.objectMapperConfig(objectMapperConfig().jackson2ObjectMapperFactory((type, s) -> mapper));
}
}
My test:
#Test
void testDeactivation_forCorrectRequestData() {
// #formatter:off
given()
.contentType(JSON)
.body(DeactivationRequest.builder()
...
.build()
).
when()
.post("/api/deactivations").
then()
.statusCode(201);
// #formatter:on
}
While debugging I noticed that first call is build correctly (with port 8081), but the client call is without 8080 port. I have both urls with ports in my application-local.yml files. I also have similar test but in the opposite direction, so module 2 is calling module 1 and that works fine without any port problems. Urls are built correctly.
The RestAssured.port is a static field. If you run both tests in the same failsafe configuration then the order of the tests can mess with the static attribute.
Do not use the static RestAssured config but construct the proper url with port for every RestAssured call.
You can use the get(), post(), etc methods with an url instead of a relative path (e.g.: .when().get("http://myhost.org:80/doSomething");). Source: https://github.com/rest-assured/rest-assured/wiki/Usage#default-values
In your case it could be:
given()
.contentType(JSON)
.body(DeactivationRequest.builder()
...
.build()
).
when()
.post("http://localhost:8081/api/deactivations").
then()
.statusCode(201);

Mockito MockedStatic when() "Cannot resolve method"

I am trying to use Mockito MockedStatic to mock a static method.
I am using mockito-core and mockito-inline version 3.6.0 with Spring Boot and maven.
I can't manage to make the mock work, I have a "Cannot resolve method post" on the Unirest::post that you can see in the code below:
#Test
public void test() {
try (MockedStatic<Unirest> mock = Mockito.mockStatic(Unirest.class)) {
mock.when(Unirest::post).thenReturn(new HttpRequestWithBody(HttpMethod.POST, "url"));
}
}
The Unirest class comes from the unirest-java package.
Did someone encounter this issue already and have a solution?
The method Unirest.post(String url) takes an argument and hence you can't refer to it using Unirest::post.
You can use the following:
#Test
void testRequest() {
try (MockedStatic<Unirest> mockedStatic = Mockito.mockStatic(Unirest.class)) {
mockedStatic.when(() -> Unirest.post(ArgumentMatchers.anyString())).thenReturn(...);
someService.doRequest();
}
}
But keep in mind that you have to mock now the whole Unirest usage and every method call on it as the mock returns null by default.
If you want to test your HTTP clients take a look at WireMock or the MockWebServer from OkHttp. This way you test your clients with real HTTP communication and can test also corner cases like slow responses or 5xx HTTP codes.

Obfuscate or Secure Jmeter Script

I am working on Jmeter Scripts from sometime now, there is a need to secure the Jmeter script and majorly make it unreadable for external stakeholders. My expectation is to obfuscate or deliver the script as some kind of JAR or executable. I need some ideas or workaround to start with.
Thanks
Senz79
It is possible to run existing JMeter script from Java code or create a JMeter test purely in Java using JMeter API so it is not a problem to create an executable binary which will run your test and obfuscate it.
Example Java code to run a JMeter test:
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[] argv) 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 existing .jmx Test Plan
HashTree testPlanTree = SaveService.loadTree(new File("/tmp/jmeter/test.jmx"));
Summariser summer = null;
String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
if (summariserName.length() > 0) {
summer = new Summariser(summariserName);
}
ResultCollector logger = new ResultCollector(summer);
logger.setFilename("/tmp/jmeter/test.jtl");
testPlanTree.add(testPlanTree.getArray()[0], logger);
// Run JMeter Test
jmeter.configure(testPlanTree);
jmeter.run();
}
}
See the following reference material to get started:
Five Ways To Launch a JMeter Test without Using the JMeter GUI
Bytecode obfuscation

JMeter not showing Sampler JAR

Moderators, please read through once before marking it as a duplicate.
This is my first time creating a custom Sampler in JMeter. I am trying a simple query.
public class CustomJavaSampler extends AbstractJavaSamplerClient implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5838315675279087366L;
#Override
public SampleResult runTest(JavaSamplerContext arg0) {
SampleResult result = new SampleResult();
result.sampleStart(); // start stopwatch
JMeterVariables vars = JMeterContextService.getContext().getVariables();
vars.putObject("search", "DoASearch");
JMeterContextService.getContext().setVariables(vars);
result.sampleEnd(); // stop stopwatch
result.setSuccessful(true);
result.setResponseMessage("Successfull");
result.setResponseCodeOK(); // 200 code
return result;
}
}
I have created a jar and I've added it to the lib/ext folder in jmeter. But I am not able to see the class in Java Request sampler.
I have enabled debug logs.
log_level.jmeter=DEBUG
log_level.jmeter.junit=DEBUG
log_level.jmeter.control=DEBUG
log_level.jmeter.testbeans=DEBUG
log_level.jmeter.engine=DEBUG
log_level.jmeter.threads=DEBUG
log_level.jmeter.gui=WARN
log_level.jmeter.testelement=DEBUG
log_level.jmeter.util=DEBUG
log_level.jmeter.util.classfinder=DEBUG
log_level.jmeter.test=DEBUG
log_level.jmeter.protocol.http=DEBUG
# For CookieManager, AuthManager etc:
log_level.jmeter.protocol.http.control=DEBUG
log_level.jmeter.protocol.ftp=WARN
log_level.jmeter.protocol.jdbc=DEBUG
log_level.jmeter.protocol.java=WARN
log_level.jmeter.testelements.property=DEBUG
log_level.jorphan=DEBUG
log_file=jmeter-debug.log
The complete jmeter log is http://pastebin.com/T39iUhFW
And also why is the log showing a "did not find" message for the /lib jars?
Nothing is wrong with your code, CustomJavaSampler is displayed in Java Request classnames.
So perhaps it's something with your .jar file. Can you upload it somewhere so we could take a look? I guess it's samp.jar.
By the way, setting a variable is a very "light" operation which can be done via Beanshell Sampler which is almost Java compatible.
If you need to perform some load - next option is JSR223 Sampler and "groovy" which is a "balance" between simplicity and productivity so if you will need to make some changes in your code you won't have to recompile, replace jars, restart JMeter, etc.

Resources