summaryrefslogtreecommitdiff
path: root/secrets/test/README.md
blob: 49d70b2a1e234a7dbf838ac1db8e4deceac063c1 (plain)
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
```