Support get apf capabilities from network_stack shell command

This utility reads output of cmd network_stack apf ${iface_name}
capabilities. This is needed for the tests to skip if the apf
version is too old.

Test: atest NetworkStaticLibHostPythonTests
Bug: 352132428
Change-Id: I1f8b523c3e6f687c2e919993bc18392dc25dbbf7
This commit is contained in:
Junyu Lai 2024-07-11 15:57:00 +08:00
commit c6fae35cfd

View file

@ -12,7 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from dataclasses import dataclass
import re
from mobly import asserts
from mobly.controllers import android_device
from mobly.controllers.android_device_lib.adb import AdbError
from net_tests_utils.host.python import adb_utils, assert_utils
@ -190,3 +192,65 @@ def send_raw_packet_downstream(
raise assert_utils.UnexpectedBehaviorError(
f"Got unexpected output: {output} for command: {cmd}."
)
@dataclass
class ApfCapabilities:
"""APF program support capabilities.
See android.net.apf.ApfCapabilities.
Attributes:
apf_version_supported (int): Version of APF instruction set supported for
packet filtering. 0 indicates no support for packet filtering using APF
programs.
apf_ram_size (int): Size of APF ram.
apf_packet_format (int): Format of packets passed to APF filter. Should be
one of ARPHRD_*
"""
apf_version_supported: int
apf_ram_size: int
apf_packet_format: int
def __init__(
self,
apf_version_supported: int,
apf_ram_size: int,
apf_packet_format: int,
):
self.apf_version_supported = apf_version_supported
self.apf_ram_size = apf_ram_size
self.apf_packet_format = apf_packet_format
def __str__(self):
"""Returns a user-friendly string representation of the APF capabilities."""
return (
f"APF Version: {self.apf_version_supported}\n"
f"Ram Size: {self.apf_ram_size} bytes\n"
f"Packet Format: {self.apf_packet_format}"
)
def get_apf_capabilities(
ad: android_device.AndroidDevice, iface_name: str
) -> ApfCapabilities:
output = adb_utils.adb_shell(
ad, f"cmd network_stack apf {iface_name} capabilities"
)
try:
values = [int(value_str) for value_str in output.split(",")]
except ValueError:
return ApfCapabilities(0, 0, 0) # Conversion to integer failed
return ApfCapabilities(values[0], values[1], values[2])
def assume_apf_version_support_at_least(
ad: android_device.AndroidDevice, iface_name: str, expected_version: int
) -> None:
caps = get_apf_capabilities(ad, iface_name)
asserts.skip_if(
caps.apf_version_supported < expected_version,
f"Supported apf version {caps.apf_version_supported} < expected version"
f" {expected_version}",
)