release notes/v0.25.0.md
k6 v0.25.0 is here! :tada:
This release contains mostly bug fixes, though it also has a few new features, enhancements, and performance improvements. These include HTTP request compression, brotli and zstd support, massive VU RAM usage and initialization time decreases, support for importing files via https and file URLs, and opt-in TLS 1.3 support.
Thanks to @THoelzel, @matlockx, @bookmoons, @cuonglm, and @imiric for contributing to this release!
Now k6 can compress the body of any HTTP request before sending it (#989). That can be enabled by setting the new compression option in the http.Params object. Doing so will cause k6 to transparently compress the supplied request body and correctly set both Content-Encoding and Content-Length, unless they were manually set in the request headers by the user. The currently supported algorithms are deflate, gzip, brotli and zstd, as well as any combination of them separated by commas (,).
k6 now also transparently decompresses brotli and zstd HTTP responses - previously only deflate and gzip were supported. Thanks, @imiric! (#1082)
import http from 'k6/http';
import { check } from "k6";
export default function () {
// Test gzip compression
let gzippedReqResp = http.post("https://httpbin.org/post", "foobar".repeat(1000), { compression: "gzip" });
check(gzippedReqResp, {
"request gzip content-encoding": (r) => r.json().headers["Content-Encoding"] === "gzip",
"actually compressed body": (r) => r.json().data.length < 200,
});
// Test br decompression
let brotliResp = http.get("https://httpbin.org/brotli", {
headers: {
"Accept-Encoding": "gzip, deflate, br"
},
});
check(brotliResp, {
"br content-encoding header": (r) => r.headers["Content-Encoding"] === "br",
"br confirmed in body": (r) => r.json().brotli === true,
});
// Test zstd decompression
let zstdResp = http.get("https://facebook.com/", {
headers: {
"Accept-Encoding": "zstd"
},
});
check(zstdResp, {
"zstd content-encoding header": (r) => r.headers["Content-Encoding"] === "zstd",
"readable HTML in body": (r) => r.body.includes("html"),
});
};
k6 uses the awesome core-js library to support new JavaScript features. It is included as a polyfill in each VU (i.e. JS runtime) and previously, it was parsed anew for every VU initialization. Now, the parsing result is cached after the first time and shared between VUs, leading to over 2x reduction of VU memory usage and initialization times for simple scripts!
Thanks, @matlockx, for noticing this opportunity for massive optimization!
https and file URLs (#1059)Previously, k6 had a mechanism for importing files via HTTPS URLs, but required that the used URLs not contain the https scheme. As a move to align k6 more closely with the rest of the JS ecosystem, we now allow and encourage users to use full URLs with a scheme (e.g. import fromurlencoded from "https://jslib.k6.io/form-urlencoded/3.0.0/index.js") when they want to load remote files. file URLs are also supported as another way to load local modules (normal absolute and relative file paths still work) from the local system, which may be especially useful for Windows scripts.
The old way of importing remote scripts from scheme-less URLs is still supported, though except for the GitHub and cdnjs shortcut loaders, it is in the process of deprecation and will result in a warning.
Following its opt-in support in Go 1.12, you can now choose to enable support for TLS 1.3 in your k6 scripts. It won't be used by default, but you can enable it by setting the tlsVersion (or it's max sub-option) to tls1.3:
import http from 'k6/http';
import { check } from "k6";
export let options = {
tlsVersion: {
min: "tls1.2",
max: "tls1.3",
}
};
export default function () {
let resp = http.get("https://www.howsmyssl.com/a/check");
check(resp, {
"status is 200": (resp) => resp.status === 200,
"tls 1.3": (resp) => resp.json().tls_version === "TLS 1.3",
});
};
Also, all cipher suites supported by Go 1.12 are now supported by k6 as well. Thanks, @cuonglm!
JS: Many fixes for open(): (#965)
"")"file.json" and paths such as "relative/path/to.txt" as relative (to the current working directory) paths; previously they had to start with a dot (i.e. "./relative/path/to.txt") for that to happen/ or \ as absolute from the current driveHTTP: Correctly always set response.url to be the URL that was ultimately fetched (i.e. after any potential redirects), even if there were non http errors. (#990)
HTTP: Correctly detect connection refused errors on dial. (#998)
JS: Run imports once per VU. (#975, #1040)
Config: Fix blacklistIPs JS configuration. Thanks, @THoelzel! (#1004)
HTTP: Fix a bunch of HTTP measurement and handling issues (#1047)
http_req_receiving metric was measured incorrectly (#1041)http.batch() call (#1044)JS: Many fixes for importing files and for URL imports in archives. (#1059)
Config: Stop saving and ignore the derived execution values, which were wrongly saved in archive bundles' metadata.json by k6 v0.24.0. (#1057, #1076)
Config: Fix handling of commas in environment variable values specified as CLI flags. (#1077)
.tar archive bundles. k6 v0.25.0 is backwards compatible and can execute bundles generated by older k6 versions, but the reverse is not true. (#1059)metadata.json file. (#1057, #1059)Content-Length header value was always automatically set by k6 - if the header value was manually specified by the user, it would have been ignored and silently overwritten. Now, k6 would set the Content-Length value only if it wasn't already set by the user. (#989, #1094)