Skip to content

Commit 58b3de1

Browse files
committed
Add a shared function for starting envtest
A few packages were doing similar things to skip or start envtest.
1 parent d276cc8 commit 58b3de1

File tree

11 files changed

+205
-277
lines changed

11 files changed

+205
-277
lines changed

internal/bridge/crunchybridgecluster/crunchybridgecluster_controller_test.go

+11-12
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import (
3535
"github.com/crunchydata/postgres-operator/internal/naming"
3636
"github.com/crunchydata/postgres-operator/internal/testing/cmp"
3737
"github.com/crunchydata/postgres-operator/internal/testing/require"
38-
3938
"github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1"
4039
)
4140

@@ -44,7 +43,7 @@ var testApiKey = "9012"
4443

4544
func TestReconcileBridgeConnectionSecret(t *testing.T) {
4645
ctx := context.Background()
47-
_, tClient := setupKubernetes(t)
46+
tClient := setupKubernetes(t)
4847
require.ParallelCapacity(t, 0)
4948

5049
reconciler := &CrunchyBridgeClusterReconciler{
@@ -99,7 +98,7 @@ func TestReconcileBridgeConnectionSecret(t *testing.T) {
9998

10099
func TestHandleDuplicateClusterName(t *testing.T) {
101100
ctx := context.Background()
102-
_, tClient := setupKubernetes(t)
101+
tClient := setupKubernetes(t)
103102
require.ParallelCapacity(t, 0)
104103

105104
clusterInBridge := testClusterApiResource()
@@ -176,7 +175,7 @@ func TestHandleDuplicateClusterName(t *testing.T) {
176175

177176
func TestHandleCreateCluster(t *testing.T) {
178177
ctx := context.Background()
179-
_, tClient := setupKubernetes(t)
178+
tClient := setupKubernetes(t)
180179
require.ParallelCapacity(t, 0)
181180

182181
ns := setupNamespace(t, tClient).Name
@@ -243,7 +242,7 @@ func TestHandleCreateCluster(t *testing.T) {
243242

244243
func TestHandleGetCluster(t *testing.T) {
245244
ctx := context.Background()
246-
_, tClient := setupKubernetes(t)
245+
tClient := setupKubernetes(t)
247246
require.ParallelCapacity(t, 0)
248247

249248
ns := setupNamespace(t, tClient).Name
@@ -301,7 +300,7 @@ func TestHandleGetCluster(t *testing.T) {
301300

302301
func TestHandleGetClusterStatus(t *testing.T) {
303302
ctx := context.Background()
304-
_, tClient := setupKubernetes(t)
303+
tClient := setupKubernetes(t)
305304
require.ParallelCapacity(t, 0)
306305

307306
ns := setupNamespace(t, tClient).Name
@@ -380,7 +379,7 @@ func TestHandleGetClusterStatus(t *testing.T) {
380379

381380
func TestHandleGetClusterUpgrade(t *testing.T) {
382381
ctx := context.Background()
383-
_, tClient := setupKubernetes(t)
382+
tClient := setupKubernetes(t)
384383
require.ParallelCapacity(t, 0)
385384

386385
ns := setupNamespace(t, tClient).Name
@@ -462,7 +461,7 @@ func TestHandleGetClusterUpgrade(t *testing.T) {
462461

463462
func TestHandleUpgrade(t *testing.T) {
464463
ctx := context.Background()
465-
_, tClient := setupKubernetes(t)
464+
tClient := setupKubernetes(t)
466465
require.ParallelCapacity(t, 0)
467466

468467
ns := setupNamespace(t, tClient).Name
@@ -570,7 +569,7 @@ func TestHandleUpgrade(t *testing.T) {
570569

571570
func TestHandleUpgradeHA(t *testing.T) {
572571
ctx := context.Background()
573-
_, tClient := setupKubernetes(t)
572+
tClient := setupKubernetes(t)
574573
require.ParallelCapacity(t, 0)
575574

576575
ns := setupNamespace(t, tClient).Name
@@ -657,7 +656,7 @@ func TestHandleUpgradeHA(t *testing.T) {
657656

658657
func TestHandleUpdate(t *testing.T) {
659658
ctx := context.Background()
660-
_, tClient := setupKubernetes(t)
659+
tClient := setupKubernetes(t)
661660
require.ParallelCapacity(t, 0)
662661

663662
ns := setupNamespace(t, tClient).Name
@@ -733,7 +732,7 @@ func TestHandleUpdate(t *testing.T) {
733732

734733
func TestGetSecretKeys(t *testing.T) {
735734
ctx := context.Background()
736-
_, tClient := setupKubernetes(t)
735+
tClient := setupKubernetes(t)
737736
require.ParallelCapacity(t, 0)
738737

739738
reconciler := &CrunchyBridgeClusterReconciler{
@@ -815,7 +814,7 @@ func TestGetSecretKeys(t *testing.T) {
815814

816815
func TestDeleteControlled(t *testing.T) {
817816
ctx := context.Background()
818-
_, tClient := setupKubernetes(t)
817+
tClient := setupKubernetes(t)
819818
require.ParallelCapacity(t, 1)
820819

821820
ns := setupNamespace(t, tClient)

internal/bridge/crunchybridgecluster/delete_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import (
3131

3232
func TestHandleDeleteCluster(t *testing.T) {
3333
ctx := context.Background()
34-
_, tClient := setupKubernetes(t)
34+
tClient := setupKubernetes(t)
3535
require.ParallelCapacity(t, 0)
3636

3737
ns := setupNamespace(t, tClient).Name

internal/bridge/crunchybridgecluster/helpers_test.go

+14-67
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,17 @@ package crunchybridgecluster
1818
import (
1919
"context"
2020
"os"
21-
"path/filepath"
2221
"strconv"
23-
"strings"
24-
"sync"
2522
"testing"
2623
"time"
2724

28-
"gotest.tools/v3/assert"
2925
corev1 "k8s.io/api/core/v1"
3026
"k8s.io/apimachinery/pkg/api/resource"
3127
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3228
"sigs.k8s.io/controller-runtime/pkg/client"
33-
"sigs.k8s.io/controller-runtime/pkg/envtest"
3429
"sigs.k8s.io/yaml"
3530

3631
"github.com/crunchydata/postgres-operator/internal/bridge"
37-
"github.com/crunchydata/postgres-operator/internal/controller/runtime"
3832
"github.com/crunchydata/postgres-operator/internal/initialize"
3933
"github.com/crunchydata/postgres-operator/internal/testing/require"
4034
"github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1"
@@ -60,80 +54,33 @@ func init() {
6054
}
6155
}
6256

63-
var kubernetes struct {
64-
sync.Mutex
65-
66-
env *envtest.Environment
67-
count int
68-
}
69-
7057
// setupKubernetes starts or connects to a Kubernetes API and returns a client
71-
// that uses it. When starting a local API, the client is a member of the
72-
// "system:masters" group. It also creates any CRDs present in the
73-
// "/config/crd/bases" directory. When any of these fail, it calls t.Fatal.
74-
// It deletes CRDs and stops the local API using t.Cleanup.
75-
//
76-
// This function was duplicated from the postgrescluster package.
77-
// TODO: Pull these duplicated functions out into a separate, shared package.
78-
//
79-
//nolint:unparam
80-
func setupKubernetes(t testing.TB) (*envtest.Environment, client.Client) {
58+
// that uses it. See [require.Kubernetes] for more details.
59+
func setupKubernetes(t testing.TB) client.Client {
8160
t.Helper()
82-
if os.Getenv("KUBEBUILDER_ASSETS") == "" && !strings.EqualFold(os.Getenv("USE_EXISTING_CLUSTER"), "true") {
83-
t.SkipNow()
84-
}
85-
86-
kubernetes.Lock()
87-
defer kubernetes.Unlock()
88-
89-
if kubernetes.env == nil {
90-
env := &envtest.Environment{
91-
CRDDirectoryPaths: []string{
92-
filepath.Join("..", "..", "..", "config", "crd", "bases"),
93-
},
94-
}
95-
96-
_, err := env.Start()
97-
assert.NilError(t, err)
98-
99-
kubernetes.env = env
100-
}
10161

102-
kubernetes.count++
62+
// Start and/or connect to a Kubernetes API, or Skip when that's not configured.
63+
cc := require.Kubernetes(t)
10364

65+
// Log the status of any test namespaces after this test fails.
10466
t.Cleanup(func() {
105-
kubernetes.Lock()
106-
defer kubernetes.Unlock()
107-
10867
if t.Failed() {
109-
if cc, err := client.New(kubernetes.env.Config, client.Options{}); err == nil {
110-
var namespaces corev1.NamespaceList
111-
_ = cc.List(context.Background(), &namespaces, client.HasLabels{"postgres-operator-test"})
112-
113-
type shaped map[string]corev1.NamespaceStatus
114-
result := make([]shaped, len(namespaces.Items))
68+
var namespaces corev1.NamespaceList
69+
_ = cc.List(context.Background(), &namespaces, client.HasLabels{"postgres-operator-test"})
11570

116-
for i, ns := range namespaces.Items {
117-
result[i] = shaped{ns.Labels["postgres-operator-test"]: ns.Status}
118-
}
71+
type shaped map[string]corev1.NamespaceStatus
72+
result := make([]shaped, len(namespaces.Items))
11973

120-
formatted, _ := yaml.Marshal(result)
121-
t.Logf("Test Namespaces:\n%s", formatted)
74+
for i, ns := range namespaces.Items {
75+
result[i] = shaped{ns.Labels["postgres-operator-test"]: ns.Status}
12276
}
123-
}
12477

125-
kubernetes.count--
126-
127-
if kubernetes.count == 0 {
128-
assert.Check(t, kubernetes.env.Stop())
129-
kubernetes.env = nil
78+
formatted, _ := yaml.Marshal(result)
79+
t.Logf("Test Namespaces:\n%s", formatted)
13080
}
13181
})
13282

133-
client, err := client.New(kubernetes.env.Config, client.Options{Scheme: runtime.Scheme})
134-
assert.NilError(t, err)
135-
136-
return kubernetes.env, client
83+
return cc
13784
}
13885

13986
// setupNamespace creates a random namespace that will be deleted by t.Cleanup.

internal/bridge/crunchybridgecluster/postgres_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import (
3232
)
3333

3434
func TestGeneratePostgresRoleSecret(t *testing.T) {
35-
_, tClient := setupKubernetes(t)
35+
tClient := setupKubernetes(t)
3636
require.ParallelCapacity(t, 0)
3737

3838
reconciler := &CrunchyBridgeClusterReconciler{
@@ -82,7 +82,7 @@ func TestGeneratePostgresRoleSecret(t *testing.T) {
8282

8383
func TestReconcilePostgresRoleSecrets(t *testing.T) {
8484
ctx := context.Background()
85-
_, tClient := setupKubernetes(t)
85+
tClient := setupKubernetes(t)
8686
require.ParallelCapacity(t, 0)
8787

8888
apiKey := "9012"

internal/bridge/crunchybridgecluster/watches_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828

2929
func TestFindCrunchyBridgeClustersForSecret(t *testing.T) {
3030
ctx := context.Background()
31-
_, tClient := setupKubernetes(t)
31+
tClient := setupKubernetes(t)
3232
require.ParallelCapacity(t, 0)
3333

3434
ns := setupNamespace(t, tClient)

internal/controller/postgrescluster/apply_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ import (
4040

4141
func TestServerSideApply(t *testing.T) {
4242
ctx := context.Background()
43-
env, cc := setupKubernetes(t)
43+
cfg, cc := setupKubernetes(t)
4444
require.ParallelCapacity(t, 0)
4545

4646
ns := setupNamespace(t, cc)
4747

48-
dc, err := discovery.NewDiscoveryClientForConfig(env.Config)
48+
dc, err := discovery.NewDiscoveryClientForConfig(cfg)
4949
assert.NilError(t, err)
5050

5151
server, err := dc.ServerVersion()

internal/controller/postgrescluster/helpers_test.go

+14-61
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,15 @@ package postgrescluster
1818
import (
1919
"context"
2020
"os"
21-
"path/filepath"
2221
"strconv"
23-
"strings"
24-
"sync"
2522
"testing"
2623
"time"
2724

28-
"gotest.tools/v3/assert"
2925
corev1 "k8s.io/api/core/v1"
3026
"k8s.io/apimachinery/pkg/api/resource"
3127
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3228
"k8s.io/client-go/rest"
3329
"sigs.k8s.io/controller-runtime/pkg/client"
34-
"sigs.k8s.io/controller-runtime/pkg/envtest"
3530
"sigs.k8s.io/controller-runtime/pkg/manager"
3631
"sigs.k8s.io/yaml"
3732

@@ -73,75 +68,33 @@ func marshalMatches(actual interface{}, expected string) cmp.Comparison {
7368
return cmp.MarshalMatches(actual, expected)
7469
}
7570

76-
var kubernetes struct {
77-
sync.Mutex
78-
79-
env *envtest.Environment
80-
count int
81-
}
82-
8371
// setupKubernetes starts or connects to a Kubernetes API and returns a client
84-
// that uses it. When starting a local API, the client is a member of the
85-
// "system:masters" group. It also creates any CRDs present in the
86-
// "/config/crd/bases" directory. When any of these fail, it calls t.Fatal.
87-
// It deletes CRDs and stops the local API using t.Cleanup.
88-
func setupKubernetes(t testing.TB) (*envtest.Environment, client.Client) {
72+
// that uses it. See [require.Kubernetes] for more details.
73+
func setupKubernetes(t testing.TB) (*rest.Config, client.Client) {
8974
t.Helper()
90-
if os.Getenv("KUBEBUILDER_ASSETS") == "" && !strings.EqualFold(os.Getenv("USE_EXISTING_CLUSTER"), "true") {
91-
t.SkipNow()
92-
}
93-
94-
kubernetes.Lock()
95-
defer kubernetes.Unlock()
96-
97-
if kubernetes.env == nil {
98-
env := &envtest.Environment{
99-
CRDDirectoryPaths: []string{
100-
filepath.Join("..", "..", "..", "config", "crd", "bases"),
101-
},
102-
}
10375

104-
_, err := env.Start()
105-
assert.NilError(t, err)
106-
107-
kubernetes.env = env
108-
}
109-
110-
kubernetes.count++
76+
// Start and/or connect to a Kubernetes API, or Skip when that's not configured.
77+
cfg, cc := require.Kubernetes2(t)
11178

79+
// Log the status of any test namespaces after this test fails.
11280
t.Cleanup(func() {
113-
kubernetes.Lock()
114-
defer kubernetes.Unlock()
115-
11681
if t.Failed() {
117-
if cc, err := client.New(kubernetes.env.Config, client.Options{}); err == nil {
118-
var namespaces corev1.NamespaceList
119-
_ = cc.List(context.Background(), &namespaces, client.HasLabels{"postgres-operator-test"})
82+
var namespaces corev1.NamespaceList
83+
_ = cc.List(context.Background(), &namespaces, client.HasLabels{"postgres-operator-test"})
12084

121-
type shaped map[string]corev1.NamespaceStatus
122-
result := make([]shaped, len(namespaces.Items))
85+
type shaped map[string]corev1.NamespaceStatus
86+
result := make([]shaped, len(namespaces.Items))
12387

124-
for i, ns := range namespaces.Items {
125-
result[i] = shaped{ns.Labels["postgres-operator-test"]: ns.Status}
126-
}
127-
128-
formatted, _ := yaml.Marshal(result)
129-
t.Logf("Test Namespaces:\n%s", formatted)
88+
for i, ns := range namespaces.Items {
89+
result[i] = shaped{ns.Labels["postgres-operator-test"]: ns.Status}
13090
}
131-
}
13291

133-
kubernetes.count--
134-
135-
if kubernetes.count == 0 {
136-
assert.Check(t, kubernetes.env.Stop())
137-
kubernetes.env = nil
92+
formatted, _ := yaml.Marshal(result)
93+
t.Logf("Test Namespaces:\n%s", formatted)
13894
}
13995
})
14096

141-
client, err := client.New(kubernetes.env.Config, client.Options{Scheme: runtime.Scheme})
142-
assert.NilError(t, err)
143-
144-
return kubernetes.env, client
97+
return cfg, cc
14598
}
14699

147100
// setupNamespace creates a random namespace that will be deleted by t.Cleanup.

0 commit comments

Comments
 (0)