Thursday, October 4, 2012

Chrome About URL

I was playing around with Chrome's about feature few days ago but forgot the actual URL. Therefore this post is to remind me the actual URL. The URL is chrome://about/. There are some useful URLs to know in the list and they are:
  • chrome://dns/
  • chrome://tracing/
  • chrome://profiler/
  • chrome://net-internals/
  • chrome://memory-redirect/
  • chrome://flags/

Tuesday, September 18, 2012

Copying parameters in LoadRunner

Scenario:
You are using same parameter(s) in more than one script and you don't want to manually create them again for each script. So how do you go about copying the parameters from an existing script.

For example:
The following parameters have already been manually created in Script 1 and same parameters are also required for Script 2.
  • DateTime
  • IterationNo
  • RandNo
  • VuserID

Rather than manually creating them, you can copy these parameters from Script 1 and this is how you do it.

Steps:
1: Navigate to Script 1 folder and open file that ends with "prm" extension. This file defines all the parameters and their attributes.


2: Copy the parameters & their attributes and paste into the parameter file of script 2.


3: Save the parameter file. Now open script 2 and navigate to parameter list. You will now noticed that the parameters have been successfully copied.





Saturday, September 8, 2012

Generating UUID in Loadrunner

There have been multiple times where I needed to generate UUID (Verion 4) in Loadrunner but there is no inbuild function to do so. Therefore, I had to either create or modify functions to satisfy my need.

NOTE: Loadrunner does have a function(lr_generate_uuid) for UUID but it does not generate your standard UUID.

Below are three different UUID functions that I normally use depending on the requirement.

For example, If only requirement is that UUID be 32 hexadecimal digits then I will use simple LR UUID to generate it. If there are proper checks in place to see the UUID generated is valid then I will use a proper UUID function's. Therefore you can select which one you want to use depending on your requirement.

Simple UUID - this is a simple 32 hexadecimal digits. You can generate hexaadecimal in Loadrunner using %x or %X Random number.

Following screenshot shows how to generate a random Hexadecimal.


Lr UUID - this function generates 32 hexadecimal digits UUID using Version 4(random) variant. This is the most common format I have seen applications use.

Win UUID - this function uses windows inbuild CoCreateGuid function (ole32.dll). The original code is written by Scott Moore and I have modified it a little bit.

NOTE: I have left the deallocation of pointer for you to do in the code.

#define Hexlength 50  //Max length

char *lr_guid_gen(); //explicitely declare the function
char *lr_uuid_gen(); //explicitely declare the function

Action()
{   

  char *Win_UUID=0; //declare window function UUID variable 
  char *slr_UUID=0; //declare loadrunner function UUID variable
  char *lr_uuid;  //declare UUID variable

  Win_UUID=(char *)malloc(sizeof(char)); //allocate dynamic memory
  slr_UUID=(char *)malloc(sizeof(char)); //allocate dynamic memory

  Win_UUID=lr_guid_gen(); //execute Window UUID function
  slr_UUID=lr_uuid_gen(); //execute LR UUID function
  lr_uuid=lr_generate_uuid(); //assign result generated by loadrunner internal
  function to lr_uuid

  /*output a simple UUID*/
   lr_output_message("smp_UUID: %s",lr_eval_string("{sHex}{sHex}-{sHex}-{sHex}-{sHex}-{sHex}{sHex}{sHex}"));
 //you could use something like this as well -> lr_output_message("smp_UUID: %s",lr_eval_string("{sHex}{sHex}-{sHex}-{FourHex}-{sHex}-{sHex}{sHex}{sHex}"));

  /*output loadrunner UUID*/
  lr_output_message("slr_UUID: %s",lr_eval_string(slr_UUID));

  /*output window generated UUID*/
  lr_output_message("Win_UUID: %s",lr_eval_string(Win_UUID));

  /*output base64 UUID*/
  lr_output_message("%s",lr_uuid);
 
 /*frees uuid created by lr_generarte_uuid*/
 lr_generate_uuid_free(lr_uuid);
 
 return 0;

}

 

/*This function uses windows ole32 CoCreateGuid function to generate UUID*/
char *lr_guid_gen()

{

    typedef struct _GUID

    {

        unsigned long Data1;

        unsigned short Data2;

        unsigned short Data3;

        unsigned char Data4[4];

    } GUID;

    char guid[Hexlength];
    GUID m_guid;

    lr_load_dll ("ole32.dll");

    CoCreateGuid(&m_guid);

    sprintf (guid, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",

    m_guid.Data1, m_guid.Data2, m_guid.Data3,

    m_guid.Data4[0], m_guid.Data4[1], m_guid.Data4[2], m_guid.Data4[3],

    m_guid.Data4[4], m_guid.Data4[5], m_guid.Data4[6], m_guid.Data4[7]);


    return guid;
}


