Skip to content

Commit

Permalink
Add "next" version folder (#1402)
Browse files Browse the repository at this point in the history
* Add "next" version folder

* Add apply-patch script to apply changes from a commit to a second directory (#1405)

* Add apply-patch script to apply changes from a commit to a second directory

Signed-off-by: Jack Baldry <[email protected]>

* Remove confusing usage output

Not implemented

---------

Signed-off-by: Jack Baldry <[email protected]>

---------

Signed-off-by: Jack Baldry <[email protected]>
Co-authored-by: Jack Baldry <[email protected]>
  • Loading branch information
heitortsergent and jdbaldry authored Nov 8, 2023
1 parent e4e73c8 commit 1b41136
Show file tree
Hide file tree
Showing 587 changed files with 47,987 additions and 0 deletions.
101 changes: 101 additions & 0 deletions docs/sources/next/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
aliases:
- /docs/k6/
description: 'The k6 documentation covers everything you need to know about k6 OSS, load testing, and performance testing.'
menuTitle: Grafana k6
title: Grafana k6 documentation
weight: -10
---

# Grafana k6 documentation

This documentation will help you go from a total beginner to a seasoned k6 expert!

## Get started

<div class="nav-cards">
<a href={{< relref "./get-started/installation" >}} class="nav-cards__item nav-cards__item--guide">
<h4>🚀 Installation</h4>
<p>Get up and running in no-time, using either a package manager, standalone installer or the official Docker image.</p>
</a>
<a href={{< relref "./get-started/running-k6" >}} class="nav-cards__item nav-cards__item--guide">
<h4>🏎️💨 Running k6</h4>
<p>Write and execute your first load test locally using JavaScript and the k6 API, adding multiple virtual users, checks and ramping stages.</p>
</a>
<a href={{< relref "./get-started/results-output" >}} class="nav-cards__item nav-cards__item--guide">
<h4>⏱ Results output</h4>
<p>Learn how to leverage the results output to gain actionable insight about your application's performance.</p>
</a>
</div>

## What is k6?

Grafana k6 is an open-source load testing tool that makes performance testing easy and productive for engineering teams.
k6 is free, developer-centric, and extensible.

Using k6, you can test the reliability and performance of your systems and catch performance regressions and problems earlier.
k6 will help you to build resilient and performant applications that scale.

k6 is developed by [Grafana Labs](https://grafana.com/) and the community.

## Key features

k6 is packed with features, which you can learn all about in the documentation.
Key features include:

- [CLI tool](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/k6-options/how-to) with developer-friendly APIs.
- Scripting in JavaScript ES2015/ES6 - with support for [local and remote modules](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/modules)
- [Checks](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/checks) and [Thresholds](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/thresholds) - for goal-oriented, automation-friendly load testing

## Use cases

k6 users are typically Developers, QA Engineers, SDETs, and SREs.
They use k6 for testing the performance and reliability of APIs, microservices, and websites.
Common k6 use cases are:

- **Load testing**

k6 is optimized for minimal resource consumption and designed for running high load tests
([spike](https://grafana.com/docs/k6/<K6_VERSION>/testing-guides/test-types/spike-testing), [stress](https://grafana.com/docs/k6/<K6_VERSION>/testing-guides/test-types/stress-testing), [soak tests](https://grafana.com/docs/k6/<K6_VERSION>/testing-guides/test-types/soak-testing)).

- **Browser testing**

Through [k6 browser](https://grafana.com/docs/k6/<K6_VERSION>/using-k6-browser), you can run browser-based performance testing and catch issues related to browsers only which can be skipped entirely from the protocol level.

- **Chaos and resilience testing**

You can use k6 to simulate traffic as part of your chaos experiments, trigger them from your k6 tests or inject different types of faults in Kubernetes with [xk6-disruptor](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor).

- **Performance and synthetic monitoring**

With k6, you can automate and schedule to trigger tests very frequently with a small load to continuously validate the performance and availability of your production environment.

## Load Testing Manifesto

Our load testing manifesto is the result of having spent years hip deep in the trenches, doing performance- and load testing.
We’ve created it to be used as guidance, helping you in getting your performance testing on the right track!

- [Simple testing is better than no testing](https://k6.io/our-beliefs/#simple-testing-is-better-than-no-testing)
- [Load testing should be goal oriented](https://k6.io/our-beliefs/#load-testing-should-be-goal-oriented)
- [Load testing by developers](https://k6.io/our-beliefs/#load-testing-by-developers)
- [Developer experience is super important](https://k6.io/our-beliefs/#developer-experience-is-super-important)
- [Load test in a pre-production environment](https://k6.io/our-beliefs/#load-test-in-a-pre-production-environment)

## What k6 does not

k6 is a high-performing load testing tool, scriptable in JavaScript. The architectural design to have these capabilities brings some trade-offs:

- **Does not run natively in a browser**

By default, k6 does not render web pages the same way a browser does.
Browsers can consume significant system resources.
Skipping the browser allows running more load within a single machine.

However, with [k6 browser](https://grafana.com/docs/k6/<K6_VERSION>/using-k6-browser), you can interact with real browsers and collect frontend metrics as part of your k6 tests.

- **Does not run in NodeJS**

JavaScript is not generally well suited for high performance.
To achieve maximum performance, the tool itself is written in Go, embedding a JavaScript runtime allowing for easy test scripting.

If you want to import npm modules or libraries using NodeJS APIs, you can [bundle npm modules with webpack](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/modules#bundling-node-modules) and import them in your tests.
10 changes: 10 additions & 0 deletions docs/sources/next/examples/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
weight: 11
title: Examples
---

# Examples

<!-- TODO: Add content -->

{{< section >}}
257 changes: 257 additions & 0 deletions docs/sources/next/examples/api-crud-operations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
---
title: 'API CRUD Operations'
excerpt: 'This example covers the usage of k6 to test a REST API CRUD operations.'
weight: 10
---

# API CRUD Operations

The examples showcase the testing of CRUD operations on a REST API.

CRUD refers to the basic operations in a database: Create, Read, Update, and Delete. We can map these operations to HTTP methods in REST APIs:

- _Create_: HTTP `POST` operation to create a new resource.
- _Read_: HTTP `GET` to retrieve a resource.
- _Update_: HTTP `PUT`or `PATCH` to change an existing resource.
- _Delete_: HTTP `DELETE` to remove a resource.

This document has two examples, one that uses the core k6 APIs (`k6/http` and `checks`) and another to show the more recent APIs [`httpx`](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/httpx) and [`k6chaijs`](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6chaijs)).

## Test steps

In the [setup() stage](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/test-lifecycle#setup-and-teardown-stages) we create a user for the [k6 HTTP REST API](https://test-api.k6.io/). We then retrieve and return a bearer token to authenticate the next CRUD requests.

The steps implemented in the [VU stage](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/test-lifecycle#the-vu-stage) are as follows:

1. _Create_ a new resource, a "croc".
2. _Read_ the list of "crocs".
3. _Update_ the name of the "croc" and _read_ the "croc" to confirm the update operation.
4. _Delete_ the "croc" resource.

## Core k6 APIs example

{{< code >}}

```javascript
import http from 'k6/http';
import { check, group, fail } from 'k6';

export const options = {
vus: 1,
iterations: 1,
};

// Create a random string of given length
function randomString(length, charset = '') {
if (!charset) charset = 'abcdefghijklmnopqrstuvwxyz';
let res = '';
while (length--) res += charset[(Math.random() * charset.length) | 0];
return res;
}

const USERNAME = `${randomString(10)}@example.com`; // Set your own email or `${randomString(10)}@example.com`;
const PASSWORD = 'superCroc2019';

const BASE_URL = 'https://test-api.k6.io';

// Register a new user and retrieve authentication token for subsequent API requests
export function setup() {
const res = http.post(`${BASE_URL}/user/register/`, {
first_name: 'Crocodile',
last_name: 'Owner',
username: USERNAME,
password: PASSWORD,
});

check(res, { 'created user': (r) => r.status === 201 });

const loginRes = http.post(`${BASE_URL}/auth/token/login/`, {
username: USERNAME,
password: PASSWORD,
});

const authToken = loginRes.json('access');
check(authToken, { 'logged in successfully': () => authToken !== '' });

return authToken;
}

export default (authToken) => {
// set the authorization header on the session for the subsequent requests
const requestConfigWithTag = (tag) => ({
headers: {
Authorization: `Bearer ${authToken}`,
},
tags: Object.assign(
{},
{
name: 'PrivateCrocs',
},
tag
),
});

let URL = `${BASE_URL}/my/crocodiles/`;

group('01. Create a new crocodile', () => {
const payload = {
name: `Name ${randomString(10)}`,
sex: 'F',
date_of_birth: '2023-05-11',
};

const res = http.post(URL, payload, requestConfigWithTag({ name: 'Create' }));

if (check(res, { 'Croc created correctly': (r) => r.status === 201 })) {
URL = `${URL}${res.json('id')}/`;
} else {
console.log(`Unable to create a Croc ${res.status} ${res.body}`);
return;
}
});

group('02. Fetch private crocs', () => {
const res = http.get(`${BASE_URL}/my/crocodiles/`, requestConfigWithTag({ name: 'Fetch' }));
check(res, { 'retrieved crocs status': (r) => r.status === 200 });
check(res.json(), { 'retrieved crocs list': (r) => r.length > 0 });
});

group('03. Update the croc', () => {
const payload = { name: 'New name' };
const res = http.patch(URL, payload, requestConfigWithTag({ name: 'Update' }));
const isSuccessfulUpdate = check(res, {
'Update worked': () => res.status === 200,
'Updated name is correct': () => res.json('name') === 'New name',
});

if (!isSuccessfulUpdate) {
console.log(`Unable to update the croc ${res.status} ${res.body}`);
return;
}
});

group('04. Delete the croc', () => {
const delRes = http.del(URL, null, requestConfigWithTag({ name: 'Delete' }));

const isSuccessfulDelete = check(null, {
'Croc was deleted correctly': () => delRes.status === 204,
});

if (!isSuccessfulDelete) {
console.log(`Croc was not deleted properly`);
return;
}
});
};
```

{{< /code >}}

## httpx and k6chaijs example

{{< code >}}

```javascript
import { describe, expect } from 'https://jslib.k6.io/k6chaijs/4.3.4.3/index.js';
import { Httpx } from 'https://jslib.k6.io/httpx/0.1.0/index.js';
import { randomIntBetween, randomItem, randomString } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';

export const options = {
// for the example, let's run only 1 VU with 1 iteration
vus: 1,
iterations: 1,
};

const USERNAME = `user${randomIntBetween(1, 100000)}@example.com`; // Set your own email;
const PASSWORD = 'superCroc2019';

const session = new Httpx({ baseURL: 'https://test-api.k6.io' });

// Register a new user and retrieve authentication token for subsequent API requests
export function setup() {
let authToken = null;

describe(`setup - create a test user ${USERNAME}`, () => {
const resp = session.post(`/user/register/`, {
first_name: 'Crocodile',
last_name: 'Owner',
username: USERNAME,
password: PASSWORD,
});

expect(resp.status, 'User create status').to.equal(201);
expect(resp, 'User create valid json response').to.have.validJsonBody();
});

describe(`setup - Authenticate the new user ${USERNAME}`, () => {
const resp = session.post(`/auth/token/login/`, {
username: USERNAME,
password: PASSWORD,
});

expect(resp.status, 'Authenticate status').to.equal(200);
expect(resp, 'Authenticate valid json response').to.have.validJsonBody();
authToken = resp.json('access');
expect(authToken, 'Authentication token').to.be.a('string');
});

return authToken;
}

export default function (authToken) {
// set the authorization header on the session for the subsequent requests
session.addHeader('Authorization', `Bearer ${authToken}`);

describe('01. Create a new crocodile', (t) => {
const payload = {
name: `Croc name ${randomString(10)}`,
sex: randomItem(['M', 'F']),
date_of_birth: '2023-05-11',
};

session.addTag('name', 'Create');
const resp = session.post(`/my/crocodiles/`, payload);

expect(resp.status, 'Croc creation status').to.equal(201);
expect(resp, 'Croc creation valid json response').to.have.validJsonBody();

session.newCrocId = resp.json('id');
});

describe('02. Fetch private crocs', (t) => {
session.clearTag('name');
const resp = session.get('/my/crocodiles/');

expect(resp.status, 'Fetch croc status').to.equal(200);
expect(resp, 'Fetch croc valid json response').to.have.validJsonBody();
expect(resp.json().length, 'Number of crocs').to.be.above(0);
});

describe('03. Update the croc', (t) => {
const payload = {
name: `New croc name ${randomString(10)}`,
};

const resp = session.patch(`/my/crocodiles/${session.newCrocId}/`, payload);

expect(resp.status, 'Croc patch status').to.equal(200);
expect(resp, 'Fetch croc valid json response').to.have.validJsonBody();
expect(resp.json('name'), 'Croc name').to.equal(payload.name);

// read "croc" again to verify the update worked
const resp1 = session.get(`/my/crocodiles/${session.newCrocId}/`);

expect(resp1.status, 'Croc fetch status').to.equal(200);
expect(resp1, 'Fetch croc valid json response').to.have.validJsonBody();
expect(resp1.json('name'), 'Croc name').to.equal(payload.name);
});

describe('04. Delete the croc', (t) => {
const resp = session.delete(`/my/crocodiles/${session.newCrocId}/`);

expect(resp.status, 'Croc delete status').to.equal(204);
});
}
```

{{< /code >}}
10 changes: 10 additions & 0 deletions docs/sources/next/examples/bundling-and-transpilation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: 'Bundling and transpilation'
redirect: 'https://github.com/k6io/k6-es6/'
excerpt: |
Reference project demonstrating how to use webpack and babel to bundle
node modules or transpile code to ES5.1+ for usage in k6 tests.
weight: 18
---

# Bundling and transpilation
Loading

0 comments on commit 1b41136

Please sign in to comment.