Added TestPlugins, TestRestart and TestRestoreBackup (#504)
Co-authored-by: Tomasz Sęk
This commit is contained in:
		
							parent
							
								
									294be87c64
								
							
						
					
					
						commit
						021ebb4745
					
				|  | @ -211,14 +211,6 @@ func (r *JenkinsReconciler) reconcile(request reconcile.Request) (reconcile.Resu | |||
| 		return reconcile.Result{Requeue: true}, jenkins, nil | ||||
| 	} | ||||
| 
 | ||||
| 	requeue, err = r.handleDeprecatedData(jenkins) | ||||
| 	if err != nil { | ||||
| 		return reconcile.Result{}, jenkins, err | ||||
| 	} | ||||
| 	if requeue { | ||||
| 		return reconcile.Result{Requeue: true}, jenkins, nil | ||||
| 	} | ||||
| 
 | ||||
| 	config := r.newJenkinsReconcilier(jenkins) | ||||
| 	// Reconcile base configuration
 | ||||
| 	baseConfiguration := base.New(config, r.JenkinsAPIConnectionSettings) | ||||
|  | @ -367,7 +359,7 @@ func (r *JenkinsReconciler) setDefaults(jenkins *v1alpha2.Jenkins) (requeue bool | |||
| 	if jenkinsContainer.ReadinessProbe == nil { | ||||
| 		logger.Info("Setting default Jenkins readinessProbe") | ||||
| 		changed = true | ||||
| 		jenkinsContainer.ReadinessProbe = resources.NewSimpleProbe(containerProbeURI, containerProbePortName, corev1.URISchemeHTTP, 30) | ||||
| 		jenkinsContainer.ReadinessProbe = resources.NewProbe(containerProbeURI, containerProbePortName, corev1.URISchemeHTTP, 30, 1, 3) | ||||
| 	} | ||||
| 	if jenkinsContainer.LivenessProbe == nil { | ||||
| 		logger.Info("Setting default Jenkins livenessProbe") | ||||
|  | @ -493,7 +485,3 @@ func basePlugins() (result []v1alpha2.Plugin) { | |||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (r *JenkinsReconciler) handleDeprecatedData(_ *v1alpha2.Jenkins) (requeue bool, err error) { | ||||
| 	return false, nil | ||||
| } | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import ( | |||
| 	"k8s.io/apimachinery/pkg/util/intstr" | ||||
| ) | ||||
| 
 | ||||
| func NewSimpleProbe(uri string, port string, scheme corev1.URIScheme, initialDelaySeconds int32) *corev1.Probe { | ||||
| func NewProbe(uri string, port string, scheme corev1.URIScheme, initialDelaySeconds, timeoutSeconds, failureThreshold int32) *corev1.Probe { | ||||
| 	return &corev1.Probe{ | ||||
| 		Handler: corev1.Handler{ | ||||
| 			HTTPGet: &corev1.HTTPGetAction{ | ||||
|  | @ -15,14 +15,9 @@ func NewSimpleProbe(uri string, port string, scheme corev1.URIScheme, initialDel | |||
| 			}, | ||||
| 		}, | ||||
| 		InitialDelaySeconds: initialDelaySeconds, | ||||
| 		TimeoutSeconds:      timeoutSeconds, | ||||
| 		FailureThreshold:    failureThreshold, | ||||
| 		SuccessThreshold:    int32(1), | ||||
| 		PeriodSeconds:       int32(1), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func NewProbe(uri string, port string, scheme corev1.URIScheme, initialDelaySeconds, timeoutSeconds, failureThreshold int32) *corev1.Probe { | ||||
| 	p := NewSimpleProbe(uri, port, scheme, initialDelaySeconds) | ||||
| 	p.TimeoutSeconds = timeoutSeconds | ||||
| 	p.FailureThreshold = failureThreshold | ||||
| 	return p | ||||
| } | ||||
|  |  | |||
|  | @ -23,49 +23,6 @@ import ( | |||
| 
 | ||||
| const e2e = "e2e" | ||||
| 
 | ||||
| // FIXME
 | ||||
| /*func TestPlugins(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 	namespace, ctx := setupTest(t) | ||||
| 	// Deletes test namespace
 | ||||
| 	defer showLogsAndCleanup(t, ctx) | ||||
| 
 | ||||
| 	jobID := "k8s-e2e" | ||||
| 
 | ||||
| 	priorityClassName := "" | ||||
| 	seedJobs := &[]v1alpha2.SeedJob{ | ||||
| 		{ | ||||
| 			ID:                    "jenkins-operator", | ||||
| 			CredentialID:          "jenkins-operator", | ||||
| 			JenkinsCredentialType: v1alpha2.NoJenkinsCredentialCredentialType, | ||||
| 			Targets:               "cicd/jobs/k8s.jenkins", | ||||
| 			Description:           "Jenkins Operator repository", | ||||
| 			RepositoryBranch:      "master", | ||||
| 			RepositoryURL:         "https://github.com/jenkinsci/kubernetes-operator.git", | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	jenkins := createJenkinsCR(t, "k8s-e2e", namespace, seedJobs, v1alpha2.GroovyScripts{}, v1alpha2.ConfigurationAsCode{}, priorityClassName) | ||||
| 	waitForJenkinsUserConfigurationToComplete(t, jenkins) | ||||
| 
 | ||||
| 	jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(t, jenkins, namespace) | ||||
| 	defer cleanUpFunc() | ||||
| 	waitForJob(t, jenkinsClient, jobID) | ||||
| 	job, err := jenkinsClient.GetJob(jobID) | ||||
| 
 | ||||
| 	require.NoError(t, err, job) | ||||
| 	i, err := job.InvokeSimple(map[string]string{}) | ||||
| 	require.NoError(t, err, i) | ||||
| 	// FIXME: waitForJobToFinish use
 | ||||
| 	time.Sleep(100 * time.Second) // wait for the build to complete
 | ||||
| 
 | ||||
| 	job, err = jenkinsClient.GetJob(jobID) | ||||
| 	require.NoError(t, err, job) | ||||
| 	build, err := job.GetLastBuild() | ||||
| 	require.NoError(t, err) | ||||
| 	assert.True(t, build.IsGood()) | ||||
| }*/ | ||||
| 
 | ||||
| func createUserConfigurationSecret(namespace string, stringData map[string]string) { | ||||
| 	By("creating user configuration secret") | ||||
| 
 | ||||
|  |  | |||
|  | @ -139,3 +139,58 @@ var _ = Describe("Jenkins controller priority class", func() { | |||
| 		}) | ||||
| 	}) | ||||
| }) | ||||
| 
 | ||||
| var _ = Describe("Jenkins controller plugins test", func() { | ||||
| 
 | ||||
| 	const ( | ||||
| 		jenkinsCRName     = e2e | ||||
| 		priorityClassName = "" | ||||
| 		jobID             = "k8s-e2e" | ||||
| 	) | ||||
| 
 | ||||
| 	var ( | ||||
| 		namespace *corev1.Namespace | ||||
| 		jenkins   *v1alpha2.Jenkins | ||||
| 		mySeedJob = seedJobConfig{ | ||||
| 			SeedJob: v1alpha2.SeedJob{ | ||||
| 				ID:                    "jenkins-operator", | ||||
| 				CredentialID:          "jenkins-operator", | ||||
| 				JenkinsCredentialType: v1alpha2.NoJenkinsCredentialCredentialType, | ||||
| 				Targets:               "cicd/jobs/k8s.jenkins", | ||||
| 				Description:           "Jenkins Operator repository", | ||||
| 				RepositoryBranch:      "master", | ||||
| 				RepositoryURL:         "https://github.com/jenkinsci/kubernetes-operator.git", | ||||
| 			}, | ||||
| 		} | ||||
| 		groovyScripts = v1alpha2.GroovyScripts{ | ||||
| 			Customization: v1alpha2.Customization{ | ||||
| 				Configurations: []v1alpha2.ConfigMapRef{}, | ||||
| 			}, | ||||
| 		} | ||||
| 		casc = v1alpha2.ConfigurationAsCode{ | ||||
| 			Customization: v1alpha2.Customization{ | ||||
| 				Configurations: []v1alpha2.ConfigMapRef{}, | ||||
| 			}, | ||||
| 		} | ||||
| 	) | ||||
| 
 | ||||
| 	BeforeEach(func() { | ||||
| 		namespace = createNamespace() | ||||
| 		jenkins = createJenkinsCRSafe(jenkinsCRName, namespace.Name, &[]v1alpha2.SeedJob{mySeedJob.SeedJob}, groovyScripts, casc, priorityClassName) | ||||
| 	}) | ||||
| 
 | ||||
| 	AfterEach(func() { | ||||
| 		destroyNamespace(namespace) | ||||
| 	}) | ||||
| 
 | ||||
| 	Context("when deploying CR with a SeedJob to cluster", func() { | ||||
| 		It("runs kubernetes plugin job successfully", func() { | ||||
| 			waitForJenkinsUserConfigurationToComplete(jenkins) | ||||
| 			jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(jenkins, namespace.Name) | ||||
| 			defer cleanUpFunc() | ||||
| 			waitForJobCreation(jenkinsClient, jobID) | ||||
| 			verifyJobCanBeRun(jenkinsClient, jobID) | ||||
| 			verifyJobHasBeenRunCorrectly(jenkinsClient, jobID) | ||||
| 		}) | ||||
| 	}) | ||||
| }) | ||||
|  |  | |||
|  | @ -0,0 +1,108 @@ | |||
| package e2e | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/jenkinsci/kubernetes-operator/api/v1alpha2" | ||||
| 
 | ||||
| 	. "github.com/onsi/ginkgo" | ||||
| 	. "github.com/onsi/gomega" | ||||
| 	corev1 "k8s.io/api/core/v1" | ||||
| 	// +kubebuilder:scaffold:imports
 | ||||
| ) | ||||
| 
 | ||||
| var _ = Describe("Jenkins controller", func() { | ||||
| 
 | ||||
| 	const ( | ||||
| 		jenkinsCRName     = e2e | ||||
| 		priorityClassName = "" | ||||
| 	) | ||||
| 
 | ||||
| 	var ( | ||||
| 		namespace     *corev1.Namespace | ||||
| 		jenkins       *v1alpha2.Jenkins | ||||
| 		groovyScripts = v1alpha2.GroovyScripts{ | ||||
| 			Customization: v1alpha2.Customization{ | ||||
| 				Configurations: []v1alpha2.ConfigMapRef{}, | ||||
| 			}, | ||||
| 		} | ||||
| 		casc = v1alpha2.ConfigurationAsCode{ | ||||
| 			Customization: v1alpha2.Customization{ | ||||
| 				Configurations: []v1alpha2.ConfigMapRef{}, | ||||
| 			}, | ||||
| 		} | ||||
| 	) | ||||
| 
 | ||||
| 	BeforeEach(func() { | ||||
| 		namespace = createNamespace() | ||||
| 
 | ||||
| 		configureAuthorizationToUnSecure(namespace.Name, userConfigurationConfigMapName) | ||||
| 		jenkins = createJenkinsCR(jenkinsCRName, namespace.Name, nil, groovyScripts, casc, priorityClassName) | ||||
| 	}) | ||||
| 
 | ||||
| 	AfterEach(func() { | ||||
| 		destroyNamespace(namespace) | ||||
| 	}) | ||||
| 
 | ||||
| 	Context("when restarting Jenkins master pod", func() { | ||||
| 		It("new Jenkins Master pod should be created", func() { | ||||
| 			waitForJenkinsBaseConfigurationToComplete(jenkins) | ||||
| 			restartJenkinsMasterPod(jenkins) | ||||
| 			waitForRecreateJenkinsMasterPod(jenkins) | ||||
| 			checkBaseConfigurationCompleteTimeIsNotSet(jenkins) | ||||
| 			waitForJenkinsBaseConfigurationToComplete(jenkins) | ||||
| 		}) | ||||
| 	}) | ||||
| }) | ||||
| 
 | ||||
| var _ = Describe("Jenkins controller", func() { | ||||
| 
 | ||||
| 	const ( | ||||
| 		jenkinsCRName     = e2e | ||||
| 		priorityClassName = "" | ||||
| 	) | ||||
| 
 | ||||
| 	var ( | ||||
| 		namespace     *corev1.Namespace | ||||
| 		jenkins       *v1alpha2.Jenkins | ||||
| 		groovyScripts = v1alpha2.GroovyScripts{ | ||||
| 			Customization: v1alpha2.Customization{ | ||||
| 				Configurations: []v1alpha2.ConfigMapRef{ | ||||
| 					{ | ||||
| 						Name: userConfigurationConfigMapName, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		} | ||||
| 		casc = v1alpha2.ConfigurationAsCode{ | ||||
| 			Customization: v1alpha2.Customization{ | ||||
| 				Configurations: []v1alpha2.ConfigMapRef{}, | ||||
| 			}, | ||||
| 		} | ||||
| 	) | ||||
| 
 | ||||
| 	BeforeEach(func() { | ||||
| 		namespace = createNamespace() | ||||
| 
 | ||||
| 		configureAuthorizationToUnSecure(namespace.Name, userConfigurationConfigMapName) | ||||
| 		jenkins = createJenkinsCRSafeRestart(jenkinsCRName, namespace.Name, nil, groovyScripts, casc, priorityClassName) | ||||
| 	}) | ||||
| 
 | ||||
| 	AfterEach(func() { | ||||
| 		destroyNamespace(namespace) | ||||
| 	}) | ||||
| 
 | ||||
| 	Context("when running Jenkins safe restart", func() { | ||||
| 		It("authorization strategy is not overwritten", func() { | ||||
| 			waitForJenkinsBaseConfigurationToComplete(jenkins) | ||||
| 			waitForJenkinsUserConfigurationToComplete(jenkins) | ||||
| 			jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(jenkins, namespace.Name) | ||||
| 			defer cleanUpFunc() | ||||
| 			checkIfAuthorizationStrategyUnsecuredIsSet(jenkinsClient) | ||||
| 
 | ||||
| 			err := jenkinsClient.SafeRestart() | ||||
| 			Expect(err).NotTo(HaveOccurred()) | ||||
| 			waitForJenkinsSafeRestart(jenkinsClient) | ||||
| 
 | ||||
| 			checkIfAuthorizationStrategyUnsecuredIsSet(jenkinsClient) | ||||
| 		}) | ||||
| 	}) | ||||
| }) | ||||
|  | @ -0,0 +1,61 @@ | |||
| package e2e | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/jenkinsci/kubernetes-operator/api/v1alpha2" | ||||
| 
 | ||||
| 	. "github.com/onsi/ginkgo" | ||||
| 	corev1 "k8s.io/api/core/v1" | ||||
| 	// +kubebuilder:scaffold:imports
 | ||||
| ) | ||||
| 
 | ||||
| var _ = Describe("Jenkins controller backup and restore", func() { | ||||
| 
 | ||||
| 	const ( | ||||
| 		jenkinsCRName = e2e | ||||
| 		jobID         = "e2e-jenkins-operator" | ||||
| 	) | ||||
| 
 | ||||
| 	var ( | ||||
| 		namespace *corev1.Namespace | ||||
| 		jenkins   *v1alpha2.Jenkins | ||||
| 	) | ||||
| 
 | ||||
| 	BeforeEach(func() { | ||||
| 		namespace = createNamespace() | ||||
| 
 | ||||
| 		createPVC(namespace.Name) | ||||
| 		jenkins = createJenkinsWithBackupAndRestoreConfigured(jenkinsCRName, namespace.Name) | ||||
| 	}) | ||||
| 
 | ||||
| 	AfterEach(func() { | ||||
| 		destroyNamespace(namespace) | ||||
| 	}) | ||||
| 
 | ||||
| 	Context("when deploying CR with backup enabled to cluster", func() { | ||||
| 		It("performs backups before pod deletion and restores them even Jenkins status is restarted", func() { | ||||
| 			waitForJenkinsUserConfigurationToComplete(jenkins) | ||||
| 			jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(jenkins, namespace.Name) | ||||
| 			defer cleanUpFunc() | ||||
| 			waitForJobCreation(jenkinsClient, jobID) | ||||
| 			verifyJobCanBeRun(jenkinsClient, jobID) | ||||
| 
 | ||||
| 			jenkins = getJenkins(jenkins.Namespace, jenkins.Name) | ||||
| 			restartJenkinsMasterPod(jenkins) | ||||
| 			waitForRecreateJenkinsMasterPod(jenkins) | ||||
| 			waitForJenkinsUserConfigurationToComplete(jenkins) | ||||
| 			jenkinsClient2, cleanUpFunc2 := verifyJenkinsAPIConnection(jenkins, namespace.Name) | ||||
| 			defer cleanUpFunc2() | ||||
| 			waitForJobCreation(jenkinsClient2, jobID) | ||||
| 			verifyJobBuildsAfterRestoreBackup(jenkinsClient2, jobID) | ||||
| 
 | ||||
| 			resetJenkinsStatus(jenkins) | ||||
| 			jenkins = getJenkins(jenkins.Namespace, jenkins.Name) | ||||
| 			checkBaseConfigurationCompleteTimeIsNotSet(jenkins) | ||||
| 			waitForJenkinsUserConfigurationToComplete(jenkins) | ||||
| 			jenkinsClient3, cleanUpFunc3 := verifyJenkinsAPIConnection(jenkins, namespace.Name) | ||||
| 			defer cleanUpFunc3() | ||||
| 			waitForJobCreation(jenkinsClient3, jobID) | ||||
| 			verifyJobBuildsAfterRestoreBackup(jenkinsClient3, jobID) | ||||
| 		}) | ||||
| 	}) | ||||
| }) | ||||
|  | @ -152,6 +152,112 @@ func createJenkinsCR(name, namespace string, seedJob *[]v1alpha2.SeedJob, groovy | |||
| 	return jenkins | ||||
| } | ||||
| 
 | ||||
| func createJenkinsCRSafeRestart(name, namespace string, seedJob *[]v1alpha2.SeedJob, groovyScripts v1alpha2.GroovyScripts, casc v1alpha2.ConfigurationAsCode, priorityClassName string) *v1alpha2.Jenkins { | ||||
| 	var seedJobs []v1alpha2.SeedJob | ||||
| 	if seedJob != nil { | ||||
| 		seedJobs = append(seedJobs, *seedJob...) | ||||
| 	} | ||||
| 
 | ||||
| 	jenkins := &v1alpha2.Jenkins{ | ||||
| 		TypeMeta: v1alpha2.JenkinsTypeMeta(), | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Name:      name, | ||||
| 			Namespace: namespace, | ||||
| 		}, | ||||
| 		Spec: v1alpha2.JenkinsSpec{ | ||||
| 			GroovyScripts:       groovyScripts, | ||||
| 			ConfigurationAsCode: casc, | ||||
| 			Master: v1alpha2.JenkinsMaster{ | ||||
| 				Annotations: map[string]string{"test": "label"}, | ||||
| 				Containers: []v1alpha2.Container{ | ||||
| 					{ | ||||
| 						Name: resources.JenkinsMasterContainerName, | ||||
| 						Env: []corev1.EnvVar{ | ||||
| 							{ | ||||
| 								Name:  "TEST_ENV", | ||||
| 								Value: "test_env_value", | ||||
| 							}, | ||||
| 						}, | ||||
| 						ReadinessProbe: &corev1.Probe{ | ||||
| 							Handler: corev1.Handler{ | ||||
| 								HTTPGet: &corev1.HTTPGetAction{ | ||||
| 									Path:   "/login", | ||||
| 									Port:   intstr.FromString("http"), | ||||
| 									Scheme: corev1.URISchemeHTTP, | ||||
| 								}, | ||||
| 							}, | ||||
| 							InitialDelaySeconds: int32(80), | ||||
| 							TimeoutSeconds:      int32(4), | ||||
| 							FailureThreshold:    int32(10), | ||||
| 							SuccessThreshold:    int32(1), | ||||
| 							PeriodSeconds:       int32(1), | ||||
| 						}, | ||||
| 						LivenessProbe: &corev1.Probe{ | ||||
| 							Handler: corev1.Handler{ | ||||
| 								HTTPGet: &corev1.HTTPGetAction{ | ||||
| 									Path:   "/login", | ||||
| 									Port:   intstr.FromString("http"), | ||||
| 									Scheme: corev1.URISchemeHTTP, | ||||
| 								}, | ||||
| 							}, | ||||
| 							InitialDelaySeconds: int32(100), | ||||
| 							TimeoutSeconds:      int32(5), | ||||
| 							FailureThreshold:    int32(12), | ||||
| 							SuccessThreshold:    int32(1), | ||||
| 							PeriodSeconds:       int32(5), | ||||
| 						}, | ||||
| 						VolumeMounts: []corev1.VolumeMount{ | ||||
| 							{ | ||||
| 								Name:      "plugins-cache", | ||||
| 								MountPath: "/usr/share/jenkins/ref/plugins", | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:  "envoyproxy", | ||||
| 						Image: "envoyproxy/envoy-alpine:v1.14.1", | ||||
| 					}, | ||||
| 				}, | ||||
| 				Plugins: []v1alpha2.Plugin{ | ||||
| 					{Name: "audit-trail", Version: "3.7"}, | ||||
| 					{Name: "simple-theme-plugin", Version: "0.6"}, | ||||
| 					{Name: "github", Version: "1.32.0"}, | ||||
| 					{Name: "devoptics", Version: "1.1905", DownloadURL: "https://jenkins-updates.cloudbees.com/download/plugins/devoptics/1.1905/devoptics.hpi"}, | ||||
| 				}, | ||||
| 				PriorityClassName: priorityClassName, | ||||
| 				NodeSelector:      map[string]string{"kubernetes.io/os": "linux"}, | ||||
| 				Volumes: []corev1.Volume{ | ||||
| 					{ | ||||
| 						Name: "plugins-cache", | ||||
| 						VolumeSource: corev1.VolumeSource{ | ||||
| 							EmptyDir: &corev1.EmptyDirVolumeSource{}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			SeedJobs: seedJobs, | ||||
| 			Service: v1alpha2.Service{ | ||||
| 				Type: corev1.ServiceTypeNodePort, | ||||
| 				Port: constants.DefaultHTTPPortInt32, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	jenkins.Spec.Roles = []rbacv1.RoleRef{ | ||||
| 		{ | ||||
| 			APIGroup: "rbac.authorization.k8s.io", | ||||
| 			Kind:     "Role", | ||||
| 			Name:     resources.GetResourceName(jenkins), | ||||
| 		}, | ||||
| 	} | ||||
| 	updateJenkinsCR(jenkins) | ||||
| 
 | ||||
| 	_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins CR %+v\n", *jenkins) | ||||
| 
 | ||||
| 	Expect(k8sClient.Create(context.TODO(), jenkins)).Should(Succeed()) | ||||
| 
 | ||||
| 	return jenkins | ||||
| } | ||||
| 
 | ||||
| func createJenkinsAPIClientFromServiceAccount(jenkins *v1alpha2.Jenkins, jenkinsAPIURL string) (jenkinsclient.Jenkins, error) { | ||||
| 	podName := resources.GetJenkinsMasterPodName(jenkins) | ||||
| 
 | ||||
|  | @ -224,12 +330,18 @@ func verifyJenkinsAPIConnection(jenkins *v1alpha2.Jenkins, namespace string) (je | |||
| 	return jenkinsClient, cleanUpFunc | ||||
| } | ||||
| 
 | ||||
| /*func restartJenkinsMasterPod(jenkins *v1alpha2.Jenkins) { | ||||
| 	_, _ = fmt.Fprintf(GinkgoWriter, "Restarting Jenkins master pod") | ||||
| func restartJenkinsMasterPod(jenkins *v1alpha2.Jenkins) { | ||||
| 	_, _ = fmt.Fprintf(GinkgoWriter, "Restarting Jenkins master pod\n") | ||||
| 	jenkinsPod := getJenkinsMasterPod(jenkins) | ||||
| 	Expect(k8sClient.Delete(context.TODO(), jenkinsPod)).Should(Succeed()) | ||||
| 	_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins master pod has been restarted") | ||||
| }*/ | ||||
| 
 | ||||
| 	Eventually(func() (bool, error) { | ||||
| 		jenkinsPod = getJenkinsMasterPod(jenkins) | ||||
| 		return jenkinsPod.DeletionTimestamp != nil, nil | ||||
| 	}, 30*retryInterval, retryInterval).Should(BeTrue()) | ||||
| 
 | ||||
| 	_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins master pod has been restarted\n") | ||||
| } | ||||
| 
 | ||||
| func getJenkinsService(jenkins *v1alpha2.Jenkins, serviceKind string) *corev1.Service { | ||||
| 	service := &corev1.Service{} | ||||
|  |  | |||
|  | @ -1,70 +1,20 @@ | |||
| package e2e | ||||
| 
 | ||||
| // TODO
 | ||||
| /* | ||||
| import ( | ||||
| 	"context" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" | ||||
| 	"github.com/jenkinsci/kubernetes-operator/api/v1alpha2" | ||||
| 	jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/client" | ||||
| 
 | ||||
| 	framework "github.com/operator-framework/operator-sdk/pkg/test" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	. "github.com/onsi/ginkgo" | ||||
| 	. "github.com/onsi/gomega" | ||||
| 	corev1 "k8s.io/api/core/v1" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| ) | ||||
| 
 | ||||
| func TestJenkinsMasterPodRestart(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 	namespace, ctx := setupTest(t) | ||||
| 
 | ||||
| 	defer showLogsAndCleanup(t, ctx) | ||||
| 
 | ||||
| 	jenkins := createJenkinsCR(t, "e2e", namespace, nil, v1alpha2.GroovyScripts{}, v1alpha2.ConfigurationAsCode{}, "") | ||||
| 	waitForJenkinsBaseConfigurationToComplete(t, jenkins) | ||||
| 	restartJenkinsMasterPod(t, jenkins) | ||||
| 	waitForRecreateJenkinsMasterPod(t, jenkins) | ||||
| 	checkBaseConfigurationCompleteTimeIsNotSet(t, jenkins) | ||||
| 	waitForJenkinsBaseConfigurationToComplete(t, jenkins) | ||||
| } | ||||
| 
 | ||||
| func TestSafeRestart(t *testing.T) { | ||||
| 	if skipTestSafeRestart { | ||||
| 		t.Skip() | ||||
| 	} | ||||
| 	t.Parallel() | ||||
| 	namespace, ctx := setupTest(t) | ||||
| 	// Deletes test namespace
 | ||||
| 	defer ctx.Cleanup() | ||||
| 
 | ||||
| 	jenkinsCRName := "e2e" | ||||
| 	configureAuthorizationToUnSecure(t, namespace, userConfigurationConfigMapName) | ||||
| 	groovyScriptsConfig := v1alpha2.GroovyScripts{ | ||||
| 		Customization: v1alpha2.Customization{ | ||||
| 			Configurations: []v1alpha2.ConfigMapRef{ | ||||
| 				{ | ||||
| 					Name: userConfigurationConfigMapName, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	jenkins := createJenkinsCR(t, jenkinsCRName, namespace, nil, groovyScriptsConfig, v1alpha2.ConfigurationAsCode{}, "") | ||||
| 	waitForJenkinsBaseConfigurationToComplete(t, jenkins) | ||||
| 	waitForJenkinsUserConfigurationToComplete(t, jenkins) | ||||
| 	jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(t, jenkins, namespace) | ||||
| 	defer cleanUpFunc() | ||||
| 	checkIfAuthorizationStrategyUnsecuredIsSet(t, jenkinsClient) | ||||
| 
 | ||||
| 	err := jenkinsClient.SafeRestart() | ||||
| 	require.NoError(t, err) | ||||
| 	waitForJenkinsSafeRestart(t, jenkinsClient) | ||||
| 
 | ||||
| 	checkIfAuthorizationStrategyUnsecuredIsSet(t, jenkinsClient) | ||||
| } | ||||
| 
 | ||||
| func configureAuthorizationToUnSecure(t *testing.T, namespace, configMapName string) { | ||||
| func configureAuthorizationToUnSecure(namespace, configMapName string) { | ||||
| 	limitRange := &corev1.ConfigMap{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Name:      configMapName, | ||||
|  | @ -83,11 +33,12 @@ jenkins.save() | |||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	err := framework.Global.Client.Create(context.TODO(), limitRange, nil) | ||||
| 	require.NoError(t, err) | ||||
| 	Expect(k8sClient.Create(context.TODO(), limitRange)).Should(Succeed()) | ||||
| } | ||||
| 
 | ||||
| func checkIfAuthorizationStrategyUnsecuredIsSet(t *testing.T, jenkinsClient jenkinsclient.Jenkins) { | ||||
| func checkIfAuthorizationStrategyUnsecuredIsSet(jenkinsClient jenkinsclient.Jenkins) { | ||||
| 	By("checking if Authorization Strategy Unsecured is set") | ||||
| 
 | ||||
| 	logs, err := jenkinsClient.ExecuteScript(` | ||||
| 	import hudson.security.* | ||||
| 
 | ||||
|  | @ -97,18 +48,18 @@ func checkIfAuthorizationStrategyUnsecuredIsSet(t *testing.T, jenkinsClient jenk | |||
| 	  throw new Exception('AuthorizationStrategy.Unsecured is not set') | ||||
| 	} | ||||
| 	`) | ||||
| 	require.NoError(t, err, logs) | ||||
| 	Expect(err).NotTo(HaveOccurred(), logs) | ||||
| } | ||||
| 
 | ||||
| func checkBaseConfigurationCompleteTimeIsNotSet(t *testing.T, jenkins *v1alpha2.Jenkins) { | ||||
| 	jenkinsStatus := &v1alpha2.Jenkins{} | ||||
| 	namespaceName := types.NamespacedName{Namespace: jenkins.Namespace, Name: jenkins.Name} | ||||
| 	err := framework.Global.Client.Get(context.TODO(), namespaceName, jenkinsStatus) | ||||
| func checkBaseConfigurationCompleteTimeIsNotSet(jenkins *v1alpha2.Jenkins) { | ||||
| 	By("checking that Base Configuration's complete time is not set") | ||||
| 
 | ||||
| 	Eventually(func() (bool, error) { | ||||
| 		actualJenkins := &v1alpha2.Jenkins{} | ||||
| 		err := k8sClient.Get(context.TODO(), types.NamespacedName{Name: jenkins.Name, Namespace: jenkins.Namespace}, actualJenkins) | ||||
| 		if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if jenkinsStatus.Status.BaseConfigurationCompletedTime != nil { | ||||
| 		t.Fatalf("Status.BaseConfigurationCompletedTime is set after pod restart, status %+v", jenkinsStatus.Status) | ||||
| 			return false, err | ||||
| 		} | ||||
| 		return actualJenkins.Status.BaseConfigurationCompletedTime == nil, nil | ||||
| 	}, time.Duration(110)*retryInterval, time.Second).Should(BeTrue()) | ||||
| } | ||||
| */ | ||||
|  |  | |||
|  | @ -1,21 +1,17 @@ | |||
| package e2e | ||||
| 
 | ||||
| // TODO
 | ||||
| /* | ||||
| import ( | ||||
| 	"context" | ||||
| 	"testing" | ||||
| 	"fmt" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/jenkinsci/kubernetes-operator/internal/try" | ||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" | ||||
| 	"github.com/jenkinsci/kubernetes-operator/api/v1alpha2" | ||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/client" | ||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/configuration/base/resources" | ||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/constants" | ||||
| 
 | ||||
| 	framework "github.com/operator-framework/operator-sdk/pkg/test" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	. "github.com/onsi/ginkgo" | ||||
| 	. "github.com/onsi/gomega" | ||||
| 	corev1 "k8s.io/api/core/v1" | ||||
| 	"k8s.io/apimachinery/pkg/api/resource" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
|  | @ -23,64 +19,33 @@ import ( | |||
| 
 | ||||
| const pvcName = "pvc-jenkins" | ||||
| 
 | ||||
| func TestBackupAndRestore(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 	namespace, ctx := setupTest(t) | ||||
| func waitForJobCreation(jenkinsClient client.Jenkins, jobID string) { | ||||
| 	By("waiting for Jenkins job creation") | ||||
| 
 | ||||
| 	defer showLogsAndCleanup(t, ctx) | ||||
| 
 | ||||
| 	jobID := "e2e-jenkins-operator" | ||||
| 	createPVC(t, namespace) | ||||
| 	jenkins := createJenkinsWithBackupAndRestoreConfigured(t, "e2e", namespace) | ||||
| 	waitForJenkinsUserConfigurationToComplete(t, jenkins) | ||||
| 
 | ||||
| 	jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(t, jenkins, namespace) | ||||
| 	defer cleanUpFunc() | ||||
| 	waitForJob(t, jenkinsClient, jobID) | ||||
| 	job, err := jenkinsClient.GetJob(jobID) | ||||
| 	require.NoError(t, err, job) | ||||
| 	i, err := job.InvokeSimple(map[string]string{}) | ||||
| 	require.NoError(t, err, i) | ||||
| 	// FIXME: waitForJobToFinish use
 | ||||
| 	time.Sleep(60 * time.Second) // wait for the build to complete
 | ||||
| 
 | ||||
| 	jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name) | ||||
| 	lastDoneBackup := jenkins.Status.LastBackup | ||||
| 	restartJenkinsMasterPod(t, jenkins) | ||||
| 	waitForRecreateJenkinsMasterPod(t, jenkins) | ||||
| 	waitForJenkinsUserConfigurationToComplete(t, jenkins) | ||||
| 	jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name) | ||||
| 	assert.Equal(t, lastDoneBackup, jenkins.Status.RestoredBackup) | ||||
| 	jenkinsClient2, cleanUpFunc2 := verifyJenkinsAPIConnection(t, jenkins, namespace) | ||||
| 	defer cleanUpFunc2() | ||||
| 	waitForJob(t, jenkinsClient2, jobID) | ||||
| 	verifyJobBuildsAfterRestoreBackup(t, jenkinsClient2, jobID) | ||||
| 
 | ||||
| 	jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name) | ||||
| 	lastDoneBackup = jenkins.Status.LastBackup | ||||
| 	resetJenkinsStatus(t, jenkins) | ||||
| 	waitForJenkinsUserConfigurationToComplete(t, jenkins) | ||||
| 	jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name) | ||||
| 	assert.Equal(t, lastDoneBackup, jenkins.Status.RestoredBackup) | ||||
| } | ||||
| 
 | ||||
| func waitForJob(t *testing.T, jenkinsClient client.Jenkins, jobID string) { | ||||
| 	err := try.Until(func() (end bool, err error) { | ||||
| 	var err error | ||||
| 	Eventually(func() (bool, error) { | ||||
| 		_, err = jenkinsClient.GetJob(jobID) | ||||
| 		if err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
| 		return err == nil, err | ||||
| 	}, time.Second*2, time.Minute*3) | ||||
| 	require.NoErrorf(t, err, "Jenkins job '%s' not created by seed job", jobID) | ||||
| 	}, time.Minute*3, time.Second*2).Should(BeTrue()) | ||||
| 
 | ||||
| 	Expect(err).NotTo(HaveOccurred()) | ||||
| } | ||||
| 
 | ||||
| func verifyJobBuildsAfterRestoreBackup(t *testing.T, jenkinsClient client.Jenkins, jobID string) { | ||||
| func verifyJobBuildsAfterRestoreBackup(jenkinsClient client.Jenkins, jobID string) { | ||||
| 	By("checking if job builds after restoring backup") | ||||
| 
 | ||||
| 	job, err := jenkinsClient.GetJob(jobID) | ||||
| 	require.NoError(t, err) | ||||
| 	Expect(err).NotTo(HaveOccurred()) | ||||
| 	build, err := job.GetLastBuild() | ||||
| 	require.NoError(t, err) | ||||
| 	assert.Equal(t, int64(1), build.GetBuildNumber()) | ||||
| 	Expect(err).NotTo(HaveOccurred()) | ||||
| 
 | ||||
| 	Expect(build.GetBuildNumber()).To(Equal(int64(1))) | ||||
| } | ||||
| 
 | ||||
| func createPVC(t *testing.T, namespace string) { | ||||
| func createPVC(namespace string) { | ||||
| 	pvc := &corev1.PersistentVolumeClaim{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Name:      pvcName, | ||||
|  | @ -96,11 +61,10 @@ func createPVC(t *testing.T, namespace string) { | |||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	err := framework.Global.Client.Create(context.TODO(), pvc, nil) | ||||
| 	require.NoError(t, err) | ||||
| 	Expect(k8sClient.Create(context.TODO(), pvc)).Should(Succeed()) | ||||
| } | ||||
| 
 | ||||
| func createJenkinsWithBackupAndRestoreConfigured(t *testing.T, name, namespace string) *v1alpha2.Jenkins { | ||||
| func createJenkinsWithBackupAndRestoreConfigured(name, namespace string) *v1alpha2.Jenkins { | ||||
| 	containerName := "backup" | ||||
| 	jenkins := &v1alpha2.Jenkins{ | ||||
| 		TypeMeta: v1alpha2.JenkinsTypeMeta(), | ||||
|  | @ -130,6 +94,16 @@ func createJenkinsWithBackupAndRestoreConfigured(t *testing.T, name, namespace s | |||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			GroovyScripts: v1alpha2.GroovyScripts{ | ||||
| 				Customization: v1alpha2.Customization{ | ||||
| 					Configurations: []v1alpha2.ConfigMapRef{}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			ConfigurationAsCode: v1alpha2.ConfigurationAsCode{ | ||||
| 				Customization: v1alpha2.Customization{ | ||||
| 					Configurations: []v1alpha2.ConfigMapRef{}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			Master: v1alpha2.JenkinsMaster{ | ||||
| 				Containers: []v1alpha2.Container{ | ||||
| 					{ | ||||
|  | @ -201,19 +175,20 @@ func createJenkinsWithBackupAndRestoreConfigured(t *testing.T, name, namespace s | |||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	updateJenkinsCR(t, jenkins) | ||||
| 
 | ||||
| 	t.Logf("Jenkins CR %+v", *jenkins) | ||||
| 	err := framework.Global.Client.Create(context.TODO(), jenkins, nil) | ||||
| 	require.NoError(t, err) | ||||
| 	updateJenkinsCR(jenkins) | ||||
| 
 | ||||
| 	_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins CR %+v\n", *jenkins) | ||||
| 
 | ||||
| 	Expect(k8sClient.Create(context.TODO(), jenkins)).Should(Succeed()) | ||||
| 
 | ||||
| 	return jenkins | ||||
| } | ||||
| 
 | ||||
| func resetJenkinsStatus(t *testing.T, jenkins *v1alpha2.Jenkins) { | ||||
| 	jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name) | ||||
| func resetJenkinsStatus(jenkins *v1alpha2.Jenkins) { | ||||
| 	By("resetting Jenkins status") | ||||
| 
 | ||||
| 	jenkins = getJenkins(jenkins.Namespace, jenkins.Name) | ||||
| 	jenkins.Status = v1alpha2.JenkinsStatus{} | ||||
| 	err := framework.Global.Client.Update(context.TODO(), jenkins) | ||||
| 	require.NoError(t, err) | ||||
| 	Expect(k8sClient.Status().Update(context.TODO(), jenkins)).Should(Succeed()) | ||||
| } | ||||
| */ | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ import ( | |||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/configuration/user/seedjobs" | ||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/constants" | ||||
| 
 | ||||
| 	"github.com/bndr/gojenkins" | ||||
| 	. "github.com/onsi/ginkgo" | ||||
| 	. "github.com/onsi/gomega" | ||||
| 	corev1 "k8s.io/api/core/v1" | ||||
|  | @ -27,12 +28,13 @@ type seedJobConfig struct { | |||
| 	PrivateKey string   `json:"privateKey,omitempty"` | ||||
| } | ||||
| 
 | ||||
| /*type seedJobsConfig struct { | ||||
| /* | ||||
| type seedJobsConfig struct { | ||||
| 	SeedJobs []seedJobConfig `json:"seedJobs,omitempty"` | ||||
| }*/ | ||||
| } | ||||
| 
 | ||||
| // FIXME
 | ||||
| /*func TestSeedJobs(t *testing.T) { | ||||
| func TestSeedJobs(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 	if seedJobConfigurationFile == nil || len(*seedJobConfigurationFile) == 0 { | ||||
| 		t.Skipf("Skipping test because flag '%+v' is not set", seedJobConfigurationFile) | ||||
|  | @ -63,22 +65,22 @@ type seedJobConfig struct { | |||
| 	verifyJenkinsSeedJobs(t, jenkinsClient, seedJobsConfig.SeedJobs) | ||||
| } | ||||
| 
 | ||||
| func loadSeedJobsConfig(t *testing.T) seedJobsConfig { | ||||
| func loadSeedJobsConfig() seedJobsConfig { | ||||
| 	//seedJobConfigurationFile = flag.String(seedJobConfigurationParameterName, "", "path to seed job config")
 | ||||
| 	jsonFile, err := os.Open(*seedJobConfigurationFile) | ||||
| 	assert.NoError(t, err) | ||||
| 	Expect(err).NotTo(HaveOccurred()) | ||||
| 	defer func() { _ = jsonFile.Close() }() | ||||
| 
 | ||||
| 	byteValue, err := ioutil.ReadAll(jsonFile) | ||||
| 	assert.NoError(t, err) | ||||
| 	Expect(err).NotTo(HaveOccurred()) | ||||
| 
 | ||||
| 	var result seedJobsConfig | ||||
| 	err = json.Unmarshal(byteValue, &result) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.NotEmpty(t, result.SeedJobs) | ||||
| 	Expect(err).NotTo(HaveOccurred()) | ||||
| 	Expect(result.SeedJobs).NotTo(BeEmpty()) | ||||
| 	return result | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| func createKubernetesCredentialsProviderSecret(namespace string, config seedJobConfig) { | ||||
| 	if config.JenkinsCredentialType == v1alpha2.NoJenkinsCredentialCredentialType { | ||||
| 		return | ||||
|  | @ -112,7 +114,7 @@ func verifyJenkinsSeedJobs(jenkinsClient jenkinsclient.Jenkins, seedJobs []seedJ | |||
| 	for _, seedJob := range seedJobs { | ||||
| 		if seedJob.JenkinsCredentialType == v1alpha2.BasicSSHCredentialType || seedJob.JenkinsCredentialType == v1alpha2.UsernamePasswordCredentialType { | ||||
| 			err = verifyIfJenkinsCredentialExists(jenkinsClient, seedJob.CredentialID) | ||||
| 			Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Jenkins credential '%s' not created for seed job ID '%s'", seedJob.CredentialID, seedJob.ID)) | ||||
| 			Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Jenkins credential '%s' not created for seed job ID '%s'\n", seedJob.CredentialID, seedJob.ID)) | ||||
| 		} | ||||
| 
 | ||||
| 		verifySeedJobProperties(jenkinsClient, seedJob) | ||||
|  | @ -122,7 +124,7 @@ func verifyJenkinsSeedJobs(jenkinsClient jenkinsclient.Jenkins, seedJobs []seedJ | |||
| 				_, err = jenkinsClient.GetJob(requireJobName) | ||||
| 				return err == nil, err | ||||
| 			}, time.Second*2, time.Minute*2) | ||||
| 			Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Jenkins job '%s' not created by seed job ID '%s'", requireJobName, seedJob.ID)) | ||||
| 			Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Jenkins job '%s' not created by seed job ID '%s'\n", requireJobName, seedJob.ID)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -292,3 +294,36 @@ for (BuildStep step : jobRef.getBuildersList()) { | |||
| 	} | ||||
| } | ||||
| `)) | ||||
| 
 | ||||
| func verifyJobCanBeRun(jenkinsClient jenkinsclient.Jenkins, jobID string) { | ||||
| 	By("retrieving created Jenkins job") | ||||
| 	job, err := jenkinsClient.GetJob(jobID) | ||||
| 	Expect(err).To(BeNil()) | ||||
| 
 | ||||
| 	By("running Jenkins job") | ||||
| 	_, err = job.InvokeSimple(map[string]string{}) | ||||
| 	Expect(err).To(BeNil()) | ||||
| 
 | ||||
| 	// FIXME: waitForJobToFinish use
 | ||||
| 	By("waiting for the job to finish") | ||||
| 	time.Sleep(100 * time.Second) // wait for the build to complete
 | ||||
| } | ||||
| func verifyJobHasBeenRunCorrectly(jenkinsClient jenkinsclient.Jenkins, jobID string) { | ||||
| 	By("retrieving finished job") | ||||
| 
 | ||||
| 	var ( | ||||
| 		err   error | ||||
| 		job   *gojenkins.Job | ||||
| 		build *gojenkins.Build | ||||
| 	) | ||||
| 
 | ||||
| 	Eventually(func() (bool, error) { | ||||
| 		job, err = jenkinsClient.GetJob(jobID) | ||||
| 		Expect(err).To(BeNil()) | ||||
| 		build, err = job.GetLastBuild() | ||||
| 		Expect(err).To(BeNil()) | ||||
| 
 | ||||
| 		By("evaluating correctness of the outcome") | ||||
| 		return build.IsGood(), err | ||||
| 	}, time.Duration(110)*retryInterval, retryInterval).Should(BeTrue()) | ||||
| } | ||||
|  |  | |||
|  | @ -3,13 +3,20 @@ package e2e | |||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/jenkinsci/kubernetes-operator/api/v1alpha2" | ||||
| 	jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/client" | ||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/configuration/base/resources" | ||||
| 
 | ||||
| 	. "github.com/onsi/ginkgo" | ||||
| 	. "github.com/onsi/gomega" | ||||
| 	corev1 "k8s.io/api/core/v1" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/labels" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	"sigs.k8s.io/controller-runtime/pkg/client" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
|  | @ -36,26 +43,28 @@ func waitForJenkinsBaseConfigurationToComplete(jenkins *v1alpha2.Jenkins) { | |||
| 	Expect(k8sClient.Get(context.TODO(), namespacedName, jenkins)).Should(Succeed()) | ||||
| } | ||||
| 
 | ||||
| /*func waitForRecreateJenkinsMasterPod(t *testing.T, jenkins *v1alpha2.Jenkins) { | ||||
| 	err := wait.Poll(retryInterval, 30*retryInterval, func() (bool, error) { | ||||
| 		lo := metav1.ListOptions{ | ||||
| 			LabelSelector: labels.SelectorFromSet(resources.GetJenkinsMasterPodLabels(*jenkins)).String(), | ||||
| func waitForRecreateJenkinsMasterPod(jenkins *v1alpha2.Jenkins) { | ||||
| 	By("waiting for Jenkins Master Pod recreation") | ||||
| 
 | ||||
| 	Eventually(func() (bool, error) { | ||||
| 		lo := &client.ListOptions{ | ||||
| 			LabelSelector: labels.SelectorFromSet(resources.GetJenkinsMasterPodLabels(*jenkins)), | ||||
| 			Namespace:     jenkins.Namespace, | ||||
| 		} | ||||
| 		podList, err := framework.Global.KubeClient.CoreV1().Pods(jenkins.ObjectMeta.Namespace).List(lo) | ||||
| 		pods := &corev1.PodList{} | ||||
| 		err := k8sClient.List(context.TODO(), pods, lo) | ||||
| 		if err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
| 		if len(podList.Items) != 1 { | ||||
| 		if len(pods.Items) != 1 { | ||||
| 			return false, nil | ||||
| 		} | ||||
| 
 | ||||
| 		return podList.Items[0].DeletionTimestamp == nil, nil | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	_, _ = fmt.Fprintf(GinkgoWriter,"Jenkins pod has been recreated") | ||||
| }*/ | ||||
| 		return pods.Items[0].DeletionTimestamp == nil, nil | ||||
| 	}, 30*retryInterval, retryInterval).Should(BeTrue()) | ||||
| 
 | ||||
| 	_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins pod has been recreated\n") | ||||
| } | ||||
| 
 | ||||
| func waitForJenkinsUserConfigurationToComplete(jenkins *v1alpha2.Jenkins) { | ||||
| 	By("waiting for Jenkins user configuration phase to complete") | ||||
|  | @ -66,22 +75,23 @@ func waitForJenkinsUserConfigurationToComplete(jenkins *v1alpha2.Jenkins) { | |||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 
 | ||||
| 		return actualJenkins.Status.UserConfigurationCompletedTime, nil | ||||
| 	}, time.Duration(110)*retryInterval, retryInterval).Should(Not(BeNil())) | ||||
| 	_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins instance is up and ready\n") | ||||
| } | ||||
| 
 | ||||
| /*func waitForJenkinsSafeRestart(t *testing.T, jenkinsClient jenkinsclient.Jenkins) { | ||||
| 	err := try.Until(func() (end bool, err error) { | ||||
| func waitForJenkinsSafeRestart(jenkinsClient jenkinsclient.Jenkins) { | ||||
| 	By("waiting for Jenkins safe restart") | ||||
| 
 | ||||
| 	Eventually(func() (bool, error) { | ||||
| 		status, err := jenkinsClient.Poll() | ||||
| 		_, _ = fmt.Fprintf(GinkgoWriter, "Safe restart status: %+v, err: %s\n", status, err) | ||||
| 		if err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
| 		if status != http.StatusOK { | ||||
| 			return false, errors.Wrap(err, "couldn't poll data from Jenkins API") | ||||
| 			return false, err | ||||
| 		} | ||||
| 		return true, nil | ||||
| 	}, time.Second, time.Second*70) | ||||
| 	require.NoError(t, err) | ||||
| }*/ | ||||
| 	}, time.Second*200, time.Second*5).Should(BeTrue()) | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue