Skip to content

Commit df0cd48

Browse files
Re-sync with internal repository
The internal and external repositories are out of sync. This Pull Request attempts to brings them back in sync by patching the GitHub repository. Please carefully review this patch. You must disable ShipIt for your project in order to merge this pull request. DO NOT IMPORT this pull request. Instead, merge it directly on GitHub using the MERGE BUTTON. Re-enable ShipIt after merging. fbshipit-source-id: a4a13e29a11d714847903917f8a629584b1d48d0
1 parent 30a62c1 commit df0cd48

17 files changed

Lines changed: 579 additions & 646 deletions

README.md

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,6 @@ are expressed as structured configurations rather than imperative scripts.
1111

1212
See the [documentation](https://github.com/facebook/DNE-Taac) for setup instructions.
1313

14-
## Running TAAC modules under OSS
15-
16-
TAAC's Python modules (e.g. `taac.libs.taac_runner`) include Meta-internal imports that aren't shipped in this slice. Set `TAAC_OSS=1` so the imports take their OSS branch:
17-
18-
```bash
19-
export TAAC_OSS=1
20-
python3 -c 'import taac.libs.taac_runner; print("ok")'
21-
```
22-
23-
Some runtime functionality is stubbed in OSS mode (NDS drainer, COOP patcher, ValidationStep, AristaSSHHelper, etc.) and will raise `NotImplementedError` if invoked on a code path that requires it. Imports succeed; trying to actually use those features fails.
24-
2514
## License
2615

2716
This project is licensed under the Apache License 2.0 — see the [LICENSE](LICENSE) file for details.
Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
11
# Copyright (c) Meta Platforms, Inc. and affiliates.
22
# pyre-unsafe
3-
import os
43
import typing as t
54

5+
from taac.ai_bb.dsf.dsf_test_handler import DsfTestHandler
66
from taac.custom_test_handlers.base_custom_test_handler import (
77
BaseCustomTestHandler,
88
)
99
from taac.custom_test_handlers.patcher_cleanup_handler import (
1010
PatcherCleanupHandler,
1111
)
1212

13-
TAAC_OSS = os.environ.get("TAAC_OSS", "").lower() in ("1", "true", "yes")
1413

1514
# pyre-ignore
1615
CUSTOM_TEST_HANDLERS: t.List[BaseCustomTestHandler] = [
16+
DsfTestHandler,
1717
PatcherCleanupHandler,
1818
]
19-
20-
if not TAAC_OSS:
21-
# DsfTestHandler lives in the Meta-internal taac.ai_bb subpackage which
22-
# isn't shipped in the OSS slice.
23-
from taac.ai_bb.dsf.dsf_test_handler import DsfTestHandler
24-
25-
# pyre-ignore[6]: registry holds handler classes, annotated as instances.
26-
CUSTOM_TEST_HANDLERS.append(DsfTestHandler)

taac/driver/fboss_switch.py

Lines changed: 4 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -36,71 +36,15 @@
3636
# =============================================================================
3737
# Third-party (PyPI / OSS-compatible)
3838
# =============================================================================
39-
if t.TYPE_CHECKING:
40-
# Keep Pyre on the real `bunch` types; the runtime fallback below would
41-
# otherwise widen `bunch.Bunch` to `Bunch | SimpleNamespace`, which breaks
42-
# callers (and the `import *` re-export in dne/drivers/fboss_switch.py).
43-
import bunch
44-
else:
45-
try:
46-
import bunch
47-
except ImportError:
48-
# bunch is abandoned (last updated 2011), use types.SimpleNamespace as replacement
49-
from types import SimpleNamespace as Bunch
50-
51-
class BunchModule:
52-
"""Compatibility wrapper for abandoned bunch module"""
53-
54-
Bunch = Bunch
55-
56-
bunch = BunchModule()
39+
import bunch
5740

5841
# =============================================================================
5942
# FBOSS thrift types & clients (already OSS'd)
6043
# =============================================================================
6144
import neteng.fboss.bgp_thrift.types as fboss_bgp_thrift_types
6245
import neteng.fboss.fsdb.types as fsdb_types
6346
import pexpect
64-
65-
TAAC_OSS = os.environ.get("TAAC_OSS", "").lower() in ("1", "true", "yes")
66-
67-
# `t.TYPE_CHECKING or` keeps the real FbossAgentClient visible to Pyre so
68-
# `with self._get_fboss_agent_client() as client:` type-checks as a context
69-
# manager (the OSS stub below is a runtime-only fallback).
70-
if t.TYPE_CHECKING or not TAAC_OSS:
71-
from fboss.fb_thrift_clients import FbossAgentClient, FbossAgentClientWrapper
72-
else:
73-
# OSS stubs - fboss.fb_thrift_clients is Meta-internal
74-
# Use FbossCtrl from OSS bindings as base
75-
class FbossAgentClient: # type: ignore
76-
"""OSS stub - using FbossCtrl from neteng.fboss.ctrl.clients"""
77-
78-
def __init__(self, hostname: str, port: int = 5909, timeout: int = 30):
79-
from neteng.fboss.ctrl.clients import FbossCtrl
80-
81-
self.hostname = hostname
82-
self.port = port
83-
self.timeout = timeout
84-
self._client = FbossCtrl
85-
86-
class FbossAgentClientWrapper: # type: ignore
87-
"""OSS stub - context manager wrapper for FbossCtrl"""
88-
89-
def __init__(self, host: str, timeout: int = 30):
90-
self.host = host
91-
self.timeout = timeout
92-
self._client = None
93-
94-
def __enter__(self):
95-
from neteng.fboss.ctrl.clients import FbossCtrl
96-
97-
# In OSS, return the client class - actual instantiation happens elsewhere
98-
return FbossCtrl
99-
100-
def __exit__(self, *args):
101-
pass
102-
103-
47+
from fboss.fb_thrift_clients import FbossAgentClient, FbossAgentClientWrapper
10448
from neteng.fboss.bgp_attr.types import TBgpAfi, TIpPrefix
10549
from neteng.fboss.bgp_route_types.types import TBgpPath, TRibEntry
10650
from neteng.fboss.bgp_thrift.clients import TBgpService
@@ -217,6 +161,8 @@ def __exit__(self, *args):
217161
to_fb_uqdn,
218162
)
219163

