Skip to content

Commit

Permalink
Fixed junit-vintage version
Browse files Browse the repository at this point in the history
Refactored JSON object of /threads endpoint, more cohesive with /test/summary

Fixed #18 - Implemented ThreadListener

Renamed to /docs and renamed example-testplan

WIP #21 - Added swagger and swagger UI for GitHub pages

Done #21 - swagger.yaml + SwaggerUI

Updated docs and moved index.html + swagger.yaml to docs

Moved index back

Changed reference for threads schema

Removed 3 dashes (---)

Moved swagger and index.html in /docs

Removed /dist and moved content into /docs/swaggerui

Grouped up endpoints with tags

feat: added /test/errors endpoint

fix #35: use queue to keep track of incoming thread count change requests
  • Loading branch information
anthonygauthier committed Jul 29, 2023
1 parent 0cde076 commit 25d9055
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 53 deletions.
19 changes: 1 addition & 18 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
<java.version>1.9</java.version>
<junit.version>4.13.1</junit.version>
<junit.jupiter.version>5.0.0</junit.jupiter.version>
<junit.vintage.version>${junit.version}.0</junit.vintage.version>
<junit.vintage.version>4.12.3</junit.vintage.version>
<junit.jupiter.version>5.0.0</junit.jupiter.version>
<junit.platform.version>1.0.0</junit.platform.version>
<org.apache.jmeter.version>5.3</org.apache.jmeter.version>
Expand Down Expand Up @@ -247,23 +247,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
<configuration> <!-- add this to disable checking -->
<additionalparam>-Xdoclint:none</additionalparam>
<detectJavaApiLink>false</detectJavaApiLink>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package io.github.delirius325.jmeter.config.livechanges;

import io.github.delirius325.jmeter.config.livechanges.api.App;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import org.apache.jmeter.config.ConfigTestElement;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.engine.event.LoopIterationEvent;
Expand All @@ -17,13 +24,10 @@
import org.apache.jmeter.threads.JMeterVariables;
import org.apache.jmeter.threads.ThreadGroup;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.SearchByClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Properties;
import io.github.delirius325.jmeter.config.livechanges.api.App;

