Skip to content
This repository has been archived by the owner on Oct 7, 2020. It is now read-only.

Commit

Permalink
add test for manager.
Browse files Browse the repository at this point in the history
  • Loading branch information
llcao committed Oct 17, 2019
1 parent c92120c commit 52c4ae1
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 20 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ require (
github.com/kylelemons/godebug v1.1.0
github.com/mholt/archiver v3.1.1+incompatible
github.com/nwaples/rardecode v1.0.0 // indirect
github.com/onsi/gomega v1.5.0
github.com/openshift/api v3.9.1-0.20191008181517-e4fd21196097+incompatible // indirect
github.com/openshift/cluster-network-operator v0.0.0-20191009144453-fdceef8e1a7b
github.com/pierrec/lz4 v2.2.5+incompatible // indirect
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright 2019 Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package istiocontrolplane

import (
"os"
"path/filepath"
"sync"
"testing"

"github.com/onsi/gomega"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

"istio.io/operator/pkg/apis"
"istio.io/pkg/log"
)

var cfg *rest.Config

func TestMain(m *testing.M) {
t := &envtest.Environment{
CRDDirectoryPaths: []string{
filepath.Join("..", "..", "..", "deploy", "crds"),
},
}

apis.AddToScheme(scheme.Scheme)

var err error
if cfg, err = t.Start(); err != nil {
log.Fatalf("error to start the test env: %s", err)
}

code := m.Run()

t.Stop()
os.Exit(code)
}

// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and
// writes the request to requests after Reconcile is finished.
func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) {
requests := make(chan reconcile.Request)
fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) {
result, err := inner.Reconcile(req)
requests <- req
return result, err
})

return fn, requests
}

// StartTestManager adds recFn
func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) {
stop := make(chan struct{})
wg := &sync.WaitGroup{}
wg.Add(1)

go func() {
defer wg.Done()
g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred())
}()

return stop, wg
}
102 changes: 82 additions & 20 deletions pkg/controller/istiocontrolplane/istiocontrolplane_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import (
"fmt"
"strconv"
"testing"
"time"

"github.com/onsi/gomega"

"istio.io/operator/pkg/apis/istio/v1alpha2"
"istio.io/operator/pkg/helmreconciler"
Expand All @@ -29,10 +32,26 @@ import (
"k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)

const (
timeout = time.Second * 2
defaultProfile = "default"
demoProfile = "demo"
minimalProfile = "minimal"
sdsProfile = "sds"
)

var (
c client.Client
icpkey = types.NamespacedName{
Name: "test-istiocontrolplane",
Namespace: "test-istio-operator",
}
expectedRequest = reconcile.Request{NamespacedName: icpkey}

minimalStatus = map[string]*v1alpha2.InstallStatus_VersionStatus{
"Pilot": {
Status: v1alpha2.InstallStatus_HEALTHY,
Expand Down Expand Up @@ -156,28 +175,28 @@ func TestICPController_SwitchProfile(t *testing.T) {
cases := []testCase{
{
description: "switch profile from minimal to default",
initialProfile: "minimal",
targetProfile: "default",
initialProfile: minimalProfile,
targetProfile: defaultProfile,
},
{
description: "switch profile from default to minimal",
initialProfile: "default",
targetProfile: "minimal",
initialProfile: defaultProfile,
targetProfile: minimalProfile,
},
{
description: "switch profile from default to demo",
initialProfile: "default",
targetProfile: "demo",
initialProfile: defaultProfile,
targetProfile: demoProfile,
},
{
description: "switch profile from demo to sds",
initialProfile: "demo",
targetProfile: "sds",
initialProfile: demoProfile,
targetProfile: sdsProfile,
},
{
description: "switch profile from sds to default",
initialProfile: "sds",
targetProfile: "default",
initialProfile: sdsProfile,
targetProfile: defaultProfile,
},
}
for i, c := range cases {
Expand All @@ -186,14 +205,15 @@ func TestICPController_SwitchProfile(t *testing.T) {
})
}
}

func testSwitchProfile(t *testing.T, c testCase) {
t.Helper()
name := "example-istiocontrolplane"
namespace := "istio-system"
icp := &v1alpha2.IstioControlPlane{
Kind: "IstioControlPlane",
ApiVersion: "install.istio.io/v1alpha2",
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Name: icpkey.Name,
Namespace: icpkey.Namespace,
},
Spec: &v1alpha2.IstioControlPlaneSpec{
Profile: c.initialProfile,
Expand All @@ -211,8 +231,8 @@ func testSwitchProfile(t *testing.T, c testCase) {

req := reconcile.Request{
NamespacedName: types.NamespacedName{
Name: name,
Namespace: namespace,
Name: icpkey.Name,
Namespace: icpkey.Namespace,
},
}
res, err := r.Reconcile(req)
Expand Down Expand Up @@ -270,13 +290,13 @@ func checkICPStatus(cl client.Client, key client.ObjectKey, profile string) (boo
}
var status map[string]*v1alpha2.InstallStatus_VersionStatus
switch profile {
case "minimal":
case minimalProfile:
status = minimalStatus
case "default":
case defaultProfile:
status = defaultStatus
case "sds":
case sdsProfile:
status = sdsStatus
case "demo":
case demoProfile:
status = demoStatus
}
installStatus := instance.GetStatus()
Expand All @@ -296,3 +316,45 @@ func checkICPStatus(cl client.Client, key client.ObjectKey, profile string) (boo
}
return true, nil
}

// TestReconcile test the reconciler process with manager from end to end.
func TestReconcile(t *testing.T) {
g := gomega.NewGomegaWithT(t)

// Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a
// channel when it is finished.
mgr, err := manager.New(cfg, manager.Options{})
g.Expect(err).NotTo(gomega.HaveOccurred())

c = mgr.GetClient()

rec := newReconciler(mgr)
recFn, requests := SetupTestReconcile(rec)

g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred())

stopMgr, mgrStopped := StartTestManager(mgr, g)

defer func() {
close(stopMgr)
mgrStopped.Wait()
}()

icp := &v1alpha2.IstioControlPlane{
Kind: "IstioControlPlane",
ApiVersion: "install.istio.io/v1alpha2",
ObjectMeta: metav1.ObjectMeta{
Name: icpkey.Name,
Namespace: icpkey.Namespace,
},
Spec: &v1alpha2.IstioControlPlaneSpec{
Profile: defaultProfile,
},
}

g.Expect(c.Create(context.TODO(), icp)).NotTo(gomega.HaveOccurred())

defer c.Delete(context.TODO(), icp)

g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest)))
}

0 comments on commit 52c4ae1

Please sign in to comment.