123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- package controllers
- import (
- "fmt"
- "reflect"
- "testing"
- "github.com/golang/mock/gomock"
- appv1 "github.com/kakao/bluegreen/api/v1"
- "github.com/kakao/bluegreen/controllers/bluegreen"
- "github.com/stretchr/testify/assert"
- v1 "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/types"
- utilruntime "k8s.io/apimachinery/pkg/util/runtime"
- clientgoscheme "k8s.io/client-go/kubernetes/scheme"
- "sigs.k8s.io/controller-runtime/pkg/reconcile"
- )
- var (
- testScheme = runtime.NewScheme()
- )
- func init() {
- utilruntime.Must(clientgoscheme.AddToScheme(testScheme))
- utilruntime.Must(appv1.AddToScheme(testScheme))
- }
- func TestBlueGreenResconciler(t *testing.T) {
- ctrl := gomock.NewController(t)
- defer ctrl.Finish()
- c := bluegreen.NewMockClient(ctrl)
- r := &BlueGreenReconciler{
- Client: c,
- Scheme: testScheme,
- }
- req := reconcile.Request{NamespacedName: types.NamespacedName{
- Namespace: "test",
- Name: "bluegreen",
- }}
- bg := appv1.BlueGreen{
- ObjectMeta: metav1.ObjectMeta{
- Namespace: req.Namespace,
- Name: req.Name,
- },
- Spec: appv1.BlueGreenSpec{
- RouteTo: appv1.Blue,
- BlueSpec: &v1.PodSpec{
- Containers: []v1.Container{{Name: "test"}},
- },
- GreenSpec: nil,
- },
- }
- blugreenMatcher := &GenericMatcher[*appv1.BlueGreen]{func(in *appv1.BlueGreen) bool { return reflect.DeepEqual(bg, *in) }}
- // EXPECTING
- c.EXPECT().Get(gomock.Any(), gomock.Eq(req.NamespacedName), gomock.Any()).
- SetArg(2, bg).
- Return(nil)
- c.EXPECT().CreateOrUpdateService(gomock.Any(), blugreenMatcher).
- Return(nil)
- c.EXPECT().CreateOrUpdateDeployment(gomock.Any(), blugreenMatcher, gomock.Eq(appv1.Blue), gomock.Eq(*bg.Spec.BlueSpec)).
- Return(nil)
- c.EXPECT().UpdateStatus(gomock.Any(),
- &GenericMatcher[*appv1.BlueGreen]{func(bg *appv1.BlueGreen) bool { return *bg.Status.RouteTo == appv1.Blue }},
- ).Return(nil)
- // Reconciling
- result, err := r.Reconcile(ctx, req)
- // Validation
- assert.NoError(t, err)
- assert.Equal(t, reconcile.Result{Requeue: false}, result)
- }
- var _ gomock.Matcher = &GenericMatcher[interface{}]{}
- type GenericMatcher[T interface{}] struct {
- F func(T) bool
- }
- func (m *GenericMatcher[T]) Matches(x interface{}) bool {
- if v, ok := x.(T); ok {
- return m.F(v)
- } else {
- return false
- }
- }
- func (m *GenericMatcher[T]) String() string {
- return fmt.Sprintf("matching %v", reflect.TypeOf(new(T)))
- }
- var _ gomock.Matcher = &RuntimeObjectMatcher{}
- type RuntimeObjectMatcher struct {
- object runtime.Object
- }
- // Matches implements gomock.Matcher
- func (r *RuntimeObjectMatcher) Matches(x interface{}) bool {
- return reflect.DeepEqual(r.object, x)
- }
- // String implements gomock.Matcher
- func (r *RuntimeObjectMatcher) String() string {
- gok := r.object.GetObjectKind().GroupVersionKind()
- return fmt.Sprintf("should match %s/%s/%s", gok.Group, gok.Version, gok.Kind)
- }
|