Skip to content

Commit

Permalink
Improvements to PTF framework (#805)
Browse files Browse the repository at this point in the history
  • Loading branch information
gab-arrobo authored May 6, 2024
1 parent aec3ca3 commit 82b7a1d
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 151 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ jobs:
- name: Build the PFCP Agent Docker image
run: DOCKER_TARGETS=pfcpiface make docker-build

build-ptf:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./ptf
steps:
- uses: actions/checkout@v4

- name: Build PTF image
run: make build

lint:
name: lint
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ registry: [upf-epc-bess](https://hub.docker.com/r/omecproject/upf-epc-bess),
* GTPu path monitoring
* Network Token Functions (_**experimental**_)
* Support for DPDK, CNDP, AF_PACKET and AF_XDP modes
- BESS uses DPDK 22.11.4

### P4-UPF
P4-UPF implements a core set of features capable of supporting requirements for
Expand Down
48 changes: 25 additions & 23 deletions ptf/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,31 @@ ARG TREX_VER=2.92-scapy-2.4.5
ARG TREX_EXT_LIBS=/external_libs
ARG TREX_LIBS=/trex_python
ARG UNITTEST_XML_REPORTING_VER=3.0.4
ARG PROTOBUF_VER=3.12
ARG GRPC_VER=1.26

ARG PROTOBUF_VER=3.20
# Install dependencies for general PTF test definitions
FROM ubuntu:20.04 as ptf-deps
FROM ubuntu:22.04 as ptf-deps

ARG SCAPY_VER
ARG PTF_VER
ARG UNITTEST_XML_REPORTING_VER
ARG PROTOBUF_VER
ARG GRPC_VER

ENV RUNTIME_DEPS \
RUN apt-get update && \
apt-get install -y --no-install-recommends \
python3 \
python3-pip \
python3-setuptools \
git
git && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

ENV PIP_DEPS \
RUN pip3 install --no-cache-dir --root /python_output \
git+https://github.com/p4lang/ptf@$PTF_VER \
protobuf==$PROTOBUF_VER \
grpcio==$GRPC_VER \
grpcio \
unittest-xml-reporting==$UNITTEST_XML_REPORTING_VER

RUN apt update && \
apt install -y $RUNTIME_DEPS
RUN pip3 install --no-cache-dir --root /python_output $PIP_DEPS

# Install TRex traffic gen and library for TRex API
FROM alpine:3.19.1 as trex-builder
ARG TREX_VER
Expand All @@ -45,8 +42,8 @@ ARG TREX_LIBS

ENV TREX_SCRIPT_DIR=/trex-core-${TREX_VER}/scripts

RUN apk update && apk add --no-cache -U wget
RUN wget https://github.com/stratum/trex-core/archive/v${TREX_VER}.zip && \
RUN apk update && apk add --no-cache -U wget && \
wget https://github.com/stratum/trex-core/archive/v${TREX_VER}.zip && \
unzip -qq v${TREX_VER}.zip && \
mkdir -p /output/${TREX_EXT_LIBS} && \
mkdir -p /output/${TREX_LIBS} && \
Expand All @@ -55,13 +52,14 @@ RUN wget https://github.com/stratum/trex-core/archive/v${TREX_VER}.zip && \
cp -r ${TREX_SCRIPT_DIR}/automation/trex_control_plane/stf/trex_stf_lib /output/${TREX_LIBS}

# Synthesize all dependencies for runtime
FROM ubuntu:20.04
FROM ubuntu:22.04

ARG TREX_EXT_LIBS
ARG TREX_LIBS
ARG SCAPY_VER

ENV RUNTIME_DEPS \
RUN apt-get update && \
apt-get install -y --no-install-recommends \
make \
net-tools \
python3 \
Expand All @@ -73,12 +71,14 @@ ENV RUNTIME_DEPS \
build-essential \
python3-pip \
wget \
netbase

RUN apt update && \
apt install -y $RUNTIME_DEPS && \
netbase && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN pip3 install --no-cache-dir scipy==1.5.4 numpy==1.19.4 matplotlib==3.3.3 pyyaml==5.4.1
RUN pip3 install --no-cache-dir \
scipy \
numpy \
matplotlib \
pyyaml

ENV TREX_EXT_LIBS=${TREX_EXT_LIBS}
ENV PYTHONPATH=${TREX_EXT_LIBS}:${TREX_LIBS}
Expand All @@ -87,7 +87,9 @@ COPY --from=trex-builder /output /
COPY --from=ptf-deps /python_output /

# Install custom scapy version from TRex so PTF tests can access certain scapy features
RUN cd ${TREX_EXT_LIBS}/scapy-${SCAPY_VER}/ && python3 setup.py install
RUN ldconfig
# TODO: Move to a newer Scapy version compatible with latest Ubuntu versions
WORKDIR ${TREX_EXT_LIBS}/scapy-${SCAPY_VER}
RUN python3 setup.py install \
&& ldconfig

ENTRYPOINT []
48 changes: 21 additions & 27 deletions ptf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,46 +73,40 @@ hosting TRex, where results are asserted.

## Steps to run tests
The run script assumes that the TRex daemon server and the UPF
instance are already running on their respective machines. It also
assumes that all the following config files are configured correctly to
route traffic to the UPF and vice versa.
* `upf/scripts/docker_setup.sh` script updated with proper values for
`ifaces`, `macaddrs`, `nhmacaddrs` parameters. For reference
please refer `upf/ptf/config/docker_setup.sh` file
* `upf/conf/upf.jsonc` file updated with proper values for
`measure_flow`, `measure_upf` parameters. For reference
please refer `upf/ptf/config/upf.jsonc` file
instance are already running on their respective machines. Please see
[here](../docs/INSTALL.md#configuration-dpdk-mode) for instructions to deploy
the UPF in DPDK mode. Note that the following additional changes are required
in the `conf/upf.jsonc` file: `"measure_flow": true`, N3 interface set to
`"ifname": "access"` and N6 interface set to `"ifname": "core"`.
To install TRex onto your server, please refer to the
[TRex installation guide](https://trex-tgn.cisco.com/trex/doc/trex_manual.html#_download_and_installation)

### Steps
1. Update the following files accordingly to route traffic to the UPF and vice versa.
* `upf/ptf/.env` file updated with `UPF_ADDR` and `TREX_ADDR` parameters
* `upf/ptf/config/trex-cfg-for-ptf.yaml` file updated with proper values for
`interfaces`, `port_info`, and `platform` parameters
* `upf/ptf/tests/linerate/baseline.py` file updated with proper values for
`TREX_SRC_MAC` and `UPF_DEST_MAC`
* `upf/ptf/tests/linerate/mbr.py` file updated with proper values for
`BESS_CORE_MAC` and `BESS_ACCESS_MAC`
* `upf/ptf/tests/linerate/qos_metrics.py` file updated with proper values for
`UPF_DEST_MAC`
* `upf/ptf/tests/linerate/common.py` file updated with proper MAC address values
for `TREX_SRC_MAC`, `UPF_CORE_MAC`, and `UPF_ACCESS_MAC`

To install TRex onto your server, please refer to the [TRex installation
guide](https://trex-tgn.cisco.com/trex/doc/trex_manual.html#_download_and_installation)

### Steps
1. Generate BESS Python protobuf files for gRPC library and PTF
Dockerfile image build dependencies:
2. Generate BESS Python protobuf files for gRPC library and PTF Dockerfile image
build dependencies:
```bash
make build
```
2. Run PTF tests using the `run_tests` script:
3. Run PTF tests using the `run_tests` script:
```bash
sudo ./run_tests -t [test-dir] [optional: filename/filename.test_case]
./run_tests -t [test-dir] [optional: filename/filename.test_case]
```
### Examples
To run all test cases in the `unary/` directory:
```bash
sudo ./run_tests -t tests/unary
./run_tests -t tests/unary
```
To run a specific test case:
```bash
sudo ./run_tests -t tests/linerate/ baseline.DownlinkPerformanceBaselineTest
sudo ./run_tests -t tests/linerate/ mbr
sudo ./run_tests -t tests/linerate/ qos_metrics
./run_tests -t tests/linerate/ baseline.DownlinkPerformanceBaselineTest
./run_tests -t tests/linerate/ mbr
./run_tests -t tests/linerate/ qos_metrics
```
Note: If the above fails, `sudo` may be needed
2 changes: 1 addition & 1 deletion ptf/lib/ptf_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def set_up_trex_server(trex_daemon_client, trex_address, trex_config):
trex_daemon_client.start_stateless(cfg=trex_config_file_on_server)
except ConnectionRefusedError:
error(
"Unable to connect to server %s.\n" + "Did you start the Trex daemon?",
"Unable to connect to server %s. Did you start the Trex daemon?",
trex_address,
)
return False
Expand Down
46 changes: 13 additions & 33 deletions ptf/tests/linerate/baseline.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,7 @@
from trex_test import TrexTest
from trex_utils import *

#Source MAC address for DL traffic
TREX_SRC_MAC = "b4:96:91:b4:4b:09"
#Destination MAC address for DL traffic
UPF_DEST_MAC = "b4:96:91:b2:06:41"

# Port setup
TREX_SENDER_PORT = 1
BESS_SENDER_PORT = 1

# test specs
DURATION = 10
RATE = 100_000 # 100 Kpps
UE_COUNT = 10_000 # 10k UEs
PKT_SIZE = 64

from common import *

class DownlinkPerformanceBaselineTest(TrexTest, GrpcTest):
"""
Expand All @@ -38,21 +24,15 @@ class DownlinkPerformanceBaselineTest(TrexTest, GrpcTest):
@autocleanup
def runTest(self):
n3TEID = 0

app_ip = '10.128.4.22'
startIP = IPv4Address("16.0.0.1")
endIP = startIP + UE_COUNT - 1

accessIP = IPv4Address("198.19.0.1")
enbIP = IPv4Address("11.1.1.128") # arbitrary ip for nonexistent gnodeB
endIP = UE_IP_START + UE_COUNT - 1

# program UPF for downlink traffic by installing PDRs and FARs
print("Installing PDRs and FARs...")
for i in range(UE_COUNT):
# install N6 DL PDR to match UE dst IP
pdrDown = self.createPDR(
srcIface=CORE,
dstIP=int(startIP + i),
dstIP=int(UE_IP_START + i),
srcIfaceMask=0xFF,
dstIPMask=0xFFFFFFFF,
precedence=255,
Expand All @@ -71,8 +51,8 @@ def runTest(self):
applyAction=ACTION_FORWARD,
dstIntf=DST_ACCESS,
tunnelType=0x1,
tunnelIP4Src=int(accessIP),
tunnelIP4Dst=int(enbIP), # only one eNB to send to downlink
tunnelIP4Src=int(N3_IP),
tunnelIP4Dst=int(GNB_IP),
tunnelTEID=0,
tunnelPort=GTPU_PORT,
)
Expand All @@ -97,16 +77,16 @@ def runTest(self):
vm = STLVM()
vm.var(
name="dst",
min_value=str(startIP),
min_value=str(UE_IP_START),
max_value=str(endIP),
size=4,
op="random",
)
vm.write(fv_name="dst", pkt_offset="IP.dst")
vm.fix_chksum()

eth = Ether(dst=UPF_DEST_MAC, src=TREX_SRC_MAC)
ip = IP(src=app_ip, id=0)
eth = Ether(dst=UPF_CORE_MAC, src=TREX_SRC_MAC)
ip = IP(src=PDN_IP, id=0)
udp = UDP(sport=10002, dport=10001, chksum=0)
pkt = eth/ip/udp

Expand All @@ -121,21 +101,21 @@ def runTest(self):
# fail due to port DOWN state
time.sleep(20)

self.trex_client.add_streams(stream, ports=[BESS_SENDER_PORT])
self.trex_client.add_streams(stream, ports=[UPF_CORE_PORT])

print("Running traffic...")
s_time = time.time()
self.trex_client.start(
ports=[BESS_SENDER_PORT],
ports=[UPF_CORE_PORT],
mult="1",
duration=DURATION,
)
self.trex_client.wait_on_traffic(ports=[TREX_SENDER_PORT])
self.trex_client.wait_on_traffic(ports=[UPF_CORE_PORT])
print(f"Duration was {time.time() - s_time}")

trex_stats = self.trex_client.get_stats()
lat_stats = get_latency_stats(0, trex_stats)
flow_stats = get_flow_stats(0, trex_stats)
lat_stats = get_latency_stats(TREX_RECEIVER_PORT, trex_stats)
flow_stats = get_flow_stats(TREX_RECEIVER_PORT, trex_stats)

# Verify test results met baseline performance expectations

Expand Down
29 changes: 29 additions & 0 deletions ptf/tests/linerate/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2024 Intel Corporation

from ipaddress import IPv4Address

# MAC addresses
TREX_SRC_MAC = "b4:96:91:b4:4b:09" # Source MAC address for DL traffic
UPF_CORE_MAC = "b4:96:91:b2:06:41" # MAC address of N6 for the UPF/BESS
UPF_ACCESS_MAC = "b4:96:91:b2:06:40" # MAC address of N3 for the UPF/BESS

# Port setup
TREX_SENDER_PORT = 1
TREX_RECEIVER_PORT = 0
UPF_CORE_PORT = 1
UPF_ACCESS_PORT = 0

# test specs
DURATION = 10
RATE = 100_000 # 100 Kpps
UE_COUNT = 10_000 # 10k UEs
PKT_SIZE = 64
PKT_SIZE_L = 1400 # Packet size for MBR test

# IP addresses
UE_IP_START = IPv4Address("16.0.0.1")
GNB_IP = IPv4Address("11.1.1.129")
N3_IP = IPv4Address("198.18.0.1")
PDN_IP = IPv4Address("6.6.6.6") # Must be routable by route_control

Loading

0 comments on commit 82b7a1d

Please sign in to comment.