views:

543

answers:

1

How do I read from the performance counter "NumberOfActiveConnections" of the category ".NET Data Provider for SqlServer" from a unit test in MS Test?

I'm trying the following but it seems like I get the instance name wrong. The MSDN documentation claims this is a correct way of getting the instance name of a WinForms app but this won't work with MS Test:

string instanceName = System.Reflection.Assembly.GetEntryAssembly().GetName().Name;

When running the code above from MS Test I get null back from the call to GetEntryAssembly()

I've also tried using the name of the MS Test process and other variations but without any luck.

This is the sample code that will throw exception when i'm using any of the instance names from above:

PerformanceCounter counter = new PerformanceCounter(
    ".NET Data Provider for SqlServer", 
    "NumberOfActiveConnections", 
    instanceName, 
    true);            

Assert.AreEqual<long>(0, counter.RawValue);

I'm enabling the "NumberOfActiveConnections" counter by adding this to the app.config as per MSDN documentation:

<system.diagnostics>
  <switches>
    <add name="ConnectionPoolPerformanceCounterDetail" value="4"/>
  </switches>
</system.diagnostics>

Perhaps the problem is that the performance counters are enabled for the MS Test host domain but not for the domain in which the tests actually run?

+1  A: 

The instance name for VSTestHost for me tends to be a long string that looks vaguely similar to a GUID followed by the PID, so figuring out the instance name is a little bit of a pain, though if you know the PID (I'll get to that in a second), then it can be done by doing something along these lines:

PerformanceCounterCategory category = new PerformanceCounterCategory(
    ".NET Data Provider for SqlServer");
string testInstanceName = null;
foreach(string instanceName in category.GetInstanceNames())
{
    if (instanceName.EndsWith(string.Format("[{0}]", pid)))
    {
        testInstanceName = instanceName;
        break;
    }
}

if(testInstanceName != null)
{
    PerformanceCounter counter = new PerformanceCounter(
        category.CategoryName,
        "Number of Active Connections",
        testInstanceName,
        true);
}

Since calling GetEntryAssembly() during a unit test returns null, it's also kind of a pain to get ahold of the PID for VSTestHost.exe. However, you should be able to do something along these lines:

Process[] testProcesses = Process.GetProcessesByName("VSTestHost");
if (testProcesses.Length == 1)
{
    pid = testProcesses[0].Id;
}
cthrek