From af9729b9f097831ceae88302ddccf7eda35870e2 Mon Sep 17 00:00:00 2001 From: h-arlt <4641065+h-arlt@users.noreply.github.com> Date: Thu, 4 Jul 2024 16:08:51 +0200 Subject: [PATCH 1/3] GH #501: ErrorCounter timer thread prevents JVM to exit (#505) - create Timer thread as daemon thread such that VM can shutdown when all user threads have terminated Co-authored-by: Hartmut Arlt --- .../com/xceptance/xlt/engine/resultbrowser/ErrorCounter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/xceptance/xlt/engine/resultbrowser/ErrorCounter.java b/src/main/java/com/xceptance/xlt/engine/resultbrowser/ErrorCounter.java index 03028a314..a0683597a 100644 --- a/src/main/java/com/xceptance/xlt/engine/resultbrowser/ErrorCounter.java +++ b/src/main/java/com/xceptance/xlt/engine/resultbrowser/ErrorCounter.java @@ -149,7 +149,7 @@ private ErrorCounter(final XltPropertiesImpl properties) this.resetInterval = tmpInterval * 1000; if (resetInterval > 0) { - timer = new Timer("ErrorCounter-ResetTimer"); + timer = new Timer("ErrorCounter-ResetTimer", true); } else { From cc0157e81a975e098de03fd62ffc96315042804c Mon Sep 17 00:00:00 2001 From: h-arlt <4641065+h-arlt@users.noreply.github.com> Date: Thu, 4 Jul 2024 17:21:37 +0200 Subject: [PATCH 2/3] GH 502: Real-time metrics reporting stopped working in XLT 7.0.0 (#506) - invoke 'Metrics.getInstance()' as late as possible such that session is properly initialized (esp. its 'loadTest' flag) - fix broken unit tests Co-authored-by: Hartmut Arlt --- .../xceptance/xlt/engine/DataManagerImpl.java | 18 ++-- .../com/xceptance/xlt/engine/SessionImpl.java | 2 +- .../xlt/agent/DataRecordLoggingTest.java | 87 ++++++++++--------- .../xlt/engine/DataManagerImplTest.java | 20 ++--- 4 files changed, 67 insertions(+), 60 deletions(-) diff --git a/src/main/java/com/xceptance/xlt/engine/DataManagerImpl.java b/src/main/java/com/xceptance/xlt/engine/DataManagerImpl.java index 89559d20e..79771e72c 100644 --- a/src/main/java/com/xceptance/xlt/engine/DataManagerImpl.java +++ b/src/main/java/com/xceptance/xlt/engine/DataManagerImpl.java @@ -21,6 +21,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; +import java.util.Optional; +import java.util.function.Supplier; import com.xceptance.common.util.CsvUtils; import com.xceptance.xlt.api.engine.Data; @@ -70,9 +72,9 @@ public class DataManagerImpl implements DataManager private volatile BufferedWriter logger; /** - * Our reference to metrics + * Our metrics provider. */ - private final Metrics metrics; + private final Supplier metrics; /** * Back-reference to session using this data manager. @@ -88,9 +90,9 @@ public class DataManagerImpl implements DataManager * @param session * the session that should use this data manager * @param metrics - * a metrics target for real time loggiing + * a metrics target for real time logging */ - protected DataManagerImpl(final Session session, final Metrics metrics) + protected DataManagerImpl(final Session session, final Supplier metrics) { this.session = session; this.metrics = metrics; @@ -104,8 +106,7 @@ protected DataManagerImpl(final Session session, final Metrics metrics) */ protected DataManagerImpl(final Session session) { - this.session = session; - this.metrics = null; + this(session, null); } /** @@ -139,10 +140,7 @@ public void logEvent(final String eventName, final String message) public void logDataRecord(final Data stats) { // update metrics for real-time reporting - if (metrics != null) - { - metrics.updateMetrics(stats); - } + Optional.ofNullable(metrics).map(Supplier::get).ifPresent((m) -> m.updateMetrics(stats)); // Check whether the data record falls into the logging period. // Take the data record's (start) time as the criterion. diff --git a/src/main/java/com/xceptance/xlt/engine/SessionImpl.java b/src/main/java/com/xceptance/xlt/engine/SessionImpl.java index 6e1a9429a..7e8db487f 100644 --- a/src/main/java/com/xceptance/xlt/engine/SessionImpl.java +++ b/src/main/java/com/xceptance/xlt/engine/SessionImpl.java @@ -323,7 +323,7 @@ public SessionImpl(final XltPropertiesImpl properties) totalAgentCount = 1; // create the session-specific helper objects - dataManagerImpl = new DataManagerImpl(this, Metrics.getInstance()); + dataManagerImpl = new DataManagerImpl(this, Metrics::getInstance); shutdownListeners = new ArrayList(); networkDataManagerImpl = new NetworkDataManagerImpl(); diff --git a/src/test/java/com/xceptance/xlt/agent/DataRecordLoggingTest.java b/src/test/java/com/xceptance/xlt/agent/DataRecordLoggingTest.java index 6cedba485..eaff9373e 100644 --- a/src/test/java/com/xceptance/xlt/agent/DataRecordLoggingTest.java +++ b/src/test/java/com/xceptance/xlt/agent/DataRecordLoggingTest.java @@ -107,7 +107,10 @@ { SessionImpl.class, DataManagerImpl.class, GlobalClock.class, AbstractExecutionTimer.class }) -@PowerMockIgnore({"javax.*", "org.xml.*", "org.w3c.dom.*"}) +@PowerMockIgnore( + { + "javax.*", "org.xml.*", "org.w3c.dom.*" +}) public class DataRecordLoggingTest { /** @@ -662,7 +665,13 @@ private void mockDataManagerCreation() throws Exception public DataManagerImpl answer(InvocationOnMock invocation) throws Throwable { // limit to constructor new DataManagerImpl(Session) and avoid using (Session, Metrics) - final DataManagerImpl instance = Whitebox.invokeConstructor(DataManagerImpl.class, invocation.getArguments()[0]); + final DataManagerImpl instance = Whitebox.invokeConstructor(DataManagerImpl.class, new Class[] + { + Session.class + }, new Object[] + { + invocation.getArgument(0, Session.class) + }); return mockDataManagers.computeIfAbsent(Thread.currentThread().getThreadGroup(), __ -> createMockDataManager(instance)); } }); @@ -915,15 +924,15 @@ public static void setGenericLoadTestImplementationFor(final Thread thread, fina enum KindOfLoadTestClass { - /** - * Use a load test class that is derived from {@link AbstractTestCase} - */ - XltDerived(GenericLoadTestClasses.XltDerived.class, true), + /** + * Use a load test class that is derived from {@link AbstractTestCase} + */ + XltDerived(GenericLoadTestClasses.XltDerived.class, true), - /** - * Use a load test class that is not derived from anything except Object - */ - NotDerived(GenericLoadTestClasses.NotDerived.class, false); + /** + * Use a load test class that is not derived from anything except Object + */ + NotDerived(GenericLoadTestClasses.NotDerived.class, false); private KindOfLoadTestClass(Class genericTestClassObject, boolean isXltDerived) { @@ -955,35 +964,35 @@ public boolean isXltDerived() enum TestExecutionThreadStrategy { - /** - * Use a {@link LoadTestRunner} thread to execute the load test class - */ - LoadTestRunner(true) - { - @Override - public Thread createThreadFor(Class loadTestClassObject, TestUserConfiguration testUserConfiguration, AgentInfo agentInfo, - DataRecordLoggingTest thisTestInstance) - { - return new LoadTestRunner(testUserConfiguration, agentInfo, dummyExecutionTimer()); - } - - }, - - /** - * Use a simple thread that will just call JUnit's - * {@linkplain Request#aClass(Class) Request.aClass(Class)}.getRunner().run(RunNotifier) to execute - * the load test class - */ - JUnitClassRequestRunner(false) - { - @Override - public Thread createThreadFor(Class loadTestClassObject, TestUserConfiguration testUserConfiguration, AgentInfo agentInfo, - DataRecordLoggingTest thisTestInstance) - { - final Runnable r = () -> Request.aClass(loadTestClassObject).getRunner().run(new RunNotifier()); - return new Thread(new ThreadGroup("JUnitRequestRunner"), r); - } - }; + /** + * Use a {@link LoadTestRunner} thread to execute the load test class + */ + LoadTestRunner(true) + { + @Override + public Thread createThreadFor(Class loadTestClassObject, TestUserConfiguration testUserConfiguration, AgentInfo agentInfo, + DataRecordLoggingTest thisTestInstance) + { + return new LoadTestRunner(testUserConfiguration, agentInfo, dummyExecutionTimer()); + } + + }, + + /** + * Use a simple thread that will just call JUnit's + * {@linkplain Request#aClass(Class) Request.aClass(Class)}.getRunner().run(RunNotifier) to execute + * the load test class + */ + JUnitClassRequestRunner(false) + { + @Override + public Thread createThreadFor(Class loadTestClassObject, TestUserConfiguration testUserConfiguration, AgentInfo agentInfo, + DataRecordLoggingTest thisTestInstance) + { + final Runnable r = () -> Request.aClass(loadTestClassObject).getRunner().run(new RunNotifier()); + return new Thread(new ThreadGroup("JUnitRequestRunner"), r); + } + }; private TestExecutionThreadStrategy(final boolean usesLoadTestRunner) { diff --git a/src/test/java/com/xceptance/xlt/engine/DataManagerImplTest.java b/src/test/java/com/xceptance/xlt/engine/DataManagerImplTest.java index fc75728a0..6ef2c5f56 100644 --- a/src/test/java/com/xceptance/xlt/engine/DataManagerImplTest.java +++ b/src/test/java/com/xceptance/xlt/engine/DataManagerImplTest.java @@ -77,7 +77,7 @@ public void after() throws IOException public void loggingPeriod() throws IOException { var session = new TestSession("TName"); - var dm = new DataManagerImpl(session, metrics); + var dm = new DataManagerImpl(session, () -> metrics); dm.setStartOfLoggingPeriod(8000L); dm.setEndOfLoggingPeriod(9000L); @@ -125,7 +125,7 @@ public void loggingOnAndOff() throws IOException GlobalClock.installFixed(1666646047921L); var session = new TestSession("TName"); - var dm = new DataManagerImpl(session, metrics); + var dm = new DataManagerImpl(session, () -> metrics); dm.enableLogging(); assertTrue(dm.isLoggingEnabled()); @@ -161,7 +161,7 @@ public void loggingOnAndOff_Legacy() throws IOException GlobalClock.installFixed(1666646047921L); var session = new TestSession("TName"); - var dm = new DataManagerImpl(session, metrics); + var dm = new DataManagerImpl(session, () -> metrics); dm.setLoggingEnabled(true); assertTrue(dm.isLoggingEnabled()); @@ -198,7 +198,7 @@ public void close() throws IOException GlobalClock.installFixed(1666646047921L); var session = new TestSession("TName"); - var dm = new DataManagerImpl(session, metrics); + var dm = new DataManagerImpl(session, () -> metrics); dm.logEvent("EventName1", "Just a message1"); @@ -226,7 +226,7 @@ public void logEvent() throws IOException GlobalClock.installFixed(1666646047921L); var session = new TestSession("TName"); - var dm = new DataManagerImpl(session, metrics); + var dm = new DataManagerImpl(session, () -> metrics); dm.logEvent("EventName", "Just a message"); @@ -293,7 +293,7 @@ public void simpleConstructor() throws IOException public void dontCountOtherThanEvent() throws IOException { var session = new TestSession("TName"); - var dm = new DataManagerImpl(session, metrics); + var dm = new DataManagerImpl(session, () -> metrics); var c = new CustomData("Custom"); c.setTime(1000L); @@ -315,7 +315,7 @@ public void dontCountOtherThanEvent() throws IOException public void logEventAppend() throws IOException { var session = new TestSession("TName"); - var dm = new DataManagerImpl(session, metrics); + var dm = new DataManagerImpl(session, () -> metrics); GlobalClock.installFixed(1666646047921L); dm.logEvent("EventName1", "M1"); @@ -328,7 +328,7 @@ public void logEventAppend() throws IOException session.clear(); session = new TestSession("TName"); - dm = new DataManagerImpl(session, metrics); + dm = new DataManagerImpl(session, () -> metrics); GlobalClock.installFixed(1666646047923L); dm.logEvent("EventName3", "M3"); @@ -357,7 +357,7 @@ public void logEventAppend() throws IOException public void numberOfEvents() { var session = new TestSession("TName"); - var dm = new DataManagerImpl(session, metrics); + var dm = new DataManagerImpl(session, () -> metrics); GlobalClock.installFixed(1666646047921L); dm.logEvent("EventName1", "M1"); @@ -376,7 +376,7 @@ public void numberOfEvents() public void directLogging() throws IOException { var session = new TestSession("TName"); - var dm = new DataManagerImpl(session, metrics); + var dm = new DataManagerImpl(session, () -> metrics); var e = new EventData(); e.setTime(1000L); From 716f8671c639e708ccf337874c4a9d5f0cea1aff Mon Sep 17 00:00:00 2001 From: Joerg Werner <4639399+jowerner@users.noreply.github.com> Date: Thu, 4 Jul 2024 18:10:43 +0200 Subject: [PATCH 3/3] prepared release 8.2.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4725abcc6..3c336fb6e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.xceptance xlt - 8.2.0 + 8.2.1 jar XLT