Skip to content

Conversation

@rsoaresd
Copy link
Contributor

@rsoaresd rsoaresd commented Oct 7, 2025

Description

Lately, we are often hitting this flaky test:

space.go:108: 
        	Error Trace:	/go/src/github.com/codeready-toolchain/toolchain-e2e/testsupport/space/space.go:108
        	            				/go/src/github.com/codeready-toolchain/toolchain-e2e/test/e2e/space_autocompletion_test.go:73
        	Error:      	Received unexpected error:
        	            	context deadline exceeded
        	Test:       	TestAutomaticClusterAssignment/set_low_max_number_of_spaces_and_expect_that_space_won't_be_provisioned_but_added_on_waiting_list/increment_the_max_number_of_spaces_and_expect_that_first_space_will_be_provisioned.

The space count mismatch seems to happen between "setup migration" and "verify migration" steps. It can be happening for two reasons:

  • Premature Operator Shutdown
    we simply kill the operators (at the end of the migration setup) too early, so it either doesn't properly decreased the counter or it doesn't store the decreased value to the ToolchainStatus

  • No Counter Reconciliation on Startup
    we don't recount the Spaces at the start of the host operator in e2e tests

Slack thread

https://redhat-internal.slack.com/archives/CHK0J6HT6/p1759830691610259

Paired PR

codeready-toolchain/toolchain-e2e#1212

Issue ticket number and link

SANDBOX-1437

Assisted-by: Cursor

Summary by CodeRabbit

  • New Features

    • Metrics: forced synchronization is now enabled by default when no explicit flag is set.
  • Bug Fixes / Behavior Changes

    • Default and non-default expectations for metrics synchronization inverted to match the new default.
  • Tests

    • Test suite updated to use new helpers and variants to initialize counters with or without metrics synchronization and to accept an explicit toolchain config during test setup.

@openshift-ci openshift-ci bot requested review from fbm3307 and jrosental October 7, 2025 15:39
@openshift-ci openshift-ci bot added the approved label Oct 7, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 7, 2025

Walkthrough

Changed the default of MetricsConfig.ForceSynchronization() to true when the flag is unset; added test helpers to initialize counters with an explicit ToolchainConfig or with metrics synchronization disabled; updated many tests and test helper signatures to use the new helpers and to pass ToolchainConfig where needed.

Changes