/**
* Class that contains executes all the logic for the REST API to communicate with JMeter
Expand All @@ -38,16 +42,15 @@ public class LiveChanges extends ConfigTestElement implements TestBean, LoopIter

// Static Attributes - available to other classes
private static int staticCalcRate;
private static int activeThreads;
private static JMeterVariables jMeterVariables;
private static Properties jMeterProperties;
private static HashSet<ThreadGroup> testThreadGroups = new HashSet<>();
private static ThreadGroup activeThreadGroup = new ThreadGroup();
private static boolean stopTest;
private static HashTree testPlanTree;
private static StandardJMeterEngine jMeterEngine;
private static SamplerMap samplerMap = new SamplerMap();
private static boolean stopThreadsFromAPI;
private static Map<String, Queue<Map<String, Object>>> changeQueueMap = new ConcurrentHashMap<>();

/**
* Method that is executed when the test has started
Expand Down Expand Up @@ -140,12 +143,15 @@ public void threadFinished() {
* @param threadName String
*/
public static void checkForThreadChanges(ThreadGroup threadGroup, LoopIterationEvent event, String threadName) {
// this if condition is necessary to verify if we are dealing with the correct thread group
if(threadGroup.getName().equals(activeThreadGroup.getName())) {
if(activeThreads != threadGroup.numberOfActiveThreads() && event.getIteration() != 1) {
int diff = threadGroup.numberOfActiveThreads() - activeThreads;
Queue<Map<String, Object>> changeQueue = changeQueueMap.get(threadGroup.getName());
if (null != changeQueue) {
Map<String, Object> changeMap = changeQueue.poll();
if (null != changeMap) {
int desiredThreadCount = (int) changeMap.get("threadNum");

int diff = threadGroup.numberOfActiveThreads() - desiredThreadCount;

if(diff != 0) {
if (diff != 0) {
for(int i=0; i < Math.abs(diff); i++) {
if(diff < 0) {
threadGroup.addNewThread(0, jMeterEngine);
Expand All @@ -154,13 +160,7 @@ public static void checkForThreadChanges(ThreadGroup threadGroup, LoopIterationE
stopThreadsFromAPI = true;
}
}
} else {
// gracefully stop threads
threadGroup.stop();
threadGroup.waitThreadsStopped();
}
} else {
activeThreads = threadGroup.numberOfActiveThreads();
}
}
}
Expand Down Expand Up @@ -195,6 +195,22 @@ public void checkForPropertyChanges(Properties props, LoopIterationEvent event)
private void startServer() {
try {
testPlanTree = SaveService.loadTree(new File(testPlanFile));
SearchByClass<ThreadGroup> ts = new SearchByClass<>(ThreadGroup.class);
testPlanTree.traverse(ts);
// initialize the Map of Queues to keep track of incoming change requests
// this only works if the thread group names are unique
// we relied on the name for thread group overrides too
Collection<ThreadGroup> objs = ts.getSearchResults();
if (!objs.isEmpty()) {
for (ThreadGroup tg : objs) {
// don't need to track disabled thread group
if (tg.isEnabled()) {
changeQueueMap.putIfAbsent(tg.getName(),
new ConcurrentLinkedDeque<Map<String, Object>>());
}
}
}

stopTest = false;
this.app = new App(this.httpServerPort);
this.app.start();
Expand All @@ -220,22 +236,19 @@ private void finalizeTest() {
/**
* Getters / Setters
*/
public static Map<String, Queue<Map<String, Object>>> getChangeQueueMap() {
return changeQueueMap;
}
public int getHttpServerPort() {
return this.httpServerPort;
}
public void setHttpServerPort(int port) {
this.httpServerPort = port;
}
public static int getActiveThreads() {
return activeThreads;
}
public static SamplerMap getSamplerMap() { return samplerMap; }
public static StandardJMeterEngine getjMeterEngine() { return jMeterEngine; }
public static ThreadGroup getActiveThreadGroup() { return activeThreadGroup; }
public static boolean getStopTest() { return stopTest; }
public static void setStopTest(boolean stop) { stopTest = stop; }
public static void setActiveThreadGroup(ThreadGroup tg) { activeThreadGroup = tg; }
public static void setActiveThreads(int num) { activeThreads = num;}
public static JMeterVariables getjMeterVariables() { return jMeterVariables; }
public static void setjMeterVariables(JMeterVariables vars) { jMeterVariables = vars; }
public static Properties getjMeterProperties() { return jMeterProperties; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

public class SamplerMap {
private HashMap<String, ResultHolder> map;
private HashMap<String, SampleResult> rawMap;

public SamplerMap(){
this.map = new HashMap<>();
Expand All @@ -20,9 +21,13 @@ public void add(SampleResult sr) {

resultHolder.calculate(sr);
this.map.put(sr.getSampleLabel(), resultHolder);
this.rawMap.put(sr.getSampleLabel(), sr);
}

public HashMap<String, ResultHolder> getMap() {
return map;
}
public HashMap<String, SampleResult> getRawMap() {
return rawMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.github.delirius325.jmeter.config.livechanges.SamplerMap;
import io.github.delirius325.jmeter.config.livechanges.helpers.GenericHelper;
import io.github.delirius325.jmeter.config.livechanges.helpers.JSONHelper;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.threads.JMeterContextService;
import org.json.JSONArray;
import org.json.JSONObject;
Expand Down Expand Up @@ -90,4 +91,32 @@ public Response getTestSummary() {

return Response.ok(jsonArray.toString()).build();
}

@GET
@Path("/errors")
@Produces(MediaType.APPLICATION_JSON)
public Response getTestErrors() {
JSONArray jsonArray = new JSONArray();
SamplerMap samplerMap = LiveChanges.getSamplerMap();
for(Map.Entry<String, SampleResult> entry : samplerMap.getRawMap().entrySet()) {
try {
SampleResult sr = entry.getValue();
if(!sr.isSuccessful()) {
JSONObject parentObject = new JSONObject();
JSONObject childObject = new JSONObject();

// construct JSON objects and add to array
childObject.put("errorCode", sr.getResponseCode());
childObject.put("errorMessage", sr.getResponseMessage());
childObject.put("errorData", sr.getResponseDataAsString());
parentObject.put(sr.getSampleLabel(), childObject);
jsonArray.put(parentObject);
}
} catch (Exception e) {
e.printStackTrace();
}
}

return Response.ok(jsonArray.toString()).build();
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package io.github.delirius325.jmeter.config.livechanges.api.resources;

import java.io.IOException;
import java.util.HashMap;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.jmeter.threads.ThreadGroup;
import org.json.JSONObject;
import io.github.delirius325.jmeter.config.livechanges.LiveChanges;
import io.github.delirius325.jmeter.config.livechanges.helpers.JSONHelper;
import io.github.delirius325.jmeter.config.livechanges.helpers.ThreadGroupHelper;
import org.apache.jmeter.threads.ThreadGroup;
import org.json.JSONObject;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;

/**
* Base endpoint for the ThreadResource class
Expand All @@ -34,8 +38,13 @@ public Response modifySpecificThread(String request, @PathParam("name") String t
JSONHelper.jsonSetInfo(json, "error", String.format("Thread Group %s does not exist.", threadGroupName));
return Response.ok(json.toString()).build();
}
LiveChanges.setActiveThreads(Integer.parseInt(json.get("threadNum").toString()));
LiveChanges.setActiveThreadGroup(threadGroup);

// add incoming thread change request to queue
HashMap<String, Object> changeMap = new HashMap<String, Object>();
changeMap.put("threadNum", Integer.parseInt(json.get("threadNum").toString()));

LiveChanges.getChangeQueueMap().get(threadGroupName).add(changeMap);

JSONHelper.jsonSetInfo(json, "success", "Changed number of active threads.");
return Response.ok(json.toString()).build();
}
Expand Down

0 comments on commit 25d9055

Please sign in to comment.