poolprovider-for-k8s/crd_controller_test.go

261 строка
7.1 KiB
Go

package main
import (
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
v1alpha1 "github.com/microsoft/poolprovider-for-k8s/pkg/apis/dev/v1alpha1"
v1controller "github.com/microsoft/poolprovider-for-k8s/pkg/controller/azurepipelinespool"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"context"
"time"
"k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
var azurepipelinepoolcr *v1alpha1.AzurePipelinesPool
var (
name = "azurepipelinepool-operator"
namespace = "azuredevops"
)
func SetupCustomResource() {
// create custom resource
azurepipelinepoolcr = &v1alpha1.AzurePipelinesPool{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Spec: v1alpha1.AzurePipelinesPoolSpec{
ControllerName: "prebansa/webserverimage",
BuildkitReplicaCount: 1,
AgentPools: []v1alpha1.AgentPoolSpec{
{
PoolName: "linux",
PoolSpec: &corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "vsts-agent",
Image: "prebansa/myagent:v5.16",
},
},
},
},
},
Initialized: true,
},
}
SetTestingEnvironmentVariables()
s := scheme.Scheme
s.AddKnownTypes(v1alpha1.SchemeGroupVersion, azurepipelinepoolcr)
v1alpha1.SetClient(s)
}
func TestControllerMustCreateExternalResources(t *testing.T) {
SetupCustomResource()
objs := []runtime.Object{
azurepipelinepoolcr,
}
s := scheme.Scheme
// Create a fake client to mock API calls.
cl := fake.NewFakeClient(objs...)
v1alpha1.SetClient(s)
r := &v1controller.ReconcileAzurePipelinesPool{Client: cl, Scheme: s}
// Mock request to simulate Reconcile() being called on an event for a
// watched resource .
req := reconcile.Request{
NamespacedName: types.NamespacedName{
Name: name,
Namespace: namespace,
},
}
for i := 0; i < 5; i++ {
res, err := r.Reconcile(req)
if err != nil {
t.Fatalf("reconcile: (%v)", err)
}
if res != (reconcile.Result{}) {
t.Error("reconcile did not return an empty Result")
}
}
// Check the deployment is created
expectedDeployment := v1controller.AddnewDeploymentForCR(azurepipelinepoolcr)
deployment := &appsv1.Deployment{}
err := cl.Get(context.TODO(), types.NamespacedName{Name: expectedDeployment.Name, Namespace: expectedDeployment.Namespace}, deployment)
if err != nil {
t.Fatalf("get deployment failed: (%v)", err)
}
expectedBuildkitPod := v1controller.AddnewBuildkitPodForCR(azurepipelinepoolcr)
buildkitpod := &appsv1.StatefulSet{}
err = cl.Get(context.TODO(), types.NamespacedName{Name: expectedBuildkitPod.Name, Namespace: expectedBuildkitPod.Namespace}, buildkitpod)
if err != nil {
t.Fatalf("get buildkit pod failed: (%v)", err)
}
expectedService := v1controller.AddnewServiceForCR(azurepipelinepoolcr)
svc := &corev1.Service{}
err = cl.Get(context.TODO(), types.NamespacedName{Name: expectedService.Name, Namespace: expectedService.Namespace}, svc)
if err != nil {
t.Fatalf("get service failed: (%v)", err)
}
expectedBuildkitService := v1controller.AddnewBuildkitServiceForCR(azurepipelinepoolcr)
buildkitsvc := &corev1.Service{}
err = cl.Get(context.TODO(), types.NamespacedName{Name: expectedBuildkitService.Name, Namespace: expectedBuildkitService.Namespace}, buildkitsvc)
if err != nil {
t.Fatalf("get buildkit service failed: (%v)", err)
}
expectedMap := v1controller.AddnewConfigMapForCR(azurepipelinepoolcr)
configmap := &corev1.ConfigMap{}
err = cl.Get(context.TODO(), types.NamespacedName{Name: expectedMap.Name, Namespace: expectedMap.Namespace}, configmap)
if err != nil {
t.Fatalf("get pod: (%v)", err)
}
}
func TestControllerMustRecreatePodIfDeleted(t *testing.T) {
SetupCustomResource()
objs := []runtime.Object{
azurepipelinepoolcr,
}
s := scheme.Scheme
// Create a fake client to mock API calls.
cl := fake.NewFakeClient(objs...)
v1alpha1.SetClient(s)
r := &v1controller.ReconcileAzurePipelinesPool{Client: cl, Scheme: s}
// Mock request to simulate Reconcile() being called on an event for a
// watched resource .
req := reconcile.Request{
NamespacedName: types.NamespacedName{
Name: name,
Namespace: namespace,
},
}
for i := 0; i < 5; i++ {
res, err := r.Reconcile(req)
if err != nil {
t.Fatalf("reconcile: (%v)", err)
}
if res != (reconcile.Result{}) {
t.Error("reconcile did not return an empty Result")
}
}
expectedDeployment := v1controller.AddnewDeploymentForCR(azurepipelinepoolcr)
deployment := &appsv1.Deployment{}
err := cl.Get(context.TODO(), types.NamespacedName{Name: expectedDeployment.Name, Namespace: expectedDeployment.Namespace}, deployment)
if err != nil {
t.Fatalf("get deployment: (%v)", err)
}
//delete deployment
errd := cl.Delete(context.TODO(), deployment)
if errd != nil {
t.Fatalf("delete pod failed: (%v)", errd)
}
deletereq := reconcile.Request{
NamespacedName: types.NamespacedName{
Name: name,
Namespace: namespace,
},
}
res, err := r.Reconcile(deletereq)
if err != nil {
t.Fatalf("reconcile: (%v)", err)
}
if res != (reconcile.Result{}) {
t.Error("reconcile did not return an empty Result")
}
time.Sleep(time.Second * 1)
recreateddeployment := &appsv1.Deployment{}
errrecreate := cl.Get(context.TODO(), types.NamespacedName{Name: expectedDeployment.Name, Namespace: expectedDeployment.Namespace}, recreateddeployment)
if errrecreate != nil {
t.Fatalf("get pod not restarted: (%v)", errrecreate)
}
}
func TestControllerMustRecreateStatefulsetIfDeleted(t *testing.T) {
SetupCustomResource()
objs := []runtime.Object{
azurepipelinepoolcr,
}
s := scheme.Scheme
// Create a fake client to mock API calls.
cl := fake.NewFakeClient(objs...)
v1alpha1.SetClient(s)
r := &v1controller.ReconcileAzurePipelinesPool{Client: cl, Scheme: s}
// Mock request to simulate Reconcile() being called on an event for a
// watched resource .
req := reconcile.Request{
NamespacedName: types.NamespacedName{
Name: name,
Namespace: namespace,
},
}
for i := 0; i < 5; i++ {
res, err := r.Reconcile(req)
if err != nil {
t.Fatalf("reconcile: (%v)", err)
}
if res != (reconcile.Result{}) {
t.Error("reconcile did not return an empty Result")
}
}
expectedPod1 := v1controller.AddnewBuildkitPodForCR(azurepipelinepoolcr)
statefulset := &appsv1.StatefulSet{}
err := cl.Get(context.TODO(), types.NamespacedName{Name: expectedPod1.Name, Namespace: expectedPod1.Namespace}, statefulset)
if err != nil {
t.Fatalf("get pod: (%v)", err)
}
//delete statefulset
errd := cl.Delete(context.TODO(), statefulset)
if errd != nil {
t.Fatalf("delete pod failed: (%v)", errd)
}
res, err := r.Reconcile(req)
if err != nil {
t.Fatalf("reconcile: (%v)", err)
}
if res != (reconcile.Result{}) {
t.Error("reconcile did not return an empty Result")
}
newstatefulset := &appsv1.StatefulSet{}
err1 := cl.Get(context.TODO(), types.NamespacedName{Name: expectedPod1.Name, Namespace: expectedPod1.Namespace}, newstatefulset)
if err1 != nil {
t.Fatalf("get pod not restarted: (%v)", err1)
}
}