164+
TAAC_OSS = os.environ.get("TAAC_OSS", "").lower() in ("1", "true", "yes")
165+
220166
if not TAAC_OSS:
221167
from openr.py.openr.cli.utils.commands import OpenrCtrlCmd
222168
from openr.py.openr.clients.openr_client import get_openr_ctrl_cpp_client

taac/health_checks/all_health_checks.py

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import os
44
import typing as t
55

6-
TAAC_OSS = os.environ.get("TAAC_OSS", "").lower() in ("1", "true", "yes")
7-
86
from taac.health_checks.abstract_health_check import (
97
AbstractDeviceHealthCheck,
108
AbstractIxiaHealthCheck,
@@ -50,6 +48,9 @@
5048
from taac.health_checks.device_health_checks.clear_counters_health_check import (
5149
ClearCountersHealthCheck,
5250
)
51+
from taac.health_checks.device_health_checks.cpu_utilization_health_check import (
52+
CpuUtilizationHealthCheck,
53+
)
5354
from taac.health_checks.device_health_checks.device_core_dumps_health_check import (
5455
DeviceCoreDumpsHealthCheck,
5556
)
@@ -65,6 +66,9 @@
6566
from taac.health_checks.device_health_checks.file_exists_health_check import (
6667
FileExistsHealthCheck,
6768
)
69+
from taac.health_checks.device_health_checks.generic_ods_health_check import (
70+
GenericOdsHealthCheck,
71+
)
6872
from taac.health_checks.device_health_checks.hardware_capacity_health_check import (
6973
HardwareCapacityHealthCheck,
7074
)
@@ -77,6 +81,9 @@
7781
from taac.health_checks.device_health_checks.log_parsing_health_check import (
7882
LogParsingHealthCheck,
7983
)
84+
from taac.health_checks.device_health_checks.memory_utilization_health_check import (
85+
MemoryUtilizationHealthCheck,
86+
)
8087
from taac.health_checks.device_health_checks.oomd_kill_health_check import (
8188
OomdKillHealthCheck,
8289
)
@@ -128,6 +135,15 @@
128135
from taac.health_checks.device_health_checks.systemctl_active_state_health_check import (
129136
SystemctlActiveStateHealthCheck,
130137
)
138+
from taac.health_checks.device_health_checks.tm_reconciliation_firing_health_check import (
139+
TmReconciliationFiringHealthCheck,
140+
)
141+
from taac.health_checks.device_health_checks.ucmp_traffic_distribution_health_check import (
142+
UcmpTrafficDistributionHealthCheck,
143+
)
144+
from taac.health_checks.device_health_checks.unclean_exit_health_check import (
145+
UncleanExitHealthCheck,
146+
)
131147
from taac.health_checks.device_health_checks.wedge_agent_configured_health_check import (
132148
WedgeAgentConfiguredHealthCheck,
133149
)
@@ -143,6 +159,12 @@
143159
from taac.health_checks.dsf_health_checks.dsf_fsdb_subscriber_timestamp_health_check import (
144160
DsfFsdbSubscriberTimestampHealthCheck,
145161
)
162+
from taac.health_checks.dsf_health_checks.dsf_pfc_health_check import (
163+
DsfPfcHealthCheck,
164+
)
165+
from taac.health_checks.dsf_health_checks.dsf_traffic_rebalance_health_check import (
166+
DsfTrafficRebalanceHealthCheck,
167+
)
146168
from taac.health_checks.ixia_health_checks.ixia_packet_loss_health_check import (
147169
IxiaPacketLossHealthCheck,
148170
)
@@ -190,6 +212,8 @@
190212
)
191213
from taac.health_check.health_check import types as hc_types
192214

