Skip to content

Commit a7c0a61

Browse files
committed
Set up DevWorkspaceRouting controller envtesting suite
Signed-off-by: Andrew Obuchowicz <aobuchow@redhat.com>
1 parent ab6c9fa commit a7c0a61

3 files changed

Lines changed: 598 additions & 0 deletions

File tree

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
// Copyright (c) 2019-2023 Red Hat, Inc.
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package devworkspacerouting_test
15+
16+
import (
17+
"context"
18+
"fmt"
19+
"os"
20+
"path/filepath"
21+
"testing"
22+
23+
dwv1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha1"
24+
dwv2 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
25+
controllerv1alpha1 "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1"
26+
"github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting"
27+
"github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers"
28+
routev1 "github.com/openshift/api/route/v1"
29+
30+
appsv1 "k8s.io/api/apps/v1"
31+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
32+
"k8s.io/utils/pointer"
33+
"sigs.k8s.io/yaml"
34+
35+
"github.com/devfile/devworkspace-operator/pkg/cache"
36+
"github.com/devfile/devworkspace-operator/pkg/config"
37+
"github.com/devfile/devworkspace-operator/pkg/infrastructure"
38+
. "github.com/onsi/ginkgo/v2"
39+
. "github.com/onsi/gomega"
40+
corev1 "k8s.io/api/core/v1"
41+
"k8s.io/client-go/kubernetes/scheme"
42+
ctrl "sigs.k8s.io/controller-runtime"
43+
"sigs.k8s.io/controller-runtime/pkg/client"
44+
"sigs.k8s.io/controller-runtime/pkg/envtest"
45+
logf "sigs.k8s.io/controller-runtime/pkg/log"
46+
"sigs.k8s.io/controller-runtime/pkg/log/zap"
47+
)
48+
49+
var (
50+
k8sClient client.Client
51+
testEnv *envtest.Environment
52+
ctx context.Context
53+
cancel context.CancelFunc
54+
testControllerCfg = config.GetConfigForTesting(&controllerv1alpha1.OperatorConfiguration{
55+
Workspace: &controllerv1alpha1.WorkspaceConfig{},
56+
Routing: &controllerv1alpha1.RoutingConfig{
57+
ClusterHostSuffix: "test-environment-cluster-suffix",
58+
},
59+
EnableExperimentalFeatures: pointer.Bool(true),
60+
})
61+
)
62+
63+
func TestAPIs(t *testing.T) {
64+
if os.Getenv("SKIP_CONTROLLER_TESTS") == "true" {
65+
t.Skip()
66+
}
67+
68+
RegisterFailHandler(Fail)
69+
70+
RunSpecs(t, "DevWorkspaceRouting Controller Suite")
71+
}
72+
73+
var _ = BeforeSuite(func() {
74+
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
75+
76+
ctx, cancel = context.WithCancel(context.TODO())
77+
78+
By("setting up controller environment")
79+
Expect(setupEnvVars()).To(Succeed())
80+
81+
By("bootstrapping test environment")
82+
testEnv = &envtest.Environment{
83+
CRDDirectoryPaths: []string{
84+
filepath.Join("..", "..", "..", "deploy", "templates", "crd", "bases"),
85+
// Required to register OpenShift route CRD in testing environment
86+
filepath.Join(".", "testdata", "route.crd.yaml"),
87+
},
88+
ErrorIfCRDPathMissing: true,
89+
BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", "1.24.2-linux-amd64"),
90+
}
91+
92+
cfg, err := testEnv.Start()
93+
Expect(err).NotTo(HaveOccurred())
94+
Expect(cfg).NotTo(BeNil())
95+
96+
infrastructure.InitializeForTesting(infrastructure.OpenShiftv4)
97+
config.SetGlobalConfigForTesting(testControllerCfg)
98+
99+
err = controllerv1alpha1.AddToScheme(scheme.Scheme)
100+
Expect(err).NotTo(HaveOccurred())
101+
err = dwv1.AddToScheme(scheme.Scheme)
102+
Expect(err).NotTo(HaveOccurred())
103+
err = dwv2.AddToScheme(scheme.Scheme)
104+
Expect(err).NotTo(HaveOccurred())
105+
err = routev1.Install(scheme.Scheme)
106+
Expect(err).NotTo(HaveOccurred())
107+
108+
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
109+
Expect(err).NotTo(HaveOccurred())
110+
Expect(k8sClient).NotTo(BeNil())
111+
112+
// Replicate controller setup similarly to how we do for main.go
113+
cacheFunc, err := cache.GetCacheFunc()
114+
Expect(err).NotTo(HaveOccurred())
115+
116+
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
117+
Scheme: scheme.Scheme,
118+
Port: 9443,
119+
NewCache: cacheFunc,
120+
})
121+
Expect(err).NotTo(HaveOccurred())
122+
123+
nonCachingClient, err := client.New(mgr.GetConfig(), client.Options{Scheme: scheme.Scheme})
124+
Expect(err).NotTo(HaveOccurred())
125+
126+
err = mgr.GetFieldIndexer().IndexField(context.Background(), &corev1.Event{}, "involvedObject.name", func(obj client.Object) []string {
127+
ev := obj.(*corev1.Event)
128+
return []string{ev.InvolvedObject.Name}
129+
})
130+
Expect(err).NotTo(HaveOccurred())
131+
132+
err = (&devworkspacerouting.DevWorkspaceRoutingReconciler{
133+
Client: nonCachingClient,
134+
Log: ctrl.Log.WithName("controllers").WithName("DevWorkspaceRouting"),
135+
Scheme: mgr.GetScheme(),
136+
SolverGetter: &solvers.SolverGetter{},
137+
DebugLogging: config.ExperimentalFeaturesEnabled(),
138+
}).SetupWithManager(mgr)
139+
Expect(err).NotTo(HaveOccurred())
140+
141+
By("Creating Namespace for the DevWorkspaceRouting")
142+
ns := &corev1.Namespace{
143+
ObjectMeta: metav1.ObjectMeta{
144+
Name: testNamespace,
145+
},
146+
}
147+
Expect(k8sClient.Create(ctx, ns)).Should(Succeed())
148+
149+
go func() {
150+
defer GinkgoRecover()
151+
err = mgr.Start(ctx)
152+
Expect(err).ToNot(HaveOccurred(), "failed to run manager")
153+
}()
154+
})
155+
156+
var _ = AfterSuite(func() {
157+
cancel()
158+
By("tearing down the test environment")
159+
err := testEnv.Stop()
160+
Expect(err).NotTo(HaveOccurred())
161+
})
162+
163+
func setupEnvVars() error {
164+
bytes, err := os.ReadFile(filepath.Join("..", "..", "..", "deploy", "templates", "components", "manager", "manager.yaml"))
165+
if err != nil {
166+
return err
167+
}
168+
deploy := &appsv1.Deployment{}
169+
if err := yaml.Unmarshal(bytes, deploy); err != nil {
170+
return err
171+
}
172+
173+
var dwContainer *corev1.Container
174+
for _, container := range deploy.Spec.Template.Spec.Containers {
175+
if container.Name == "devworkspace-controller" {
176+
dwContainer = &container
177+
break
178+
}
179+
}
180+
if dwContainer == nil {
181+
return fmt.Errorf("could not read devworkspace-controller container from manager.yaml")
182+
}
183+
184+
for _, envvar := range dwContainer.Env {
185+
if err := os.Setenv(envvar.Name, envvar.Value); err != nil {
186+
return err
187+
}
188+
}
189+
190+
return nil
191+
}

0 commit comments

Comments
 (0)