【问题标题】:How can I call Perl code from LoadRunner?如何从 LoadRunner 调用 Perl 代码?
【发布时间】:2013-03-22 13:58:10
【问题描述】:

对不起,如果这是一个重复的问题;我没有找到答案。 (是的,我查过了,但我没有为 LR 11.04 使用 RTFM。我想保持我所剩无几的理智。)

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

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

例如:

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

  • 标准 Web 应用程序 - 对某人的沙箱进行第三方调用。所有信息均采用 Base64 编码。我们需要获取明文(作为响应提供),然后编码为 Base 64,并将其发送到主系统。所以,AUT 是系统 A;系统 A 调用系统 B(302 响应),系统 B 响应,然后 AUT 将该数据发送回系统 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

示例代码sn-ps:

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);

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

问题是,很明显 AUT 会立即使用这两个值,所以我不能在稍后将值发回时使用它 - 显然,数字比文本更重要。

感谢任何建议,但我想避免使用system() - 这是我对 Base64 问题的解决方法(它应该是唯一的 Perl 调用,永远。)它工作得很好......直到我添加了 M$ 所需的补丁之一,并且无法再在 LoadRunner 中打开和读取文件(HP 说,这是自定义代码,我们帮不了你。所以我删除了 M$ 补丁并运行测试。它是大约 2010 年的 c++ Redistributable。那是 2012 年末。作为参考,我们仍在这家商店运行 XP。我的办公桌上有一个 4 GB 的 Core i5 ... 与 Win7 一起发货。我们重新运行 Xtra Pathetic。这里的理智供不应求……)

// ****** 后期修订:

在我理顺了 RegEx 之后,修改 LoadRunner 调用(到 web_reg_save_param_regexp)起作用了。不清楚为什么“不引用”正则表达式没有为第一个值返回 A*,但我发现了为什么 271 没有出现 - 实际上这很容易。最终值没有相同的边界条件。当值中有“*”时,第一个值显然不包括“不引用”。 ???

web_reg_save_param_regexp(
"ParamName=Charity_REGEX",
"RegExp={\"text\":\"([^\"]{1,8})\",\"value\":\"", 
"Ordinal=All",
SEARCH_FILTERS,
"Scope=Body",
"IgnoreRedirections=Yes",
"RequestUrl=*/Person.aspx*",
LAST);

web_reg_save_param_regexp(
"ParamName=Tenants_REGEX",
"RegExp=\",\"value\":\"([0-9]{1,3})\"}",
"Ordinal=All",
SEARCH_FILTERS,
"Scope=Body",
"IgnoreRedirections=Yes",
"RequestUrl=*/Person.aspx*",
LAST);

【问题讨论】:

    标签: perl loadrunner


    【解决方案1】:

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

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

    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;
    }
    

    【讨论】:

    • 就像一个插件一样,从 V 12 开始,LoadRunner 似乎已经创建了一个数据格式扩展来处理 Base 64 编码。谢谢你的回答,詹姆斯·普利。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多