Monday, August 31, 2009

Cable Problem Causing The Internet To Fritz

Today, the DSL just decided not to work - again - ever. A technician is scheduled and he replaces the cable and everything works - so far.

Friday, August 28, 2009

LoadRunner Doesn't Like 64 Bit Emulation

LoadRunner doesn't like 64 bit emulation over 32 bit machine. It doesn't like long long declaration on .h header file. It spews:
invalid use of `long'
Thus begin the hacking and slashing of sqlite3.h

Wednesday, August 26, 2009

Each VUser Must Use Unique Login ID

This is a problem: the web app that I am testing is using the login id as session id. Since I am furnished with data, that has multiple non-unique logins, I have to make sure that all of virtual users are using unique login id.

Several solutions come to mind, but I decided to give LoadRunner VTS a whirl.

Perusing VTS2.doc I quickly hone in lrvtc_send_if_unique function:
VTCERR lrvtc_send_if_unique(char *columnName, char *message)
But this function is pretty much useless since the VTCERR equals 1 no matter if the insertion is successful or not. Trying its cousin instead:
VTCERR vtc_send_if_unique(PVCI pvci, char *columnName, char *message, unsigned short *outRc)
This function returns successful insertion status in outRc parameter (1 = Pass, 0 = Fail).
lr_start_transaction("GetUniqueUserName");
status = 0;
while (status == 0) {
lr_save_string(lr_eval_string("{pDATAFILEUserName}"), "pUserName");

pvci = lrvtc_connect(lr_eval_string("{pVTSServer}"), 8888, 0);
rc = vtc_send_if_unique(pvci, "pUserName1", lr_eval_string("{pUserName}"), &status);
lr_output_message("Insert if unique, rc = %d, status: = %d", rc, status);
lrvtc_disconnect();

if (status == 0) //try another login in the data file if fail
lr_advance_param("pDATAFILEUserName ");
else
user_removed = 0; // just another flag
}
lr_end_transaction("GetUniqueUserName", LR_AUTO);
The login removal process is a trickier than the insert process, since VTS doesn’t have a function to look up a value in a column, a value has to be looked up (one by one):
int removePreviousUserName() { // to eliviate the nasty side effect of exit when error
int rc = 0;
unsigned short status;
int EOT = 0;
int i;
int user_removed = 0;

lr_start_transaction("RemovePreviousUserName");
i=lastrowID;

while (!EOT) {
i++;
pvci = lrvtc_connect(lr_eval_string("{pVTSServer}"), 8888, 0);

rc = lrvtc_query_column("pUserName1", i);
lr_output_message("query row %d, rc = %d", i, rc);

if (rc!=0)
EOT = 1;
else {
if (stricmp(lr_eval_string("{pUserName}"), lr_eval_string("{pUserName1}")) == 0) {
lr_output_message("Del msg (%s) at row %d", lr_eval_string("{pUserName1}"), i);
rc = vtc_clear_message(pvci, "pUserName1", i, &status);
lr_output_message("Del msg, rc = %d, Status = %d", rc, status);
lastrowID = i;
EOT = 1; // exit anyway
user_removed = 1;
}
}
lrvtc_disconnect();
}
lr_end_transaction("RemovePreviousUserName", LR_AUTO);
return user_removed;
}
A little explanation about lastrowID, when a data is deleted from VTS, a value can never be re-inserted into that row again via vtc_send_if_unique function. So, there are lots of empty rows at the lower index after the value is deleted. Thus there is no point for the script to start the search for a login to delete from row 1; instead it should start the search from the last deletion point.

Functionally the script works, but VTS system is not capable of handling multiple virtual users. At 10 virtual users, each running 20 seconds transactions, VTS is throwing numerous -10003 errors, that causes slow GetUniqueUserName transaction:
  • 75% of population: 2.201 +/- 2.912
  • 90 Percentile: 6.506
2.2 seconds on the average to insert unique value? I don’t think so. I need a better solution.

Tuesday, August 25, 2009

Internet Is All Good

The Alarm app on my BlackBerry seg-faulted this morning. Too bad I was too groggy & pissed off to take a picture, it would be interesting.

Note to self: steal an olde alarm clock from Lisa.

Btw: Internet is all good, looks like I don't need to talk to the good people in St Louis after all.

Monday, August 24, 2009

AT&T Support, The Competency May Varies

AT&T support @ 800-288-2020: FireFox's history/cookies causes the router's red light (DSL) to blink & drop the internet.

I think I should better wait for the good AT&T support (866-865-7685) in St Louis to wake up.

Wednesday, August 12, 2009

Identifying Location Based On The Soil's Microbial Makeup

Received this email and it raised little hairs on my neck.
from Melanie S
date Wed, Aug 12, 2009 at 6:05 PM
subject JOB: soil microbiome profiling @ LLNL (must be US citizen)

Tom Slezak, Biodefense Group Leader, Lawrence Livermore National Laboratory, https://www.llnl.gov/str/April04/Slezak.html, mentioned last week at the Microarray World Congress, http://www.selectbiosciences.com/conferences/MWC2009/Agenda.aspx, that he has a funded soil microbiome profiling position currently available.

The candidate must be a US citizen, and should ideally have a PhD in a related field such as bioinformatics and 1-4 years work experience. Tom’s contact information is here: https://www.llnl.gov/str/April04/Slezak.html

Specifically, the position/project entails looking at:

* Can soil microbiome profiling characterize locations? To what resolution?
* Determine the ability to characterize locations by analyzing microbial content
* Utilize microarrays and sequencing to determine the ability to resolve where a soil sample came from or rule out locations
* Develop a soil microbiome microarray to provide a low-cost way to ‘fingerprint’ locations
* Determine degree of location resolution possible due to species-level soil microbe differences


Uh-oh Dexter, beware of that dirt on your shoes.

Translating The Name of Month To Number

Another Perl code posted since I am getting tired of rewriting it all the time.
my %months = (
Jan=>1, Feb=>2, Mar=>3, Apr=>4, May=>5, Jun=>6,
Jul=>7, Aug=>8, Sep=>9, Oct=>10, Nov=>11, Dec=>12,
January=>1, February=>2, March=>3,
April=>4, May=>5, June=>6,
July=>7, August=>8, September=>9,
October=>10, November=>11, December=>12,
);
eg:
parseDate('Jan  1 2009 12:00:00:000AM');

sub parseSQLDate {
my ($txt) = @_;

if ($txt =~ /^(\w+)\s+(\d+)\s+(\d+)\s+(\d+):(\d+):(\d+):(\d+)/) {
use DateTime;

my %months = (
Jan=>1, Feb=>2, Mar=>3, Apr=>4, May=>5, Jun=>6,
Jul=>7, Aug=>8, Sep=>9, Oct=>10, Nov=>11, Dec=>12,
January=>1, February=>2, March=>3,
April=>4, May=>5, June=>6,
July=>7, August=>8, September=>9,
October=>10, November=>11, December=>12,
);

my $dt = DateTime->new(
year => $3,
month => $months{$1},
day => $2,
time_zone => 'floating',
);

return $dt;
}
}

Tuesday, August 11, 2009

SQL Server Version

From: How to identify your SQL Server version and edition
SELECT @@VERSION
or
SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPERTY ('edition')

Thursday, July 30, 2009

Ambigous Win32:OLE::LastError() Message

Running this code snippet:
use Win32::OLE;
$lrEngine = Win32::OLE->new('wlrun.LrEngine');
$lrScenario = $lrEngine->Scenario();
$rc = $lrScenario->new(0, 1);
# do not save previous
# regular vusers based scenario

$scriptLocation = 'PATH\TO\SCRIPTNAME\SCRIPTNAME.usr';
$scriptName = 'SCRIPTNAME';
$lrScenario->Scripts->Add($scriptLocation, $scriptName);
print "Win32::OLE::LastError: ".Win32::OLE::LastError()."\n";
Yields:
Win32::OLE::LastError: Win32::OLE(0.1709) error 0x80020005: "Type mismatch"
in METHOD/PROPERTYGET "Add" argument 2
Yes, the code passes string, even changing the code to force COM BSTR usage still generates the same error message
use Win32::OLE::Variant;
$scriptName = Variant(VT_BSTR, 'SCRIPTNAME');
What gives? The code definitely follows the documentation to the dot
Function Add(Path As String, Name As String) As Long
Add Script to Scenario
The answer: Variants by reference, changing the code, to reflect the snippet below, fixes the problem.
use Win32::OLE::Variant;
$scriptName = Variant(VT_BSTR|VT_BYREF, 'SCRIPTNAME');

Wednesday, July 29, 2009

Submitted 1st Perl Bug To ActiveState

http://bugs.activestate.com/show_bug.cgi?id=83895

--Note: I see, basically reverse doesn't sort the list in reverse order, but it will reverse the list.

Reverse Function Is Not Working Properly

Dan caught it, not me
use strict;
my $DATA;
{
local $/ = undef;
my $DATA_text = ;
eval "$DATA_text";
die $@ if $@;
}
print "# incorrect reverse sort using reverse function\n";
foreach my $date (reverse keys %{$DATA}) {
print "$date\n";
}
print "\n";
print "# correct reverse sort\n";
foreach my $date (sort {$b cmp $a} keys %{$DATA}) {
print "$date\n";
}

__DATA__
$DATA = {
'2009/07/19' => {
files => 1,
},
'2009/07/12' => {
files => 1,
},
'2009/07/05' => {
files => 1,
},
'2009/06/28' => {
files => 1,
},
'2009/06/21' => {
files => 1,
},
};

It prints:
>perl reverse_problem.pl
# incorrect reverse sort using reverse function
2009/07/12
2009/07/05
2009/07/19
2009/06/28
2009/06/21

# correct reverse sort
2009/07/19
2009/07/12
2009/07/05
2009/06/28
2009/06/21

>perl -v

This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 18 registered patches, see perl -V for more detail)

Copyright 1987-2007, Larry Wall

Binary build 822 [280952] provided by ActiveState http://www.ActiveState.com
Built Jul 31 2007 19:34:48

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

--Apparently I can reproduced this using ActiveState v5.10.0 build 1001 [283495]

Monday, June 15, 2009

Collect My Passport

The window opens from 13:30 to 16:00. I arrived 15:55. I hate LA's traffic.

Thursday, June 11, 2009

Ambiguous Extraction

Say you need to extract the id of Company A as originator ({pOriginatorName}) and Company A as underwriter ({pUnderwriterName}), what should you do when you encounter this response?

<html>
<head />
<body>
...
<select name="originator">
<option selected value="0">Company A</value>
<option value="1">Company B</value>
<option value="2">Company C</value>
</select>
...
<select name="underwriter">
<option value="-1">Please select</value>
<option value="9005">Company A</value>
<option value="9006">Company B</value>
</select>
...
</body>
</html>
Then it's time to use the XML functions provided by the good people of Mercury (now HP), first extract the options inside the select element by using web_reg_save_param function:
web_reg_save_param("pOriginatorIDText",
"LB/IC=name=\"originator\"",
"RB/IC=</select>",
"Ord=1",
"Search=body",
LAST);

web_reg_save_param("pUnderwriterIDText",
"LB/IC=name=\"underwriter\"",
"RB/IC=</select>",
"Ord=1",
"Search=body",
LAST);


Follow by the functions to extract the related values:
iNumOfValues = lr_xml_get_values("XML=<select {pOriginatorIDText}</select>",
"ValueParam=pCollectedOriginatorName",
"Query=/select/option",
"SelectAll=yes",
LAST);

iNumOfValues = lr_xml_get_values("XML=<select {pOriginatorIDText}</select>",
"ValueParam=pCollectedOriginatorID",
"Query=/select/option/@value",
"SelectAll=yes",
LAST);

for (i = 0; i < iNumOfValues; i++) {
sprintf(buf, "{pCollectedOriginatorName_%d}", i+1);
sprintf(buf, rtrim(lr_eval_string(buf)) );
sprintf(sParamName, "pCollectedOriginatorName_%d", i+1);
lr_save_string(buf, sParamName);

if (strcmp(buf, lr_eval_string("{pOriginatorName}")) == 0) {
lr_output_message("Originator name found");
sprintf (buf, "{pCollectedOriginatorID_%d}", i+1);
lr_save_string(lr_eval_string(buf), "pOriginatorID");
}

sprintf (buf, "Retrieved value %d : {pCollectedOriginatorName_%d}", i+1, i+1);
lr_output_message(lr_eval_string(buf));
}
//#####################################
iNumOfValues = lr_xml_get_values("XML=<select {pUnderwriterIDText}</select>",
"ValueParam=pCollectedUnderwriterName",
"Query=/select/option",
"SelectAll=yes",
LAST);

iNumOfValues = lr_xml_get_values("XML=<select {pUnderwriterIDText}</select>",
"ValueParam=pCollectedUnderwriterID",
"Query=/select/option/@value",
"SelectAll=yes",
LAST);

for (i = 0; i < iNumOfValues; i++) {
sprintf(buf, "{pCollectedUnderwriterName_%d}", i+1);
sprintf(buf, rtrim(lr_eval_string(buf)) );
sprintf(sParamName, "pCollectedUnderwriterName_%d", i+1);
lr_save_string(buf, sParamName);

if (strcmp(buf, lr_eval_string("{pUnderwriterName}")) == 0) {
lr_output_message("Underwriter name found");
sprintf (buf, "{pCollectedUnderwriterID_%d}", i+1);
lr_save_string(lr_eval_string(buf), "pUnderwriterID");
}

sprintf (buf, "Retrieved value %d : {pCollectedUnderwriterName_%d}", i+1, i+1);
lr_output_message(lr_eval_string(buf));
}

Yes, it looks complicated, but:
pOriginatorID = 0
pUnderwriterID = 9005

Mish Mash Of Different Version Work

This is weird, but LR controller v9.1 can talk & run scripts when paired with generator v7.8FP1, vice versa.

Test it this morning.

Wednesday, June 10, 2009

rtrim

Delete trailing spaces
char *rtrim(char * string)
{
while (strcmp(strrchr(string, ' '), " ") == 0) {
string[strlen(string)-1] = 0;
}
return string;
}
Googled this and can't find good solution.