215+
TAAC_OSS = os.environ.get("TAAC_OSS", "").lower() in ("1", "true", "yes")
216+
193217
HealthCheck = t.Union[
194218
t.Type[AbstractIxiaHealthCheck],
195219
t.Type[AbstractDeviceHealthCheck],
@@ -202,23 +226,23 @@
202226
DrainStateHealthCheck,
203227
DsfDrainStateHealthCheck,
204228
DsfFabricReachabilityHealthCheck,
205-
# DsfTrafficRebalanceHealthCheck, # neteng.test_infra.dne.taac dep, excluded in OSS
229+
DsfTrafficRebalanceHealthCheck,
206230
DsfFsdbSessionHealthCheck,
207231
DsfFsdbSubscriberTimestampHealthCheck,
208232
NdpHealthCheck,
209233
IxiaPortStatsHealthCheck,
210234
SystemctlActiveStateHealthCheck,
211235
WedgeAgentConfiguredHealthCheck,
212-
# DsfPfcHealthCheck, # neteng.test_infra.dne.taac dep, excluded in OSS
236+
DsfPfcHealthCheck,
213237
CoreDumpsHealthCheck,
214238
PortStateHealthCheck,
215239
LldpHealthCheck,
216240
IxiaTrafficRateHealthCheck,
217241
PfcWdHealthCheck,
218242
CpuQueueHealthCheck,
219-
# UncleanExitHealthCheck, # ODS-dependent (taac.internal), excluded in OSS
220-
# CpuUtilizationHealthCheck, # ODS-dependent (taac.internal), excluded in OSS
221-
# MemoryUtilizationHealthCheck, # ODS-dependent (taac.internal), excluded in OSS
243+
UncleanExitHealthCheck,
244+
CpuUtilizationHealthCheck,
245+
MemoryUtilizationHealthCheck,
222246
BgpSessionEstablishedHealthCheck,
223247
BgpConvergenceHealthCheck,
224248
BgpGracefulRestartHealthCheck,
@@ -228,7 +252,7 @@
228252
BgpNonBestRouteHealthCheck,
229253
BgpTcpdumpHealthCheck,
230254
L2EntryThresholdHealthCheck,
231-
# GenericOdsHealthCheck, # ODS-dependent (taac.internal), excluded in OSS
255+
GenericOdsHealthCheck,
232256
OomdKillHealthCheck,
233257
EcmpGroupAndMemberCountHealthCheck,
234258
DeviceCoreDumpsHealthCheck,
@@ -248,7 +272,7 @@
248272
BgpFibProgrammingCheck,
249273
PortSpeedHealthCheck,
250274
PortSpeedSnapshotHealthCheck,
251-
# UcmpTrafficDistributionHealthCheck, # ODS-dependent (taac.internal), excluded in OSS
275+
UcmpTrafficDistributionHealthCheck,
252276
BgpRouteCountVerificationHealthCheck,
253277
BgpMultipathNextHopCountHealthCheck,
254278
RouteConvergenceTimeHealthCheck,
@@ -262,7 +286,7 @@
262286
OpenrKvstoreConsistencyHealthCheck,
263287
AristaFbossNextHopValidityHealthCheck,
264288
PortChannelExpectedStateHealthCheck,
265-
# TmReconciliationFiringHealthCheck, # ODS-dependent (taac.internal), excluded in OSS
289+
TmReconciliationFiringHealthCheck,
266290
TmKernelStateSnapshotHealthCheck,
267291
]
268292

