Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propose of new structure and associated scripts #1

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
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
123 changes: 113 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,22 +1,125 @@

# Test tshark's dissectors on small test files

TEST_CASES = $(wildcard tests/*/*.pdml)
.DEFAULT_GOAL := help
.SECONDEXPANSION:

# Set home dir to empty dir
ifneq ("$(wildcard /tmp)","")
HOME=/tmp
else
HOME?=$(mktemp -d)
endif

# List all available test directories
TEST_CASE_DIRS=$(wildcard tests/*/*)

# Convert directories to test case names
TEST_CASES=$(foreach test,$(TEST_CASE_DIRS), $(test)/$(notdir $(test)))

# Convert directories to test case names with output dir
TEST_CASES_OUTPUT=$(foreach test,$(TEST_CASE_DIRS), $(test)/output/$(notdir $(test)))

# Editor backup files
EDITOR_BACKUP_FILES=$(wildcard *~) $(wildcard */*~) $(wildcard */*/*~) $(wildcard */*/*/*~) $(wildcard */*/*/*/*~)

# List of versions for which we check and store different outputs
# When output is verified, current wireshark version's output is compared to same version's stored output or to the latest previous version
# - list should be ordered from the oldest to the newest version
SUPPORTED_VERSIONS?=2.0 2.2 2.3 2.4 2.5
VERSION?=
SELECTED_VERSIONS=$(if $(VERSION),$(VERSION),$(SUPPORTED_VERSIONS))

TSHARK_EXECUTABLE?=tshark
TSHARK_VERSION=$(shell $(TSHARK_EXECUTABLE) --version | head -1 | cut -d' ' -f 3 | cut -d'.' -f1,2)

VERBOSE?=no
TEST_FAIL_ON_ERROR?=yes