Cohort / File(s) Summary
Configuration default
controllers/toolchainconfig/configuration.go
Inverted default for MetricsConfig.ForceSynchronization() when the flag is unset (now returns true). No signature changes.
Test counter helpers
test/counter.go
Added InitializeCountersWithToolchainConfig(...) and InitializeCountersWithMetricsSyncDisabled(...); adjusted existing InitializeCounters variants to create FakeClients including a ToolchainConfig or to disable metrics sync during initialization; imports updated.
Usersignup controller tests
controllers/usersignup/*_test.go
prepareReconcile signature extended to accept *toolchainv1alpha1.ToolchainConfig (nil uses default); tests updated to pass ToolchainConfig and to use InitializeCountersWithToolchainConfig or the disabled-sync helper.
MasterUserRecord & Space tests
controllers/masteruserrecord/masteruserrecord_controller_test.go, controllers/space/space_controller_test.go
Replaced InitializeCounters(...) calls with InitializeCountersWithMetricsSyncDisabled(...) to disable metrics sync during test initialization.
SpaceCompletion tests
controllers/spacecompletion/space_completion_controller_test.go
Added forceSynchronization boolean parameter to prepareReconcile; code now chooses between InitializeCounters (true) and InitializeCountersWithMetricsSyncDisabled (false); call sites updated accordingly.
ToolchainStatus & ToolchainConfig tests
controllers/toolchainstatus/toolchainstatus_controller_test.go, controllers/toolchainconfig/configuration_test.go
Tests updated to use new InitializeCounters helpers; assertions changed to reflect the inverted default of ForceSynchronization() (default true when unset); some tests construct explicit ToolchainConfig with ForceSynchronization(false).
Package counter tests
pkg/counter/cache_test.go
Switched initialization to InitializeCountersWithMetricsSyncDisabled(...); removed some commonconfig/testconfig imports and adjusted inits accordingly.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant App
  participant ToolchainConfig
  participant MetricsConfig

  App->>ToolchainConfig: Load ToolchainConfig (may be absent)
  ToolchainConfig->>MetricsConfig: Query ForceSynchronization()
  alt Flag explicitly set
    MetricsConfig-->>ToolchainConfig: Return configured value
  else Flag unset
    note right of MetricsConfig `#D8F3DC`: New default → true
    MetricsConfig-->>ToolchainConfig: Return true
  end
  ToolchainConfig-->>App: Provide effective Metrics configuration
Loading
sequenceDiagram
  autonumber
  participant TestRunner
  participant InitHelper
  participant FakeClient
  participant Counters

  TestRunner->>InitHelper: Call InitializeCountersWithToolchainConfig(...) or InitializeCountersWithMetricsSyncDisabled(...)
  alt With ToolchainConfig
    InitHelper->>FakeClient: Build FakeClient including ToolchainConfig
  else Metrics sync disabled
    InitHelper->>FakeClient: Build FakeClient without metrics sync init
  end
  InitHelper->>Counters: Initialize counters using FakeClient
  Counters-->>TestRunner: Test state ready
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay attention to test helper behavior in test/counter.go and its interactions with FakeClient construction.
  • Verify tests that explicitly set ForceSynchronization(false) (various controller tests) to ensure assertions match new defaults.
  • Inspect controllers/spacecompletion/space_completion_controller_test.go for correct usage of the new forceSynchronization parameter.

Suggested reviewers

  • metlos
  • alexeykazakov
  • MatousJobanek
  • rajivnathan
  • fbm3307

Poem

I twitched my whiskers, toggled a flag anew,
Defaults hopped over — now true by view.
Counters split their paths, some skip, some sing,
Tests line up neatly as I nibble a thing.
Carrot in paw, I celebrate this new cue. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: setting ForceSynchronization to true by default in MetricsConfig, which is the core objective across all modified files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3599eea and 79951f3.

📒 Files selected for processing (2)
  • controllers/spacecompletion/space_completion_controller_test.go (12 hunks)
  • test/counter.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/counter.go
🧰 Additional context used
🧬 Code graph analysis (1)
controllers/spacecompletion/space_completion_controller_test.go (1)
test/counter.go (2)
  • InitializeCounters (106-111)
  • InitializeCountersWithMetricsSyncDisabled (120-123)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build & push operator bundles for e2e tests
🔇 Additional comments (4)
controllers/spacecompletion/space_completion_controller_test.go (4)

34-34: LGTM! Call sites correctly pass false for standard test cases.

All these call sites appropriately pass false to disable metrics synchronization during counter initialization, which is suitable for standard test scenarios where synchronization overhead is unnecessary.

Also applies to: 50-50, 67-67, 85-85, 103-103, 119-119, 135-135, 153-153, 197-197


173-175: Excellent comment explaining the synchronization requirement!

The comment clearly explains why this test needs forceSynchronization=true: to prevent ToolchainConfig caching during initialization, ensuring the mock at lines 176-181 is actually invoked when testing GetToolchainConfig error handling.


217-217: LGTM! Function signature appropriately extended.

The new forceSynchronization parameter clearly conveys its purpose and enables selective control over counter initialization behavior in tests.


227-231: LGTM! Branching logic correctly implements counter initialization.

The conditional logic properly calls InitializeCounters when synchronization is needed and InitializeCountersWithMetricsSyncDisabled otherwise, enabling precise control over ToolchainConfig caching behavior in tests.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9e5f2e and 5b02925.

📒 Files selected for processing (1)
  • controllers/toolchainconfig/configuration.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build & push operator bundles for e2e tests
  • GitHub Check: GolangCI Lint
  • GitHub Check: Test with Coverage

Comment on lines 201 to 203
func (d MetricsConfig) ForceSynchronization() bool {
return commonconfig.GetBool(d.metrics.ForceSynchronization, false)
return commonconfig.GetBool(d.metrics.ForceSynchronization, true)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify that forced synchronization resolves the flaky test and doesn't degrade performance.

The default change from false to true aligns with the PR objective to fix flaky space count verification failures. However, please confirm:

  1. Has this change been tested with the paired toolchain-e2e PR update .govulncheck.yaml #1212 to verify it resolves the context deadline exceeded errors?
  2. What is the performance impact of forcing synchronization by default? If synchronization is expensive, this could introduce latency in the operator's reconciliation loops.
  3. Are there any existing deployments or configurations that explicitly rely on the old default of false? If so, they should be documented in migration notes.

Run the following script to check how ForceSynchronization() is used throughout the codebase to assess potential impact:


🏁 Script executed:

#!/bin/bash
# Description: Find all usages of ForceSynchronization to understand the impact of changing the default

# Search for direct calls to ForceSynchronization method
echo "=== Direct calls to ForceSynchronization() ==="
rg -n -C3 'ForceSynchronization\(\)' --type=go

echo -e "\n=== References to metrics config that might use ForceSynchronization ==="
rg -n -C3 '\.Metrics\(\)' --type=go

echo -e "\n=== Check for any documentation mentioning ForceSynchronization ==="
rg -n 'ForceSynchronization' --type=md

Length of output: 5123


Fix default in configuration tests and document the change

  • The default for ForceSynchronization() is now true, but the test at controllers/toolchainconfig/configuration_test.go:335 still asserts false; update it to assert.True(...).
  • Update any documentation or migration notes to reflect the new default and evaluate potential performance impacts of always forcing synchronization.
🤖 Prompt for AI Agents
In controllers/toolchainconfig/configuration.go around lines 201 to 203, the
ForceSynchronization() default was changed to true; update the failing unit test
at controllers/toolchainconfig/configuration_test.go line ~335 to
assert.True(...) instead of assert.False(...), and update any related
documentation or migration notes to indicate the new default is true and call
out potential performance implications of always forcing synchronization so
reviewers/operators are aware of the change.

Copy link
Contributor

@alexeykazakov alexeykazakov left a comment

Choose a reason for hiding this comment

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

@xcoulon are there any potential side effects if always force synch? If so then I would make sure we set it to false in production configuration.

@rsoaresd rsoaresd marked this pull request as draft October 8, 2025 10:40
@MatousJobanek
Copy link
Contributor

@alexeykazakov We already force do the force sync in production: https://github.com/codeready-toolchain/sandbox-sre/blob/dc7005f467bb0c8651b3d538cf2c03c87f183db7/components/sandbox/devsandbox-production/host-cluster/toolchain-config.yaml#L13-L14

When this is executed, then the client cache is already initialized so there shouldn't be any extra load on the API as this will use only the client cache. This is also the reason why I suggested enabling the force sync by default.

Copy link
Contributor

@MatousJobanek MatousJobanek left a comment

Choose a reason for hiding this comment

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

Looks good, but let's try to simplify the code-duplication.

Comment on lines 1033 to 1034
toolchainConfig := commonconfig.NewToolchainConfigObjWithReset(t, testconfig.Metrics().ForceSynchronization(false))
InitializeCounters(t, toolchainStatus, toolchainConfig)
Copy link
Contributor

Choose a reason for hiding this comment

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

it looks like that most of the cases use the disabled synchronization, so maybe worth adjusting the InitializeCounters logic and/or create another one called InitializeCounterWithConfig, or something similar.

t.Cleanup(counter.Reset)
initializeCounters(t, commontest.NewFakeClient(t), toolchainStatus)

toolchainConfig := commonconfig.NewToolchainConfigObjWithReset(t, testconfig.Metrics().ForceSynchronization(false))
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, we could do something similar also in the other function. TBH, I'm wondering how many test cases we have where we don't sync the counters from the ToolchainStatus, but by syncing from the resources. There is maybe some room for additional simplification.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestions!

  • I kept the InitializeCounters for the cases we want ForceSynchronization to true (which is now our default).

  • I created InitializeCountersWithMetricsSyncDisabled to initialize the counters with the metrics synchronization disabled (covers the majority of the test cases)

  • I also created InitializeCountersWithToolchainConfig to initialize the counters with the toolchain configuration given (because some tests require synchronization disabled plus other specific config like automatic approval)

@rsoaresd rsoaresd marked this pull request as ready for review October 20, 2025 09:03
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
controllers/usersignup/usersignup_controller_test.go (2)

2403-2426: Fix variable mix-up: use userSignup2 instead of userSignup in this subtest.

Assertions reference the wrong variable, so the test may pass/fail for the wrong object.

Apply this diff:

-        assert.Equal(t, "deactivated", userSignup.Labels[toolchainv1alpha1.UserSignupStateLabelKey])
+        assert.Equal(t, "deactivated", userSignup2.Labels[toolchainv1alpha1.UserSignupStateLabelKey])

-        test.AssertConditionsMatch(t, userSignup.Status.Conditions,
+        test.AssertConditionsMatch(t, userSignup2.Status.Conditions,
           toolchainv1alpha1.Condition{
             Type:   toolchainv1alpha1.UserSignupApproved,
             Status: corev1.ConditionFalse,
             Reason: "Deactivated",
           },
           toolchainv1alpha1.Condition{
             Type:   toolchainv1alpha1.UserSignupComplete,
             Status: corev1.ConditionTrue,
             Reason: "Deactivated",
           },
           toolchainv1alpha1.Condition{
             Type:   toolchainv1alpha1.UserSignupUserDeactivatedNotificationCreated,
             Status: corev1.ConditionTrue,
             Reason: "NotificationCRCreated",
           })

2149-2156: Don’t recreate the fake client; update the existing object instead.

Re-invoking prepareReconcile drops the previously created MUR, weakening the intent (“synchronize modified claims to existing MUR”). Update the existing UserSignup and reconcile again.

Apply this diff:

-    // Reconcile the UserSignup again
-    r, req, _ = prepareReconcile(t, userSignup.Name, nil, spc1, userSignup, deactivate30Tier)
-    res, err = r.Reconcile(context.TODO(), req)
+    // Reconcile the UserSignup again (same client, preserves existing MUR)
+    require.NoError(t, r.Client.Update(context.TODO(), userSignup))
+    res, err = r.Reconcile(context.TODO(), req)
🧹 Nitpick comments (5)
controllers/spacecompletion/space_completion_controller_test.go (1)

215-229: Consider clearer naming for the boolean parameter.

The skipToolchainConfig parameter creates somewhat inverted logic: false means "create a ToolchainConfig with metrics sync disabled", while true means "don't create one" (allowing the default ForceSynchronization=true behavior). This aligns with the past review comment suggesting a clearer helper approach.

Consider either:

  1. Renaming to enableMetricsSync for more intuitive semantics
  2. Creating a dedicated helper like prepareReconcileWithMetricsSync(enable bool) as suggested in the past review

Current implementation works correctly, but the semantics could be more intuitive.

Based on learnings.

controllers/usersignup/usersignup_controller_test.go (4)

4109-4135: Avoid double counter initialization and config divergence in tests.

prepareReconcile initializes counters with a default ToolchainConfig (and a default ToolchainStatus), but many tests reinitialize counters immediately after with custom ToolchainStatus. This causes:

  • Redundant resets/work.
  • Potential divergence between the ToolchainStatus stored in r.Client and the one used to seed in-memory counters.

Consider one of:

  • Accept a ToolchainStatus parameter (or an option) in prepareReconcile and initialize counters only once with the caller-provided status.
  • Or add a flag/option to skip internal counter init when tests will call InitializeCounters* themselves.

116-119: Reduce boilerplate for test configs that just disable metrics sync.

You repeatedly build ToolchainConfig with Metrics().ForceSynchronization(false). Add a tiny helper, eg newTestConfig(t, opts...) that always includes ForceSynchronization(false) and merges extra options (AutomaticApproval, Tiers, Captcha, etc.). This will simplify tests and prevent omissions.

Also applies to: 239-240, 428-431, 572-576, 623-626, 667-673, 716-719, 759-766, 962-965, 1025-1026, 1088-1091, 1219-1229


115-115: Remove redundant counter.Reset() defers when using InitializeCounters helpers.*

InitializeCountersWithToolchainConfig/InitializeCountersWithMetricsSyncDisabled already call counter.Reset() and register t.Cleanup(counter.Reset). The extra defers are unnecessary.

Also applies to: 229-229, 334-334


1660-1669: Ensure InitializeCounters reads the same ToolchainConfig used by the reconciler.*

When prepareReconcile is called with toolchainConfig == nil, it creates and injects a default config into r.Client, while InitializeCountersWithMetricsSyncDisabled creates a separate ToolchainConfig instance inside its own fake client. Prefer passing the same ToolchainConfig object to both paths (eg, create it once and pass into prepareReconcile; or provide an InitializeCountersFromClient(fakeClient) helper) to avoid subtle divergence.

Also applies to: 1723-1731, 1769-1777

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b02925 and 4fe0c60.

📒 Files selected for processing (8)
  • controllers/masteruserrecord/masteruserrecord_controller_test.go (28 hunks)
  • controllers/space/space_controller_test.go (39 hunks)
  • controllers/spacecompletion/space_completion_controller_test.go (12 hunks)
  • controllers/toolchainconfig/configuration_test.go (1 hunks)
  • controllers/toolchainstatus/toolchainstatus_controller_test.go (14 hunks)
  • controllers/usersignup/usersignup_controller_test.go (66 hunks)
  • pkg/counter/cache_test.go (11 hunks)
  • test/counter.go (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
controllers/toolchainstatus/toolchainstatus_controller_test.go (1)
test/counter.go (1)
  • InitializeCountersWithMetricsSyncDisabled (127-137)
controllers/space/space_controller_test.go (2)
test/counter.go (1)
  • InitializeCountersWithMetricsSyncDisabled (127-137)
test/toolchainstatus.go (4)
  • NewToolchainStatus (15-26)
  • WithEmptyMetrics (125-135)
  • WithMember (76-87)
  • WithSpaceCount (91-95)
pkg/counter/cache_test.go (2)
test/counter.go (1)
  • InitializeCountersWithMetricsSyncDisabled (127-137)
test/toolchainstatus.go (1)
  • NewToolchainStatus (15-26)
test/counter.go (2)
controllers/toolchainconfig/configuration.go (1)
  • ToolchainConfig (33-36)
pkg/counter/cache.go (1)
  • Reset (53-57)
controllers/spacecompletion/space_completion_controller_test.go (1)
test/counter.go (2)
  • InitializeCounters (106-112)
  • InitializeCountersWithMetricsSyncDisabled (127-137)
controllers/usersignup/usersignup_controller_test.go (2)
test/counter.go (2)
  • InitializeCountersWithToolchainConfig (115-124)
  • InitializeCountersWithMetricsSyncDisabled (127-137)
test/toolchainstatus.go (1)
  • NewToolchainStatus (15-26)
controllers/masteruserrecord/masteruserrecord_controller_test.go (2)
test/counter.go (1)
  • InitializeCountersWithMetricsSyncDisabled (127-137)
test/toolchainstatus.go (1)
  • NewToolchainStatus (15-26)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Test with Coverage
  • GitHub Check: Build & push operator bundles for e2e tests
  • GitHub Check: Build & push operator bundles for e2e tests
  • GitHub Check: Test with Coverage
🔇 Additional comments (11)
controllers/toolchainconfig/configuration_test.go (1)

330-343: LGTM: Test correctly reflects the inverted default for ForceSynchronization.

The test expectations have been properly updated to reflect the new default behavior where ForceSynchronization() returns true when the flag is unset, and false when explicitly configured.

controllers/masteruserrecord/masteruserrecord_controller_test.go (1)

57-57: LGTM: Tests updated to use explicit metrics sync disabled initialization.

All test initializations in this file have been consistently updated to use InitializeCountersWithMetricsSyncDisabled, ensuring deterministic test behavior that's independent of the new ForceSynchronization default.

controllers/space/space_controller_test.go (1)

70-70: LGTM: Consistent test initialization with metrics sync disabled.

All space controller tests have been systematically updated to explicitly disable metrics synchronization during initialization, ensuring consistent and predictable test behavior.

pkg/counter/cache_test.go (1)

28-411: LGTM: Counter tests appropriately distinguish sync behavior.

Most tests now explicitly use InitializeCountersWithMetricsSyncDisabled for deterministic behavior. Notably, TestForceInitializeCounterByLoadingExistingResources (line 373) intentionally continues using InitializeCounters to specifically test the force synchronization path where counters are recalculated from actual resources. This distinction is correct and aligns with the test's intent.

controllers/toolchainstatus/toolchainstatus_controller_test.go (3)

513-532: LGTM! Test correctly configures synchronization behavior.

The test appropriately creates a ToolchainConfig with ForceSynchronization(false) to test counter initialization from ToolchainStatus without interference from cluster resource synchronization. This allows verification of incremental counter updates as intended by lines 1535-1538.


705-705: LGTM! Consistent use of metrics sync disabled helper.

The consistent use of InitializeCountersWithMetricsSyncDisabled across these test cases is appropriate. These tests verify specific counter states and member cluster scenarios where deterministic counter values from ToolchainStatus are required without interference from force synchronization with cluster resources.

Also applies to: 742-742, 778-778, 806-806, 827-827, 852-852, 905-905, 927-927, 958-958, 985-985, 1017-1017


1569-1571: LGTM! Counter assertions are correct.

The space count assertions correctly verify:

  • member-1: 7 spaces (6 from initial ToolchainStatus + 1 from increment at line 1536)
  • member-2: 2 spaces (from initial ToolchainStatus, unchanged)

The inline comments accurately document the counter sources, and the values match the expected behavior with metrics synchronization disabled.

test/counter.go (4)

114-124: LGTM! Well-designed helper function.

InitializeCountersWithToolchainConfig provides appropriate flexibility for tests that need explicit control over the ToolchainConfig. The implementation follows established patterns, properly handles cleanup, and includes clear documentation.


126-137: LGTM! Useful convenience helper.

InitializeCountersWithMetricsSyncDisabled appropriately encapsulates the pattern of disabling metrics synchronization for tests that require deterministic counter initialization from ToolchainStatus. The clear naming and documentation make the intent obvious.


139-147: LGTM! Appropriate explicit configuration.

Both InitializeCountersWithoutReset and InitializeCountersWith correctly maintain their previous behavior by explicitly setting ForceSynchronization(false). These functions are designed for specific test scenarios where counter initialization from ToolchainStatus without cluster resource synchronization is required. The inline comment at lines 155-158 provides helpful context for this behavior.

Also applies to: 169-173


106-112: Update: Verify that controllers/usersignup/approval_test.go tests don't depend on the changed default behavior.

The codebase shows a deliberate pattern: cache_test.go switched to InitializeCountersWithMetricsSyncDisabled, and space_completion_controller_test.go uses conditional logic to handle both cases. However, approval_test.go has 13 calls to InitializeCounters that remain unchanged.

InitializeCounters now uses the default ForceSynchronization=true (set in controllers/toolchainconfig/configuration.go:202), whereas InitializeCountersWithMetricsSyncDisabled explicitly disables it. The approval tests don't assert counter/metrics behavior directly, but the counter initialization could still affect test behavior. The inconsistency suggests these tests should be reviewed to ensure they handle the new default correctly.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
test/counter.go (2)

138-146: Consider documenting the implicit metrics synchronization behavior.

This function now creates a ToolchainConfig with ForceSynchronization(false), which is an implicit behavior not reflected in the function name or documentation. While the "WithoutReset" name accurately describes the counter reset behavior, tests using this function may not expect the metrics synchronization to be explicitly disabled.

Consider adding a documentation comment similar to:

// InitializeCountersWithoutReset initializes the counters without resetting the counter cache first.
// Metrics synchronization is disabled to preserve backward compatibility with existing tests.

148-172: Consider documenting the metrics synchronization behavior and exploring refactoring opportunities.

This function now creates a ToolchainConfig with ForceSynchronization(false), which represents a behavior change that isn't documented. Additionally, there's notable code duplication across the counter initialization functions (the pattern of setting WATCH_NAMESPACE, calling counter.Reset(), and registering cleanup repeats in multiple functions).

Based on learnings:

  • The past review comment at line 142 already identified potential for simplification
  • Consider extracting the common setup pattern into a private helper function
  • Consider adding a comment noting that metrics synchronization is explicitly disabled

Example documentation addition:

// InitializeCountersWith initializes the count cache from the counts parameter.
// Metrics synchronization is disabled to ensure initialization from ToolchainStatus counts.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4fe0c60 and 3599eea.

📒 Files selected for processing (1)
  • test/counter.go (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
test/counter.go (2)
controllers/toolchainconfig/configuration.go (1)
  • ToolchainConfig (33-36)
pkg/counter/cache.go (1)
  • Reset (53-57)
🔇 Additional comments (3)
test/counter.go (3)

14-14: LGTM! Necessary imports for the new configuration helpers.

The new imports support creating ToolchainConfig instances with specific metrics synchronization settings, which is essential for the new helper functions.

Also applies to: 16-16


113-123: LGTM! Well-structured helper for custom ToolchainConfig.

This function follows the established pattern and provides a clean way for tests to specify custom ToolchainConfig settings while maintaining proper cleanup semantics.


125-136: LGTM! Clear helper for backward-compatible test behavior.

This function provides an explicit way for tests to disable metrics synchronization, which is useful for maintaining backward compatibility with tests that were written when ForceSynchronization defaulted to false.

@rsoaresd
Copy link
Contributor Author

/retest

infra issue

Copy link
Contributor

@metlos metlos left a comment

Choose a reason for hiding this comment

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

Nice simplifications! The only comment I have is to reuse the logic as much as possible so that we don't forget to update multiple places in the future if we need to make changes in the parts of the logic that is common to all the Initialize* functions.

Copy link
Contributor

@mfrancisc mfrancisc left a comment

Choose a reason for hiding this comment

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

Looks good 👍

I have only few minor comments

space := spacetest.NewSpace(test.HostOperatorNs, "oddity",
spacetest.WithTierName(""))
r, req, cl := prepareReconcile(t, space, nil)
r, req, cl := prepareReconcile(t, space, nil, true)
Copy link
Contributor

Choose a reason for hiding this comment

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

just curious - why does it needs to synch the metrics here ? I'm not seeing anything different in this test but maybe I've missed it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just to prevent ToolchainConfig from being cached during counter initialization. With false, a ToolchainConfig is created and cached, so when Reconcile calls GetToolchainConfig it returns from cache and bypasses our mock. With true, no config is cached, so the mock actually gets called and returns the error we're testing for. I will add a comment

@rsoaresd rsoaresd requested review from metlos and mfrancisc October 31, 2025 12:28
Copy link
Contributor

@mfrancisc mfrancisc left a comment

Choose a reason for hiding this comment

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

Nice 👍

Thanks for addressing my comments.

@sonarqubecloud
Copy link

@openshift-ci
Copy link

openshift-ci bot commented Dec 23, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: alexeykazakov, MatousJobanek, metlos, mfrancisc, rajivnathan, rsoaresd

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

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [MatousJobanek,alexeykazakov,metlos,mfrancisc,rajivnathan,rsoaresd]

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

@rsoaresd rsoaresd merged commit 3de6efa into codeready-toolchain:master Jan 5, 2026
12 of 15 checks passed
@codecov
Copy link

codecov bot commented Jan 5, 2026

Codecov Report

❌ Patch coverage is 76.92308% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.21%. Comparing base (060beea) to head (996f339).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
test/counter.go 75.00% 3 Missing ⚠️

❌ Your changes status has failed because you have indirect coverage changes. Learn more about Unexpected Coverage Changes and reasons for indirect coverage changes.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1210      +/-   ##
==========================================
+ Coverage   84.08%   84.21%   +0.13%     
==========================================
  Files          84       84              
  Lines        6561     6571      +10     
==========================================
+ Hits         5517     5534      +17     
+ Misses        827      820       -7     
  Partials      217      217              
Files with missing lines Coverage Δ
controllers/toolchainconfig/configuration.go 91.62% <100.00%> (ø)
test/counter.go 85.36% <75.00%> (-0.75%) ⬇️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants