Friday, April 19, 2013

Visual Studio 2010 Code Coverage of IIS and Windows Service based Application

Code Coverage of IIS based application

It was very surprising to find that there was no enough information available over the internet regarding how to perform code coverage of IIS hosted application. 

All the site/ blog i visited was having half information causing me to spent lot of time debugging the issue. Anyways but good news is, i was able to solve this issue and thought of writing my first ever blog with all the detailed information i was able to learn from this


Lets Start

Assumption
You have an asp.net based application hosted on Windows Server and there are some windows services that you are application is interacting with

Pre-requisite: 
1. Visual Studio 2010 Performance Tools are required to be installed on the server box where your product is installed/ hosted.
2. You should have .pdb (symbols) in hand. Symbol files are must for instrumentation
3. If possible, try to get code (.cs) file on the installation box. This will be required for analyzing the code

Performance tools are available at: 
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Performance Tools
You can set this as path in environment variable 

Quick steps
  1. vsperfclrenv /globaltraceon  and reboot 
  2. vsinstr /COVERAGE [assembly] 
  3. vsperfcmd /START:COVERAGE /OUTPUT:[ouputfile].coverage /CS /USER:"[ASP.NET worker process user]" 
  4. vsperfcmd /ATTACH:w3wp.exe
  5. Run the test scenario against the web application 
  6. vsperfcmd /DETACH 
  7. iisreset /STOP 
  8. vsperfcmd -SHUTDOWN


Step 1: vsperfclrenv /globaltraceon  and reboot
This will turn on trace on for the machine. Reboot the machine after turning the trace ON.

Step 2: vsinstr /COVERAGE [assembly] 
Second step is to instrument the dll's. Now this is the most trickiest and most important steps. You can not skip this. To instrument a dll you can use "vsinstr /coverage <<your assemble name>>.dll"
You will find this information on all the blogs but there is something missing in most of the blogs:

  1. You may get error saying Files are in use
  2. You need to have .pdb (symbols) file at the same location your dll is present
  3. Now there will the case when you have your n numbers of dll and in different folders under hosted directory
  4. Above command will only instrument only one dll but how to instrument all the dlls specially when there are 100s of dll present for your application
Don't worry, i have a solution for this:
  1. First copy all the .pdb where the dlls are present. This you need to do manually. If you need to automate this, ask your release management to build installer in such a fashion that when you install the build, pdbs are present with dlls
  2. Stop IIS using "iisreset /stop" command and also make sure all the windows service referring to your dlls are stop. If this step is not done, some dlls which are actively being used may not get instrumented
  3. Create a batch file with following commands. This bat file will take care of issue 3 mentioned above, it will search for all the dll, in a specific folder and instrument those dll's one by one. This will save lot of your times when you have multiple dlls.  

cd <location of your dll>
if not EXIST C:\Bin mkdir C:\Bin\
for /f "delims==" %%F in ('dir /b *.dll') do copy "%%F" C:\Bin\
for /f "delims==" %%F in ('dir /b *.pdb') do vsinstr /Coverage "%%~nF.dll"

     4. Run this batch file for all the folders you have. Place this batch file in each folder you have your dll's  and then run the bat file from Visual studio 2010 command prompt

Once the instrument is complete, you will find your original dll will be renamed with .orig extension existing dll will be instrumented. Now start the iis using "iisreset /start" command and start all the services again

Step 3: vsperfcmd /START:COVERAGE /OUTPUT:[ouputfile].coverage /CS /USER:"system" 

This step will start the monitoring of instrumented dll. Lets review each arguments
  • /start:Coverage - This will tell the tool to start the coverage
  • /Output:[outputfile].coverage - This will allow you to name the output file
  • /CS: CS means cross session. This will be required so that you can attach to IIS
  • /User:"system" - This is very important step. In order to monitor IIS based application, you need to have this option and user mentioned should be correct. Go to your iis and in application pool, check under what user iis is running. Same user should be mentioned /user clause

Once this step is done, just to ensure it will capture what you want, restart iis using "iisreset" command and restart all the windows services

Step 4: vsperfcmd /ATTACH:w3wp.exe
This step will tell code coverage tool to monitor iis. To do this, open your application in a browser. This will start w3wp.exe process and now run "vsperfcmd /ATTACH:w3wp.exe" command. 

Sometimes you may find there are multiple w3wp.exe command. In that case you can attach to both the process using process id (replace w3wp.exe with PID)

Step 5: Run tests
Run all your test from anywhere. You can run from same machine or from your test machine. Test can be run manually or through automation. Just to regular testing using browser

Step 6: vsperfcmd /DETACH 
Once your tests are completed, detach the process using above mentioned command

Step 7: Stop your iis and application related windows services
This step is required so that perf tool can collect code coverage data

Step 8: vsperfcmd -SHUTDOWN
This command will ask the tool to stop collecting code coverage and generate code coverage file in output location provided in step 3.

Now you can open the .coverage file using Visual Studio and understand the coverage of your test.

