Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ant-scripts/test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@
<jvmarg value="--add-opens=java.base/java.util=ALL-UNNAMED" />
<jvmarg value="--add-opens=java.base/java.util.concurrent=ALL-UNNAMED" />
<jvmarg value="--add-opens=java.base/java.util.regex=ALL-UNNAMED" />
<jvmarg value="--add-opens=java.base/java.util.stream=ALL-UNNAMED" />
<jvmarg value="--add-opens=java.base/java.io=ALL-UNNAMED" />
<jvmarg value="--add-opens=java.base/sun.nio.fs=ALL-UNNAMED" />

Expand Down
3 changes: 3 additions & 0 deletions samples/testsuite-performance/config/default.properties
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ com.xceptance.xlt.maximumTransactionRunTime = 900000
## Useful in case of severe server errors, etc.
com.xceptance.xlt.maxErrors = 1000

## Whether to use virtual threads instead of platform threads (default: false).
#com.xceptance.xlt.virtualThreads.enabled = false


################################################################################
#
Expand Down
3 changes: 3 additions & 0 deletions samples/testsuite-posters/config/default.properties
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ com.xceptance.xlt.maximumTransactionRunTime = 900000
## Useful in case of severe server errors, etc.
com.xceptance.xlt.maxErrors = 1000

## Whether to use virtual threads instead of platform threads (default: false).
#com.xceptance.xlt.virtualThreads.enabled = false


################################################################################
#
Expand Down
3 changes: 3 additions & 0 deletions samples/testsuite-showcases/config/default.properties
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ com.xceptance.xlt.maximumTransactionRunTime = 900000
## Useful in case of severe server errors, etc.
com.xceptance.xlt.maxErrors = 1000

## Whether to use virtual threads instead of platform threads (default: false).
#com.xceptance.xlt.virtualThreads.enabled = false


################################################################################
#
Expand Down
3 changes: 3 additions & 0 deletions samples/testsuite-template/config/default.properties
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ com.xceptance.xlt.maximumTransactionRunTime = 900000
## Useful in case of severe server errors, etc.
com.xceptance.xlt.maxErrors = 1000

## Whether to use virtual threads instead of platform threads (default: false).
#com.xceptance.xlt.virtualThreads.enabled = false


################################################################################
#
Expand Down
3 changes: 3 additions & 0 deletions samples/testsuite-xlt/config/default.properties
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ com.xceptance.xlt.maximumTransactionRunTime = 900000
## Useful in case of severe server errors, etc.
com.xceptance.xlt.maxErrors = 1000

## Whether to use virtual threads instead of platform threads (default: false).
#com.xceptance.xlt.virtualThreads.enabled = false


################################################################################
#
Expand Down
80 changes: 80 additions & 0 deletions src/main/java/com/xceptance/common/util/Holder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2005-2025 Xceptance Software Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.xceptance.common.util;

/**
* Simple Holder class that holds a value. Use this class to mimic a mutable reference.
*/
public class Holder<T>
{
/**
* The value.
*/
private T value;

/**
* Creates a new Holder instance and initializes it with a <code>null</code> value.
*/
public Holder()
{
this(null);
}

/**
* Creates a new Holder instance and initializes it with the given value.
*
* @param value
* the initial value of the holder
*/
public Holder(final T value)
{
this.value = value;
}

/**
* Returns the current value.
*
* @return the value
*/
public T get()
{
return value;
}

/**
* Sets the new value.
*
* @param value
* the new value
*/
public void set(T value)
{
this.value = value;
}

/**
* Removes the current value.
*
* @return the value just removed
*/
public T remove()
{
final T oldValue = value;
value = null;

return oldValue;
}
}
19 changes: 15 additions & 4 deletions src/main/java/com/xceptance/xlt/agent/LoadTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.xceptance.xlt.agentcontroller.TestUserConfiguration;
import com.xceptance.xlt.api.util.XltProperties;
import com.xceptance.xlt.common.XltConstants;
import com.xceptance.xlt.engine.XltThreadFactory;

/**
* Class responsible for running a load test.
Expand All @@ -37,17 +38,28 @@ public class LoadTest
*/
private static final long DEFAULT_GRACE_PERIOD = 30 * 1000;

/**
* The thread factory that creates either virtual threads or platform threads for the {@link LoadTestRunner}
* instances.
*/
private static final XltThreadFactory xltThreadFactory;

/**
* The configured time period [ms] to wait for threads to finish voluntarily before quitting the JVM.
*/
private static final long gracePeriod;

static
{
final long v = XltProperties.getInstance().getProperty(XltConstants.XLT_PACKAGE_PATH + ".hangingUsersGracePeriod",
DEFAULT_GRACE_PERIOD);
final XltProperties props = XltProperties.getInstance();

// grace period
final long v = props.getProperty(XltConstants.XLT_PACKAGE_PATH + ".hangingUsersGracePeriod", DEFAULT_GRACE_PERIOD);
gracePeriod = (v < 0) ? DEFAULT_GRACE_PERIOD : v;

// thread factory
final boolean useVirtualThreads = props.getProperty(XltConstants.PROP_VIRTUAL_THREADS_ENABLED, false);
xltThreadFactory = new XltThreadFactory(useVirtualThreads, false);
}

