test: Phase 3 comprehensive test coverage — 105 tests, zero race conditions

- Add test/crypto/ (19 tests): AES-256-GCM encrypt/decrypt, PBKDF2, IsEncrypted, HashPassword
- Add test/knownhosts/ (14 tests): TOFU verify, MITM detection, CRUD, persistence
- Add test/storage/ (20 tests): KeyPair/Snippet CRUD, encryption, MergeStrategy
- Add test/config/ (9 tests): config lifecycle, path getters
- Add test/tui/ (10 tests): WrapFooter, ClampWidth, TruncateStr
- Fix knownhosts deadlock: Add/Remove use saveInternal()
- Export responsive.go functions for testing
- Add docs/TEST_PLAN.md with full scenario documentation

Coverage: crypto 0%→100%, knownhosts 0%→100%, storage 40%→90%, config 22%→80%, tui 40%→70%
This commit is contained in:
swanadiva
2026-06-29 12:05:02 +07:00
parent 408681c8e4
commit 4a8b4a2bc4
10 changed files with 1439 additions and 7 deletions
+9 -4
View File
@@ -72,9 +72,14 @@ func (kh *KnownHosts) load() error {
// Save writes the known_hosts file
func (kh *KnownHosts) Save() error {
kh.mu.RLock()
defer kh.mu.RUnlock()
kh.mu.Lock()
defer kh.mu.Unlock()
return kh.saveInternal()
}
// saveInternal writes the known_hosts file without locking (caller must hold lock)
func (kh *KnownHosts) saveInternal() error {
var hosts []*HostKey
for _, h := range kh.hosts {
hosts = append(hosts, h)
@@ -124,7 +129,7 @@ func (kh *KnownHosts) Add(hostname string, port int, remoteKey cryptossh.PublicK
AddedAt: time.Now(),
}
return kh.Save()
return kh.saveInternal()
}
// Remove removes a host key
@@ -135,7 +140,7 @@ func (kh *KnownHosts) Remove(hostname string, port int) error {
key := fmt.Sprintf("%s:%d", hostname, port)
delete(kh.hosts, key)
return kh.Save()
return kh.saveInternal()
}
// Get returns the stored host key for a given host