Skip to content

client: filter devices by type-specific capacity during auto-selection#3550

Merged
juan-malbeclabs merged 4 commits intomainfrom
jo/3549
Apr 20, 2026
Merged

client: filter devices by type-specific capacity during auto-selection#3550
juan-malbeclabs merged 4 commits intomainfrom
jo/3549

Conversation

@juan-malbeclabs
Copy link
Copy Markdown
Contributor

Resolves: #3549

Summary of Changes

  • When auto-selecting a device for 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 like Device X has reached its multicast publisher limit (48/48).
  • Fixed by extending the devices.retain() predicate in both the unicast path (find_or_create_user) and the multicast path (find_or_create_user_and_subscribe) to also call check_user_type_capacity, excluding devices that have no remaining capacity for the requested connection type before device selection occurs.

Diff Breakdown

Category Files Lines (+/-) Net
Core logic 1 +9 / -2 +7
Tests 1 +233 / -0 +233

Small targeted fix; the bulk of the diff is test coverage.

Key files (click to expand)
  • client/doublezero/src/command/connect.rs — two devices.retain() predicates extended to include check_user_type_capacity; 6 new unit tests covering unicast, multicast publisher, and multicast subscriber capacity filtering

Testing Verification

  • Added 6 unit tests covering all three capacity types (unicast, multicast publisher, multicast subscriber):
    • test_auto_select_skips_device_at_unicast_limit — verifies a device at its unicast limit is skipped in favor of a second device with capacity
    • test_auto_select_skips_device_at_multicast_publisher_limit — same for multicast publisher limit
    • test_auto_select_skips_device_at_multicast_subscriber_limit — same for multicast subscriber limit
    • test_auto_select_fails_when_all_devices_at_multicast_publisher_limit — verifies an error is returned when no device has multicast publisher capacity
    • test_auto_select_fails_when_all_devices_at_multicast_subscriber_limit — same for multicast subscriber
    • test_auto_select_fails_when_all_devices_at_unicast_limit — same for unicast
  • Confirmed tests fail without the fix and pass with it
  • Full cargo test -p doublezero suite passes (94 tests)

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.
@juan-malbeclabs juan-malbeclabs merged commit 9a77270 into main Apr 20, 2026
36 checks passed
@juan-malbeclabs juan-malbeclabs deleted the jo/3549 branch April 20, 2026 18:37
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validate user limits when selecting device for connection (unicast vs multicast)

2 participants