Skip to content

Commit 0bd4834

Browse files
authored
Fix tests to work with out of source builds. (#1926)
* Update Packet++ tests to work with out of source builds. * Updated Pcap++ to work with out of source builds. * Lint * Fix unix run_tests. * args fixes. * fix typo * updated build dir name. * changed build dir to a flag. * Fix path errors by resolving to absolute path before sending to subprocess. * Lint * Update github actions to utilize working_directory. * Fix windivert to copy to binary directory. * Refactory run_tests_windows to mimic run_tests. * Remove duplicate find_interface call. * Add build dir to windows ci runs. * Fix missed Bin. * Fix f-string ambiguity. * Make path absolute before passing to subprocess. * Fix f-string. * Fix cmd argument, * Fix run command. * Update mingw run_tests args. * Fix windivert args. * Try converting path to string before passing to subprocess.run()? * Changed subprocess.run to use non-shell environment and utilize integrated success check. * Simplify run_tests_windows. * Add overrides for executable locations to allow easier local testing. * Update Windows coverage results location as they are now generated in the build directory. * Remove shell flag from subprocess call. * Add __future__ annotations to enable lazy annotation evaluation. * Lint * Add logging info to help debugging. * Add .exe to windows exe paths. * Fix typo. * Add overrides for Visual Studio as its is a multi-config generator. * Fixup coverage report location. * Fix run. * Revert shell. * Fixup Popen arguments. * Pass shell=True. * Fix command line option generation for include tests and skip tests. * Lint * Fix command. * Lint. * Update run_tests_windows from base. * Add factory for tests lists. Fix duplicate TCP command. * Update run commands. * Remove hard coded path. * Lint * Update new CI job. * Set logging to always log info.
1 parent e92b7f9 commit 0bd4834

7 files changed

Lines changed: 209 additions & 117 deletions

File tree

.github/workflows/build_and_test.yml

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ jobs:
131131
- name: Test PcapPlusPlus
132132
run: |
133133
. .venv/bin/activate
134-
python3 ci/run_tests/run_tests.py --interface eth0 ${{ matrix.additional-test-flags }}
134+
python3 ci/run_tests/run_tests.py --interface eth0 ${{ matrix.additional-test-flags }} --build-dir "$BUILD_DIR"
135135
136136
- name: Test Examples
137137
run: |
@@ -216,7 +216,7 @@ jobs:
216216
- name: Test PcapPlusPlus
217217
run: |
218218
. .venv/bin/activate
219-
python3 ci/run_tests/run_tests.py --interface eth0 --test-suites "packet"
219+
python3 ci/run_tests/run_tests.py --interface eth0 --test-suites "packet" --build-dir "$BUILD_DIR"
220220
221221
- name: Check installation
222222
run: |
@@ -286,7 +286,7 @@ jobs:
286286
- name: Test PcapPlusPlus
287287
run: |
288288
. .venv/bin/activate
289-
python3 ci/run_tests/run_tests.py --interface eth0
289+
python3 ci/run_tests/run_tests.py --interface eth0 --build-dir "$BUILD_DIR"
290290
291291
- name: Check installation
292292
run: |
@@ -347,9 +347,8 @@ jobs:
347347

348348
- name: Test Packet++
349349
if: env.avx512 == 'true'
350-
run: |
351-
cd Tests/Packet++Test
352-
Bin/Packet++Test
350+
run: ./Packet++Test
351+
working-directory: ${{ github.workspace }}/${{ env.BUILD_DIR }}/Tests/Packet++Test
353352

354353
- name: Tests skipped (no AVX-512 hardware support)
355354
if: env.avx512 == 'false'
@@ -403,14 +402,12 @@ jobs:
403402
run: cmake --build "$BUILD_DIR" -j
404403

405404
- name: Test Packet++
406-
run: |
407-
cd Tests/Packet++Test
408-
Bin/Packet++Test
405+
run: ./Packet++Test
406+
working-directory: ${{ github.workspace }}/${{ env.BUILD_DIR }}/Tests/Packet++Test
409407

410408
- name: Test Pcap++
411-
run: |
412-
cd Tests/Pcap++Test
413-
Bin/Pcap++Test -n
409+
run: ./Pcap++Test -n
410+
working-directory: ${{ github.workspace }}/${{ env.BUILD_DIR }}/Tests/Pcap++Test
414411

415412
- name: Check installation
416413
run: |
@@ -505,7 +502,7 @@ jobs:
505502
if: ${{ matrix.host-arch == matrix.arch }}
506503
run: |
507504
. .venv/bin/activate
508-
python ci/run_tests/run_tests.py --interface en0
505+
python ci/run_tests/run_tests.py --interface en0 --build-dir "$BUILD_DIR"
509506
510507
- name: Test Examples
511508
if: ${{ matrix.host-arch == matrix.arch }}
@@ -645,7 +642,7 @@ jobs:
645642
- name: Test PcapPlusPlus
646643
run: |
647644
python -m pip install -r ci\run_tests\requirements.txt
648-
python ci\run_tests\run_tests_windows.py
645+
python ci\run_tests\run_tests_windows.py --build-dir $env:BUILD_DIR
649646
650647
- name: Test Examples
651648
run: |
@@ -730,6 +727,8 @@ jobs:
730727
echo "ZSTD_HOME_PARAM=-z C:\zstd" >> $env:GITHUB_ENV
731728
if: matrix.use_zstd == true
732729

730+
# The visual studio generator is a multi-config generator. This means that the executable will be in a configuration subfolder (e.g., Debug or Release),
731+
# relative to the target folder. Example: $(BuildDir)/Test/Packet++Test/Debug/Packet++Test.exe
733732
- name: Configure PcapPlusPlus
734733
run: cmake -A ${{ matrix.arch }} -G "${{ matrix.platform }}" -DPCAP_ROOT=${{ env.PCAP_SDK_DIR }} -S . -B "$env:BUILD_DIR"
735734

@@ -742,7 +741,7 @@ jobs:
742741
- name: Test PcapPlusPlus
743742
run: |
744743
python -m pip install -r ci\run_tests\requirements.txt
745-
python ci\run_tests\run_tests_windows.py --coverage
744+
python ci\run_tests\run_tests_windows.py --coverage --build-dir $env:BUILD_DIR --packet-test-exe "Tests/Packet++Test/Debug/Packet++Test.exe" --pcap-test-exe "Tests/Pcap++Test/Debug/Pcap++Test.exe"
746745
747746
- name: Test Examples
748747
run: |
@@ -754,7 +753,7 @@ jobs:
754753
- name: Upload Coverage Results
755754
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
756755
with:
757-
files: ./Tests/Pcap++Test/Pcap++Coverage.xml,./Tests/Packet++Test/Packet++Coverage.xml
756+
files: ./Dist/Tests/Pcap++Test/Debug/Pcap++Coverage.xml,./Dist/Tests/Packet++Test/Debug/Packet++Coverage.xml
758757
flags: ${{ matrix.os }},unittest,${{ matrix.pcap_lib }}
759758
fail_ci_if_error: false
760759
verbose: true
@@ -781,6 +780,8 @@ jobs:
781780
shell: pwsh
782781
run: .\ci\install_windivert.ps1 -Target "$env:WINDIVERT_DIR"
783782

783+
# The visual studio generator is a multi-config generator. This means that the executable will be in a configuration subfolder (e.g., Debug or Release),
784+
# relative to the target folder. Example: $(BuildDir)/Test/Packet++Test/Debug/Packet++Test.exe
784785
- name: Configure PcapPlusPlus (WinDivert)
785786
run: cmake -A x64 -G "Visual Studio 17 2022" -DPCAP_ROOT=${{ env.PCAP_SDK_DIR }} -DPCAPPP_USE_WINDIVERT=ON -DWinDivert_ROOT=${{ env.WINDIVERT_DIR }} -S . -B "$env:BUILD_DIR"
786787

@@ -790,14 +791,17 @@ jobs:
790791
- name: Install tcpreplay
791792
run: ci\install_tcpreplay.bat
792793

793-
- name: Test PcapPlusPlus
794+
- name: Copy WinDivert files to test folder
794795
shell: pwsh
795796
run: |
796-
Copy-Item "${{ env.WINDIVERT_DIR }}\x64\WinDivert.dll" "Tests\Pcap++Test\Bin\WinDivert.dll" -Force
797-
Copy-Item "${{ env.WINDIVERT_DIR }}\x64\WinDivert64.sys" "Tests\Pcap++Test\Bin\WinDivert64.sys" -Force
797+
Copy-Item "${{ env.WINDIVERT_DIR }}\x64\WinDivert.dll" "$env:BUILD_DIR\Tests\Pcap++Test\Debug\WinDivert.dll" -Force
798+
Copy-Item "${{ env.WINDIVERT_DIR }}\x64\WinDivert64.sys" "$env:BUILD_DIR\Tests\Pcap++Test\Debug\WinDivert64.sys" -Force
798799
800+
- name: Test PcapPlusPlus
801+
shell: pwsh
802+
run: |
799803
python -m pip install -r ci\run_tests\requirements.txt
800-
python ci\run_tests\run_tests_windows.py --include-tests windivert
804+
python ci\run_tests\run_tests_windows.py --include-tests windivert --build-dir "$env:BUILD_DIR" --packet-test-exe "Tests/Packet++Test/Debug/Packet++Test.exe" --pcap-test-exe "Tests/Pcap++Test/Debug/Pcap++Test.exe"
801805
802806
freebsd:
803807
runs-on: ubuntu-latest
@@ -831,7 +835,7 @@ jobs:
831835
echo "Testing PcapPlusPlus"
832836
python -m ensurepip
833837
python -m pip install -r ci/run_tests/requirements.txt
834-
python ci/run_tests/run_tests.py --interface "$interface_name"
838+
python ci/run_tests/run_tests.py --interface "$interface_name" --build-dir Dist
835839
836840
echo "Testing PcapPlusPlus examples"
837841
cd Tests/ExamplesTest
@@ -964,7 +968,7 @@ jobs:
964968
- name: Test PcapPlusPlus
965969
run: |
966970
. .venv/bin/activate
967-
python ci/run_tests/run_tests.py --interface eth0 --use-sudo --pcap-test-args="-t xdp"
971+
python ci/run_tests/run_tests.py --interface eth0 --use-sudo --pcap-test-args="-t xdp" --build-dir "$BUILD_DIR"
968972
969973
- name: Create Cobertura Report
970974
run: |

Tests/Packet++Test/CMakeLists.txt

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,31 @@ if(WIN32)
6363
target_compile_definitions(Packet++Test PUBLIC WIN32_LEAN_AND_MEAN)
6464
endif()
6565

66+
target_include_directories(Packet++Test PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
67+
6668
if(MSVC)
6769
# This executable requires getopt.h not available on VStudio
6870
target_link_libraries(Packet++Test PRIVATE Getopt-for-Visual-Studio)
6971
endif()
7072

71-
set_property(TARGET Packet++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
72-
set_property(TARGET Packet++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
73-
set_property(TARGET Packet++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
74-
add_test(NAME Packet++Test COMMAND $<TARGET_FILE:Packet++Test> WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/)
73+
add_custom_command(
74+
TARGET Packet++Test
75+
POST_BUILD
76+
COMMAND
77+
${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/PacketExamples
78+
$<TARGET_FILE_DIR:Packet++Test>/PacketExamples
79+
)
80+
81+
add_custom_command(
82+
TARGET Packet++Test
83+
POST_BUILD
84+
COMMAND
85+
${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/../../3rdParty/OUIDataset/PCPP_OUIDataset.json"
86+
"$<TARGET_FILE_DIR:Packet++Test>/PCPP_OUIDataset.json"
87+
)
88+
89+
# set_property(TARGET Packet++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
90+
# set_property(TARGET Packet++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
91+
# set_property(TARGET Packet++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
92+
# add_test(NAME Packet++Test COMMAND $<TARGET_FILE:Packet++Test> WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/)
93+
add_test(NAME Packet++Test COMMAND $<TARGET_FILE:Packet++Test> WORKING_DIRECTORY $<TARGET_FILE_DIR:Packet++Test>)

Tests/Packet++Test/Tests/EthAndArpTests.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ using pcpp_tests::utils::createPacketFromHexResource;
1515
PTF_TEST_CASE(OUILookup)
1616
{
1717
pcpp::OUILookup lookupEngineJson;
18-
PTF_ASSERT_GREATER_THAN(lookupEngineJson.initOUIDatabaseFromJson("../../3rdParty/OUIDataset/PCPP_OUIDataset.json"),
19-
0);
18+
PTF_ASSERT_GREATER_THAN(lookupEngineJson.initOUIDatabaseFromJson("PCPP_OUIDataset.json"), 0);
2019

2120
PTF_ASSERT_EQUAL(lookupEngineJson.getVendorName("aa:aa:aa:aa:aa:aa"), "Unknown");
2221
// CIDR 36

Tests/Packet++Test/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
#include "PcppTestFrameworkRun.h"
44
#include "TestDefinition.h"
55
#include "Logger.h"
6-
#include "../../Tests/Packet++Test/Utils/TestUtils.h"
76
#include "Resources.h"
7+
#include "Utils/TestUtils.h"
88

99
static struct option PacketTestOptions[] = {
1010
{ "include-tags", required_argument, nullptr, 't' },

Tests/Pcap++Test/CMakeLists.txt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,16 @@ if(MSVC)
2727
target_link_libraries(Pcap++Test PRIVATE Getopt-for-Visual-Studio)
2828
endif()
2929

30-
set_property(TARGET Pcap++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
31-
set_property(TARGET Pcap++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
32-
set_property(TARGET Pcap++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
30+
add_custom_command(
31+
TARGET Pcap++Test
32+
POST_BUILD
33+
COMMAND
34+
${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/PcapExamples"
35+
"$<TARGET_FILE_DIR:Pcap++Test>/PcapExamples"
36+
)
3337

34-
add_test(NAME Pcap++Test COMMAND $<TARGET_FILE:Pcap++Test> -n WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/)
38+
# set_property(TARGET Pcap++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
39+
# set_property(TARGET Pcap++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
40+
# set_property(TARGET Pcap++Test PROPERTY RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/Bin")
41+
# add_test(NAME Pcap++Test COMMAND $<TARGET_FILE:Pcap++Test> -n WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/)
42+
add_test(NAME Pcap++Test COMMAND $<TARGET_FILE:Pcap++Test> -n WORKING_DIRECTORY $<TARGET_FILE_DIR:Pcap++Test>)

ci/run_tests/run_tests.py

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import os
44
import subprocess
55
import argparse
6+
from pathlib import Path
7+
from dataclasses import dataclass
68
from contextlib import contextmanager
79
from scapy.all import get_if_addr
810

@@ -21,30 +23,44 @@ def tcp_replay_worker(interface: str, tcpreplay_dir: str):
2123
tcpreplay_proc.kill()
2224

2325

24-
def run_packet_tests(args: list[str], use_sudo: bool):
25-
cmd_line = ["sudo"] if use_sudo else []
26-
cmd_line += [os.path.join("Bin", "Packet++Test"), *args]
26+
@dataclass
27+
class Runner:
28+
build_dir: Path
29+
use_sudo: bool = False
30+
packet_test_path = Path("Tests", "Packet++Test", "Packet++Test")
31+
pcap_test_path = Path("Tests", "Pcap++Test", "Pcap++Test")
2732

28-
completed_process = subprocess.run(cmd_line, cwd="Tests/Packet++Test")
33+
def run_packet_tests(self, args: list[str]):
34+
exe_path = self.build_dir / self.packet_test_path
35+
work_dir = exe_path.parent
2936

30-
if completed_process.returncode != 0:
31-
raise RuntimeError(f"Error while executing Packet++ tests: {completed_process}")
37+
cmd_line = ["sudo"] if self.use_sudo else []
38+
cmd_line += [str(exe_path.absolute()), *args]
3239

40+
completed_process = subprocess.run(cmd_line, cwd=str(work_dir))
3341

34-
def run_pcap_tests(interface: str, tcpreplay_dir: str, args: list[str], use_sudo: bool):
35-
ip_address = get_if_addr(interface)
36-
print(f"IP address is: {ip_address}")
37-
38-
with tcp_replay_worker(interface, tcpreplay_dir):
39-
cmd_line = ["sudo"] if use_sudo else []
40-
cmd_line += [os.path.join("Bin", "Pcap++Test"), "-i", ip_address, *args]
41-
42-
completed_process = subprocess.run(cmd_line, cwd="Tests/Pcap++Test")
4342
if completed_process.returncode != 0:
4443
raise RuntimeError(
45-
f"Error while executing Pcap++ tests: {completed_process}"
44+
f"Error while executing Packet++ tests: {completed_process}"
4645
)
4746

47+
def run_pcap_tests(self, interface: str, tcpreplay_dir: str, args: list[str]):
48+
ip_address = get_if_addr(interface)
49+
print(f"IP address is: {ip_address}")
50+
51+
exe_path = self.build_dir / self.pcap_test_path
52+
work_dir = exe_path.parent
53+
54+
cmd_line = ["sudo"] if self.use_sudo else []
55+
cmd_line += [str(exe_path.absolute()), "-i", ip_address, *args]
56+
57+
with tcp_replay_worker(interface, tcpreplay_dir):
58+
completed_process = subprocess.run(cmd_line, cwd=str(work_dir))
59+
if completed_process.returncode != 0:
60+
raise RuntimeError(
61+
f"Error while executing Pcap++ tests: {completed_process}"
62+
)
63+
4864

4965
def main():
5066
parser = argparse.ArgumentParser()
@@ -78,17 +94,19 @@ def main():
7894
default=None,
7995
help="tcpreplay directory",
8096
)
97+
parser.add_argument(
98+
"--build-dir", type=str, default=os.getcwd(), help="path to the build directory"
99+
)
81100
args = parser.parse_args()
82101

102+
runner = Runner(build_dir=Path(args.build_dir), use_sudo=args.use_sudo)
103+
83104
if "packet" in args.test_suites:
84-
run_packet_tests(args.packet_test_args.split(), args.use_sudo)
105+
runner.run_packet_tests(args.packet_test_args.split())
85106

86107
if "pcap" in args.test_suites:
87-
run_pcap_tests(
88-
args.interface,
89-
args.tcpreplay_dir,
90-
args.pcap_test_args.split(),
91-
args.use_sudo,
108+
runner.run_pcap_tests(
109+
args.interface, args.tcpreplay_dir, args.pcap_test_args.split()
92110
)
93111

94112

0 commit comments

Comments
 (0)