Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions tests/k6/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules/
dist/
results/
*.log
.env
.idea/
.vscode/
.DS_Store
8 changes: 8 additions & 0 deletions tests/k6/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"semi": true,
"trailingComma": "all",
"printWidth": 100,
"singleQuote": true,
"tabWidth": 2,
"arrowParens": "always"
}
59 changes: 59 additions & 0 deletions tests/k6/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.PHONY: help install build test smoke load stress reports clean

.DEFAULT_GOAL := help

API_URL ?= http://127.0.0.1:4340

help:
@echo "Acropolis K6 Performance Tests"
@echo ""
@echo "Usage: make [target]"
@echo ""
@echo "Available targets:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " %-15s %s\n", $$1, $$2}'

install: ## Install dependencies
@echo "Installing dependencies..."
npm install

build: ## Build TypeScript files
@echo "Building TypeScript..."
npm run build

results-dir: ## Create results directory
@echo "Creating results directory..."
@mkdir -p results
@echo "✅ Results directory created"

test-smoke: build results-dir ## Run smoke test only (1 minute)
@echo "Running Smoke Test..."
@export API_URL=$(API_URL) && k6 run --out json=results/smoke-$$(date +%Y%m%d-%H%M%S).json dist/smoke.test.js

test-load: build results-dir ## Run load test only (16 minutes)
@echo "Running Load Test..."
@export API_URL=$(API_URL) && k6 run --out json=results/load-$$(date +%Y%m%d-%H%M%S).json dist/load.test.js

test-stress: build results-dir ## Run stress test only (13 minutes)
@echo "Running Stress Test..."
@export API_URL=$(API_URL) && k6 run --out json=results/stress-$$(date +%Y%m%d-%H%M%S).json dist/stress.test.js

test-soak: build results-dir ## Run soak test only (2 hours 10 minutes)
@echo "Running Soak Test..."
@export API_URL=$(API_URL) && k6 run --out json=results/soak-$$(date +%Y%m%d-%H%M%S).json dist/soak.test.js

test-all: ## Run all performance tests (30 minutes total)
@chmod +x scripts/run-all.sh
@API_URL=$(API_URL) scripts/run-all.sh

clean: ## Remove results directory
@echo "Cleaning results..."
rm -rf results/
@echo "✅ Results cleaned"

clean-build: ## Remove build artifacts
@echo "Cleaning build artifacts..."
rm -rf dist/
@echo "✅ Build artifacts cleaned"

clean-all: clean clean-build ## Remove all generated files
@echo "✅ All generated files cleaned"
136 changes: 136 additions & 0 deletions tests/k6/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Acropolis K6s Performance Tests

Performance testing suite for the Acropolis Cardano Node leveraging [Grafana's k6 tool](https://github.com/grafana/k6).

## Prerequisites

Before running the tests, you'll need to install Node.js dependencies and k6.

### Install Node Dependencies

```bash
npm install
```

## Installing k6

For more detailed instructions on installing k6, please refer to the [documentation here](https://grafana.com/docs/k6/latest/set-up/install-k6/#install-k6).


### macOS

Using Homebrew:

```bash
brew install k6
```

### Linux

#### Debian/Ubuntu

```bash
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg \
--keyserver hkp://keyserver.ubuntu.com:80 \
--recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69

echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | \
sudo tee /etc/apt/sources.list.d/k6.list

sudo apt-get update
sudo apt-get install k6
```

#### Fedora/CentOS

```bash
sudo dnf install https://dl.k6.io/rpm/repo.rpm
sudo dnf install k6
```

### Verify Installation

Confirm k6 is installed correctly:

```bash
k6 version
```

## Project Structure

```
performance-tests/
├── src/
│ ├── tests/ # Test configurations (smoke, load, stress, soak)
│ ├── scenarios/ # Endpoint-specific test scenarios
│ ├── config/ # Endpoints, test data, thresholds
│ └── utils/ # Helpers, metrics, checks
├── scripts/ # Run scripts
└── Makefile # Convenient test commands
```

## Usage

See the `Makefile` for all available commands:

```bash
# Build TypeScript
make build

# Run individual tests
make test-smoke # Quick validation (1 minute)
make test-load # Sustained load (16 minutes)
make test-stress # Find breaking point (13 minutes)
make test-soak # Long-running stability (2+ hours)

# Run all tests
make test-all

# Clean build artifacts
make clean
```

### Environment Variables

Configure the API endpoint:

```bash
export API_URL="http://127.0.0.1:4340"
make test-smoke
```

Or inline:

```bash
API_URL="http://127.0.0.1:4340" make test-load
```

## Results

Test results are saved as JSON files in the `results/` directory with timestamps. These can
be imported into Grafana for analysis.

## Customization

### Modify Load Patterns

Edit test files in `src/tests/` to adjust:
- Virtual user counts
- Ramp-up/ramp-down durations
- Test duration
- Traffic distribution weights

### Add New Endpoints

1. Add endpoint definition to `src/config/endpoints.ts`
2. Add test data to `src/config/test-data.ts`
3. Create scenario function in `src/scenarios/`
4. Import and use in test files

### Adjust Thresholds

Edit `src/config/thresholds.ts` to modify performance expectations.


---
33 changes: 33 additions & 0 deletions tests/k6/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import prettier from 'eslint-config-prettier';

export default [
js.configs.recommended,
...tseslint.configs.recommended,
prettier,
{
files: ['**/*.ts', '**/*.js'],
languageOptions: {
ecmaVersion: 2020,
sourceType: 'module',
parser: tseslint.parser,
parserOptions: {
project: './tsconfig.json',
},
},
rules: {
'max-len': ['warn', { code: 100, ignoreStrings: true, ignoreTemplateLiterals: true }],
'comma-dangle': ['error', 'always-multiline'],
quotes: ['error', 'single', { avoidEscape: true }],
semi: ['error', 'always'],
indent: ['error', 2, { SwitchCase: 1 }],
'no-console': 'off', // K6 uses console.log
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/explicit-function-return-type': 'off',
},
},
{
ignores: ['dist/', 'node_modules/', '*.config.js', 'webpack.config.js'],
},
];
Loading