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