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
    }
}