Change:
The following PriorityClass endpoints was Promoted it 1.14 without Conformance tests, and remain untested: replace-, read-, patch-, list-, delete-collection- SchedulingV1PriorityClass According to this APIsnoop query, there are still some remaining PriorityClass endpoints which are untested. with this query you can filter untested endpoints by their category and eligiblity for conformance. e.g below shows a query to find all conformance eligible untested,stable,core endpoints ! createSchedulingV1PriorityClass deleteSchedulingV1PriorityClass Promoted to Conformance 1.19 with /sig testing /sig architecture /area conformance
Is the ultimiate goal to use conformance tests to explicitly issue all CRUD requests against PriorityClass? And, is equivalent to "update PriorityClass"?
all APIs must have Conformance tests unless they are not eligible for Conformance due to the There is other APIGroups that have both Replace and Update as endpoints. That is the prerogative of the SIG to decide.
can you please point us to similar conformance tests used for core objects such as pods and nodes?
This is a life cycle test for Create, List, Update, Patch, DeleteCollection More can be found in the test/e2e folder. Also look for examples on the Conformance at previously Promoted Conformance test Reach out if we can help with more information on our approach to Conformance testing.
I remembered about this PR. Last week a few lines of code was to cover the last of the "Lease" endpoint group for conformance. The one file contain the Conformance tests for the complete life cycle of Lease endpoints.
/assign I will work on it.
/reopen Will monitor in test grid to move to Conformance after 2 weeks soak.
Reopened this issue. <detailsIn response to : /reopen Will monitor in test grid to move to Conformance after 2 weeks soak. </details
/triage accepted

Discussion:
ginkgo.AfterEach(func() { // print out additional info if tests failed if ginkgo.CurrentGinkgoTestDescription().Failed { <del> // list existing priorities </del> <ins> // List existing PriorityClasses. </ins> priorityList, err := cs.SchedulingV1().PriorityClasses().List(context.TODO(), metav1.ListOptions{}) if err != nil { <del> framework.Logf("Unable to list priorities: %v", err) </del> <ins> framework.Logf("Unable to list PriorityClasses: %v", err) </ins> } else { <del> framework.Logf("List existing priorities:") </del> <ins> framework.Logf("List existing PriorityClasses:") </ins> for _, p := range priorityList.Items { framework.Logf("%v/%v created at %v", p.Name, p.Value, p.CreationTimestamp) }

priorityPairs = append(priorityPairs, priorityPair{name: priorityName, value: priorityVal}) _, err := cs.SchedulingV1().PriorityClasses().Create(context.TODO(), &schedulingv1.PriorityClass{ObjectMeta: metav1.ObjectMeta{Name: priorityName}, Value: priorityVal}, metav1.CreateOptions{}) if err != nil { <del> framework.Logf("Failed to create priority '%v/%v': %v", priorityName, priorityVal, err) framework.Logf("Reason: %v. Msg: %v", apierrors.ReasonForError(err), err) </del> <ins> framework.Logf("Failed to create priority '%v/%v'. Reason: %v. Msg: %v", priorityName, priorityVal, apierrors.ReasonForError(err), err) </ins> } framework.ExpectEqual(err == nil || apierrors.IsAlreadyExists(err), true) }

} }) }) <ins> ginkgo.Context("PriorityClass endpoints", func() { var cs clientset.Interface f := framework.NewDefaultFramework("sched-preemption-path") var pcs []*schedulingv1.PriorityClass ginkgo.BeforeEach(func() { cs = f.ClientSet // Create 2 PriorityClass: p1, p2. for i := 1; i <= 2; i++ { name, val := fmt.Sprintf("p%d", i), int32(i) pc, err := cs.SchedulingV1().PriorityClasses().Create(context.TODO(), &schedulingv1.PriorityClass{ObjectMeta: metav1.ObjectMeta{Name: name}, Value: val}, metav1.CreateOptions{}) if err != nil { framework.Logf("Failed to create priority '%v/%v'. Reason: %v. Msg: %v", name, val, apierrors.ReasonForError(err), err) } framework.ExpectEqual(err == nil || apierrors.IsAlreadyExists(err), true) pcs = append(pcs, pc) } }) ginkgo.AfterEach(func() { // Print out additional info if tests failed. if ginkgo.CurrentGinkgoTestDescription().Failed { // List existing PriorityClasses. priorityList, err := cs.SchedulingV1().PriorityClasses().List(context.TODO(), metav1.ListOptions{}) if err != nil { framework.Logf("Unable to list PriorityClasses: %v", err) } else { framework.Logf("List existing PriorityClasses:") for _, p := range priorityList.Items { framework.Logf("%v/%v created at %v", p.Name, p.Value, p.CreationTimestamp) } } } // Cannot run collection deletion which would delete all system level priority classes. for _, pc := range pcs { err := cs.SchedulingV1().PriorityClasses().Delete(context.TODO(), pc.Name, *metav1.NewDeleteOptions(0)) framework.ExpectNoError(err) } }) ginkgo.It("verify PriorityClass endpoints can be operated with different HTTP methods", func() { // 1. Patch/Update on immutable fields will fail. pcCopy := pcs[0].DeepCopy() pcCopy.Value = pcCopy.Value * 10 err := patchPriorityClass(cs, pcs[0], pcCopy) framework.ExpectError(err, "expect a patch error on an immutable field") framework.Logf("%v", err) pcCopy = pcs[1].DeepCopy() pcCopy.Value = pcCopy.Value * 10 _, err = cs.SchedulingV1().PriorityClasses().Update(context.TODO(), pcCopy, metav1.UpdateOptions{}) framework.ExpectError(err, "expect an update error on an immutable field") framework.Logf("%v", err) // 2. Patch/Update on mutable fields will succeed. newDesc := "updated description" pcCopy = pcs[0].DeepCopy() pcCopy.Description = newDesc err = patchPriorityClass(cs, pcs[0], pcCopy) framework.ExpectNoError(err) pcCopy = pcs[1].DeepCopy() pcCopy.Description = newDesc _, err = cs.SchedulingV1().PriorityClasses().Update(context.TODO(), pcCopy, metav1.UpdateOptions{}) framework.ExpectNoError(err) // 3. List existing PriorityClasses. _, err = cs.SchedulingV1().PriorityClasses().List(context.TODO(), metav1.ListOptions{}) framework.ExpectNoError(err) // 4. Verify fields of updated PriorityClasses. for _, pc := range pcs { livePC, err := cs.SchedulingV1().PriorityClasses().Get(context.TODO(), pc.Name, metav1.GetOptions{}) framework.ExpectNoError(err) framework.ExpectEqual(livePC.Value, pc.Value) framework.ExpectEqual(livePC.Description, newDesc) } }) }) </ins> }) type pauseRSConfig struct {

_, err = client.CoreV1().Nodes().Patch(context.TODO(), old.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}, "status") return err } <ins> func patchPriorityClass(cs clientset.Interface, old, new *schedulingv1.PriorityClass) error { oldData, err := json.Marshal(old) if err != nil { return err } newData, err := json.Marshal(new) if err != nil { return err } patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, &schedulingv1.PriorityClass{}) if err != nil { return fmt.Errorf("failed to create merge patch for PriorityClass %q: %v", old.Name, err) } _, err = cs.SchedulingV1().PriorityClasses().Patch(context.TODO(), old.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}) return err } </ins>