Skip to content

v0.25.0

Compare
Choose a tag to compare
@na-- na-- released this 31 Jul 10:28
· 2945 commits to master since this release
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
  • 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)

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

    • the http_req_receiving metric was measured incorrectly (#1041)
    • binary response bodies could get mangled in an http.batch() call (#1044)
    • timed out requests could produce wrong metrics (#925)
  • 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)

Breaking changes

  • Previously, the 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)