Skip to content

Commit

Permalink
Update running k6 (#26)
Browse files Browse the repository at this point in the history
* Update Running k6 guide + restructure info

* Release to staging `update-running-k6`

* Address Running k6 review

* Revert " Release to staging `update-running-k6`"

This reverts commit 926e21b.
  • Loading branch information
Pepe Cano authored May 25, 2020
1 parent beba364 commit 9697e41
Show file tree
Hide file tree
Showing 15 changed files with 324 additions and 439 deletions.
6 changes: 6 additions & 0 deletions gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,12 @@ const createRedirects = ({ actions, pathPrefix }) => {
'/javascript-api/k6-http/response-k6-http/response-submitform-params',
isPermanent: true,
});

createRedirect({
fromPath: '/using-k6/cloud-execution',
toPath: '/cloud/creating-and-running-a-test/cloud-tests-from-the-cli',
isPermanent: true,
});
};

exports.createPages = async (options) => {
Expand Down
151 changes: 37 additions & 114 deletions src/data/markdown/docs/01 guides/01 Getting started/03 Running k6.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,9 @@ title: 'Running k6'
excerpt: ''
---

## Running k6 the first time
## Running local tests

This will run a very simple k6 sample script from github (click on the _Docker_ tab
if you prefer using the k6 [Docker image](https://en.wikipedia.org/wiki/Docker_%28software%29)):

<div class="code-group" data-props='{"labels": ["Mac / prebuilt binary", "Docker image"]}'>

```shell
$ k6 run github.com/loadimpact/k6/samples/http_get.js
```

```shell
$ docker run loadimpact/k6 run github.com/loadimpact/k6/samples/http_get.js
```

</div>

You should see `k6` download the sample script and run it with a single virtual user (VU).

## Executing local scripts

Next, let's try to run a local script. Copy the code below, paste it into your
Let's start by running a simple local script. Copy the code below, paste it into your
favourite editor, and save it as "script.js":

<div class="code-group" data-props='{"labels": ["script.js"], "lineNumbers": [true]}'>
Expand All @@ -43,13 +24,19 @@ export default function() {

Then run k6 using this command:

<div class="code-group" data-props='{"labels": ["Mac / prebuilt binary", "Docker", "Docker in Win PowerShell"]}'>
<div class="code-group" data-props='{"labels": ["CLI", "Docker", "Docker in Win PowerShell"]}'>

```shell
$ k6 run script.js
```

```shell
# When using the `k6` docker image, you can't just give the script name since
# the script file will not be available to the container as it runs. Instead
# you must tell k6 to read `stdin` by passing the file name as `-`. Then you
# pipe the actual file into the container with `<` or equivalent. This will
# cause the file to be redirected into the container and be read by k6.

$ docker run -i loadimpact/k6 run - <script.js
```

Expand All @@ -59,26 +46,11 @@ $ cat script.js | docker run -i loadimpact/k6 run -

</div>

### Docker syntax

When using the `k6` docker image, you can't just give the script name since
the script file will not be available to the container as it runs. Instead
you must tell k6 to read `stdin` by passing the file name as `-`. Then you
pipe the actual file into the container with `<` or equivalent. This will
cause the file to be redirected into the container and be read by k6.

> ### ⚠️ Note
>
> If your script imports other files (JS modules), piping like this
> will not work since the extra files will not be visible inside the container.
> To use modules you need to first mount your host/local directory into the
> Docker container, see [Modules with Docker](/using-k6/modules#using-local-modules-with-docker).
## Adding more VUs

Now we'll try running a _real_ load test, with more than 1 virtual user and a slightly longer duration:
Now we'll try running a load test with more than 1 virtual user and a slightly longer duration:

<div class="code-group" data-props='{"labels": ["Mac / prebuilt binary", "Docker", "Docker in Win PowerShell"]}'>
<div class="code-group" data-props='{"labels": ["CLI", "Docker", "Docker in Win PowerShell"]}'>

```shell
k6 run --vus 10 --duration 30s script.js
Expand All @@ -103,55 +75,43 @@ which allows you to break larger tests into smaller pieces, or make reusable pie
Scripts must contain, at the very least, a `default` function - this defines the entry point for
your VUs, similar to the `main()` function in many other languages:

<div class="code-group" data-props='{"labels": [], "lineNumbers": [true]}'>
<div class="code-group" data-props='{"labels": []}'>

```javascript
export default function() {
// do things here...
// vu code: do things here...
}
```

</div>

## The init context and the default function
### The init context and the default function

"Why not just run my script normally, from top to bottom", you might ask - the answer is: we do,
but code inside and outside your default function can do different things.

Code _inside_ `default` is called "VU code", and is run over and over for as long as the test is
running. Code _outside_ of it is called "init code", and is run only once per VU.

VU code can make HTTP requests, emit metrics, and generally do everything you'd expect a load test
to do - with a few important exceptions: you can't load anything from your local filesystem, or
import any other modules. This all has to be done from init-code.

There are two reasons for this. The first is, of course: performance.
<div class="code-group" data-props='{"labels": [""]}'>

If you read a file from disk on every single script iteration, it'd be needlessly slow; even if
you cache the contents of the file and any imported modules, it'd mean the _first run_ of the
script would be much slower than all the others. Worse yet, if you have a script that imports
or loads things based on things that can only be known at runtime, you'd get slow iterations
thrown in every time you load something new.
```js
// init code

But there's another, more interesting reason. By forcing all imports and file reads into the
init context, we design for distributed execution. We know which files will be needed, so we
distribute only those files. We know which modules will be imported, so we can bundle them up
from the get-go. And, tying into the performance point above, the other nodes don't even need
writable filesystems - everything can be kept in-memory.
export default function( {
// vu code
}

As an added bonus, you can use this to reuse data between iterations (but only for the same VU):
```
<div class="code-group" data-props='{"labels": [], "lineNumbers": [true]}'>
</div>
```javascript
var counter = 0;
VU code can make HTTP requests, emit metrics, and generally do everything you'd expect a load test
to do - with a few important exceptions: you can't load anything from your local filesystem, or
import any other modules. This all has to be done from init-code.
export default function() {
counter++;
}
```
Read more about the different [life cycle stages of a k6 test](/using-k6/test-life-cycle).
</div>
## Using options
Expand All @@ -177,7 +137,7 @@ export default function() {
Then you just run the script without those parameters on the command line:
<div class="code-group" data-props='{"labels": ["Mac / prebuilt binary", "Docker", "Docker in Win PowerShell"]}'>
<div class="code-group" data-props='{"labels": ["CLI", "Docker", "Docker in Win PowerShell"]}'>
```shell
$ k6 run script.js
Expand Down Expand Up @@ -221,63 +181,26 @@ export default function() {
</div>
## Using checks

Maybe we want to verify that an HTTP transaction worked and that the transaction time stayed below some acceptable value. We can use the [check()](/javascript-api/k6/check-val-sets-tags) function for this:

<div class="code-group" data-props='{"labels": ["stages.js"], "lineNumbers": [true]}'>
## Running cloud tests
```javascript
import http from 'k6/http';
import { check, sleep } from 'k6';

export let options = {
vus: 10,
duration: '30s',
};

export default function() {
let res = http.get('http://test.k6.io');
check(res, {
'status was 200': r => r.status == 200,
'transaction time OK': r => r.timings.duration < 200,
});
sleep(1);
}
```
k6 supports three execution modes to run your k6 tests:
</div>
- [Local](#running-local-tests): on your local machine or a CI server.
- [Cloud](/cloud): on cloud infrastructure managed by k6 Cloud.
- Clustered: on more than one machine managed by you. [Not supported yet](https://github.com/loadimpact/k6/issues/140).
_Using check() to verify that transactions work and are fast enough_
One of the goals with k6 is to support running a test in the three execution modes without making modifications to the script.
The above will generate a couple of extra output lines after the test, telling you if your check conditions succeeded or failed during the test. If the check conditions never failed, you will see this:
For running cloud tests from the CLI, you must first register a k6 Cloud account and then log into your account via the CLI. Then, you only have to pass your existing script to the `k6 cloud` command.
<div class="code-group" data-props='{"labels": []}'>
<div class="code-group" data-props='{"labels": ["Running a cloud test"]}'>
```shell
done [==========================================================] 30s / 30s

✓ status was 200 OK
✓ transaction time OK
$ k6 cloud script.js

```
</div>
And if a check condition fails, it will instead look like this:

<div class="code-group" data-props='{"labels": []}'>

```shell
done [==========================================================] 30s / 30s

✗ status was 200
↳ 0% — ✓ 0 / ✗ 150
✓ transaction time OK
```

</div>

If you are using [k6 Cloud Insights](/cloud/analyzing-results/overview) you can also see how a given check has failed or passed during the test run:

![Cloud Insights checks](./images/cloud-insights-checks.png)
For detailed instructions and the different options, read more on [running cloud tests from the CLI](/cloud/creating-and-running-a-test/cloud-tests-from-the-cli).

This file was deleted.

14 changes: 14 additions & 0 deletions src/data/markdown/docs/01 guides/02 Using k6/15 Test life cycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ we distribute only those files. We know which modules will be imported, so we ca
up from the get-go. And, tying into the performance point above, the other nodes don't even
need writable filesystems - everything can be kept in-memory.

As an added bonus, you can use this to reuse data between iterations (but only for the same VU):

<div class="code-group" data-props='{"labels": []}'>

```javascript
var counter = 0;

export default function() {
counter++;
}
```

</div>

## The default function life-cycle

A VU will execute the default function from start to end in sequence. Nothing out of the ordinary
Expand Down
Loading

0 comments on commit 9697e41

Please sign in to comment.