[tests/mock_tests]: Migrate test_vnet VS tests to C++ mock tests - #4815
Open
theasianpianist wants to merge 31 commits into
Open
[tests/mock_tests]: Migrate test_vnet VS tests to C++ mock tests#4815theasianpianist wants to merge 31 commits into
theasianpianist wants to merge 31 commits into
Conversation
Collaborator
|
/azp run |
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request migrates the VNET virtual-switch integration test suite to fast in-process C++/gtest mock tests, reducing CI time and flakiness while preserving coverage by asserting the SAI programming via the mock SAI harness.
Changes:
- Removed the legacy VNET VS test suite (
tests/test_vnet.py) as part of the coverage swap. - Added a comprehensive C++ mock-test suite for VNET (
tests/mock_tests/vnetorch_ut.cpp) and integrated it into the mock test build. - Extended the mock-test SAI harness to support BFD API usage and introduced a shared SAI-attribute assertion helper (
mock_test_helpers::findAttr), refactoring existing tests to use it.
Reviewed changes
Copilot reviewed 6 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/test_vnet.py | Removed VNET VS integration tests as coverage is migrated to mock tests. |
| tests/mock_tests/vnetorch_ut.cpp | New C++/gtest mock-test suite covering VNET/VXLAN/BFD behaviors previously tested in VS. |
| tests/mock_tests/ut_saihelper.cpp | Wires up SAI BFD API in the mock-test SAI initialization/teardown. |
| tests/mock_tests/mock_orchagent_main.h | Exposes sai_bfd_api for mock-test compilation and linking. |
| tests/mock_tests/common/mock_test_helpers.h | Adds shared helper declarations for asserting captured SAI attribute lists. |
| tests/mock_tests/common/mock_test_helpers.cpp | Implements mock_test_helpers::findAttr for captured attribute-list inspection. |
| tests/mock_tests/policerorch_ut.cpp | Refactors attribute lookup to use the shared findAttr helper. |
| tests/mock_tests/Makefile.am | Adds the new VNET unit test and shared helper source to the mock test build. |
theasianpianist
force-pushed
the
migrate-test-vnet-to-mock
branch
from
August 4, 2026 20:22
f146d30 to
4cf4eae
Compare
Collaborator
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
theasianpianist
force-pushed
the
migrate-test-vnet-to-mock
branch
from
August 4, 2026 21:27
4cf4eae to
e4ac62f
Compare
Collaborator
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Collaborator
|
/azp run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
…sertions
Introduce tests/mock_tests/common/mock_test_helpers.{h,cpp} as the shared
home for helpers that verify what an orch programs by inspecting the
sai_attribute_t list captured from a mocked SAI call (the mock-test
equivalent of reading an attribute back from ASIC_DB, which the in-process
harness has no populated ASIC_DB for).
The first helper is findAttr(), extracted from the inline lookup in
policerorch_ut.cpp per the on-second-use rule: policerorch_ut.cpp now calls
mock_test_helpers::findAttr() instead of its own copy. Subsequent mock-test
ports (starting with the VNet orch tests) reuse this module rather than
re-deriving attribute-list inspection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510
Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
… check Introduce tests/mock_tests/vnetorch_ut.cpp, the fixture for migrating tests/test_vnet.py to C++ mock tests. It subclasses MockOrchTest (which already builds VNetOrch + VxlanTunnelOrch), brings the default ports up so those orchs run, and mocks the SAI virtual-router API via the shared mock_sai_api.h framework using the DEFINE_SAI_GENERIC_API_MOCK_WITH_SET variant (virtual_router is create/set/remove with no bulk ops). Because the mock harness has no cfgmgr daemons, the fixture writes the APP_DB entries vxlanmgr/vrfmgr would have produced (vrfmgr passes VNET fields through unchanged) instead of the CONFIG_DB entries the VS test writes. The first case, VnetCreateProgramsVirtualRouter, drives a VXLAN tunnel + VNET and asserts VNetOrch programs a SAI virtual router for the VNET -- the mock-test equivalent of the VS check_vnet_entry() ASIC_DB assertion. Further cluster-A cases (tunnel maps, tunnel, term entry, tunnel map entries) build on this fixture. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Bind a VNET to a VXLAN tunnel and verify -- by capturing the attributes VNetOrch/VxlanTunnelOrch pass to the mocked sai_tunnel_api (the harness has no populated ASIC_DB) -- the same SAI programming the VS test checks: - 4 tunnel maps, in creation order VNI->VLAN, VLAN->VNI, VNI->VR, VR->VNI (vnet_lib.check_vxlan_tunnel) - the tunnel (VXLAN, encap src IP, and decap/encap mapper wiring) - the P2MP tunnel-term entry (default VR, dst IP, action tunnel) - the two VR<->VNI tunnel-map entries carrying the VNET's VNI, keyed/ valued by the VNET virtual router (vnet_lib.check_vxlan_tunnel_entry) Also cover teardown: deleting the VNET (via a DEL_COMMAND pushed through the consumer, so the delete handler actually runs) removes the two map entries and the VNET virtual router, and deleting the VXLAN tunnel then removes the shared tunnel, four maps, and term entry (vnet_lib.check_del_vxlan_tunnel). The virtual_router create/remove handlers call through to real libsaivs so the VR gets a valid OID -- a fabricated OID makes the downstream real create_route_entry (RouteOrch::addLinkLocalRouteToMe) throw and abort the bind before any tunnel objects are programmed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Add mock-test coverage for VNET tunnel route programming -- the C++ equivalent of vnet_lib.check_vnet_routes / check_vnet_ecmp_routes / check_next_hop_group_member / check_del_vnet_routes: - single-endpoint route -> one TUNNEL_ENCAP next hop + route entry in the VNET's virtual router - endpoint carrying an inner MAC -> SAI_NEXT_HOP_ATTR_TUNNEL_MAC - multi-endpoint route -> one next hop per endpoint + an ECMP next hop group + one member per endpoint, route pointing at the group - route delete via DEL_COMMAND -> route entry and tunnel next hop removed Build VNetRouteOrch (plus its gBfdOrch and gTunneldecapOrch dependencies, which it dereferences without null-guards) into the fixture, mock the next_hop, next_hop_group and route SAI APIs, and assert on the sai_attribute_t lists orchagent programs. Reset the process-global mock DB (testing_db::reset()) at the start of each test: MockOrchTest::TearDown() does not flush gDB, so rows written by one test would otherwise be re-consumed by the next test's addExistingData()+doTask() and inflate the captured object counts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Add mock-test equivalents of test_vnet.py's route idempotency tests (test_vnet_orch_13/14/15, the non-BFD idempotency cases): - VnetEcmpRouteReaddIsIdempotent: re-applying an identical IPv6 ECMP route reuses the existing next hop group (no new group/members, same OID, nothing removed), then delete tears it down. - VnetEcmpRouteEndpointUpdateReplacesGroup: changing the endpoint set creates a new group, removes the old, and repoints the route; deleting twice is idempotent. - VnetSingleRouteReaddIsIdempotent: re-applying an identical single-endpoint route reuses the tunnel next hop and creates no group. Supporting infrastructure: - Extend ipAddrEquals/prefixAddrEquals to IPv6 so the helpers and findRoute() handle the fd:8:10::32/128 -> fd:8:1::N routes these tests use. - Add STATE_DB assertions (checkStateDbRoute/checkStateDbRouteRemoved/ checkRouteNotAdvertised), the mock equivalent of vnet_lib.check_state_db_routes / check_remove_routes_advertisement. VNetRouteOrch writes VNET_ROUTE_TUNNEL_TABLE via a plain Table on STATE_DB, which is directly readable here (unlike ASIC_DB). - Capture in-place route repoints: set_route_entry_attribute is not routed through the mock_sai_api framework (its macro only mocks create/remove), yet VNetRouteOrch::update_route repoints an ECMP route in place on an endpoint change. Swap that single function pointer to a trampoline that records the new NEXT_HOP_ID onto the matching captured route, so a captured route's next_hop_id reflects its current value (mirroring the ASIC_DB read in check_vnet_ecmp_routes). All 11 VNetOrchTest tests pass; full mock suite 923/923. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Query SAI_API_BFD during the mock SAI init so the global sai_bfd_api pointer is populated, and declare its extern in mock_orchagent_main.h alongside the other SAI api-pointer externs. Reset it to nullptr in uninitSaiApi(). This lets mock tests mock the BFD session API (via DEFINE_SAI_GENERIC_API_MOCK(bfd, bfd_session)); without the query the apply-mock helper dereferences a null sai_bfd_api and segfaults. Needed by the VNET BFD-monitored ECMP route tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Add the BFD counterparts of the non-BFD idempotency tests, the equivalent of test_vnet_orch_16 and test_vnet_orch_17. - VnetMonitoredSingleRouteReaddIsIdempotent (test_vnet_orch_16): a monitored single-endpoint route programs one tunnel next hop while its BFD session is up; re-applying it (while up, and while down then back up) neither leaks nor duplicates the next hop; deleting removes it. - VnetMonitoredEcmpRouteReaddIsIdempotent (test_vnet_orch_17): re-applying a monitored ECMP route while all monitors are down keeps it unprogrammed; re-applying while up reuses the same next hop group (no new group, none removed); deleting removes the group and all its BFD sessions. Full mock suite: 927/927. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Add the mock equivalent of test_vnet_orch_12: BFD health-monitored ECMP routes on a VNET created with advertise_prefix=true. Verifies that an active monitored route is published to STATE_DB ADVERTISE_NETWORK_TABLE carrying its route profile, that the advertisement follows the route's active/inactive state, and that its profile follows a make-before-break endpoint/profile change (test_profile -> test_profile2). Extend setVnet with an advertise_prefix flag and setVnetRouteMonitored with a profile field, and add a checkRouteAdvertised helper (the mock equivalent of vnet_lib.check_routes_advertisement). Both helper signature changes are backward-compatible optional parameters. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Add the mock equivalent of test_vnet_orch_11: mixed single-endpoint and ECMP BFD-monitored routes that share BFD sessions. A single-endpoint monitored route programs one tunnel next hop (no group); an overlapping ECMP monitored route programs a group whose members follow BFD state; a monitor shared between routes is a single ref-counted BFD session removed only when its last referencing route is deleted. Run the scenario for both unordered and ordered ECMP, mirroring the VS test's ordered_ecmp parametrization: enableOrderedEcmp() writes SWITCH_TABLE:switch ordered_ecmp=true so VNET ECMP groups are programmed as SAI_NEXT_HOP_GROUP_TYPE_DYNAMIC_ORDERED_ECMP with per-member SAI_NEXT_HOP_GROUP_MEMBER_ATTR_SEQUENCE_ID, and checkGroupMember asserts the sequence ids (mock equivalent of vnet_lib.check_next_hop_group_member). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Add the mock equivalent of test_vnet_orch_18: a priority (primary/secondary) VNET tunnel route whose endpoints are health-checked by custom monitors driven through STATE_DB VNET_MONITOR_TABLE, with no SAI BFD sessions. Fixture/infra changes reused by the rest of the custom-monitoring cluster (tests 19-23, 25-27): - Wire a MonitorOrch into the fixture (registered in gDirectory the way orchdaemon does) so STATE_DB VNET_MONITOR_TABLE writes are forwarded to VNetRouteOrch, exactly as gMonitorOrch does in production. - setVnetRoutePriority(): write a VNET_ROUTE_TUNNEL row with primary / monitoring / adv_prefix; updateMonitorSessionState(): drive a single monitor up/down via a Consumer SET (mock update_monitor_session_state). - checkPriorityRoute(): assert the SAI programming for the active endpoint subset -- a single active endpoint points at that endpoint's tunnel next hop, several at an unordered-ECMP group whose members are exactly the active endpoints (mock check_priority_vnet_ecmp_routes). - checkCustomMonitorAppDb()/checkCustomMonitorDeleted(): assert the APP_DB VNET_MONITOR_TABLE monitor-session rows. - setVnet(): optional overlay_dmac field. - Make findRoute() active-aware (last created net of removals) so a route removed and re-added within one test resolves to the current entry. The test walks the full failover ladder: all monitors down (route not programmed / adv_prefix not advertised), all up (primary subset only), primaries dropping one at a time down to secondary fallback, full withdrawal when every endpoint is down, re-add on secondary, switch back to primary, and secondary churn not disturbing a primary-active route; then deletes the route and confirms every monitor session is removed. STATE_DB active_endpoints remain the authoritative active-set check. Full mock suite 931/931. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Port test_vnet_orch_19-22 (priority/adv_prefix custom-monitored routes) to VNetOrchTest: - VnetTwoPriorityRoutesOverlappingGroups (test 19): two routes over the same four endpoints with different primary subsets and separate adv_prefixes; per-route independent monitors, primary preference, secondary fallback and per-route advertisement (with/without profile) as endpoints flap. - VnetSingleEndpointPriorityRouteSwitchover (test 20): single-endpoint primary/secondary switchover -- the route points directly at one endpoint's tunnel next hop (never a group) and prefers the primary while it is up. - VnetPriorityRoutesSharedAdvPrefixRefcount (test 21): three IPv6 routes sharing one adv_prefix; the advertisement is reference-counted and withdrawn only when the last contributor is deleted; includes add-after-advertise. - VnetPriorityRouteReaddAndPrimarySwap (test 22): identical re-add is a no-op; swapping the primary to currently-down endpoints keeps the route on its active set; a full endpoint-set change moves it; and a no-secondary route is custom-monitored without any SAI BFD session. Also fix delVnetRoute() to remove the deleted row from the backing mock DB in addition to the Consumer DEL push: setVnetRoute*() uses addExistingData(), which re-enqueues every current row as a SET, so a row left behind after delete would resurrect the route. These are the first tests to delete a route and then add another within one test, which is what exposes it. Full mock suite 935/935. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Add VnetCustomMonitorOverlayDmacUpdate, the mock equivalent of test_vnet_orch_23: a VNET can be created, deleted and re-created repeatedly with its overlay_dmac updated; each custom-monitor APP_DB row a route creates carries the VNET's current overlay_dmac, and updating the dmac while routes exist rewrites every monitor row via updateAllMonitoringSession. An empty-dmac update is a no-op. Also exercises route re-add + advertisement after a dmac change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Add VnetTunnelRouteMetricValues, the mock equivalent of test_vnet_orch_33. metric is a passthrough field: VNetCfgRouteOrch mirrors it verbatim into APP_DB VNET_ROUTE_TUNNEL_TABLE and VNetRouteOrch does not act on it. The test asserts that a full range of metric values (0..20) does not disturb route programming -- each single-endpoint route still programs a tunnel encap next hop and an active STATE_DB entry -- and that the metric round-trips into APP_DB. Extends setVnetRoute with an optional metric field. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
…over (29)
Port test_vnet_orch_29: a custom-monitored priority route whose secondary
endpoints are directly-connected/local. Adds the local-endpoint fixture
infrastructure reused by the remaining local tests:
- createL3Interface(port, ipPrefix): write APP_INTF_TABLE rows + drive
gIntfsOrch (mock of create_l3_intf + add_ip_address).
- addNeighbor(port, ip, mac): write APP_NEIGH_TABLE + drive gNeighOrch so
isLocalEndpoint() resolves the neighbor and the route reuses the IP next
hop gNeighOrch creates (mock of add_neighbor / neighsyncd).
- setVnetRoutePriority gains a check_directly_connected flag.
- checkEndpointIsLocal/Remote assert an active endpoint's next hop type
(SAI_NEXT_HOP_TYPE_IP vs TUNNEL_ENCAP) -- the directly-connected
distinction STATE_DB active_endpoints alone cannot show.
The failover ladder mirrors test 18, but the secondary subset {9.1.0.3,
9.1.0.4} is local (IP next hops) while the primary {9.1.0.1,9.1.0.2} is
remote (tunnel-encap). Primary-active states use the full priority-route
group check; local secondary states are backbone-checked via STATE_DB plus
per-endpoint locality assertions (as the VS test does).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510
Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
…route (28) Mock equivalent of test_vnet_orch_28: a custom-monitored priority route whose primary endpoint is directly-connected/local, exercising the tunnel-termination ACL VNetRouteOrch programs for local endpoints. Unique coverage vs the other priority tests: no tunnel-term ACL rule exists before the route; creating the route programs a redirect ACL rule (DST_IP=vip, TUNNEL_TERM, redirect to the local endpoint IP, priority 9998) whose table type carries the REDIRECT + COUNTER actions -- even before any monitor is up, since the ACL follows the local endpoint, not route health; and the local endpoint's next hop persists across a primary->secondary->primary flap while the remote endpoint's tunnel next hop is created/removed on demand (active next-hop set 1->2->1). The ACL rule's APP_DB->SAI translation is covered by aclorch_ut, so the new checkTunnelTermAclRule/checkNoTunnelTermAclRules helpers assert at the VNet->ACL (APP_DB) boundary; the VS test asserts the resulting SAI ACL entry in ASIC_DB. Adds an activeEndpointNexthops helper (the mock view of the ASIC_DB next hops the VS test counts). Full mock suite 939/939; VNET suite 27/27. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Port test_vnet_local_route_single (30) and test_vnet_local_route_ecmp (31) to the vnetorch mock suite. VNET *local* routes (non-empty nexthop list) are delegated by VNetRouteOrch to gRouteOrch, which programs them through its route and next-hop-group-member bulkers. Those bulkers copy the SAI create/remove/set_*_route_entries and create/remove_next_hop_group_members function pointers at construction time -- before PostSetUp() applies the gmock SAI mock -- so the bulk calls bypass the gmock global and were invisible to the existing captures. Install plain function-pointer trampolines for the bulk route-entry, bulk route-entry-attribute-set, and bulk NHG-member APIs in a new ApplySaiMock() override, which PrepareSai() runs before any Orch is constructed, and restore them in PreTearDown() after RestoreSaiApis(). The bulk set_route_entries_attribute trampoline is required to observe the in-place NEXT_HOP_ID repoint an ECMP endpoint-set change performs. Add local-route helpers: setPortOperStatus() brings a fixture port oper-up (via a port_state_change notification) so neighbors learned on it yield programmable, non-IFDOWN next hops; createVnetL3Interface() binds a VNET RIF; setVnetLocalRoute()/delVnetLocalRoute() drive the APP_DB VNET_ROUTE_TABLE; checkVnetLocalRoute()/checkVnetLocalRouteRemoved() assert the SAI programming (direct IP next hop for a single nexthop, unordered ECMP group + members for multiple), the mock equivalent of vnet_lib.check_vnet_local_routes / check_vnet_local_route_nexthops / check_del_vnet_local_routes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Add VnetMonitoredEcmpRouteTsaWithdrawsAndRestores, the mock equivalent of test_vnet_orch_25. Drives a BFD-monitored ECMP VNET route through a Traffic-Shift-Away cycle: with all monitors up the route is programmed over the ECMP group; enabling TSA (BGP_DEVICE_GLOBAL|STATE tsa_enabled) tears down every BFD session and withdraws the route (STATE_DB inactive) while the group persists; clearing TSA recreates the sessions (initially down) so the route stays withdrawn until the monitors report up again, at which point it is restored over the same group; deleting the route removes the group and its sessions. Adds a setTsa(bool) helper that drives BgpGlobalStateOrch::doTask -> BfdOrch::handleTsaStateChange, and registers gBfdOrch in gDirectory in PostSetUp so BgpGlobalStateOrch can resolve BfdOrch for TSA (mirrors orchdaemon.cpp). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Add VnetDefaultScopeReusesDefaultVirtualRouter, the mock equivalent of test_vnet_orch_5 / vnet_lib.check_default_vnet_entry. A VNET with scope=default reuses the global default virtual router (gVirtualRouterId) instead of creating a per-VNET one, so binding it must not call create_virtual_router (asserted Times(0)); the VXLAN tunnel is still fully programmed and its VR<->VNI tunnel-map entries are keyed by the default VR carrying the VNI. Deleting the VNET removes its map entries without removing the default VR, and deleting the tunnel tears down the shared tunnel/maps/term. Extends setVnet() with an optional scope field. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Port test_vnet_ip2me_link_local to the vnetorch mock suite. A non-default scope VNET VR gets an fe80::/10 link-local trap route installed at VR creation (VNetVrfObject::createObj -> RouteOrch::addLinkLocalRouteToMe) that forwards matched control packets to the CPU, and the route is torn down when the VNET is deleted (~VNetVrfObject -> delLinkLocalRouteToMe). VnetInstallsIpv6LinkLocalTrapRoute asserts exactly one fe80::/10 route is programmed in the VNET's own VR (not the default VR), with packet action FORWARD and a next hop set to the CPU port, and that deleting the VNET removes it. The link-local route flows through the single create_route_entry (captured in m_rt.routes), unlike VNET tunnel routes, so its vr / action / next-hop are directly assertable. Adds a packet_action field to the route capture struct. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Port test_vnet_orch_local_endpoint_alias_resolution to the vnetorch mock suite. A custom-monitored, check_directly_connected route whose endpoints resolve to directly-connected local endpoints: the routes are added before the neighbors exist (so the endpoint NextHopKey is cached unresolved), then the neighbors are added and the monitors brought up. The single-endpoint route resolves to point directly at the local endpoint's SAI_NEXT_HOP_TYPE_IP next hop (not a tunnel-encap next hop), and the two-primary route forms an unordered ECMP group of both local IP next hops. Uses the existing createL3Interface / addNeighbor / setVnetRoutePriority / updateMonitorSessionState / checkVnetLocalRoute / checkEndpointIsLocal helpers; no new fixture infrastructure. Full VNetOrchTest 33/33, full mock suite 945/945. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
…te (34,35,36)
Add mock equivalents of test_vnet_orch_34/35/36, the custom_bfd priority
route scenarios:
* VnetCustomBfdPriorityRouteRepairing (34): primary/secondary re-pair
that swaps the remote secondary and promotes a new primary.
* VnetCustomBfdMonitorRepairSameNpu (35): the monitor IP paired with a
remote endpoint is re-pointed several times while the endpoint set is
unchanged; each re-pair tears down the old BFD session and creates one
for the new monitor.
* VnetCustomBfdPinnedMonitorState (36): a monitor's pinned_state
overrides its live BFD state (pin-down forces failover to the backup
while BFD is up; pin-up keeps the route on the primary while BFD is
down).
custom_bfd routes react to BFD state ONLY through STATE_DB
BFD_SESSION_TABLE: VNetRouteOrch::updateVnetTunnel (the SAI-notification
observer) explicitly skips custom_bfd sessions, and BfdMonitorOrch instead
consumes the STATE_DB row gBfdOrch writes and drives updateCustomBfdState.
The fixture had no BfdMonitorOrch, so a bfd_session_state_change alone
never activated these routes. Wire a BfdMonitorOrch (STATE_DB
BFD_SESSION_TABLE) into the fixture and drive it after every BFD
notification; for plain-BFD routes it has no monitor_info_ entry and is a
harmless no-op.
Extend setVnetRoutePriority with optional rx/tx monitor timers and a
pinned_state trailing param so the custom_bfd routes can be programmed
with the same fields the VS create_vnet_routes uses.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510
Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
…stom_bfd (32) Port test_vnet_orch_32 to VNetOrchTest.VnetCustomBfdPriorityRouteTwoPrimaryTwoSecondary: a custom_bfd priority route with two remote primary and two directly-connected local secondary endpoints. Exercises the full failover cascade -- primaries preferred whenever any is up, fall back to the local secondary group only when both primaries are down, withdrawn entirely when all four are down, then restored primary-first as monitors return -- and verifies that secondary monitor churn never disturbs an active-primary route. The /24 adv_prefix summary is advertised whenever the route is active. No new fixture infra: reuses createL3Interface/addNeighbor for the local endpoints, setVnetRoutePriority (rx/tx timers), updateBfdSessionState (drives BfdMonitorOrch for custom_bfd), checkPriorityRoute/checkStateDbRoute/ checkRouteAdvertised. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Port test_vnet_orch_26 and test_vnet_orch_27 to VNetOrchTest, covering the MP2MP IPINIP subnet-decap term that VNetRouteOrch programs for a BFD-monitored ECMP route on a subnet-decap-enabled switch. The decap term is tied to the route's ACTIVE/INACTIVE state: it is created when the route first becomes active (first monitor up) via VNetRouteOrch::createSubnetDecapTerm, and removed when the route goes inactive (all monitors down) or is deleted. Test 26 covers the IPv4 case; test 27 the IPv6 counterpart (term source subnet taken from the SUBNET_DECAP src_ip_v6). Fixture infrastructure added (reusable): - syncTunnelDecapTerm(): diffs APP_TUNNEL_DECAP_TERM_TABLE and delivers VNetRouteOrch's producer writes to gTunneldecapOrch, modeled on syncBfd(); wired into the monitored-route set/del and BFD-state-change drive paths. No-op when subnet decap is disabled. - setSubnetDecapConfig()/createSubnetDecapTunnel()/delSubnetDecapTunnel(): drive the CFG_SUBNET_DECAP + APP_TUNNEL_DECAP_TABLE config through gTunneldecapOrch (mock equivalents of the setup_subnet_decap fixture + vnet_lib.create/delete_subnet_decap_tunnel). - checkIpinipTunnel()/checkIpinipDecapTerm()/checkNoIpinipDecapTerm()/ checkIpinipDecapTermRemoved(): capture and assert the IPINIP tunnel's decap DSCP/ECN/TTL modes and the MP2MP term's VR, action tunnel, and src/dst network+mask (mock equivalents of vnet_lib.check_ipinip_tunnel / check_ipinip_tunnel_decap_term / check_del_ipinip_tunnel_decap_term). Extends the captured Tunnel struct with decap dscp/ecn/ttl modes and the Term struct with dst mask + src network/mask. Full VNetOrchTest 39/39; full mock suite 951/951. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Port test_vnet_vxlan_multi_map (test 6) to VNetOrchTest.VnetVxlanMultiMap. On a tunnel a VNET has already bound (and thus activated), an explicit VXLAN_TUNNEL_MAP entry adds a further VLAN<->VNI decap tunnel-map entry on top of the VNET's VR<->VNI maps -- the "multi map" case. The mock builds a VxlanTunnelMapOrch on APP_DB VXLAN_TUNNEL_MAP_TABLE (gVxlanTunnelMapOrch equivalent, registered in gDirectory like orchdaemon), brings up Vlan1000 so getVlanByVlanId() resolves, and asserts the third tunnel-map entry is a VNI_TO_VLAN_ID map (vni 1000 -> vlan 1000) against the tunnel's VNI->VLAN decap map, leaving the VNET's two VR<->VNI entries untouched. The VS test asserts only the VNET/tunnel entries and that adding the map does not disturb them (it stops after delete_vnet + delete_vxlan_tunnel, checking nothing on teardown). The mock is a faithful superset: it also asserts the explicit entry's vni/vlan, and -- because the explicit map holds a reference that blocks tunnel teardown -- deletes the map before the tunnel so the full teardown (tunnel + 4 maps + P2MP term + 3 map entries) can be verified. Adds createVlan / createVxlanTunnelMap / delVxlanTunnelMap helpers and captures the VLAN_ID key/value slots on tunnel-map entries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
…(24) Add VnetDuplicateRouteHandledGracefully, the mock equivalent of test_vnet_orch_24 (the duplicate-route regression from commit 6e25014, "Handle duplicate routes in a graceful manner"). A default-scope VNET programs a tunnel route for 100.100.1.0/24 directly in the default virtual router (gVirtualRouterId). A regular route for the same prefix -- normally learned via FRR/BGP and delivered by fpmsyncd, here substituted as a direct APP_DB ROUTE_TABLE write (that netlink to APP_DB translation is covered by test_route + tests_fpmsyncd) -- then drives gRouteOrch, which is unaware of the VNET route and tries to program the same prefix in the same VR. libsaivs returns SAI_STATUS_ITEM_ALREADY_EXISTS for that bulk create, and handleSaiCreateStatus must treat it as success rather than recording a SAI failure. The VS test asserts this via check_syslog for the ABSENCE of the failure message; the mock equivalent is getSaiFailureStatus() staying false after both the create and the remove phases. The captured per-entry bulk status proves the conflicting create really hit a duplicate, and the surviving route entry is the check_route_entries equivalent. Verified the gate is strong: temporarily routing ITEM_ALREADY_EXISTS through handleSaiFailure makes the test fail as expected. Adds setRoute/delRoute helpers (regular gRouteOrch route via APP_DB ROUTE_TABLE + DEL_COMMAND withdraw) and a lastBulkCreateStatuses capture on RouteCaptures. Full VNetOrchTest 41/41; full mock suite 953/953. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
The 37 migrated test_vnet.py methods are now covered by the C++/gtest
mock tests in tests/mock_tests/vnetorch_ut.cpp (41 TEST_Fs). Remove them
from the VS suite so their coverage isn't duplicated and the Docker-based
VS CI runtime is reclaimed.
test_vnet_orch_4 is intentionally RETAINED: it is @pytest.mark.skip
("Failing. Under investigation") in the VS suite and its VNET peering
behaviour (cross-VRF route replication via peer_list) has no mock
equivalent, so it was not migrated. Per policy, un-migrated cases are not
deleted. The class scaffolding it depends on is kept with it, and the
module-level test_nonflaky_dummy remains so the module still has an active
test.
vnet_lib.py is likewise kept (imported by test_vnet2.py and orch_4).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510
Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
…eering Two coverage-fidelity fixes to the VNET mock tests, both matching what the original test_vnet.py actually exercised: 1. Route CONFIG->APP path. The VS create_vnet_routes / create_vnet_local_ routes write CONFIG_DB VNET_ROUTE_TUNNEL / VNET_ROUTE and rely on VNetCfgRouteOrch to mirror them to the APP_DB tables VNetRouteOrch consumes. The mock wrote APP_DB directly, bypassing VNetCfgRouteOrch::doVnetTunnelRouteTask / doVnetRouteTask. Add VNetCfgRouteOrch to the fixture (as orchdaemon does) and route every SET helper (setVnetRoute, setVnetRouteMonitored, setVnetRoutePriority, setVnetLocalRoute) through CONFIG_DB via a new programVnetRouteViaCfg(), so the real CONFIG->APP translation runs. Deletes still go to APP_DB, matching the VS delete_vnet_routes. 2. VNET peering -- migrates test_vnet_orch_4 (which is @pytest.mark.skip in the VS suite, so this restores real coverage rather than duplicating a live test). VnetPeeringReplicatesRouteIntoPeerVr: two VNETs peer via peer_list, and a tunnel route created in one is programmed in BOTH its own VR and the peer's VR (VNetRouteOrch::doRouteTask builds vr_set over vnet + peer_list), the check_vnet_routes(peer) assertion the VS test made. Full VNetOrchTest 42/42; full mock suite 974/974. VNetOrchTest is stable across 20 shuffled in-process repeats. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
…MP test All 38 originally-migrated test_vnet.py methods (incl. orch_4 peering, now covered by VnetPeeringReplicatesRouteIntoPeerVr) are removed. The one method kept is test_vnet_local_route_ecmp_unnumbered -- added on master after this branch was cut and not yet migrated, so per policy it stays in the VS module rather than being deleted. tests/vnet_lib.py is likewise kept (test_vnet2.py imports it). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
Migrate test_vnet_local_route_ecmp_unnumbered (added on master) as VnetLocalRouteUnnumberedEcmp. A VNET local ECMP route whose members share ONE link-local next-hop IP reached via two interfaces: master's VNetRouteOrch parses `nexthop` as an ordered ip/ifname list (duplicate IPs preserved) instead of a deduped IpAddresses set, so 169.254.0.1 listed twice with different ifnames yields a 2-member NHG on distinct RIFs. The test walks all five VS phases: 2-member NHG on distinct RIFs (A); shrink to a single IP next hop on one RIF (B); regrow (C); oper-down one port so its member is pruned (D); bring it back up + re-learn the neighbor so the group reforms (E). Because the IP is shared, membership is asserted by RIF (captured from SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID), mirroring the VS _nhgm_rifs()/_nh_rif() checks. Fixture: build gMlagOrch (as orchdaemon does) -- FdbOrch observes port oper-status changes and calls gMlagOrch->isMlagInterface() on a DOWN, so a null gMlagOrch segfaults the port-down phase (fdborch.cpp:1722). Full VNetOrchTest 43/43; full mock suite 982/982; stable across 20 shuffled in-process repeats. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
test_vnet_local_route_ecmp_unnumbered is now covered by VnetLocalRouteUnnumberedEcmp, so the last remaining VS method is migrated and tests/test_vnet.py is deleted in full. tests/vnet_lib.py is kept -- test_vnet2.py imports it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b820490a-c3c2-490a-96de-a1fcfc233510 Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
theasianpianist
force-pushed
the
migrate-test-vnet-to-mock
branch
from
August 5, 2026 18:30
a43f459 to
35d0437
Compare
Collaborator
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
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.
What I did
Migrated
tests/test_vnet.py(the VNET virtual-switch integration suite, 38 testmethods) to fast in-process C++/gtest mock tests in
tests/mock_tests/vnetorch_ut.cpp(41VNetOrchTestTEST_Fs — several VSmethods split into IPv4/IPv6 and ordered/unordered-ECMP variants). The VS module
is deleted in the same PR so the coverage delta is reviewed at the swap.
Coverage ported (mock equivalents of every
test_vnet.pymethod):single+ECMP, priority failover clusters, re-pairing and pinned state.
tunnel-term ACL priority routes, local-endpoint alias resolution.
overlay_dmacchange on the fly, TSA route withdrawal, subnet-decap MP2MPterms, vxlan multi-map tunnel-map entries, IPv6 link-local trap route.
test_vnet_orch_24regression from6e25014).
Shared infra added (used on second use, per the mock-first testing policy):
tests/mock_tests/common/mock_test_helpers.{h,cpp}(findAttrSAI-attributeassertion helper), and
policerorch_ut.cpprefactored onto it.tests/vnet_lib.pyis intentionally kept —tests/test_vnet2.pystill importsit; it will be removed when
test_vnet2.pyis migrated in a follow-up.Why I did it
VNET is the single longest-running and flakiest VS module (~52 min of Docker
virtual-switch CI wall-clock). The VS suite requires a full swss/syncd/redis
container and real kernel/netns stimulus, making it slow and flaky. The
equivalent mock tests run in ~1.8s in-process against the orchagent objects with
the SAI API mocked, reclaiming that CI time and removing the flakiness while
preserving the same behavioral coverage.
This is the second migration in the effort tracked alongside the merged
test_policerPOC (#4756); it establishes the reusable SAI-attribute assertionhelper for later ports.
How I verified it
VNetOrchTestsuite: 41/41 passing.master, whichincludes
namelabelmapper— no regressions).substituted with the equivalent APP_DB/STATE_DB writes; that netlink→DB
translation stays covered by the kept
test_route/tests_fpmsyncd.findAttr), theestablished pattern in the mock harness (no readable ASIC_DB). VS
check_syslogfailure-absence assertions map togetSaiFailureStatus(); theduplicate-route gate was confirmed strong by temporarily routing
ITEM_ALREADY_EXISTSthroughhandleSaiFailureand observing the expectedfailure.
Details if related
squash-on-merge collapses them at merge time.