285 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Go
		
	
	
	
package seedjobs
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
 | 
						|
	jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/client"
 | 
						|
	"github.com/jenkinsci/kubernetes-operator/pkg/configuration"
 | 
						|
	"github.com/jenkinsci/kubernetes-operator/pkg/configuration/base/resources"
 | 
						|
 | 
						|
	"github.com/bndr/gojenkins"
 | 
						|
	"github.com/golang/mock/gomock"
 | 
						|
	"github.com/stretchr/testify/assert"
 | 
						|
	appsv1 "k8s.io/api/apps/v1"
 | 
						|
	corev1 "k8s.io/api/core/v1"
 | 
						|
	"k8s.io/apimachinery/pkg/api/errors"
 | 
						|
	"k8s.io/apimachinery/pkg/api/resource"
 | 
						|
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						|
	"k8s.io/apimachinery/pkg/types"
 | 
						|
	"k8s.io/client-go/kubernetes"
 | 
						|
	"k8s.io/client-go/kubernetes/scheme"
 | 
						|
	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 | 
						|
)
 | 
						|
 | 
						|
const agentSecret = "test-secret"
 | 
						|
 | 
						|
func jenkinsCustomResource() *v1alpha2.Jenkins {
 | 
						|
	return &v1alpha2.Jenkins{
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "jenkins",
 | 
						|
			Namespace: "default",
 | 
						|
		},
 | 
						|
		Spec: v1alpha2.JenkinsSpec{
 | 
						|
			Master: v1alpha2.JenkinsMaster{
 | 
						|
				Annotations: map[string]string{"test": "label"},
 | 
						|
				Containers: []v1alpha2.Container{
 | 
						|
					{
 | 
						|
						Name:  resources.JenkinsMasterContainerName,
 | 
						|
						Image: "jenkins/jenkins",
 | 
						|
						Resources: corev1.ResourceRequirements{
 | 
						|
							Requests: corev1.ResourceList{
 | 
						|
								corev1.ResourceCPU:    resource.MustParse("300m"),
 | 
						|
								corev1.ResourceMemory: resource.MustParse("500Mi"),
 | 
						|
							},
 | 
						|
							Limits: corev1.ResourceList{
 | 
						|
								corev1.ResourceCPU:    resource.MustParse("2"),
 | 
						|
								corev1.ResourceMemory: resource.MustParse("2Gi"),
 | 
						|
							},
 | 
						|
						},
 | 
						|
					},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			SeedJobs: []v1alpha2.SeedJob{
 | 
						|
				{
 | 
						|
					ID:                    "jenkins-operator-e2e",
 | 
						|
					JenkinsCredentialType: v1alpha2.NoJenkinsCredentialCredentialType,
 | 
						|
					Targets:               "cicd/jobs/*.jenkins",
 | 
						|
					Description:           "Jenkins Operator e2e tests repository",
 | 
						|
					RepositoryBranch:      "master",
 | 
						|
					RepositoryURL:         "https://github.com/jenkinsci/kubernetes-operator.git",
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestEnsureSeedJobs(t *testing.T) {
 | 
						|
	t.Run("happy", func(t *testing.T) {
 | 
						|
		// given
 | 
						|
		ctrl := gomock.NewController(t)
 | 
						|
		ctx := context.TODO()
 | 
						|
		defer ctrl.Finish()
 | 
						|
 | 
						|
		jenkinsClient := jenkinsclient.NewMockJenkins(ctrl)
 | 
						|
		fakeClient := fake.NewClientBuilder().Build()
 | 
						|
		err := v1alpha2.SchemeBuilder.AddToScheme(scheme.Scheme)
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		jenkins := jenkinsCustomResource()
 | 
						|
		err = fakeClient.Create(ctx, jenkins)
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		testNode := &gojenkins.Node{
 | 
						|
			Raw: &gojenkins.NodeResponse{
 | 
						|
				DisplayName: AgentName,
 | 
						|
			},
 | 
						|
		}
 | 
						|
 | 
						|
		config := configuration.Configuration{
 | 
						|
			Client:        fakeClient,
 | 
						|
			ClientSet:     kubernetes.Clientset{},
 | 
						|
			Notifications: nil,
 | 
						|
			Jenkins:       jenkins,
 | 
						|
		}
 | 
						|
 | 
						|
		seedJobCreatingScript, err := seedJobCreatingGroovyScript(jenkins.Spec.SeedJobs[0])
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		jenkinsClient.EXPECT().GetNode(AgentName).Return(nil, nil).AnyTimes()
 | 
						|
		jenkinsClient.EXPECT().CreateNode(AgentName, 1, "The jenkins-operator generated agent", "/home/jenkins", AgentName).Return(testNode, nil).AnyTimes()
 | 
						|
		jenkinsClient.EXPECT().GetNodeSecret(AgentName).Return(agentSecret, nil).AnyTimes()
 | 
						|
		jenkinsClient.EXPECT().ExecuteScript(seedJobCreatingScript).AnyTimes()
 | 
						|
 | 
						|
		seedJobClient := New(jenkinsClient, config)
 | 
						|
 | 
						|
		// when
 | 
						|
		_, err = seedJobClient.EnsureSeedJobs(jenkins)
 | 
						|
 | 
						|
		// then
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		var agentDeployment appsv1.Deployment
 | 
						|
		err = fakeClient.Get(ctx, types.NamespacedName{Namespace: jenkins.Namespace, Name: agentDeploymentName(*jenkins, AgentName)}, &agentDeployment)
 | 
						|
		assert.NoError(t, err)
 | 
						|
		assert.Equal(t, "jenkins/inbound-agent:3248.v65ecb_254c298-6", agentDeployment.Spec.Template.Spec.Containers[0].Image)
 | 
						|
		assert.Equal(t, "JENKINS_WEB_SOCKET", agentDeployment.Spec.Template.Spec.Containers[0].Env[0].Name)
 | 
						|
		assert.Equal(t, "true", agentDeployment.Spec.Template.Spec.Containers[0].Env[0].Value)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("delete agent deployment when no seed jobs", func(t *testing.T) {
 | 
						|
		// given
 | 
						|
		ctrl := gomock.NewController(t)
 | 
						|
		ctx := context.TODO()
 | 
						|
		defer ctrl.Finish()
 | 
						|
 | 
						|
		jenkins := jenkinsCustomResource()
 | 
						|
		jenkins.Spec.SeedJobs = []v1alpha2.SeedJob{}
 | 
						|
 | 
						|
		jenkinsClient := jenkinsclient.NewMockJenkins(ctrl)
 | 
						|
		fakeClient := fake.NewClientBuilder().Build()
 | 
						|
		err := v1alpha2.SchemeBuilder.AddToScheme(scheme.Scheme)
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		config := configuration.Configuration{
 | 
						|
			Client:        fakeClient,
 | 
						|
			ClientSet:     kubernetes.Clientset{},
 | 
						|
			Notifications: nil,
 | 
						|
			Jenkins:       jenkins,
 | 
						|
		}
 | 
						|
 | 
						|
		jenkinsClient.EXPECT().GetNode(AgentName).AnyTimes()
 | 
						|
		jenkinsClient.EXPECT().CreateNode(AgentName, 1, "The jenkins-operator generated agent", "/home/jenkins", AgentName).AnyTimes()
 | 
						|
		jenkinsClient.EXPECT().GetNodeSecret(AgentName).Return(agentSecret, nil).AnyTimes()
 | 
						|
 | 
						|
		seedJobsClient := New(jenkinsClient, config)
 | 
						|
 | 
						|
		err = fakeClient.Create(ctx, &appsv1.Deployment{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{
 | 
						|
				Name:      agentDeploymentName(*jenkins, AgentName),
 | 
						|
				Namespace: jenkins.Namespace,
 | 
						|
			},
 | 
						|
		})
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		// when
 | 
						|
		_, err = seedJobsClient.EnsureSeedJobs(jenkins)
 | 
						|
 | 
						|
		// then
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		var deployment appsv1.Deployment
 | 
						|
		err = fakeClient.Get(ctx, types.NamespacedName{Namespace: jenkins.Namespace, Name: agentDeploymentName(*jenkins, AgentName)}, &deployment)
 | 
						|
 | 
						|
		assert.True(t, errors.IsNotFound(err), "Agent deployment hasn't been deleted")
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
func TestCreateAgent(t *testing.T) {
 | 
						|
	t.Run("don't fail when deployment is already created", func(t *testing.T) {
 | 
						|
		// given
 | 
						|
		ctrl := gomock.NewController(t)
 | 
						|
		ctx := context.TODO()
 | 
						|
		defer ctrl.Finish()
 | 
						|
 | 
						|
		jenkins := jenkinsCustomResource()
 | 
						|
 | 
						|
		jenkinsClient := jenkinsclient.NewMockJenkins(ctrl)
 | 
						|
		fakeClient := fake.NewClientBuilder().Build()
 | 
						|
		err := v1alpha2.SchemeBuilder.AddToScheme(scheme.Scheme)
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		jenkinsClient.EXPECT().GetNode(AgentName).AnyTimes()
 | 
						|
		jenkinsClient.EXPECT().CreateNode(AgentName, 1, "The jenkins-operator generated agent", "/home/jenkins", AgentName).AnyTimes()
 | 
						|
		jenkinsClient.EXPECT().GetNodeSecret(AgentName).Return(agentSecret, nil).AnyTimes()
 | 
						|
 | 
						|
		config := configuration.Configuration{
 | 
						|
			Client:        fakeClient,
 | 
						|
			ClientSet:     kubernetes.Clientset{},
 | 
						|
			Notifications: nil,
 | 
						|
			Jenkins:       &v1alpha2.Jenkins{},
 | 
						|
		}
 | 
						|
 | 
						|
		seedJobsClient := New(jenkinsClient, config)
 | 
						|
 | 
						|
		err = fakeClient.Create(ctx, &appsv1.Deployment{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{
 | 
						|
				Name:      agentDeploymentName(*jenkins, AgentName),
 | 
						|
				Namespace: jenkins.Namespace,
 | 
						|
			},
 | 
						|
		})
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		// when
 | 
						|
		err = seedJobsClient.createAgent(jenkinsClient, fakeClient, jenkinsCustomResource(), jenkins.Namespace, AgentName)
 | 
						|
 | 
						|
		// then
 | 
						|
		assert.NoError(t, err)
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
func TestSeedJobs_isRecreatePodNeeded(t *testing.T) {
 | 
						|
	config := configuration.Configuration{
 | 
						|
		Client:        nil,
 | 
						|
		ClientSet:     kubernetes.Clientset{},
 | 
						|
		Notifications: nil,
 | 
						|
		Jenkins:       &v1alpha2.Jenkins{},
 | 
						|
	}
 | 
						|
	seedJobsClient := New(nil, config)
 | 
						|
	t.Run("empty", func(t *testing.T) {
 | 
						|
		jenkins := v1alpha2.Jenkins{}
 | 
						|
 | 
						|
		got := seedJobsClient.isRecreatePodNeeded(jenkins)
 | 
						|
 | 
						|
		assert.False(t, got)
 | 
						|
	})
 | 
						|
	t.Run("same", func(t *testing.T) {
 | 
						|
		jenkins := v1alpha2.Jenkins{
 | 
						|
			Spec: v1alpha2.JenkinsSpec{
 | 
						|
				SeedJobs: []v1alpha2.SeedJob{
 | 
						|
					{
 | 
						|
						ID: "name",
 | 
						|
					},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			Status: v1alpha2.JenkinsStatus{
 | 
						|
				CreatedSeedJobs: []string{"name"},
 | 
						|
			},
 | 
						|
		}
 | 
						|
 | 
						|
		got := seedJobsClient.isRecreatePodNeeded(jenkins)
 | 
						|
 | 
						|
		assert.False(t, got)
 | 
						|
	})
 | 
						|
	t.Run("removed one", func(t *testing.T) {
 | 
						|
		jenkins := v1alpha2.Jenkins{
 | 
						|
			Spec: v1alpha2.JenkinsSpec{
 | 
						|
				SeedJobs: []v1alpha2.SeedJob{
 | 
						|
					{
 | 
						|
						ID: "name1",
 | 
						|
					},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			Status: v1alpha2.JenkinsStatus{
 | 
						|
				CreatedSeedJobs: []string{"name1", "name2"},
 | 
						|
			},
 | 
						|
		}
 | 
						|
 | 
						|
		got := seedJobsClient.isRecreatePodNeeded(jenkins)
 | 
						|
 | 
						|
		assert.True(t, got)
 | 
						|
	})
 | 
						|
	t.Run("renamed one", func(t *testing.T) {
 | 
						|
		jenkins := v1alpha2.Jenkins{
 | 
						|
			Spec: v1alpha2.JenkinsSpec{
 | 
						|
				SeedJobs: []v1alpha2.SeedJob{
 | 
						|
					{
 | 
						|
						ID: "name1",
 | 
						|
					},
 | 
						|
					{
 | 
						|
						ID: "name3",
 | 
						|
					},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			Status: v1alpha2.JenkinsStatus{
 | 
						|
				CreatedSeedJobs: []string{"name1", "name2"},
 | 
						|
			},
 | 
						|
		}
 | 
						|
 | 
						|
		got := seedJobsClient.isRecreatePodNeeded(jenkins)
 | 
						|
 | 
						|
		assert.True(t, got)
 | 
						|
	})
 | 
						|
}
 |