k6

A modern load testing tool, using Go and JavaScript - https://k6.io

AGPL-3.0 License

Stars
23.3K
Committers
196

Bot releases are hidden (Show)

k6 - https://github.com/grafana/k6/releases/tag/v0.47.0

Published by mstoykov about 1 year ago

k6 v0.47.0 is here 🎉! This release includes:

Deprecations

  • #3347 The built-in statsd output option has been deprecated, and users should use the xk6-output-statsd extension instead. See #2982 for future plans.
  • #3288 Loading remote modules now requires users to prepend them with https://. Before, k6 would try to resolve importing remote modules by prepending https:// if it was missing. This behavior has been deprecated and will be fully removed in the next release (v0.48.0).

New features

Add gRPC's binary metadata support #3234, xk6-grpc#46

The k6 gRPC modules (k6/net/grpc and k6/experimental/grpc) now support handling binary metadata that uses the -bin postfix, according to the gRPC specification.

let resp = client.invoke("grpc.testing.TestService/EmptyCall", {}, { metadata: { "X-Load-Tester-bin": new Uint8Array([2, 200]) } })

Thanks to @sapphire-janrain for the contribution!

Add gRPC's reflection metadata support #3343, xk6-grpc#46

The k6 gRPC modules (k6/net/grpc and k6/experimental/grpc) now support adding metadata to reflection requests by using a new connection parameter reflectMetadata.

Higher precision for Trend metrics in Grafana Cloud k6 #3302

Grafana Cloud k6 is now able to store and visualize Trend metrics up to 3 digits of precision for decimal numbers.

Docker support for browser-based tests #3199

k6 is now publishig Docker images that include Chromium web browser. This allows k6 users to run tests that use Browser API without having to install Chrome first. Check the "A note on running browser tests" section of the Overview page on DockerHub for details.

Docker images for ARM64 architecture #3320

The k6's release process now builds and pushes dedicated Docker images for ARM64. Check k6's tags page on DockerHub for details.

New authentication methods and HTTP headers API for Prometheus remote write output xk6-output-prometheus-remote#143, xk6-output-prometheus-remote#145, xk6-output-prometheus-remote#147

The experimental Prometheus remote write output now supports two new authentication methods: Bearer token and TLS certificates. Check out the documentation to learn more about how to define them using the new environment variables.
We've also added the K6_PROMETHEUS_RW_HTTP_HEADERS that defines a new and more convenient way to set custom HTTP headers to pass through each flush metrics' request.

Improved the browser module's cookie API