/*This function uses loadrunner random numbers to generate version 4 UUID*/
char *lr_uuid_gen()
{
  char uuid[Hexlength];
  switch (atoi(lr_eval_string("{RandNo}")))
  {
   case 1:
    sprintf(uuid,lr_eval_string("{Hex}{Hex}-{Hex}-{FourHex}-{aHex}-{Hex}{Hex}{Hex}"));
    break;
   case 2:
    sprintf(uuid,lr_eval_string("{Hex}{Hex}-{Hex}-{FourHex}-{bHex}-{Hex}{Hex}{Hex}"));
    break;
   case 3:
    sprintf(uuid,lr_eval_string("{Hex}{Hex}-{Hex}-{FourHex}-{EightHex}-{Hex}{Hex}{Hex}"));
    break;
   case 4:
    sprintf(uuid,lr_eval_string("{Hex}{Hex}-{Hex}-{FourHex}-{NineHex}-{Hex}{Hex}{Hex}"));
    break;
   default:
    break;
  }
 return uuid;
}




Output:
Action.c(23): smp_UUID: 492ec6db-dcaf-fb6d-1009-72a542e26ee7
Action.c(26): slr_UUID: c4fbde14-4f41-4963-8400-32f77f6e0633
Action.c(29): Win_UUID: cee9f8fd-3715-4183-b367-a4c13b84a7c8
Action.c(32): LBase_64: J3+Lpj2t20KzpBSgg0e5Bg==

Action.c(23): smp_UUID: 65ea1bc1-8434-e05b-92f5-7e23a0f7e253
Action.c(26): slr_UUID: 358390f7-2405-4b03-8be4-b8c61b90a2b6
Action.c(29): Win_UUID: 75d74eb9-a2bf-42b4-b114-61d634a2c7db
Action.c(32): LBase_64: uzxvhpLXP0ifUjMSqzngCQ==

Action.c(23): smp_UUID: 0a86ce02-7413-1da3-bd39-63fc4cb9d60e
Action.c(26): slr_UUID: 726546c5-500d-4ef2-a27e-f447bb925143
Action.c(29): Win_UUID: db65a02f-1ca1-4fb3-ab22-0e41088b1633
Action.c(32): LBase_64: IJV65qREQUOe5CVwcE5aVQ==
 
Action.c(23): smp_UUID: 6678a6ac-3356-eb2f-63e6-02fe5a5185f2
Action.c(26): slr_UUID: acddc8f9-746d-4655-838c-7802483e06bb
Action.c(29): Win_UUID: e7a7ff1c-4019-4053-a51a-7567582d825c
Action.c(32): LBase_64: i+b5VpgA7Ueis8r1bxBTJg==
 
Action.c(23): smp_UUID: 3f8eb05e-9936-b5fc-6be9-454fd8fb9ab5
Action.c(26): slr_UUID: cc835158-9e86-4df5-8a4e-1e3f25808754
Action.c(29): Win_UUID: 3d604abe-046b-43dc-a5c4-e759fb04f960
Action.c(32): LBase_64: Rk2mSYUuOUmU0Yti_W+a5Q==

If you have a different function to generate UUID in Loadrunner, I would love to know about it.

Thursday, June 7, 2012

Plagiarizing someone else experience

Whenever I get a "Join my network on LinkediIn" message from someone on LinkedIn, I always try to view their profile before accepting it. This is because I just like to know a little bit more about them.

Recently, I received a join message from Manish Sinha(works for Accenture(Bengaluru - India) as a performance test lead) and as always, before accepting it, I viewed his profile and what I found was bit of a surprise. He was plagiarizing someone else experience on his profile as his own and guess what, that was my experience he was plagiarizing.

I emailed him couple of times to remove the experience from his profile but so far no luck. Therefore, I thought, I blog about it.

His Experience as ASc Consultant at Capgemini.


Can you see the similarity with my experience.

Friday, June 1, 2012

Publishing result in Silkperformer

SilkPerformer reports percentiles in a different section than the main table and it can be time consuming, if you want to publish all the metrics in a single table. Therefore to solve this issue, a colleague (Murray Wardle) of mine wrote a visual basic script that generates a table with all the metrics.

He has kindly allowed me to share it here and below is his description on how to use it.

"Publishing results from SilkPerformer can sometimes be very time consuming. Most projects will have requirements involving the 90th or 95th percentiles and for some reason SilkPerformer reports percentiles in a different section of the report and not in the main table I wish to publish.

Generally in my scripts I’ll use Timers for measuring response times (I’m not too keen of the automatic page and form timers) for timers controlled with the MeasureStart() and MeasureStop() functions, Inserting the following into the TInit will enable percentiles to be calculated for the Timers.

MeasureCalculatePercentiles(NULL,MEASURE_TIMER_RESPONSETIME);

