Skip to content

Commit

Permalink
[Enhancement] By using setup-envtest, setup k8s environment for unit …
Browse files Browse the repository at this point in the history
…test (#347)

Signed-off-by: yandongxiao <[email protected]>
  • Loading branch information
yandongxiao authored Dec 8, 2023
1 parent a56309a commit f82f706
Show file tree
Hide file tree
Showing 11 changed files with 295 additions and 22 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# Image URL to use all building/pushing image targets
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.23
ENVTEST_K8S_VERSION = 1.25

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
Expand Down Expand Up @@ -81,7 +81,7 @@ vet: ## Run go vet against code.

.PHONY: test
test: manifests generate fmt vet envtest ## Run tests.
@KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" GOFLAGS="-mod=vendor" go test ./... -coverprofile=coverage.data -timeout 30m || return 1
@KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" GOFLAGS="-mod=vendor" go test ./pkg/... -coverprofile=coverage.data -timeout 30m || return 1
@go tool cover -func=coverage.data

##@ Build
Expand Down
120 changes: 120 additions & 0 deletions pkg/controllers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package pkg

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/api/meta"
controllerruntime "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

v1 "github.com/StarRocks/starrocks-kubernetes-operator/pkg/apis/starrocks/v1"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/k8sutils/fake"
)

func TestSetupClusterReconciler(t *testing.T) {
type args struct {
mgr controllerruntime.Manager
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "test setup cluster reconciler",
args: args{
mgr: func() controllerruntime.Manager {
env := fake.NewEnvironment(fake.WithClusterCRD())
defer func() {
err := env.Stop()
assert.Nil(t, err)
}()
return fake.NewManager(env)
}(),
},
wantErr: false,
},
}

v1.Register()

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := SetupClusterReconciler(tt.args.mgr); (err != nil) != tt.wantErr {
t.Errorf("SetupClusterReconciler() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func TestSetupWarehouseReconciler(t *testing.T) {
env1 := fake.NewEnvironment(fake.WithClusterCRD())
env2 := fake.NewEnvironment(fake.WithClusterCRD(), fake.WithWarehouseCRD())
defer func() {
err := env1.Stop()
assert.Nil(t, err)
err = env2.Stop()
assert.Nil(t, err)
}()

type args struct {
mgr controllerruntime.Manager
ctx context.Context
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "test setup warehouse reconciler with no warehouse CRD",
args: args{
mgr: func() controllerruntime.Manager {
env1 = fake.NewEnvironment(fake.WithClusterCRD())
return fake.NewManager(env1)
}(),
ctx: context.Background(),
},
wantErr: false,
},
{
name: "test setup warehouse reconciler with warehouse CRD",
args: args{
mgr: func() controllerruntime.Manager {
return fake.NewManager(env2)
}(),
ctx: context.Background(),
},
wantErr: false,
},
}

v1.Register()

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := SetupWarehouseReconciler(tt.args.ctx, tt.args.mgr); (err != nil) != tt.wantErr {
t.Errorf("SetupWarehouseReconciler() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

type Reader struct {
hasWarehouseCRD bool
}

func (r Reader) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
return nil
}

func (r Reader) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
if r.hasWarehouseCRD {
return nil
}
return &meta.NoKindMatchError{}
}

var _ client.Reader = &Reader{}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package k8sutils
package fake

import (
"context"
Expand Down
111 changes: 111 additions & 0 deletions pkg/k8sutils/fake/fake_kubebuiler_manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package fake

import (
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"sigs.k8s.io/controller-runtime/pkg/manager"

v1 "github.com/StarRocks/starrocks-kubernetes-operator/pkg/apis/starrocks/v1"
)

type WithCRD func() *apiextensionsv1.CustomResourceDefinition

var (
clusterCRD = &apiextensionsv1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: "starrocksclusters.starrocks.com",
},
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
Group: "starrocks.com",
Names: apiextensionsv1.CustomResourceDefinitionNames{
Plural: "starrocksclusters",
Singular: "starrockscluster",
Kind: "StarRocksCluster",
},
Scope: apiextensionsv1.NamespaceScoped,
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
{
Name: "v1",
Served: true,
Storage: true,
Schema: &apiextensionsv1.CustomResourceValidation{
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
Type: "object",
},
},
},
},
},
}

warehouseCRD = &apiextensionsv1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: "starrockswarehouses.starrocks.com",
},
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
Group: "starrocks.com",
Names: apiextensionsv1.CustomResourceDefinitionNames{
Plural: "starrockswarehouses",
Singular: "starrockswarehouse",
Kind: "StarRocksWarehouse",
},
Scope: apiextensionsv1.NamespaceScoped,
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
{
Name: "v1",
Served: true,
Storage: true,
Schema: &apiextensionsv1.CustomResourceValidation{
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
Type: "object",
},
},
},
},
},
}
)

// NewEnvironment is used to create a fake manager, code inspired from pkg/manager/internal/integration/manager_test.go
// see https://github.com/kubernetes-sigs/controller-runtime/blob/main/pkg/manager/internal/integration/manager_test.go
// for more information
func NewEnvironment(crds ...WithCRD) *envtest.Environment {
env := &envtest.Environment{
Scheme: v1.Scheme,
CRDInstallOptions: envtest.CRDInstallOptions{},
}
for i := range crds {
env.CRDInstallOptions.CRDs = append(env.CRDInstallOptions.CRDs, crds[i]())
}
return env
}

func WithClusterCRD() WithCRD {
return func() *apiextensionsv1.CustomResourceDefinition {
return clusterCRD
}
}