I will try to add screenshot soon but at this point you are ready to go.

Some tips:
1. Place the .cs file as mentioned in pdb file. Double click any function you are evaluating and it will tell you where you need to place your .cs files. Once done, you are can evaluate the code
2. vsperfcmd /Status will let help you find the status of process. Just try it and you will find some interesting information



10 comments:

  1. Hello Kartik,

    Your blog post on code coverage has helped me in setting up a code coverage environment in the project on which I am working.

    For other readers of this blog spot, every step mentioned in the post have to be executed exactly in the same way and in the same sequence. If any step is missed/ignored and if the sequence is changed the code coverage is not going to work.

    These are few more points to be noted while setting up the code coverage environment especially for IIS based applications (IIS 7.0 and above) on a 64-bit server machine:


    Step1 : Very Important : Check application pool’s Version (64 bit / 32 bit) support:
    - On a 64 bit machine the configurations are such that even a 32-bit application can run in the 64 bit environment.
    - This behaviour is configured using the property “Enable 32-Bit Applications”.
    - run-> INETMGR -> The relevant application pool -> Advanced Settings -> Enable 32-Bit Applications

    Step 2: If the application is 32 bit and if Enable 32-Bit Application property is set to TRUE:
    - Use the “VS2013 x64 Native Tools Command Prompt” instead of “Developer Command Prompt for VS2013” to execute all the steps mentioned in the blog.
    - If the value is TRUE and “Developer Command Prompt for VS2013” is used instead of “VS2013 x64 Native Tools Command Prompt”, we will get an error during step when we attach the w3wp.exe process using “vsperfcmd /ATTACH:w3wp.exe”
    - “Error vsp1336: could not attach to process id w3wp.exe. Profiling 64-bit process is not supported by this version…..”

    Step 3: If the application is 32 bit and if Enable 32-Bit Application property is set to FALSE:
    - Use the “Developer Command Prompt for VS2013” to execute all the steps mentioned in the blog.

    Notes:

    Note 1: Wrong Process ID selected:
    - In case after all the steps mentioned, if the Code Coverage still fails to generate any data (file is basic 84K without any data in it) implies the attached process id is wrong. Re check the Process Id and re – execute all the steps right from the step “vsperfclrenv /globaltraceon”
    - The process Id should be the one instance of w3wp.exe where the “User Name” should be the name of ur Application Pool.

    Note 2: Wrong USER name and hence restricted access issue:
    - If the Process ID is right, the steps executed are all correct and still if the Code Coverage file generated is empty (basic 84K) re-check the “vsperfcmd /START:COVERAGE /OUTPUT:[ouputfile].coverage /CS /USER:"system" step.
    - Here the USER parameter is invalid. Check the access rights associated with the application pool in which your application is running.
    - In most of the cases the IIS runs under “NT AUTHORITY\Network Service” user.
    - In my case it was “IIS AppPool\TestAppPool” where TestAppPool is the name of application pool in which my application is running.

    Hope these steps will help some.

    Regards,
    abhijit.parkhi@gmail.com

    ReplyDelete
  2. I am glad that it helped you. And thanks for the observations. Will incorporate your comments in my blog soon.

    ReplyDelete
  3. Sorry, but those steps are wrong. VSPerfCmd /attach and /detach are intended to be used for Sampling Profiling, which is mutually excusive with Coverage.

    ReplyDelete
    Replies
    1. Did you tried these steps? I have written these steps based on my research and was able to perform code coverage successfully. And without attach and detach process it dint work. Let me know if you have any better solution and i will try that. Will update the steps accordingly.

      Delete
    2. Those are steps that are expected to work:

      1. vsperfclrenv /globaltraceon and reboot
      2. vsinstr /COVERAGE [assembly]
      3. Make sure your target process *doesn’t run*
      4. vsperfcmd /START:COVERAGE /OUTPUT:[ouputfile].coverage /CS /USER:"[ASP.NET worker process user]"
      5. Run the test scenario against the web application
      6. iisreset /STOP (you have to terminate the target process in order to shutdown profiler)
      7. vsperfcmd -SHUTDOWN

      attach and detach are not required, as registration of the process with profiler tool happens when instrumented binary is executed. It is essential though that target process starts after profiler and not before.

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. How to instrument the multiple dll? Is there any command or we need to do using for loop..

    ReplyDelete
    Replies
    1. Looping is the only option that i am aware of.

      Delete
  6. Hi Kartik,

    We want to work on code coverage but we don't have command or developer tool line of VSTS as in our company allocated VSTS version.
    It is VSTS test professional.
    Can you tell me can we still instrument it by using normal command tool or by any tool.

    ReplyDelete
  7. Hi
    Good work.. if i want to do the code coverage for my wcf service in server.
    in my windows server we haven't installed the visual studio only dotnet framework 4.5 is installed.
    could you please assist me if i want to do the profiling in server what are the tool need to install and provide me the download url also

    Thanks in advance

    ReplyDelete