test(soteria): tighten edge-path coverage
This commit is contained in:
parent
8d4dd26d14
commit
683014443d
@ -2,6 +2,7 @@ package k8s
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@ -11,7 +12,9 @@ import (
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
k8sfake "k8s.io/client-go/kubernetes/fake"
|
||||
k8stesting "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
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" {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,6 +114,18 @@ func TestListBackupJobsAndListBackupJobsForPVCCoverFilteringAndSorting(t *testin
|
||||
if len(items) != 2 || items[0].Name != "backup-alpha" || items[1].Name != "backup-zeta" {
|
||||
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) {
|
||||
|
||||
@ -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) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
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)
|
||||
}
|
||||
|
||||
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")
|
||||
if err != nil {
|
||||
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) {
|
||||
serverURL := ""
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@ -309,8 +309,5 @@ func targetPVCName(prefix, sourcePVC string) string {
|
||||
if len(name) > 63 {
|
||||
name = strings.Trim(name[:63], "-")
|
||||
}
|
||||
if name == "" {
|
||||
name = "restore"
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
@ -31,6 +31,11 @@ type fakeKubeClient struct {
|
||||
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) {
|
||||
return namespace + "-" + pvcName + "-pv", nil, nil, nil
|
||||
}
|
||||
@ -135,6 +140,10 @@ func (f *fakeKubeClient) SaveSecretData(_ context.Context, _, _, key string, val
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *secretErrorKubeClient) LoadSecretData(_ context.Context, _, _, _ string) ([]byte, error) {
|
||||
return nil, f.err
|
||||
}
|
||||
|
||||
type fakeLonghornClient struct {
|
||||
backups []longhorn.Backup
|
||||
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) {
|
||||
host, secure, err := normalizeS3Endpoint("https://s3.us-west-000.backblazeb2.com")
|
||||
if err != nil || host != "s3.us-west-000.backblazeb2.com" || !secure {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user