Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions internal/doctor/helpers_coverage_test.go
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
package doctor

import (
"context"
"testing"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"

"github.com/tracebloc/cli/internal/cluster"
)

func TestStatus_String(t *testing.T) {
cases := map[Status]string{
StatusOK: "ok",
StatusWarn: "warn",
StatusFail: "fail",
Status(99): "unknown",
}
for s, want := range cases {
if got := s.String(); got != want {
t.Errorf("Status(%d).String() = %q, want %q", s, got, want)
}
}
}

func TestNodeReady(t *testing.T) {
cond := func(s corev1.ConditionStatus) corev1.Node {
return corev1.Node{Status: corev1.NodeStatus{Conditions: []corev1.NodeCondition{{Type: corev1.NodeReady, Status: s}}}}
}
if !nodeReady(cond(corev1.ConditionTrue)) {
t.Error("Ready=True must be ready")
}
if nodeReady(cond(corev1.ConditionFalse)) {
t.Error("Ready=False must not be ready")
}
if nodeReady(corev1.Node{}) {
t.Error("a node with no Ready condition must not be ready")
}
}

func TestGetDeployment_EmptyCandidateAndMissing(t *testing.T) {
empty := fake.NewClientset()
if d := getDeployment(context.Background(), empty, "ns", []string{"", "nope"}); d != nil {
t.Errorf("getDeployment with only an empty + a missing candidate = %v, want nil", d)
}
present := fake.NewClientset(&appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "x", Namespace: "ns"}})
if d := getDeployment(context.Background(), present, "ns", []string{"", "x"}); d == nil {
t.Error("getDeployment must find an existing deployment (skipping the empty candidate)")
}
}

func TestJobsManagerEnv_SkipsValueFrom(t *testing.T) {
dep := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "tracebloc-jobs-manager", Namespace: "ns"},
Spec: appsv1.DeploymentSpec{Template: corev1.PodTemplateSpec{Spec: corev1.PodSpec{
Containers: []corev1.Container{{Name: "jm", Env: []corev1.EnvVar{
{Name: "PLAIN", Value: "v"},
{Name: "FROM", ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{FieldPath: "metadata.name"}}},
}}},
}}},
}
env := jobsManagerEnv(context.Background(), fake.NewClientset(dep), "ns",
&cluster.ParentRelease{ReleaseName: "tracebloc"})
if env["PLAIN"] != "v" {
t.Errorf("a plain env value must be read, got %v", env)
}
if _, ok := env["FROM"]; ok {
t.Error("a valueFrom env (no literal value) must be skipped")
}
}

func TestFindDeployment_AmbiguousUnknownRelease(t *testing.T) {
// Release unknown (nil) + two suffix-matching deployments → no safe
// attribution → nil (don't guess across releases).
cs := fake.NewClientset(
&appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "a-requests-proxy", Namespace: "ns"}},
&appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "b-requests-proxy", Namespace: "ns"}},
)
if d := findDeployment(context.Background(), cs, "ns", nil, "requests-proxy"); d != nil {
t.Errorf("ambiguous unknown-release match must return nil, got %q", d.Name)
}
}
51 changes: 51 additions & 0 deletions internal/helm/upgrade_coverage_test.go
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
package helm

import (
"context"
"testing"
)

func TestSupportsResetThenReuse_Probe(t *testing.T) {
install(t, &fakeRunner{help: "Flags:\n " + resetThenReuse + " strings\n"})
if !supportsResetThenReuse(context.Background()) {
t.Error("help advertising the reuse flag → true")
}
install(t, &fakeRunner{failOn: "upgrade --help"})
if supportsResetThenReuse(context.Background()) {
t.Error("a probe error → conservative false")
}
}

func TestRepoPresent_Match(t *testing.T) {
if !repoPresent(repoName + "\thttps://charts.example\n") {
t.Error("a list naming the repo in column 1 → present")
}
if repoPresent("NAME\tURL\nother\thttps://x\n") {
t.Error("a list without the repo → absent")
}
if repoPresent("") {
t.Error("empty list → absent")
}
}

func TestEnsureRepo_FatalErrors(t *testing.T) {
// repo-add fails (the empty list means the repo isn't present → add is tried).
install(t, &fakeRunner{failOn: "repo add"})
if err := ensureRepo(context.Background()); err == nil {
t.Error("a repo-add failure must be fatal")
}
// repo-update fails (add succeeds, update is failOn'd).
install(t, &fakeRunner{failOn: "repo update"})
if err := ensureRepo(context.Background()); err == nil {
t.Error("a repo-update failure must be fatal")
}
}

// TestUpgrade_EnsureRepoFailureIsFatal drives the full non-dry-run Upgrade path
// (reuse-flag probe → ensureRepo) and asserts an unresolvable repo aborts it.
func TestUpgrade_EnsureRepoFailureIsFatal(t *testing.T) {
install(t, &fakeRunner{failOn: "repo add"}) // remote chart → ensureRepo runs → add fails
if _, err := Upgrade(context.Background(), baseParams()); err == nil {
t.Error("Upgrade must fail when the helm repo can't be ensured")
}
}
Loading