Skip to content
Merged
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
19 changes: 17 additions & 2 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -452,10 +452,25 @@ jobs:
# pypcap ships no wheel: it compiles pcap.c against libpcap, so both the
# headers and the shared library have to be present before pip is asked
# to build it.
- name: Install libpcap headers and a C toolchain
#
# tshark joins them per #845's finding 1: this job installs pyshark and
# its fixture-tier selection (see this job's own comment above) is the
# only place tests/integration/test_engine_runtime.py's real
# ``engine='pyshark'`` extraction is reachable at all --
# `engine-tests`'s own selection ignores tests/integration and
# *_runtime.py wholesale. Without tshark, PyShark.unsupported_reason()
# declines the engine, the extractor silently falls back to the default
# parser, and the test's assertions used to pass on that fallback's
# output -- a vacuous pass, invisible in skip counts. The debconf
# pre-seed and DEBIAN_FRONTEND mirror `engine-tests`'s "Install system
# libpcap and tshark" step exactly, for the same reason: tshark's
# postinst otherwise blocks on the "allow non-superusers to capture
# packets" prompt.
- name: Install libpcap headers, a C toolchain, and tshark
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends build-essential libpcap-dev
echo "wireshark-common wireshark-common/install-setuid boolean false" | sudo debconf-set-selections
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends build-essential libpcap-dev tshark

- name: Install package, test and generator dependencies
run: |
Expand Down
8 changes: 5 additions & 3 deletions tests/integration/test_engine_parity.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
capture through each engine and wrote four reports nobody compared, into
assertions that the engines agree.

``pyshark`` is left out on purpose. It needs :program:`tshark`, which is not
installed here, and on Python 3.14 it fails inside its own
``get_event_loop()`` before it reads a byte;
``pyshark`` is left out on purpose -- not for want of :program:`tshark`, which
the ``pypcap-parity`` job (the one whose selection collects this file) now
installs, but because on Python 3.14 it fails inside its own
``get_event_loop()`` before it reads a byte, so it cannot take part in a parity
comparison that runs on every version;
:file:`tests/integration/test_engine_runtime.py` already pins that. The
``pipeline`` and ``server`` engines are commented out in the original script and
are not covered here either.
Expand Down
20 changes: 19 additions & 1 deletion tests/integration/test_engine_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import importlib.util
import sys
import unittest
from unittest import mock

from tests._support import close_extractor, purge_modules, sample_path

Expand Down Expand Up @@ -99,8 +100,25 @@ def test_pyshark_engine_is_refused_before_asyncio_can_break(self) -> None:
# And the fall back is a working extraction, not an empty one.
self.assertEqual(extractor.length, 6)
else:
extractor = extract(fin=sample_path('in.pcap'), fout='/tmp/out', format='tree', store=True, nofile=True, engine='pyshark')
# Prove pyshark actually ran, rather than the built-in parser wearing
# its label -- see test_new_engine_parity_runtime.py's own `extract`
# helper, which asserts the same thing for PyPCAP/PyPCAPFile. Without
# this, a CI leg missing the ``tshark`` binary makes
# ``PyShark.unsupported_reason()`` decline the engine, the extractor
# silently falls back to the default parser, and the length assertion
# below passes on the fallback's output -- a vacuous pass (#845).
from pcapkit.foundation.engines.pyshark import PyShark

with mock.patch('pcapkit.foundation.extraction.warn') as warn:
extractor = extract(fin=sample_path('in.pcap'), fout='/tmp/out', format='tree', store=True, nofile=True, engine='pyshark')
self.addCleanup(close_extractor, extractor)

engines = [call.args[0] for call in warn.call_args_list
if len(call.args) > 1 and call.args[1] is EngineWarning]
self.assertEqual(engines, [], "'pyshark' was replaced by the fallback engine")
self.assertEqual(extractor._exnam, 'pyshark')
self.assertIsInstance(extractor.engine, PyShark)

self.assertGreater(extractor.length, 0)


Expand Down
Loading