New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed sort-by not sorting Resources as expected #100435
Conversation
Hi @lauchokyip. Thanks for your PR. I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/cc @eddiezane |
/ok-to-test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lauchokyip thanks for your PR.
I've left some comments, PTAL :)
|
||
// IsQuantity returns true if the reflect.Value is type Quantity | ||
func IsQuantity(obj reflect.Value) bool { | ||
objInterface := obj.Interface() | ||
switch objInterface.(type) { | ||
case apiresource.Quantity: | ||
return true | ||
default: | ||
return false | ||
} | ||
} | ||
|
||
// QuantityToString returns the string value of Quantity. | ||
// IsQuantity needs to be called in advance to check if it's Quantity | ||
func QuantityToString(obj reflect.Value) string { | ||
objInterface := obj.Interface() | ||
quantity := objInterface.(apiresource.Quantity) | ||
return quantity.String() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking if those two functions couldn't be simplified into one, as:
func GetQuantity(obj reflect.Value) reflect.Value {
switch objInterface := obj.Interface(); objInterface.(type) {
case apiresource.Quantity:
objStr := objInterface.(apiresource.Quantity)
return reflect.ValueOf(objStr.String())
default:
return obj
}
}
And then, when it's called, just to a later iField = cmdutil.GetQuantity(iField)
:)
@@ -95,6 +97,8 @@ func (s *SortingPrinter) sortObj(obj runtime.Object) error { | |||
return meta.SetList(obj, objs) | |||
} | |||
|
|||
// SortObjects sorts the runtime.Obejct based on filedInput and returns RuntimeSort that implements |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo here - Obejct/Object
Thank You @rikatz, your feedbacks are very helpful! |
/retest |
/lgtm Thank you! |
/hold cancel |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: eddiezane, lauchokyip, rikatz The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Will this support sort of |
Hi @pacoxu I believe it will because essentially the field @eddiezane @KnVerey Do you think I should add more test cases for all of them |
This change LGTM. |
@@ -95,6 +96,8 @@ func (s *SortingPrinter) sortObj(obj runtime.Object) error { | |||
return meta.SetList(obj, objs) | |||
} | |||
|
|||
// SortObjects sorts the runtime.Object based on filedInput and returns RuntimeSort that implements |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// SortObjects sorts the runtime.Object based on filedInput and returns RuntimeSort that implements | |
// SortObjects sorts the runtime.Object based on fieldInput and returns RuntimeSort that implements |
// check if it's a Quantity | ||
itypeQuantity, err := resource.ParseQuantity(itype) | ||
if err != nil { | ||
return sortorder.NaturalLess(itype, jtype), nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of ignoring the error parsing jtypeQuanity below, I think we should return this default behavior if either one cannot be parsed to a quantity.
q, _ := resource.ParseQuantity(str) | ||
return q | ||
} | ||
func createPodSpecResource(memReq, memLimit, cpuReq, cpuLimit string) corev1.PodSpec { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's pass t *testing.T
as the first argument and use it to make the test fail if the setup is invalid. In other words, if the helper is given an invalid quantity, the test should fail, not ignore the parsing error and potentially not test what it is expected to. You can call t.Helper()
to make it a proper test helper with better line information on failures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sense!
No, I don't think it's necessary to add coverage for additional |
@KnVerey , fixed, PTAL 👍🏼 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple more little test quibbles, but after that I think this looks ready to go!
@@ -47,6 +48,61 @@ func encodeOrDie(obj runtime.Object) []byte { | |||
} | |||
return data | |||
} | |||
func createResource(str string) (resource.Quantity, error) { | |||
q, err := resource.ParseQuantity(str) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could just return resource.ParseQuantity(str)
... so let's get rid of this function and inline the resource.ParseQuantity(str)
calls.
|
||
return podSpec | ||
} | ||
func createUnstructuredPodResource(t *testing.T, memReq, memLimit, cpuReq, cpuLimit string) unstructured.Unstructured { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason not to add t.Helper()
here too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just thought because that function doesnn't have t.Errorf()
so it might not be needed 😕 will add that in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What t.Helper()
does is let Go know that this is a test helper, so that it can skip it when printing line and file information, which makes error reporting easier to understand when a test fails. A pretty minor thing, but since the Testing instance already has to be passed in, might as well get this benefit. 🙂
@KnVerey fixed! ready for final look 😃 |
/lgtm |
What type of PR is this?
/kind bug
What this PR does / why we need it:
When using
sort-by
to sort Resources, output is sorted unexpectedlyWhich issue(s) this PR fixes:
Fixes kubernetes/kubectl#1019
Special notes for your reviewer:
Does this PR introduce a user-facing change?
Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.: