secrets/test/README.md (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# szecret Test Suite
Unit tests for the szecret secret management system.
## Running Tests
```bash
# Run all tests
./test/run.sh
# Run specific test files
./test/run.sh list get
# Run a single test file directly
./test/list.sh
```
## Test Structure
```
test/
├── common.sh # Shared utilities, setup/teardown, assertions
├── run.sh # Test runner entrypoint
├── create-local.sh # Tests for create-local command
├── edge-cases.sh # Edge case tests (special chars, unicode, etc.)
├── ensure.sh # Tests for ensure command
├── get.sh # Tests for get command
├── list.sh # Tests for list command
├── local.sh # Tests for put-local/get-local commands
├── main.sh # Tests for main entrypoint
├── paths.sh # Tests for where the store and public key are found
├── put.sh # Tests for put command
└── ready.sh # Tests for ready command
```
## Writing New Tests
### Basic test file template
```bash
#!/bin/bash
# Tests for <command> command
this_dir="$(cd "$(dirname "$0")" && pwd)"
source "${this_dir}/common.sh"
test_something() {
# Test code here
pass "description of what passed"
}
test_something_else() {
# Test code here
pass "another test"
}
run_tests() {
test_something
test_something_else
}
[[ "${BASH_SOURCE[0]}" == "${0}" ]] && run_tests
```
### Available helpers
From `common.sh`:
| Function | Description |
|----------|-------------|
| `szecret <cmd> [args]` | Run a szecret command via main.sh |
| `szecret_script <name> [args]` | Run a specific script directly (e.g., `szecret_script get secret-name`) |
| `pass <msg>` | Print green PASS message |
| `fail <msg>` | Print red FAIL message and exit |
| `skip <msg>` | Print yellow SKIP message |
| `assert_success <cmd>` | Assert command exits 0 |
| `assert_failure <cmd>` | Assert command exits non-zero |
| `assert_equals <expected> <actual> [msg]` | Assert string equality |
| `assert_contains <haystack> <needle> [msg]` | Assert string contains substring |
| `assert_file_exists <path> [msg]` | Assert file exists |
### Environment variables
Tests run in an isolated environment with these variables set:
| Variable | Description |
|----------|-------------|
| `TEST_DIR` | Temporary directory for test artifacts |
| `SZECRET_STORE` | Points to `$TEST_DIR/store` |
| `SZECRET_PUBLIC_KEY` | Points to test public key |
| `SZECRET_PRIVATE_KEY` | Points to test private key |
The test environment is created automatically when `common.sh` is sourced and cleaned up on exit.
## Design Notes
### Isolation
Each test file runs in its own subprocess with a fresh environment. This ensures tests don't interfere with each other. The `run.sh` runner executes each test file as a separate process.
### Auto-setup
The `common.sh` file automatically runs `setup` and registers the `teardown` trap when first sourced. A guard variable (`_SZECRET_TEST_INITIALIZED`) prevents duplicate initialization if common.sh is sourced multiple times.
### Configurable paths
The szecret scripts support these environment variables for testing:
- `SZECRET_STORE` - Override the store directory
- `SZECRET_PUBLIC_KEY` - Override the public key path
- `SZECRET_PRIVATE_KEY` - Override the private key path
This allows tests to use a temporary directory without affecting the real secret store.
## Known Limitations
### Trailing newlines
Bash command substitution `$()` strips trailing newlines. This means:
```bash
# This will lose the trailing newline
retrieved="$(szecret get my-secret)"
```
This is bash behavior, not a szecret bug. The encrypted data preserves trailing newlines correctly.
### Interactive commands
The `ensure` command prompts for private key input when run interactively. This flow isn't fully tested since it requires TTY input. The tests verify it fails gracefully in non-interactive mode.
### Binary data
The tests don't currently cover binary data. Secrets are expected to be text (the encryption handles binary, but shell pipelines may have issues with null bytes).
## Adding Tests for New Commands
1. Create `test/<command>.sh` following the template above
2. Make it executable: `chmod +x test/<command>.sh`
3. The runner will automatically discover and run it
## CI Integration
The test suite exits with code 0 on success, non-zero on failure. Example CI usage:
```bash
./secrets/test/run.sh || exit 1
```
|