Skip to content

Comments

Rewrite test framework#11

Merged
cathay4t merged 1 commit intorust-netlink:mainfrom
cathay4t:main
Feb 20, 2026
Merged

Rewrite test framework#11
cathay4t merged 1 commit intorust-netlink:mainfrom
cathay4t:main

Conversation

@cathay4t
Copy link
Member

No description provided.

@gemini-code-assist
Copy link

Summary of Changes

Hello @cathay4t, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request primarily focuses on a significant rewrite of the project's test framework, aiming to enhance the robustness and isolation of integration tests for network interface commands. This refactoring ensures that each test runs in a clean, dedicated environment, preventing interference between tests. Additionally, it includes improvements to the ip link show command, specifically enhancing the display of detailed information for bridge interfaces by incorporating newly supported optional attributes and refining the interface filtering mechanism. A minor adjustment to color output detection is also included for better compatibility.

Highlights

  • Test Framework Refactoring: The testing infrastructure has been significantly rewritten to improve test isolation and reliability, moving from a single shared network namespace setup/teardown to per-test, isolated network interface creation and cleanup.
  • Enhanced Bridge Interface Information: The ip link show command now provides more comprehensive and accurate details for bridge interfaces by correctly parsing additional optional boolean flags from rtnetlink.
  • Improved ip link show Filtering: The filtering logic for ip link show <interface_name> has been updated to filter results after fetching all links, ensuring consistent behavior.
  • Color Output Adjustment: The CLI's color detection logic has been adjusted to assume a dark color scheme when the TERM environment variable is unknown, aligning with iproute2's behavior.
Changelog
  • .cargo/config.toml
    • Added a target-specific runner configuration to use sudo for tests.
  • Cargo.toml
    • Removed the ctor dependency from development dependencies.
  • Makefile
    • Simplified the cargo test command by removing specific test thread and target arguments.
  • src/color.rs
    • Modified color detection logic to assume a dark terminal for unknown TERM environments.
  • src/ip/link/ifaces/bridge.rs
    • Removed deprecated bridge constants.
    • Updated InfoBridge parsing to use BridgeBooleanOptionFlags.
    • Converted several bridge properties to Option<u8> for better optionality handling.
  • src/ip/link/show.rs
    • Changed the ip link show filtering mechanism to apply after fetching all links rather than during the initial query.
  • src/ip/link/tests/bridge.rs
    • Renamed src/ip/link/tests/link.rs to src/ip/link/tests/bridge.rs.
    • Refactored bridge-related tests to use a new with_bridge_iface helper for isolated setup and teardown.
  • src/ip/link/tests/color.rs
    • Updated color tests to use the new ip_rs_exec_cmd helper.
    • Modified color tests to target the loopback interface instead of showing all links.
  • src/ip/link/tests/loopback.rs
    • Added new tests specifically for the loopback interface's link show output, both standard and JSON.
  • src/ip/link/tests/mod.rs
    • Updated module declarations to reflect the new test file structure, including bridge, color, and loopback modules.
  • src/ip/tests/cmd.rs
    • Introduced a new ip_rs_exec_cmd helper function for executing the ip-rs binary within tests.
  • src/ip/tests/mod.rs
    • Updated module exports to include the new ip_rs_exec_cmd.
    • Removed the path module export.
  • src/ip/tests/path.rs
    • Removed the path module, as its functionality was integrated into cmd.rs.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request provides a significant and welcome rewrite of the test framework, moving from a global setup/teardown to a per-test setup using a helper function. This improves test isolation and allows for parallel execution. The changes also leverage updated features in the rtnetlink dependency, which cleans up the code for bridge interface handling. I've identified one critical build-breaking typo, a potential performance regression, and a couple of areas for further improvement in code structure and test robustness.

Comment on lines +149 to +151
if let Some(iface_name) = opts.first() {
ifaces.retain(|i| i.ifname.as_str() == *iface_name);
}

Choose a reason for hiding this comment

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

high

This change moves the interface filtering from the kernel-side (handle.link().get().match_name(...)) to be client-side after fetching all links. While this might offer more flexibility, it can be significantly less performant if there are many network interfaces on the system, as it now fetches all of them over the netlink socket before filtering. Was this change intentional to support a use case that match_name doesn't cover? If not, I'd recommend reverting to the more efficient kernel-side filtering.

Copy link
Member Author

Choose a reason for hiding this comment

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

Explained with comment.

Comment on lines +231 to 265
InfoBridge::MultiBoolOpt(opts) => {
if opts.mask.contains(BoolOptFlags::NoLinkLocalLearn) {
no_linklocal_learn = Some(
opts.value
.contains(BoolOptFlags::NoLinkLocalLearn)
.into(),
);
}
if opts.mask.contains(BoolOptFlags::VlanMulticastSnooping) {
mcast_vlan_snooping = Some(
opts.value
.contains(BoolOptFlags::VlanMulticastSnooping)
.into(),
);
}
if opts.mask.contains(BoolOptFlags::MstEnable) {
mst_enabled = Some(
opts.value.contains(BoolOptFlags::MstEnable).into(),
);
}
if opts.mask.contains(BoolOptFlags::MdbOffloadFailNotif) {
mdb_offload_fail_notification = Some(
opts.value
.contains(BoolOptFlags::MdbOffloadFailNotif)
.into(),
);
}
if opts.mask.contains(BoolOptFlags::FdbLocalVlan0) {
fdb_local_vlan_0 = Some(
opts.value
.contains(BoolOptFlags::FdbLocalVlan0)
.into(),
);
}
}

Choose a reason for hiding this comment

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

medium

The logic for handling MultiBoolOpt is repeated for each flag. This could be simplified by extracting it into a helper function to reduce code duplication and improve readability.

For example, you could introduce a helper function like this:

fn get_bool_opt(opts: &rtnetlink::packet_route::link::BridgeMultiBooleanOption, flag: BoolOptFlags) -> Option<u8> {
    if opts.mask.contains(flag) {
        Some(opts.value.contains(flag).into())
    } else {
        None
    }
}

And then use it like so:

no_linklocal_learn = get_bool_opt(opts, BoolOptFlags::NoLinkLocalLearn);
mcast_vlan_snooping = get_bool_opt(opts, BoolOptFlags::VlanMulticastSnooping);
// ... and so on


let expected_output = exec_in_netns(&["ip", "-d", "-j", "link", "show"]);
// Wait 1 second for bridge ID to be stable
std::thread::sleep(std::time::Duration::from_secs(1));

Choose a reason for hiding this comment

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

medium

Using a fixed thread::sleep can make tests flaky (if the operation takes longer than expected) or slow down the test suite. It would be more robust to poll for the desired state (e.g., the bridge ID becoming stable) with a reasonable timeout instead of a fixed sleep.

Signed-off-by: Gris Ge <fge@redhat.com>
@cathay4t cathay4t merged commit 34fa778 into rust-netlink:main Feb 20, 2026
3 checks passed
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.

1 participant