删除测试期间生成的 ID
remove ids generated during the tests
为了在 vu
阶段进行负载测试,我生成了许多具有唯一 ID 的对象,并将它们放入数据库中。我想在 teardown
阶段删除它们,以免污染数据库。
当保持这样的状态时
let ids = [];
export function setup() {
ids.push('put in setup id');
}
export default function () {
ids.push('put in vu id');
}
export function teardown() {
ids.push('put in teardown id');
console.log('Resources: ' + ids);
}
它不起作用,因为数组始终包含我放入 teardown
阶段的数据。
由于众所周知的 Cannot extend Go slice
问题,在阶段之间传递数据也不起作用,但即使如此,您也无法将数据从 vu
阶段传递到 teardown
它总是从 setup
阶段获取数据。
唯一剩下的解决方案是使用 console log
或者只是使用简单的 id 预设并在测试中使用它们。还有别的办法吗?
setup()
、teardown()
和 VU 的 default
功能在完全不同的 JavaScript 运行时执行。对于分布式执行,它们可能在完全不同的机器上执行。因此,您不能只拥有一个可以从任何地方访问的全局 ids
变量。
该限制是您应该 return 来自 setup()
的任何您关心的数据的原因 - k6 将复制它并将其作为参数传递给 default
功能(这样你就可以使用你设置的任何资源)和teardown()
(这样你就可以清理它们)。
您的示例必须看起来像这样:
export function setup() {
let ids = [];
ids.push('put in setup id');
return ids;
}
export default function (ids) {
// you cannot push to ids here
console.log('Resources: ' + ids);
}
export function teardown(ids) {
console.log('Resources: ' + ids);
}
找到更多信息
为了扩展@na-- 的回答,我建议使用 Redis 和 Webdis 管理 ID 的外部解决方法。
其实很简单,如果你不介意运行一个额外的进程,应该不会对性能产生太大影响:
启动一个Webdis/Redis容器:
docker run --rm -it -p 127.0.0.1:7379:7379 nicolas/webdis
script.js
:
import http from 'k6/http';
const url = "http://127.0.0.1:7379/"
export function setup() {
const ids = [1, 2, 3];
for (let id of ids) {
http.post(url, `LPUSH/ids/${id}`);
}
}
export default function () {
const id = Math.floor(Math.random() * 10);
http.post(url, `LPUSH/ids/${id}`);
}
export function teardown() {
let res = http.get(`${url}LRANGE/ids/0/-1`);
let ids = JSON.parse(res.body)['LRANGE'];
for (let id of ids) {
console.log(id);
}
// cleanup
http.post(url, 'DEL/ids');
}
- 运行 5 次迭代:
k6 run -i 5 script.js
示例输出:
INFO[0000] 7
INFO[0000] 2
INFO[0000] 2
INFO[0000] 6
INFO[0000] 5
INFO[0000] 3
INFO[0000] 2
INFO[0000] 1
此解决方案的一个缺点是它会扭曲整体测试结果,因为额外的 HTTP 请求与测试本身无关。可能有一种方法可以用标签排除这些,否则这将是一个很好的功能请求。 :)
使用 Node.js Redis 客户端来避免 HTTP 请求可能是一种替代方法,但这些库通常不是 "browserifiable" 因此它们可能无法在 k6 中工作。
为了在 vu
阶段进行负载测试,我生成了许多具有唯一 ID 的对象,并将它们放入数据库中。我想在 teardown
阶段删除它们,以免污染数据库。
当保持这样的状态时
let ids = [];
export function setup() {
ids.push('put in setup id');
}
export default function () {
ids.push('put in vu id');
}
export function teardown() {
ids.push('put in teardown id');
console.log('Resources: ' + ids);
}
它不起作用,因为数组始终包含我放入 teardown
阶段的数据。
由于众所周知的 Cannot extend Go slice
问题,在阶段之间传递数据也不起作用,但即使如此,您也无法将数据从 vu
阶段传递到 teardown
它总是从 setup
阶段获取数据。
唯一剩下的解决方案是使用 console log
或者只是使用简单的 id 预设并在测试中使用它们。还有别的办法吗?
setup()
、teardown()
和 VU 的 default
功能在完全不同的 JavaScript 运行时执行。对于分布式执行,它们可能在完全不同的机器上执行。因此,您不能只拥有一个可以从任何地方访问的全局 ids
变量。
该限制是您应该 return 来自 setup()
的任何您关心的数据的原因 - k6 将复制它并将其作为参数传递给 default
功能(这样你就可以使用你设置的任何资源)和teardown()
(这样你就可以清理它们)。
您的示例必须看起来像这样:
export function setup() {
let ids = [];
ids.push('put in setup id');
return ids;
}
export default function (ids) {
// you cannot push to ids here
console.log('Resources: ' + ids);
}
export function teardown(ids) {
console.log('Resources: ' + ids);
}
找到更多信息
为了扩展@na-- 的回答,我建议使用 Redis 和 Webdis 管理 ID 的外部解决方法。
其实很简单,如果你不介意运行一个额外的进程,应该不会对性能产生太大影响:
启动一个Webdis/Redis容器:
docker run --rm -it -p 127.0.0.1:7379:7379 nicolas/webdis
script.js
:
import http from 'k6/http';
const url = "http://127.0.0.1:7379/"
export function setup() {
const ids = [1, 2, 3];
for (let id of ids) {
http.post(url, `LPUSH/ids/${id}`);
}
}
export default function () {
const id = Math.floor(Math.random() * 10);
http.post(url, `LPUSH/ids/${id}`);
}
export function teardown() {
let res = http.get(`${url}LRANGE/ids/0/-1`);
let ids = JSON.parse(res.body)['LRANGE'];
for (let id of ids) {
console.log(id);
}
// cleanup
http.post(url, 'DEL/ids');
}
- 运行 5 次迭代:
k6 run -i 5 script.js
示例输出:
INFO[0000] 7
INFO[0000] 2
INFO[0000] 2
INFO[0000] 6
INFO[0000] 5
INFO[0000] 3
INFO[0000] 2
INFO[0000] 1
此解决方案的一个缺点是它会扭曲整体测试结果,因为额外的 HTTP 请求与测试本身无关。可能有一种方法可以用标签排除这些,否则这将是一个很好的功能请求。 :)
使用 Node.js Redis 客户端来避免 HTTP 请求可能是一种替代方法,但这些库通常不是 "browserifiable" 因此它们可能无法在 k6 中工作。