Monthly Archives: April 2016

A loadtest plugin to select the transition from a probability matrix

An important part of loadtesting with Markov chains is choosing which transition the test should take. This boils down to generating a random number and then seeing in which of the transitions in the probability matrix that number belongs to.

In a previous post I showed how to generate a random number. In this post we’ll see how we can decide which transition to actually take based upon the probabilities from the matrix.

Webtests can include various types of plugins that execute requests based on some boolean condition. These type of plugins are called ConditionalRule plugins. I created a simple plugin that determines if the random number falls within a user specified range. This allows me to implement the following kind of logic in my webtest:

Picture showing how the plug-in is included in a .webtest

Here is the code for the plugin:

using System;
using Microsoft.VisualStudio.TestTools.WebTesting;
using System.ComponentModel;
using Microsoft.VisualStudio.TestTools.WebTesting.Rules;

namespace LoadTestPlugins
{

    [DisplayNameAttribute("Number in range")]
    [DescriptionAttribute("Determines if the number in the context parameter is in the specified range")]
    public class NumberInRange : ConditionalRule
    {

        #region Methods
        public override void CheckCondition(object sender, ConditionalEventArgs e)
        {
            Int32 Input = Convert.ToInt32(e.WebTest.Context[this.ContextParameterName]);
            e.IsMet = (Input >= this.LowerBound && Input <= this.UpperBound) ? true : false;
            return;
        }

        public override string StringRepresentation()
        {
            return string.Format("{0} (Number in range [{1} - {2}])"
                , this.Description
                , this.LowerBound
                , this.UpperBound);
        }
        
        #endregion

        #region Properties
        // Properties
        [Description("Name of context parameter that contains the number"),
        DisplayName("Context parameter"), IsContextParameterName(true)]
        public string ContextParameterName {get; set;}

        [Description("The lower bound"),
        DisplayName("Lower bound")]
        public Int32 LowerBound { get; set; }


        [Description("The upper (inclusive) bound"),
        DisplayName("Upper bound")]
        public Int32 UpperBound { get; set; }

        [Description("Your description of this rule"),
        DisplayName("Description")]
        public string Description { get; set; }
        
        #endregion
    }
}

A loadtest plugin to simulate random chance

An important part of loadtesting with Markov chains is choosing which transition the test should take. This boils down to generating a random number and then seeing in which of the transitions in the probability matrix that number belongs to.

The plugin code below generates a random number between your specified lower- and upper bound and places it into the specified context parameter. Its very similar to the out-of-the box plugin. However Visual Studio’s plugin can only be executed once when a webtest starts. I needed a new random number every time that my loops executes.

using System;
using System.ComponentModel;
using Microsoft.VisualStudio.TestTools.WebTesting;
using Microsoft.VisualStudio.TestTools.WebTesting.Rules;

namespace LoadTestPlugins
{

    [DisplayNameAttribute("Generate random number")]
    [DescriptionAttribute("Generates a random number during a request")]
    public class GenerateRandomNumber : WebTestRequestPlugin
    {

        #region Methods
        private void GenerateIt(WebTestContext Context)
        {
            Context[this.ContextParameterName] = new Random().Next(this.LowerBound, this.UpperBound);
        }

        public override void PostRequest(object sender, PostRequestEventArgs e)
        {
            if(this.BeforeRequest == false)
            {
                this.GenerateIt(e.WebTest.Context);
            }
        }
        
        public override void PreRequest(object sender, PreRequestEventArgs e)
        {
            if(this.BeforeRequest == true)
            {
                this.GenerateIt(e.WebTest.Context);
            }
        }
        #endregion

        #region Properties
        [Description("Name of context parameter to store the number in"),
        DisplayName("Context parameter"), IsContextParameterName(true)]
        public string ContextParameterName {get; set;}

        [Description("The lower bound"),
        DisplayName("Lower bound"),
        DefaultValue(1)]
        public Int32 LowerBound { get; set; }


        [Description("The upper (inclusive) bound"),
        DisplayName("Upper bound"),
        DefaultValue(100)]
        public Int32 UpperBound { get; set; }

        [Description("Whether to generate the number before or after the request has executed"),
        DisplayName("Apply before request"),
        DefaultValue(true)]
        public bool BeforeRequest { get; set; }
        #endregion
    }
}