Skip to content

Commit d1d2ff1

Browse files
authored
Several CI related fixes (#3399)
* Fix UTscapy timeout logs * Add doc * Set fail-fast to false * Linting * Use bash substring * Install libpcap * Run tox in parallel mode
1 parent 5cc1390 commit d1d2ff1

File tree

6 files changed

+56
-26
lines changed

6 files changed

+56
-26
lines changed

.appveyor.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,10 @@ test_script:
6363
# Set environment variables
6464
- set PYTHONPATH=%APPVEYOR_BUILD_FOLDER%
6565
- set PATH=%APPVEYOR_BUILD_FOLDER%;C:\Program Files\Wireshark\;C:\Program Files\Windump\;%PATH%
66+
- set TOX_PARALLEL_NO_SPINNER=1
6667

6768
# Main unit tests
68-
- "%PYTHON%\\python -m tox -- %UT_FLAGS%"
69+
- "%PYTHON%\\python -m tox --parallel -- %UT_FLAGS%"
6970

7071
after_test:
7172
# Run codecov

.config/ci/install.sh

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44
# ./install.sh [install mode]
55

66
# Detect install mode
7-
if [[ "${1}" == "libpcap" ]]; then
7+
if [[ "${1}" == "libpcap" ]]
8+
then
89
SCAPY_USE_LIBPCAP="yes"
9-
if [[ ! -z "$GITHUB_ACTIONS" ]]; then
10+
if [[ ! -z "$GITHUB_ACTIONS" ]]
11+
then
1012
echo "SCAPY_USE_LIBPCAP=yes" >> $GITHUB_ENV
1113
fi
1214
fi
1315

1416
# Install on osx
15-
if [ "$OSTYPE" = "darwin"* ] || [ "$TRAVIS_OS_NAME" = "osx" ]
17+
if [ "${OSTYPE:0:6}" = "darwin" ] || [ "$TRAVIS_OS_NAME" = "osx" ]
1618
then
1719
if [ ! -z $SCAPY_USE_LIBPCAP ]
1820
then
@@ -27,12 +29,12 @@ then
2729
sudo apt-get update
2830
sudo apt-get -qy install tshark net-tools || exit 1
2931
sudo apt-get -qy install can-utils build-essential linux-headers-$(uname -r) linux-modules-extra-$(uname -r) || exit 1
30-
fi
3132

32-
# Make sure libpcap is installed
33-
if [ ! -z $SCAPY_USE_LIBPCAP ]
34-
then
35-
sudo apt-get -qy install libpcap-dev || exit 1
33+
# Make sure libpcap is installed
34+
if [ ! -z $SCAPY_USE_LIBPCAP ]
35+
then
36+
sudo apt-get -qy install libpcap-dev || exit 1
37+
fi
3638
fi
3739

3840
# On Travis, "osx" dependencies are installed in .travis.yml

.config/ci/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ echo UT_FLAGS=$UT_FLAGS
8989
echo TOXENV=$TOXENV
9090

9191
# Launch Scapy unit tests
92-
tox -- ${UT_FLAGS} || exit 1
92+
TOX_PARALLEL_NO_SPINNER=1 tox --parallel -- ${UT_FLAGS} || exit 1
9393

9494
# Stop if NO_BASH_TESTS is set
9595
if [ ! -z "$SIMPLE_TESTS" ]

.github/workflows/unittests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ jobs:
6060
runs-on: ${{ matrix.os }}
6161
timeout-minutes: 20
6262
strategy:
63+
fail-fast: false
6364
matrix:
6465
os: [ubuntu-latest]
6566
python: [2.7, 3.9]

scapy/autorun.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
import code
1212
import logging
1313
import sys
14+
import threading
1415
import traceback
1516

1617
from scapy.config import conf
1718
from scapy.themes import NoTheme, DefaultTheme, HTMLTheme2, LatexTheme2
1819
from scapy.error import log_scapy, Scapy_Exception
1920
from scapy.utils import tex_escape
21+
from scapy.modules.six.moves import queue
2022
import scapy.modules.six as six
2123

2224

@@ -28,6 +30,10 @@ class StopAutorun(Scapy_Exception):
2830
code_run = ""
2931

3032

33+
class StopAutorunTimeout(StopAutorun):
34+
pass
35+
36+
3137
class ScapyAutorunInterpreter(code.InteractiveInterpreter):
3238
def __init__(self, *args, **kargs):
3339
code.InteractiveInterpreter.__init__(self, *args, **kargs)
@@ -87,6 +93,27 @@ def autorun_commands(cmds, my_globals=None, verb=None):
8793
return six.moves.builtins.__dict__.get("_", None)
8894

8995

96+
def autorun_commands_timeout(cmds, timeout=None, **kwargs):
97+
"""
98+
Wraps autorun_commands with a timeout that raises StopAutorunTimeout
99+
on expiration.
100+
"""
101+
if timeout is None:
102+
return autorun_commands(cmds, **kwargs)
103+
104+
q = queue.Queue()
105+
106+
def _runner():
107+
q.put(autorun_commands(cmds, **kwargs))
108+
th = threading.Thread(target=_runner)
109+
th.daemon = True
110+
th.start()
111+
th.join(timeout)
112+
if th.is_alive():
113+
raise StopAutorunTimeout
114+
return q.get()
115+
116+
90117
class StringWriter(object):
91118
"""Util to mock sys.stdout and sys.stderr, and
92119
store their output in a 's' var."""
@@ -111,6 +138,7 @@ def autorun_get_interactive_session(cmds, **kargs):
111138
commands passed as "cmds" and return all output
112139
113140
:param cmds: a list of commands to run
141+
:param timeout: timeout in seconds
114142
:returns: (output, returned) contains both sys.stdout and sys.stderr logs
115143
"""
116144
sstdout, sstderr, sexcepthook = sys.stdout, sys.stderr, sys.excepthook
@@ -122,7 +150,7 @@ def autorun_get_interactive_session(cmds, **kargs):
122150
try:
123151
sys.stdout = sys.stderr = sw
124152
sys.excepthook = sys.__excepthook__
125-
res = autorun_commands(cmds, **kargs)
153+
res = autorun_commands_timeout(cmds, **kargs)
126154
except StopAutorun as e:
127155
e.code_run = sw.s
128156
raise
@@ -138,14 +166,15 @@ def autorun_get_interactive_live_session(cmds, **kargs):
138166
commands passed as "cmds" and return all output
139167
140168
:param cmds: a list of commands to run
169+
:param timeout: timeout in seconds
141170
:returns: (output, returned) contains both sys.stdout and sys.stderr logs
142171
"""
143172
sstdout, sstderr = sys.stdout, sys.stderr
144173
sw = StringWriter(debug=sstdout)
145174
try:
146175
try:
147176
sys.stdout = sys.stderr = sw
148-
res = autorun_commands(cmds, **kargs)
177+
res = autorun_commands_timeout(cmds, **kargs)
149178
except StopAutorun as e:
150179
e.code_run = sw.s
151180
raise

scapy/tools/UTscapy.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
from scapy.consts import WINDOWS
3131
import scapy.modules.six as six
32-
from scapy.modules.six.moves import range, queue
32+
from scapy.modules.six.moves import range
3333
from scapy.config import conf
3434
from scapy.compat import base64_bytes, bytes_hex, plain_str
3535
from scapy.themes import DefaultTheme, BlackAndWhite
@@ -521,18 +521,14 @@ def remove_empty_testsets(test_campaign):
521521

522522
def _run_test_timeout(test, get_interactive_session, verb=3, my_globals=None):
523523
"""Run a test with timeout"""
524-
q = queue.Queue()
525-
526-
def _runner():
527-
output, res = get_interactive_session(test, verb=verb, my_globals=my_globals)
528-
q.put((output, res))
529-
th = threading.Thread(target=_runner)
530-
th.daemon = True
531-
th.start()
532-
th.join(60 * 3) # 3 min timeout
533-
if th.is_alive():
534-
return "Test timed out", False
535-
return q.get()
524+
from scapy.autorun import StopAutorunTimeout
525+
try:
526+
return get_interactive_session(test,
527+
timeout=3 * 60, # 3 min
528+
verb=verb,
529+
my_globals=my_globals)
530+
except StopAutorunTimeout:
531+
return "-- Test timed out ! --", False
536532

537533

538534
def run_test(test, get_interactive_session, theme, verb=3,
@@ -1242,7 +1238,6 @@ def main():
12421238

12431239
# Check active threads
12441240
if VERB > 2:
1245-
import threading
12461241
if threading.active_count() > 1:
12471242
print("\nWARNING: UNFINISHED THREADS")
12481243
print(threading.enumerate())
@@ -1252,6 +1247,8 @@ def main():
12521247
print("\nWARNING: UNFINISHED PROCESSES")
12531248
print(processes)
12541249

1250+
sys.stdout.flush()
1251+
12551252
# Return state
12561253
return glob_result
12571254

0 commit comments

Comments
 (0)