The browser module now provides a more complete and robust API for handling cookies. The cookie API was stabilized by defining a new Cookie class (browser#1008, browser#1030) that can be used while creating and retrieving cookies. This enabled us to add a new browserContext.cookies([urls]) method (browser#1005) that returns all cookies from the current browser context. The new API also supports filtering cookies by URL (browser#1016).

That led to fixing a bug where the expires field was not being set correctly while adding cookies using the context.addCookie() method (browser#1031). Lastly, the existing context.clearCookies() method was fixed to clear all cookies from the current browser context (browser#1040).

const context = browser.newContext();
context.addCookies([
    {name: 'foo', value: 'bar', url: 'https://test.k6.io'},
    {name: 'baz', value: 'qux', url: 'https://grafana.com'},
]);

const cookies = context.cookies('https://test.k6.io');
console.log(cookies.length);         // 1
console.log(cookies[0].name);        // foo
console.log(cookies[0].value);       // bar

context.clearCookies();
console.log(context.cookies.length); // 0

Add support for browser module's page.on('console') browser#1006

Allows users to register a handler to be executed every time the console API methods are called from within the page's JavaScript context. The arguments passed into the handler are defined by the ConsoleMessage class.

page.on('console', msg => {
    check(msg, {
        'assertConsoleMessageType': msg => msg.type() == 'log',
        'assertConsoleMessageText': msg => msg.text() == 'this is a console.log message 42',
        'assertConsoleMessageArgs0': msg => msg.args()[0].jsonValue() == 'this is a console.log message',
        'assertConsoleMessageArgs1': msg => msg.args()[1].jsonValue() == 42,
    });
});

page.evaluate(() => console.log('this is a console.log message', 42));

UX improvements and enhancements

  • #3338, xk6-grpc#48 Adds support for the gRPC reflection protocol v1.
  • #3290 Adds error logging when executing setup and teardown via REST API. Thanks to @kmtym1998 for the contribution!
  • #3327 Adds commit identifier for the k6 build when running k6 version.
  • #3340 Updates k6 *-with-browser Docker images to automatically set the no-sandbox environment variable.
  • #3335 The character limit for metric names increased from 63 to 128 after the OpenTelemetry update. k6 will return an error starting on the next release (v0.48.0) if users hit the limit.
  • browser#1007 Adds a k6 object (window.k6 = {};) to help identify k6 browser module tests.
  • browser#1022 Refactors the check in examples/fillform.js so that it matches the type definitions and documentation for check.

Bug fixes

  • xk6-grpc#47 Fixes the premature closing of a gRPC stream when a stream's client has finished sending. Thanks to @thiagodpf for reporting!
  • #3344, xk6-grpc#49 Adds support for Google's protobuf wrappers. Thanks to @zibul444 for reporting!
  • #3308 Updates goja version, and fixes a compiler bug when a class is declared in a function with an argument.
  • browser#1039 Fixes goja conversions while adding and retrieving cookies.
  • browser#1038 Fixes read/write data race for edge case with remote browsers.
  • browser#1034 Fixes page.reload & page.setContent to use the default navigation timeout over the default timeout.
  • browser#1033 Fixes the page timeouts so it is actually used after being set.

Maintenance and internal improvements

  • #3342 Updates xk6-grpc to the latest version. This change brings all the latest fixes and improvements to the experimental gRPC module.
  • #3271,#3272 Updates the golangci version and adds the interfacebloat linter.
  • #3279 Fixes the CI not publishing the SBOM file on a new release.
  • #3283 Updates the Go version in k6's CI used to build the binaries.
  • #3341, #3339 Updates goja, includes runtime initialization speed-up and a fix for source indexes.
  • #3311 Updates the alpine image version that is used as the base of the k6 Docker image.
  • browser#1043, browser#1021, browser#1019, browser#1014 Fixes xk6-browser tests.
  • browser#1000, browser#1024 Refines xk6-browser issue and PR templates.
  • browser#1003, browser#1009, browser#1010 Internal changes to xk6-browser.
  • browser#997 Updates xk6-browser readme.
  • browser#962 CI fixes.
  • browser#1035 Refactors int64 timeout to time.Duration, to help avoid confusion as to whether a timeout is in milliseconds or seconds.

Roadmap

Native ECMAScript Modules support

Work on this epic issue has been picked up and there is some progress in the underlying implementation.

One of the main internal changes will be dropping Babel, which is currently used to transpile ESM code to CommonJS.

For users, it will mean better JavaScript support as this change will automatically get object spread working and likely faster startup for big scripts. In the future, this also means JavaScript compatibility will be easier to add, since it'll only need to be supported in the JavaScript VM we use - goja.

There's a risk that some k6 tests using both CommonJS and ECMAScript modules syntax will change in behavior. In practice, using both should never really be done as they're not compatible.

Because there are risks involved, we are going to do this very carefully and only once we have done a lot of tests. That means this is currently planned for v0.49.0, but with the majority of the remaining work done in the v0.48.0 cycle.

This way, we will also be able to have most of our users test these changes from our master branch, using Docker images, for example.

Future breaking changes

There are several changes in the next release that are entering the final stage of their deprecation period. That means the next release will include the following breaking changes:

  • #3065 Metric names will be limited to 128 characters and a set of allowed symbols. This was going to be changed to a 63 character limit to ensure compatibility with OpenTelemetry standards, but since then, the OTel limit has been updated to 255 characters. You can find more details about the changes in the linked issue.
  • #3365 The k6 converter command will be removed.
  • #3350 The headers param for the gRPC module will be removed. Users should use the metadata property instead.
  • #3287 Loading remote modules will require users to include the https:// protocol in their URLs, otherwise it will return an error.
  • CSV output no longer accepts arguments in snake case (for example, fileName should be used instead of file_name).
  • The --logformat flag for defining the Log format option will be removed. --log-format should be used instead.

We recommend checking this list to see if you are impacted, and updating your scripts or CI/CD processes to avoid any issues. If you have any feedback, please open an issue.

k6 - v0.28.0

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.

New features and enhancements!

Cloud execution logs (#1599)

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.

Pushing k6 logs to loki (#1576)

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.

Optional port to host mappings (#1489)

@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',
    },
};

Support for specifying data types to InfluxDB fields (#1395)

@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:

  • Use the environment variable 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.
  • Each pair of field name and its data type is represented in the format (name):(data_type), for example, event_processing_time:int.
  • One of four data types (int, float, bool and string) can be specified to one field name.
  • When the colon and a 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.

Support for automatic gzip-ing of the CSV output result (#1566)

@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

UX

  • Various spacing and progress bar rendering issues were improved (#1580).
  • The k6 ASCII logo was made a bit more proportional (#1615). Thanks, @rawtaz!
  • The docker-compose example setup from the k6 repo now contains a built-in simple dashboard (#1610). Thanks, @jeevananthank!
  • Some logs now have a source field specifying if a log comes from console, http-debug or stacktrace (when an exception has bubbled to the top of the iteration).

Bugs fixed!

  • Network: IPv6 support was fixed as a part of the new hosts port mapping (#1489). Thanks, @calavera!
  • Metrics: Fixed the wrong name metric tag for redirected requests (#1474).
  • UI: Fixed a divide by zero panic caused by some unusual execution environments that present a TTY, but return 0 for the terminal size (#1581).
  • Config: Fixed the parsing of K6_DATADOG_TAG_BLACKLIST (#1602).
  • Config: Fixed marshaling of tlsCipherSuites and tlsVersion (#1603). Thanks, @berndhartzer!
  • WebSockets: Fixed a ws.SetTimeout() and ws.SetInterval() panic when float values were passed (#1608).

Internals

  • goja, the JavaScript runtime k6 uses, was updated to the latest version. This means that k6 with --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).
  • Go modules are now used to manage the k6 dependencies instead of dep (#1584).

Breaking changes

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

k6 - v0.27.1

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.

Other minor fixes and changes:

  • The Go version that k6 is compiled with was updated to 1.14.6, to incorporate the latest Go fixes (#1563).
  • If the throw option is enabled, warnings for failed HTTP requests will no longer be logged to the console (#1199).
  • Metric sample packets sent to the cloud with 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).
  • The gracefulRampDown VU requirement calculations for the ramping-vus executor were greatly optimized for large test runs (#1567).
  • Fixed a rare bug where dropped_iterations wouldn't be emitted by the per-vu-iterations executor on time due to a race (#1357).
  • Metrics, including checks, from setup() and teardown(), were not correctly shown in local k6 runs (#949).
k6 - v0.27.0

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.

New features and enhancements!

New execution engine (#1007)

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.

New executors

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.

Execution scenarios and executor options

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:

  • Each executor has a startTime property, which defines at what time, relative to the beginning of the whole test run, the scenario will start being executed.
  • Executors have a new 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.
  • Different executors can execute different functions other than the 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.
  • To allow for even greater script flexibility and code reuse, you can specify different environment variables and tags in each scenario, via the new env and tags executor options respectively.
  • k6 may now emit a new 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.

UX

  • CLI: There are separate descriptions and real-time thread-safe progress bars for each individual executor.
  • CLI: Improve module import error message (#1439).
  • JS: The __VU variable is now available in the script init context, allowing easier splitting of test input data per VU and reducing RAM usage (#889).
  • A new method to stop engine execution via the REST API (#1352). Thanks @hynd!

Bugs fixed!

  • CLI: Stop --http-debug from exiting k6 on request dump error (#1402). Thanks @berndhartzer!
  • CLI: JSON output is now less noisy (#1469). Thanks @michiboo!
  • CLI: k6 doesn't exit when using iterations with stages (#812).
  • CLI: Mismatch in check counts in the end-of-test summary (#1033).
  • Config: Better validation of stages (#875).
  • JS: Rare panics in goja (#867,#1552).
  • HTTP: Fix request timeout and wrong context used for pushing metrics (#1260).
  • Execution: Fix sometimes skipping iterations with a context cancelled error when rapidly ramping up and down (#1283).
  • WebSockets: Fix possible connection hanging when the main context is cancelled (#1260).
  • WebSockets: Avoid leaking goroutines (#1513).
  • WebSockets: Emit WS metrics as soon as possible instead of when the connection is closed (#885).

Internals

  • As mentioned above, #1007 was almost a complete re-write of the execution scheduling parts of k6. This involved deep architectural changes in how test runs are executed and improved overall code coverage by around 2%.
  • Switched to Go 1.14 for building and testing k6, bringing some fixes and performance improvements.
  • WebSockets: Updated gorilla/websocket library bringing minor performance improvements (#1515).
  • Code cleanup and formatting. Thanks @thinkerou!

Breaking changes

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

k6 - v0.26.2

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.

k6 - 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

Changes in this release compared to v0.26.0:

  • Fix how HTTP request timeouts are specified internally. This is not a bug in current k6 releases, it only affects k6 if it is compiled with Go 1.14, which at this time is still not officially released. (#1261)
  • Improve the official docker image to use an unprivileged user. Thanks, @funkypenguin! (#1314)
  • Fix the unintentional sharing of __ENV between VUs, which could result in data races and crashes of k6. (#1329)
  • Update cloud URLs to point to https://app.k6.io instead of https://app.loadimpact.com. (#1335)
k6 - v0.26.0

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!

New features and enhancements!

A new JavaScript compatibility mode option (#1206)

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.

JSON export of the end-of-test summary report (#1168)

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.

New CSV output (#1067)

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!

JSON output optimizations (#1114)

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.

InfluxDB output improvements (#1113)

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

HTTP response body decompression with multiple layered algorithms (#1125)

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.

New optional 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.

Docker Compose refactor (#1183)

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:

  • Calling http.batch() should now be more efficient, especially for many requests, because of reduced locking, type conversions, and goroutine spawning.
  • The default value for 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.
  • Calling 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.

UX

  • Better timeout messages for setup and teardown timeouts, including hints on how to fix them. (#1173)
  • When a folder is passed to open(), the resulting error message will now include the path to the specified folder. (#1238)
  • The 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)

Bugs fixed!

  • Cloud: Stop sending metrics to the cloud output when the cloud returns that you have reached the limit. (#1130)
  • JS: Fail a check if an uncaught error is thrown inside of it. (#1137)
  • HTTP: Replace any user credentials in the metric sample tags with * when emitting HTTP metrics. (#1132)
  • WS: Many fixes:
    • return an error instead of panicking if an error occurs during the making of the WebSocket connection (#1127)
    • calling the error handler on an error when closing the WebSocket, instead of calling with a null (#1118)
    • correctly handle server initiated close (#1186)
  • JSON: Better error messages when parsing JSON fails. Now telling you at which line and row the error is instead of just the offset. Thanks, @openmohan! (#905)
  • HTTP: Use Request's 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)
  • JS: Don't export internal go struct fields of script options.(#1151)
  • JS: Ignore minIterationDuration for setup and teardown. (#1175)
  • HTTP: Return error on any request that returns 101 status code as k6 currently doesn't support any protocol upgrade behavior. (#1172)
  • HTTP: Correctly capture TCP reset by peer and broken pipe errors and give them the appropriate error_code metric tag values. (#1164)
  • Config: Don't interpret non-K6_ prefixed environment variables as k6 configuration, most notably DURATION and ITERATIONS. (#1215)
  • JS/html: 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)
  • HTTP: When there are redirects, k6 will now correctly set the cookie for the current URL, instead of for the one the current response is redirecting to. Thanks @dimatock! (#1201)
  • Cloud: Add token to make calls to the cloud API idempotent. (#1208)
  • Cloud: Improve aggregation of HTTP metrics for requests to different URLs, but with the same explicitly set name tag. (#1220)
  • Cloud: Fix a bug where you weren't able to run a script, outputting to cloud, if it was using the shortcut URLs for github/cdnjs. (#1237)
  • Config: The previous default value for batchPerHost of 20 wasn't propagated properly and was instead 0. (#1264)

Internals

  • CI: Stop using external service for testing WebSockets (#1138) and remove the last use of the external httpbin.org. (#1213)
  • Switched to Go 1.13.5 for building and testing k6, removed official support for 1.11.
  • CI: Fix a test on MacOS. (#1142)
  • CI: Fixing flaky tests. (#1149, #1223)
  • Drop an external dependency for getting user's configdir. (#1162)
  • Use bitmask for checking whether system tags are enabled, adding some small speedup where this is required. (#1148)
  • Update envconfig as it was very old and the newer versions had fixes and features we want. (#1214)
  • Metrics: Emit iterations as part of netext.NetTrail, instead of as a standalone one. Also cutting down on amount of bytes we sent to the cloud output. (#1203)
  • JS: goja has been updated to the latest master version (commit 007eef3) (#1259)
  • All official binary packages now are built with -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)

Breaking changes

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

    • The default value for 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.
    • Calling 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.
k6 - v0.25.1

Published by na-- about 5 years ago

A minor release that fixes some of the issues in the v0.25.0 release.

Bugs fixed!

  • Config: Properly handle the systemTags JS/JSON option and the K6_SYSTEM_TAGS environment variable. Thanks, @cuonglm! (#1092)
  • HTTP: Fix how request bodies are internally specified so we can properly handle redirects and can retry some HTTP/2 requests. (#1093)
  • HTTP: Fix the handling of response decoding errors and slightly improve the digest auth and --http-debug code. (#1102)
  • HTTP: Always set the correct Content-Length header for all requests. (#1106)
  • JS: Fix a panic when executing archive bundles for scripts with unsuccessfull import / require() calls. (#1097)
  • JS: Fix some issues related to the handling of exports corner cases. (#1099)
k6 - v0.25.0

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!

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)
k6 - v0.24.0

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!

New Features!

Redirect 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!

New result outputs: StatsD and Datadog (#915)

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:

  • By default both outputs send metrics to a local agent listening on 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.
  • The new outputs also support adding a 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.
  • You can configure how often data batches are sent via the K6_STATSD_PUSH_INTERVAL / K6_DATADOG_PUSH_INTEVAL environment variables. The default value is 1s.
  • Another performance tweak can be done by changing the default buffer size of 20 through K6_STATSD_BUFFER_SIZE / K6_DATADOG_BUFFER_SIZE.
  • In the case of Datadog, there is an additional configuration 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!

k6/crypto: random bytes method (#922)

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!

k6/crypto: add a 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.

New feature: unified error codes (#907)

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:

  • 1000-1099 - General errors
  • 1100-1199 - DNS errors
  • 1200-1299 - TCP errors
  • 1300-1399 - TLS errors
  • 1400-1499 - HTTP 4xx errors
  • 1500-1599 - HTTP 5xx errors
  • 1600-1699 - HTTP/2 specific errors

For a list of all current error codes, see the docs page here.

Internals

  • Improvements in the integration with loadimpact.com. (#910 and #934)
  • Most of the HTTP request code has been refactored out of the 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)
  • As a preparation for the upcoming big refactoring of how VUs are scheduled in k6, including the arrival-rate based execution, we've added the future 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)
  • Switched to golangci-lint via golangci.com for code linting in this repo. The gometalinter check in CircleCI is still enabled as well, but it will be removed in the following few weeks. (#943)
  • Switched to Go 1.12.1 for building and testing k6, removed official support for 1.10. (#944 and #966)

Bugs fixed!

  • JS: Consistently report setup/teardown timeouts as such and switch the error message to be more expressive. (#890)
  • JS: Correctly exit with non zero exit code when setup or teardown timeouts. (#892)
  • Thresholds: When outputting metrics to loadimpact.com, fix the incorrect reporting of threshold statuses at the end of the test. (#894)
  • UX: --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)

Breaking changes

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.

k6 - v0.23.1

Published by na-- almost 6 years ago

A minor release that fixes some of the issues in the v0.23.0 release.

Bugs fixed!

  • Cloud: Fixed the interaction between the environment variable and JSON-based configuration, and the Load Impact specific 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)
  • JS: Fixed a Babel transformation issue that caused closing brackets to sometimes be commented out. (#853)
  • JS: Fixed environment variable propagation when executing script bundles. (#853)
  • HAR converter: Fixed a panic due to a missing nil check. (#861)
  • Cloud: Limit the amount of samples that k6 sends in a single package to the ingest by splitting them up. (#860)
  • Metrics: Fix the incorrect tracing of some corner case HTTP requests that resulted in negative or hugely positive metric values. (#862)
k6 - v0.23.0

Published by na-- almost 6 years ago

v0.23.0 is here! 🎉

Hopefully this is the last intermediary release before v1.0.0. It is a bit light on new features, but it includes a lot of bug fixes and minor improvements! Also, the latest Docker tag will point to this release until we release the next stable one. Users wanting to use the bleeding edge k6 features can do that via the new master docker tag, which is pushed by every CI build of the git master branch.

Thanks to @sherrman, @ofauchon, @AndriiChuzhynov, @entone, @mariolopjr, and @tkbky for contributing to this release!

To see what's left for the v1.0.0 release, check out this milestone!

Also, have a look at our roadmap for what's up ahead, beyond the v1.0 release.

New Features!

New option: No Cookies Reset (#729)

A new option has been added that disables the default behavior of resetting the cookie jar after each VU iteration. If it's enabled, saved cookies will be persisted across VU iterations. For the moment there's no CLI flag for this option, instead it can only be set via the noCookiesReset key from the exported script options or via the K6_NO_COOKIES_RESET environment variable.

k6/http: New options to discard the response body or to specify its type (#742 and #749)

You can now specify what the type of an HTTP response's body should be with the new responseType request option. The possible values for it are text (the default), binary and none. The default text response type is backward-compatible, it doesn't change the current k6 behavior of returning the body attribute of the http/Response object as a string. It's well suited for working with web pages, text-based APIs and similar HTTP responses, but it can be unsuitable when dealing with binary files.

That's mostly because JavaScript strings are encoded with UTF-16 and converting binary data to it will frequently mangle some of the data. The new binary response type allows us to avoid that, it causes k6 to return the HTTP response's body as a byte array. This allows us to deal with the binary data without mangling it:

import http from 'k6/http';
import { sha256 } from 'k6/crypto';

export default function () {
    const expectedLogoHash = "fce7a09dde7c25b9822eca8438b7a5c397c2709e280e8e50f04d98bc8a66f4d9";

    let resp = http.get("http://test.loadimpact.com/images/logo.png", { responseType: "binary" });
    let logoHash = sha256(resp.body, "hex");
    if (logoHash !== expectedLogoHash) {
        throw new Error(`Expected logo hash to be ${expectedLogoHash} but it was ${logoHash}`);
    }
    http.post("https://httpbin.org/post", resp.body);
};

Saving HTTP response bodies is generally useful, especially when we need to use them (or parts of them) in subsequent requests. But in many cases it makes little to no sense to spend memory on saving the response body. For example, when requesting static website assets (JS, CSS, images etc.) or web pages without needed information, the actual file contents rarely matter when running load tests.

For cases like that, the value none for the responseType option allows k6 to discard incoming data on arrival, in order to save CPU cycles and prevent unnecessary copying of data. When enabled, the actual HTTP response body would be fully downloaded (so that the load test and all HTTP metrics for that request are still accurate), it just won't be saved in memory and passed on to the JavaScript runtime at all - the response.body attribute would be null:

import http from 'k6/http';
import { check } from "k6";

export default function () {
    const url = "http://test.loadimpact.com";
    let resp = http.get(url);
    let cssFile = resp.html().find("link[rel='stylesheet']").attr("href");

    check(http.get(`${url}/${cssFile}`, { responseType: "none" }), {
        "body was empty": (res) => res.body === null,
        "response code was 200": (res) => res.status == 200,
        "timings are present": (res) => res.timings.duration > 0,
    });
};

For convenience, there's also a new global config option that causes k6 to discard response bodies by default by switching the default responseType value to none. It can be enabled via the --discard-response-bodies CLI flag, the K6_DISCARD_RESPONSE_BODIES environment variable, or the discardResponseBodies script option:

import http from 'k6/http';
export let options = {
  discardResponseBodies: true,
};
export default function () {
  let response = http.get("http://test.loadimpact.com", { responseType: "text" });
  // ... do something with the response, but ignore the contents of static files:
  http.batch([
    "http://test.loadimpact.com/images/logo.png",
    "http://test.loadimpact.com/style.css"
  ]);
};

Thanks to @sherrman for reporting the binary handling issues that prompted the addition of the responseType option! And thanks to @ofauchon for implementing both of the discard response body options, of which the local per-request one was later transformed into the responseType=none value!

k6/http: The Response.json() method now supports selectors

The selectors are implemented with the gjson library and allow optimized lookups and basic filtering of JSON elements in HTTP responses, which could be especially useful in combination with k6 checks:

import http from "k6/http";
import { check } from "k6";

export default function () {
	let resp = http.get("https://api.spacexdata.com/v2/launches/");

	let currentYear = (new Date()).getFullYear();
	check(resp, {
		"falcon heavy": (r) => r.json("#[flight_number==55].rocket.second_stage.payloads.0.payload_id") === "Tesla Roadster",
		"no failure this year": (r) => r.json("#[launch_success==false]#.launch_year").every((y) => y < currentYear),
		"success ratio": (r) => r.json("#[launch_success==true]#").length > 10 * r.json("#[launch_success==false]#").length,
	});
}

Thanks to @AndriiChuzhynov for implementing this! (#766)

New option: disable the summary at the end of a test (#729)

A new option that disables the end-of-test summary has been added. That summary is often superfluous when k6 tests are run in a distributed execution mode, or when the generated metrics are piped to an external output like InfluxDB or Load Impact Insights. The option can be enabled with the --no-summary CLI flag or the K6_NO_SUMMARY environment variable. When both it and the and the --no-thresholds option are enabled, k6 won't store any generated metrics in-memory, making the test execution a bit more efficient.

New option: set a minimum iteration duration (#821)

You can now specify the minimum amount of time a single iteration should take via the new minIterationDuration option. It's also configurable via the --min-iteration-duration CLI flag and K6_MIN_ITERATION_DURATION environment variable. This setting only applies for full iterations, so any interrupted iterations due to ramping down of VUs from a stage or at the end of the tests can still be shorter.

UX

  • Added a warning when the maximum number of VUs is more than the total number of iterations (#802)

Internals

  • Cloud output: improved outlier metric detection for small batches. (#744)
  • Use 20 as the the default values of the batch and batchPerHost options. They determine the maximum number of parallel requests (in total and per-host respectively) an http.batch() call will make per VU. The previous value for batch was 10 and for batchPerHost it was 0 (unlimited). We now also use their values to determine the maximum number of open idle connections in a VU. (#685)
  • Due to refactoring needed for the redirect fixes, the NTLM authentication library k6 uses is changed from this to this. (#753)
  • Switched the default CircleCI tests and linting to use Go 1.11.2, but we still maintain 1.10 compatibility by running all of the tests with Go 1.10.3 too. Official k6 standalone builds will also be done with Go 1.11+ from now on. (#813)
  • Automated docker builds of the git master branch will now tag the resulting docker image as master as well. The latest docker tag will point to the latest stable official release, so it will be equivalent to v0.23.0 until we release the next k6 version. (#846)

Bugs fixed!

  • UI: The interactive k6 login influxdb command failed to write the supplied options to the config file. (#734)
  • UI: Password input is now masked in k6 login influxdb and k6 login cloud. (#734)
  • Config: Environment variables can now be used to modify k6's behavior in the k6 login subcommands. (#734)
  • HTTP: Binary response bodies were mangled because there was no way to avoid converting them to UTF-16 JavaScript strings. (#749)
  • Config: Stages were appended instead of overwritten from upper config "tiers", and were doubled when supplied via the CLI flag. (#759)
  • HAR converter: Fixed a panic due to a missing array length check. (#760)
  • HTTP: http.batch() calls could panic because of a data race when the batchPerHost global option was used. (#770)
  • Docker: Fixed the grafana image in the docker-compose setup. Thanks @entone and @mariolopjr! (#783)
  • Config: Stages configured via the script options or environment variables couldn't be disabled via the CLI flags. (#786)
  • UI: Don't report infinities and extreme speeds when tests take 0 time. Thanks @tkbky! (#790)
  • HTTP: Correct metric tracking when HTTP requests are redirected. (#753)
  • HAR converter: Added escaping for page IDs and names in the generated scripts. (#801)
  • Setup data: Distinguish between undefined (when there is no setup() function or when it doesn't return anything) and null (when setup() explicitly returns null) values for the setup data that's passed to the default function and teardown(). (#799)
  • Setup data: Prevent data races by having each VU have its own independent copy of the setup data. (#799)
  • HAR converter: Support HAR files that don't have a pages array. (#806)
  • Setup data: The property names of some of the internal k6 objects like http.Response weren't properly encoded when they were returned from the setup() function. (#804)
  • UX: Instead of panicking on some operations in the init context, we now return an error that the given action is not supported; this includes making HTTP requests (batched or not), websockets, adding to custom metrics, making checks and groups, or initializing cookie jars. (#811)
  • Cloud execution: properly send specific environment variables to the cloud option validation endpoint when running k6 cloud. Most notably this includes K6_CLOUD_PROJECT_ID. (#829)
  • Cloud execution and archive running: Fixed an issue when files were imported or opened with their full paths and they were in the users' home folders. (#823)
  • Script: Fixed a panic when group() is called without a callback function. (#841)

Breaking changes

  • Metric names are now restricted to only allow Unicode letters or numbers, spaces, and the following special characters: ._!?/&#()<>%-. They also need to be between 1 and 128 characters. Previously practically anything was a valid metric name. (#810)
k6 - v0.22.1

Published by na-- about 6 years ago

A minor release that adds some UX improvements and fixes some of the issues in the v0.22.0 release.

UX

  • The consolidated user-supplied options (the final combination of config file options, exported script options, environment variables and command-line flags) are now exported back into the options script variable and can be accessed from the script. Thanks to @mohanprasaths for working on this! (#681 and #713)
  • Improved error messages when outputting results to or executing tests in the Load Impact cloud (#716)

Bugs fixed!

  • Logging: using the --no-color flag caused k6 to print output intended for sdtout to stderr instead. (#712)
  • Logging: some error messages originating from Go's standard library did not obey the --logformat option. (#712)
  • JSON output: when the standard output was used, the JSON collector closed it before k6 was finished printing the end-of-test summary to it (#715)
  • Metrics: some zero-filled metrics were emitted when scaling down the number of VUs (#710)
k6 - v0.22.0

Published by robingustafsson over 6 years ago

v0.22.0 is here! 🎉

We're making an intermediary release before v1.0.0, as we wanted to get some changes out quicker. Thanks to @mohanprasaths for contributing to this release!

To see what's left for the v1.0.0 release, check out this milestone!

Also, have a look at our roadmap for what's up ahead, beyond the v1.0 release.

New Features!

  • New JS API to set seed for PRNG. Now, you are able to set a seed to get reproducible (pseudo-)random numbers. (#677)
import {randomSeed} from "k6";

randomSeed(123456789);
let rnd = Math.random();
console.log(rnd)
  • A new option --no-vu-connection-reuse lets users close HTTP keep-alive connections between iterations of a VU. (#676)
  • You can now set the minimum and maximum sleep time at the end of an iteration with the new --min-sleep and --max-sleep HAR coverter CLI flags. (#694)
  • Another new feature in the HAR converter enabled users to specify a JSON file with script options that would be added to the options of the generated scripts with the new --options flag. (#694)

UX

Automated deb, rpm, msi and nuget package builds (#675)

Previously we only had Homebrew releases for Mac and simple archives with plain binary releases for all other platforms. From now on, we'll also automatically build installation packages for Windows and rpm or deb based Linux distributions and upload them to bintray on every new release: https://bintray.com/loadimpact

For Debian-based Linux distributions, you have to do something like this to install k6:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 379CE192D401AB61
echo "deb https://dl.bintray.com/loadimpact/deb stable main" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install k6

And for rpm-based ones like Fedora and CentOS:

wget https://bintray.com/loadimpact/rpm/rpm -O bintray-loadimpact-rpm.repo
sudo mv bintray-loadimpact-rpm.repo /etc/yum.repos.d/
sudo yum install k6

For Windows you can download and install the latest .msi package or, if you use the chocolatey package manager, follow these instructions to set up the k6 repository.

Other UX improvements

  • There's a new option to reset the saved cloud token: k6 login cloud --reset (#672)
  • The check and group names in the summary at the end of a test now appear in the order they were defined. Thanks to @mohanprasaths for fixing this! (#674)

Internals

Real-time metrics (#678)

Previously most metrics were emitted only when a script iteration ended. With these changes, metrics would be continuously pushed in real-time, even in the middle of a script iteration. This should slightly decrease memory usage and help a lot with the aggregation efficiency of the cloud collector.

Portable builds (#658)

Before this, k6 builds that were done with just the standard Go language tools (i.e. go get, go build, etc.) were not portable because static resources like JS libraries had to be embedded in the binary after the build. Building fully portable binaries was done with the build-release.sh script (which used go.rice to bundle the static resources in the binary), but now that embedding is done beforehand and is commited in the git repo, so commands like go get/build/install produce fully-portable binary files without extra steps.

Bugs fixed!

  • Metrics emitted by setup() and teardown() are not discarded anymore. They are emitted and have the implicit root group tag values of setup and teardown respectively (#678)
  • Fixed a potential nil pointer error when the k6 cloud command is interrupted. (#682)

Breaking Changes

  • The --no-connection-reuse option has been re-purposed and now disables keep-alive connections globally. The newly added --no-vu-connection-reuse option does what was previously done by --no-connection-reuse - it closes any open connections between iterations of a VU, but allows for reusing them inside of a single iteration. (#676)
k6 - v0.21.1

Published by robingustafsson over 6 years ago

A bug fix release to fix some issues in the v0.21.0 release.

Bugs fixed!

  • Multiple bugs in the HTTP request and batch handling (#642)
  • Fix negative http_req_sending values in the summary (#651)
  • Respect the setup() and teardown() timeouts even when triggered by the API (#661)
k6 - v0.21.0

Published by robingustafsson over 6 years ago

v0.21.0 is here! 🎉

We're happy to see continued contributions from members of the community in this release, from 4 people outside of Load Impact this time around. A big thanks to the following people for contributing to this release: @antekresic, @cyberw, @danron and @jmccann. Also, thanks to everyone that contributed in other ways on Github, in Slack and for spreading the word about k6!

To see the current plan for the next release, check out this milestone, which we aim to make the v1.0 release!

Have a look at our roadmap for what's up ahead, beyond the v1.0 release.

New Features!

CLI/Options: Add --tag flag and tags option to set test-wide tags (#553)

You can now specify any number of tags on the command line using the --tag NAME=VALUE flag. You can also use the tags option to the set tags in the code.

The specified tags will be applied across all metrics. However if you have set a tag with the same name on a request, check or custom metric in the code that tag value will have precedence.

Thanks to @antekresic for their work on this!

Docs: Test wide tags and Options

CLI/Options: Add --summary-time-unit flag (#638)

You can now specify the time unit used to show the summary trend stats. It can be: 's' for seconds, 'ms' for milliseconds or 'us' microseconds.

$ k6 run --summary-time-unit ms ~/script.js

Docs: Options

k6/http: Support for HTTP NTLM Authentication (#556)

import http from "k6/http";
import { check } from "k6";

export default function() {
    // Passing username and password as part of URL plus the auth option will authenticate using HTTP Digest authentication
    let res = http.get("http://user:[email protected]/path", {auth: "ntlm"});

    // Verify response
    check(res, {
        "status is 200": (r) => r.status === 200
    });
}

Docs: HTTP Params

HAR converter: Add support for correlating JSON values (#516)

There is now support for correlating JSON values in recordings, replacing recorded request values with references to the previous response.

Thanks to @cyberw for their work on this!

InfluxDB output: Add support for sending certain sample tags as fields (#585)

Since InfluxDB indexes tags, highly variable information like vu, iter or even url may lead to high memory usage. The InfluxDB documentation recommends to use fields in that case, which is what k6 does now. There is a new INFLUXDB_TAGS_AS_FIELDS option (collectors.influxdb.tagsAsFields in the global k6 JSON config) that specifies which of the tags k6 emits will be sent as fields to InfluxDB. By default that's only url (but not name), vu and iter (if enabled).

Thanks to @danron for their work on this!

Configurable setup and teardown timeouts (#602)

Previously the setup() and teardown() functions timed out after 10 seconds. Now that period is configurable via the setupTimeout and teardownTimeout script options or the K6_SETUP_TIMEOUT and K6_TEARDOWN_TIMEOUT environment variables. The default timeouts are still 10 seconds and at this time there are no CLI options for changing them to avoid clutter.

In-client aggregation for metrics streamed to the cloud (#600)

Metrics streamed to the Load Impact cloud can be partially aggregated to reduce bandwidth usage and processing times. Outlier metrics are automatically detected and excluded from that aggregation.

Docs: Load Impact Insights Aggregation

HAR converter: Set more realistic sleep time (#608)

The default sleep time added at the end of the generated test has been changed from 2-4s to 20-40s to be more realistic (although still probably on the low end for some types of sites [1][2]).

[1] - https://moz.com/blog/ecommerce-benchmark-kpi-study-2017
[2] - https://www.brafton.com/blog/strategy/brafton-2017-content-marketing-benchmark-report/

Remote IP address as an optional system metric tag (#616)

It's now possible to add the remote server's IP address to the tags for HTTP and WebSocket metrics. The ip system tag is not included by default, but it could easily be enabled by modifying the systemTags option.

Raw log format (#634)

There is a new log format called raw. When used, it will print only the log message without adding any debug information like, date or the log level. It should be useful for debuging scripts when printing a HTML response for example.

$ k6 run --log-format raw ~/script.js

Option to output metrics to Apache Kafka (#617)

There is now support for outputing metrics to Apache Kafka! You can configure a Kafka broker (or multiple ones), topic and message format directly from the command line like this:

k6 --out kafka=brokers={broker1,broker2},topic=k6,format=json

The default format is json, but you can also use the InfluxDB line protocol for direct ingestion by InfluxDB:

k6 --out kafka=brokers=my_broker_host,topic=k6metrics,format=influxdb

You can even specify format options such as the tagsAsFields option for InfluxDB:

k6 --out kafka=brokers=someBroker,topic=someTopic,format=influxdb,influxdb.tagsAsFields={url,name,myCustomTag}

Docs: Apache Kafka output

Thanks to @jmccann for their work on this!

Multiple outputs (#624)

It's now possible to simultaneously send the emitted metrics to several outputs by using the CLI --out flag multiple times, for example:
k6 run --out json=test.json --out influxdb=http://localhost:8086/k6

Thanks to @jmccann for their work on this!

Cloud execution: CLI flag to exit k6 when test reaches running state (#632)

There's now a new CLI flag --exit-on-running when running cloud tests (k6 cloud ...) to have k6 exit when the test reaches the running state.

UX

  • Clearer error message when using open function outside init context (#563)
  • Better error message when a script or module can't be found (#565). Thanks to @antekresic for their work on this!

Internals

  • Removed all httpbin.org usage in tests, now a local transient HTTP server is used instead (#555). Thanks to @mccutchen for the great go-httpbin library!
  • Fixed various data races and enabled automated testing with -race (#564)

Bugs

  • Archive: archives generated on Windows can now run on *nix and vice versa. (#566)
  • Submetrics are being tagged properly now. (#609)
  • HTML: fixed the Selection.each(fn) function, which was returning only the first element. (#610)
  • Invalid Stages option won't keep k6 running indefinitely. (#615)
  • the --no-color option is now being repected for the logs. (#634)

Breaking changes

  • The Load Impact cloud configuration options no_compress and project_id and the payload_size InfluxDB option have been renamed to noCompress, projectID and payloadSize respectively, to match the other JS option names.
k6 - v0.20.0

Published by robingustafsson over 6 years ago

Lots of goodies in this release! 🎉

We are working towards a 1.0 release of k6, and as part of this release we've also published our roadmap for 2018 in the Github wiki, here it is. We welcome comments and discussion relating to the roadmap, both in the corresponding issues as well as in Slack.

Once again we saw contributions from several members of the community in this release, from 9 people outside of Load Impact, woop woop! A big thanks to the following people for contributing to this release: @antekresic, @cstyan, @cyberw, @danron, @dstpierre, @luizbafilho, @marklagendijk, @na-- and @pkruhlei.

Two of the above contributors have also become full time employees of Load Impact since the last release, to accelerate the development of k6. We welcome @luizbafilho and @na-- to the distributed k6 core team!

To see the current plan for the next release, check out this milestone.

New Features!

k6/http: Support for binary files and multipart requests (#370, #420 and #524)

The init context open() function now supports binary files:

import http from "k6/http";
import {md5} from "k6/crypto";

let binFile = open("./image.png", "b");

export default function() {
    console.log(md5(binFile, "hex"));
}

and the HTTP module has handily gained support for multipart requests:

import http from "k6/http";

let binFile = open("./image.png", "b");

export default function() {
    var data = {
        field: "this is a standard form field",
        file: http.file(binFile, "my image file.png")
    };
    var res = http.post("https://example.com/upload", data);
}

Thanks @dstpierre for their work on this!

Docs: Multipart requests

k6/http: Request information through response object (#447)

Request information is now exposed through the Response object:

import http from "k6/http";

export default function() {
    let res = http.get("https://example.com/")
    console.log(`Method: ${res.request.method}`);
    new Map(Object.entries(res.request.headers)).forEach((v, k) => console.log(`Header: ${k}=${v}`));
    console.log(`Body: ${res.request.method}`);
}

Thanks to @cstyan for their work on this!

Docs: Request information

Lifecycle: setup/teardown functions (#457)

Finally k6 has the same basic test lifecycle hooks as many "normal" testing tools, setup and teardown, and you have the full JS API of k6 available within these functions which means you can make HTTP calls etc. that you can’t do in the global/init scope.

To use the lifecycle hooks you simply define an exported setup() and/or teardown() function in your script:

export function setup() {
	return { “data”: “passed to main and teardown function” };
}

export function teardown(data)  {
	console.log(JSON.stringify(data));
}

export default function(data) {
if (data.v != 1) {
		throw new Error("incorrect data: " + JSON.stringify(data));
	}
}

Docs: Test life cycle

CLI: HTTP debug flag (#447)

If you specify --http-debug when running a test k6 will now continuously print request and response information.

Thanks to @marklagendijk for their work on this!

Docs: HTTP debugging

Options: DNS override (#494)

Overriding DNS resolution of hostnames can come in handy when testing a system that is run in multiple environments (dev, staging, prod etc.) with different IP addresses but responds to the same Host header.

import http from "k6/http";

export let options = {
    hosts: {
        "loadimpact.com": "1.2.3.4",
        "test.loadimpact.com": "5.6.7.8"
    }
};

export default function() {
    http.get("http://loadimpact.com/");
    http.get("http://test.loadimpact.com/");
}

Tip: you can use environment variables to switch the IP based on environment.

Thanks @luizbafilho for their work on this!

Docs: DNS Override option

CLI: Add -e flag environment variable flag (#495)

You can now specify any number of environment variables on the command line using the -e NAME=VALUE flag.

As a matter of security, when running k6 cloud ... or k6 archive ... the system's environment variables will not be included in the resulting archive, you'll now have to use the new --include-system-env-vars flag to get that behavior. When executing k6 run ... the system's environment will continue to be exposed to your script.

We encourage the use of -e NAME=VALUE to make environment variable use explicit and compatible across local and cloud execution.

Thanks @na-- for their work on this!

Docs: Environment variables

HAR converter: Add --no-batch flag (#497)

A --no-batch CLI flag has been added to k6 convert command to disable the creation of batch request statements in favor of individual http.get/del/options/patch/post/put statements.

Thanks @danron and @cyberw for their work on this!

HAR converter: Add --return-on-failed-check flag (#499)

A --return-on-failed-check CLI flag has been added to k6 convert command to optionally return/exit the current VU iteration if a response status code check fails (requires the existing --enable-status-code-checks to be specified as well).

Thanks @cyberw for their work on this!

HAR converter: Add --correlate flag (#500)

A first step towards doing correlations when converting HAR to JS has implemented. In this first iteration, if --correlate is specified the converter will try to detect issues with redirects.

Thanks @cyberw for their work on this!

Stats: Use linear interpolation when calculating percentiles (#498)

The percentile calculation has been changed to use linear interpolation of two bounding values if percentile doesn't precisely fall on a value/sample index.

Thresholds: Support for aborting test early as soon as threshold is hit (#508)

Up until now thresholds were evaluated continuously throughout the test but could never abort a running test.
This PR adds functionality to specify that a test run should abort the test as soon as a threshold evaluates to false, optionally with a delay in threshold evaluation to avoid aborting to early when the number of samples collected is low.

export let options = {
    thresholds: {
        "http_req_duration": ["avg<100", { threshold: "p(95)<200", abortOnFail: true, delayAbortEval: "30s" }]
    }
};

Thanks @antekresic for their work on this!

Docs: Thresholds with abort

Docker: Use full Alpine as base image for k6 (#514)

Thanks @pkruhlei for their contribution!

CLI: Option to whitelist what tags should be added to metric samples (#525)

Adds a CLI option --system-tags "url,method,status" to specify a whitelist of system tags that will be included in the metrics output.

The following tags can be specified:

  • url (http, websocket)
  • method (http)
  • status (http, websocket)
  • proto (http)
  • subproto (websocket)
  • error (http)
  • name (http)
  • group (http)
  • check (http)
  • tls_version (http)
  • ocsp_status (http)
  • iter (vu)
  • vu (vu)

All but the last 3 (ocsp_status, iter, vu) are included by default. Some collectors (e.g. cloud) could require that certain tags are included.

Docs: System tags

k6/http: Support for HTTP Digest Authentication (#533)

import http from "k6/http";
import { check } from "k6";

export default function() {
    // Passing username and password as part of URL plus the auth option will authenticate using HTTP Digest authentication
    let res = http.get("http://user:[email protected]/digest-auth/auth/user/passwd", {auth: "digest"});

    // Verify response
    check(res, {
        "status is 200": (r) => r.status === 200,
        "is authenticated": (r) => r.json().authenticated === true,
        "is correct user": (r) => r.json().user === "user"
    });
}

Docs: HTTP Params

Bugs fixed!

  • HAR converter: Fixed issue with construction of body parameter when PostData.Params values are present. (#489)

  • Stats: Fixed output of rate metrics to truncate rather than round when converting to string representation from float for summary output.

  • Stats: Fixes issue where calls to TrendSink.P() and TrendSink.Format() could return wrong results if TrendSink.Calc() hadn't been previously called. (#498)

  • Cloud/Insights: Fixed issue causing default test name to be empty when parsing script from STDIN (#510)

  • Cloud/Insights: Fixed handling of unexpected responses from server. (#522)

  • Stats: Fixed issue with calculation of data_received and data_sent metrics. (#523)

  • WebSockets: Fixed issue that different TLS settings like InsecureSkipTLSVerify were ignored for websockets (#531)

Breaking changes

  • The SummaryTrendStats configuration option has been renamed to summaryTrendStats, to match all of the other JS option names.
k6 - v0.19.0

Published by robingustafsson over 6 years ago

The first release of 2018! 🎉

We have contributions from 10 people outside of Load Impact in this release, yay! To celebrate that and make onboarding of new users and contributors easier we’ve improved the README to give a better overview of the project and the Contributing guide with better instructions how to get a k6 dev environment set up.

A big thanks to the following people for contributing to this release: @antekresic, @borjacampina, @cstyan, @dstpierre, @ivoreis, @jonathon-l, @marklagendijk, @Ripolin, @tbroadley, and @tmcgannon

New Features!

HAR to JS converter (#291, #453)

k6 now has a builtin command k6 convert recording.har > recording.js to convert HAR files to JS. This is great for being able to quickly go from a browser/proxy recording to a k6 script, a common flow for getting started with a new test case.

Thanks to @borjacampina for their work on this!

Docs: HAR converter

CLI/options: RPS limiter

A global request per second limiter has been added to k6. It will trigger if the RPS level goes above the set value, blocking further requests for a short period to maintain the desired level.

export let options = {
    rps: 100
};

Or --rps on the CLI.

CLI: Logging in JSON format (#434)

You can now output logs in JSON format! It looks something like this:
{"level":"debug","msg":"Engine terminated cleanly","time":"2017-12-20T12:30:35Z"}

Thanks to @ivoreis for this PR!

k6/http: Automatic decompression of deflate encoded response bodies (#419)

Adds handling of deflate (as specified in RFC 1950) encoded response bodies by automatically decompressing them.

k6/http: Automatic decompression of gzip encoded response bodies (#438)

Same as the one above but for gzip. k6 previously automatically handled gzip compressed bodies as long as no Accept-Encoding header was explicitly specified when making a request, but this adds transparent decompression as long as the Content-Encoding header in a response is set to gzip.

Thanks to @Ripolin for discovering the discrepancy in the handling of gzipped responses and for fixing it!

k6/http: TLS handshaking metric (#454)

k6 will now measure TLS handshaking time. The metric is called http_req_tls_handshaking and is accessible in scripts as res.timings.tls_handshaking.

Thanks to @antekresic for this PR!

k6/html: Form serialization methods (#435)

This feature adds some missing jQuery APIs for serializing form elements to a URL-encoded string, array or object.

import http from "k6/http";

export default function() {
    let res = http.get(“https://example.com/form”);
    let form = res.html().find('form');
    const serialized = form.serializeObject();
}

Thanks to @marklagendijk for their work on this!

Docs: serialize(), serializeArray() and serializeObject()

k6/http: Form submission method (#437, #445)

A sister feature to the one above, adding a submitForm(...) method to the response object for making it easier to work with HTML form submissions.

import http from "k6/http";

export default function() {
    let res = http.get(“https://example.com/form”);
    res = res.submitForm({ fields: { message: "hello world" });
}

Again, thanks to @marklagendijk for their work on this!

Docs: Response.submitForm() and Working with HTML forms

k6/http: Add back OPTIONS method (#451)

Up until v0.13.0 k6 supported CONNECT, OPTIONS and TRACE methods, besides the more common HTTP methods. In v0.13.0 these methods were then lost in a big refactor where we switched JS engine from Otto to goja.

Thanks to @cstyan for this PR!

k6/http: Link click method (#459)

A wrapper around the Selection API to locate an link/anchor tag in the response HTML and generate a click request. It adds a clickLink(...) method to the response object.

import http from "k6/http";

export default function() {
    let res = http.get("https://httpbin.org/links/10/0");
    res = res.clickLink({ selector: 'a:nth-child(4)' })
}

Yet again, thanks to @marklagendijk for their work on this!

Docs: Response.clickLink()

Metrics: iteration_duration metric, vu and iter tags (#460)

A new metric, iteration_duration, has been added to k6. It measures the time it takes to run one full iteration of the default/main function. Most builtin metrics (http, group, checks etc.) are now also automatically tagged with vu and iter tags, representing the VU and iteration number where the metric data point was collected.

CLI: Specify what stats to report for trend metrics (#462)

A new CLI option --summary-trend-stats avg,med,max,p(95),p(99),p(99.9) for specifying what stats to show for trend metrics (response times) in the summary output after a test run has finished.

Thanks @antekresic for this contribution!

k6/http: Set default user-agent (#466)

By default k6 will now send a user-agent string in the following format: k6/0.19.0 (https://k6.io/);.

Bugs fixed!

  • k6/http: The val() Selection method now properly returns an empty string for input fields when the value attribute is missing. (#435, thanks @marklagendijk)

  • k6/http: Fixed three bugs related to cookie handling when doing redirects. (#479, thanks @marklagendijk)

  • Archive: Fixed JSON encoding of <, > and & characters. (#421, thanks @dstpierre)

  • Engine: Improved stability of some tests to decrease flakiness of CI builds.

  • Stats: Fixed median calculation when sample count is even (#432, thanks @tmcgannon)

  • Docs: Fixed typo in README (#433, thanks @tbroadley)

  • Docs: Fixed broken link in README (#482, thanks @jonathon-l)

k6 - v0.18.2

Published by liclac almost 7 years ago

Features:

  • k6/http: Limit concurrent requests in http.batch() calls. (#296)

    export let options = {
      batch: 20, // Default: 10
    }
    
  • Flag to blacklist certain IP ranges from being called from scripts. (#389)

  • Flag to disable running of thresholds. (#42)

  • Archives now contain original sources, not transpiled gibberish. (#387)

  • k6/http: Enabled TLS Renegotiation

Fixed:

  • Broken colouring on Windows (#398)
  • Incorrect progress bars when using stages (#347)
  • Unhelpful errors from -o cloud
  • Tests with -o cloud failing when sources were read from stdin (#375)
k6 - v0.18.0

Published by liclac almost 7 years ago

This release was quite some time in the making, and for good reason - we changed a ton of stuff under the hood, merged a bunch of big features, and we had to make sure it was all stable before releasing it out into the wild.

Note! This version removes the web UI, which has been unmaintained and deprecated for several releases. If you're interested in maintaining a web UI, please contact us and we can work something out. (#300)

Note! Due to some significant changes in how we store disk configuration, if you previously used k6 login to store credentials for influxdb, you will need to do so again after updating to v0.18.0.

New Features!

k6/html: full jQuery API compatibility!! (#197)

This is a huge feature and incredibly exciting to us - res.html() now returns an object that supports the full jQuery API!

check(http.get("http://example.com/"), {
    "status is 200": (r) => r.status === 200,
    "caption is correct": (r) => r.html("h1").text() == "Example Domain",
})

Well, we say the full, but there are actually two exceptions: stuff like height() and width() that only makes sense if you're actually rendering the page in a browser, and anything that modifies the document (data("key", "value")), which doesn't make any sense in the context of a load testing tool.

If you'd like to see these two added, show us a use case and we'll see what we can do!

It's worth noting that this isn't just a huge feature, it's the single biggest pull request I have ever seen, adding over 5000 lines of code (many of which are code generated!). For scale, the entire k6 codebase (before this PR) was around 20,000 lines.

Huge thanks to @mitnuh for their tireless work on this!

Complete rework of the CLI! (#110)

This is a huge change and the biggest culprit for this delay - because the CLI is so important, and because of the sheer size of this change, we couldn't just ship it off until we were absolutely sure it worked.

Not only is the new CLI code substantially easier to work with for us - we don't have to get all antsy about adding any CLI-facing features out of fear we may break something:

  • Help pages (k6 --help) are now more helpful, complete with usage examples.
  • There's no more weirdness with certain flags having to be in certain positions (eg. k6 run -v now works, not just k6 -v run).
  • And we threw in coloured output for control commands while we were at it.

All options can now be set from the environment

Yup. Instead of -u 100/--vus 100, or specifying the vus: 100 option, you can now set K6_VUS in the environment instead.

The order of predecence for this is: defaults > disk config > script options > environment variables > commandline flags.

k6/http: You can pass objects to http.batch() (#295)

http.batch([
    { "method": "GET", "url": "http://example.com/" },
])

Thanks to @borjacampina for this contribution!

k6/http: TLS information in HTTP responses (#322)

HTTP responses now have several new fields, all of which are also exported as tags, and a couple of new constants for their values:

  • tls_version (eg. http.TLS_1_2)
  • tls_cipher_suite (eg. "TLS_RSA_WITH_RC4_128_SHA")
  • ocsp
    • produced_at (timestamp, ms)
    • this_update (timestamp, ms)
    • next_update (timestamp, ms)
    • revoked_at (timestamp, ms)
    • revocation_reason (eg. http.OCSP_REASON_KEY_COMPROMISE)
    • status (eg. http.OCSP_STATUS_GOOD)

k6/http: New API for cookie management (#323)

This is a pretty big feature youthat has been asked about for a long time - we now have a comprehensive API for anything you could possibly want to do regarding cookies.

There's much more, but the biggest thing that's been asked for is how to manually set a cookie for a request, and read it back out - without messing about with manually constructing HTTP headers:

check(http.get("http://example.com/", { cookies: { name: "value" } }), {
    "status is 200": (r) => r.status === 200,
    "some cookie is set": (r) => r.cookies.my_cookie === "hi",
});

Much smaller Docker images (#337)

With the web UI gone, we could drop our Node dependency, and we're also now using Alpine Linux base images.

Thanks to @StephenRadachy for this contribution!

Much faster loading of external ES5 libraries! (#212)

The code responsible for loading JS files now skips invoking Babel for files that are already valid ES5. Yes, it was actually that simple, and it cuts minutes(!) off loading big, already minimised libraries like Faker.js.

k6/encoding: base64 encoding and decoding (#327)

What it says on the tin. Supports normal or URL-safe encodings.

import enc from "k6/encoding";

export default function() {
	console.log(enc.b64encode("hello!!")); // aGVsbG8hIQ==
	console.log(enc.b64encode("hello!!", "rawurl")); // aGVsbG8hIQ
}

Bugs fixed!

  • The iterations metric wasn't exported properly. (#313)

  • Sporadic errors at the end of tests. (#358)

  • Incorrect scaling/failed requests at the start of a test when using stages. (#326)

  • k6/ws: The close event sometimes wouldn't be emitted. (#329)

  • k6/ws: Respond to pings with pongs as decreed by the ws spec. (#330)

  • k6/ws: Missing metrics at the end of a test. (#333)

  • cloud: Anonymous tests with -o cloud now show correct URLs. (#348)

  • cloud: More useful error messages from tests with -o cloud.