Skip to content

Conversation

@kwiesmueller
Copy link
Member

While working on an implementation of kubernetes/enhancements#1123
i discovered that removing fields is not behaving like I expected.

Provided an original fieldSet like:

.status.phase

and a fieldSet to be removed:

.status

The current Difference and Intersect methods for fieldSets do not match all child paths when a parent path is defined, because .status != .status.phase.

For most cases, this seems reasonable (like ownership).

But to define a set of fields that should be removed from the object, it is impractical.
To avoid a user has to define every deep path to be removed (for status wiping),
a second Remove method is added to value.TypedValue that removes a fieldpath once found.

It extends the already available RemoveItems behavior to also remove from maps.

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Dec 9, 2019
@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Dec 9, 2019
@kwiesmueller
Copy link
Member Author

/retest

@kwiesmueller kwiesmueller changed the title [WIP] add extended remove method for typed values add extended remove method for typed values Dec 23, 2019
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Dec 23, 2019
@kwiesmueller kwiesmueller changed the title add extended remove method for typed values [WIP] add extended remove method for typed values Dec 23, 2019
@k8s-ci-robot k8s-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Dec 23, 2019
Copy link
Contributor

@apelisse apelisse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the tests Kevin! They are extremely useful

object: `{"a": "value", "b":{"c":"value"}}`,
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b")),
deep: false,
// TODO: this seems to behave differently with a non deduced schema: {"a": "value", "b":{"c":"value"}} which is the reason for this PR
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jennybuckley probably knows, I suspect it's because we treat deduced fields as map fields?

Copy link
Member Author

@kwiesmueller kwiesmueller Jan 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking about adding a second test that defines the schema for all the tests above to verify.
If the behavior differs, we can at least be sure we want it to do.
Probably tomorrow.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think this is because deduced schema would see "b":{"c":"value"} as a map item, and so it would be removable, but if you defined a schema which has the fields named, then it would be seen as a struct field, and I don't think we expect to remove those with RemoveItems, since this function was created to remove list/map items that no appliers owns anymore, a behavior which doesn't apply to struct fields (since we didn't want removing replicas from a config and reapplying to reset replicas to 1)

@kwiesmueller
Copy link
Member Author

/retest
to see if everything breaks now (as it should with the race test)

@kwiesmueller
Copy link
Member Author

/test pull-structured-merge-diff-test

@kwiesmueller kwiesmueller force-pushed the extend-remove branch 2 times, most recently from 37509fd to bf5b0dc Compare January 15, 2020 23:13
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jan 21, 2020
@k8s-ci-robot k8s-ci-robot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Feb 18, 2020
@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels Feb 18, 2020
@kwiesmueller
Copy link
Member Author

@apelisse i pushed my current state including the failing tests.
The TestUpdateLeaf ones are the ones i mentioned a week ago. They fail because of pruning and the new remove.

The TestMultipleAppliers are new and should be caused by the different null behavior.
I am not sure yet why they fail, but am looking at it.

Copy link
Contributor

@apelisse apelisse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked at merge/update.go yet and how prune will be broken with this. We can do that later.

}

// NewIndexPathElement creates a PathElement with the given index
func NewIndexPathElement(index int) PathElement {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're not using the method above, but you're using this one. We really shouldn't depend on this. Let's see ...

}

// PrintState is an Operation printing the current state to help with debugging tests
type PrintState struct{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are good suggestions. I had thought about some version of this but thought that it was equally simple to have multiple tests:

Test 1: do a
Test 2: do a and b
Test 3: do a, b and c

if you really care about intermediate state, what do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, multiple tests would solve that as well.
While creating (and debugging) the remove tests, it was already getting less comfortable working with them due to the amount of tests. Also because of my unfortunate decision not to name them...

For now I only wanted to understand and debug the broken tests that already exist.
Pulling them apart into multiple tests would have been something for another PR and then still might cause more clutter while the Print and Expect Operations would allow for the same result in the existing test fixture thing.

Object: `
mapOfMapsRecursive:
a:
a: {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little unfortunate :-/ but I think that's fine.

@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 3, 2020
Copy link
Contributor

@apelisse apelisse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, the code looked OK to me, and I don't see anything wrong with the tests either. I suspect we can try a few more corner-cases though.

return fmt.Errorf("failed to compare live with config: %v", err)
}
if !comparison.IsSame() {
config, err := state.Parser.Type(string(op.APIVersion)).FromYAML(FixTabsOrDie(op.Object))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move this code to a separate function since it's done twice and is hard to read.

},
{
object: `{"a": "value", "b": ["c", "d"]}`,
remove: _NS(_P("b", _I(1))),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a test that removes by value, do we have one? Maybe below, but I suspect it belongs here

l := w.value.AsListUsing(w.allocator)
defer w.allocator.Free(l)
// If list is null, empty, or atomic just return
if l == nil || l.Length() == 0 || t.ElementRelationship == schema.Atomic {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jennybuckley Do you remember why we had the atomic check here? Would it be a problem to remove it?

Copy link
Contributor

@apelisse apelisse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I think this is good, @jennybuckley would you mind looking at this?

@jennybuckley
Copy link

/assign

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: kwiesmueller
To complete the pull request process, please assign jennybuckley
You can assign the PR to them by writing /assign @jennybuckley in a comment when ready.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kwiesmueller kwiesmueller changed the title [WIP] add extended remove method for typed values add extended remove method for typed values Mar 25, 2020
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 25, 2020
@kwiesmueller
Copy link
Member Author

@jennybuckley did you have time to look at this?

@apelisse
Copy link
Contributor

Can you please squash? Thanks

@fejta-bot
Copy link

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

@k8s-ci-robot k8s-ci-robot added lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Jul 9, 2020
@k8s-ci-robot
Copy link
Contributor

@kwiesmueller: PR needs rebase.

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.

@apelisse
Copy link
Contributor

apelisse commented Jul 9, 2020

I think that's been replaced.

@apelisse apelisse closed this Jul 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants