--- src/core/org/apache/jmeter/samplers/SampleResult.java 2008-03-12 13:02:10 +0000 +++ src/core/org/apache/jmeter/samplers/SampleResult.java 2008-03-23 12:55:47 +0000 @@ -26,6 +26,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; import org.apache.avalon.framework.configuration.Configuration; import org.apache.jmeter.assertions.AssertionResult; @@ -140,6 +142,38 @@ private String dataEncoding;// (is this really the character set?) e.g. // ISO-8895-1, UTF-8 + private static Method initNanoTimeMethod() { + try { + return System.class.getMethod("nanoTime", null); + } catch (NoSuchMethodException e) { + return null; + } + } + + private static boolean haveNanoTime() { + return nanoTimeMethod != null; + } + + private static long nanoTime() { + Long result = null; + try { + result = (Long) nanoTimeMethod.invoke(null, null); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + return result.longValue(); + } + + private static final Method nanoTimeMethod = initNanoTimeMethod(); + + // a reference time from the nanosecond clock + private static final long referenceTimeNsClock = haveNanoTime() ? sampleNsClockInMs() : Long.MIN_VALUE; + + private static final long referenceTimeMsClock = System.currentTimeMillis(); // a reference time from the + // millisecond clock + private long time = 0; // elapsed time private long latency = 0; // time to first response @@ -228,7 +262,7 @@ * create the sample finishing now, else starting now */ protected SampleResult(long elapsed, boolean atend) { - long now = System.currentTimeMillis(); + long now = currentTimeInMs(); if (atend) { setTimes(now - elapsed, now); } else { @@ -262,7 +296,7 @@ * desired elapsed time */ public static SampleResult createTestSample(long elapsed) { - long now = System.currentTimeMillis(); + long now = currentTimeInMs(); return createTestSample(now, now + elapsed); } @@ -280,6 +314,20 @@ stampAndTime(stamp, elapsed); } + private static long sampleNsClockInMs() { + return nanoTime() / 1000000; + } + + // Helper method to get 1 ms resolution timing. + public static long currentTimeInMs() { + if (haveNanoTime()) { + long elapsedInMs = sampleNsClockInMs() - referenceTimeNsClock; + return referenceTimeMsClock + elapsedInMs; + } else { + return System.currentTimeMillis(); + } + } + // Helper method to maintain timestamp relationships private void stampAndTime(long stamp, long elapsed) { if (startTimeStamp) { @@ -325,7 +373,7 @@ if (startTime != 0 || endTime != 0){ throw new RuntimeException("Calling setTime() after start/end times have been set"); } - long now = System.currentTimeMillis(); + long now = currentTimeInMs(); setTimes(now - elapsed, now); } @@ -805,7 +853,7 @@ */ public void sampleStart() { if (startTime == 0) { - setStartTime(System.currentTimeMillis()); + setStartTime(currentTimeInMs()); } else { log.error("sampleStart called twice", new Throwable("Invalid call sequence")); } @@ -817,7 +865,7 @@ */ public void sampleEnd() { if (endTime == 0) { - setEndTime(System.currentTimeMillis()); + setEndTime(currentTimeInMs()); } else { log.error("sampleEnd called twice", new Throwable("Invalid call sequence")); } @@ -831,7 +879,7 @@ if (pauseTime != 0) { log.error("samplePause called twice", new Throwable("Invalid call sequence")); } - pauseTime = System.currentTimeMillis(); + pauseTime = currentTimeInMs(); } /** @@ -842,7 +890,7 @@ if (pauseTime == 0) { log.error("sampleResume without samplePause", new Throwable("Invalid call sequence")); } - idleTime += System.currentTimeMillis() - pauseTime; + idleTime += currentTimeInMs() - pauseTime; pauseTime = 0; } @@ -943,7 +991,7 @@ * */ public void latencyEnd() { - latency = System.currentTimeMillis() - startTime - idleTime; + latency = currentTimeInMs() - startTime - idleTime; } /** --- test/src/org/apache/jmeter/samplers/TestSampleResult.java 2008-03-12 13:02:10 +0000 +++ test/src/org/apache/jmeter/samplers/TestSampleResult.java 2008-03-23 12:59:52 +0000 @@ -98,6 +98,10 @@ assertEquals("sample of size 100 bytes", res.getSampleLabel()); } + private static long sampleClock() { + return SampleResult.currentTimeInMs(); + } + public void testSubResults() throws Exception { // This test tries to emulate a http sample, with two // subsamples, representing images that are downloaded for the @@ -106,8 +110,8 @@ // Sample that will get two sub results, simulates a web page load SampleResult resWithSubResults = new SampleResult(); - long beginTest = System.currentTimeMillis(); - + long beginTest = sampleClock(); + resWithSubResults.sampleStart(); Thread.sleep(100); resWithSubResults.setBytes(300); @@ -142,8 +146,8 @@ resNoSubResults2.sampleEnd(); long sample2Time = resNoSubResults2.getTime(); - long overallTime = System.currentTimeMillis() - beginTest; - + long overallTime = sampleClock() - beginTest; + assertTrue(resNoSubResults2.isSuccessful()); assertEquals(200, resNoSubResults2.getBytes()); assertEquals("sample with no subresults", resNoSubResults2.getSampleLabel());