Skip to content
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

test: add ResourceGroup assertions to WatchForSync #1579

Conversation

sdowell
Copy link
Contributor

@sdowell sdowell commented Feb 28, 2025

This adds validation for the ResourceGroup status in the WatchForSync function, which is used extensively in the test framework to validate RSyncs and wait for them to finish syncing.

This will cause WatchForSync to now also wait for all synced objects to reconcile and for the ResourceGroup to be current. This is intended to provide test coverage for the resource-group-controller when integrated with Config Sync.

@sdowell sdowell force-pushed the add-rg-assertions-watch-for-sync branch from 25f73b2 to 48b2528 Compare March 1, 2025 00:25
@@ -229,6 +229,17 @@ func (nt *NT) WatchForSync(
return fmt.Errorf("waiting for sync: %w", err)
}
nt.T.Logf("%s %s/%s is synced", gvk.Kind, namespace, name)
rgPredicates := []testpredicates.Predicate{
// Wait until status.observedGeneration matches metadata.generation
testpredicates.HasObservedLatestGeneration(nt.Scheme),
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not really sure what the expected behavior was intended to be for the observedGeneration today. My guess is that nobody really considered how it would work with two controllers.

Anyway, I'm changing how it works in #1575

Instead of adding controller-specific observedGenerations, I was able to get it to work by having the applier inventory client handle setting it correctly when it updates the status, and then the RGC requires them to match before it will do its status updates, to avoid race conditions between spec & status updates.

This means that there's no status flag we can really use to confirm that the RGC has done its job. But that's sort of ok, for now.

It does mean that the kstatus fields will still be UNKNOWN until we fix cli-utils to pass it through to the inventory client so it can write them.

Another gotcha worth mentioning is that when the status is disabled, the observedGeneration is not updated. So this check likely needs to be embedded in resourceGroupHasReconciled.

@sdowell sdowell force-pushed the add-rg-assertions-watch-for-sync branch 2 times, most recently from 89ebbc1 to 72561c8 Compare March 6, 2025 22:59
@google-oss-prow google-oss-prow bot added size/L and removed size/M labels Mar 6, 2025
@sdowell sdowell force-pushed the add-rg-assertions-watch-for-sync branch 3 times, most recently from 58cbff9 to 46658f2 Compare March 7, 2025 21:34
@sdowell
Copy link
Contributor Author

sdowell commented Mar 7, 2025

/retest

return nil
}

if len(rg.Spec.Resources) != len(rg.Status.ResourceStatuses) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to validate that all the resources match in spec & status? Or is that too much here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's exactly what the code below does.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, right. I was kinda confused by the resourceCount map.

It looks like you're validating that there's not more than one entry with the same ID, which seems good. But it's kinda hard to read.

I think there's a way to enforce that in the apiserver with schema validation, but it doesn't look like our CRD has those defined today. I know resources can define unique compound list keys. They added it for server-side apply list merging. I guess that's something we can add later.

What about building a fake []ResourceStatus from the status.resourceStatuses and then using semantic.DeepEquals to compare it to the real status.resources. Then you could error with a yaml diff that would make it easy to see how they compare?

Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW, this only works if they're sorted, which they might not be. So you might have to DeepCopy status.resources and then sort both the actual and expected lists before comparing them.

Copy link
Contributor Author

@sdowell sdowell Mar 10, 2025

Choose a reason for hiding this comment

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

Correct, the lists are not sorted - hence the decision to build a map to determine equality. Also it's not validating that the IDs are unique - this is purely verifying list equality. It's validating that the lists have the same set of IDs, including same number of duplicate IDs if there are duplicates.

Copy link
Contributor

Choose a reason for hiding this comment

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

Alright. I think there's some readability/correctness changed we could make here, but I don't want to hold up our other PRs, and I don't really think it's all that important for general validation we use in every e2e test.

I wish we could just check the conditions here, and save all the other fields for validating in RG-specific tests, but that's not today's reality.

We can iterate on this later.

if rs.Actuation != v1alpha1.ActuationSucceeded {
return fmt.Errorf("resourceStatus.actuation is not %s. Got %s", v1alpha1.ActuationSucceeded, rs.Actuation)
}
if rs.SourceHash != status.TruncateSourceHash(sourceHash) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Huh. I didn't even know these had a source hash field. Nifty.

So I guess you can tell if they're all on the same commit pretty easy, you just can't tell what commit it's supposed to be from the spec.

I guess if we have this in the status, maybe we should add a SourceHash to the spec, instead of adding a source-commit annotation. That would make it possible to check that the status matches the spec without external knowledge.

Guess we can do that in a different PR, but we're gonna need approval from @janetkuo

@sdowell sdowell force-pushed the add-rg-assertions-watch-for-sync branch 5 times, most recently from d2b2b58 to 07d83e0 Compare March 7, 2025 23:12
This adds validation for the ResourceGroup status in the WatchForSync
function, which is used extensively in the test framework to validate
RSyncs and wait for them to finish syncing.

This will cause WatchForSync to now also wait for all synced objects to
reconcile and for the ResourceGroup to be current. This is intended to
provide test coverage for the resource-group-controller when integrated
with Config Sync.
@sdowell sdowell force-pushed the add-rg-assertions-watch-for-sync branch from 07d83e0 to e97ee76 Compare March 8, 2025 05:55
Copy link
Contributor

@karlkfi karlkfi left a comment

Choose a reason for hiding this comment

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

/lgtm

Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: karlkfi

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@google-oss-prow google-oss-prow bot merged commit bb19d8a into GoogleContainerTools:main Mar 10, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants