test(soteria): tighten edge-path coverage

This commit is contained in:
codex 2026-04-20 19:53:58 -03:00
parent 8d4dd26d14
commit 683014443d
5 changed files with 111 additions and 3 deletions

View File

@ -2,6 +2,7 @@ package k8s
import ( import (
"context" "context"
"errors"
"strings" "strings"
"testing" "testing"
@ -11,7 +12,9 @@ import (
batchv1 "k8s.io/api/batch/v1" batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
k8sfake "k8s.io/client-go/kubernetes/fake" k8sfake "k8s.io/client-go/kubernetes/fake"
k8stesting "k8s.io/client-go/testing"
) )
func TestJobSupportHelpersCoverFallbackAndFormattingBranches(t *testing.T) { func TestJobSupportHelpersCoverFallbackAndFormattingBranches(t *testing.T) {
@ -130,4 +133,19 @@ func TestCopySecretAndBindSecretToJobCoverErrorBranches(t *testing.T) {
if secret.Namespace != "apps" || secret.Name != "copy" || secret.Labels["app"] != "soteria" { if secret.Namespace != "apps" || secret.Name != "copy" || secret.Labels["app"] != "soteria" {
t.Fatalf("expected copied secret in destination namespace, got %#v", secret) t.Fatalf("expected copied secret in destination namespace, got %#v", secret)
} }
clientset := k8sfake.NewSimpleClientset(
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Name: "src", Namespace: "shared"},
Type: corev1.SecretTypeOpaque,
Data: map[string][]byte{"token": []byte("atlas")},
},
)
clientset.PrependReactor("create", "secrets", func(action k8stesting.Action) (bool, runtime.Object, error) {
return true, nil, errors.New("create secret exploded")
})
client = &Client{Clientset: clientset}
if _, err := client.copySecret(context.Background(), "shared", "src", "apps", "copy", nil); err == nil || !strings.Contains(err.Error(), "create secret exploded") {
t.Fatalf("expected wrapped secret create error, got %v", err)
}
} }

View File

@ -114,6 +114,18 @@ func TestListBackupJobsAndListBackupJobsForPVCCoverFilteringAndSorting(t *testin
if len(items) != 2 || items[0].Name != "backup-alpha" || items[1].Name != "backup-zeta" { if len(items) != 2 || items[0].Name != "backup-alpha" || items[1].Name != "backup-zeta" {
t.Fatalf("expected filtered pvc job list, got %#v", items) t.Fatalf("expected filtered pvc job list, got %#v", items)
} }
listFailClientset := k8sfake.NewSimpleClientset()
listFailClientset.PrependReactor("list", "jobs", func(action k8stesting.Action) (bool, runtime.Object, error) {
return true, nil, errors.New("list jobs exploded")
})
listFailClient := &Client{Clientset: listFailClientset}
if _, err := listFailClient.ListBackupJobs(context.Background(), "apps"); err == nil || !strings.Contains(err.Error(), "list jobs exploded") {
t.Fatalf("expected list backup jobs error, got %v", err)
}
if _, err := listFailClient.ListBackupJobsForPVC(context.Background(), "apps", "data"); err == nil || !strings.Contains(err.Error(), "list jobs exploded") {
t.Fatalf("expected pvc-scoped list backup jobs error, got %v", err)
}
} }
func TestResolvePVCMountedNodeIgnoresDeadPodsAndFindsMountedClaim(t *testing.T) { func TestResolvePVCMountedNodeIgnoresDeadPodsAndFindsMountedClaim(t *testing.T) {

View File

@ -181,6 +181,20 @@ func TestVolumeOperationsPropagateAPIErrorsAndOptionalBranches(t *testing.T) {
} }
}) })
t.Run("snapshot backup api error", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "snapshot failed", http.StatusBadGateway)
}))
defer server.Close()
client := New(server.URL)
_, err := client.SnapshotBackup(ctx, "pv/name", "snap-1", map[string]string{"env": "dev"}, "incremental")
apiErr, ok := err.(*APIError)
if !ok || apiErr.Status != http.StatusBadGateway {
t.Fatalf("expected APIError 502 for SnapshotBackup, got %#v", err)
}
})
t.Run("create volume from backup error", func(t *testing.T) { t.Run("create volume from backup error", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "create failed", http.StatusBadGateway) http.Error(w, "create failed", http.StatusBadGateway)
@ -344,6 +358,14 @@ func TestListBackupsAndFindBackupSelections(t *testing.T) {
t.Fatalf("expected snapshot lookup to return backup-old, got %#v", bySnapshot) t.Fatalf("expected snapshot lookup to return backup-old, got %#v", bySnapshot)
} }
byName, err := client.FindBackup(ctx, "vol-a", "backup-new")
if err != nil {
t.Fatalf("FindBackup by name: %v", err)
}
if byName.Name != "backup-new" {
t.Fatalf("expected name lookup to return backup-new, got %#v", byName)
}
byURL, err := client.FindBackup(ctx, "vol-a", "s3://bucket/invalid") byURL, err := client.FindBackup(ctx, "vol-a", "s3://bucket/invalid")
if err != nil { if err != nil {
t.Fatalf("FindBackup by URL: %v", err) t.Fatalf("FindBackup by URL: %v", err)
@ -369,6 +391,20 @@ func TestListBackupsAndFindBackupErrors(t *testing.T) {
} }
}) })
t.Run("backup volume lookup error", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "volume lookup failed", http.StatusBadGateway)
}))
defer server.Close()
client := New(server.URL)
_, err := client.ListBackups(ctx, "vol-a")
apiErr, ok := err.(*APIError)
if !ok || apiErr.Status != http.StatusBadGateway {
t.Fatalf("expected backup volume lookup APIError 502, got %#v", err)
}
})
t.Run("backup list request fails", func(t *testing.T) { t.Run("backup list request fails", func(t *testing.T) {
serverURL := "" serverURL := ""
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

View File

@ -309,8 +309,5 @@ func targetPVCName(prefix, sourcePVC string) string {
if len(name) > 63 { if len(name) > 63 {
name = strings.Trim(name[:63], "-") name = strings.Trim(name[:63], "-")
} }
if name == "" {
name = "restore"
}
return name return name
} }

View File

@ -31,6 +31,11 @@ type fakeKubeClient struct {
secretData map[string][]byte secretData map[string][]byte
} }
type secretErrorKubeClient struct {
*fakeKubeClient
err error
}
func (f *fakeKubeClient) ResolvePVCVolume(_ context.Context, namespace, pvcName string) (string, *corev1.PersistentVolumeClaim, *corev1.PersistentVolume, error) { func (f *fakeKubeClient) ResolvePVCVolume(_ context.Context, namespace, pvcName string) (string, *corev1.PersistentVolumeClaim, *corev1.PersistentVolume, error) {
return namespace + "-" + pvcName + "-pv", nil, nil, nil return namespace + "-" + pvcName + "-pv", nil, nil, nil
} }
@ -135,6 +140,10 @@ func (f *fakeKubeClient) SaveSecretData(_ context.Context, _, _, key string, val
return nil return nil
} }
func (f *secretErrorKubeClient) LoadSecretData(_ context.Context, _, _, _ string) ([]byte, error) {
return nil, f.err
}
type fakeLonghornClient struct { type fakeLonghornClient struct {
backups []longhorn.Backup backups []longhorn.Backup
createSnapshotName string createSnapshotName string
@ -493,6 +502,42 @@ func TestLoadB2SecretValueValidatesInputs(t *testing.T) {
} }
} }
func TestLoadB2SecretValueWrapsClientErrors(t *testing.T) {
srv := &Server{
cfg: &config.Config{
B2SecretNamespace: "atlas",
B2SecretName: "b2-creds",
},
client: &secretErrorKubeClient{
fakeKubeClient: &fakeKubeClient{},
err: fmt.Errorf("vault bridge exploded"),
},
}
if _, err := srv.loadB2SecretValue(context.Background(), "AWS_ACCESS_KEY_ID"); err == nil || !strings.Contains(err.Error(), "vault bridge exploded") {
t.Fatalf("expected wrapped secret load error, got %v", err)
}
}
func TestResolveB2CredentialsWrapsSecretLoadErrors(t *testing.T) {
srv := &Server{
cfg: &config.Config{
B2SecretNamespace: "atlas",
B2SecretName: "b2-creds",
B2AccessKeyField: "AWS_ACCESS_KEY_ID",
B2SecretKeyField: "AWS_SECRET_ACCESS_KEY",
},
client: &secretErrorKubeClient{
fakeKubeClient: &fakeKubeClient{},
err: fmt.Errorf("secret load exploded"),
},
}
if _, err := srv.resolveB2Credentials(context.Background()); err == nil || !strings.Contains(err.Error(), "secret load exploded") {
t.Fatalf("expected wrapped secret load error during credential resolution, got %v", err)
}
}
func TestNormalizeS3Endpoint(t *testing.T) { func TestNormalizeS3Endpoint(t *testing.T) {
host, secure, err := normalizeS3Endpoint("https://s3.us-west-000.backblazeb2.com") host, secure, err := normalizeS3Endpoint("https://s3.us-west-000.backblazeb2.com")
if err != nil || host != "s3.us-west-000.backblazeb2.com" || !secure { if err != nil || host != "s3.us-west-000.backblazeb2.com" || !secure {