mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 22:46:12 +00:00
CronJob: Add e2e test for adoption.
Currently, an e2e test is the only way to ensure we have the proper RBAC permissions to adopt Jobs.
This commit is contained in:
parent
1e14323ac2
commit
33d7788793
@ -33,6 +33,7 @@ import (
|
|||||||
batchv1 "k8s.io/kubernetes/pkg/apis/batch/v1"
|
batchv1 "k8s.io/kubernetes/pkg/apis/batch/v1"
|
||||||
batchv2alpha1 "k8s.io/kubernetes/pkg/apis/batch/v2alpha1"
|
batchv2alpha1 "k8s.io/kubernetes/pkg/apis/batch/v2alpha1"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
|
"k8s.io/kubernetes/pkg/controller"
|
||||||
"k8s.io/kubernetes/pkg/controller/job"
|
"k8s.io/kubernetes/pkg/controller/job"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
@ -274,6 +275,53 @@ var _ = framework.KubeDescribe("CronJob", func() {
|
|||||||
err = deleteCronJob(f.ClientSet, f.Namespace.Name, cronJob.Name)
|
err = deleteCronJob(f.ClientSet, f.Namespace.Name, cronJob.Name)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Adopt Jobs it owns that don't have ControllerRef yet.
|
||||||
|
// That is, the Jobs were created by a pre-v1.6.0 master.
|
||||||
|
It("should adopt Jobs it owns that don't have ControllerRef yet", func() {
|
||||||
|
By("Creating a cronjob")
|
||||||
|
cronJob := newTestCronJob("adopt", "*/1 * * * ?", batchv2alpha1.ForbidConcurrent,
|
||||||
|
sleepCommand, nil)
|
||||||
|
// Replace cronJob with the one returned from Create() so it has the UID.
|
||||||
|
// Save Kind since it won't be populated in the returned cronJob.
|
||||||
|
kind := cronJob.Kind
|
||||||
|
cronJob, err := createCronJob(f.ClientSet, f.Namespace.Name, cronJob)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
cronJob.Kind = kind
|
||||||
|
|
||||||
|
By("Ensuring a Job is running")
|
||||||
|
err = waitForActiveJobs(f.ClientSet, f.Namespace.Name, cronJob.Name, 1)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
By("Orphaning a Job")
|
||||||
|
jobs, err := f.ClientSet.BatchV1().Jobs(f.Namespace.Name).List(metav1.ListOptions{})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(jobs.Items).To(HaveLen(1))
|
||||||
|
job := jobs.Items[0]
|
||||||
|
framework.UpdateJobFunc(f.ClientSet, f.Namespace.Name, job.Name, func(job *batchv1.Job) {
|
||||||
|
job.OwnerReferences = nil
|
||||||
|
})
|
||||||
|
|
||||||
|
By("Checking that the CronJob readopts the Job")
|
||||||
|
Expect(wait.Poll(framework.Poll, cronJobTimeout, func() (bool, error) {
|
||||||
|
job, err := framework.GetJob(f.ClientSet, f.Namespace.Name, job.Name)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
controllerRef := controller.GetControllerOf(job)
|
||||||
|
if controllerRef == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if controllerRef.Kind != cronJob.Kind || controllerRef.Name != cronJob.Name || controllerRef.UID != cronJob.UID {
|
||||||
|
return false, fmt.Errorf("Job has wrong controllerRef: got %v, want %v", controllerRef, cronJob)
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
})).To(Succeed(), "wait for Job %q to be readopted", job.Name)
|
||||||
|
|
||||||
|
By("Removing CronJob")
|
||||||
|
err = deleteCronJob(f.ClientSet, f.Namespace.Name, cronJob.Name)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// newTestCronJob returns a cronjob which does one of several testing behaviors.
|
// newTestCronJob returns a cronjob which does one of several testing behaviors.
|
||||||
@ -285,6 +333,9 @@ func newTestCronJob(name, schedule string, concurrencyPolicy batchv2alpha1.Concu
|
|||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: name,
|
Name: name,
|
||||||
},
|
},
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: "CronJob",
|
||||||
|
},
|
||||||
Spec: batchv2alpha1.CronJobSpec{
|
Spec: batchv2alpha1.CronJobSpec{
|
||||||
Schedule: schedule,
|
Schedule: schedule,
|
||||||
ConcurrencyPolicy: concurrencyPolicy,
|
ConcurrencyPolicy: concurrencyPolicy,
|
||||||
|
@ -17,8 +17,10 @@ limitations under the License.
|
|||||||
package framework
|
package framework
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
@ -120,6 +122,29 @@ func UpdateJob(c clientset.Interface, ns string, job *batch.Job) (*batch.Job, er
|
|||||||
return c.Batch().Jobs(ns).Update(job)
|
return c.Batch().Jobs(ns).Update(job)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateJobFunc updates the job object. It retries if there is a conflict, throw out error if
|
||||||
|
// there is any other errors. name is the job name, updateFn is the function updating the
|
||||||
|
// job object.
|
||||||
|
func UpdateJobFunc(c clientset.Interface, ns, name string, updateFn func(job *batch.Job)) {
|
||||||
|
ExpectNoError(wait.Poll(time.Millisecond*500, time.Second*30, func() (bool, error) {
|
||||||
|
job, err := GetJob(c, ns, name)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("failed to get pod %q: %v", name, err)
|
||||||
|
}
|
||||||
|
updateFn(job)
|
||||||
|
_, err = UpdateJob(c, ns, job)
|
||||||
|
if err == nil {
|
||||||
|
Logf("Successfully updated job %q", name)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if errors.IsConflict(err) {
|
||||||
|
Logf("Conflicting update to job %q, re-get and re-update: %v", name, err)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, fmt.Errorf("failed to update job %q: %v", name, err)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteJob uses c to delete the Job named name in namespace ns. If the returned error is nil, the Job has been
|
// DeleteJob uses c to delete the Job named name in namespace ns. If the returned error is nil, the Job has been
|
||||||
// deleted.
|
// deleted.
|
||||||
func DeleteJob(c clientset.Interface, ns, name string) error {
|
func DeleteJob(c clientset.Interface, ns, name string) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user