taac/ixia/ixia.py

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -42,49 +42,25 @@
4242
retryable,
4343
to_fb_uqdn,
4444
)
45-
46-
# The monorepo ships these constants at neteng.test_infra.ixia.ixnetwork_restpy.constants;
47-
# in OSS we vendor a copy alongside this module.
48-
if TAAC_OSS:
49-
from taac.ixia.ixnetwork_restpy_constants import (
50-
ALLOWED_IPV4_ADVERTISEMENTS,
51-
ALLOWED_IPV6_ADVERTISEMENTS,
52-
API_SERVER_PASSWORD,
53-
API_SERVER_USERNAME,
54-
DESIRED_BGP_V4_PEER_NAME,
55-
DESIRED_BGP_V4_PREFIX_NAME,
56-
DESIRED_BGP_V6_PEER_NAME,
57-
DESIRED_BGP_V6_PREFIX_NAME,
58-
DESIRED_DEVICE_GROUP_NAME,
59-
DESIRED_ETHERNET_NAME,
60-
DESIRED_IPV4_NAME,
61-
DESIRED_IPV6_NAME,
62-
DESIRED_IPV6_PTP_NAME,
63-
DESIRED_TOPOLOGY_NAME,
64-
DESIRED_V4_BGP_PREFIX_NAME,
65-
DESIRED_V6_BGP_PREFIX_NAME,
66-
DESIRED_VPORT_NAME,
67-
)
68-
else:
69-
from neteng.test_infra.ixia.ixnetwork_restpy.constants import (
70-
ALLOWED_IPV4_ADVERTISEMENTS,
71-
ALLOWED_IPV6_ADVERTISEMENTS,
72-
API_SERVER_PASSWORD,
73-
API_SERVER_USERNAME,
74-
DESIRED_BGP_V4_PEER_NAME,
75-
DESIRED_BGP_V4_PREFIX_NAME,
76-
DESIRED_BGP_V6_PEER_NAME,
77-
DESIRED_BGP_V6_PREFIX_NAME,
78-
DESIRED_DEVICE_GROUP_NAME,
79-
DESIRED_ETHERNET_NAME,
80-
DESIRED_IPV4_NAME,
81-
DESIRED_IPV6_NAME,
82-
DESIRED_IPV6_PTP_NAME,
83-
DESIRED_TOPOLOGY_NAME,
84-
DESIRED_V4_BGP_PREFIX_NAME,
85-
DESIRED_V6_BGP_PREFIX_NAME,
86-
DESIRED_VPORT_NAME,
87-
)
45+
from neteng.test_infra.ixia.ixnetwork_restpy.constants import (
46+
ALLOWED_IPV4_ADVERTISEMENTS,
47+
ALLOWED_IPV6_ADVERTISEMENTS,
48+
API_SERVER_PASSWORD,
49+
API_SERVER_USERNAME,
50+
DESIRED_BGP_V4_PEER_NAME,
51+
DESIRED_BGP_V4_PREFIX_NAME,
52+
DESIRED_BGP_V6_PEER_NAME,
53+
DESIRED_BGP_V6_PREFIX_NAME,
54+
DESIRED_DEVICE_GROUP_NAME,
55+
DESIRED_ETHERNET_NAME,
56+
DESIRED_IPV4_NAME,
57+
DESIRED_IPV6_NAME,
58+
DESIRED_IPV6_PTP_NAME,
59+
DESIRED_TOPOLOGY_NAME,
60+
DESIRED_V4_BGP_PREFIX_NAME,
61+
DESIRED_V6_BGP_PREFIX_NAME,
62+
DESIRED_VPORT_NAME,
63+
)
8864
from uhd_restpy.assistants.sessions.sessionassistant import (
8965
SessionAssistant as UhdSessionAssistant,
9066
)
@@ -5078,6 +5054,47 @@ def find_bgp_peers(
50785054
)
50795055
return bgp_peers
50805056

