A modern load testing tool, using Go and JavaScript - https://k6.io
AGPL-3.0 License
Bot releases are visible (Hide)
Published by github-actions[bot] over 2 years ago
k6 v0.36.0 is here! π It introduces a couple of new features which enhance its usability, includes a number of fixes, and the result of ongoing refactoring efforts.
Following #2082, k6 now has support for Source Maps. k6 will try to load source maps either from the file system(s) or from inside the script, based on the standard(-ish) //#sourceMappingURL=
comments. Furthermore, as k6 internally uses Babel to transform ES6+ scripts to ES5.1+, it will now make use of its ability to generate source maps, including combining with previously generated ones, to report correct line numbers. This should fix #1804; however, we anticipate some more issues will arise, and further tweaking will be necessary.
Thus, given an imported.js
module such as:
export function f1() {
throw "line 2";
}
throw "line 6";
}
export function f3() {
throw "line 10";
}
and a k6 test script importing it as such:
import { f2 } from "./imported.js"
export default function() {
f2();
}
Previous versions of k6 would report an error stack trace indicating an invalid line number in imported.js
(10):
ERRO[0000] line 6
at f2 (file:///some/path/imported.js:10:61(2))
at file:///some/path/sourcemap.js:4:20(4) executor=per-vu-iterations scenario=default source=stacktrace
Starting with v0.36.0
and source maps support, k6 would now report the exception at the correct line in imported.js
:
ERRO[0000] line 6
at f2 (file:///some/path/imported.js:6:2(2))
at file:///some/path/loadtest.js:4:2(4)
at native executor=per-vu-iterations scenario=default source=stacktrace
Note that if a file size is greater than 250kb and the internal Babel is needed, Babel will not generate source map. This is because during internal testing it was found this takes 3x to 4x more memory, potentially leading to OOM (standing for "Out Of Memory", a state in which the OS kills a process for using too much memory) on bigger inputs. If required, you can control the accepted file size limit via the temporary K6_DEBUG_SOURCEMAP_FILESIZE_LIMIT=524288
environment variable; which will be removed after we no longer rely on Babel (#2296). A pre-generated source map will always be loaded. For more details, check #2345.
Thanks to the contribution of @gernest (#2093), k6 now has the ability to abort a test run from within the test script. The newly added test.abort()
function in the k6/execution
module allows k6 scripts to immediately abort the test execution - the VU that called it will abort immediately and any other VUs in the same or other instances (in the case of k6 cloud
) will also be interrupted and abort soon after. Local k6 run
tests will exit with a code of 108
, so this event can also be easily detected in a CI script.
Aborting is possible during initialization:
import exec from "k6/execution";
exec.test.abort();
As well as inside the default function:
import exec from "k6/execution";
export default function() {
// Note that you can abort with a specific message too
exec.test.abort("this is the reason");
}
export function teardown() {
console.log("teardown will still be called after test.abort()");
}
Following #2279, the k6 inspect
command now supports an --execution-requirements
flag. When used, the command's output will include fields related to the execution requirements, by deriving k6's configuration from the execution context, and including the maxVUs
and totalDuration
fields in the output.
Thanks to the work of @sjordhani22, #2222 made it possible to force k6 to use version 1.1 of the protocol when firing HTTP requests.
It can be done by setting the http2client=0
value in the GODEBUG
environment variable:
GODEBUG=http2client=0 k6 run testscript.js
N.B: the usage of the GODEBUG
variable is considered temporary, and expected to change in the future. If you start using this feature, keep an eye out for potential future changes.
v0.36.0
marks the switch of some of our internal modules to a new Go/JavaScript module API. We expect this change to make the process of developing internal JavaScript modules and advanced JavaScript extensions easier and more streamlined in the future. Although this switch to a new API does not introduce breaking changes for existing extensions yet, we anticipate deprecating the old extension API (e.g. common.Bind()
, lib.WithState()
, etc.) at an undecided point in the future.
For more details, see: #2243, #2241, #2239, #2242, #2226, and #2232.
VUs are now restricted to only open()
files that were also opened in the init context of the first VU - the one that was initialized to get the exported options
from the JS script (__VU==0
). While it was somewhat possible to open files only in other VUs (e.g __VU==2
) in the past, it was unreliable. #2314 ensures that k6 would now throw an error in a similar scenario. This means that you can still open files only for some VUs, but you need to have opened all of those files in the initial VU (__VU==0
).
let file;
if (__VU == 0) {
open("./file1.bin")
open("./file2.bin")
} else if (__VU % 2 == 0) {
file = open("./file1.bin")
} else {
file = open("./file2.bin")
}
export default () => {
// use file for something
}
go-ntlmssp
dependency. The updating PR #2290 indeed fixes issues with NTLM Authentication backends returning two authorization headers.make ci-like-lint
target will run the exact same golangci-lint version that will be used in our GitHub Actions CI pipeline.api.v1
's client.Call
method in favor of its newer client.CallAPI
counterpart. It allows us to both reduce our reliance on external dependencies and improve its maintainability.http.head()
. The signature in k6 v0.35.0 was http.head(url, [params])
and was inadvertently changed to http.head(url, [body], [params])
in v0.36.0. That change will be reverted in k6 v0.37.0, but until then, we suggest users use the stable http.request('HEAD', url, null, params)
API for HTTP HEAD requests that need to specify custom parameters. Thanks, @grantyoung, for reporting the problem (#2401)!Published by github-actions[bot] almost 3 years ago
k6 v0.35.0 is here! π It introduces several new features that nicely enhance its usability and also contains a whole lot of fixes and ongoing efforts with refactoring.
In total, we have closed 14 issues. We have also branched out three new xk6 extensions during this release β
k6 now supports setting tags for VUs as part of the Execution API with an easy key-value interface. These tags are attached to the metrics emitted by the VU. Example usage:
import http from 'k6/http';
import exec from 'k6/execution';
export const options = {
duration: '10s',
vus: 3,
};
export default function () {
exec.vu.tags['mytag'] = 'value';
exec.vu.tags['vuId'] = exec.vu.idInTest;
console.log(`mytag is ${exec.vu.tags['mytag']} and my VU's ID in tags ${exec.vu.tags['vuId']}`);
// the metrics these HTTP requests emit will get tagged with `mytag` and `vuId`:
http.batch(['https://test.k6.io', 'https://test-api.k6.io']);
}
One of the most requested use cases for this feature is that now we can tag all metrics with the current stage number. With a bit of JS code it is possible to calculate which stage of a ramping-vus
or ramping-arrival-rate
scenario the VU is currently in. This in turn allows the setting of thresholds only on the metrics that were emitted in specific stages of the test run! π
There are some caveats, however: values can be only of String
, Number
or Boolean
type, while values of other types will result either in a warning or an exception if throw
option is enabled. Additionally, given that k6 has a whole bunch of system tags, one should be careful with using them as keys. You can read complete information about VU tags in k6/execution
docs.
With the goja update in #2197, you can now make a Promise
and chain it in your k6 scripts:
export default function () {
var p = new Promise((resolve, reject) => {
console.log('do something promising!');
reject('here');
});
p.then(
(s) => { console.log('fulfilled with', s) },
(s) => { console.log('rejected with', s) },
);
}
It must be noted that Promise
s are not used by k6 itself yet but this addition is a stepping stone for implementing async functionality in future releases. Thanks, @dop251, for your awesome work in developing goja! β€οΈ
k6's gRPC capabilities were extended with a support for server reflection which allows one to use gRPC even without a proto
file at hand. In other words, the following script is now possible:
import grpc from 'k6/net/grpc';
import { check } from "k6";
let client = new grpc.Client();
export default () => {
client.connect("127.0.0.1:10000", {plaintext: true, reflect: true})
const response = client.invoke("main.RouteGuide/GetFeature", {
latitude: 410248224,
longitude: -747127767
})
check(response, {"status is OK": (r) => r && r.status === grpc.StatusOK});
console.log(JSON.stringify(response.message))
client.close()
}
You can read more about the protocol here. Thanks, @joshcarp, for putting a lot of effort into this feature!
k6/ws
(#2193).metric.Add
calls to let NaN
values through. Instead, k6 will log nice warnings or throw an exception if --throw
is enabled (#1876, #2219).nil
response body (#2195). Thanks, @daniel-shuy!xk6-browser is a browser automation extension which relies on Chrome Devtools Protocol. With xk6-browser, you can interact with the browser to test your web applications end-to-end while accessing all of the k6 core features, including protocol-level APIs and other k6 extensions. Itβs a single tool for both protocol and browser-level testing.
The browser extension comes with an API that aims for rough compatibility with the Playwright API for NodeJS, meaning k6 users do not have to learn an entirely new API.
Prometheus is now officially supported in k6 OSS with a xk6-output-remote-write extension. This is an output extension with implementation for Prometheus Remote-Write protocol which means that beyond Prometheus, any compatible remote-write solution can be used with it. You can read the full guide to using the extension in the relevant tutorial.
After hard work at working out how to integrate InfluxDB v2 API, it was decided to pull that integration into a new xk6-output-influxdb extension for now. The built-in influxdb
output in k6 still supports only InfluxDB v1, as before, with some minor optimizations (#2190).
Please try out the new extensions and tell us what you think!
new Counter("http_req_duration")
will now abort. Similarly, an attempt to redefine a metric with the same name but with different type will error out. Builtin metrics may no longer be referenced as global objects in xk6 extensions either.K6_NO_SETUP
and K6_NO_TEARDOWN
options instead of NO_SETUP
and NO_TEARDOWN
(#2140).afero.FS
: implement a newer version of the afero.FS
interface for internal filesystems so that extension depending on that or newer version can be built (#2216).User-Agent
setting (#2151). Thanks, @cooliscool!mapstructure
(#2223).k6 participated in this year's hacktoberfest and we would like to thank all contributors! Here're some additional improvements made by the community members:
Thank you, @knittl, @cooliscool, @JosephWoodward, @b5710546232, @nontw, @divshacker, @daniel-shuy, @Sayanta66, @marooncoder09, @idivyanshbansal, @saintmalik, @EricSmekens, for helping make k6 better π
Published by github-actions[bot] about 3 years ago
k6 v0.34.1 is a patch release with a few minor bugfixes:
k6/execution
API added to k6 v0.34.0 - some of its properties weren't usable with the externally-controlled
executor (#2132).Response.json()
to not have a length
property when the response was a JSON array, i.e.response.json().hasOwnProperty('length')
was returning false
(#2133). Thanks for reporting, @julien-sugg!Published by github-actions[bot] about 3 years ago
k6 v0.34.0 is here! π It introduces the already announced k6/execution
API and includes some more enhancements and a bunch of minor bug fixes.
k6/execution
The k6/execution module allows the fetching of information about the current VU, instance (mostly relevant in distributed/cloud) or scenario execution state through a series of exported properties.
Some of the previously suggested solutions with the globally available __VU
and __ITER
values, such as for getting a unique object per iteration from an array or SharedArray
, can be done by using the scenario.iterationInTest
property, which is guaranteed to be unique across VUs, even for distributed or cloud tests. For example:
import exec from "k6/execution";
import { SharedArray } from "k6/data";
const data = new SharedArray("my dataset", function(){
return JSON.parse(open('my-large-dataset.json'));
})
export const options = {
scenarios :{
"use-all-the-data": {
executor: "shared-iterations",
vus: 100,
iterations: data.length,
maxDuration: "1h"
}
}
}
export default function() {
// this is unique even in the cloud
var item = data[exec.scenario.iterationInTest];
http.post("https://httpbin.test.k6.io/anything?endpoint=amazing", item)
}
You can read the full documentation here.
POST
HTTP request method instead of GET
for pushing logs to Loki (#2100).blacklistIPs
option using the CIDR notation in JSON (#2083).ext.loadimpact
option has the same precedence as the script configuration during the consolidation process (#2099).common.Bind
, which also gives JS modules and extensions easy access to some useful internal objects and runtime information (#2108). This API is not yet stable, it's very likely to change more in future k6 versions.Published by github-actions[bot] over 3 years ago
k6 v0.33.0 is here! π It's a small release that includes a bunch of minor bugfixes and enhancements, but is also laying the groundwork for some major new features like the upcoming k6/execution
API in k6 v0.34.0.
Load Impact, the company behind k6, was acquired by Grafana Labs! π Nothing changes regarding the k6 development for now, and any changes in the future will only be in the direction of accelerating our existing roadmap and plans, as well as better integration between k6 and the awesome Grafana tools. For more details, see the official Grafana press release.
--verbose
help message and the statsd warning message were improved (#2005). Thanks, @vishalkuo!noColor
k6 option and the current UI state are now propagated to the handleSummary()
function. The state
object has the isStdErrTTY
, isStdOutTTY
and testRunDurationMs
keys (#1975).context deadline exceeded
) and it now has an error_code
value of 1050
(#2008). Thanks, @vishalkuo!GoError
prefix in their error messages (#1775).name
property (#2058 and #2076). Thanks, @olimpias and @david-gourde!application/x-www-form-urlencoded
request (#2060). Thanks, @noelzubin!minIterationDuration
option was uninterruptible and could delay the stopping of a scenario even after gracefulStop
had expired. (#2035).error_code
detection for HTTP/2, x509 and TLS (and potentially others) was unreliable (#2025).responseType
was binary
, but there was no response body actually returned, e.g. when there was an HTTP error (#2041).throw
option was not respected when there was an invalid URL (#2045). Thanks, @gchaincl!103
instead of 107
for script errors when initializing non-service VUs (#2046).github
and cdnjs
"magic" loaders were slightly wrong (#2066).ramping-arrival-rate
scenarios was not optimal (#1863).k6-summary
JS code that is hosted on jslib.k6.io (#1975). That PR also improved the k6 TTY detection and removed a few Go dependencies and code hacks, though it also caused us to bump the minimum required Go version for compiling k6 to Go 1.16 (because of its usage of go:embed
).__VU
and __ITER
execution context variables we plan to introduce. The new API will be able to return other information as well, for example which scenario the current iteration is in, what's the number of the current VU/iteration globally across all k6 instances, or in the current scenario, etc. These APIs are still not available to JS scripts, but we plan to expose them via the k6/x/execution
xk6 extension for now and iterate on them in the following weeks, releasing a stable version in k6 v0.34.0.k6 cloud
exit code for a failed cloud test was changed from 99
to 97
(#2046).K6_STATSD_TAG_BLOCKLIST
and K6_DATADOG_TAG_BLACKLIST
is now vu,iter,url
(#2063).__ITER
execution context variable is no longer set in setup()
and teardown()
due to #1863. This might be better classified as removing a previously undefined behavior instead of a breaking change, but it's still worth mentioning.Published by github-actions[bot] over 3 years ago
k6 v0.32.0 is here! π It's a smaller release, featuring mostly chores that we never got to or that needed to be done in this release cycle, but also includes a significant performance improvement for arrival-rate executors and some breaking changes.
Bintray has stopped servicing users on 1st of May, which meant that we needed to move the deb and rpm repositories out of there before then. Please follow the new installation instructions and the "Note about Bintray" to find out how to remove the old repository if you have used them.
We started on this in the previous v0.31.0 release and now all internal outputs implement the new Output
interface we provided for xk6 output extensions. Additionally one of the old built-in outputs is being deprecated and one renamed:
kafka
output has been somewhat neglected since it was added 3 years ago. Additionally it brings a lot of complexity and isn't well understood by anyone on the team. Given that output extensions are possible since the last version, the Kafka output has been moved to one. The built-in output will continue to work for a few more k6 versions, emitting a deprecation warning when used, so that everyone has time to transition to the extension. All future improvements will happen only in the extension, the built-in output is frozen until it's dropped.datadog
output. It should've probably always been just a configuration of the statsd
output and now in k6 v0.32.0, it is going to be just that. We've added a new K6_STATSD_ENABLE_TAGS
option to the statsd
output, which, when enabled (it's false
by default), will send metric tags the same way the datadog
output did before. That is, instead of using the datadog
output, you should use the statsd
one with K6_STATSD_ENABLE_TAGS=true
. Additionally, the new K6_STATSD_TAG_BLOCKLIST
option can be used to not send tags that the user doesn't want to, similar to the old K6_DATADOG_TAG_BLACKLIST
option.datadog
output will still work for a few k6 versions, emitting a warning to switch to statsd
when used.Apart from a message about them being deprecated, nothing should be changed from the actual refactoring yet, but we advise users to use the proposed alternatives starting with this release.
json
output emits thresholds defined on the metrics (#1886)Previous to this change thresholds were not included in the json
output. Now the Metric
JSON object will get its thresholds
field properly populated.
Thanks to @codebien for this contribution!
cloud
output has an option to abort the test if aborted from the cloud (#1965)In v0.26.0 we made the cloud output stop emitting metrics if it gets a particular error from the backend, as that meant that the test was aborted in the cloud. Now we added K6_CLOUD_ABORT_ON_ERROR
to be able to say that it should not only stop emitting metrics, but also stop the execution of the local k6 test run. The default configuration is false
, so it is backwards compatible. This also works when the test is aborted by the user or if cloud execution limits are reached, which would also lead to the test being aborted.
For a long time, if there was an exception in either the init context or in the setup()
or teardown()
invocations, the stack trace would be just the last line, making it really hard to debug issues there. Now there is a full stack trace and, as such errors will result in aborted k6 execution, k6 run
will also exit with exit code 107
, signalling a script error.
Due to a wrong re-usage for a particular internal data structure, the arrival rate executors were having a much worse performance than expected. With this release they should be a lot more performant, especially with large numbers of VUs.
The list is too long and we have been postponing updating for quite some time now, but we have finally updated all our dependencies that we don't want to drop. This could lead to some stability problems, which is why it was done early on in the cycle. While the team has not found any regressions, given all the updates we could have missed something so please open a issue if you find anything.
Some notable updates:
let
/const
which allowed us to disable a Babel plugin. Previous to this if you had a particularly long script sometimes Babel took upwards of 30 minutes to transpile. Now even our worst contender that previously took 51 minutes is transpiled in less than a minute π. Also globalThis
is now available.ArrayBuffer
is now supported in all JS APIs dealing with binary data, including in WebSocket messages (#1841)Besides the minor breaking changes (see the "Breaking changes" section below), it's now possible to send binary WS messages with the socket.sendBinary()
function and to receive binary messages with the binaryMessage
event handler:
const binFile = open('./file.pdf', 'b');
export default function () {
ws.connect('http://wshost/', function(socket) {
socket.on('open', function() {
socket.sendBinary(binFile);
});
socket.on('binaryMessage', function(msg) {
// msg is an ArrayBuffer, so we can wrap it in a typed array directly.
new Uint8Array(msg);
});
});
}
We will now publish binary arm64 releases for macOS and Linux for new k6 releases. Support for these new architectures should be stable, given Go's cross-platform compatibility, but please report any issues you experience.
error_code
should now be set more accurately in some cases. (#1952)ssl3.0
a valid value for the tlsVersion
k6 option. Thanks @codebien! (#1897)responseCallback
in v0.31.0 would be evaluated with the returned status code, while the reported one would be 0
, as the response errored out and k6 does not return incomplete responses. Now responseCallback
will also receive a 0
status. (#1962)ramping-vus
executor would've not run a single iteration instead of just doing nothing. (#1942)go.k6.io/k6/js/modules#HasModuleInstancePerVU
. (Part of #1911)ArrayBuffer
in all k6 JS APIs (#1841)Continuing from k6 v0.31.0, we're finalizing the transition to ArrayBuffer
values for working with binary data. This release introduces some changes that might break scripts that relied on the previous array of integers
or string
result types, returned by some of our JS APIs. Specifically these cases now return ArrayBuffer
instead: open(..., 'b')
, HTTP response bodies for requests that specified responseType: 'binary'
(including when http.batch()
is used), crypto.randomBytes()
, hasher.digest('binary')
and encoding.b64decode()
.
The previous default behavior of returning string from encoding.b64decode()
can be replicated with a new optional format
argument and a value of "s"
: encoding.b64decode("5bCP6aO85by-Li4=", "url", "s")
.
Most of these shouldn't cause issues if the script is simply passing the values to another k6 API (e.g. opening a file as binary and passing it to http.post()
), but in other cases the script will need to be modified to wrap the ArrayBuffer
in a typed array view and use that API instead.
We have stopped offering official builds for 32-bit Windows and Linux binaries, as they were causing issues in some cases, and users were likely using them by mistake instead of necessity.
go.k6.io/k6
(#2010)We moved the repository location from https://github.com/loadimpact/k6 to https://github.com/k6io/k6. Instead of also moving the Go module paths to the new repo location, we decided to use custom ones with our own domain, for more control. This will be a breaking change for all xk6 extensions, since they import parts of k6 by source to register themselves.
.deb
and .rpm
repositoriesWe already mentioned this in the v0.31.0 release, but because of the Bintray shutdown, we had to move our .deb
and .rpm
repositories. They are now located at dl.k6.io, and you can use the updated installation instructions to transition to them.
Published by github-actions[bot] over 3 years ago
k6 v0.31.1 is a patch release with a single bugfix.
The bugfix is about the cloud output and the new http_req_failed
metric in k6 v0.31.0. Due to additional state being used for its transport to the k6 cloud, and a misunderstanding of what a functional call from a library dependency does, the http_req_failed
values were always set to 1
. This did not affect any other output or the end of test summary. (#1908)
Published by github-actions[bot] over 3 years ago
k6 v0.31.0 is here! π It's a smaller release with some significant performance improvements, a new http_req_failed
metric and changes to the output subsystem that enable output extensions with xk6!
The state of k6's output packages has been a development pain point for a long time, which made it difficult to add new outputs in a consistent way. In the refactor done in v0.31.0, this has been mostly addressed and outputs now implement a simpler and cleaner Output
interface.
In addition to this, it is now possible to implement custom k6 output extensions in Go with xk6! This is very useful if you use a system that's currently not supported by the built-in outputs, or need some custom handling of the metrics k6 produces.
Writing output extensions is done very similarly to how JS module extensions are currently written, though instead of calling js/modules.Register()
, you should implement the new Output
interface and call output.RegisterExtension()
with your constructor.
We are working on the proper documentation for this, as well as the overdue xk6 documentation about JS extensions, so keep a lookout for those on k6.io/docs.
It's now possible to declare expected HTTP response statuses for either the entire test or for individual HTTP requests, and k6 will emit a new http_req_failed
metric as well as tag HTTP metrics with expected_response: <bool>
. By default, k6 will now fail requests that return HTTP 4xx/5xx response codes.
For example:
import http from 'k6/http';
// Set expected statuses globally for all requests.
http.setResponseCallback(http.expectedStatuses({min: 200, max: 399}, 418));
export default function () {
// This request will be marked as failed.
http.get('https://httpbin.test.k6.io/status/400');
// This request will be considered as "passed" because of the responseCallback override.
http.get('https://httpbin.test.k6.io/status/400', { responseCallback: http.expectedStatuses(400) });
}
Running this script will produce a summary like:
http_req_duration..............: avg=204.57ms min=203.31ms med=204.57ms max=205.82ms p(90)=205.57ms p(95)=205.7ms
{ expected_response:true }...: avg=203.31ms min=203.31ms med=203.31ms max=203.31ms p(90)=203.31ms p(95)=203.31ms
http_req_failed................: 50.00% β 1 β 1
Note the new http_req_duration
sub-metric for expected responses only, and the new http_req_failed
Rate
metric. This new metric and metric tag have many potential use cases, and one of the most important ones is the ability to set better thresholds. For example:
'http_req_failed': ['rate<0.1']
, i.e. fail the test if more than 10% of requests fail.'http_req_duration{expected_response:true}': ['p(95)<300', 'p(99.9)<500']
- fail the test if the the 95th percentile HTTP request duration is above 300ms or the 99.9th percentile is above 500ms; specifying expected_response:true
here may be important, because a lot of times failed requests may return more quickly than normal ones, thus skewing the results and wrongly satisfying the threshold.If the response callback is not specified, the default expected statuses will be {min: 200, max: 399}
. The previous behavior of not emitting anything can be achieved by setting the callback to null
, i.e. http.setResponseCallback(null)
. Additionally, the expected_response
tag can be disabled by removing it from the default list of system tags, e.g. k6 run --system-tags 'proto,subproto,status,method,url,name,group,check,error,error_code,tls_version,scenario,service'
.
The http.setResponseCallback()
is planned to allow arbitrary JS functions to process responses in the future, but for now only the http.expectedStatuses()
callback is supported.
--compatibility-mode=extended
. So in v0.31.0 core.js has been dropped entirely, yielding some significant CPU and memory usage improvements. The actual numbers will depend on the use case, but for simple tests users can expect a memory drop of about 2MB per VU (from ~2.7MB to ~600KB), and a slight CPU decrease of about 5-10%. For more complex tests with a lot of JS code this benefit won't be as pronounced. Another benefit of this change is that initializing VUs and starting a test is substantially faster than before! (#1824)ArrayBuffer
support in most internal modules, so now you can pass ArrayBuffer
to http.file()
, in k6/encoding
and k6/crypto
functions. This makes working with binary files more efficient as it doesn't require string translations. In upcoming versions we plan to expand this to the WebSocket module, as well as make some potentially breaking changes for APIs that currently return an array of integers or string (see the details in the Breaking Changes announcement below). (#1800)ca-certificates
as a dependency. Thanks @Bablzz! (#1854)^C
) will now properly propagate to any used outputs. (#1869)ext.loadimpact.name
JS option or config, or the K6_CLOUD_NAME
environment variable. (#1870)SharedArray
introduced in v0.30.0 can now be iterated with forEach
. (#1848)SharedArray
was rewritten using goja.DynamicArray
making it more performant and easier to reason about. (#1848)Promise
is now undefined
, and some unused Babel plugins like transform-es2015-for-of
and transform-regenerator
were also removed. This means that some workarounds like the ones mentioned here and here also won't work as is and will need additional polyfills and plugins to work properly.The following are not breaking changes in this release, but we'd like to announce them so users can prepare for them in upcoming releases (likely k6 v0.32.0).
ArrayBuffer
changes in this release are backwards compatible and shouldn't cause any issues, but in v0.32.0 some JS APIs that currently return an array of integers or string for binary data will return ArrayBuffer
instead. This is the case for open()
when used with the 'b'
argument, response bodies for requests that specify responseType: 'binary'
, crypto.randomBytes()
, hasher.digest('binary')
, and encoding.b64decode()
. Response.json()
and Response.html()
will also probably stop working when used with requests that specify responseType: 'binary'
. These changes shouldn't be a problem for most users that were simply using these values to pass them to other internal modules (e.g. opening a binary file and passing it to http.post()
), but if the scripts modified the binary data or depended on the current array of integers or string values they will need to be adapted to use typed arrays instead. You can follow the discussion in PR #1841 and issue #1020.Published by github-actions[bot] over 3 years ago
k6 v0.30.0 is here! π It was a bit of a slow after-holiday release, but it still packs a few major new features and improvements that users have been requesting for a long time!
k6 has long had an issue with the handling of big data files with test fixtures. For example, if you have a huge users.json
file with test users for your application:
[
{"username": "user1", "password": "password1", "other": "some-long-data-....-1"},
{"username": "user2", "password": "password2", "other": "some-long-data-....-2"},
// ... ~1 million more users or more... :D
{"username": "user999999", "password": "password999999", "other": "some-long-data-....-999999"}
]
If you just use JSON.parse(open('users.json'))
in your script, then every VU will have a copy of the whole huge data set. Every VU in k6 is a separate JavaScript runtime, so there wasn't a thread-safe way to share data between them. Until now, that is!
We've added a new built-in SharedArray
object in the new k6/data
module that allows VUs to share read-only data:
import { SharedArray } from 'k6/data';
import { sleep } from 'k6';
import http from 'k6/http';
let users = new SharedArray('someName', function () {
// This function will be called only once, in the first init context
// execution. Every other VU will just get a memory-safe read-only reference
// to the already loaded data.
console.log('Loading users.json, this happens only once...');
// You are not restricted to JSON, you can do anything - parse a CSV or XML
// file, generate random data, etc. - as long as you return an array.
return JSON.parse(open('users.json'));
});
export let options = { vus: 10, duration: '30s' };
export default function () {
let randomUserID = Math.floor(Math.random() * users.length);
let user = users[randomUserID]; // alternatively, we can also use __VU and/or __ITER
console.log(`VU ${__VU} is running iteration ${__ITER} with user ${user.username}...`);
http.post('https://httpbin.test.k6.io/post', JSON.stringify(user));
sleep(Math.random() * 2); // or, better yet, use arrival-rate
}
Notice how Loading users.json
is logged only once, but each VU uses the users
variable like a normal JS array. The data is read only once and we have just a single copy of the huge array in memory! Behind the scenes, k6 uses a JS Proxy
to transparently copy only the row each VU requests in users[randomUserID]
to it. This on-demand copying is a bit inefficient, but it's still leagues better than having a copy of the huge array in every VU! And you can avoid the copying in every iteration by pinning the data used by every VU and having let user = users[randomUserID]
in the init context!
And yes, you can have multiple SharedArray
objects in the same script, just make sure to give them unique names - this is what someName
in the script above was for. Because VUs are independent JS runtimes, we need some way to differentiate between the different shared memory objects, so we require them to have unique names. These names are also the IDs that any xk6 extensions would need to use to access them.
This works both locally and in the cloud. We advise everyone who deals with large data files to wrap them in a SharedArray
and give this new feature a try. The required script changes should be minimal, while the memory usage should be significantly lower. Hopefully, we can finally consider one of the biggest blockers k6 users have had for a long time solved! π
handleSummary()
callback at the end of the test (#1768)You can now export
a function called handleSummary()
and k6 will call it at the end of the test run, after even teardown()
. handleSummary()
will be called with a JS object containing the same information that is used to generate the end-of-test summary and --summary-export
, and allows users to completely customize how the end-of-test summary looks like.
Besides customizing the end-of-test CLI summary (if handleSummary()
is exported, k6 will not print the default), you can also transform the summary data to various machine or human-readable formats and save it to files. This allows the creation of JS helper functions that generate JSON, CSV, XML (JUnit/xUnit/etc.), HTML, etc. files from the summary data. Even binary formats like PDF are not out of reach, potentially, with an appropriate JS library that works in k6! You can also send the generated reports to a remote server by making an HTTP request with them (or using any of the other protocols k6 already supports)! Here's a simple example:
import http from 'k6/http';
import k6example from 'https://raw.githubusercontent.com/loadimpact/k6/master/samples/thresholds_readme_example.js';
export default k6example; // use some predefined example to generate some data
export const options = { vus: 5, iterations: 10 };
// These are still very much WIP and untested, but you can use them as is or write your own!
import { jUnit, textSummary } from 'https://jslib.k6.io/k6-summary/0.0.1/index.js';
export function handleSummary(data) {
console.log('Preparing the end-of-test summary...');
// Send the results to some remote server or trigger a hook
let resp = http.post('https://httpbin.test.k6.io/anything', JSON.stringify(data));
if (resp.status != 200) {
console.error('Could not send summary, got status ' + resp.status);
}
return {
'stdout': textSummary(data, { indent: ' ', enableColors: true}), // Show the text summary to stdout...
'junit.xml': jUnit(data), // but also transform it and save it as a JUnit XML...
'summary.json': JSON.stringify(data), // and a JSON with all the details...
// And any other JS transformation of the data you can think of,
// you can write your own JS helpers to transform the summary data however you like!
}
}
k6 expects handleSummary()
to return a {key1: value1, key2: value2, ...}
map. The values can be string or ArrayBuffer
and represent the generated summary report contents. The keys should be strings and determine where the contents will be displayed or saved: stdout
for standard output, stderr
for standard error, or a path to a file on the system (which will be overwritten).
The format of the data
parameter is similar but not identical to the data format of --summary-export
. The format of --summary-export
remains unchanged, for backwards compatibility, but the data format for this new k6 feature was made more extensible and had some of the ambiguities and issues from the previous format fixed. We can't cover the new format in the release notes, though you can easily see what it contains by using return { 'stdout': JSON.stringify(data)};
in handleSummary()
! π
This feature is only available for local k6 run
tests for now, though we plan to support k6 cloud
tests eventually. And, as mentioned in the snippet above, the JS helper functions that transform the summary in various formats are far from final, so keep an eye on jslib.k6.io for updates. Or, better yet, submit PRs with improvements and more transformations at https://github.com/loadimpact/jslib.k6.io π
master
version. This includes a few bugfixes and support for several new features, so --compatibility-mode=base
is even more feature-rich at no additional runtime cost. We are contributing patches to goja in an effort to completely drop core.js and have the benefit of lower CPU and memory usage per VU even with --compatibility-mode=extended
in the next k6 version! πduration
and similar time values in the exported script options
and environment variables are now treated as milliseconds. Similarly, the timeout
option in http.Params
can now be "stringy", e.g. "30s"
, "1m10s"
, etc. (#1738).ArrayBuffer
values for the HTTP request body (#1776). This is a prelude/MVP for us gradually adopting ArrayBuffer
for all binary data in k6 (#1020).WORKDIR /home/k6
to our official Dockerfile
(#1794).golang.org/x/crypto
and golang.org/x/net
dependencies, which should have resolved some corner case issues with HTTP/2 connections, since k6 depends on golang.org/x/net/http2
(#1734).blockHostnames
that prevented zero-length matches for wildcards, as well as the explicit blocking of a domain and its sub-domain at the same time (#1723).host
value from http.Response.request.headers
when it was explicitly set in the HTTP request params. (#1744). Thanks, @noelzubin!k6 login
password inputs (#1749). Thanks, @paroar!html.Selection.slice()
method (#1756). Thanks, @asettouf!Rate
metrics in the --summary-export
JSON file was was always 0
, regardless of the pass/(pass+fail)
ratio (#1768).Some of the changes above deserve a special second mention, since they either slightly break previously documented k6 behavior, or fix previously undefined behavior and bugs that someone might have inadvertently relied on:
--no-summary
now also disables --summary-export
(#1768). You can recreate the previous behavior of k6 run --no-summary --summary-export=summary.json script.js
by having an empty exported handleSummary()
function in your script (so that the default text summary is not shown by k6) and executing only k6 run --summary-export=summary.json script.js
. Or omitting --summary-export
as well and using handleSummary()
as shown above.duration
and similar time values in the exported script options
and environment variables are now treated as milliseconds. This was previously undefined behavior, but instead of k6 erroring out, it silently accepted and treated such values as nanoseconds (#1738).WORKDIR /home/k6
to our official Dockerfile
(#1794).Published by github-actions[bot] almost 4 years ago
k6 v0.29.0 is here! π It's a feature-packed release with tons of much-requested changes and additions, a lot of them implemented by awesome external contributors! β€οΈ
As promised in the previous release notes, we're trying to stick to a roughly 8-week release cycle, so you can expect the next k6 version at the start of January 2021, barring any bugfix releases before that.
k6 now supports unary gRPC calls via the new k6/net/grpc
built-in module. Streaming RPCs are not yet supported and the JS API is in beta, so there might be slight breaking changes to the API in future k6 versions, but it's a good start on the road to fully supporting this much-requested protocol!
This is a simple example of how the new module can be used with grpcb.in:
import grpc from "k6/net/grpc";
let client = new grpc.Client();
// Download addsvc.proto for https://grpcb.in/, located at:
// https://raw.githubusercontent.com/moul/pb/master/addsvc/addsvc.proto
// and put it in the same folder as this script.
client.load(null, "addsvc.proto");
export default () => {
client.connect("grpcb.in:9001", { timeout: "5s" });
let response = client.invoke("addsvc.Add/Sum", {
a: 1,
b: 2
});
console.log(response.message.v); // should print 3
client.close();
}
You can find more information and examples how to use k6's new gRPC testing capabilities in our documentation.
Huge thanks to @rogchap for adding this feature!
You can now control some aspects of how k6 performs DNS resolution! Previously, k6 would have cached DNS responses indefinitely (#726) and always picked the first resolved IP (#738) for all connections. This caused issues, especially when load testing services that relied on DNS for load-balancing or auto-scaling.
For technical reasons explored in (#726), k6 v0.29.0 still doesn't respect the actual TTL value of resolved IPs, that will be fixed in a future k6 version. For now, it simply allows users to specify a global static DNS TTL value and resolution strategy manually. It also has better defaults! Now, by default, the global DNS TTL value is 5 minutes and, if the DNS resolution returned multiple IPs, k6 will pick a random (preferably IPv4) one for each connection.
You can also configure this behavior with the new --dns
CLI flag, the K6_DNS
environment variable, or the dns
script/JSON option. Three DNS resolution options are exposed in this k6 version: ttl
, select
, and policy
.
Possible ttl
values are :
0
: no caching at all - each request will trigger a new DNS lookup.inf
: cache any resolved IPs for the duration of the test run (the old k6 behavior).60s
, 5m30s
, 10m
, 2h
, etc.; if no unit is specified (e.g. ttl=3000
), k6 assumes milliseconds. The new default value is 5m
.
Possible select
values are:
first
- always pick the first resolved IP (the old k6 behavior).random
- pick a random IP for every new connection (the new default value).roundRobin
- iterate sequentially over the resolved IPs.Possible policy
values are:
preferIPv4
: use IPv4 addresses, if available, otherwise fall back to IPv6 (the new default value).preferIPv6
: use IPv6 addresses, if available, otherwise fall back to IPv4.onlyIPv4
: only use IPv4 addresses, ignore any IPv6 ones.onlyIPv6
: only use IPv6 addresses, ignore any IPv4 ones.any
: no preference, use all addresses (the old k6 behavior).Here are some configuration examples:
k6 run --dns "ttl=inf,select=first,policy=any" script.js # this is the old k6 behavior
K6_DNS="select=random,ttl=5m,policy=preferIPv4" k6 cloud script.js # new default behavior
# syntax for the JSON config file or for the exported script `options`:
echo '{"dns": {"select": "roundRobin", "ttl": "1h33m7s", "policy": "onlyIPv6"}}' > config.json
k6 run --config "config.json" script.js
After some discussions (#1353) and exploration of different approaches for Go-based k6 extensions, we've settled on adopting something very similar to caddy's extensions. In short, xk6
(modeled after xcaddy
) is a small stand-alone tool that will be able to build custom k6 binaries with 3rd party extensions bundled in. The extensions can be simple Git repositories (no central infrastructure needed!) with Go modules. They will be fully compiled, not interpreted, a part of the final custom k6 binary users will be able to build with k6.
xk6 is not yet stable or documented, so any extension authors will struggle until we stabilize and document everything in the coming weeks. The important part is that the k6 changes that would allow xk6 to work were implemented in #1688, so k6 v0.29.0 is the first version compatible with xk6!
Expect more information soon, but for a brief example, xk6 will work somewhat like this:
xk6 build v0.29.0 --with github.com/k6io/xk6-k8s --with github.com/k6io/[email protected]
./k6 run some-script-with-sql-and-k8s.js
Thanks, @andremedeiros, for pushing us to add plugins in k6 and for making a valiant attempt to harness Go's poor plugin API! Thank you, @mardukbp, for pointing us towards the xcaddy approach and explaining its benefits!
You can now specify a list of source IPs, IP ranges and CIDRs for k6 run
, from which VUs will make requests via the new --local-ips
CLI flag or K6_LOCAL_IPS
environment variable. The IPs will be sequentially given out to VUs, allowing you to distribute load between different local addresses. This option doesn't change anything on the OS level, so the IPs need to already be configured on the OS level in order for k6 to be able to use them.
The biggest use case for this feature is splitting the network traffic from k6 between multiple network adapters, thus potentially greatly increasing the available network throughput. For example, if you have 2 NICs, you can run k6 with --local-ips="<IP-from-first-NIC>,<IP-from-second-NIC>"
to balance the traffic equally between them - half of the VUs will use the first IP and the other half will use the second. This can scale to any number of NICs, and you can repeat some local IPs to give them more traffic. For example, --local-ips="<IP1>,<IP2>,<IP3>,<IP3>"
will split VUs between 3 different source IPs in a 25%:25%:50% ratio.
Thanks to @ofauchon, @srguglielmo, and @divfor for working on previous iterations of this!
You can now block network traffic by hostnames with the new --block-hostnames
CLI flag / K6_BLOCK_HOSTNAMES
environment variable / blockHostnames
JS/JSON option. Wildcards are also supported at the beginning, allowing you to easily block a domain and all of its subdomains. For example, this will make sure k6 never attempts to connect to any k6.io
subdomain (test.k6.io
, test-api.k6.io
, etc.) and www.example.com
:
export let options = {
blockHostnames: ["*.k6.io" , "www.example.com"],
};
Thanks to @krashanoff for implementing this feature!
Response.json(selector)
behavior was updated, so we now support more modifiers like @flatten
and multipaths (#1626). Thanks, @sondnm!Response.status_text
field (#1649). Thanks, @lcd1232!--http-debug
now emits extra UUID values that can be used to match HTTP requests and their responses (#1644). Thanks, @repl-david-winiarski!allowedLabels
sub-option is added to the Loki configuration (#1639).k6 cloud
test with Ctrl+C
, k6 will now wait for the cloud service to fully abort the test run before returning. A second Ctrl+C
will cause it to immediately exit (#1647), (#1705). Thanks, @theerapatcha!--compatibility-mode=extended
when Babel can transpile the code but goja can't parse it (#1651).context canceled
error message to be shown (#1677).userAgent
option caused k6 to revert to the default Go User-Agent
header value of Go-http-client
. Now something like --user-agent=''
will cause k6 to not send the User-Agent
header at all (#1695).k6 cloud --quiet
didn't just hide the progressbar, but caused the k6 process to exit as soon as the cloud test was created, without waiting for it to finish. k6 cloud -q
is now fixed to be similar to the k6 run -q
behavior, but if the old behavior was wanted, something close to it can be recreated by using k6 cloud --exit-on-running
(#1702).--dns="ttl=inf,select=first,policy=any"
.Published by imiric about 4 years ago
k6 v0.28.0 is here! π It's a small release that adds some much requested features and a few important bugfixes!
Starting with this release, we'll be trying to stick to a new 8-week fixed release schedule for new k6 versions. This release comes ~8 weeks after v0.27.0 was released, and k6 v0.29.0 should be released in mid-November.
Logs from distributed k6 cloud test runs will now be shown in the terminal that executed the k6 cloud
command, as well as in the k6 cloud web app on app.k6.io! π This means that, if your script contains console.log()
/ console.warn()
/ etc. calls, or some of your requests or iterations fail, you'd be able to see that and debug them much more easily! Even --http-debug
data should be proxied, up to 10000 bytes per message. To prevent abuse and not to overwhelm any user terminals, cloud logs are rate-limited at 10 messages per second per instance, for now, but that should be more than enough to debug most issues!
This feature is enabled by default, though you can disable it with k6 cloud --show-logs=false script.js
.
k6 can now push its execution logs to a loki server! This can be done via the new --log-output
CLI flag or the K6_LOG_OUTPUT
environment variable option. For example, k6 run --log-output "loki=https://my-loki-server/loki/api/v1/push,limit=100,level=info,msgMaxSize=10000"
will push up to 100 k6 log messages per second, of severity INFO
and up, truncated to 10000
bytes, to https://my-loki-server
.
@calavera added an extension for the host mapping feature. Now you can specify different port numbers via the hosts
option, like this:
import http from 'k6/http';
export let options = {
hosts: {
'test.k6.io': '127.0.0.1:8080',
},
};
@TamiTakamiya added support for specifying the data type (int/float/bool/string) of fields that are emitted to InfluxDB outputs.
In order to specify the data type, you should:
K6_INFLUXDB_TAGS_AS_FIELDS
, which is used to specify which k6 metric tag values should be sent as nonindexable fields (instead of tags) to an InfluxDB output. This is specified as a comma-separated string, and is now extended to optionally allow specifying a data type to each name.(name):(data_type)
, for example, event_processing_time:int
.int
, float
, bool
and string
) can be specified to one field name.data_type
are omitted, for example transaction_id
, it is interpreted as a string field.A complete example can look like this: export K6_INFLUXDB_TAGS_AS_FIELDS="vu:int,iter:int,url:string,boolField:bool,floatField:float"
Note: If you have existing InfluxDB databases that contain fields whose data types are different from the ones that you want to save in future k6 test executions, you may want to create a new database or change field names as the current InfluxDB offers limited support for changing fields' data type. See the InfluxDB documentation for more details.
@thejasbabu added support to gzip archiving the file emitted by the CSV output on the fly. To use it, simply append .gz
at the end of the file name, like this: k6 run --out csv=test.csv.gz test.js
source
field specifying if a log comes from console
, http-debug
or stacktrace
(when an exception has bubbled to the top of the iteration).hosts
port mapping (#1489). Thanks, @calavera!name
metric tag for redirected requests (#1474).divide by zero
panic caused by some unusual execution environments that present a TTY, but return 0
for the terminal size (#1581).K6_DATADOG_TAG_BLACKLIST
(#1602).tlsCipherSuites
and tlsVersion
(#1603). Thanks, @berndhartzer!ws.SetTimeout()
and ws.SetInterval()
panic when float values were passed (#1608).--compatibility-mode=base
now supports some standard library features from ES6 (goja's PR), though no new syntax yet. In future versions we plan to drop some current core.js modules that are no longer needed, which should greatly reduce memory usage per VU (#1588).dep
(#1584).k6 cloud
will now proxy execution logs back to the client machine. To disable this behavior, use k6 cloud --show-logs=false
.
--http-debug
request and response dumps are now emitted through the logging sub-system, to facilitate the cloud log proxying (#1577).
Published by na-- about 4 years ago
k6 v0.27.1 is a minor release with a few bugfixes and almost no functional changes compared to v0.27.0.
The biggest fix was resolving a panic (and some k6 login
errors) when k6 was ran through git bash / Mintty on Windows (#1559).
k6 will now work in those terminals, however, if you're using git bash or Mintty as your terminal on Windows, you might not get the best user experience out of k6. Consider using a different terminal like Windows Terminal, PowerShell or Cmder. Alternatively, to work around the issues with the incompatible terminals, you can try running k6 through winpty
, which should already be preinstalled in your git bash environment: winpty k6 run script.js
.
If you're using the Windows Subsystem for Linux (WSL), you are probably going to get better experience by using the official Linux k6 binary or .deb package. For all other cases of running k6 on Windows, the normal k6 Windows binary / .msi
package should work well.
throw
option is enabled, warnings for failed HTTP requests will no longer be logged to the console (#1199).k6 run --out cloud
can now be sent in parallel via the new K6_CLOUD_METRIC_PUSH_CONCURRENCY
option, with a default value of 1
(#1569).gracefulRampDown
VU requirement calculations for the ramping-vus
executor were greatly optimized for large test runs (#1567).dropped_iterations
wouldn't be emitted by the per-vu-iterations
executor on time due to a race (#1357).setup()
and teardown()
, were not correctly shown in local k6 runs (#949).Published by na-- over 4 years ago
k6 v0.27.0 is here! π
This is a milestone release containing a major overhaul to the execution subsystem of k6, along with many improvements and bug fixes.
After 1.5 years in the making, the k6 team is proud to release the first public version of the new execution engine, offering users new ways of modeling advanced load testing scenarios that can more closely represent real-world traffic patterns.
These new scenarios are entirely optional, and the vast majority of existing k6 scripts and options should continue to work the same as before. There are several minor breaking changes and fixes of previously undefined behavior, but please create a new issue if you find some issue we haven't explicitly noted as a breaking change.
See the documentation for details and examples, or keep reading for the summary.
Some of the currently possible script execution patterns were formalized into standalone executors:
shared-iterations
: a fixed number of iterations are "shared" by all VUs, and the test ends once all iterations are executed. This executor is equivalent to the global vus
and iterations
(plus optional duration
) options.constant-vus
: a fixed number of VUs execute as many iterations as possible for a specified amount of time. This executor is equivalent to the global vus
and duration
options.ramping-vus
: a variable number of VUs execute as many iterations as possible for a specified amount of time. This executor is equivalent to the global stages
option.externally-controlled
: control and scale execution at runtime via k6's REST API or the CLI.You'd still be able to use the global vus
, iterations
, duration
, and stages
options, they are not deprecated! They are just transparently converted to one of the above executors underneath the hood. And if your test run needs just a single, simple scenario, you may never need to use more than these shortcut options. For more complicated use cases however, you can now fine-tune any of these executors with additional options, and use multiple different executors in the same test run, via the new scenarios
option, described below.
Additionally, besides the 4 "old" executor types, there are 3 new executors, added to support some of the most frequently requested load testing scenarios that were previously difficult or impossible to model in k6:
per-vu-iterations
: each VU executes a fixed number of iterations (#381).constant-arrival-rate
: iterations are started at a specified fixed rate, for a specified duration. This allows k6 to dynamically change the amount of active VUs during a test run, to achieve the specified amount of iterations per period. This can be very useful for a more accurate representation of RPS (requests per second), for example. See #550 for details.ramping-arrival-rate
: a variable number of iterations are executed in a specified period of time. This is similar to the ramping VUs executor, but instead of specifying how many VUs should loop through the script at any given point in time, the iterations per second k6 should execute at that point in time can be specified.It's important to also note that all of these executors, except the externally-controlled
one, can be used both in local k6 execution with k6 run
, and in the distributed cloud execution with k6 cloud
. This even includes "old" executors that were previously unavailable in the cloud, like the shared-iterations
one. Now, you can execute something like k6 cloud --iterations 10000 --vus 100 script.js
without any issues.
Multiple execution scenarios can now be configured in a single test run via the new scenarios
option. These scenarios can run both sequentially and in parallel, and can independently execute different script functions, have different executor types and execution options, and have custom environment variables and metrics tags.
An example using 3 scenarios:
import http from 'k6/http';
import { sleep } from 'k6';
export let options = {
scenarios: {
my_web_test: { // some arbitrary scenario name
executor: 'constant-vus',
vus: 50,
duration: '5m',
gracefulStop: '0s', // do not wait for iterations to finish in the end
tags: { test_type: 'website' }, // extra tags for the metrics generated by this scenario
exec: 'webtest', // the function this scenario will execute
},
my_api_test_1: {
executor: 'constant-arrival-rate',
rate: 90, timeUnit: '1m', // 90 iterations per minute, i.e. 1.5 RPS
duration: '5m',
preAllocatedVUs: 10, // the size of the VU (i.e. worker) pool for this scenario
maxVUs: 10, // we don't want to allocate more VUs mid-test in this scenario
tags: { test_type: 'api' }, // different extra metric tags for this scenario
env: { MY_CROC_ID: '1' }, // and we can specify extra environment variables as well!
exec: 'apitest', // this scenario is executing different code than the one above!
},
my_api_test_2: {
executor: 'ramping-arrival-rate',
startTime: '30s', // the ramping API test starts a little later
startRate: 50, timeUnit: '1s', // we start at 50 iterations per second
stages: [
{ target: 200, duration: '30s' }, // go from 50 to 200 iters/s in the first 30 seconds
{ target: 200, duration: '3m30s' }, // hold at 200 iters/s for 3.5 minutes
{ target: 0, duration: '30s' }, // ramp down back to 0 iters/s over the last 30 second
],
preAllocatedVUs: 50, // how large the initial pool of VUs would be
maxVUs: 100, // if the preAllocatedVUs are not enough, we can initialize more
tags: { test_type: 'api' }, // different extra metric tags for this scenario
env: { MY_CROC_ID: '2' }, // same function, different environment variables
exec: 'apitest', // same function as the scenario above, but with different env vars
},
},
discardResponseBodies: true,
thresholds: {
// we can set different thresholds for the different scenarios because
// of the extra metric tags we set!
'http_req_duration{test_type:api}': ['p(95)<250', 'p(99)<350'],
'http_req_duration{test_type:website}': ['p(99)<500'],
// we can reference the scenario names as well
'http_req_duration{scenario:my_api_test_2}': ['p(99)<300'],
}
};
export function webtest() {
http.get('https://test.k6.io/contacts.php');
sleep(Math.random() * 2);
}
export function apitest() {
http.get(`https://test-api.k6.io/public/crocodiles/${__ENV.MY_CROC_ID}/`);
// no need for sleep() here, the iteration pacing will be controlled by the
// arrival-rate executors above!
}
As shown in the example above and the documentation, all executors have some additional options that improve their flexibility and facilitate code reuse, especially in multi-scenario test runs:
startTime
property, which defines at what time, relative to the beginning of the whole test run, the scenario will start being executed.gracefulStop
property that allows for iterations to complete gracefully for some amount of time after the normal executor duration is over (#879, #1033). The ramping-vus
executor additionally also has gracefulRampDown
, to give iterations time to finish when VUs are ramped down. The default value for both options is 30s
, so it's a slight breaking change, but the old behavior of immediately interrupting iterations can easily be restored by setting these options to 0s
.default
exported one. This can be specified by the exec
option in each scenarios
config, and allows for more flexibility in organizing your tests, easier code reuse, building test suites, etc.env
and tags
executor options respectively.dropped_iterations
metric in the shared-iterations
, per-vu-iterations
, constant-arrival-rate
and ramping-arrival-rate
executors; this is done if it can't run an iteration on time, depending on the configured rates (for the arrival-rate executors) or scenario maxDuration
(for the iteration-based executors), so it's generally a sign of a poor config or an overloaded system under test (#1529).We've also introduced new --execution-segment
and --execution-segment-sequence
options, which allow for relatively easy partitioning of test runs across multiple k6 instances. Initially this applies to the test execution (all new executor types are supported!), but opens the door to test data partitioning, an often requested feature. See #997 for more details.
__VU
variable is now available in the script init context, allowing easier splitting of test input data per VU and reducing RAM usage (#889).--http-debug
from exiting k6 on request dump error (#1402). Thanks @berndhartzer!iterations
with stages
(#812).stages
(#875).context cancelled
error when rapidly ramping up and down (#1283).Execution config options (scenarios
, stages
, iterations
, duration
) from "upper" config layers overwrite execution options from "lower" (i.e. CLI flags > environment variables > JS options > JSON options) config layers. For example, the --iterations
CLI flag will overwrite any execution options set as environment variables (e.g. K6_DURATION
, K6_STAGES
, etc.) or script options (stages: [ /* ... */]
, scenarios: { /* ... */ }
, etc. ).
Previously, if the iterations
and vus
script options were specified, but duration
was not, the script could have ran practically indefinitely, given a sufficiently large number or length of the used iterations. There was no implicit or explicit time limit, one of the reasons this execution pattern was not allowed in k6 cloud
test runs before. From k6 v0.27.0, by default, if the specified iterations haven't finished, these scripts will abort after 10 minutes, the default maxDuration
value of shared-iterations
executors. This default value can easily be changed by either setting the maxDuration
option in the corresponding scenarios
entry, or, if just the execution shortcuts were used to run the script, by setting the duration
/ --duration
/ K6_DURATION
script option.
Previously, all iterations were interruptible - as soon as the specified duration
expired, or when VUs were ramped down in a stage, any running iterations were interrupted. Now all executors besides the externally-controlled
one have a gracefulStop
period of 30s
by default (#898). Additionally, the ramping-vus
executor has a gracefulRampDown
parameter that configures the ramp-down grace period. For those periods, no new iterations will be started by the executors, but any currently running iterations will be allowed up to the specified periods to finish their execution.
Using different execution config options on the same level is now a configuration conflict error and will abort the script. For example, executing k6 run --duration 10s --stages 5s:20 script.js
won't work (#812). The only exception is combining duration
and iterations
, which will result in a shared-iterations
executor with the specified non-default maxDuration
(#1058).
The k6 REST API for controlling script execution (i.e. the k6 pause
, k6 scale
commands) now only works when a externally-controlled
executor is configured in the scenarios
config. The initial pausing of a test (i.e. k6 run --paused script.js
) still works with all executor types, but once the test is started with k6 resume
(or the corresponding REST API call), it can't be paused again unless only the externally-controlled
executor is used.
Previously, running a script with k6 run --paused script.js
would have still executed the script's setup()
function (if it was present and wasn't explicitly disabled with --no-setup
) and paused immediately after. Now, k6 will pause before it executes setup()
.
Previously, if you ramped down and ramped up VUs via stages
, the __VU
global variables would have been incremented on the ramp-ups. This will no longer happen, the max value of __VU
across a test run will never exceed the number of initialized VUs.
The vusMax
/ K6_VUS_MAX
/ -m
/ --max
option is deprecated - it was previously used for the control of the initialized VUs by the REST API. Since that has now been restricted to the externally-controlled
executor, the equivalent option there is called maxVUs
.
Tests with infinite duration are now only possible via the externally-controlled
executor.
k6 will now exit with an error if --address
is specified but the API server is unable to start. Previously this would've resulted in a warning message.
The format returned by Date.prototype.toUTCString()
was changed from Thu Jan 01 1970 00:00:00 GMT+0000 (UTC)
to Thu, 01 Jan 1970 00:00:00 GMT
. This is a fix that aligns it with the ECMAScript spec. See https://github.com/dop251/goja/issues/119 .
The default setupTimeout
and teardownTimeout
values were changed from 10s to 60s (#1356).
Published by imiric over 4 years ago
k6 v0.26.2 is a minor release that updates the used Go version for the Windows builds to Go 1.13.8. Due to an oversight, previous v0.26 k6 builds for Windows used an old Go version, while builds of other OSes used the correct one. This is meant to address an issue in the Go net/http package: https://github.com/golang/go/issues/34285 .
There are no functional changes compared to v0.26.1.
Published by na-- over 4 years ago
k6 v0.26.1 is here! This is a minor release that supports the rebranding of LoadImpact to k6, the new k6.io website, and the new k6 cloud service! π
In practical terms, all that it means for k6 is that the URLs for cloud tests will point to https://app.k6.io, instead of https://app.loadimpact.com. The old URLs (and old k6 versions) will still continue to work - for the next 3 months the old app and the new one would work in parallel, and after that period the old app will redirect to the new one. Nothing changes in regards to the k6 open source project and our commitment to it!
You can find more information about the rebranding in our blog post about it: https://k6.io/blog/load-impact-rebranding-to-k6
__ENV
between VUs, which could result in data races and crashes of k6. (#1329)Published by na-- almost 5 years ago
k6 v0.26.0 is here! π
This release contains mostly bug fixes, though it also has several new features and enhancements! They include a new JS compatibility mode option, exporting the end-of-test summary to a JSON report file, speedups to the InfluxDB and JSON outputs, http.batch()
improvements, a brand new CSV output, multiple layered HTTP response body decompression, being able to use console
in the init context, a new optional column in the summary, and Docker improvements!
Thanks to @Sirozha1337, @openmohan, @MMartyn, @KajdeMunter, @dmitrytokarev and @dimatock for contributing to this release!
This adds a way to disable the automatic script transformation by Babel (v6.4.2) and loading of core-js (v2) polyfills, bundled in k6. With the new base
compatibility mode, k6 will instead rely only on the goja runtime and what is built into k6.
This can be configured through the new --compatibility-mode
CLI flag and the K6_COMPATIBILITY_MODE
environment variable. The possible values currently are:
extended
: this is the default and current compatibility mode, which uses Babel and core.js to achieve ES6+ compatibility.base
: an optional mode that disables loading of Babel and core.js, running scripts with only goja's native ES5.1+ compatibility. If the test scripts don't require ES6 compatibility (e.g. they were previously transformed by Babel), this option can be used to reduce RAM usage during test runs.More info what this means can be found in the documentation.
Our benchmarks show a considerable drop in memory usage - around 80% for simple scripts, and around 50% in the case of 2MB script with a lot of static data in it. The CPU usage is mostly unchanged, except that k6 initializes test runs a lot faster. All of those benefits will be most noticeable if k6 is used with big number of VUs (1k+). More performance comparisons can be found in #1167.
This returns (from the very early days of k6) the ability to output the data from the end of test summary in a machine-readable JSON file.
This report can be enabled by the --summary-export <file_path>
CLI flag or the K6_SUMMARY_EXPORT
environment variable. The resulting JSON file will include data for all test metrics, checks and thresholds.
There is an entirely new csv
output that can be enabled by using the --out csv
CLI flag. There are two things that can be configured: the output file with K6_CSV_FILENAME
(by default it's file.csv
), and the interval of pushing metrics to disk, which is configured with K6_CSV_SAVE_INTERVAL
(1 second by default). Both of those can be configured by the CLI as well: --out csv=somefile.csv
will output to somefile.csv
and --out file_name=somefile.csv,save_interval=2s
will output again to somefile.csv
, but will flush the data every 2 seconds instead of every second.
The first line of the output is the names of columns and looks like:
metric_name,timestamp,metric_value,check,error,error_code,group,method,name,proto,status,subproto,tls_version,url,extra_tags
http_reqs,1573131887,1.000000,,,,,GET,http://httpbin.org/,HTTP/1.1,200,,,http://httpbin.org/,
http_req_duration,1573131887,116.774321,,,,,GET,http://httpbin.org/,HTTP/1.1,200,,,http://httpbin.org/,
http_req_blocked,1573131887,148.691247,,,,,GET,http://httpbin.org/,HTTP/1.1,200,,,http://httpbin.org/,
http_req_connecting,1573131887,112.593448,,,,,GET,http://httpbin.org/,HTTP/1.1,200,,,http://httpbin.org/,
All thanks to @Sirozha1337!
The JSON output no longer blocks the goroutine sending samples to the file, but instead (like all other outputs) buffers the samples and writes them at regular intervals (100ms and is currently not configurable). It also uses a slightly faster way of encoding the data, which should decrease the memory usage by a small amount.
Another improvement is the ability to compress the generated JSON file by simply adding .gz
to the end of the file name. Compressed files are typically 30x smaller.
The InfluxDB output has been updated to use less memory and try to send smaller and consistent chunks of data to InfluxDB, in order to not drop packets and be more efficient. This is primarily done by sending data in parallel, as this seems to be better from a performance perspective, and more importantly, queuing data in separate packets, so that we don't send the data for a big time period all at once. Also, the used library was updated, which also decreased the memory usage.
Two new options were added:
K6_INFLUXDB_PUSH_INTERVAL
- configures at what interval the collected data is queued to be sent to InfluxDB. By default this is "1s".K6_INFLUXDB_CONCURRENT_WRITES
- configures the number of concurrent write calls to InfluxDB. If this limit is reached the next writes will be queued and made when a slot is freed. By default this is 10.console
is now available in the init context (#982):This wasn't supported for the longest time, which made debugging things outside of VU code much harder, but now it's here! π
In order to get this feature shipped in a timely manner, it currently has a known bug. The output of console
calls in the init context will always be written to the stderr
, even if the --console-output
option is specified. This bug is tracked in https://github.com/loadimpact/k6/issues/1131
In v0.25.0 compressing bodies was added and it had support for multiple layered algorithms. Now this is also true for decompressing bodies when k6 gets them as responses.
count
column in the end-of-test summary (#1143)The --summary-trend-stats
now also recognizes count
as a valid column and will output the count of samples in all Trend
metrics. This could be especially useful for custom Trend
metrics, since with them you no longer need to specify a separate accompanying Counter
metric.
The example docker-compose that enabled easy running of InfluxDB+Grafana+k6 was refactored and all the images were updated to use the latest stable versions.
Thanks, @KajdeMunter!
Also the k6 Dockerfile
Alpine version was bumped to 3.10. Thanks @dmitrytokarev!
http.batch()
improvements and optimizations (#1259)We made several small improvements to the mechanism for executing multiple HTTP requests simultaneously from a single VU:
http.batch()
should now be more efficient, especially for many requests, because of reduced locking, type conversions, and goroutine spawning.batchPerHost
has been reduced from 0
(unlimited) to 6
, to more closely match browser behavior. The default value for the batch
option remains unchanged at 20
.http.batch(arg)
, where arg
is an array, would now return an array. Previously, this would have returned an object with integer keys, as explained in #767... Now http.batch()
will return an array when you pass it an array, and return an object when you pass an object.setup
and teardown
timeouts, including hints on how to fix them. (#1173)open()
, the resulting error message will now include the path to the specified folder. (#1238)k6 version
output will now include more information - the git commit it was built from (in most cases), as well as the used Go version and architecture. (#1235)check
if an uncaught error is thrown inside of it. (#1137)*
when emitting HTTP metrics. (#1132)error
handler on an error when closing the WebSocket, instead of calling with a null (#1118)GetBody
in order to be able to get the body multiple times for a single request as needed in 308 redirects of posts and if the server sends GOAWAY with no error. (#1093)minIterationDuration
for setup
and teardown
. (#1175)error_code
metric tag values. (#1164)K6_
prefixed environment variables as k6 configuration, most notably DURATION
and ITERATIONS
. (#1215)Selection.map
was not wrapping the nodes it was outputting, which lead to wrongly using the internal Goquery.Selection
instead of k6's Selection
. Thanks to @MMartyn for reporting this! (#1198)name
tag. (#1220)batchPerHost
of 20
wasn't propagated properly and was instead 0
. (#1264)httpbin.org
. (#1213)configdir
. (#1162)envconfig
as it was very old and the newer versions had fixes and features we want. (#1214)netext.NetTrail
, instead of as a standalone one. Also cutting down on amount of bytes we sent to the cloud output. (#1203)master
version (commit 007eef3
) (#1259)-trimpath
and CGO_ENABLED=0
. Previously the GitHub release assets were built with CGO_ENABLED=0
, making them unsuitable for non-glibc systems (like Alpine Linux). (#1244, #1245)The output of k6 version
is different. It now contains not only the k6 version number, but also information about the git commit, build date, Go version and system architecture. For example, if previously the output of k6 version
looked like k6 v0.25.1
, now it is like this: k6 v0.26.0 (2019-12-16T10:58:59+0000/v0.26.0-0-gaeec9a7f, go1.13.5, linux/amd64)
. (#1235)
We had to make a few minor breaking changes in the course of improving http.batch()
(#1259):
batchPerHost
has been reduced from 0
(unlimited) to 6
, to more closely match browser behavior. The default value for the batch
option remains unchanged at 20
.http.batch(arg)
, where arg
is an array, would now return an array. Previously, this would have returned an object with integer keys, as explained in #767... Now http.batch()
will return an array when you pass it an array, and return an object when you pass an object.Published by na-- about 5 years ago
A minor release that fixes some of the issues in the v0.25.0 release.
systemTags
JS/JSON option and the K6_SYSTEM_TAGS
environment variable. Thanks, @cuonglm! (#1092)digest
auth and --http-debug
code. (#1102)Content-Length
header for all requests. (#1106)import
/ require()
calls. (#1097)exports
corner cases. (#1099)Published by na-- about 5 years ago
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!
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)Published by na-- over 5 years ago
v0.24.0 is here! π
Another intermediary release that was mostly focused on refactoring and bugfixes, but also has quite a few new features, including the ability to output metrics to StatsD and Datadog!
Thanks to @cheesedosa, @ivoreis, @bookmoons, and @oboukili for contributing to this release!
console
messages to a file (#833)You can now specify a file to which all things logged by console.log()
and other console
methods will get written to. The CLI flag to specify the output file path is --console-output
, and you can also do it via the K6_CONSOLE_OUTPUT
environment variable. For security reasons, there's no way to configure this from inside of the script.
Thanks to @cheesedosa for both proposing and implementing this!
You can now output any metrics k6 collects to StatsD or Datadog by running k6 run --out statsd script.js
or k6 run --out datadog script.js
respectively. Both are very similar, but Datadog has a concept of metric tags, the key-value metadata pairs that will allow you to distinguish between requests for different URLs, response statuses, different groups, etc.
Some details:
localhost:8125
(currently only UDP is supported as a transport). You can change this address via the K6_DATADOG_ADDR
or K6_STATSD_ADDR
environment variables, by setting their values in the format of address:port
.namespace
- a prefix before all the metric names. You can set it via the K6_DATADOG_NAMESPACE
or K6_STATSD_NAMESPACE
environment variables respectively. Its default value is k6.
- notice the dot at the end.K6_STATSD_PUSH_INTERVAL
/ K6_DATADOG_PUSH_INTEVAL
environment variables. The default value is 1s
.K6_STATSD_BUFFER_SIZE
/ K6_DATADOG_BUFFER_SIZE
.K6_DATADOG_TAG_BLACKLIST
, which by default is equal to `` (nothing). This is a comma separated list of tags that should NOT be sent to Datadog. All other metric tags that k6 emits will be sent.Thanks to @ivoreis for their work on this!
This feature adds a method to return an array with a number of cryptographically random bytes. It will either return exactly the amount of bytes requested or will throw an exception if something went wrong.
import crypto from "k6/crypto";
export default function() {
var bytes = crypto.randomBytes(42);
}
Thanks to @bookmoons for their work on this!
binary
output encoding to the crypto functions (#952)Besides hex
and base64
, you can now also use binary
as the encoding parameter for the k6 crypto hashing and HMAC functions.
Error codes are unique numbers that can be used to identify and handle different application and network errors more easily. For the moment, these error codes are applicable only for errors that happen during HTTP requests, but they will be reused and extended to support other protocols in future k6 releases.
When an error occurs, its code is determined and returned as both the error_code
field of the http.Response
object, and also attached as the error_code
tag to any metrics associated with that request. Additionally, for more details, the error
metric tag and http.Response
field will still contain the actual string error message.
Error codes for different errors are as distinct as possible, but for easier handling and grouping, codes in different error categories are also grouped in broad ranges. The current error code ranges are:
For a list of all current error codes, see the docs page here.
js
packages and is now independent from the goja JS runtime. This was done mostly so we can implement the error codes feature (#907), but will allow us more flexibility in the future. (#928)execution
configuration framework. It currently doesn't do anything besides warn users that use execution option combinations that won't be supported in future k6 versions. See the Breaking Changes section in these release notes for more information. (#913)--quiet
/-q
doesn't hide the summary stats at the end of the test. When necessary, they can still be hidden via the explicit --no-summary
flag. Thanks, @oboukili! (#937)None in this release, but in preparation for the next one, some execution option combinations will emit warnings, since they will no longer be supported in future k6 releases. Specifically, you won't be able to simultaneously run k6 with stages
and duration
set, or with iterations
and stages
, or with duration
and iterations
, or with all three. These VU schedulers (and much more, including arrival-rate based ones!) will still be supported in future k6 releases. They will just be independent from each other, unlike their current implementation where there's one scheduler with 3 different conflicting constraints.
Published by na-- almost 6 years ago
A minor release that fixes some of the issues in the v0.23.0 release.
env.loadimpact
JS options. Now only the projectID
, name
and token
fields will be populated (without overriding other fields) when executing scripts with k6 cloud
, and taken into account when sending metrics to Load Impact Insights with k6 run -o cloud
. (#848, #871, #872)