v0.25.0
k6 v0.25.0 is here! 🎉
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!
New features and enhancements!
HTTP: request body compression + brotli and zstd decompression (#989, #1082)
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"),
});
};
Performance improvement: reuse the parsed core-js library across VUs (#1038)
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!
JS files can now be imported via 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.
Opt-in support for TLS 1.3 and more TLS ciphers (#1084)
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!
Bugs fixed!
-
JS: Many fixes for
open()
: (#965)- don't panic with an empty filename (
""
) - don't make HTTP requests (#963)
- correctly open simple filenames like
"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 - windows: work with paths starting with
/
or\
as absolute from the current drive
- don't panic with an empty filename (
-
HTTP: 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)
-
Config: Fix blacklistIPs JS configuration. Thanks, @THoelzel! (#1004)
-
HTTP: Fix a bunch of HTTP measurement and handling issues (#1047)
-
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)
Internals
- CI: removed the gometalinter check in CircleCI, since that project was deprecated and now exclusively rely on golangci-lint. (#1039)
- Archive bundles: The support for URL imports included a lot of refactoring and internal k6 changes. This included significant changes in the structure of
.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) - Archive bundles: The k6 version and the operating system are now saved in the archive bundles'
metadata.json
file. (#1057, #1059)