Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions nmrs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ All notable changes to the `nmrs` crate will be documented in this file.
`NetworkManager::set_device_autoconnect()` / `set_device_managed()` provide
high-level control of both writable properties. ([#541](https://github.com/freedesktop-rs/nmrs/issues/541))

### Fixed

- `wired_connection_lifecycle` restored device autoconnect immediately after
remanaging the veth, which let NetworkManager reactivate the saved profile and
race the disconnect assertions that follow. Autoconnect is now restored once
the profile is deleted, and the test waits for the remanaged device to settle.
([#547](https://github.com/freedesktop-rs/nmrs/pull/547))

## [3.5.2] - 2026-09-05
### Fixed
- `#[deprecated(since = ...)]` on `connect_vpn_by_uuid()` and `disconnect_vpn_by_uuid()` said `3.6.0`; corrected to `3.5.1`, the release that actually deprecated them.([#544](https://github.com/freedesktop-rs/nmrs/pull/544))
Expand Down
47 changes: 41 additions & 6 deletions nmrs/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1136,13 +1136,28 @@ async fn wired_connection_lifecycle() {
)
.await
.expect("failed to restore managed state");
bounded(
"restore autoconnect on the managed veth client",
DBUS_TIMEOUT,
nm.set_device_autoconnect(&interface, true),
)
// Remanaging clears the autoconnect block that an explicit disconnect
// leaves behind, so NetworkManager reactivates the saved profile as soon
// as the device is ready. Keep device autoconnect off until the profile
// is deleted and wait for the device to settle; otherwise that
// reactivation races the disconnect assertions below.
timeout(EVENT_TIMEOUT, async {
loop {
let devices = bounded("refresh remanaged device", DBUS_TIMEOUT, nm.list_devices())
.await
.expect("failed to refresh devices after restoring managed state");
let device = devices
.iter()
.find(|device| device.interface == interface)
.expect("veth disappeared after restoring managed state");
if device.managed == Some(true) && device.state == DeviceState::Disconnected {
break;
}
sleep(Duration::from_millis(25)).await;
}
})
.await
.expect("failed to restore device autoconnect");
.expect("the remanaged veth never settled to Disconnected");

bounded(
"disconnect the managed veth client",
Expand Down Expand Up @@ -1236,6 +1251,26 @@ async fn wired_connection_lifecycle() {
.expect("failed to resolve wired profile after deletion")
.is_none()
);

bounded(
"restore autoconnect on the managed veth client",
DBUS_TIMEOUT,
nm.set_device_autoconnect(&interface, true),
)
.await
.expect("failed to restore device autoconnect");
let devices = bounded(
"read restored autoconnect",
DBUS_TIMEOUT,
nm.list_wired_devices(),
)
.await
.expect("failed to refresh wired devices");
let device = devices
.iter()
.find(|device| device.interface == interface)
.expect("veth disappeared after restoring autoconnect");
assert_eq!(device.autoconnect, Some(true));
})
.catch_unwind()
.await;
Expand Down