func WithWarehouseCRD() WithCRD {
return func() *apiextensionsv1.CustomResourceDefinition {
return warehouseCRD
}
}

func NewManager(env *envtest.Environment) ctrl.Manager {
_, err := env.Start()
if err != nil {
panic(err)
}

mgr, err := manager.New(env.Config, manager.Options{
MetricsBindAddress: "0",
Scheme: v1.Scheme,
})
if err != nil {
panic(err)
}
return mgr
}
13 changes: 7 additions & 6 deletions pkg/k8sutils/k8sutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/scheme"

srapi "github.com/StarRocks/starrocks-kubernetes-operator/pkg/apis/starrocks/v1"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/k8sutils/fake"
)

var (
Expand Down Expand Up @@ -71,7 +72,7 @@ func Test_DeleteAutoscaler(t *testing.T) {
},
}

k8sClient := NewFakeClient(sch, &v1autoscaler, &v2autoscaler, &v2beta2Autoscaler)
k8sClient := fake.NewFakeClient(sch, &v1autoscaler, &v2autoscaler, &v2beta2Autoscaler)
// confirm the v1.autoscaler exist.
var cv1autoscaler v1.HorizontalPodAutoscaler
cerr := k8sClient.Get(context.Background(), types.NamespacedName{Name: "test", Namespace: "default"}, &cv1autoscaler)
Expand Down Expand Up @@ -120,7 +121,7 @@ func Test_getValueFromConfigmap(t *testing.T) {
{
name: "get value from configmap",
args: args{
k8sClient: NewFakeClient(sch, &corev1.ConfigMap{
k8sClient: fake.NewFakeClient(sch, &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
Expand Down Expand Up @@ -167,7 +168,7 @@ func Test_getValueFromSecret(t *testing.T) {
{
name: "get value from secret",
args: args{
k8sClient: NewFakeClient(sch, &corev1.Secret{
k8sClient: fake.NewFakeClient(sch, &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
Expand Down Expand Up @@ -213,7 +214,7 @@ func TestGetEnvVarValue(t *testing.T) {
{
name: "get value",
args: args{
k8sClient: NewFakeClient(sch),
k8sClient: fake.NewFakeClient(sch),
namespace: "default",
envVar: corev1.EnvVar{
Name: "test",
Expand All @@ -226,7 +227,7 @@ func TestGetEnvVarValue(t *testing.T) {
{
name: "get value from configmap",
args: args{
k8sClient: NewFakeClient(sch,
k8sClient: fake.NewFakeClient(sch,
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Expand Down Expand Up @@ -255,7 +256,7 @@ func TestGetEnvVarValue(t *testing.T) {
{
name: "get value from secret",
args: args{
k8sClient: NewFakeClient(sch,
k8sClient: fake.NewFakeClient(sch,
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Expand Down
40 changes: 40 additions & 0 deletions pkg/k8sutils/load/load_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package load

import (
"reflect"
"testing"

v1 "github.com/StarRocks/starrocks-kubernetes-operator/pkg/apis/starrocks/v1"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/common/resource_utils"
)

func TestSelector(t *testing.T) {
type args struct {
clusterName string
spec v1.SpecInterface
}
tests := []struct {
name string
args args
want resource_utils.Labels
}{
{
name: "test selector",
args: args{
clusterName: "kube-starrocks",
spec: (*v1.StarRocksFeProxySpec)(nil),
},
want: map[string]string{
"app.kubernetes.io/component": "fe-proxy",
"app.starrocks.ownerreference/name": "kube-starrocks-fe-proxy",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Selector(tt.args.clusterName, tt.args.spec); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Selector() = %v, want %v", got, tt.want)
}
})
}
}
4 changes: 2 additions & 2 deletions pkg/starrockscluster_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (

srapi "github.com/StarRocks/starrocks-kubernetes-operator/pkg/apis/starrocks/v1"
rutils "github.com/StarRocks/starrocks-kubernetes-operator/pkg/common/resource_utils"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/k8sutils"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/k8sutils/fake"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/sub_controller"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/sub_controller/cn"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/sub_controller/fe"
Expand All @@ -41,7 +41,7 @@ import (
func newStarRocksClusterController(objects ...runtime.Object) *StarRocksClusterReconciler {
srcController := &StarRocksClusterReconciler{}
srcController.Recorder = record.NewFakeRecorder(10)
srcController.Client = k8sutils.NewFakeClient(srapi.Scheme, objects...)
srcController.Client = fake.NewFakeClient(srapi.Scheme, objects...)
srcController.Scs = []sub_controller.ClusterSubController{fe.New(srcController.Client), cn.New(srcController.Client)}
return srcController
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/starrockswarehouse_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"

v1 "github.com/StarRocks/starrocks-kubernetes-operator/pkg/apis/starrocks/v1"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/k8sutils"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/k8sutils/fake"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/sub_controller"
"github.com/StarRocks/starrocks-kubernetes-operator/pkg/sub_controller/cn"
)
Expand All @@ -24,7 +24,7 @@ func init() {
}

func newStarRocksWarehouseController(objects ...runtime.Object) *StarRocksWarehouseReconciler {
client := k8sutils.NewFakeClient(v1.Scheme, objects...)
client := fake.NewFakeClient(v1.Scheme, objects...)
warehouseController := &StarRocksWarehouseReconciler{
recorder: record.NewFakeRecorder(10),
Client: client,
Expand Down
Loading

0 comments on commit f82f706

Please sign in to comment.