diff --git a/Makefile b/Makefile index 3061a72..b8c9e11 100644 --- a/Makefile +++ b/Makefile @@ -152,7 +152,7 @@ CONTAINER_RUNTIME ?= $(shell command -v docker 2>/dev/null || command -v podman # Set SKIP_BUILD=true to skip the image build/load steps and use a pre-built image. SKIP_BUILD ?= false # Number of parallel Ginkgo workers. Defaults to 1 (sequential). Override with GINKGO_PROCS=N. -GINKGO_PROCS ?= 4 +GINKGO_PROCS ?= 1 .PHONY: e2e-setup e2e-setup: ## One-time setup: create Kind cluster and install dependencies (Argo, CSI, Vault) diff --git a/internal/pkg/util/interface.go b/internal/pkg/util/interface.go index ba04de2..76e7d12 100644 --- a/internal/pkg/util/interface.go +++ b/internal/pkg/util/interface.go @@ -23,15 +23,21 @@ func InterfaceSlice(slice interface{}) []interface{} { return ret } -// ParseBool returns result in bool format after parsing +// ParseBool returns result in bool format after parsing. +// It handles concrete bool/string types as well as any named type whose +// underlying kind is bool or string (e.g. type MyBool bool). func ParseBool(value interface{}) bool { - if reflect.Bool == reflect.TypeOf(value).Kind() { - b, _ := value.(bool) - return b - } else if reflect.String == reflect.TypeOf(value).Kind() { - s, _ := value.(string) - result, _ := strconv.ParseBool(s) - return result + if value == nil { + return false + } + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.Bool: + return v.Bool() + case reflect.String: + result, _ := strconv.ParseBool(v.String()) + return result + default: + return false } - return false } diff --git a/internal/pkg/util/util_test.go b/internal/pkg/util/util_test.go index 161e92d..d76daf8 100644 --- a/internal/pkg/util/util_test.go +++ b/internal/pkg/util/util_test.go @@ -8,6 +8,45 @@ import ( "github.com/stakater/Reloader/internal/pkg/options" ) +// custom named types to verify reflect-based extraction +type myBool bool +type myString string + +func TestParseBool(t *testing.T) { + tests := []struct { + name string + input interface{} + want bool + }{ + // concrete bool + {"true bool", true, true}, + {"false bool", false, false}, + // concrete string + {"string true", "true", true}, + {"string 1", "1", true}, + {"string false", "false", false}, + {"string 0", "0", false}, + {"string invalid", "banana", false}, + // custom named bool kind + {"myBool true", myBool(true), true}, + {"myBool false", myBool(false), false}, + // custom named string kind + {"myString true", myString("true"), true}, + {"myString false", myString("false"), false}, + // nil and unsupported + {"nil", nil, false}, + {"int", 42, false}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + if got := ParseBool(tc.input); got != tc.want { + t.Errorf("ParseBool(%v) = %v, want %v", tc.input, got, tc.want) + } + }) + } +} + func TestConvertToEnvVarName(t *testing.T) { data := "www.stakater.com" envVar := ConvertToEnvVarName(data) diff --git a/test/e2e/README.md b/test/e2e/README.md index cfa989d..608ecf5 100644 --- a/test/e2e/README.md +++ b/test/e2e/README.md @@ -40,13 +40,13 @@ SKIP_BUILD=true RELOADER_IMAGE=ghcr.io/stakater/reloader:v1.2.0 make e2e ### Environment Variables -| Variable | Default | Description | -|----------|---------|-------------| +| Variable | Default | Description | +|----------|----------------------------------|-------------| | `RELOADER_IMAGE` | `ghcr.io/stakater/reloader:test` | Image to test | -| `SKIP_BUILD` | `false` | Skip the container image build and Kind load steps; requires `RELOADER_IMAGE` to point to an already-loaded image | -| `KIND_CLUSTER` | `reloader-e2e` | Kind cluster name | -| `E2E_TIMEOUT` | `45m` | Test timeout | -| `GINKGO_PROCS` | `4` | Number of parallel Ginkgo worker processes | +| `SKIP_BUILD` | `false` | Skip the container image build and Kind load steps; requires `RELOADER_IMAGE` to point to an already-loaded image | +| `KIND_CLUSTER` | `reloader-e2e` | Kind cluster name | +| `E2E_TIMEOUT` | `45m` | Test timeout | +| `GINKGO_PROCS` | `1` | Number of parallel Ginkgo worker processes | ## Test Structure