5057+
def get_bgp_session_addresses(
5058+
self, regex: str, session_idx: int, ignore_case: bool = False
5059+
) -> t.Tuple[str, str]:
5060+
"""Resolve the ``(peer_ip, dut_ip)`` pair for a 1-based BGP session index.
5061+
5062+
For the first BGP peer (device group) whose name matches ``regex``,
5063+
returns the addresses for session ``session_idx``:
5064+
- ``peer_ip``: the IXIA-side neighbor address -- the UPDATE *destination*
5065+
when the DUT dumps routes to the peer,
5066+
- ``dut_ip``: the DUT-side address the peer points at -- the UPDATE
5067+
*source*.
5068+
5069+
These are used to scope a packet capture to a single DUT->peer direction,
5070+
which is required to compare exactly what the DUT sent each peer (an IXIA
5071+
vport carries every session on the link, plus the peers' own
5072+
advertisements back to the DUT).
5073+
"""
5074+
peers = self.find_bgp_peers(regex, ignore_case)
5075+
if not peers:
5076+
raise ValueError(f"No BGP peer matches regex {regex!r}")
5077+
peer = peers[0]
5078+
idx = session_idx - 1
5079+
if idx < 0:
5080+
raise ValueError(f"session_idx must be >= 1; got {session_idx}")
5081+
# DutIp lives on the BGP peer; the peer's own address lives on the parent
5082+
# IP (Ipv6/Ipv4) stack. Both are Multivalues with one entry per session.
5083+
dut_ips = list(peer.DutIp.Values)
5084+
ip_stack = peer.parent
5085+
peer_ips = list(ip_stack.Address.Values)
5086+
if idx >= len(dut_ips) or idx >= len(peer_ips):
5087+
raise ValueError(
5088+
f"session_idx {session_idx} out of range for peer {peer.Name!r}: "
5089+
f"{len(peer_ips)} session address(es), {len(dut_ips)} DUT IP(s)"
5090+
)
5091+
peer_ip, dut_ip = peer_ips[idx], dut_ips[idx]
5092+
self.logger.info(
5093+
f"BGP session {session_idx} of {peer.Name!r}: "
5094+
f"DUT {dut_ip} -> peer {peer_ip}"
5095+
)
5096+
return peer_ip, dut_ip
5097+
50815098
def find_bgp_ipv6_peer(self, port_identifier: str) -> t.Optional["BgpIpv6Peer"]:
50825099
"""Finds the BGP peer in the IXIA setup"""
50835100
ipv6 = self.find_ipv6(port_identifier)

0 commit comments

Comments
 (0)