Skip to content

balancer/randomsubsetting: Extend the unit tests in the randomsubsetting package#9059

Open
marek-szews wants to merge 7 commits intogrpc:masterfrom
marek-szews:randomsubsetting-lb-unit-test-extention
Open

balancer/randomsubsetting: Extend the unit tests in the randomsubsetting package#9059
marek-szews wants to merge 7 commits intogrpc:masterfrom
marek-szews:randomsubsetting-lb-unit-test-extention

Conversation

@marek-szews
Copy link
Copy Markdown
Contributor

@marek-szews marek-szews commented Apr 13, 2026

Add more unit tests to increase test coverage of 'randomsubsetting' package.

RELEASE NOTES: none

…ackage.

RELEASE NOTES:

balancer/randomsubsetting: Implementation of additional UT.
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.13%. Comparing base (d574bad) to head (a2d4f2b).
⚠️ Report is 27 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9059      +/-   ##
==========================================
+ Coverage   83.08%   83.13%   +0.05%     
==========================================
  Files         413      413              
  Lines       33269    33476     +207     
==========================================
+ Hits        27642    27831     +189     
- Misses       4215     4226      +11     
- Partials     1412     1419       +7     
Files with missing lines Coverage Δ
internal/testutils/roundrobin/roundrobin.go 78.72% <100.00%> (+0.82%) ⬆️

... and 42 files with indirect coverage changes

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

@marek-szews
Copy link
Copy Markdown
Contributor Author

This pull request is a continuation of the work started in PR#8781. Due to a high volume of merge conflicts that made the previous PR impossible to merge cleanly, I have decided to close the old one and start fresh here with the latest changes.

@Pranjali-2501 Pranjali-2501 self-assigned this Apr 14, 2026
@Pranjali-2501 Pranjali-2501 self-requested a review April 14, 2026 03:40
Copy link
Copy Markdown
Contributor

@Pranjali-2501 Pranjali-2501 left a comment

Choose a reason for hiding this comment

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

@marek-szews, PTAL at the comments.

Comment thread balancer/randomsubsetting/randomsubsetting_test.go Outdated
Comment thread balancer/randomsubsetting/randomsubsetting_test.go Outdated
Copy link
Copy Markdown
Contributor Author

@marek-szews marek-szews left a comment

Choose a reason for hiding this comment

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

Would you refer to my answers to the asked questions ?

Comment thread balancer/randomsubsetting/randomsubsetting_test.go
{
eps: 16,
subsetSize: 4,
iteration: 10,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are we using such a small value for iterations here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That explains the situation perfectly! Using a hardcoded seed in your tests creates a deterministic environment where the algorithm's choices are fixed for every run.
While this is excellent for reproducibility, it can create a "false sense of randomness" if the specific seed happens to generate a sequence that fits your distribution criteria perfectly, even with low iterations.

positive: true,
},
{
eps: 4,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

When the subset size equals the total number of endpoints (eps == subsetSize), the algorithm returns all endpoints every time.

We can remove this testcase.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I agree with your point regarding the first part of the statement; however, the successful outcome of the verification process is not entirely definitive. It primarily depends on the number of repetitions to ensure the sample is statistically representative.
The distribution will only begin to align once this specific threshold is exceeded. If we wish to examine the Load Balancer algorithm's actual output, a relevant test can be found in the TestCalculateSubset_Simple() function, specifically under the test name SubsetSizeEqualToNumberOfEndpoints.

It was my underlying objective to demonstrate the correlation between EPs, subsetSize, and the total iteration count. As subsetSize converges with EPs, the number of iterations required for successful verification increases significantly.

EndPoints |16 | 8 | 4 |
subsetSize | 4 | 4 | 4 |
repetition 1600 -> 3200 -> 6400

iteration: 6400,
positive: true,
},
{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we don't need the false assertion here. IMO, just having testcases that are expected to pass is sufficient.

Copy link
Copy Markdown
Contributor Author

@marek-szews marek-szews Apr 24, 2026

Choose a reason for hiding this comment

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

The fact that your tests do not fail is actually the point—it confirms that the algorithm is operationally sound. However, checking for a uniform distribution serves a different purpose than simply checking for a "pass/fail" result.

Comment thread balancer/randomsubsetting/randomsubsetting_test.go
@Pranjali-2501
Copy link
Copy Markdown
Contributor

Copy link
Copy Markdown
Contributor Author

@marek-szews marek-szews left a comment

Choose a reason for hiding this comment

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

All of your comments have been reviewed and addressed. Please find my response below.

@Pranjali-2501 Pranjali-2501 assigned easwars and unassigned marek-szews May 5, 2026
@Pranjali-2501 Pranjali-2501 requested a review from easwars May 5, 2026 03:42
for i := 0; i < K; i++ {
lb := &subsettingBalancer{
cfg: &lbConfig{SubsetSize: uint32(L)},
hashSeed: uint64(i ^ 3 + K*i + L),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What is the significance of the way this seed value is computed? Why can't it just be i?

Comment on lines +367 to +371
N := len(endpoints)
L := int(tc.subsetSize)
K := int(tc.iteration)
p := float64(L) / float64(N) // Probability of x ∈ N being drawn p(x) = L / N
E := float64(K) * p // Expected Value (Mean) E(N) = K * p
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Having single letter variable names that are spread through the function does not help with readability at all. Please get rid of these variables and instead use the RHS of these variables directly in the code.

p := float64(L) / float64(N) // Probability of x ∈ N being drawn p(x) = L / N
E := float64(K) * p // Expected Value (Mean) E(N) = K * p

EndpointCount := make(map[string]int, N)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

s/EndpointCount/endpointCount

expectedCounts[k] = E
}

err := roundrobin.PearsonsChiSquareTest(t, observedCounts, expectedCounts, 0.05)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How was the value of 0.05 arrived at?

Comment on lines +288 to +293
// TestUniformDistributionOfEndpoints verifies that the random subsetting
// policy achieves a uniform distribution across backends. From a set of N
// numbers, it randomly selects K-times a subset of L numbers, where L < N.
// Then it calculates how many times each number belonging to set N appears,
// compute the variance and standard deviation, and use a Chi-Square test to
// check whether the distribution is uniform.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

From what I can see, this test is actually testing the hashing function. If we really want to test the functionality in the policy, we should be overriding the hashing function in some deterministic fashion, so that we can verify the algorithm in the policy.

I'm concerned about a bunch of things in this test, but most importantly, if this test fails, how would one go about debugging? What do the scenarios in the different table entries correspond to, how were they arrived at?

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.

3 participants