Sunday, September 15, 2013

Using WCAT Scenario Creator

Stress and Load testing on Windows used to be done using a utility called WCAT - Web Capacity Analysis Tool. This tool is powerful and it requires more manual scripting to get the performance results.  The current version of WCAT is 6.3 and can be downloaded from the following location: http://www.iis.net/downloads/default.aspx?tabid=34

 

setup and test

1.       Download the file

2.       Run the installation package

3.       Read the introduction to WCAT included in the installation   

c:\program files\wcat\doc\wcat.doc

1.       Once you have reviewed the basics you will need to install it on your client machines. (client are machines that will actually issue the commands to the server simulating your web clients).

1.       open a command prompt (as administrator if on vista)

2.       cd c:\program files\wcat\

3.       cscript //H:Cscript

4.       wcat.wsf -terminate -update -clients localhost

5.       machine will reboot

2.       To run the software you will first need to edit the client (scenario.ubr) and settings.ubr files to match the requests you wish to test. A simple HTTP get request for the scenario should suffice

3.       Save these two files to your WCAT directory

4.       Run your test with the following commands:

wcat.wsf -clients yourclientmachineip -run -t scenario.ubr -f settings.ubr -s yourserverip  -p yourserverport

5.       To view the results open log.xml

scenario.ubr

scenario
{
    name    = "HTTP Request Test";

    warmup      = 5; //seconds
    duration    = 10; //seconds
    cooldown    = 5; //seconds

    default
    {
        // send keep-alive header
        setheader
        {
            name    = "Connection";
            value   = "keep-alive";
        }

        // set the host header
        setheader
        {
            name    = "Host";
            value   = server();
        }

        // HTTP1.1 request
        version     = HTTP11;

        // keep the connection alive after the request
        close       = ka;
    }

    transaction
    {
        id = "simple scenario";
        weight = 1;

        request
        {
            url         = "/";
        secure      = true;
        statuscode  = 200;
        }


        close
        {
            method      = reset;
        }
    }
}

settings.ubr

settings
{   
    server         = "yourserveripaddresshere";
    clients        = 2;
    virtualclients = 5;

    counters
    {
        interval = 10;

        counter = "Processor(_Total)\\% Processor Time";
        counter = "Processor(_Total)\\% Privileged Time";
        counter = "Processor(_Total)\\% User Time";
        counter = "Processor(_Total)\\Interrupts/sec";

        counter = "Memory\\Available KBytes";
        counter = "Process(w3wp)\\Working Set";

        counter = "System\\Context Switches/sec";
        counter = "System\\System Calls/sec";

        counter = "Web Service(_Total)\\Bytes Received/sec" ; 
        counter = "Web Service(_Total)\\Bytes Sent/sec" ; 
        counter = "Web Service(_Total)\\Connection Attempts/sec" ; 
        counter = "Web Service(_Total)\\Get Requests/sec" ; 
    }

    registry
    {
        path = "System\\CurrentControlSet\\Control\\FileSystem";
        name = "NtfsDisableLastAccessUpdate";
        type = REG_DWORD;
    }

    registry
    {
        path = "System\\CurrentControlSet\\Services\\Tcpip\\Parameters";
        name = "SynAttackProtect";
        type = REG_DWORD;
    }
}

more complicated scenarios and tests

Since building more complex scripts can be a pain and time consuming, it is recommended to download the following two pieces of software that will help automate the building of the scenario scripts.

Downloads:
1. Fiddler 2.0
http://www.fiddler2.com/Fiddler2/version.asp

2. WCAT Scenario Creator
http://fiddler2wcat.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=35356
You will need to download WCATScenarioGenerator.dll

Installation:
1. Install Fiddler2
2. Save WCATScenarioGenerator.dll to the Fiddler2 scripts folder

Use:

1.       Open fiddler and click the launch IE button from within Fiddler2

2.       It will start recording a list of sessions along the left side

3.       After you've got a sequence on the left you want to save to a scenario for WCAT do the following:

4.       In fiddler 2 in the bottom left you should see a black rectangle.  This is where you can type commands for the WCAT extension

1.       Type wcat reset then carriage return

2.       type wcat addtrans then carriage return

3.       type wcat save

5.       you will now have a file called fiddler.wcat in your fiddler2 install folder

6.       open fiddler.wcat and save it to your c:\program files\wcat\ as newscenarioname.ubr

7.       run wcat and execute your new scenario file
wcat.wsf -clients yourclientmachineip -run -t newscenarioname.ubr -f settings.ubr -s yourserverip  -p yourserverport

 

 

Tuesday, November 20, 2012

ASP.NET ~ SQL Cache Notification issue

After enabling the database and table in sql server to support sql caching, I noticed that the cache is not still reflected with the updates. I verified to make sure if the database and tables are enabled and found that those are enabled. I opened the AspNet_SqlCacheTablesForChangeNotification table in sql server and noticed my table listed. The web.config file was also updated properly but still the cache was not getting invalidated. This was driving me crazy as why is the notification not working.

 

I enabled the database to support sql caching as follows:

C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727>aspnet_regsql -S <<server>> -E -d <<myDB>> –ed

 

I enabled the table to support sql caching as follows:

C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727>aspnet_regsql -S <<server>> -E -t <<myTable>> -d <<myDB>> –et

 

I have also set the web.config to support sql caching as follows:

 

    <caching>

      <sqlCacheDependency enabled="true" pollTime="2000">

        <databases>

          <add name="<<myDB>>" connectionStringName="myDBConnString" />

        </databases>

      </sqlCacheDependency>

    </caching>

 

After a while I checked the AspNet_SqlCacheTablesForChangeNotification table again just to make sure if everything is alright and that the table name is listed properly. I noticed that the case of the table name was different in AspNet_SqlCacheTablesForChangeNotification table. I was not sure but I just wanted to change case exactly as how it is displayed in the list of tables and give a try. I changed the table name manually in AspNet_SqlCacheTablesForChangeNotification table and then I tried again and it worked.

 

Whew….That was a great relief.

Hope this helps someone facing similar problem

Saturday, October 27, 2012

ASP.NET MVC ~ JSON decimal binding problem

With ASP.NET MVC, we will face problem when mapping JSON decimal values in an AJAX call to the model. For example consider the following class and the action method:

public class MyClass {
  
public decimal decValue1 { get; set; }
  
public int intValue1 { get; set; }
  
public decimal decValue2 { get; set; }
}

public ActionResult MyMethod(MyClass mc) {
  
return View();
}

and assume the following jquery ajax call:

$.ajax({
   type
: "POST",
   url
: "/Default/MyMethod",
   contentType
:'application/json',
   data
:JSON.stringify({decValue1:21.00,intValue1:3,decValue2:6.36})
});

On executing the above code, we will notice that the value for decValue1 will not be binded properly and that it will hold a value of 0. The reason is that the method JSON.stringify converts the value as follows before actually posting:

{"decValue1":21,"intValue1":3,"decValue2":6.36}

The default model binding behaviour believes the value of decValue1 to be of type integer (21) and therefore ignores to map this value to the destination type which is decimal. In order to overcome this problem, we will have to create our custom decimal binder and then register that in the application start event. The following is the code provided by Phil Haack to manage the custom binding of decimal types:

using System;
using System.Globalization;
using System.Web.Mvc;

public class DecimalModelBinder : IModelBinder
{
                  public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
                  {
                         ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
                         ModelState modelState = new ModelState { Value = valueResult };
                         object actualValue = null;

                         try
                        {
                                             actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
                         }
                        catch (FormatException e)
                        {
                                             modelState.Errors.Add(e);
                         }

                         bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
                         return actualValue;
                  }
}

and then we should register this custom decimal binder class in the application start event in the Global.asax.cs file as follows:

protected void Application_Start() 
{
    AreaRegistration.RegisterAllAreas();
    
    ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
 
    // All that other stuff you usually put in here...
}

Now, if we execute the same code, we should see the values mapped properly.

Thursday, October 25, 2012

Knockoutjs ~ Int16 data mapping fails from JSON to .NET

We design class comprising of different data types based on our requirement. Assume there is a requirement to store the age of a person. In this case, we can specify any numerical datatype for Age like byte, short or int. In most cases we end up choosing int (Int32) datatype. But sometimes developer opts for either byte datatype or short (Int16) datatype.

Let’s assume that we have the following Person class with Age datatype as short (Int16).

public class Person
    {
        public Int32 Id { get; set; }
        public string Name { get; set; }
        public Int16 Age { get; set; }
    }

The corresponding class definition on the cshtml view (javascript side) will be defined as follows:

function Person (person) {
        var self = this;
        self.Id=ko.observable(person.Id);
        self.Name=ko.observable(person.Name);
        self.Age=ko.observable(person.Age);
    }

The following would normally be our method to send the information back to the server:

        self.save = function (person) {               
            $.ajax({
                type: "POST",
                url: "Save",
                data: ko.toJSON(self),
                dataType: 'json',
                contentType: 'application/json;charset=UTF-8',
                success: function (result) {
                    alert("success");
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert("save error status: " + xhr.status);
                    alert("save error thrown: " + thrownError);
                }
            });
        };

And the following would be our ASP.NET code to capture the information:

        [HttpPost]
        public JsonResult Save(Person person)
        {
            if (person == null) throw new ArgumentNullException("person");

            var personBusiness = new PersonBusiness();

            var result = person.Id == 0 ? personBusiness.Insert(person) : personBusiness.Update(person);

            return Json(result);
        }

In the above case we would expect that the person object would have the information mapped properly provided by the user but unfortunately Age will hold value of 0 no matter what value is supplied by the user. It seems like the mapping of short datatype is not properly implemented. This becomes evident when we change the datatype of Age from Int16 to Int32. Now on the save action we can see that the Age attribute will has the value as set by the user.

Hope this solves someone facing such issue.

Thursday, October 18, 2012

"Dynamic" deep validation with KnockoutJS model

In this article, Knockout Model and Validating "inner" Models, we have seen how deep validation is done. Here is a snippet of that validation:
 
self.save = function () {
if (self.errors().length != 0) { //verifying the errors attribute using the count of errors
self.errors.showAllMessages(); //displaying the corresponding error messages
return; //returning the control providing user a chance to correct the issues
}
 
In the above method, we are simply invoking the showAllMessages method from the errors member. This will work for on occasion but sometimes this will fail and the validation error messages will not be displayed. In this situation, there is a workaround using which we can achieve this validation functionality working. The workaround is to add errors member to javascript class and then invoike the showAllMessage method for each of the instance of the class as shown below:
 
function Contact(id, phoneType, phone) {
var self = this;
self.ClientId = ko.observable(id);
self.PhoneType = ko.observable(phoneType).extend({ required: true });
self.Phone = ko.observable(phone).extend({ required: true });
self.errors = ko.validation.group(self); //adding the errors object for javascript class making each instance to hold the error individually
};
 
function ClientModel (id, firstName, lastName, email, contacts) {
var self = this;
self.Id = ko.observable(id);
self.FirstName = ko.observable(firstName).extend({ required: true, maxLength: 50 });
self.LastName = ko.observable(lastName).extend({ required: true, maxLength: 50 });
self.Email = ko.observable(email).extend({ maxLength: 50, email: true });
 
self.Contacts = ko.observableArray(ko.utils.arrayMap(contacts, function (aContact) { return aContact; }));
 }
 
Next we will update the save method as follows to perform the validation:
 
self.save = function () {
       var errorCount = 0;
ko.utils.arrayForEach(self.Contacts(), function(contact){
contact.errors.showAllMessages();
errorCount = errorCount + 1;
});
 
if (errorCount != 0) {
return;
       }
 
       //save code block
}
 
Hope this helps.

Wednesday, September 12, 2012

Dealing with JSON format date

When working with web application and dealing with JSON formatted data, we may come across date types that are represented as /Date(1347490800000)/. The value between the parenthesis i.e. 1347490800000 indicates the number of milliseconds elapsed since 1st Jan 1970.

In order to show the date in human understandable format, we will have to construct the date object using these millisecond values. In JavaScript, this can be done as follows:

var myJSONDate = "/Date(1347490800000)/"; //For demonstration purpose but in realtime we will get from Ajax call returning data in JSON format
var value = new Date(parseInt(myJSONDate.replace(/\/Date\((.*?)\)\//gi, "$1")));

In the above method, we have used native JavaScript’s regular expression technique to get hold of the millisecond value stripping the /, Date and parenthesis characters. In JavaScript, the new date object by default starts from 1st Jan 1970.

Similarly, we will can construct the DateTime object in .NET from JSON date as follows:

var jsonDate = "/Date(1347490800000)/";
jsonDate = System.Text.RegularExpressions.Regex.Replace(jsonDate, @"/Date\((.*?)\)\/", "$1");
var date = new DateTime(1970, 1, 1, 0, 0, 0, 0).AddMilliseconds(long.Parse(jsonDate));

Hope this helps…

Wednesday, September 05, 2012

Knockout Model and Validating "inner" Models

More and more technologies, projects and products are basing their foundation on MVC and MVVM principles. The reason is that it makes the project or product to be maintained easily without much headache. The latest trend in client based web development is also shifting towards MVVM model and the tool that is getting most widely used is the Knockout javascript library. It’s a great tool that eases binding making even the complex javascript tasks to be designed pretty easily like for example dynamically rendering design for multiple contacts and collecting details, etc..,

Basic Knockout Model Validation

Validating a basic knockout model is a straight forward task. We just have to use the extend method on the observable attributes and set the necessary parameters. Consider the following model:

function ClientModel (id, firstName, lastName, email) {
        var self = this;
        self.Id = ko.observable(id);
        self.FirstName = ko.observable(firstName).extend({ required: true, maxLength: 50 });
        self.LastName = ko.observable(lastName).extend({ required: true, maxLength: 50 });
        self.Email = ko.observable(email).extend({ maxLength: 50, email: true });

        self.save = function () {
            if (self.errors().length != 0) { //verifying the errors attribute using the count of errors
                self.errors.showAllMessages(); //displaying the corresponding error messages
                return; //returning the control providing user a chance to correct the issues
            }

            $.ajax({
                type: "POST",
                url: "Save",
                data: ko.toJSON(self),
                contentType: 'application/json',
                success: function (mydata) {
                    alert("Success");
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert("save method error status: " + xhr.status);
                    alert("save method error thrown: " + thrownError);
                }
            });
        };
};

$(document).ready(function () {
var clientModel = new ClientModel(1, "Hello", "World", "hell0@world.com");
clientModel.errors = ko.validation.group(clientModel); //setting up the errors attribute to the model to capture the validation error message
ko.applyBindings(clientModel);
});

The above is a basic model with validations added for the attributes using the extend method (More validation can be found here). The validation error messages are shown when the save method of the model is executed.

Deep Knockout Model Validation

Often we face situation where we will have a requirement for a complex model than the basic one. For example: our client may request us to design a solution to allow multiple contact numbers for a customer to be collected. In this case, the underlying model is changed as follows.

function Contact(id, phoneType, phone) {
        var self = this;
        self.ClientId = ko.observable(id);
        self.PhoneType = ko.observable(phoneType).extend({ required: true });
        self.Phone = ko.observable(phone).extend({ required: true });
};

function ClientModel (id, firstName, lastName, email, contacts) {
       var self = this;
       self.Id = ko.observable(id);
       self.FirstName = ko.observable(firstName).extend({ required: true, maxLength: 50 });
       self.LastName = ko.observable(lastName).extend({ required: true, maxLength: 50 });
       self.Email = ko.observable(email).extend({ maxLength: 50, email: true });

self.Contacts = ko.observableArray(ko.utils.arrayMap(contacts, function (aContact) { return aContact; }));

       self.save = function () {
            if (self.errors().length != 0) { //verifying the errors attribute using the count of errors
                self.errors.showAllMessages(); //displaying the corresponding error messages
                return; //returning the control providing user a chance to correct the issues
            }

            $.ajax({
                type: "POST",
                url: "Save",
                data: ko.toJSON(self),
                contentType: 'application/json',
                success: function (mydata) {
                    alert("Success");
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert("save method error status: " + xhr.status);
                    alert("save method error thrown: " + thrownError);
                }
            });
       };
};

$(document).ready(function () {
       var contacts = { new Contact(1, "Home", "1234567890"), new Contact(1, "Work", "9876543210") };
var clientModel = new ClientModel(1, "Hello", "World", "hell0@world.com", contacts);
clientModel.errors = ko.validation.group(clientModel); //setting up the errors attribute to the model to capture the validation error message
ko.applyBindings(clientModel);
});

The above is a also a model with validations added for the attributes using the extend method. The validation error messages excepts the contacts will be displayed when the save method of the model is executed. The reason is that we have not made the validation “deep” so the inner validations are not executed. In order to achieve this, we will have to include the following Knockout initialization block:

ko.validation.init({grouping: { deep: true }, messagesOnModified: false });

Adding the above line of code should make the inner validations work in most cases. But if it still doesn’t work, then we will have to add the errors attribute to the Contact model just like we have added for the ClientModel. The below listing shows the updated Contact model with errors attribute added:

function Contact(id, phoneType, phone) {
        var self = this;
        self.ClientId = ko.observable(id);
        self.PhoneType = ko.observable(phoneType).extend({ required: true });
        self.Phone = ko.observable(phone).extend({ required: true });

self.errors = ko.validation.group(self); //setting up the errors attribute to the Contact model to capture the validation error message
};

Having added the errors attribute to the Contact model, we also need to update the save method of the ClientModel to verify the errors collection attribute and return if in case there are errors. The updated save method is listed below:

self.save = function () {
       var errorExists = false;

if (self.Contacts().errors().length != 0) { //verifying the errors attribute from the Contact model
              self.Contacts().errors.showAllMessages(); //displaying the corresponding error messages
              errorExists = true; //set error flag to stop further processing
       }

if (self.errors().length != 0) { //verifying the errors attribute using the count of errors
              self.errors.showAllMessages(); //displaying the corresponding error messages
              errorExists = true; //set error flag to stop further processing
       }

if (errorExists) {
              return; //returning the control providing user a chance to correct the issues
       }

      
       $.ajax({
              type: "POST",
              url: "Save",
              data: ko.toJSON(self),
              contentType: 'application/json',
              success: function (mydata) {
                     alert("Success");
              },
              error: function (xhr, ajaxOptions, thrownError) {
                     alert("save method error status: " + xhr.status);
                    alert("save method error thrown: " + thrownError);
              }
            });
};

From the above updated save method, all the errors corresponding to the main model (ClientModel) and the child model (Contact) will be displayed.
Hope this helps!!!