0
votes

I have the following JSR223 Sampler which reads the image changes it a bit and sends a POST multipart/form-data request. I see that it is extensively using CPU compared to HTTP Sampler but I can't use HTTP sampler as it doesn't support changing the image without saving to file system.

Appreciate if anyone has any input to optimize the script in JSR223 sampler so it doesn't extensively lot of CPU.

import org.apache.http.HttpHeaders
import org.apache.http.client.config.RequestConfig
import org.apache.http.client.methods.HttpUriRequest
import org.apache.http.client.methods.RequestBuilder
import org.apache.http.conn.ssl.NoopHostnameVerifier
import org.apache.http.conn.ssl.SSLConnectionSocketFactory
import org.apache.http.conn.ssl.TrustStrategy
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.HttpClients
import org.apache.http.ssl.SSLContextBuilder
import org.apache.http.util.EntityUtils
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.HttpMultipartMode;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.awt.Graphics;
import java.io.ByteArrayOutputStream;
import org.apache.http.entity.ContentType;

import java.security.cert.CertificateException
import java.security.cert.X509Certificate

List<String> sendRequest(String url, String method, String body) {


RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout(40000)
        .setSocketTimeout(50000)
        .build();

BufferedImage image = ImageIO.read(new File("/home/4567/loadtest/Bank.JPG"));
Graphics graphics = image.getGraphics();
graphics.setFont(graphics.getFont().deriveFont(16f));
graphics.drawString("User " + ctx.getThreadNum() + '-' + Math.random()  +"; iteration: " + ctx.getVariables().getIteration(), 50, 50);
graphics.dispose();
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", bytes);

final MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
multipartEntity.setMode(HttpMultipartMode.STRICT);
multipartEntity.addBinaryBody("File", bytes.toByteArray(),ContentType.IMAGE_JPEG, "Bank.JPG");


HttpUriRequest request = RequestBuilder.create(method)
        .setConfig(requestConfig)
        .setUri(url)
        .setHeader("x-ibm-client-id","248a20f3-c39b-45d0-b26a-9019c26e9be8")
        .setHeader("X-Client-Id","2861D410-773B-4DD9-AE74-882116B08856")
        .setHeader("ResponseMinLatencyMs","45")
        .setHeader("ResponseMaxLatencyMs","55")
        .setEntity(multipartEntity.build())
        .build();

   // String req = "REQUEST:" + "User " + ctx.getThreadNum() + "; iteration: " + ctx.getVariables().getIteration() + " " + request.getRequestLine() + "\n";

def builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        return true;
    }
});
def trustAllFactory = new SSLConnectionSocketFactory(builder.build(), new NoopHostnameVerifier());

HttpClients.custom().setSSLSocketFactory(trustAllFactory).build().withCloseable { httpClient ->

    httpClient.execute(request).withCloseable { response ->

       // String res = "RESPONSE:" + "User " + ctx.getThreadNum() + "; iteration: " + ctx.getVariables().getIteration() + " " + response.getStatusLine()  + (response.getEntity() != null ? EntityUtils.toString(response.getEntity()) : "") + "\n";

       // log.info(req + "\n" + res);

       // return Arrays.asList(req, res);
       response.close()
    }
    httpClient.close()
}
image.flush()
bytes.flush()
bytes.close()

}

sendRequest("https://test-server.com/upload", "POST", "");
1

1 Answers

0
votes
  1. StackOverflow is not a code-writing service and asking someone do optimise the code you didn't even write is something you should do i.e. on sites like Toptal
  2. I believe normal HTTP Request sampler doesn't change the images before sending the request that's why it is not that CPU intensive.
  3. Looking into Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For! article it seems that Java it still the best choice in terms of performance and resources usage so you might want to re-implement your code in Java and use JUnit or Java request samplers
  4. If you run up above 85% of CPU on your JMeter machine most probably you won't get accurate results because JMeter won't be able to send requests fast enough, consider going for Distributed Testing