Skip to content

Commit

Permalink
Merge pull request #1811 from grafana/v0.55.x
Browse files Browse the repository at this point in the history
Publish v0.55.x documentation
  • Loading branch information
oleiade authored Nov 11, 2024
2 parents 92e8a24 + 4cad6d5 commit d4a1fd7
Show file tree
Hide file tree
Showing 822 changed files with 62,830 additions and 0 deletions.
87 changes: 87 additions & 0 deletions docs/sources/k6/v0.55.x/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
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
weight: -10
hero:
title: Grafana k6
level: 1
image: /media/docs/k6/GrafanaLogo_k6_orange_icon.svg
width: 100
height: 100
description: Grafana k6 is an open-source, developer-friendly, and extensible load testing tool. k6 allows you to prevent performance issues and proactively improve reliability.
cards:
title_class: pt-0 lh-1
items:
- title: Run your first k6 test
href: ./get-started/
description: Learn how to install the k6 CLI, run your first k6 test, and view metric results in the terminal.
height: 24
- title: Using k6
href: ./using-k6/
description: Learn about k6 options and concepts such as thresholds, metrics, lifecycle hooks, and more.
height: 24
- title: Testing guides
href: ./testing-guides/
description: Discover how to plan and define your performance testing strategy with these guides.
height: 24
- title: k6 JavaScript API
href: ./javascript-api/
description: Explore the k6 APIs through their documentation and examples.
height: 24
- title: Explore k6 extensions
href: ./extensions/
description: Have a particular testing need? Find k6 extensions that extend the native k6 functionality.
height: 24
- title: k6 script examples
href: ./extensions/
description: Learn how to script your tests with this list of common k6 examples.
height: 24
---

{{< docs/hero-simple key="hero" >}}

---

## Overview

Using k6, you can test the reliability and performance of your application and infrastructure.

k6 helps engineering teams prevent errors and SLO breaches, enabling them to build resilient and high-performing applications that scale.

Engineering teams, including Developers, QA Engineers, SDETs, and SREs, commonly use k6 for:

- **Load and performance testing**

k6 is optimized for minimal resource consumption and designed for running high-load performance tests such as
[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), or [soak tests](https://grafana.com/docs/k6/<K6_VERSION>/testing-guides/test-types/soak-testing).

- **Browser performance testing**

Through the [k6 browser API](https://grafana.com/docs/k6/<K6_VERSION>/using-k6-browser), you can run browser-based performance tests and collect browser metrics to identify performance issues related to browsers. Additionally, you can mix browser tests with other performance tests to get a comprehensive view of your website's performance.

- **Performance and synthetic monitoring**

You can schedule tests to run with minimal load very frequently, continuously validating the performance and availability of your production environment. For this, you can also use [Grafana Cloud Synthetic Monitoring](https://grafana.com/docs/grafana-cloud/testing/synthetic-monitoring/create-checks/checks/k6/), which supports running k6 scripts.

- **Automation of performance tests**

k6 integrates seamlessly with CI/CD and automation tools, enabling engineering teams to [automate performance testing](https://grafana.com/docs/k6/<K6_VERSION>/testing-guides/automated-performance-testing/) as part of their development and release cycle.

- **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>/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor).

- **Infrastructure testing**

With [k6 extensions](https://grafana.com/docs/k6/<K6_VERSION>/extensions/), you can add support to k6 for new protocols or use a particular client to directly test individual systems within your infrastructure.

Watch the video below to learn more about k6 and why it could be the missing puzzle in your Grafana stack.

{{< youtube id="1mtYVDA2_iQ" >}}

## Explore

{{< card-grid key="cards" type="simple" >}}
10 changes: 10 additions & 0 deletions docs/sources/k6/v0.55.x/examples/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: Examples
weight: 800
---

# Examples

<!-- TODO: Add content -->

{{< section >}}
261 changes: 261 additions & 0 deletions docs/sources/k6/v0.55.x/examples/api-crud-operations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
---
title: 'API CRUD Operations'
description: '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 >}}
12 changes: 12 additions & 0 deletions docs/sources/k6/v0.55.x/examples/bundling-and-transpiling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
aliases:
- ./bundling-and-transpilation # docs/k6/<K6_VERSION>/examples/bundling-and-transpilation
title: 'Bundling and transpiling'
description: |
Refer to the JavaScript and TypeScript compatibility mode page for more details on how to use TypeScript with k6
weight: 18
---

# Bundling and transpiling

For more details about bundling and transpiling, refer to [JavaScript and TypeScript compatibility mode](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/javascript-typescript-compatibility-mode/).
Loading

0 comments on commit d4a1fd7

Please sign in to comment.