aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2019-01-22 19:01:44 +0100
committerPeter Wu <peter@lekensteyn.nl>2019-01-24 00:26:17 +0000
commit8c698ffc99375e67809fb376d5090fcc2d535048 (patch)
tree2c8978cbf5784b6fc1b7c343d146ff963de39742 /test
parente35139533912890217259cf5dbec8d7388733f1a (diff)
Test: enable capture tests by default using the Loopback interface
Avoid pinging www.wireshark.org, this removes an external dependency. Instead send small UDP datagrams to UDP port 9 (discard) every 50ms. Enable this for all platforms (including macOS and Linux) by default. On Windows the tests requires Npcap and will be skipped with WinPcap. Remove the --capture-interface option since it is no longer needed. Copy WSDG Wireshark Tests Quick Start to README.test and add a link. Change-Id: Id4105a6b1e95407ebf69b871c785c68f9ae26368 Reviewed-on: https://code.wireshark.org/review/31677 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'test')
-rw-r--r--test/README.test26
-rw-r--r--test/conftest.py3
-rw-r--r--test/fixtures_ws.py48
-rw-r--r--test/suite_capture.py59
-rwxr-xr-xtest/test.py1
5 files changed, 62 insertions, 75 deletions
diff --git a/test/README.test b/test/README.test
index ef484348cc..535913eeb0 100644
--- a/test/README.test
+++ b/test/README.test
@@ -1,23 +1,13 @@
Wireshark Tests
-The main testing script is `test.py`. It will attempt to test as much as
-possible by default, including packet capture. This means that you will
-probably either have to supply a capture interface (`--capture-interface
-<interface>`) or disable capture tests (`--disable-capture`). You must
-also build the test-programs target in order for the unittests suite to
-pass.
+The recommended steps to prepare for and to run tests:
-To run all tests from CMake do the following:
-- Pass `-DTEST_EXTRA_ARGS=--disable-capture` or
- `-DTEST_EXTRA_ARGS=--capture-interface=<interface>`
- as needed for your system.
-- Build the “test” target or run ctest, e.g. `ctest --force-new-ctest-process -j 4 --verbose`.
+* Install two Python packages, pytest: `pip install pytest pytest-xdist`
+* Build programs (“wireshark”, “tshark”, etc.): `ninja`
+* Build additional programs for the “unittests” suite: `ninja test-programs`
+* Run tests in the build directory: `pytest`
-To run all tests directly, run `test.py -p
-/path/to/wireshark-build/run-directory <capture args>`.
+Replace `ninja test-programs` by `make test-programs` as needed.
-To see a list of all options, run `test.py -h` or `test.py --help`.
-
-To see a list of all tests, run `test.py -l`.
-
-See the “Wireshark Tests” chapter of the Developer's Guide for details.
+See the “Wireshark Tests” chapter of the Developer's Guide for details:
+https://www.wireshark.org/docs/wsdg_html_chunked/ChapterTests.html
diff --git a/test/conftest.py b/test/conftest.py
index 3b70e049c3..954195fdfb 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -15,9 +15,6 @@ def pytest_addoption(parser):
parser.addoption('--disable-capture', action='store_true',
help='Disable capture tests'
)
- parser.addoption('--capture-interface',
- help='Capture interface index or name.'
- )
parser.addoption('--program-path', help='Path to Wireshark executables.')
parser.addoption('--skip-missing-programs',
help='Skip tests that lack programs from this list instead of failing'
diff --git a/test/fixtures_ws.py b/test/fixtures_ws.py
index ed656e0c2d..5b5d9b8061 100644
--- a/test/fixtures_ws.py
+++ b/test/fixtures_ws.py
@@ -8,7 +8,6 @@
#
'''Fixtures that are specific to Wireshark.'''
-import logging
import os
import re
import subprocess
@@ -24,31 +23,36 @@ import subprocesstest
def capture_interface(request, cmd_dumpcap):
'''
Name of capture interface. Tests will be skipped if dumpcap is not
- available or if the capture interface is unknown.
+ available or no Loopback interface is available.
'''
- iface = request.config.getoption('--capture-interface', default=None)
disabled = request.config.getoption('--disable-capture', default=False)
if disabled:
fixtures.skip('Capture tests are disabled via --disable-capture')
- if iface:
- # If a non-empty interface is given, assume capturing is possible.
+ proc = subprocess.Popen((cmd_dumpcap, '-D'), stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, universal_newlines=True)
+ outs, errs = proc.communicate()
+ if proc.returncode != 0:
+ print('"dumpcap -D" exited with %d. stderr:\n%s' %
+ (proc.returncode, errs))
+ fixtures.skip('Test requires capture privileges and an interface.')
+ # Matches: "lo (Loopback)" (Linux), "lo0 (Loopback)" (macOS) or
+ # "\Device\NPF_{...} (Npcap Loopback Adapter)" (Windows)
+ print('"dumpcap -D" output:\n%s' % (outs,))
+ m = re.search(r'^(\d+)\. .*\(.*Loopback.*\)', outs, re.MULTILINE)
+ if not m:
+ fixtures.skip('Test requires a capture interface.')
+ iface = m.group(1)
+ # Interface found, check for capture privileges (needed for Linux).
+ try:
+ subprocess.check_output((cmd_dumpcap, '-L', '-i', iface),
+ stderr=subprocess.STDOUT,
+ universal_newlines=True)
return iface
- else:
- if sys.platform == 'win32':
- patterns = '.*(Ethernet|Network Connection|VMware|Intel)'
- else:
- patterns = None
- if patterns:
- try:
- output = subprocess.check_output((cmd_dumpcap, '-D'),
- stderr=subprocess.DEVNULL,
- universal_newlines=True)
- m = re.search(r'^(\d+)\. %s' % patterns, output, re.MULTILINE)
- if m:
- return m.group(1)
- except subprocess.CalledProcessError:
- pass
- fixtures.skip('Test requires capture privileges and an interface.')
+ except subprocess.CalledProcessError as e:
+ print('"dumpcap -L -i %s" exited with %d. Output:\n%s' % (iface,
+ e.returncode,
+ e.output))
+ fixtures.skip('Test requires capture privileges.')
@fixtures.fixture(scope='session')
@@ -152,7 +156,7 @@ def features(cmd_tshark, make_env):
)
tshark_v = re.sub(r'\s+', ' ', tshark_v)
except subprocess.CalledProcessError as ex:
- logging.warning('Failed to detect tshark features: %s', ex)
+ print('Failed to detect tshark features: %s' % (ex,))
tshark_v = ''
gcry_m = re.search(r'with +Gcrypt +([0-9]+\.[0-9]+)', tshark_v)
return types.SimpleNamespace(
diff --git a/test/suite_capture.py b/test/suite_capture.py
index 6da25578d6..2522530668 100644
--- a/test/suite_capture.py
+++ b/test/suite_capture.py
@@ -13,9 +13,11 @@ import fixtures
import glob
import hashlib
import os
+import socket
import subprocess
import subprocesstest
import sys
+import threading
import time
import uuid
@@ -25,6 +27,23 @@ testout_pcap = 'testout.pcap'
testout_pcapng = 'testout.pcapng'
snapshot_len = 96
+class UdpTrafficGenerator(threading.Thread):
+ def __init__(self):
+ super().__init__(daemon=True)
+ self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ self.stopped = False
+
+ def run(self):
+ while not self.stopped:
+ time.sleep(.05)
+ self.sock.sendto(b'Wireshark test\n', ('127.0.0.1', 9))
+
+ def stop(self):
+ if not self.stopped:
+ self.stopped = True
+ self.join()
+
+
@fixtures.fixture
def traffic_generator():
'''
@@ -32,41 +51,19 @@ def traffic_generator():
where cfilter is a capture filter to match the generated traffic.
start_func can be invoked to start generating traffic and returns a function
which can be used to stop traffic generation early.
- Currently calls ping www.wireshark.org for 60 seconds.
+ Currently generates a bunch of UDP traffic to localhost.
'''
- # XXX replace this by something that generates UDP traffic to localhost?
- # That would avoid external access which is forbidden by the Debian policy.
- nprocs = 1
- if sys.platform.startswith('win32'):
- # XXX Check for psping? https://docs.microsoft.com/en-us/sysinternals/downloads/psping
- args_ping = ('ping', '-n', '60', '-l', '100', 'www.wireshark.org')
- nprocs = 3
- elif sys.platform.startswith('linux') or sys.platform.startswith('freebsd'):
- args_ping = ('ping', '-c', '240', '-s', '100', '-i', '0.25', 'www.wireshark.org')
- elif sys.platform.startswith('darwin'):
- args_ping = ('ping', '-c', '1', '-g', '1', '-G', '240', '-i', '0.25', 'www.wireshark.org')
- else:
- # XXX Other BSDs, Solaris, etc
- fixtures.skip('ping utility is unavailable - cannot generate traffic')
- procs = []
- def kill_processes():
- for proc in procs:
- proc.kill()
- for proc in procs:
- proc.wait()
- procs.clear()
+ threads = []
def start_processes():
- for i in range(nprocs):
- if i > 0:
- # Fake subsecond interval if the ping utility lacks support.
- time.sleep(0.1)
- proc = subprocess.Popen(args_ping, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
- procs.append(proc)
- return kill_processes
+ thread = UdpTrafficGenerator()
+ thread.start()
+ threads.append(thread)
+ return thread.stop
try:
- yield start_processes, 'icmp || icmp6'
+ yield start_processes, 'udp port 9'
finally:
- kill_processes()
+ for thread in threads:
+ thread.stop()
@fixtures.fixture(scope='session')
diff --git a/test/test.py b/test/test.py
index 27d75efc63..df3e9337aa 100755
--- a/test/test.py
+++ b/test/test.py
@@ -54,7 +54,6 @@ def main():
parser = argparse.ArgumentParser(description='Wireshark unit tests')
cap_group = parser.add_mutually_exclusive_group()
cap_group.add_argument('-E', '--disable-capture', action='store_true', help='Disable capture tests')
- cap_group.add_argument('-i', '--capture-interface', help='Capture interface index or name')
parser.add_argument('-p', '--program-path', default=os.path.curdir, help='Path to Wireshark executables.')
parser.add_argument('--skip-missing-programs',
help='Skip tests that lack programs from this list instead of failing'