Adds basic tests.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -10,3 +10,6 @@ CLAUDE.md
|
||||
# Wild Cloud
|
||||
**/config/secrets.env
|
||||
**/config/config.env
|
||||
|
||||
# Test directory - ignore temporary files
|
||||
test/tmp
|
||||
|
9
.gitmodules
vendored
Normal file
9
.gitmodules
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
[submodule "test/bats"]
|
||||
path = test/bats
|
||||
url = https://github.com/bats-core/bats-core.git
|
||||
[submodule "test/test_helper/bats-support"]
|
||||
path = test/test_helper/bats-support
|
||||
url = https://github.com/bats-core/bats-support.git
|
||||
[submodule "test/test_helper/bats-assert"]
|
||||
path = test/test_helper/bats-assert
|
||||
url = https://github.com/bats-core/bats-assert.git
|
104
test/README.md
Normal file
104
test/README.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Test Directory
|
||||
|
||||
This directory is used for testing wild-cloud functionality using the Bats testing framework.
|
||||
|
||||
## Contents
|
||||
- `test_helper.bash` - Shared Bats test setup and utilities
|
||||
- `test_helper/` - Bats framework extensions (bats-support, bats-assert)
|
||||
- `bats/` - Bats core framework (git submodule)
|
||||
- `fixtures/` - Test data and sample configuration files
|
||||
- `*.bats` - Bats test files for different components
|
||||
- `run_bats_tests.sh` - Runs the complete Bats test suite
|
||||
- `tmp/` - Temporary test projects (auto-created/cleaned)
|
||||
|
||||
## Test Files
|
||||
|
||||
### `test_common_functions.bats`
|
||||
Tests the core functions in `wild-common.sh`:
|
||||
- `find_wc_home()` - Project root detection
|
||||
- `init_wild_env()` - Environment setup
|
||||
- `check_wild_directory()` - Project validation
|
||||
- Print functions and utilities
|
||||
|
||||
### `test_project_detection.bats`
|
||||
Tests project detection and script execution:
|
||||
- Script execution from various directory levels
|
||||
- Environment variable setup from different paths
|
||||
- Proper failure outside project directories
|
||||
|
||||
### `test_config_functions.bats`
|
||||
Tests configuration and secret access:
|
||||
- `get_current_config()` function
|
||||
- `get_current_secret()` function
|
||||
- Configuration access from subdirectories
|
||||
- Fixture data usage
|
||||
|
||||
## Running Tests
|
||||
|
||||
```bash
|
||||
# Initialize git submodules (first time only)
|
||||
git submodule update --init --recursive
|
||||
|
||||
# Run all Bats tests
|
||||
./run_bats_tests.sh
|
||||
|
||||
# Run individual test files
|
||||
./bats/bin/bats test_common_functions.bats
|
||||
./bats/bin/bats test_project_detection.bats
|
||||
./bats/bin/bats test_config_functions.bats
|
||||
|
||||
# Test from subdirectory (should work)
|
||||
cd deep/nested/path
|
||||
../../../bin/wild-cluster-node-up --help
|
||||
```
|
||||
|
||||
## Fixtures
|
||||
|
||||
The `fixtures/` directory contains:
|
||||
- `sample-config.yaml` - Complete test configuration
|
||||
- `sample-secrets.yaml` - Test secrets file
|
||||
|
||||
## Adding New Tests
|
||||
|
||||
1. Create `test_<feature>.bats` following the Bats pattern:
|
||||
```bash
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load 'test_helper'
|
||||
|
||||
setup() {
|
||||
setup_test_project "feature-test"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_test_project "feature-test"
|
||||
}
|
||||
|
||||
@test "feature description" {
|
||||
# Your test here using Bats assertions
|
||||
run some_command
|
||||
assert_success
|
||||
assert_output "expected output"
|
||||
}
|
||||
```
|
||||
|
||||
2. Add test data to `fixtures/` if needed
|
||||
|
||||
3. The Bats runner will automatically discover and run new tests
|
||||
|
||||
## Common Test Functions
|
||||
|
||||
From `test_helper.bash`:
|
||||
- `setup_test_project "name"` - Creates test project in `tmp/`
|
||||
- `teardown_test_project "name"` - Removes test project
|
||||
- `create_test_project "name" [with-config]` - Creates additional test projects
|
||||
- `remove_test_project "name"` - Removes additional test projects
|
||||
|
||||
## Bats Assertions
|
||||
|
||||
Available through bats-assert:
|
||||
- `assert_success` / `assert_failure` - Check command exit status
|
||||
- `assert_output "text"` - Check exact output
|
||||
- `assert_output --partial "text"` - Check output contains text
|
||||
- `assert_equal "$actual" "$expected"` - Check equality
|
||||
- `assert [ condition ]` - General assertions
|
1
test/bats
Submodule
1
test/bats
Submodule
Submodule test/bats added at 855844b834
72
test/fixtures/sample-config.yaml
vendored
Normal file
72
test/fixtures/sample-config.yaml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
wildcloud:
|
||||
root: /test/path/wild-cloud
|
||||
operator:
|
||||
email: test@example.com
|
||||
cloud:
|
||||
domain: test.example.com
|
||||
internalDomain: internal.test.example.com
|
||||
dockerRegistryHost: docker-registry.internal.test.example.com
|
||||
tz: America/New_York
|
||||
router:
|
||||
dynamicDns: test.ddns.com
|
||||
ip: 192.168.100.1
|
||||
nfs:
|
||||
host: test-nfs
|
||||
mediaPath: /data/media
|
||||
storageCapacity: 100Gi
|
||||
dns:
|
||||
ip: 192.168.100.50
|
||||
externalResolver: 8.8.8.8
|
||||
dhcpRange: 192.168.100.100,192.168.100.200
|
||||
dnsmasq:
|
||||
interface: eth0
|
||||
username: testuser
|
||||
cluster:
|
||||
name: test-cluster
|
||||
ipAddressPool: 192.168.100.240-192.168.100.249
|
||||
loadBalancerIp: 192.168.100.240
|
||||
kubernetes:
|
||||
config: /home/testuser/.kube/config
|
||||
context: default
|
||||
dashboard:
|
||||
adminUsername: admin
|
||||
certManager:
|
||||
namespace: cert-manager
|
||||
cloudflare:
|
||||
domain: example.com
|
||||
ownerId: test-cluster-owner
|
||||
externalDns:
|
||||
ownerId: test-cluster-owner
|
||||
dockerRegistry:
|
||||
storage: 10Gi
|
||||
nodes:
|
||||
talos:
|
||||
version: v1.10.4
|
||||
schematicId: test123456789abcdef
|
||||
control:
|
||||
vip: 192.168.100.200
|
||||
active:
|
||||
192.168.100.201:
|
||||
maintenanceIp: 192.168.100.131
|
||||
interface: eth0
|
||||
disk: /dev/sda
|
||||
control: "true"
|
||||
192.168.100.202:
|
||||
interface: eth0
|
||||
disk: /dev/nvme0n1
|
||||
control: "true"
|
||||
192.168.100.210:
|
||||
interface: eth0
|
||||
disk: /dev/sda
|
||||
control: "false"
|
||||
apps:
|
||||
postgres:
|
||||
database: postgres
|
||||
user: postgres
|
||||
storage: 10Gi
|
||||
image: pgvector/pgvector:pg15
|
||||
timezone: America/New_York
|
||||
redis:
|
||||
image: redis:alpine
|
||||
timezone: UTC
|
||||
port: 6379
|
14
test/fixtures/sample-secrets.yaml
vendored
Normal file
14
test/fixtures/sample-secrets.yaml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
operator:
|
||||
cloudflareApiToken: test_api_token_123456789
|
||||
cluster:
|
||||
dashboard:
|
||||
adminPassword: test_admin_password_123
|
||||
certManager:
|
||||
cloudflare:
|
||||
apiToken: test_cf_token_456789
|
||||
apps:
|
||||
postgres:
|
||||
password: test_postgres_password_789
|
||||
databases:
|
||||
immich:
|
||||
password: test_immich_db_password_321
|
25
test/run_bats_tests.sh
Executable file
25
test/run_bats_tests.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# run_bats_tests.sh
|
||||
# Run all Bats tests in the test directory
|
||||
|
||||
set -e
|
||||
|
||||
# Get the directory where this script is located
|
||||
TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Check if bats is available
|
||||
if [ ! -f "$TEST_DIR/bats/bin/bats" ]; then
|
||||
echo "Error: Bats not found. Make sure git submodules are initialized:"
|
||||
echo " git submodule update --init --recursive"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Running Wild Cloud Bats Test Suite..."
|
||||
echo "======================================"
|
||||
|
||||
# Run all .bats files
|
||||
"$TEST_DIR/bats/bin/bats" "$TEST_DIR"/*.bats
|
||||
|
||||
echo ""
|
||||
echo "All tests completed!"
|
86
test/test_common_functions.bats
Normal file
86
test/test_common_functions.bats
Normal file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
# test_common_functions.bats
|
||||
# Tests for the wild-common.sh library functions
|
||||
|
||||
load 'test_helper'
|
||||
|
||||
setup() {
|
||||
setup_test_project "common-test"
|
||||
cd "$TEST_PROJECT_DIR"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_test_project "common-test"
|
||||
}
|
||||
|
||||
@test "find_wc_home from project root" {
|
||||
cd "$TEST_PROJECT_DIR"
|
||||
WC_HOME_RESULT=$(find_wc_home)
|
||||
assert_equal "$WC_HOME_RESULT" "$TEST_PROJECT_DIR"
|
||||
}
|
||||
|
||||
@test "find_wc_home from nested subdirectory" {
|
||||
mkdir -p "$TEST_PROJECT_DIR/deep/nested/path"
|
||||
cd "$TEST_PROJECT_DIR/deep/nested/path"
|
||||
WC_HOME_RESULT=$(find_wc_home)
|
||||
assert_equal "$WC_HOME_RESULT" "$TEST_PROJECT_DIR"
|
||||
}
|
||||
|
||||
@test "find_wc_home when no project found" {
|
||||
cd /tmp
|
||||
run find_wc_home
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "init_wild_env sets WC_HOME correctly" {
|
||||
mkdir -p "$TEST_PROJECT_DIR/deep/nested"
|
||||
cd "$TEST_PROJECT_DIR/deep/nested"
|
||||
unset WC_HOME WC_ROOT
|
||||
init_wild_env
|
||||
assert_equal "$WC_HOME" "$TEST_PROJECT_DIR"
|
||||
}
|
||||
|
||||
@test "init_wild_env sets WC_ROOT correctly" {
|
||||
cd "$TEST_PROJECT_DIR"
|
||||
unset WC_HOME WC_ROOT
|
||||
init_wild_env
|
||||
# WC_ROOT is set (value depends on test execution context)
|
||||
assert [ -n "$WC_ROOT" ]
|
||||
}
|
||||
|
||||
@test "check_wild_directory passes when in project" {
|
||||
cd "$TEST_PROJECT_DIR"
|
||||
run check_wild_directory
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "print functions work correctly" {
|
||||
cd "$TEST_PROJECT_DIR"
|
||||
run bash -c '
|
||||
source "$PROJECT_ROOT/bin/wild-common.sh"
|
||||
print_header "Test Header"
|
||||
print_info "Test info message"
|
||||
print_warning "Test warning message"
|
||||
print_success "Test success message"
|
||||
print_error "Test error message"
|
||||
'
|
||||
assert_success
|
||||
assert_output --partial "Test Header"
|
||||
assert_output --partial "Test info message"
|
||||
}
|
||||
|
||||
@test "command_exists works for existing command" {
|
||||
run command_exists "bash"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "command_exists fails for nonexistent command" {
|
||||
run command_exists "nonexistent-command-xyz"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "generate_random_string produces correct length" {
|
||||
RANDOM_STR=$(generate_random_string 16)
|
||||
assert_equal "${#RANDOM_STR}" "16"
|
||||
}
|
59
test/test_config_functions.bats
Normal file
59
test/test_config_functions.bats
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
# test_config_functions.bats
|
||||
# Tests for config and secret access functions
|
||||
|
||||
load 'test_helper'
|
||||
|
||||
setup() {
|
||||
setup_test_project "config-test"
|
||||
cd "$TEST_PROJECT_DIR"
|
||||
init_wild_env
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_test_project "config-test"
|
||||
}
|
||||
|
||||
@test "get_current_config with existing config" {
|
||||
CLUSTER_NAME=$(get_current_config "cluster.name")
|
||||
assert_equal "$CLUSTER_NAME" "test-cluster"
|
||||
}
|
||||
|
||||
@test "get_current_config with nested path" {
|
||||
VIP=$(get_current_config "cluster.nodes.control.vip")
|
||||
assert_equal "$VIP" "192.168.100.200"
|
||||
}
|
||||
|
||||
@test "get_current_config with non-existent key" {
|
||||
NONEXISTENT=$(get_current_config "nonexistent.key")
|
||||
assert_equal "$NONEXISTENT" ""
|
||||
}
|
||||
|
||||
@test "active nodes configuration access - interface" {
|
||||
CONTROL_NODE_INTERFACE=$(get_current_config "cluster.nodes.active.\"192.168.100.201\".interface")
|
||||
assert_equal "$CONTROL_NODE_INTERFACE" "eth0"
|
||||
}
|
||||
|
||||
@test "active nodes configuration access - maintenance IP" {
|
||||
MAINTENANCE_IP=$(get_current_config "cluster.nodes.active.\"192.168.100.201\".maintenanceIp")
|
||||
assert_equal "$MAINTENANCE_IP" "192.168.100.131"
|
||||
}
|
||||
|
||||
@test "get_current_secret function" {
|
||||
# Create temporary secrets file for testing
|
||||
cp "$TEST_DIR/fixtures/sample-secrets.yaml" "$TEST_PROJECT_DIR/secrets.yaml"
|
||||
|
||||
SECRET_VAL=$(get_current_secret "operator.cloudflareApiToken")
|
||||
assert_equal "$SECRET_VAL" "test_api_token_123456789"
|
||||
}
|
||||
|
||||
@test "config access from subdirectory" {
|
||||
mkdir -p "$TEST_PROJECT_DIR/config-subdir"
|
||||
cd "$TEST_PROJECT_DIR/config-subdir"
|
||||
unset WC_HOME WC_ROOT
|
||||
init_wild_env
|
||||
|
||||
SUBDIR_CLUSTER=$(get_current_config "cluster.name")
|
||||
assert_equal "$SUBDIR_CLUSTER" "test-cluster"
|
||||
}
|
63
test/test_helper.bash
Normal file
63
test/test_helper.bash
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# test_helper.bash
|
||||
# Common setup and utilities for bats tests
|
||||
|
||||
# Load bats helpers
|
||||
load 'test_helper/bats-support/load'
|
||||
load 'test_helper/bats-assert/load'
|
||||
|
||||
# Test environment variables
|
||||
export TEST_DIR="$(cd "$(dirname "${BATS_TEST_FILENAME}")" && pwd)"
|
||||
export PROJECT_ROOT="$(dirname "$TEST_DIR")"
|
||||
export TMP_DIR="$TEST_DIR/tmp"
|
||||
|
||||
# Set up test environment
|
||||
setup_test_project() {
|
||||
local project_name="${1:-test-project}"
|
||||
|
||||
# Create tmp directory
|
||||
mkdir -p "$TMP_DIR"
|
||||
|
||||
# Create test project
|
||||
export TEST_PROJECT_DIR="$TMP_DIR/$project_name"
|
||||
mkdir -p "$TEST_PROJECT_DIR/.wildcloud"
|
||||
|
||||
# Copy fixture config if it exists
|
||||
if [ -f "$TEST_DIR/fixtures/sample-config.yaml" ]; then
|
||||
cp "$TEST_DIR/fixtures/sample-config.yaml" "$TEST_PROJECT_DIR/config.yaml"
|
||||
fi
|
||||
|
||||
# Source wild-common.sh
|
||||
source "$PROJECT_ROOT/bin/wild-common.sh"
|
||||
}
|
||||
|
||||
# Clean up test environment
|
||||
teardown_test_project() {
|
||||
local project_name="${1:-test-project}"
|
||||
|
||||
if [ -n "$TMP_DIR" ] && [ -d "$TMP_DIR" ]; then
|
||||
rm -rf "$TMP_DIR/$project_name"
|
||||
fi
|
||||
}
|
||||
|
||||
# Create additional test project
|
||||
create_test_project() {
|
||||
local project_name="$1"
|
||||
local project_dir="$TMP_DIR/$project_name"
|
||||
|
||||
mkdir -p "$project_dir/.wildcloud"
|
||||
|
||||
# Copy fixture config if requested
|
||||
if [ $# -gt 1 ] && [ "$2" = "with-config" ]; then
|
||||
cp "$TEST_DIR/fixtures/sample-config.yaml" "$project_dir/config.yaml"
|
||||
fi
|
||||
|
||||
echo "$project_dir"
|
||||
}
|
||||
|
||||
# Remove additional test project
|
||||
remove_test_project() {
|
||||
local project_name="$1"
|
||||
rm -rf "$TMP_DIR/$project_name"
|
||||
}
|
1
test/test_helper/bats-assert
Submodule
1
test/test_helper/bats-assert
Submodule
Submodule test/test_helper/bats-assert added at 912a98804e
1
test/test_helper/bats-support
Submodule
1
test/test_helper/bats-support
Submodule
Submodule test/test_helper/bats-support added at 0ad082d459
101
test/test_project_detection.bats
Normal file
101
test/test_project_detection.bats
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
# test_project_detection.bats
|
||||
# Tests for wild-cloud project detection from various directory structures
|
||||
|
||||
load 'test_helper'
|
||||
|
||||
setup() {
|
||||
setup_test_project "detection-test"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_test_project "detection-test"
|
||||
}
|
||||
|
||||
@test "script execution from project root" {
|
||||
cd "$TEST_PROJECT_DIR"
|
||||
run "$PROJECT_ROOT/bin/wild-cluster-node-up" --help
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "script execution from nested subdirectory" {
|
||||
mkdir -p "$TEST_PROJECT_DIR/deep/very/nested/path"
|
||||
cd "$TEST_PROJECT_DIR/deep/very/nested/path"
|
||||
run "$PROJECT_ROOT/bin/wild-cluster-node-up" --help
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "wild-cluster-node-up works from subdirectory" {
|
||||
mkdir -p "$TEST_PROJECT_DIR/subdir"
|
||||
cd "$TEST_PROJECT_DIR/subdir"
|
||||
run "$PROJECT_ROOT/bin/wild-cluster-node-up" --help
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "wild-setup works from subdirectory" {
|
||||
mkdir -p "$TEST_PROJECT_DIR/subdir"
|
||||
cd "$TEST_PROJECT_DIR/subdir"
|
||||
run "$PROJECT_ROOT/bin/wild-setup" --help
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "wild-setup-cluster works from subdirectory" {
|
||||
mkdir -p "$TEST_PROJECT_DIR/subdir"
|
||||
cd "$TEST_PROJECT_DIR/subdir"
|
||||
run "$PROJECT_ROOT/bin/wild-setup-cluster" --help
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "wild-cluster-config-generate works from subdirectory" {
|
||||
mkdir -p "$TEST_PROJECT_DIR/subdir"
|
||||
cd "$TEST_PROJECT_DIR/subdir"
|
||||
run "$PROJECT_ROOT/bin/wild-cluster-config-generate" --help
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "config access from subdirectories" {
|
||||
mkdir -p "$TEST_PROJECT_DIR/config-test"
|
||||
cd "$TEST_PROJECT_DIR/config-test"
|
||||
|
||||
# Set up environment like the scripts do
|
||||
unset WC_HOME WC_ROOT
|
||||
init_wild_env
|
||||
|
||||
CLUSTER_NAME=$("$PROJECT_ROOT/bin/wild-config" cluster.name 2>/dev/null)
|
||||
assert_equal "$CLUSTER_NAME" "test-cluster"
|
||||
}
|
||||
|
||||
@test "environment variables from project root" {
|
||||
cd "$TEST_PROJECT_DIR"
|
||||
unset WC_HOME WC_ROOT
|
||||
source "$PROJECT_ROOT/bin/wild-common.sh"
|
||||
init_wild_env
|
||||
|
||||
assert_equal "$WC_HOME" "$TEST_PROJECT_DIR"
|
||||
assert [ -n "$WC_ROOT" ]
|
||||
}
|
||||
|
||||
@test "environment variables from nested directory" {
|
||||
mkdir -p "$TEST_PROJECT_DIR/deep/very"
|
||||
cd "$TEST_PROJECT_DIR/deep/very"
|
||||
unset WC_HOME WC_ROOT
|
||||
source "$PROJECT_ROOT/bin/wild-common.sh"
|
||||
init_wild_env
|
||||
|
||||
assert_equal "$WC_HOME" "$TEST_PROJECT_DIR"
|
||||
assert [ -n "$WC_ROOT" ]
|
||||
}
|
||||
|
||||
@test "scripts fail gracefully outside project" {
|
||||
# Create a temporary directory without .wildcloud
|
||||
TEMP_NO_PROJECT=$(create_test_project "no-wildcloud")
|
||||
rm -rf "$TEMP_NO_PROJECT/.wildcloud"
|
||||
cd "$TEMP_NO_PROJECT"
|
||||
|
||||
# The script should fail because check_wild_directory won't find .wildcloud
|
||||
run "$PROJECT_ROOT/bin/wild-cluster-node-up" 192.168.1.1 --dry-run
|
||||
assert_failure
|
||||
|
||||
remove_test_project "no-wildcloud"
|
||||
}
|
Reference in New Issue
Block a user