Skip to content

Commit

Permalink
clean up, behave tests activated
Browse files Browse the repository at this point in the history
  • Loading branch information
stbraun committed May 10, 2018
1 parent c9c06c5 commit 3291ef8
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 64 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ src/
fuzzing.log*
.installed.cfg
statistics
.coverage
.pytest_cache
develop-eggs
11 changes: 11 additions & 0 deletions .idea/fuzzing.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/libraries/Buildout_Eggs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion .idea/watcherTasks.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ pylint --rcfile=resrc/pylintrc fuzzing > reports/pylint.txt
# run test and measure coverage
nosetests --with-coverage --cover-branches --cover-inclusive --with-xunit --xunit-file=reports/nosetests.xml --cover-html --cover-html-dir=reports/coverage --cover-xml --cover-xml-file=reports/coverage.xml tests/

# run behave tests
behave > reports/behave.txt

# build source distribution tarball
python setup.py sdist

Expand Down
8 changes: 6 additions & 2 deletions features/steps/ft_fuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ def step_impl(context, len_list):
count = number_of_modified_bytes(context.seed, fuzzed_string)
assert count >= 0


# ## file fuzzer


Expand Down Expand Up @@ -121,8 +122,10 @@ def step_impl(context):
:param context: test context.
"""
assert context.app_list and len(context.app_list) > 0, "ENSURE: app list is provided."
assert context.file_list and len(context.file_list) > 0, "ENSURE: file list is provided."
assert context.app_list and len(
context.app_list) > 0, "ENSURE: app list is provided."
assert context.file_list and len(
context.file_list) > 0, "ENSURE: file list is provided."
context.fuzz_executor = FuzzExecutor(context.app_list, context.file_list)
assert context.fuzz_executor, "VERIFY: fuzz executor created."

Expand Down Expand Up @@ -183,6 +186,7 @@ def step_impl(context, runs):
failed_runs = stats.cumulated_counts_for_status(Status.FAILED)
assert failed_runs == runs


# ##### helpers


Expand Down
51 changes: 35 additions & 16 deletions fuzzing/fuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,30 @@
Copyright (c) 2015 Stefan Braun
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and
associated documentation files (the "Software"), to deal in the Software
without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to
whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
The above copyright notice and this permission notice shall be included in
all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
A PARTICULAR PURPOSE
AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

import random
Expand Down Expand Up @@ -65,8 +75,8 @@ def fuzz_string(seed_str, runs=100, fuzz_factor=50):
def fuzzer(buffer, fuzz_factor=101):
"""Fuzz given buffer.
Take a buffer of bytes, create a copy, and replace some bytes with random values.
Number of bytes to modify depends on fuzz_factor.
Take a buffer of bytes, create a copy, and replace some bytes
with random values. Number of bytes to modify depends on fuzz_factor.
This code is taken from Charlie Miller's fuzzer code.
:param buffer: the data to fuzz.
Expand All @@ -77,14 +87,24 @@ def fuzzer(buffer, fuzz_factor=101):
:rtype: byte array
"""
buf = deepcopy(buffer)
num_writes = random.randrange(math.ceil((float(len(buf)) / fuzz_factor))) + 1
num_writes = number_of_bytes_to_modify(len(buf), fuzz_factor)
for _ in range(num_writes):
random_byte = random.randrange(256)
random_position = random.randrange(len(buf))
buf[random_position] = random_byte
return buf


def number_of_bytes_to_modify(buf_len, fuzz_factor):
"""Calculate number of bytes to modify.
:param buf_len: len of data buffer to fuzz.
:param fuzz_factor: degree of fuzzing.
:return: number of bytes to change.
"""
return random.randrange(math.ceil((float(buf_len) / fuzz_factor))) + 1


@enum.unique
class Status(enum.Enum):
"""Status values for test runs."""
Expand Down Expand Up @@ -182,9 +202,8 @@ def __repr__(self):
count_failed = self.cumulated_counts_for_status(Status.FAILED)
count_succeeded = self.cumulated_counts_for_status(Status.SUCCESS)
count_all = count_succeeded + count_failed
info = 'Tests run/succeeded/failed: {} / {} / {}\n'.format(count_all,
count_succeeded,
count_failed)
tmpl = 'Tests run/succeeded/failed: {} / {} / {}\n'
info = tmpl.format(count_all, count_succeeded, count_failed)
for key in self.keys_:
info += '{}\n'.format(key)
for status in Status:
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ Sphinx
behave
setuptools
pylint
pytest
zc.buildout
56 changes: 31 additions & 25 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
# coding=utf-8
"""
fuzzing: Some general meta classes.
Note that "python setup.py test" invokes pytest on the package. With appropriately
configured setup.cfg, this will check both xxx_test modules and docstrings.
Note that "python setup.py test" invokes pytest on the package.
With appropriately configured setup.cfg, this will check both
xxx_test modules and docstrings.
Currently all tests are written for behave!
Copyright 2015, Stefan Braun.
Licensed under MIT.
"""
import sys
from setuptools import setup, find_packages
from setuptools.command.test import test as TestCommand
from setuptools import setup
from setuptools.command.test import test


class PyTest(TestCommand):
class PyTest(test):
"""This is a plug-in for setuptools.
It will invoke py.test when you run python setup.py test
"""

def finalize_options(self):
"""Configure."""
TestCommand.finalize_options(self)
test.finalize_options(self)
self.test_args = []
self.test_suite = True

def run_tests(self):
"""Execute tests."""
import pytest # import here, because outside the required eggs aren't loaded yet
# import here, because outside the required eggs aren't loaded yet
import pytest
sys.exit(pytest.main(self.test_args))


Expand All @@ -36,38 +40,40 @@ def run_tests(self):
version=version,
description="Tools for stress testing applications.",
long_description=open("README.rst").read(),
classifiers=[ # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Software Development :: Testing'
# Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=[
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Software Development :: Testing'
],
keywords="development tools", # Separate with spaces
author="Stefan Braun",
author_email="sb@action.ms",
url="https://github.com/stbraun/fuzzing",
license="MIT",
packages=find_packages(exclude=['examples', 'tests']),
packages=['fuzzing'],
include_package_data=True,
zip_safe=False,
tests_require=['pytest', 'behave>=1.2.4'],
tests_require=['pytest', 'behave>=1.2.4', 'nose'],
cmdclass={'test': PyTest},
scripts=['run_fuzzer.py', ],

# List of packages that this one depends upon:
install_requires=['sphinx', 'wrapt', 'PyYAML', 'argh', 'pathtools', 'setuptools'],
requires=['sphinx', 'wrapt', 'PyYAML', 'argh', 'pathtools', 'setuptools'],
install_requires=['sphinx', 'wrapt', 'PyYAML', 'argh', 'pathtools',
'setuptools', 'zc.buildout'],
requires=['wrapt', 'PyYAML', 'argh', 'pathtools', 'setuptools'],
provides=['fuzzing', 'gp_decorators'],
# entry_points={
# 'console_scripts':
# ['fuzzing=fuzzing:main']
# }
)
)

0 comments on commit 3291ef8

Please sign in to comment.