client: filter devices by type-specific capacity during auto-selection#3550
Merged
juan-malbeclabs merged 4 commits intomainfrom Apr 20, 2026
Merged
client: filter devices by type-specific capacity during auto-selection#3550juan-malbeclabs merged 4 commits intomainfrom
juan-malbeclabs merged 4 commits intomainfrom
Conversation
When auto-selecting a device, exclude devices that have reached their per-type limit (unicast users, multicast publishers, multicast subscribers) so provisioning does not fail after device selection.
Test that auto-selection skips devices at their unicast, multicast publisher, and multicast subscriber limits, and fails when no devices have capacity for the requested connection type.
snormore
approved these changes
Apr 20, 2026
packethog
added a commit
that referenced
this pull request
Apr 21, 2026
## Summary - QA tests that pin to an explicit device (e.g. `TestQA_AllDevices_UnicastConnectivity`) were failing on devices that had free aggregate slots but zero free slots in a per-type bucket (e.g. `max_unicast_users=29 / unicast_users_count=29` while `max_users=128 / users_count=61`). - `qa.Test.ValidDevices` only consulted the aggregate `MaxUsers`/`UsersCount` counters, so these devices passed the capacity check and failed later at connect time with an onchain cap error. - Extends `qa.Device` with the three per-type counters already exposed by the serviceability SDK (unicast, multicast publisher, multicast subscriber), adds a `DeviceUserType` enum, and makes `ValidDevices` take the user type so it enforces both the type-specific and aggregate buckets. Related: builds on the auto-select fix from #3550, which solved the same class of problem for callers that don't specify a device code. ## Testing Verification - `go build -tags=qa ./e2e/...` clean - `go vet -tags=qa ./e2e/...` clean - Ran through the failure scenario from [infra run 24744593257](https://github.com/malbeclabs/infra/actions/runs/24744593257): with the fix, `ValidDevices(DeviceUserTypeUnicast, 2, false)` filters out the saturated `nyc001-dz002` entry that previously leaked through.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves: #3549
Summary of Changes
doublezero connect, the selection filter only checked general eligibility (is_device_eligible_for_provisioning) but not per-type limits. This allowed a device that had reached its multicast publisher, multicast subscriber, or unicast user limit to be selected, causing provisioning to fail after selection with an error likeDevice X has reached its multicast publisher limit (48/48).devices.retain()predicate in both the unicast path (find_or_create_user) and the multicast path (find_or_create_user_and_subscribe) to also callcheck_user_type_capacity, excluding devices that have no remaining capacity for the requested connection type before device selection occurs.Diff Breakdown
Small targeted fix; the bulk of the diff is test coverage.
Key files (click to expand)
client/doublezero/src/command/connect.rs— twodevices.retain()predicates extended to includecheck_user_type_capacity; 6 new unit tests covering unicast, multicast publisher, and multicast subscriber capacity filteringTesting Verification
test_auto_select_skips_device_at_unicast_limit— verifies a device at its unicast limit is skipped in favor of a second device with capacitytest_auto_select_skips_device_at_multicast_publisher_limit— same for multicast publisher limittest_auto_select_skips_device_at_multicast_subscriber_limit— same for multicast subscriber limittest_auto_select_fails_when_all_devices_at_multicast_publisher_limit— verifies an error is returned when no device has multicast publisher capacitytest_auto_select_fails_when_all_devices_at_multicast_subscriber_limit— same for multicast subscribertest_auto_select_fails_when_all_devices_at_unicast_limit— same for unicastcargo test -p doublezerosuite passes (94 tests)