Skip to content

Commit 64ecd7e

Browse files
committed
Automate test environment setup and cleanup. Use OpenTelemetry as a Tracetest source.
1 parent f214c4f commit 64ecd7e

File tree

12 files changed

+328
-76
lines changed

12 files changed

+328
-76
lines changed

example-apps/chatbot-rag-app/docker-compose.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,9 @@ services:
3333
- "4000:4000"
3434
extra_hosts: # send localhost traffic to the docker host, e.g. your laptop
3535
- "localhost:host-gateway"
36+
healthcheck:
37+
test: ["CMD", "bash", "-c", "exec 6<>/dev/tcp/localhost/4000"]
38+
interval: 5s
39+
timeout: 3s
40+
retries: 3
41+
start_period: 5s

example-apps/chatbot-rag-app/test/tracetest/Dockerfile.tracetest

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Trace-Based Testing for Chatbot RAG Application
2+
3+
*The instructions and tests below have been used with models hosted by OpenAI.
4+
We plan to add tests for additional model configurations in the future.*
5+
6+
## Introduction to Trace Testing
7+
8+
Trace testing is a modern approach to testing distributed systems by leveraging the distributed traces that flow through your applications. In a complex system like the Chatbot RAG application, traditional testing approaches may fall short because they can't effectively monitor the interactions between microservices, databases, and external APIs.
9+
10+
Tracetest is an open-source tool that enables you to create, run, and maintain integration tests using distributed traces with support for OpenTelemetry and observability backends such as Elastic APM. It allows you to:
11+
12+
- Validate the flow of requests through your entire system
13+
- Assert on specific spans within a trace
14+
- Test complex scenarios involving multiple services
15+
16+
For more information about Tracetest, visit the [official documentation](https://docs.tracetest.io/).
17+
18+
## Setup
19+
20+
Chatbot RAG application setup uses Docker to create a testing environment that includes:
21+
22+
1. A Tracetest server for executing and managing tests
23+
2. An Elasticsearch cluster for storing traces, logs, and application data
24+
3. An OpenTelemetry collector for processing and routing telemetry data
25+
4. The chatbot RAG application itself
26+
27+
The setup leverages several Docker Compose files to combine the test environment with the local Elastic Stack (from [docker/docker-compose-elastic.yml](../../../../docker/docker-compose-elastic.yml)) and Chatbot RAG application (from [example-apps/chatbot-rag-app/docker-compose.yml](../../docker-compose.yml)). In order to spin up the up-to-date versions of all moving parts, we leverage overrides maintained within this directory. We use:
28+
29+
- `docker-compose.test.yml` - for Tracetest configuration
30+
- `docker-compose.test.override.yml` - Test-specific Tracetest configuration
31+
- `elastic-stack.override.yml` - for test-specific configuration for Elasticsearch and OpenTelemetry Collector
32+
- `chatbot-rag.override.yml` - for configuration of the chatbot application in test mode.
33+
34+
All services are connected through a shared Docker network to enable communication between components.
35+
36+
## Environment Configuration
37+
38+
Before running tests, you need to prepare a `.env.test` file with the necessary environment variables. This file configures the behavior of the chatbot application during testing (same configuration as described in [the applications's directory](../../README.md)).
39+
40+
Create a `.env.test` file in the `test/tracetest` directory with the following content to reproduce the environment we're testing with:
41+
42+
```bash
43+
# Location of the application routes
44+
FLASK_APP=api/app.py
45+
# Ensure print statements appear as they happen
46+
PYTHONUNBUFFERED=1
47+
48+
# How you connect to Elasticsearch: change details to your instance
49+
ELASTICSEARCH_URL=http://elasticsearch:9200
50+
ELASTICSEARCH_USER=elastic
51+
ELASTICSEARCH_PASSWORD=elastic
52+
53+
# The name of the Elasticsearch indexes
54+
ES_INDEX=workplace-app-docs
55+
ES_INDEX_CHAT_HISTORY=workplace-app-docs-chat-history
56+
57+
# OpenAI Configuration
58+
LLM_TYPE=openai
59+
OPENAI_API_KEY=
60+
CHAT_MODEL=gpt-4o-mini
61+
62+
# Set to false to record logs, traces and metrics
63+
OTEL_SDK_DISABLED=false
64+
65+
# Assign the service name that shows up in Kibana
66+
OTEL_SERVICE_NAME=chatbot-rag-app
67+
68+
# OpenTelemetry configuration
69+
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
70+
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
71+
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
72+
73+
# Performance tuning
74+
OTEL_METRIC_EXPORT_INTERVAL=3000
75+
OTEL_BSP_SCHEDULE_DELAY=3000
76+
OTEL_EXPERIMENTAL_RESOURCE_DETECTORS=process_runtime,os,otel,telemetry_distro
77+
```
78+
79+
> Note: Make sure to add your actual OpenAI API key.
80+
81+
## Running the Tests
82+
83+
To run the trace-based tests for the chatbot RAG application, follow these steps:
84+
85+
1. Navigate to the test directory:
86+
87+
```bash
88+
cd example-apps/chatbot-rag-app/test/tracetest
89+
```
90+
91+
2. Execute the test script:
92+
93+
```bash
94+
./run-tests.sh
95+
```
96+
97+
To automatically clean up resources after the tests complete (or if they fail), you can use the --with-cleanup flag:
98+
99+
```bash
100+
./run-tests.sh --with-cleanup
101+
```
102+
103+
The script performs the following operations:
104+
105+
- Creates a shared Docker network for all services
106+
- Sets up the Tracetest server
107+
- Starts the Elastic stack (Elasticsearch and OpenTelemetry Collector)
108+
- Builds and starts the chatbot RAG application
109+
- Executes the trace tests defined in `resources/openai-chatbot-test.yaml`
110+
- If `--with-cleanup` is provided, automatically cleans up all resources when the script exits (normally or due to an error)
111+
112+
The example test sends a question about working from home policy to the LLM via API and validates several aspects of the application:
113+
114+
- Successful interraction with the LLM (in the initial setup, a `gpt-4o-mini` via OpenAI API)
115+
- Proper search operations in Elasticsearch for RAG functionality
116+
- Correct updating of chat history
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
networks:
2+
shared-test-network:
3+
external: true # Reference the network created above
4+
5+
services:
6+
create-index:
7+
env_file:
8+
- ./test/tracetest/.env.test
9+
networks:
10+
- shared-test-network
11+
api-frontend:
12+
# Build image on the local codebase to allow testing locally.
13+
image: chatbot-rag-app-local
14+
build:
15+
context: .
16+
env_file:
17+
- ./test/tracetest/.env.test
18+
networks:
19+
- shared-test-network
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
networks:
2+
shared-test-network:
3+
external: true # Reference the network created above
4+
5+
services:
6+
postgres:
7+
networks:
8+
- shared-test-network
9+
tracetest:
10+
networks:
11+
- shared-test-network
12+

example-apps/chatbot-rag-app/test/tracetest/docker-compose.yaml renamed to example-apps/chatbot-rag-app/test/tracetest/docker-compose.test.yml

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ services:
1212
interval: 1s
1313
retries: 60
1414
image: postgres:14
15-
networks:
16-
default: null
1715
tracetest:
1816
command: --provisioning-file /app/provision.yaml
1917
depends_on:
@@ -34,8 +32,6 @@ services:
3432
interval: 1s
3533
retries: 60
3634
image: kubeshop/tracetest:v1.7.1
37-
networks:
38-
default: null
3935
ports:
4036
- mode: ingress
4137
target: 11633
@@ -48,20 +44,4 @@ services:
4844
- type: bind
4945
source: ./resources/tracetest-provision.yaml
5046
target: /app/provision.yaml
51-
52-
tracetest-run:
53-
build:
54-
dockerfile: Dockerfile.tracetest
55-
volumes:
56-
- ./resources:/resources
57-
entrypoint:
58-
- bash
59-
- /resources/run.sh
60-
networks:
61-
default: null
62-
depends_on:
63-
tracetest:
64-
condition: service_healthy
65-
networks:
66-
default:
67-
name: tracetest_default
47+
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
networks:
2+
shared-test-network:
3+
external: true # Reference the network created above
4+
5+
services:
6+
elasticsearch:
7+
networks:
8+
- shared-test-network
9+
elasticsearch_settings:
10+
networks:
11+
- shared-test-network
12+
kibana:
13+
networks:
14+
- shared-test-network
15+
otel-collector:
16+
networks:
17+
- shared-test-network
18+
configs:
19+
# This is the minimal yaml configuration needed to listen on all interfaces
20+
# for OTLP logs, metrics and traces, exporting to Elasticsearch.
21+
# Overriding for test purposes in order to add tracetest exporter
22+
edot-collector-config:
23+
content: |
24+
receivers:
25+
otlp:
26+
protocols:
27+
grpc:
28+
endpoint: 0.0.0.0:4317
29+
http:
30+
endpoint: 0.0.0.0:4318
31+
32+
connectors:
33+
elasticapm:
34+
35+
processors:
36+
elastictrace:
37+
38+
exporters:
39+
40+
elasticsearch:
41+
endpoint: http://elasticsearch:9200
42+
user: elastic
43+
password: elastic
44+
mapping:
45+
mode: otel
46+
logs_dynamic_index:
47+
enabled: true
48+
metrics_dynamic_index:
49+
enabled: true
50+
traces_dynamic_index:
51+
enabled: true
52+
flush:
53+
interval: 1s # improve responsiveness in example apps (default 30s)
54+
otlp/tracetest:
55+
endpoint: http://tracetest:4317
56+
tls:
57+
insecure: true
58+
59+
service:
60+
pipelines:
61+
traces:
62+
receivers: [otlp]
63+
processors: [elastictrace]
64+
exporters: [elasticapm, elasticsearch, otlp/tracetest]
65+
66+
metrics:
67+
receivers: [otlp]
68+
processors: []
69+
exporters: [elasticsearch]
70+
71+
metrics/aggregated:
72+
receivers: [elasticapm]
73+
processors: []
74+
exporters: [elasticsearch]
75+
76+
logs:
77+
receivers: [otlp]
78+
processors: []
79+
exporters: [elasticapm, elasticsearch]

example-apps/chatbot-rag-app/test/tracetest/resources/chatbot-test.yaml

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
type: Test
2+
spec:
3+
id: chatbot-e2e-test
4+
name: Chatbot Trace Test
5+
description: Test to verify the chatbot's response to the work from home policy question.
6+
trigger:
7+
type: http
8+
httpRequest:
9+
method: POST
10+
url: http://api-frontend:4000/api/chat
11+
body: "{\"question\": \"What is the work from home policy?\"}"
12+
headers:
13+
- key: Content-Type
14+
value: application/json
15+
specs:
16+
- selector: span[span.type="genai" name="chat gpt-4o-mini"]
17+
name: Calls OpenAI API
18+
assertions:
19+
- attr:gen_ai.usage.output_tokens > 0
20+
- attr:event.outcome = "success"
21+
- selector: span[span.type="db" name="search" db.system="elasticsearch" db.operation="search" db.elasticsearch.path_parts.index = "workplace-app-docs"]
22+
name: Searches docs index for RAG
23+
assertions:
24+
- attr:event.outcome = "success"
25+
- attr:db.elasticsearch.path_parts.index = "workplace-app-docs"
26+
- selector: span[span.type="db" name="index" db.system="elasticsearch" db.operation="index" db.elasticsearch.path_parts.index = "workplace-app-docs-chat-history"]
27+
name: Updates chat history
28+
assertions:
29+
- attr:event.outcome = "success"

example-apps/chatbot-rag-app/test/tracetest/resources/run.sh

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)