%.pdml1.current: TESTDIR = $(patsubst %/,%,$(dir $(patsubst %/,%,$(dir $*))))
%.pdml1.current: TESTNAME = $(notdir $*)
%.pdml1.current: $$(dir $$(subst /output,,$$@))/filter.xsl $$(wildcard $$(dir $$(subst /output,,$$@))/*.pcap*.gz)
@./scripts/sample_test.sh "$(TSHARK_EXECUTABLE)" "$(TESTDIR)/$(TESTNAME)" pdml1 $(VERBOSE) $(TEST_FAIL_ON_ERROR) $(SELECTED_VERSIONS)

%.pdml2.current: TESTDIR = $(patsubst %/,%,$(dir $(patsubst %/,%,$(dir $*))))
%.pdml2.current: TESTNAME = $(notdir $*)
%.pdml2.current: $$(dir $$(subst /output,,$$@))/filter.xsl $$(wildcard $$(dir $$(subst /output,,$$@))/*.pcap*.gz)
@./scripts/sample_test.sh "$(TSHARK_EXECUTABLE)" "$(TESTDIR)/$(TESTNAME)" pdml2 $(VERBOSE) $(TEST_FAIL_ON_ERROR) $(SELECTED_VERSIONS)

%.text.current: TESTDIR = $(patsubst %/,%,$(dir $(patsubst %/,%,$(dir $*))))
%.text.current: TESTNAME = $(notdir $*)
%.text.current: $$(dir $$(subst /output,,$$@))/filter.xsl $$(wildcard $$(dir $$(subst /output,,$$@))/*.pcap*.gz)
@./scripts/sample_test.sh "$(TSHARK_EXECUTABLE)" "$(TESTDIR)/$(TESTNAME)" text $(VERBOSE) $(TEST_FAIL_ON_ERROR) $(SELECTED_VERSIONS)

%.pdml1: TESTDIR = $(patsubst %/,%,$(dir $(patsubst %/,%,$(dir $*))))
%.pdml1: $$(dir $$(subst /output,,$$@))/filter.xsl $$(wildcard $$(dir $$(subst /output,,$$@))/*.pcap*.gz)
@./scripts/sample_make_output.sh "$(TSHARK_EXECUTABLE)" "$(TESTDIR)" pdml1 $(VERBOSE)

%.pdml2: TESTDIR = $(patsubst %/,%,$(dir $(patsubst %/,%,$(dir $*))))
%.pdml2: $$(dir $$(subst /output,,$$@))/filter.xsl $$(wildcard $$(dir $$(subst /output,,$$@))/*.pcap*.gz)
@./scripts/sample_make_output.sh "$(TSHARK_EXECUTABLE)" "$(TESTDIR)" pdml2 $(VERBOSE)

check_output = @(echo -n "Processing $(notdir $1)" && cd $(dir $1) && \
$(TSHARK_EXECUTABLE) -T pdml -r $(subst .pdml,,$(notdir $1)) > $(notdir $2) 2>&1 && \
xsltproc filter.xsl $(notdir $2) | diff $(notdir $1) - ) && echo " [OK]"
%.text: TESTDIR = $(patsubst %/,%,$(dir $(patsubst %/,%,$(dir $*))))
%.text: $$(dir $$(subst /output,,$$@))/filter.xsl $$(wildcard $$(dir $$(subst /output,,$$@))/*.pcap*.gz)
@./scripts/sample_make_output.sh "$(TSHARK_EXECUTABLE)" "$(TESTDIR)" text $(VERBOSE)

all: test
tests_pdml1: $(foreach test, $(TEST_CASE_DIRS), $(test)/output/$(notdir $(test)).pdml1.current)

%.pdml.current: %.pdml %
$(call check_output, $<, $@)
tests_pdml2: $(foreach test, $(TEST_CASE_DIRS), $(test)/output/$(notdir $(test)).pdml2.current)

test: $(TEST_CASES:.pdml=.pdml.current)
tests_text: $(foreach test, $(TEST_CASE_DIRS), $(test)/output/$(notdir $(test)).text.current)

%/output: %/output/$$(notdir $$*).pdml1.current %/output/$$(notdir $$*).pdml2.current %/output/$$(notdir $$*).text.current
@

tests: $(foreach test, $(TEST_CASE_DIRS), $(test)/output)

make_outputs_pdml1: $(foreach test_case, $(TEST_CASE_DIRS), $(test_case)/output/$(notdir $(test_case))_$(TSHARK_VERSION).pdml1)
@

make_outputs_pdml2: $(foreach test_case, $(TEST_CASE_DIRS), $(test_case)/output/$(notdir $(test_case))_$(TSHARK_VERSION).pdml2)
@

make_outputs_text: $(foreach test_case, $(TEST_CASE_DIRS), $(test_case)/output/$(notdir $(test_case))_$(TSHARK_VERSION).text)
@

outputs: make_outputs_pdml1 make_outputs_pdml2 make_outputs_text

verify_repository:
@$(foreach test_case, $(TEST_CASE_DIRS), ./scripts/sample_verify.sh "$(test_case)" $(VERBOSE) $(SELECTED_VERSIONS);)

clean:
@rm -f $(TEST_CASES:.pdml=.pdml.current)
@rm -f $(TEST_CASES_OUTPUT:=.pdml1.current)
@rm -f $(TEST_CASES_OUTPUT:=.pdml1.current.tmp)
@rm -f $(TEST_CASES_OUTPUT:=.pdml1.current.tmp2)
@rm -f $(TEST_CASES_OUTPUT:=.pdml2.current)
@rm -f $(TEST_CASES_OUTPUT:=.pdml2.current.tmp)
@rm -f $(TEST_CASES_OUTPUT:=.pdml2.current.tmp2)
@rm -f $(TEST_CASES_OUTPUT:=.text.current)
@rm -f $(TEST_CASES_OUTPUT:=.text.current.tmp)
@rm -f $(TEST_CASES_OUTPUT:=.text.current.tmp2)

clean-backups: $(EDITOR_BACKUP_FILES)
@rm -f $(EDITOR_BACKUP_FILES)

maintainer-clean: clean clean-backups

help:
@echo "Usage:"
@echo "make outputs create missing output files (.test, .pdml1, .pdml2)"
@echo "make verify_repository verifies whether each test is equipped with required files"
@echo "make tests test each sample output with current wireshark"
@echo "make all do verify_repository outputs tests in row"
@echo ""
@echo "you can use variables:"
@echo "TSHARK_EXECUTABLE=/path/to/tshark"
@echo "VERSION=2.0"
@echo "VERBOSE=yes"
@echo "TEST_FAIL_ON_ERROR=no"
@echo "e.g. make outputs TSHARK_EXECUTABLE=/path/to/tshark creates outputs with specified tshark and with its version"
@echo "e.g. make tests VERSION=2.0 test samples with current tshark, but compares its outputs with specified version"

all: verify_repository outputs tests

.PHONY: all maintainer-clean clean outputs verify_repository tests

.PHONY: clean
42 changes: 37 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,52 @@ and a collection of capture files.

Running tests
-------------
Simply invoke `make` or `make -j4` for more parallelism.
Simply invoke `make tests` or `make tests -j4` for more parallelism.

Adding a new test
-----------------
Create a new subdirectory under `tests/` with the following files:
Create a new subdirectory under `tests/<protocol>/`. <protocol> is name of protocol
subjected to test (e.g. 'dns' or 'rtp.ed137a'). Use same name as display filter in wireshark.
Directory populate with the following files:

- FOO.pdml - the expected processed output (e.g. `dns.pcapng.pdml`).
- FOO - the source capture file (e.g. `dns.pcapng`).
- FOO.pcap.gz or FOO.pcapng.gz - the source file (noncompressed files shall not be used, e.g. 'dns-1.pcapng.gz')
- FOO.description - description of purpose the file is included (e.g. basic DNS query, RTP header with ED-137A header extension, packet missing in sequence)
- FOO.requirements - requirements, how tshark/wireshark should process the file (e.g. packet should be decoded by specification of ED-137B, PTT and SQL bits should be shown in packet info column). Requirements can describe non dissector related staff too (e.g. RTP Stream Analysis window should show warning about bad packet sequence, warning should be shown in yellow color).
- FOO.args - optional file, contains options for tshark to process file as expected (e.g. 'decode as' parameters)
- FOO_<version>.pdml1 - the expected processed output from <version> of tshark in PDML format for first pass (e.g. `dns-1_2.0.pcapng.pdml1`). Only first two levels of version number are used.
- FOO_<version>.pdml2 - the expected processed output from <version> of tshark in PDML format for second pass (e.g. `dns-1_2.0.pcapng.pdml1`). Only first two levels of version number are used.
- FOO_<version>.text - the expected processed output from <version> of tshark in TEXT format (e.g. `dns-1_2.0.pcapng.text`). Only first two levels of version number are used.
- FOO.no_pdml - optional file expressing that PDML output should not be checked (requirements probably describe GUI related requiremens only)
- FOO.no_text - optional file expressing that TEXT output should not be checked (requirements probably describe GUI related requiremens only)
- filter.xsl - the post-processor.

Run make outputs to generate .pdml and .text and make verify_repository to check all required files before commit.

When proposing a new test, please include the source of the packet capture file
in the commit message. The source could be a link to https://bugs.wireshark.org/
or https://wiki.wireshark.org/SampleCaptures for example. Try to keep capture
files small and specific to a small number of protocols.

Options and variables to run framework
--------------------------------------

SUPPORTED_VERSIONS - list of versions checked during make or make outputs, when not specified, default in Makefile is used
VERSION - version used for make or make outputs, when not specified, tshark version is used
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe WS_VERSION (to make clearer that this is not some other version)?

TSHARK_EXECUTABLE - path to tshark, when not specified, tshark in PATH is used
VERBOSE=yes - produce more verbose messages during processing
TEST_FAIL_ON_ERROR=no - do not stop on first error during tests

make tests - run tests, compare output of latest stored .pdml and .text
make tests VERSION=2.0 - same as above, compare output with version 2.0 or previous
make test_pdml or make test_text - run tests for PDML or TEXT output only
make verify_repository - check whether each sample contains required files for at least one of checked versions
make verify_repository VERSION=2.0 - same above, check is made for specified version only
make outputs - generate .pdml and .text output for samples where files are missing, version is derived from version of used tshark
make outputs TSHARK_EXECUTABLE=path/tshark - same as above, but you can determine used tshark
make clean - removes temporary files after make test
make maintainer-clean - removes temporary files including editor backup files
make all - do verify_repository outputs tests in row

Architecture
------------
The initial desired features were:
Expand All @@ -28,10 +59,11 @@ The initial desired features were:
- Take a packet capture file and produce the expected "output".
- Have a filter that strips layers or just keeps a single layer.
- Allow preferences to be applied (SSL keys, port numbers, ...).
- Maybe check both single and second pass mode (tshark -2) to catch issues
- Check both single and second pass mode (tshark -2) to catch issues
related to maintained state within a dissector.

License
-------
This project including the tools and capture files are provided under the terms
of version 2 of the GPL or any later version.

51 changes: 51 additions & 0 deletions doc/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
1) Won't be good idea to ask for e.g. <sample>.description.txt and
<sample>.specification.txt for each sample?
=> done

2) Won't be good idea to allow skip a sample from automatic testing
(because it is for GUI demonstration)?
=> <sample>.no_pdml => done
=> <sample>.no_txt => done

3) There should be easy way how to describe which wireshark version
processed stored PDML file.
Probably different outputs should be stored for main branches (2.0, 2.2,
...). It is obvious that each version of wireshark will change (improve)
some outputs. Therefore older release will not be able to process it
correctly (PDML diff will fail).
I think that without output version you can't run regression tests
automatically.
=> <FILE>_<VERSION>.pdml should be created => done
=> <FILE>_<VERSION>.text should be created => done
=> output is validated to version of used tshark or older version => done

4) There should be easy way how to run custom wireshark version without
modifying Makefile. I have multiple versions for testing. I think
environment variable solve it.
=> done

5) There should be easy way how to describe which filter should be used
for preprocessing PDML. Now only filter.xsl is used.
=> filter.xsl in directory with sample is used => done

6) Rules must be written.

7) There should be a procedure which checks whether repository/new sample
contains expected information. Something like git review procedure for
wireshark source/gerrit.
=> make verify_repository

8) Run -T text and -T pdml
=> done

9) It should be possible to set parameters for tshark run (e.g. decode as).
=> optional file <file>.args => done

---------------------------

There are two levels of directory structure in tests/. It looks like <PROTO>/<sample_description>. First level is name of protocol which is tested. Second level is name/description of sample.
Protocol name shall be name of procotol which is going to be tested. The easiest way is to name is same way as display filter in wireshark names it - including upper layer protocols (e.g. rtp or rtp.ed137a).
Name of test depends on author, but should somehow describe the tested subject. When expected description (directory) is already there, add number to it (e.g. dns, dns-1, dns-2).

Sample file should be stored as .pcap.gz or .pcapng.gz.

102 changes: 102 additions & 0 deletions scripts/sample_make_output.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/bin/bash

TSHARK_EXECUTABLE="$1"
SAMPLE_DIR="$2"
TYPE="$3"
VERBOSE="$4"
REQ_VERSION="$5"

OUTPUT=""

echo_history () {
echo -ne "${OUTPUT} $*"
OUTPUT=""
}

echo_verbose () {
if [ "${VERBOSE}" == "yes" ]; then
echo -ne "$*"
else
OUTPUT="${OUTPUT} $*"
fi
}

${TSHARK_EXECUTABLE} --version > /dev/null 2> /dev/null
if [ "$?" != "0" ]; then
echo_history "Executable for tshark doesn't exists (${TSHARK_EXECUTABLE})\n"
exit 0
fi

echo_verbose "Creating output '${TYPE}' for ${SAMPLE_DIR}:\n"
FILE=`basename "${SAMPLE_DIR}"`

TSHARK_VERSION=`${TSHARK_EXECUTABLE} --version | head -1 | cut -d' ' -f 3 | cut -d'.' -f1,2`
if [ -n "${REQ_VERSION}" ]; then
if [ "${REQ_VERSION}" != "${TSHARK_VERSION}" ]; then
echo_history " FAILED, required tshark version do not match running version\n"
exit 1
fi
fi

cd "${SAMPLE_DIR}"

if [ -f "${FILE}.pcap.gz" ]; then
FILE_PCAP="${FILE}.pcap.gz"
elif [ -f "${FILE}.pcapng.gz" ]; then
FILE_PCAP="${FILE}.pcapng.gz"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are capture formats other than (compressed) pcap like android logcat, etc. What do you think about using a single extension (like FOO.pcap or FOO.cap) even if it is compressed? Otherwise we might have a lot of files here.

Alternatively, we can stick to the original convention of looking for FOO given FOO.pdml (e.g. dns.pcapng.pdml)

else
echo_history " No sample for ${SAMPLE_DIR}\n"
exit 0
fi

TSHARK_ARGS=
if [ -r "${FILE}.args" ]; then
TSHARK_ARGS=`cat "${FILE}.args"`
fi

OUTPUT_FILE="output/${FILE}_${TSHARK_VERSION}.${TYPE}"

XTYPE=${TYPE}
XARGS=
if [ "${TYPE}" == "pdml1" ]; then
XTYPE=pdml
XARGS=
elif [ "${TYPE}" == "pdml2" ]; then
XTYPE=pdml
XARGS=-2
fi

"${TSHARK_EXECUTABLE}" $TSHARK_ARGS -T ${XTYPE} ${XARGS} -r "${FILE_PCAP}" > "${OUTPUT_FILE}".tmp
if [ "$?" -eq "0" ]; then
if [ "${XTYPE}" == "pdml" ]; then
mv -f "${OUTPUT_FILE}.tmp" "${OUTPUT_FILE}.tmp2"
xsltproc filter.xsl "${OUTPUT_FILE}.tmp2" > "${OUTPUT_FILE}.tmp"
if [ "$?" -ne "0" ]; then
rm -f "${OUTPUT_FILE}.tmp"
rm -f "${OUTPUT_FILE}.tmp2"
echo_history " FAILED, file ${SAMPLE_DIR}/${OUTPUT_FILE}\n"
exit 1
fi
rm -f "${OUTPUT_FILE}.tmp2"
fi
mv "${OUTPUT_FILE}.tmp" "${OUTPUT_FILE}"
echo_history " OK, file ${SAMPLE_DIR}/${OUTPUT_FILE}\n"
exit 0
else
rm -f "${OUTPUT_FILE}.tmp"
echo_history " FAILED, file ${SAMPLE_DIR}/${OUTPUT_FILE}\n"
exit 1
fi

#*
#* Editor modelines - http://www.wireshark.org/tools/modelines.html
#*
#* Local variables:
#* c-basic-offset: 4
#* tab-width: 4
#* indent-tabs-mode: nil
#* End:
#*
#* vi: set shiftwidth=4 tabstop=4 expandtab:
#* :indentSize=4:tabSize=4:noTabs=true:
#*
Loading