140 lines
4.1 KiB
Go
140 lines
4.1 KiB
Go
|
|
package secretstore
|
||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/99designs/keyring"
|
||
|
|
|
||
|
|
"gitea.lclr.dev/AI/mcp-framework/manifest"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestOpenFromManifestUsesPolicyFromManifest(t *testing.T) {
|
||
|
|
var gotStartDir string
|
||
|
|
|
||
|
|
store, err := OpenFromManifest(OpenFromManifestOptions{
|
||
|
|
ServiceName: "email-mcp",
|
||
|
|
LookupEnv: func(name string) (string, bool) {
|
||
|
|
if name == "EMAIL_TOKEN" {
|
||
|
|
return "from-env", true
|
||
|
|
}
|
||
|
|
return "", false
|
||
|
|
},
|
||
|
|
ExecutableResolver: func() (string, error) {
|
||
|
|
return filepath.Join(string(filepath.Separator), "opt", "email-mcp", "bin", "email-mcp"), nil
|
||
|
|
},
|
||
|
|
ManifestLoader: func(startDir string) (manifest.File, string, error) {
|
||
|
|
gotStartDir = startDir
|
||
|
|
return manifest.File{
|
||
|
|
SecretStore: manifest.SecretStore{BackendPolicy: string(BackendEnvOnly)},
|
||
|
|
}, filepath.Join(startDir, manifest.DefaultFile), nil
|
||
|
|
},
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("OpenFromManifest returned error: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
wantDir := filepath.Join(string(filepath.Separator), "opt", "email-mcp", "bin")
|
||
|
|
if gotStartDir != wantDir {
|
||
|
|
t.Fatalf("manifest loader startDir = %q, want %q", gotStartDir, wantDir)
|
||
|
|
}
|
||
|
|
|
||
|
|
value, err := store.GetSecret("EMAIL_TOKEN")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("GetSecret returned error: %v", err)
|
||
|
|
}
|
||
|
|
if value != "from-env" {
|
||
|
|
t.Fatalf("GetSecret = %q, want from-env", value)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestOpenFromManifestFallsBackToAutoWhenManifestIsMissing(t *testing.T) {
|
||
|
|
withKeyringHooks(t, nil, func(cfg keyring.Config) (keyring.Keyring, error) {
|
||
|
|
t.Fatal("unexpected keyring open call")
|
||
|
|
return nil, nil
|
||
|
|
})
|
||
|
|
|
||
|
|
store, err := OpenFromManifest(OpenFromManifestOptions{
|
||
|
|
ServiceName: "email-mcp",
|
||
|
|
LookupEnv: func(name string) (string, bool) {
|
||
|
|
if name == "EMAIL_TOKEN" {
|
||
|
|
return "env-token", true
|
||
|
|
}
|
||
|
|
return "", false
|
||
|
|
},
|
||
|
|
ExecutableResolver: func() (string, error) {
|
||
|
|
return filepath.Join(string(filepath.Separator), "opt", "email-mcp", "bin", "email-mcp"), nil
|
||
|
|
},
|
||
|
|
ManifestLoader: func(string) (manifest.File, string, error) {
|
||
|
|
return manifest.File{}, "", os.ErrNotExist
|
||
|
|
},
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("OpenFromManifest returned error: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
value, err := store.GetSecret("EMAIL_TOKEN")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("GetSecret returned error: %v", err)
|
||
|
|
}
|
||
|
|
if value != "env-token" {
|
||
|
|
t.Fatalf("GetSecret = %q, want env-token", value)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestOpenFromManifestReturnsExplicitErrorForInvalidManifestPolicy(t *testing.T) {
|
||
|
|
_, err := OpenFromManifest(OpenFromManifestOptions{
|
||
|
|
ServiceName: "email-mcp",
|
||
|
|
ExecutableResolver: func() (string, error) {
|
||
|
|
return filepath.Join(string(filepath.Separator), "opt", "email-mcp", "bin", "email-mcp"), nil
|
||
|
|
},
|
||
|
|
ManifestLoader: func(startDir string) (manifest.File, string, error) {
|
||
|
|
return manifest.File{
|
||
|
|
SecretStore: manifest.SecretStore{BackendPolicy: "totally-invalid"},
|
||
|
|
}, filepath.Join(startDir, manifest.DefaultFile), nil
|
||
|
|
},
|
||
|
|
})
|
||
|
|
if err == nil {
|
||
|
|
t.Fatal("expected error")
|
||
|
|
}
|
||
|
|
if !errors.Is(err, ErrInvalidBackendPolicy) {
|
||
|
|
t.Fatalf("error = %v, want ErrInvalidBackendPolicy", err)
|
||
|
|
}
|
||
|
|
if !strings.Contains(err.Error(), "secret_store.backend_policy") {
|
||
|
|
t.Fatalf("error = %v, want manifest policy context", err)
|
||
|
|
}
|
||
|
|
if !strings.Contains(err.Error(), manifest.DefaultFile) {
|
||
|
|
t.Fatalf("error = %v, want manifest path", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestOpenFromManifestReturnsExecutableResolutionError(t *testing.T) {
|
||
|
|
execErr := errors.New("boom")
|
||
|
|
_, err := OpenFromManifest(OpenFromManifestOptions{
|
||
|
|
ExecutableResolver: func() (string, error) {
|
||
|
|
return "", execErr
|
||
|
|
},
|
||
|
|
})
|
||
|
|
if !errors.Is(err, execErr) {
|
||
|
|
t.Fatalf("error = %v, want wrapped executable resolver error", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestOpenFromManifestReturnsManifestLoaderError(t *testing.T) {
|
||
|
|
loadErr := errors.New("cannot parse manifest")
|
||
|
|
_, err := OpenFromManifest(OpenFromManifestOptions{
|
||
|
|
ExecutableResolver: func() (string, error) {
|
||
|
|
return filepath.Join(string(filepath.Separator), "opt", "email-mcp", "bin", "email-mcp"), nil
|
||
|
|
},
|
||
|
|
ManifestLoader: func(string) (manifest.File, string, error) {
|
||
|
|
return manifest.File{}, "", loadErr
|
||
|
|
},
|
||
|
|
})
|
||
|
|
if !errors.Is(err, loadErr) {
|
||
|
|
t.Fatalf("error = %v, want wrapped manifest loader error", err)
|
||
|
|
}
|
||
|
|
}
|