Check errors by identity, not by message text, in tests (closes #49)
check / check (push) Failing after 4s

Tests that asserted a failure by a fragment of its message now use
errors.Is: a refactor returning the wrong error, or wrapping with %v
instead of %w, now fails them. New tests return each exported error of
internal/vault and pkg/bip85 that no test returned, and check wrapped
causes (os.ErrNotExist, ErrMnemonicMismatch through GetSecret,
ErrInvalidPathComponent through DeriveBIP85Entropy). The 999-versions
test moves into package secret to name its unexported error. Checks of
errors no test can name keep their text; they are listed on the issue.

Model: opus-5-5
This commit is contained in:
2026-10-04 20:44:24 +00:00
parent 2adc588ace
commit 79bc021412
19 changed files with 401 additions and 256 deletions
+28 -43
View File
@@ -680,10 +680,10 @@ func test06GetSecret(t *testing.T, testMnemonic string, runSecret func(...string
require.NoError(t, err, "get secret should succeed")
assert.Equal(t, "password123", strings.TrimSpace(output), "should return correct secret value")
// Test that without mnemonic, we get an error
output, err = runSecret("get", "database/password")
require.Error(t, err, "get should fail without unlock method")
assert.Contains(t, output, "failed to unlock vault", "should indicate unlock failure")
// Test that without mnemonic, we get an error: the passphrase unlocker
// cannot ask for its passphrase, as the tests have no terminal
_, err = runSecret("get", "database/password")
require.ErrorIs(t, err, secret.ErrPassphraseNotRead, "get should fail without unlock method")
}
func test07AddSecretVersion(t *testing.T, tempDir, testMnemonic string, runSecret func(...string) (string, error), runSecretWithEnv func(map[string]string, ...string) (string, error), runSecretWithStdin func(string, map[string]string, ...string) (string, error)) {
@@ -839,12 +839,11 @@ func test09GetSpecificVersion(t *testing.T, tempDir, testMnemonic string, runSec
assert.Equal(t, "newpassword456", strings.TrimSpace(output), "should return new secret value without --version")
// An empty --version is not a version; it does not mean the current one
output, err = runSecretWithEnv(map[string]string{
_, err = runSecretWithEnv(map[string]string{
secret.EnvMnemonic: testMnemonic,
}, "get", "--version", "", "database/password")
require.Error(t, err, "get with an empty version should fail")
assert.Contains(t, output, "version '' not found", "should reject the empty version")
require.ErrorIs(t, err, vault.ErrVersionNotFound, "should reject the empty version")
}
func test10PromoteVersion(t *testing.T, tempDir, testMnemonic string, runSecret func(...string) (string, error), runSecretWithEnv func(map[string]string, ...string) (string, error)) {
@@ -1158,11 +1157,7 @@ func testInvalidSecretNames(t *testing.T, testMnemonic string, runSecretWithStdi
shouldFail := slices.Contains(definitelyInvalid, invalidName)
if shouldFail {
require.Error(t, err, "add '%s' should fail", invalidName)
if err != nil {
assert.Contains(t, output, "invalid secret name", "should indicate invalid name for '%s'", invalidName)
}
require.ErrorIs(t, err, vault.ErrInvalidSecretName, "add '%s' should fail", invalidName)
} else {
// For the slash cases and .hidden, they might succeed
// Just log what happened
@@ -1310,9 +1305,8 @@ func test12cCrossVaultMove(t *testing.T, testMnemonic string, runSecretWithEnv f
require.NoError(t, err, "add force/test in work should succeed")
// Move without force should fail
output, err = runSecretWithEnv(env, "move", "work:force/test", "default")
require.Error(t, err, "move without force should fail when dest exists")
assert.Contains(t, output, "already exists", "should indicate destination exists")
_, err = runSecretWithEnv(env, "move", "work:force/test", "default")
require.ErrorIs(t, err, vault.ErrSecretExists, "move without force should fail when dest exists")
// Move with force should succeed
output, err = runSecretWithEnv(env, "move", "--force", "work:force/test", "default")
@@ -1427,9 +1421,8 @@ func test14SwitchVault(t *testing.T, tempDir string, runSecret func(...string) (
require.NoError(t, err, "vault select default should succeed")
// Test selecting non-existent vault
output, err := runSecret("vault", "select", "nonexistent")
require.Error(t, err, "selecting non-existent vault should fail")
assert.Contains(t, output, "does not exist", "should indicate vault doesn't exist")
_, err = runSecret("vault", "select", "nonexistent")
require.ErrorIs(t, err, vault.ErrVaultNotFound, "selecting non-existent vault should fail")
}
func test15VaultIsolation(t *testing.T, testMnemonic string, runSecret func(...string) (string, error), runSecretWithEnv func(map[string]string, ...string) (string, error), runSecretWithStdin func(string, map[string]string, ...string) (string, error)) {
@@ -1450,11 +1443,10 @@ func test15VaultIsolation(t *testing.T, testMnemonic string, runSecret func(...s
require.NoError(t, err, "vault select work should succeed")
// Try to get the default-only secret (should fail)
output, err := runSecretWithEnv(map[string]string{
_, err = runSecretWithEnv(map[string]string{
secret.EnvMnemonic: testMnemonic,
}, "get", "default-only/secret")
require.Error(t, err, "should not be able to get default vault secret from work vault")
assert.Contains(t, output, "not found", "should indicate secret not found")
require.ErrorIs(t, err, vault.ErrSecretNotFound, "should not be able to get default vault secret from work vault")
// Add a unique secret to work vault
_, err = runSecretWithStdin("work-vault-secret", map[string]string{
@@ -1467,14 +1459,13 @@ func test15VaultIsolation(t *testing.T, testMnemonic string, runSecret func(...s
require.NoError(t, err, "vault select default should succeed")
// Try to get the work-only secret (should fail)
output, err = runSecretWithEnv(map[string]string{
_, err = runSecretWithEnv(map[string]string{
secret.EnvMnemonic: testMnemonic,
}, "get", "work-only/secret")
require.Error(t, err, "should not be able to get work vault secret from default vault")
assert.Contains(t, output, "not found", "should indicate secret not found")
require.ErrorIs(t, err, vault.ErrSecretNotFound, "should not be able to get work vault secret from default vault")
// Verify we can still get the default-only secret
output, err = runSecretWithEnv(map[string]string{
output, err := runSecretWithEnv(map[string]string{
secret.EnvMnemonic: testMnemonic,
}, "get", "default-only/secret")
require.NoError(t, err, "get default-only secret should succeed")
@@ -1586,11 +1577,10 @@ func test17ImportFromFile(t *testing.T, tempDir, testMnemonic string, runSecretW
// Just verify the import succeeded
// Test importing non-existent file
output, err = runSecretWithEnv(map[string]string{
_, err = runSecretWithEnv(map[string]string{
secret.EnvMnemonic: testMnemonic,
}, "import", "imported/nonexistent", "--source", "/nonexistent/file")
require.Error(t, err, "importing non-existent file should fail")
assert.Contains(t, output, "failed", "should indicate failure")
require.ErrorIs(t, err, os.ErrNotExist, "importing non-existent file should fail")
// Verify filesystem structure
defaultVaultDir := filepath.Join(tempDir, "vaults.d", "default")
@@ -1905,11 +1895,10 @@ func test23ErrorHandling(t *testing.T, tempDir, secretPath, testMnemonic string,
t.Helper()
// Get non-existent secret
output, err := runSecretWithEnv(map[string]string{
_, err := runSecretWithEnv(map[string]string{
secret.EnvMnemonic: testMnemonic,
}, "get", "nonexistent/secret")
require.Error(t, err, "get non-existent secret should fail")
assert.Contains(t, output, "not found", "should indicate secret not found")
require.ErrorIs(t, err, vault.ErrSecretNotFound, "get non-existent secret should fail")
// Add secret without mnemonic or unlocker
unsetMnemonic := os.Getenv(secret.EnvMnemonic)
@@ -1939,13 +1928,12 @@ func test23ErrorHandling(t *testing.T, tempDir, secretPath, testMnemonic string,
// Invalid secret names (already tested in test 12)
// Non-existent vault operations
output, err = runSecret("vault", "select", "nonexistent")
require.Error(t, err, "select non-existent vault should fail")
assert.Contains(t, output, "does not exist", "should indicate vault doesn't exist")
_, err = runSecret("vault", "select", "nonexistent")
require.ErrorIs(t, err, vault.ErrVaultNotFound, "select non-existent vault should fail")
// Import to non-existent vault with test passphrase
testPassphrase := "test-passphrase-123" // Define testPassphrase locally
output, err = runSecretWithEnv(map[string]string{
output, err := runSecretWithEnv(map[string]string{
secret.EnvMnemonic: testMnemonic,
secret.EnvUnlockPassphrase: testPassphrase,
}, "vault", "import", "nonexistent")
@@ -1953,11 +1941,10 @@ func test23ErrorHandling(t *testing.T, tempDir, secretPath, testMnemonic string,
assert.Contains(t, output, "does not exist", "should indicate vault doesn't exist")
// Get specific version that doesn't exist
output, err = runSecretWithEnv(map[string]string{
_, err = runSecretWithEnv(map[string]string{
secret.EnvMnemonic: testMnemonic,
}, "get", "--version", "99999999.999", "database/password")
require.Error(t, err, "get non-existent version should fail")
assert.Contains(t, output, "not found", "should indicate version not found")
require.ErrorIs(t, err, vault.ErrVersionNotFound, "get non-existent version should fail")
// Promote non-existent version
output, err = runSecretWithEnv(map[string]string{
@@ -2367,11 +2354,10 @@ func test30BackupRestore(t *testing.T, tempDir, secretPath, testMnemonic string,
assert.NotEmpty(t, output, "restored secret should have value")
// Verify post-backup secret is gone
output, err = runSecretWithEnv(map[string]string{
_, err = runSecretWithEnv(map[string]string{
secret.EnvMnemonic: testMnemonic,
}, "get", "post-backup/secret")
require.Error(t, err, "post-backup secret should not exist after restore")
assert.Contains(t, output, "not found", "should indicate secret not found")
require.ErrorIs(t, err, vault.ErrSecretNotFound, "post-backup secret should not exist after restore")
t.Log("Backup and restore completed successfully")
}
@@ -2436,8 +2422,7 @@ func test31EnvMnemonicUsesVaultDerivationIndex(t *testing.T, tempDir, secretPath
t.Logf("Output: %s", getOutput)
// This is the expected behavior with the current bug
require.Error(t, err, "get should fail due to wrong derivation index")
assert.Contains(t, getOutput, "derived public key does not match vault", "should indicate key derivation failure")
require.ErrorIs(t, err, vault.ErrMnemonicMismatch, "get should fail due to wrong derivation index")
// Document what should happen when the bug is fixed
t.Log("When the bug is fixed, GetValue should read vault metadata and use derivation index 1")