Forum Discussion

AndyHughes's avatar
AndyHughes
Regular Contributor
14 years ago

Request Rate not reaching desired level.

I've noticed this a few times now when doing load tests and wondered if anyone could shed some light on it. I use a ramp generator to reach a certain level in say 5 mins and then plot the request rate and ave response time. I expect the graph to show the request rate rising consistently over the 5 min period up to the maximum value, but instead the request rate becomes erratic and levels off, never reaching the required level. This is making it impossible to get a good graph of response time with increasing request rate.
I have attached one of the graphs I have produced. The blue line represents the request rate which should have steadily increased to 400.
Also could you explain why the request rate become more and more erratic as the test progresses.

3 Replies

  • Hi Andy!

    The Ramp component is old and it's our goal to replace it with the Ramp Sequence component as soon as we're certain that nobody will miss the Ramp component.

    The Ramp component has been improved since beta 2 to be much better when it comes to the things that you point out. If you would like to give it a go, please use this code:

    /**
    * Ramps up, holds steady and then ramps down.
    *
    * @id com.eviware.MultiRamp
    * @name Ramp Sequence
    * @category generators
    * @help http://loadui.org/Generators/ramp-sequence.html
    * @nonBlocking true
    */

    import java.util.concurrent.TimeUnit

    createProperty( 'rampLength', Long, 10 ) { calculateAcceleration() }
    createProperty( 'peakRate', Long, 10 ) { calculateAcceleration() }
    createProperty( 'peakLength', Long, 10 )
    createProperty( 'peakRateUnit', String, 'sec' ) { calculateAcceleration(); redraw() }

    future = null
    cancellingFuture = null
    startTime = 0
    triggersSent = 0
    calculateAcceleration()

    onAction( 'START' ) {
    calculateAcceleration()
    startTime = currentTime()
    hasPeaked = false
    scheduleNext( startTime )
    triggersSent = 0
    }

    onAction( 'STOP' ) {
    future?.cancel( true )
    cancellingFuture?.cancel( true )
    startTime = null
    }

    scheduleNext = { wakeTime ->
    def t0 = getT0()

    // println( "Too late with: " + wakeTime - getT0() )
    // println( "Missed triggers: " + a*(t0**2 - wakeTime**2)/2 )

    if( t0 >= rampLength.value && !hasPeaked ) {
    hasPeaked = true
    triggersSent = 0
    def delay = 1000000/peakRate.value
    if( peakRateUnit.value == 'min' )
    delay = 1000000/(peakRate.value/60)
    future = scheduleAtFixedRate( { trigger() }, delay, delay, TimeUnit.MICROSECONDS )
    cancellingFuture = schedule( {
    future?.cancel( true )
    a = a*-1
    scheduleNext( rampLength.value )
    }, peakLength.value, TimeUnit.SECONDS )
    } else if( t0 >= 0 ) {
    def triggersThatShouldHaveBeenSent = 0
    if( hasPeaked ) {
    triggersThatShouldHaveBeenSent = Math.floor( a*t0**2/2 - a*rampLength.value**2/2 )
    }
    else
    triggersThatShouldHaveBeenSent = Math.floor( a*t0**2/2 )

    while( triggersSent < triggersThatShouldHaveBeenSent ) {
    trigger()
    triggersSent++
    }

    t1 = Math.sqrt( 2/a + t0**2 )
    future?.cancel( true )
    def diff = Math.abs( t1 - getT0() )
    if( !Double.isNaN( diff ) ) {
    future = schedule( {
    trigger()
    triggersSent++
    scheduleNext( t1 )
    }, ( diff*1000000) as long, TimeUnit.MICROSECONDS )
    }
    }
    }

    def getT0() {
    if( !startTime ) return 0
    relativeTime = currentTime() - startTime
    if( relativeTime >= rampLength.value + peakLength.value )
    return startTime + rampLength.value*2 + peakLength.value - currentTime()
    if( relativeTime >= rampLength.value )
    return rampLength.value
    return relativeTime
    }

    def redraw() {
    layout {
    property( property:rampLength, label:'Ramp Duration\n(sec)', min:1 )
    property( property:peakLength, label:'Peak Duration\n(sec)', min:0 )
    separator( vertical:true )
    property( property:peakRate, label:'Peak Rate\n(VU/' + peakRateUnit.value + ')', min:1 )
    property( property:peakRateUnit, label:'Unit', options:['sec','min'] )
    separator( vertical:true )
    box( widget:'display' ) {
    node( label:'Rate', content: { if( getT0() > 0 ) String.format( '%7.1f', peakRateUnit.value == 'sec' ? a*getT0() : a*getT0()*60 ) else 0 }, constraints:'w 45!' )
    }
    }
    }
    redraw()

    compactLayout {
    box( widget:'display' ) {
    node( label:'Rate', content: { if( getT0() > 0 ) String.format( '%7.1f', peakRateUnit.value == 'sec' ? a*getT0() : a*getT0()*60 ) else 0 }, constraints:'w 45!' )
    }
    }

    def currentTime() {
    System.currentTimeMillis() / 1000
    }

    def calculateAcceleration() {
    if( peakRateUnit.value == 'sec' )
    a = peakRate.value / rampLength.value
    else
    a = (peakRate.value/60) / rampLength.value
    }


    Regards!

    Henrik
    SmartBear Software
  • AndyHughes's avatar
    AndyHughes
    Regular Contributor
    wow. Thats looks great ......but what exactly do i do with that code?