Skip to content

Commit

Permalink
chore: Tracetest Cloud x K6 example (#3452)
Browse files Browse the repository at this point in the history
* chore: Tracetest Cloud x  K6 example

* chore: Tracetest Cloud x  K6 example

* Edit comments
  • Loading branch information
xoscar committed Dec 18, 2023
1 parent f78c51b commit da1acc1
Show file tree
Hide file tree
Showing 10 changed files with 316 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/tracetest-cloud-k6/.env.template
@@ -0,0 +1 @@
TRACETEST_API_KEY=
2 changes: 2 additions & 0 deletions examples/tracetest-cloud-k6/.gitignore
@@ -0,0 +1,2 @@
.env
k6
61 changes: 61 additions & 0 deletions examples/tracetest-cloud-k6/README.md
@@ -0,0 +1,61 @@
# Tracetest Cloud + K6

This example's objective is to show how you can run load tests enhanced with trace-based testing using Tracetest Cloud and k6 against an instrumented service (Pokeshop API).

For more detailed information about the K6 Tracetest Binary take a look a the [docs](https://docs.tracetest.io/tools-and-integrations/integrations/k6).

## Prerequisites

1. Signing up to [app.tracetest.io](https://app.tracetest.io).
2. Creating an [environment](https://docs.tracetest.io/concepts/environments).
3. Having access to the environment's [agent token](https://docs.tracetest.io/configuration/agent).

## Steps

1. [Install the Tracetest CLI](https://docs.tracetest.io/installing/).
2. Copy the `.env.template` file into `.env` and add the `TRACETEST_API_KEY`. This is the Agent API token from your environment.
3. Create a [token from your environment](https://docs.tracetest.io/concepts/environment-tokens).
4. Run `tracetest configure` on a terminal and select the environment in use.
5. Run the project by using docker-compose: `docker-compose up -d` (Linux) or `docker compose up -d` (Mac).
6. Test if it works by running: `tracetest run test -f tests/test.yaml`. This will create and run a test with trace id as the trigger.
7. Build the k6 binary with the extension by using `xk6 build v0.42.0 --with github.com/kubeshop/xk6-tracetest`.
8. Now you are ready to run your load test; you can achieve this by running the following command: `XK6_TRACETEST_API_TOKEN=<your-environment-token> ./k6 run ./import-pokemon.js -o xk6-tracetest`.
9. After the load test finishes you should be able to see an output like the following:

```bash
./k6 run ./import-pokemon.js -o xk6-tracetest
context menu


/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io

execution: local
script: ./import-pokemon.js
output: xk6-tracetest-output (TestRunID: 38055)

scenarios: (100.00%) 1 scenario, 1 max VUs, 35s max duration (incl. graceful stop):
* default: 1 looping VUs for 5s (gracefulStop: 30s)

[TotalRuns=6, SuccessfulRus=1, FailedRuns=5]
[FAILED]
[Request=GET - http://localhost:8081/pokemon/import, TraceID=dc0718bcecceeec731b343235eb9c15a, RunState=FINISHED FailingSpecs=true, TracetestURL= https://app.tracetest.io/organizations/ttorg_ced62e34638d965e/environments/ttenv_807d0129a10be776/test/kc_MgKoVR/run/11]
[Request=POST - http://localhost:8081/pokemon/import, TraceID=dc0718fe83cfeec7315daf10d212d351, RunState=FINISHED FailingSpecs=true, TracetestURL= https://app.tracetest.io/organizations/ttorg_ced62e34638d965e/environments/ttenv_807d0129a10be776/test/kc_MgKoVR/run/4]
[Request=POST - http://localhost:8081/pokemon/import, TraceID=dc0718a8f4ceeec731e47f13762e61b8, RunState=FINISHED FailingSpecs=true, TracetestURL= https://app.tracetest.io/organizations/ttorg_ced62e34638d965e/environments/ttenv_807d0129a10be776/test/kc_MgKoVR/run/8]
[Request=POST - http://localhost:8081/pokemon/import, TraceID=dc0718bcecceeec731b343235eb9c15a, RunState=FINISHED FailingSpecs=true, TracetestURL= https://app.tracetest.io/organizations/ttorg_ced62e34638d965e/environments/ttenv_807d0129a10be776/test/kc_MgKoVR/run/9]
[Request=POST - http://localhost:8081/pokemon/import, TraceID=dc071893fcceeec731148270c6671a1e, RunState=FINISHED FailingSpecs=true, TracetestURL= https://app.tracetest.io/organizations/ttorg_ced62e34638d965e/environments/ttenv_807d0129a10be776/test/kc_MgKoVR/run/6]
[SUCCESSFUL]
[Request=POST - http://localhost:8081/pokemon/import, TraceID=dc0718cee4ceeec731f3f414bf3a2a16, RunState=FINISHED FailingSpecs=false, TracetestURL= https://app.tracetest.io/organizations/ttorg_ced62e34638d965e/environments/ttenv_807d0129a10be776/test/kc_MgKoVR/run/3]

running (05.0s), 0/1 VUs, 5 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs 5s
```
## What's Next?
After running the initial set of tests, you can click the run link for any of them, update the assertions and run the scripts once more. This flow enables complete a trace-based TDD flow.
![assertions](assets/assertions.gif)
Binary file added examples/tracetest-cloud-k6/assets/assertions.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions examples/tracetest-cloud-k6/collector.config.yaml
@@ -0,0 +1,22 @@
receivers:
otlp:
protocols:
grpc:
http:

processors:
batch:
timeout: 100ms

exporters:
jaeger:
endpoint: jaeger:14250
tls:
insecure: true

service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [jaeger]
125 changes: 125 additions & 0 deletions examples/tracetest-cloud-k6/docker-compose.yml
@@ -0,0 +1,125 @@
version: "3"

services:
tracetest-agent:
image: kubeshop/tracetest-agent:latest
environment:
TRACETEST_DEV: ${TRACETEST_DEV}
TRACETEST_API_KEY: ${TRACETEST_API_KEY}

postgres:
image: postgres:14
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
healthcheck:
test: pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB"
interval: 1s
timeout: 5s
retries: 60

otel-collector:
image: otel/opentelemetry-collector:0.54.0
command:
- "--config"
- "/otel-local-config.yaml"
volumes:
- ./collector.config.yaml:/otel-local-config.yaml
depends_on:
- jaeger

jaeger:
image: jaegertracing/all-in-one:latest
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--spider", "localhost:16686"]
interval: 1s
timeout: 3s
retries: 60

cache:
image: redis:6
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 1s
timeout: 3s
retries: 60

queue:
image: rabbitmq:3.8-management
restart: unless-stopped
healthcheck:
test: rabbitmq-diagnostics -q check_running
interval: 1s
timeout: 5s
retries: 60

demo-api:
image: kubeshop/demo-pokemon-api:latest
restart: unless-stopped
pull_policy: always
environment:
REDIS_URL: cache
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres?schema=public
RABBITMQ_HOST: queue
POKE_API_BASE_URL: https://pokeapi.co/api/v2
COLLECTOR_ENDPOINT: http://otel-collector:4317
NPM_RUN_COMMAND: api
healthcheck:
test: ["CMD", "wget", "--spider", "localhost:8081"]
interval: 1s
timeout: 3s
retries: 60
ports:
- 8081:8081
depends_on:
postgres:
condition: service_healthy
cache:
condition: service_healthy
queue:
condition: service_healthy

demo-worker:
image: kubeshop/demo-pokemon-api:latest
restart: unless-stopped
pull_policy: always
environment:
REDIS_URL: cache
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres?schema=public
RABBITMQ_HOST: queue
POKE_API_BASE_URL: https://pokeapi.co/api/v2
COLLECTOR_ENDPOINT: http://otel-collector:4317
NPM_RUN_COMMAND: worker
depends_on:
postgres:
condition: service_healthy
cache:
condition: service_healthy
queue:
condition: service_healthy

demo-rpc:
image: kubeshop/demo-pokemon-api:latest
restart: unless-stopped
pull_policy: always
environment:
REDIS_URL: cache
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres?schema=public
RABBITMQ_HOST: queue
POKE_API_BASE_URL: https://pokeapi.co/api/v2
COLLECTOR_ENDPOINT: http://otel-collector:4317
NPM_RUN_COMMAND: rpc
healthcheck:
test: ["CMD", "lsof", "-i", "8082"]
interval: 1s
timeout: 3s
retries: 60
depends_on:
postgres:
condition: service_healthy
cache:
condition: service_healthy
queue:
condition: service_healthy
56 changes: 56 additions & 0 deletions examples/tracetest-cloud-k6/import-pokemon.js
@@ -0,0 +1,56 @@
import { Http, Tracetest } from "k6/x/tracetest";
import { sleep } from "k6";

export const options = {
vus: 1,
duration: "5s",
};

const http = new Http();
const testId = "kc_MgKoVR";
const tracetest = Tracetest();

let pokemonId = 6;

export default function () {
const url = "http://localhost:8081/pokemon/import";
const payload = JSON.stringify({
id: pokemonId++,
});
const params = {
headers: {
"Content-Type": "application/json",
},
tracetest: {
testId,
},
};

const response = http.post(url, payload, params);

tracetest.runTest(
response.trace_id,
{
test_id: testId,
variable_name: "TRACE_ID",
should_wait: true,
},
{
id: "123",
url,
method: "GET",
}
);

sleep(1);
}

export function handleSummary() {
return {
stdout: tracetest.summary(),
};
}

export function teardown() {
tracetest.validateResult();
}
23 changes: 23 additions & 0 deletions examples/tracetest-cloud-k6/tests/test.yaml
@@ -0,0 +1,23 @@
type: Test
spec:
id: kc_MgKoVR
name: K6
description: K6
trigger:
type: traceid
traceid:
id: ${env:TRACE_ID}
specs:
- selector: span[tracetest.span.type="general" name="import pokemon"]
name: Should have imported the pokemon
assertions:
- attr:tracetest.selected_spans.count = 1
- selector: |-
span[tracetest.span.type="http" net.peer.name="pokeapi.co" http.method="GET"]
name: Should trigger a request to the POKEAPI
assertions:
- attr:http.url = "https://pokeapi.co/api/v2/pokemon/6"
- selector: span[tracetest.span.type="database" name="create postgres.pokemon"]
name: Should insert the pokemon to the DB
assertions:
- attr:db.result | json_path '.name' = "charizard"
7 changes: 7 additions & 0 deletions examples/tracetest-cloud-k6/tracetest-config.yaml
@@ -0,0 +1,7 @@
postgres:
host: postgres
user: postgres
password: postgres
port: 5432
dbname: postgres
params: sslmode=disable
19 changes: 19 additions & 0 deletions examples/tracetest-cloud-k6/tracetest-provision.yaml
@@ -0,0 +1,19 @@
---
type: PollingProfile
spec:
name: Default
strategy: periodic
default: true
periodic:
retryDelay: 5s
timeout: 10m

---
type: DataStore
spec:
name: jaeger
type: jaeger
jaeger:
endpoint: jaeger:16685
tls:
insecure: true

0 comments on commit da1acc1

Please sign in to comment.