/**
Expand Down Expand Up @@ -85,8 +97,7 @@ public void run()
final AbstractExecutionTimer timer = ExecutionTimerFactory.createTimer(config);

// create runner for configuration
final LoadTestRunner runner = new LoadTestRunner(config, agentInfo, timer);
runner.setDaemon(true);
final LoadTestRunner runner = new LoadTestRunner(config, agentInfo, timer, xltThreadFactory);

// add runner to list of known runners
testRunners.add(runner);
Expand Down
53 changes: 44 additions & 9 deletions src/main/java/com/xceptance/xlt/agent/LoadTestRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.xceptance.xlt.api.engine.GlobalClock;
import com.xceptance.xlt.engine.DataManagerImpl;
import com.xceptance.xlt.engine.SessionImpl;
import com.xceptance.xlt.engine.XltThreadFactory;
import com.xceptance.xlt.engine.util.TimerUtils;

/**
Expand All @@ -40,7 +41,7 @@
*
* @author Jörg Werner (Xceptance Software Technologies GmbH)
*/
public class LoadTestRunner extends Thread
public class LoadTestRunner
{
/**
* Class logger instance.
Expand Down Expand Up @@ -72,6 +73,11 @@ public class LoadTestRunner extends Thread
*/
private volatile boolean aborted;

/**
* The main thread of this runner.
*/
private final Thread thread;

/**
* Creates a new LoadTestRunner object for the given load test configuration. Typically, multiple runners are
* started for one test case configuration, so the number of the current runner is passed as well.
Expand All @@ -82,19 +88,49 @@ public class LoadTestRunner extends Thread
* load test agent information
* @param timer
* the execution timer that controls this load test runner
* @param xltThreadFactory
* the thread factory to create the worker thread
*/
public LoadTestRunner(final TestUserConfiguration config, final AgentInfo agentInfo, final AbstractExecutionTimer timer)
public LoadTestRunner(final TestUserConfiguration config, final AgentInfo agentInfo, final AbstractExecutionTimer timer,
final XltThreadFactory xltThreadFactory)
{
// create a new thread group for each LoadTestRunner as a means
// to keep the main thread and any supporting threads together
super(new ThreadGroup(config.getUserId()), config.getUserId());

this.config = config;
this.agentInfo = agentInfo;
this.timer = timer;

status = new TestUserStatus();
status.setUserName(config.getUserId());

thread = xltThreadFactory.newThread(this::run);
thread.setName(config.getUserId());
}

/**
* Returns the thread this runner is using under the hood.
* <p>
* Note: For unit-testing only.
*
* @return the thread
*/
Thread getThread()
{
return thread;
}

/**
* Starts this runner.
*/
public void start()
{
thread.start();
}

/**
* Waits until this runner is finished.
*/
public void join() throws InterruptedException
{
thread.join();
}

/**
Expand All @@ -110,8 +146,7 @@ public TestUserStatus getTestUserStatus()
/**
* Runs the test case as configured in the test case configuration.
*/
@Override
public void run()
private void run()
{
try
{
Expand Down Expand Up @@ -196,7 +231,7 @@ public void run()
}
catch (final Exception ex)
{
log.error("Failed to run test as user: " + getName(), ex);
log.error("Failed to run test as user: " + thread.getName(), ex);

status.setState(TestUserStatus.State.Failed);
status.setException(ex);
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/xceptance/xlt/common/XltConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -509,4 +509,10 @@ private XltConstants()
* The name of the HTML output file for rendering the scorecard report page.
*/
public static final String SCORECARD_REPORT_HTML_FILENAME = "scorecard.html";

/*
* Virtual threads
*/

public static final String PROP_VIRTUAL_THREADS_ENABLED = XLT_PACKAGE_PATH + ".virtualThreads.enabled";
}
7 changes: 4 additions & 3 deletions src/main/java/com/xceptance/xlt/engine/RequestQueue.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.util.concurrent.ThreadFactory;

import com.xceptance.common.util.SynchronizingCounter;
import com.xceptance.common.util.concurrent.DaemonThreadFactory;
import com.xceptance.xlt.api.engine.Session;
import com.xceptance.xlt.api.util.XltLogger;

Expand Down Expand Up @@ -74,14 +73,16 @@ public class RequestQueue
* the web client to use
* @param threadCount
* the number of threads
* @param useVirtualThreads
* whether to use virtual threads instead of platform threads
*/
public RequestQueue(final XltWebClient webClient, final int threadCount)
public RequestQueue(final XltWebClient webClient, final int threadCount, final boolean useVirtualThreads)
{
this.webClient = webClient;
this.threadCount = threadCount;
parallelModeEnabled = true;

final ThreadFactory threadFactory = new DaemonThreadFactory(i -> Session.getCurrent().getUserID() + "-pool-" + i);
final ThreadFactory threadFactory = new XltThreadFactory(useVirtualThreads, true, Session.getCurrent().getUserID() + "-pool-");

executorService = Executors.newFixedThreadPool(threadCount, threadFactory);
ongoingRequestsCount = new SynchronizingCounter(0);
Expand Down
Loading