diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 30a1e04a1..b6422a627 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -9,7 +9,7 @@ on: jobs: Test-in-Qemu: - #if: ${{ false }} # disable for now + if: ${{ false }} # disable for now runs-on: ubuntu-24.04 name: Test in Qemu (${{ matrix.distro }}) strategy: @@ -120,7 +120,7 @@ jobs: libpcre3-dev libssl-dev liblua5.1-0-dev kmod python3-pip libxml2-dev libxslt1-dev zlib1g-dev iproute2 ppp pppoe isc-dhcp-client timelimit && - (sudo pip3 install pytest pytest-dependency || sudo pip3 install --break-system-packages pytest pytest-dependency)" + (sudo pip3 install pytest pytest-dependency pytest-order || sudo pip3 install --break-system-packages pytest pytest-dependency pytest-order)" - name: Copy source code to target OS run: | tar -Jcf accel-ppp.tar.xz accel-ppp @@ -139,7 +139,7 @@ jobs: timeout-minutes: 5 run: > ssh -i ssh-key -p2222 user@localhost "cd accel-ppp/tests && - sudo python3 -m pytest -Wall -v -m \"not ipoe_driver and not vlan_mon_driver\"" + sudo python3 -m pytest -Wall --order-dependencies -v -m \"not ipoe_driver and not vlan_mon_driver\"" - name: Display processes and dmesg after tests if: ${{ always() }} run: > @@ -157,7 +157,7 @@ jobs: if: ${{ always() }} run: > ssh -i ssh-key -p2222 user@localhost "cd accel-ppp/tests && - sudo python3 -m pytest -Wall -v -m \"not vlan_mon_driver\"" + sudo python3 -m pytest -Wall --order-dependencies -v -m \"not vlan_mon_driver\"" - name: Display processes and dmesg after tests if: ${{ always() }} run: > @@ -174,15 +174,145 @@ jobs: timeout-minutes: 5 run: > ssh -i ssh-key -p2222 user@localhost "cd accel-ppp/tests && - sudo python3 -m pytest -Wall -v" + sudo python3 -m pytest -Wall --order-dependencies -v" - name: Display processes and dmesg after tests if: ${{ always() }} run: > ssh -i ssh-key -p2222 user@localhost "ps aux | grep accel- && sudo dmesg" - Test-in-GH: + Test-in-Alpine: #if: ${{ false }} # disable for now + runs-on: ubuntu-24.04 + name: Test in Qemu (Alpine) + + steps: + - name: Check out repository code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + path: "accel-ppp" + - name: Install qemu and required tools + run: > + sudo apt update && + NEEDRESTART_SUSPEND=1 DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true sudo -E apt -y install qemu-system-x86 qemu-utils cloud-image-utils cpu-checker cloud-image-utils wget openssh-client screen + - name: Check kvm support + run: sudo kvm-ok + - name: Prepare cloud-init image disk + run: | + ssh-keygen -t ed25519 -q -N "" -f ssh-key + echo "instance-id: $(uuidgen || echo i-abcdefg)" > init-meta + echo "#cloud-config" > init-data + echo "package_update: true" >> init-data + echo "package_upgrade: true" >> init-data + echo "package_reboot_if_required: false" >> init-data + echo "users:" >> init-data + echo " - default" >> init-data + echo " - name: alpine" >> init-data + echo " shell: /bin/bash" >> init-data + echo " ssh_authorized_keys:" >> init-data + echo " - "`cat ssh-key.pub` >> init-data + echo "power_state:">> init-data + echo " mode: poweroff">> init-data + cat init-data + cloud-localds init.img init-data init-meta + - name: Download and resize target OS cloud image + run: | + mkdir img + # we need to use metal image because virt image doesn't provide pppoe driver (https://gitlab.alpinelinux.org/alpine/aports/-/issues/13739) + wget -nv https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/cloud/nocloud_alpine-3.20.2-x86_64-bios-cloudinit-metal-r0.qcow2 -O img/image + qemu-img resize -f qcow2 img/`ls -1 img` +2G + - name: Run target OS first time (for cloud-init actions) + run: sudo qemu-system-x86_64 -enable-kvm -cpu host -m 4096 -nographic -drive format=qcow2,file=img/`ls -1 img` -drive format=raw,file=init.img + - name: Run target OS + run: sudo screen -dmS qemu qemu-system-x86_64 -enable-kvm -cpu host -net nic -net user,hostfwd=tcp::2222-:22 -m 4096 -nographic -drive format=qcow2,file=img/`ls -1 img` + - name: Check that target OS is running + run: | + sleep 1 + sudo screen -ls + - name: Wait for ssh connection + timeout-minutes: 30 + run: > + while ! ssh -o StrictHostKeyChecking=accept-new -p2222 -o ConnectTimeout=5 -i ssh-key alpine@localhost "exit 0"; + do + echo "Trying to establish ssh connection"; + sleep 5; + done; + cat ~/.ssh/known_hosts + - name: Display free space, current dir, kernel version and test doas + run: | + ssh -i ssh-key -p2222 alpine@localhost "df -h" + ssh -i ssh-key -p2222 alpine@localhost "pwd" + ssh -i ssh-key -p2222 alpine@localhost "uname -a" + ssh -i ssh-key -p2222 alpine@localhost "doas cat /etc/passwd" + - name: Install build tools (on target OS) + run: > + ssh -i ssh-key -p2222 alpine@localhost "doas apk add --no-cache git cmake make g++ pcre-dev libressl-dev linux-headers libucontext-dev lua5.1-dev linux-lts-dev py3-pip + ppp ppp-pppoe && + (doas pip3 install pytest pytest-dependency pytest-order || doas pip3 install --break-system-packages pytest pytest-dependency pytest-order)" + - name: Copy source code to target OS + run: | + tar -Jcf accel-ppp.tar.xz accel-ppp + scp -i ssh-key -P2222 accel-ppp.tar.xz alpine@localhost: + ssh -i ssh-key -p2222 alpine@localhost "tar -xf accel-ppp.tar.xz" + - name: Build accel-ppp + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp && + mkdir build && cd build && + cmake -DBUILD_IPOE_DRIVER=TRUE -DBUILD_VLAN_MON_DRIVER=TRUE -DCMAKE_INSTALL_PREFIX=/usr + -DKDIR=/usr/src/linux-headers-\`uname -r\` + -DLUA=TRUE -DSHAPER=TRUE -DRADIUS=TRUE .. && + make && doas make install" + + - name: Run tests (not related to ipoe and vlan_mon drivers) + timeout-minutes: 5 + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp/tests && + doas python3 -m pytest -Wall --order-dependencies -v -m \"not ipoe_driver and not vlan_mon_driver\"" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: > + ssh -i ssh-key -p2222 alpine@localhost "ps aux | grep accel- && + doas dmesg" + + - name: Insert ipoe kernel module + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp && + doas insmod build/drivers/ipoe/driver/ipoe.ko && + lsmod | grep ipoe " + + - name: Run tests (not related to vlan_mon drivers) + timeout-minutes: 5 + if: ${{ always() }} + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp/tests && + doas python3 -m pytest -Wall --order-dependencies -v -m \"not vlan_mon_driver\"" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: > + ssh -i ssh-key -p2222 alpine@localhost "ps aux | grep accel- && + doas dmesg" + + - name: Insert vlan_mon kernel module + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp && + doas insmod build/drivers/vlan_mon/driver/vlan_mon.ko && + lsmod | grep vlan_mon" + + - name: Run tests (all) + timeout-minutes: 5 + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp/tests && + doas python3 -m pytest -Wall --order-dependencies -v" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: > + ssh -i ssh-key -p2222 alpine@localhost "ps aux | grep accel- && + doas dmesg" + + + Test-in-GH: + if: ${{ false }} # disable for now strategy: fail-fast: false matrix: @@ -200,7 +330,7 @@ jobs: - name: Install testing tools (using pip) run: > - sudo pip3 install pytest pytest-dependency || sudo pip3 install --break-system-packages pytest pytest-dependency + sudo pip3 install pytest pytest-dependency pytest-order || sudo pip3 install --break-system-packages pytest pytest-dependency pytest-order - name: Check out repository code uses: actions/checkout@v4 @@ -232,10 +362,10 @@ jobs: - name: Run tests timeout-minutes: 5 working-directory: ./tests - run: sudo python3 -m pytest -Wall -v + run: sudo python3 -m pytest -Wall --order-dependencies -v Test-in-GH-Coverage: - #if: ${{ false }} # disable for now + if: ${{ false }} # disable for now strategy: fail-fast: false matrix: @@ -253,7 +383,7 @@ jobs: - name: Install testing tools (using pip) run: > - sudo pip3 install pytest pytest-dependency gcovr || sudo pip3 install --break-system-packages pytest pytest-dependency gcovr + sudo pip3 install pytest pytest-dependency pytest-order gcovr || sudo pip3 install --break-system-packages pytest pytest-dependency pytest-order gcovr - name: Check out repository code uses: actions/checkout@v4 @@ -286,7 +416,7 @@ jobs: - name: Run tests (for coverage report) (fail is ok) timeout-minutes: 5 working-directory: ./tests - run: sudo python3 -m pytest -Wall -v || exit 0 + run: sudo python3 -m pytest -Wall --order-dependencies -v || exit 0 - name: Generate coverage reports (default(txt), csv, html) run: | diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c index dd623accb..8678db800 100644 --- a/accel-pppd/ctrl/pppoe/pppoe.c +++ b/accel-pppd/ctrl/pppoe/pppoe.c @@ -1394,6 +1394,8 @@ static void pppoe_add_interface_re(const char *opt, void *cli) re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL); if (!re) { + if (cli) + cli_sendv(cli, "pppoe: %s at %i\r\n", pcre_err, pcre_offset); log_error("pppoe: %s at %i\r\n", pcre_err, pcre_offset); return; } diff --git a/tests/README.md b/tests/README.md index d062ed469..689a16d8f 100644 --- a/tests/README.md +++ b/tests/README.md @@ -6,7 +6,7 @@ These tests are done for Ubuntu and Debian distros. Please use latest stable Deb Install pytest -Using apt: `sudo apt install python3-pytest python3-pytest-dependency` or using pip: `sudo pip3 install pytest pytest-dependency`. +Using apt: `sudo apt install python3-pytest python3-pytest-dependency python3-pytest-order` or using pip: `sudo pip3 install pytest pytest-dependency pytest-order`. pytest-dependency version must be >= 0.5 (with 'scope' support) @@ -43,13 +43,13 @@ sudo insmod build/drivers/ipoe/driver/ipoe.ko ```bash # from this dir (tests) -sudo python3 -m pytest -Wall -v +sudo python3 -m pytest -Wall --order-dependencies -v ``` To skip tests related to ipoe and vlan_mon kernel modules: ```bash # from this dir (tests) -sudo python3 -m pytest -Wall -v -m "not ipoe_driver and not vlan_mon_driver" +sudo python3 -m pytest -Wall --order-dependencies -v -m "not ipoe_driver and not vlan_mon_driver" ``` ## Preparations (for coverage report) @@ -83,7 +83,7 @@ Then insert kernel modules (ipoe.ko and vlan-mon.ko) ```bash # from root dir (parent for this dir) -sudo python3 -m pytest -Wall tests -v # execute tests to collect coverage data +sudo python3 -m pytest -Wall --order-dependencies tests -v # execute tests to collect coverage data mkdir tests/report gcovr --config=tests/gcovr.conf # default report gcovr --config=tests/gcovr.conf --csv # csv report diff --git a/tests/accel-pppd/test_basic.py b/tests/accel-pppd/general/test_basic.py similarity index 99% rename from tests/accel-pppd/test_basic.py rename to tests/accel-pppd/general/test_basic.py index 2b2c6f719..fe2f80931 100644 --- a/tests/accel-pppd/test_basic.py +++ b/tests/accel-pppd/general/test_basic.py @@ -19,9 +19,11 @@ def accel_pppd_config(): log_tcp #log_pgsql + connlimit pptp l2tp sstp + radius pppoe ipoe @@ -30,7 +32,6 @@ def accel_pppd_config(): auth_chap_md5 auth_pap - radius chap-secrets ippool @@ -38,8 +39,7 @@ def accel_pppd_config(): pppd_compat shaper #net-snmp - logwtmp - connlimit + #logwtmp ipv6_nd ipv6_dhcp diff --git a/tests/accel-pppd/general/test_pcre_negative_cases.py b/tests/accel-pppd/general/test_pcre_negative_cases.py new file mode 100644 index 000000000..788b606a7 --- /dev/null +++ b/tests/accel-pppd/general/test_pcre_negative_cases.py @@ -0,0 +1,65 @@ +import pytest +from common import process + + +@pytest.fixture() +def accel_pppd_config(): + return """ + [modules] + radius + pppoe + + [core] + log-error=/dev/stderr + + [log] + log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr + level=5 + + [cli] + tcp=127.0.0.1:2001 + + [radius] + + [pppoe] + """ + + +# test pcre-related negative cases +def test_pcre_negative_cases(accel_pppd_instance, accel_cmd): + + # test that accel-pppd started successfully + assert accel_pppd_instance + + (exit_sh_sess, out_sh_sess, err_sh_sess) = process.run([accel_cmd, "show sessions match username 00("]) + # test that 'show sessions' with invalid regexp reports the issue and error position + assert ( + exit_sh_sess == 0 + and len(out_sh_sess) > 0 + and err_sh_sess == "" + and "match: " in out_sh_sess + and "at 3" in out_sh_sess + ) + + + (exit_iface_add, out_iface_add, err_iface_add) = process.run([accel_cmd, "pppoe interface add re:000("]) + # test that 'pppoe interface add' with invalid regexp reports the issue and error position + assert ( + exit_iface_add == 0 + and len(out_iface_add) > 0 + and err_iface_add == "" + and "pppoe: " in out_iface_add + and "at 4" in out_iface_add + ) + + (exit_term, out_term, err_term) = process.run([accel_cmd, "terminate match username 00("]) + # test that 'terminate' with invalid regexp reports the issue and error position + assert ( + exit_term == 0 + and len(out_term) > 0 + and err_term == "" + and "match: " in out_term + and "at 3" in out_term + ) diff --git a/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_wo_auth.py b/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_wo_auth.py index 104e4e9b7..7ebb420a3 100644 --- a/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_wo_auth.py +++ b/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_wo_auth.py @@ -9,7 +9,8 @@ def accel_pppd_config(veth_pair_netns): return ( """ [modules] - pppoe + connlimit + radius ipoe ippool @@ -20,16 +21,23 @@ def accel_pppd_config(veth_pair_netns): [cli] tcp=127.0.0.1:2001 + [core] + log-error=/dev/stderr + [log] log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr level=5 + [radius] + [ipoe] noauth=1 shared=1 gw-ip-address=192.0.2.1/24 - interface=""" - + veth_pair_netns["veth_a"] + interface=re:.""" + + veth_pair_netns["veth_a"][1:] ) diff --git a/tests/accel-pppd/pppoe/test_pppoe_disc.py b/tests/accel-pppd/pppoe/test_pppoe_disc.py index eb069c42c..64a0d295a 100644 --- a/tests/accel-pppd/pppoe/test_pppoe_disc.py +++ b/tests/accel-pppd/pppoe/test_pppoe_disc.py @@ -8,15 +8,23 @@ def accel_pppd_config(veth_pair_netns): return ( """ [modules] + radius pppoe + [core] + log-error=/dev/stderr + [log] log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr level=5 [cli] tcp=127.0.0.1:2001 + [radius] + [pppoe] ac-name=test-accel interface=""" diff --git a/tests/accel-pppd/pppoe/test_pppoe_pado_delay.py b/tests/accel-pppd/pppoe/test_pppoe_pado_delay.py index 96c73bf87..3a93d9208 100644 --- a/tests/accel-pppd/pppoe/test_pppoe_pado_delay.py +++ b/tests/accel-pppd/pppoe/test_pppoe_pado_delay.py @@ -30,15 +30,23 @@ def accel_pppd_config(veth_pair_netns): return ( """ [modules] + radius pppoe + [core] + log-error=/dev/stderr + [log] log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr level=5 [cli] tcp=127.0.0.1:2001 + [radius] + [pppoe] ac-name=test-accel pado-delay=1500 diff --git a/tests/accel-pppd/pppoe/test_pppoe_session_wo_auth.py b/tests/accel-pppd/pppoe/test_pppoe_session_wo_auth.py index 0c8aa2c07..822ef7b87 100644 --- a/tests/accel-pppd/pppoe/test_pppoe_session_wo_auth.py +++ b/tests/accel-pppd/pppoe/test_pppoe_session_wo_auth.py @@ -9,12 +9,18 @@ def accel_pppd_config(veth_pair_netns): return ( """ [modules] + radius pppoe auth_pap ippool + [core] + log-error=/dev/stderr + [log] log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr level=5 [auth] @@ -27,6 +33,8 @@ def accel_pppd_config(veth_pair_netns): [cli] tcp=127.0.0.1:2001 + [radius] + [pppoe] interface=""" + veth_pair_netns["veth_a"] @@ -47,7 +55,7 @@ def pppd_config(veth_pair_netns): mtu 1492 noaccomp default-asyncmap - plugin rp-pppoe.so + plugin pppoe.so user loginAB password pass123 nic-""" @@ -69,7 +77,7 @@ def test_pppoe_session_wo_auth(pppd_instance, accel_cmd): (exit, out, err) = process.run( [ accel_cmd, - "show sessions match username loginAB username,ip,state", + "show sessions match username log.nAB username,ip,state", ] ) assert exit == 0 # accel-cmd fails diff --git a/tests/accel-pppd/pppoe/test_pppoe_vlan_mon.py b/tests/accel-pppd/pppoe/test_pppoe_vlan_mon.py index 670abc330..e6e9f48a7 100644 --- a/tests/accel-pppd/pppoe/test_pppoe_vlan_mon.py +++ b/tests/accel-pppd/pppoe/test_pppoe_vlan_mon.py @@ -13,15 +13,23 @@ def accel_pppd_config(veth_pair_netns): print(veth_pair_netns) return """ [modules] + radius pppoe + [core] + log-error=/dev/stderr + [log] log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr level=5 [cli] tcp=127.0.0.1:2001 + [radius] + [pppoe] ac-name=test-accel vlan-mon=%s,10-20