Skip to content

Commit 4c6214f

Browse files
Merge pull request #8 from etas-contrib/bot6abt/97445_itf_integration_test
Update ITF to latest from main branch commit e994cb6
2 parents 9f9730a + b9eb4c4 commit 4c6214f

File tree

19 files changed

+600
-198
lines changed

19 files changed

+600
-198
lines changed

MODULE.bazel

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ bazel_dep(name = "googletest", version = "1.17.0", dev_dependency = True)
6363
bazel_dep(name = "google_benchmark", version = "1.9.4", dev_dependency = True)
6464

6565
bazel_dep(name = "score_itf", version = "0.1.0")
66+
git_override(
67+
module_name = "score_itf",
68+
commit = "e994cb6", # Main branch with simplified QEMU plugin
69+
patch_strip = 1,
70+
patches = ["//third_party:score_itf_oci_conflict.patch"],
71+
remote = "https://github.com/eclipse-score/itf.git",
72+
)
6673

6774
# ============================================================================
6875
# Build System Rules

README.md

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,17 @@ bazel run //examples/car_window_sim:car_window_controller
4040
If you type `open` or `close` the command will be sent via network.
4141

4242

43-
### QEMU x86_64 - based integration test POC
43+
### QEMU x86_64 - based integration test and unit tests
4444

45-
For integration tests, a QEMU based approach was taken.
46-
A pytest based setup has been implemented connect to the QEMU instances and run integration and unit tests.
47-
For unit tests one QEMU instance is sufficient, for integration tests two instances are used to test the communication between two SOME/IP stacks via the gateway.A host bridge network is used to connect the QEMU instances with the host and with each other.
45+
For integration tests and unit tests, ITF framework is used, main branch commit e994cb6.
46+
For integration tests where the communication between two QEMU instances is required, a custom implementation is used to start and manage the QEMU instances within the test logic. This is because ITF does not support starting multiple QEMU instances in parallel yet.
4847

49-
Build the QEMU images and the dependant c++ binaries/ libraries / configuration files. Any change will be automatically detected.
48+
Start by building the QEMU images and the dependant c++ binaries/ libraries / configuration files. Any change will be automatically detected.
5049

5150
```sh
5251
bazel build //deployment/qemu:someip_gateway_ifs --config=x86_64-qnx
5352
```
54-
55-
The QEMU instances can be started manually if needed for debugging or development purposes.
53+
For the QEMU QNX x864 image to run on host please run the script deployment/qemu/setup_bridge.sh with sudo privileges to setup the required network bridge and tap interfaces.The QEMU instances can be started manually if needed for debugging or development purposes.
5654

5755
```sh
5856
bazel run //deployment/qemu:run_qemu_1 --config=x86_64-qnx
@@ -65,12 +63,41 @@ ssh root@192.168.87.2 -o StrictHostKeyChecking=no
6563
ssh root@192.168.87.3 -o StrictHostKeyChecking=no
6664
```
6765

68-
Those QEMU instances are pre-configured (IP addresses, multicast route, ...). The tests will start thhe required processes (gatewayd, someipd, example app) and then run the test logic.
66+
Those QEMU instances are pre-configured (IP addresses, multicast route, ...). The tests will start the required processes (gatewayd, someipd, example app) and then run the test logic.
67+
68+
Unit tests are defined by the bazel `test_ut` target:
69+
70+
```sh
71+
bazel test //tests/UT:test_ut --test_output=all --config=x86_64-qnx
72+
```
73+
74+
For Integration tests Host to QEMU communication:
75+
76+
```sh
77+
bazel test //tests/integration:test_qemu_network_single --test_output=all --config=x86_64-qnx
78+
```
79+
For integration tests QEMU to QEMU communication (dual instance test):
80+
81+
```sh
82+
bazel test //tests/integration:test_qemu_network_dual --test_output=all --config=x86_64-qnx
83+
```
84+
Execute SOMEIP SD tests:
85+
Execute in seperate terminals for each instance:
86+
87+
```sh
88+
deployment/qemu/setup_qemu_1.sh
89+
deployment/qemu/setup_qemu_2.sh
90+
```
91+
92+
Save the SOMEIP SD communication via tcpdump on the host `virbr0` interface:
6993

70-
The network traffic can be seen on the host via tcpdump on the host `virbr0` interface:
7194
```sh
7295
sudo tcpdump -i virbr0 -w someip_capture.pcap "host 192.168.87.2 or host 192.168.87.3"
7396
```
97+
Use Wireshark or provided utility analyze_pcap_someip.py to oberve the SOMEIP SD communication in the capture file.
98+
When finished use `pkill -9 qemu-system` to stop the QEMU instances.
99+
100+
//TODO: add python test to automatically check the SOMEIP SD communication in the pcap file and validate the expected behavior (e.g. correct service discovery, ...)
74101

75102
## QNX Build
76103

deployment/qemu/BUILD.bazel

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ pkg_tar(
5757
pkg_tar(
5858
name = "test_binaries_pkg",
5959
srcs = [
60-
"//tests/UT/UnitTest_UT:cpp_test_main",
60+
"//tests/UT/UnitTest_UT1:cpp_test_main1",
61+
"//tests/UT/UnitTest_UT2:cpp_test_main2",
6162
],
6263
include_runfiles = True,
6364
package_dir = "/",

deployment/qemu/setup_bridge.sh

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
#!/bin/bash
2+
# *******************************************************************************
3+
# Copyright (c) 2025 Contributors to the Eclipse Foundation
4+
#
5+
# See the NOTICE file(s) distributed with this work for additional
6+
# information regarding copyright ownership.
7+
#
8+
# This program and the accompanying materials are made available under the
9+
# terms of the Apache License Version 2.0 which is available at
10+
# https://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# SPDX-License-Identifier: Apache-2.0
13+
# *******************************************************************************
14+
15+
# Setup bridge networking for QEMU instances
16+
# This script creates a bridge (virbr0) and configures it for QEMU networking.
17+
#
18+
# Usage:
19+
# sudo ./setup_bridge.sh # Create bridge and configure it
20+
# sudo ./setup_bridge.sh teardown # Remove bridge and clean up
21+
#
22+
# Prerequisites:
23+
# - bridge-utils package (brctl command)
24+
# - iproute2 package (ip command)
25+
# - Linux kernel with bridging support
26+
# - Root privileges
27+
#
28+
# Network layout:
29+
# Bridge: virbr0
30+
# IP: 192.168.87.1/24
31+
# QEMU Instance 1: 192.168.87.2
32+
# QEMU Instance 2: 192.168.87.3
33+
#
34+
35+
36+
#WORK IN PROGRESS - initial version with bridge setup and TAP device creation for ITF compatibility.
37+
#USE IT at your own risk
38+
39+
set -euo pipefail
40+
41+
BRIDGE_NAME="virbr0"
42+
BRIDGE_IP="192.168.87.1"
43+
BRIDGE_NETMASK="255.255.255.0"
44+
45+
# TAP devices for ITF compatibility (manual TAP mode)
46+
# ITF expects pre-created tap devices passed via network_adapters
47+
# Note: tap-qemu2 not used - dual instance tests use QEMU bridge helper (auto-creates tapN)
48+
TAP_DEVICES=("tap-qemu1")
49+
TAP_USER="${SUDO_USER:-$(whoami)}"
50+
51+
# QEMU bridge helper path
52+
QEMU_BRIDGE_HELPER="/usr/lib/qemu/qemu-bridge-helper"
53+
QEMU_BRIDGE_ACL="/etc/qemu/bridge.conf"
54+
55+
print_usage() {
56+
echo "Usage: $0 [setup|teardown|status]"
57+
echo ""
58+
echo "Commands:"
59+
echo " setup - Create and configure bridge (default)"
60+
echo " teardown - Remove bridge and clean up"
61+
echo " status - Show bridge status"
62+
echo ""
63+
echo "Network Configuration:"
64+
echo " Bridge: ${BRIDGE_NAME}"
65+
echo " Bridge IP: ${BRIDGE_IP}/${BRIDGE_NETMASK}"
66+
echo " QEMU 1: 192.168.87.2"
67+
echo " QEMU 2: 192.168.87.3"
68+
}
69+
70+
check_root() {
71+
if [[ $EUID -ne 0 ]]; then
72+
echo "ERROR: This script must be run as root (sudo)"
73+
exit 1
74+
fi
75+
}
76+
77+
check_prerequisites() {
78+
local missing=0
79+
80+
if ! command -v brctl &>/dev/null && ! command -v ip &>/dev/null; then
81+
echo "ERROR: Neither brctl nor ip command found. Install bridge-utils or iproute2."
82+
missing=1
83+
fi
84+
85+
return $missing
86+
}
87+
88+
setup_bridge() {
89+
echo "=== Setting up bridge network: ${BRIDGE_NAME} ==="
90+
91+
# Check if bridge already exists
92+
if ip link show "${BRIDGE_NAME}" &>/dev/null; then
93+
echo "[INFO] Bridge ${BRIDGE_NAME} already exists, skipping creation"
94+
else
95+
echo "[INFO] Creating bridge ${BRIDGE_NAME}..."
96+
ip link add name "${BRIDGE_NAME}" type bridge
97+
ip link set "${BRIDGE_NAME}" up
98+
fi
99+
100+
# Configure bridge IP
101+
if ! ip addr show "${BRIDGE_NAME}" | grep -q "${BRIDGE_IP}"; then
102+
echo "[INFO] Configuring bridge IP: ${BRIDGE_IP}"
103+
ip addr add "${BRIDGE_IP}/${BRIDGE_NETMASK}" dev "${BRIDGE_NAME}"
104+
else
105+
echo "[INFO] Bridge IP ${BRIDGE_IP} already configured"
106+
fi
107+
108+
# Configure QEMU bridge helper ACL
109+
echo "[INFO] Configuring QEMU bridge helper..."
110+
mkdir -p "$(dirname "${QEMU_BRIDGE_ACL}")"
111+
if [[ ! -f "${QEMU_BRIDGE_ACL}" ]] || ! grep -q "allow ${BRIDGE_NAME}" "${QEMU_BRIDGE_ACL}" 2>/dev/null; then
112+
echo "allow ${BRIDGE_NAME}" >> "${QEMU_BRIDGE_ACL}"
113+
echo "[INFO] Added ${BRIDGE_NAME} to ${QEMU_BRIDGE_ACL}"
114+
fi
115+
116+
# Set bridge helper permissions (needs setuid for non-root QEMU)
117+
if [[ -f "${QEMU_BRIDGE_HELPER}" ]]; then
118+
chmod u+s "${QEMU_BRIDGE_HELPER}"
119+
echo "[INFO] Set setuid on ${QEMU_BRIDGE_HELPER}"
120+
else
121+
echo "[WARNING] QEMU bridge helper not found at ${QEMU_BRIDGE_HELPER}"
122+
echo " Install qemu-system-x86 package or run QEMU as root"
123+
fi
124+
125+
# Configure multicast support for SOME/IP Service Discovery
126+
# Disable IGMP snooping to allow multicast flooding between guests
127+
echo "[INFO] Configuring multicast support..."
128+
echo 0 > /sys/devices/virtual/net/${BRIDGE_NAME}/bridge/multicast_snooping
129+
echo "[INFO] Disabled IGMP snooping on ${BRIDGE_NAME}"
130+
131+
# Add multicast route through the bridge
132+
if ! ip route show | grep -q "224.0.0.0/4 dev ${BRIDGE_NAME}"; then
133+
ip route add 224.0.0.0/4 dev "${BRIDGE_NAME}" 2>/dev/null || true
134+
echo "[INFO] Added multicast route via ${BRIDGE_NAME}"
135+
else
136+
echo "[INFO] Multicast route already exists"
137+
fi
138+
139+
# Create persistent TAP devices for ITF compatibility
140+
# ITF uses manual TAP mode: -netdev tap,ifname=<tap>,script=no,downscript=no
141+
echo "[INFO] Creating persistent TAP devices for ITF..."
142+
for tap in "${TAP_DEVICES[@]}"; do
143+
if ip link show "${tap}" &>/dev/null; then
144+
echo "[INFO] TAP ${tap} already exists"
145+
else
146+
ip tuntap add dev "${tap}" mode tap user "${TAP_USER}"
147+
ip link set "${tap}" up
148+
ip link set "${tap}" master "${BRIDGE_NAME}"
149+
echo "[INFO] Created TAP ${tap} (owner: ${TAP_USER}) attached to ${BRIDGE_NAME}"
150+
fi
151+
done
152+
153+
echo ""
154+
echo "=== Bridge setup complete ==="
155+
show_status
156+
}
157+
158+
teardown_bridge() {
159+
echo "=== Tearing down bridge network: ${BRIDGE_NAME} ==="
160+
161+
# Remove TAP devices
162+
echo "[INFO] Removing TAP devices..."
163+
for tap in "${TAP_DEVICES[@]}"; do
164+
if ip link show "${tap}" &>/dev/null; then
165+
ip link set "${tap}" down
166+
ip tuntap del dev "${tap}" mode tap
167+
echo "[INFO] Removed TAP ${tap}"
168+
fi
169+
done
170+
171+
# Remove multicast route
172+
ip route del 224.0.0.0/4 dev "${BRIDGE_NAME}" 2>/dev/null || true
173+
174+
# Remove bridge
175+
if ip link show "${BRIDGE_NAME}" &>/dev/null; then
176+
echo "[INFO] Removing bridge ${BRIDGE_NAME}..."
177+
ip link set "${BRIDGE_NAME}" down
178+
ip link delete "${BRIDGE_NAME}" type bridge
179+
else
180+
echo "[INFO] Bridge ${BRIDGE_NAME} does not exist"
181+
fi
182+
183+
echo "=== Bridge teardown complete ==="
184+
}
185+
186+
show_status() {
187+
echo ""
188+
echo "=== Bridge Status ==="
189+
190+
if ip link show "${BRIDGE_NAME}" &>/dev/null; then
191+
echo "[OK] Bridge ${BRIDGE_NAME} exists"
192+
ip addr show "${BRIDGE_NAME}"
193+
echo ""
194+
echo "Connected interfaces:"
195+
brctl show "${BRIDGE_NAME}" 2>/dev/null || bridge link show master "${BRIDGE_NAME}" 2>/dev/null || echo " (none)"
196+
else
197+
echo "[NOT FOUND] Bridge ${BRIDGE_NAME} does not exist"
198+
echo "Run: sudo $0 setup"
199+
return 1
200+
fi
201+
202+
echo ""
203+
echo "QEMU bridge helper:"
204+
if [[ -f "${QEMU_BRIDGE_ACL}" ]]; then
205+
echo " ACL file: ${QEMU_BRIDGE_ACL}"
206+
cat "${QEMU_BRIDGE_ACL}"
207+
else
208+
echo " [WARNING] ${QEMU_BRIDGE_ACL} not found"
209+
fi
210+
211+
echo ""
212+
echo "TAP devices (for ITF):"
213+
for tap in "${TAP_DEVICES[@]}"; do
214+
if ip link show "${tap}" &>/dev/null; then
215+
state=$(ip -br link show "${tap}" | awk '{print $2}')
216+
echo " [OK] ${tap}: ${state}"
217+
else
218+
echo " [NOT FOUND] ${tap}"
219+
fi
220+
done
221+
222+
echo ""
223+
echo "To run QEMU with bridge networking:"
224+
echo " ./run_qemu.sh <IFS_IMAGE> 1"
225+
echo " ./run_qemu.sh <IFS_IMAGE> 2"
226+
echo ""
227+
echo "To use with ITF, configure network_adapters in your JSON:"
228+
echo ' "networks": [{"name": "tap-qemu1", ...}]'
229+
}
230+
231+
# Main
232+
case "${1:-setup}" in
233+
setup)
234+
check_root
235+
check_prerequisites
236+
setup_bridge
237+
;;
238+
teardown)
239+
check_root
240+
teardown_bridge
241+
;;
242+
status)
243+
show_status
244+
;;
245+
-h|--help|help)
246+
print_usage
247+
;;
248+
*)
249+
echo "Unknown command: $1"
250+
print_usage
251+
exit 1
252+
;;
253+
esac

0 commit comments

Comments
 (0)