Skip to content

Ethernet Test: Dynamic Interface Detection and Robust CI Validation #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Runner/plans/meta-qcom_PreMerge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ metadata:
run:
steps:
- cd Runner
- $PWD/suites/Connectivity/Ethernet/run.sh || true
- $PWD/utils/send-to-lava.sh $PWD/suites/Connectivity/Ethernet/Ethernet.res || true
- $PWD/suites/Kernel/FunctionalArea/baseport/adsp_remoteproc/run.sh || true
- $PWD/utils/send-to-lava.sh $PWD/suites/Kernel/FunctionalArea/baseport/adsp_remoteproc/adsp_remoteproc.res || true
- $PWD/suites/Kernel/FunctionalArea/baseport/cdsp_remoteproc/run.sh || true
Expand All @@ -36,6 +38,4 @@ run:
- $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioRecord/AudioRecord.res || true
- $PWD/suites/Connectivity/Bluetooth/run.sh || true
- $PWD/utils/send-to-lava.sh $PWD/suites/Connectivity/Bluetooth/Bluetooth.res || true
- $PWD/suites/Connectivity/Ethernet/run.sh || true
- $PWD/utils/send-to-lava.sh $PWD/suites/Connectivity/Ethernet/Ethernet.res || true
- $PWD/utils/result_parse.sh
13 changes: 12 additions & 1 deletion Runner/suites/Connectivity/Ethernet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ cd <this-repo>
scp -r common Runner user@target_device_ip:<Path in device>
ssh user@target_device_ip
cd <Path in device>/Runner && ./run-test.sh Ethernet
# Optional: specify preferred interface (e.g., eth1)
./run.sh [preferred-interface]
```

## Prerequisites
Expand All @@ -53,5 +55,14 @@ Test result will be saved in `Ethernet.res` as:
## Output
A .res file is generated in the same directory:

`PASS Ethernet` OR `FAIL Ethernet`
`Ethernet PASS` OR `Ethernet FAIL`

## Sample Log
```
Output

[INFO] 2025-06-11 10:12:23 - Detected Ethernet interface: enP1p4s0u1u1
[PASS] 2025-06-11 10:12:30 - enP1p4s0u1u1 is UP
[INFO] 2025-06-11 10:12:31 - Assigned IP: 10.0.0.55
[PASS] 2025-06-11 10:12:35 - Ping successful on enP1p4s0u1u1
```
161 changes: 102 additions & 59 deletions Runner/suites/Connectivity/Ethernet/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,90 +3,133 @@
#Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
#SPDX-License-Identifier: BSD-3-Clause-Clear

# Source init_env and functestlib.sh
# Robustly find and source init_env
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
INIT_ENV=""
SEARCH="$SCRIPT_DIR"

while [ "$SEARCH" != "/" ]; do
if [ -f "$SEARCH/init_env" ]; then
INIT_ENV="$SEARCH/init_env"
break
fi
SEARCH=$(dirname "$SEARCH")
done

if [ -z "$INIT_ENV" ]; then
echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2
exit 1
fi

# shellcheck disable=SC1090
. "$INIT_ENV"

if [ -z "$__INIT_ENV_LOADED" ]; then
# shellcheck disable=SC1090
. "$INIT_ENV"
fi
# shellcheck disable=SC1090,SC1091
. "$TOOLS/functestlib.sh"

TESTNAME="Ethernet"
test_path=$(find_test_case_by_name "$TESTNAME") || {
log_fail "$TESTNAME : Test directory not found."
echo "FAIL $TESTNAME" > "./$TESTNAME.res"
exit 1
}

test_path=$(find_test_case_by_name "$TESTNAME")
cd "$test_path" || exit 1
res_file="./$TESTNAME.res"
rm -f "$res_file"
summary_file="./$TESTNAME.summary"
rm -f "$res_file" "$summary_file"

log_info "--------------------------------------------------------------------------"
log_info "-------------------Starting $TESTNAME Testcase----------------------------"


# Check for dependencies
check_dependencies ip ping

IFACE="eth0"
RETRIES=3
SLEEP_SEC=3

# Check interface existence
if ! ip link show "$IFACE" >/dev/null 2>&1; then
log_fail "Ethernet interface $IFACE not found"
echo "FAIL $TESTNAME" > "$res_file"
exit 1

# User-specified interface (argument) or all detected
user_iface="$1"
if [ -n "$user_iface" ]; then
ETH_IFACES="$user_iface"
log_info "User specified interface: $user_iface"
else
ETH_IFACES="$(get_ethernet_interfaces)"
log_info "Auto-detected Ethernet interfaces: $ETH_IFACES"
fi

# Bring up interface with retries
log_info "Ensuring $IFACE is UP..."
i=0
while [ $i -lt $RETRIES ]; do
ip link set "$IFACE" up
sleep "$SLEEP_SEC"
if ip link show "$IFACE" | grep -q "state UP"; then
log_info "$IFACE is UP"
break

if [ -z "$ETH_IFACES" ]; then
log_warn "No Ethernet interfaces detected."
echo "No Ethernet interfaces detected." >> "$summary_file"
echo "$TESTNAME SKIP" > "$res_file"
Copy link
Contributor

Choose a reason for hiding this comment

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

is it not a failure if /sys/class/net/ is not having any ethernet interfaces

Copy link
Contributor Author

Choose a reason for hiding this comment

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

is it not a failure if /sys/class/net/ is not having any ethernet interfaces

Reason for SKIP:
If the device or platform does not have any Ethernet hardware (i.e., a WiFi-only board, or platform without an Ethernet PHY/port), marking the test as FAIL is misleading—it’s not a test failure, but a non-applicable scenario.

Test Meaning:
SKIP means “test was not applicable or could not be performed due to missing prerequisites.”
FAIL means “test was run, prerequisites were met, but the result did not match expectations.”

exit 0
fi

any_passed=0
any_tested=0

for iface in $ETH_IFACES; do
log_info "---- Testing interface: $iface ----"

if ! is_interface_up "$iface"; then
log_warn "$iface is DOWN, skipping"
echo "$iface: SKIP (down/no cable)" >> "$summary_file"
Copy link
Contributor

Choose a reason for hiding this comment

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

i see an entry to check the cable aswell.
Do you think it is required to add that aswell
sh-5.2# cat /sys/class/net/eth0/carrier
0
0 - if cable is not present

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i see an entry to check the cable aswell. Do you think it is required to add that aswell sh-5.2# cat /sys/class/net/eth0/carrier 0 0 - if cable is not present

As far as I know, it is not needed. Lava CI debugging is happening only on the serial logs, and no other device logs will be seen. The stdout is sufficient for debugging.

Copy link
Contributor

Choose a reason for hiding this comment

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

You can save additional logs if required. This is done over networks, so if there is no network it won't work. Example here https://github.com/Linaro/test-definitions/blob/master/automated/utils/upload-to-artifactorial.sh

I'd say if the additional debugging is helpful for manual testing it should be kept.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What additional logs are required for debugging? I can save them to the location. If dmesg logs are sufficient to debug the initial failures, which are already available in the job.

Copy link
Contributor

Choose a reason for hiding this comment

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

There is no mandatory requirement. Additional debug should be something useful from your pov or sth requested by maintainers. What I'm trying to say is that you can include the $summary_file in the code. There is no harm doing that. If it's not used in LAVA that's OK.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The summary_file will still be available, it is not being removed. We can capture everything needed from network maintainers to log into the summary based on the requirements.

continue
fi

ip_addr=$(get_ip_address "$iface")
if [ -z "$ip_addr" ]; then
if try_dhcp_client_safe "$iface" 10; then
ip_addr=$(get_ip_address "$iface")
log_info "$iface obtained IP after DHCP: $ip_addr"
fi
fi

if [ -z "$ip_addr" ]; then
log_warn "$iface did not obtain an IP address after DHCP attempt, skipping"
echo "$iface: SKIP (no IP, DHCP failed)" >> "$summary_file"
continue
fi

if echo "$ip_addr" | grep -q '^169\.254'; then
log_warn "$iface got only link-local IP ($ip_addr), skipping"
echo "$iface: SKIP (link-local only: $ip_addr)" >> "$summary_file"
continue
fi

log_pass "$iface is UP"
log_info "$iface got IP: $ip_addr"

any_tested=1
retries=3
pass=0
for i in $(seq 1 $retries); do
if ping -I "$iface" -c 4 -W 2 8.8.8.8 >/dev/null 2>&1; then
log_pass "Ethernet connectivity verified via ping"
echo "$iface: PASS (IP: $ip_addr, ping OK)" >> "$summary_file"
pass=1
any_passed=1
break
else
log_warn "Ping failed for $iface (attempt $i/$retries)"
sleep 2
fi
done

if [ "$pass" -eq 0 ]; then
log_fail "Ping test failed for $iface"
echo "$iface: FAIL (IP: $ip_addr, ping failed)" >> "$summary_file"
fi
log_warn "$IFACE is still DOWN (attempt $((i + 1))/$RETRIES)..."
i=$((i + 1))
done

if [ $i -eq $RETRIES ]; then
log_fail "Failed to bring up $IFACE after $RETRIES attempts"
echo "FAIL $TESTNAME" > "$res_file"

log_info "---- Ethernet Interface Test Summary ----"
if [ -f "$summary_file" ]; then
cat "$summary_file"
else
log_info "No summary information recorded."
fi

if [ "$any_passed" -gt 0 ]; then
echo "$TESTNAME PASS" > "$res_file"
exit 0
elif [ "$any_tested" -gt 0 ]; then
echo "$TESTNAME FAIL" > "$res_file"
exit 1
else
log_warn "No interfaces were tested (all were skipped)."
echo "No suitable Ethernet interfaces found. All were down, link-local, or failed to get IP." >> "$summary_file"
echo "$TESTNAME SKIP" > "$res_file"
exit 0
fi

# Ping test with retries
log_info "Running ping test to 8.8.8.8 via $IFACE..."
i=0
while [ $i -lt $RETRIES ]; do
if ping -I "$IFACE" -c 4 -W 2 8.8.8.8 >/dev/null 2>&1; then
log_pass "Ethernet connectivity verified via ping"
echo "PASS $TESTNAME" > "$res_file"
exit 0
fi
log_warn "Ping failed (attempt $((i + 1))/$RETRIES)... retrying"
sleep "$SLEEP_SEC"
i=$((i + 1))
done

log_fail "Ping test failed after $RETRIES attempts"
echo "FAIL $TESTNAME" > "$res_file"
exit 1
Loading
Loading