Unfortunately percentiles are displayed in a different section of the report to the Min, Avg, Max, StdDev, Count, and it’s a waste of time trying to copy and paste the values into a spreadsheet.

So, here is a simple little script which does the work. Just drag and drop the OverviewReport.xml file onto the script and it will create a csv file with the following:

ScriptName, TimerName, Min, Avg, Max, StDev, Count, 50th Perc, 90th Perc, 95th Perc, 99th Perc"


NOTE: You are allowed to use the code as long as you acknowledge the author.

'Copyright (c) 2012 Murray Wardle, murray.wardle@advancedperformance.com.au
'Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sub license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
'The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 

Option Explicit

Dim xmlDoc
Dim scriptName, scriptNodes, SNode, TNode, timerNodes, timerName
Dim reportFile, outputFile
Dim myFSO, fileHandle
Dim min, avg, max, stDev, count, p50, p90, p95, p99
Set xmlDoc = CreateObject("Microsoft.XMLDOM") 

Const ForReading = 1, ForWriting = 2, ForAppending = 8 

If Wscript.Arguments.Count = 0 Then
    msgbox "Please specify the overview Report file to process"
Else

 ' Get report file name & set output filename
    reportFile = Wscript.Arguments(0) 
 outputFile = Left(reportFile, Len(reportFile)-3) + "csv"

 xmlDoc.async = false 
 xmlDoc.SetProperty "SelectionLanguage", "XPath" 
 xmlDoc.SetProperty "ServerHTTPRequest", True
 xmlDoc.validateOnParse = False 
 xmlDoc.resolveExternals = False

 'load overview report
 xmlDoc.load(reportFile)
 xmlDoc.setProperty "SelectionLanguage", "XPath"  

 'open csv file to dump results into
 Set myFSO = CreateObject("Scripting.FileSystemObject")
 Set fileHandle = myFSO.OpenTextFile(outputFile, ForWriting, True)
 fileHandle.WriteLine("Script,Timer,Min,Avg,Max,StDev,Count,50th Perc,90th Perc,95th Perc,99th Perc")

 'For each script
 Set scriptNodes = xmlDoc.selectNodes("/Overview_Report_Data/UserGroups/Group") 
 For Each SNode in scriptNodes 
  scriptName = SNode.SelectSingleNode("Name").text

  'For each measure of type Timer
  Set timerNodes = SNode.selectNodes("Measures/Measure") 
  For Each TNode in timerNodes 
   If TNode.SelectSingleNode("Class").text = "Timer" then
   
    ' Extract the timer data
    timerName = TNode.SelectSingleNode("Name").text
    min = TNode.SelectSingleNode("MinMin").text
    avg = TNode.SelectSingleNode("Avg").text
    max = TNode.SelectSingleNode("MaxMax").text
    stDev = TNode.SelectSingleNode("Stdd").text
    count = TNode.SelectSingleNode("SumCount2").text
    p50 = TNode.SelectSingleNode("Percentiles/Values/Value[1]/Value").text
    p90 = TNode.SelectSingleNode("Percentiles/Values/Value[2]/Value").text
    p95 = TNode.SelectSingleNode("Percentiles/Values/Value[3]/Value").text
    p99 = TNode.SelectSingleNode("Percentiles/Values/Value[4]/Value").text

    'Write to File
    fileHandle.WriteLine(scriptName+","+timerName+","+min+","+avg+","+max+","+stDev+","+count+","+p50+","+p90+","+p95+","+p99)
   
   end if
  
  Next 'TNode in timerNodes 

 Next 'SNode in scriptNodes
 
 fileHandle.Close
 
End If


Example:
1: Save the above code as a visual basic script into a folder. Lets call this script as "ExtractOverviewReportData.vbs".
2: Navigate to you SilkPerformer project and copy OverviewReport.xml into the folder where you have saved vbs script. See the screenshot below.
When you open the xml file, it would look something like this:




  1.100000000
  ABCDEFG
   ForMyBlog.tsd (D:\Silkperformer_Projects\ABCDEF\) 
  Silk Performance Explorer
  Monday, 20 April 2012 - 3:00:00 AM
  1
  
Header ABCD 8 None 1 28/05/2012 1:00:12 AM 6280.000000000 4 Merged MPPO SVT 23
... Timer #Overall Response Time# Response time[s] Seconds 0.000000000 0.000000000 3 2 Response time[s] 200.000000000 100.000000000 830.000000000 35000.000000000 0.500000000 60.00000000 6.412345678 11.123456789 0.000000000 0 0.000000000 0 0 0 50 1.123456789 90 22.123456789 95 60.00000000 99 60.00000000 ...
3:Now drag and drop the OverviewReport.xml file onto the script and it will create a csv file.
4: Now open up the csv file in excel and you should have all the necessary metric. You will see something like this: