0

对不起,如果这是一个重复的问题;我没有找到答案。(是的,我查过了,但我没有为 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 信息(到目前为止最好的是在 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);

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

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

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

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

在我理顺了 RegEx 之后,修改 LoadRunner 调用(到 web_reg_save_param_regexp)起作用了。不清楚为什么“不引用”正则表达式没有A*为第一个值返回 an,但我发现了为什么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);
4

1 回答 1

2

用于在 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;
}
于 2013-03-22T19:58:14.923 回答