如何从LoadRunner调用Perl代码?

时间:2013-03-22 13:58:10

标签: perl loadrunner

对不起,如果这是一个重复的问题;我找不到答案。 (是的,我检查了一下,但我没有为LR 11.04进行RTFM。我想保持我留下的稍纵即逝的理智。)

我知道可以在loadrunner中调用Perl,但还没有找到一个例子。我知道这是可能的,因为Web_Reg_Save_Param_ex / Web_Reg-Save_Param_Regexp函数中的RegEx逻辑被移植到Perl子例程。

我需要知道如何做到这一点,因为我需要对我们测试的(half - @ $$ ed)应用程序做很多事情。

例如:

  • .NET应用程序 - 我可以快速轻松地查找参数值,在LR之外切片和解析它们,然后将值返回到LR。

  • 标准网络应用程序 - 对某人的沙箱进行第三方调用。所有信息均采用Base64编码。我们需要获取明文(在响应中提供),然后编码到Base 64,并将其发送到主系统。所以,AUT是系统A;系统A调用系统B(302响应),系统B响应,并且AUT将该数据发送回Systam A以存储在其数据库中。 (由于系统A和系统B来自同一个供应商 - 嗯,我对我们的投标过程有疑问,但它是OT。)

我有一个问题,我是一个优秀的程序员,但在Perl是一个菜鸟。所以我需要清除和重写,而不仅仅是坐下来编写代码。我检查了我能找到的RegEx信息(目前为止最好的是using regular expressions in loadrunner),但到目前为止还不足以满足我的目的。

来源:

{"text":"A*","value":"271"},  // This is just the pattern - it's repeated 320 times or so

示例代码段:

web_reg_save_param_ex(
    "ParamName=Charity1",
    "LB={\"text\":\"", 
    "RB/RE=\",\"value\":\"([0-9]+)\"},", 
    "Ordinal=All",
    SEARCH_FILTERS,
    "Scope=Body",
    "IgnoreRedirections=Yes",
    "RequestUrl=*/Person.aspx*",
    LAST);

那个工作,返回名称(上面的来源A*)。

web_reg_save_param_ex(
    "ParamName=Charity1",
    "LB/RE={\"text\":\"([A-Za-z0-9].+)\",\"value\":\"",
    "RB=\"},", 
    "Ordinal=All",
    SEARCH_FILTERS,
    "Scope=Body",
    "IgnoreRedirections=Yes",
    "RequestUrl=*/Person.aspx*",
    LAST);

这对我不起作用 - 找到的总记录,ZERO。好吧,一个条目中有一个“ - ”,有些条目有空格 - 但100%失败? OTOH,如果我可以捕获整个列表,我会将它发送到Perl,拆分子串,并返回修剪和整齐的两个值,以保存为LoadRunner字符串(我认为 - LR不像一个单一的返回到目前为止,我可以做一个STRUCT并将值返回到那个,或者指向内存空间的指针,并让LR将引用的内存读取到STRUCT,或类似的内容。)

问题是,很明显AUT直接使用这两个值,所以我以后不能使用它,当值被发送回来时 - 显然,NUMBERS比文本更重要。

任何建议都值得赞赏,但我想避免使用system() - 这就是我对Base64问题的解决方法(它本来应该是唯一的Perl调用。)它工作得很好。 ..直到我添加了M$所需的补丁之一,并且无法再在LoadRunner中打开并读取该文件(而HP说,它是自定义代码,我们无法帮助您。所以我删除了{{1补丁并运行测试。它是一个c ++ Redistributable,大约在2010年。那是2012年末。作为参考,我们仍然在这个店里运行XP。我的桌面上有一个4 GB的Core i5 ...发货与Win7。我们正在运行Xtra Pathetic。这里的Sanity供不应求......)

// * ** * ** 晚修订版:

修改了LoadRunner调用(到web_reg_save_param_regexp),在我完成了RegEx的调整之后。不清楚为什么“不引用”RegExp没有为第一个值返回M$,但我发现为什么A*没有显示 - 实际上这很容易。最终值没有相同的边界条件。当值中有“271”时,第一个值,即“不引用”不包括在内。 ???

*

1 个答案:

答案 0 :(得分:2)

用于调用外部项目(包括perl代码)system()。您可能必须将perl项输出到您随后读回的文件中。或者,您可以将代码放在DLL中并使用lr_load_dll()调用它。

根据你的base64挑战,这里有一些你可能想要利用的base64函数。按原样提供,使用风险自负,不暗示支持或其他方式。我会说这段代码直接来自正在编码和解码的工作loadrunner虚拟用户。

static const unsigned char base64_table[64] =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";


unsigned char outbuf[BUFSIZE];

unsigned char * base64_encode(unsigned char *src, size_t len,
                              size_t *out_len)
{
        unsigned char *out, *pos;
        const unsigned char *end, *in;
        size_t olen;
        int line_len;

        olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
        olen += olen / 72; /* line feeds */
        olen++; /* nul termination */
        if (olen >= BUFSIZE)
            {
            lr_message("ERROR:  required buffer size of %d versus fixed buffer of %d.\n",
                        olen, BUFSIZE);
            return NULL;
            }
        out = outbuf;

        end = src + len;
        in = src;
        pos = out;
        line_len = 0;
        while (end - in >= 3) {
                *pos++ = base64_table[in[0] >> 2];
                *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
                *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
                *pos++ = base64_table[in[2] & 0x3f];
                in += 3;
                line_len += 4;
                if (line_len >= 72) {
                        *pos++ = '\n';
                        line_len = 0;
                }
        }

        if (end - in) {
                *pos++ = base64_table[in[0] >> 2];
                if (end - in == 1) {
                        *pos++ = base64_table[(in[0] & 0x03) << 4];
                        *pos++ = '=';
                } else {
                        *pos++ = base64_table[((in[0] & 0x03) << 4) |
                                              (in[1] >> 4)];
                        *pos++ = base64_table[(in[1] & 0x0f) << 2];
                }
                *pos++ = '=';
                line_len += 4;
        }

        if (line_len)
                *pos++ = '\n';

        *pos = '\0';
        if (out_len)
                *out_len = pos - out;
        return out;
}


unsigned char * base64_decode(unsigned char *src, size_t len,
                              size_t *out_len)
{
        unsigned char dtable[256], *out, *pos, in[4], block[4], tmp;
        size_t i, count, olen;

        memset(dtable, 0x80, 256);
        for (i = 0; i < sizeof(base64_table); i++)
                dtable[base64_table[i]] = i;
        dtable['='] = 0;

        /*for (i = 0;  i < 256;  i++)
            printf("%d ('%c')\t%d ('%c')\n", i, i, dtable[i], dtable[i]);*/

        count = 0;
        for (i = 0; i < len; i++) {
                if (dtable[src[i]] != 0x80)
                        count++;
        }

        //printf("count is %d\n", count);
        /*if (count % 4)
                return NULL;*/

        /*  handle code missing the ender equals - russelladd   */
        //if (count % 4)
                //printf("Input file with wrong number of valid characters.\n");
        for (i = 0;  i < count % 4;  i++)
            strcat(src, "=");

        count += (count % 4);
        /*  russelladd  */

        olen = count / 4 * 3;
        if (olen >= BUFSIZE)
            {
            lr_message("ERROR:  required buffer size of %d versus fixed buffer of %d.\n",
                        olen, BUFSIZE);
            return NULL;
            }
        pos = out = outbuf;

        count = 0;
        for (i = 0; i < len; i++) {
                tmp = dtable[src[i]];
                if (tmp == 0x80)
                        continue;

                in[count] = src[i];
                block[count] = tmp;
                count++;
                if (count == 4) {
                        *pos++ = (block[0] << 2) | (block[1] >> 4);
                        *pos++ = (block[1] << 4) | (block[2] >> 2);
                        *pos++ = (block[2] << 6) | block[3];
                        count = 0;
                }
        }

        if (pos > out) {
                if (in[2] == '=')
                        pos -= 2;
                else if (in[3] == '=')
                        pos--;
        }

        *out_len = pos - out;
        return out;
}