diff --git a/.flake8 b/.flake8
deleted file mode 100644
index 8f8cdc3..0000000
--- a/.flake8
+++ /dev/null
@@ -1,2 +0,0 @@
-[flake8]
-ignore = E501,E203
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4550298..3616bea 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -3,22 +3,22 @@ name: CI
on:
push:
branches:
- - main
+ - main
pull_request:
branches:
- - main
+ - main
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- - '3.8'
- - '3.9'
- - '3.10'
- - '3.11'
- - 'pypy-3.8'
- - 'pypy-3.9'
+ - "3.8"
+ - "3.9"
+ - "3.10"
+ - "3.11"
+ - "pypy-3.8"
+ - "pypy-3.9"
fail-fast: false
name: Test on Python ${{ matrix.python-version }}
steps:
diff --git a/Makefile b/Makefile
index 64032ab..9c66978 100644
--- a/Makefile
+++ b/Makefile
@@ -25,9 +25,10 @@ test: build
docs: build
$(BIN)/tox -e docs
-$(BIN)/black:
- $(BIN)/pip install black
+$(BIN)/ruff:
+ $(BIN)/pip install ruff
+
+ruff: $(BIN)/ruff
+ $(BIN)/ruff check setup.py molotov/
+ $(BIN)/ruff format setup.py molotov/*.py
-black: $(BIN)/black
- $(BIN)/black setup.py molotov/
- $(BIN)/flake8 molotov/
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 5d2a980..7422c88 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -31,31 +31,32 @@
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
-extensions = ['sphinxarg.ext', 'sphinx.ext.autodoc']
+extensions = ["sphinxarg.ext", "sphinx.ext.autodoc"]
# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
-source_suffix = '.rst'
+source_suffix = ".rst"
# The master toctree document.
-master_doc = 'index'
+master_doc = "index"
# General information about the project.
-project = 'Molotov'
-copyright = '2017, Tarek Ziadé'
-author = 'Tarek Ziadé'
+project = "Molotov"
+copyright = "2017, Tarek Ziadé"
+author = "Tarek Ziadé"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
-import molotov
+import molotov # noqa
+
release = version = molotov.__version__
# The language for content autogenerated by Sphinx. Refer to documentation
@@ -63,7 +64,7 @@
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
-language = 'en'
+language = "en"
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
@@ -71,7 +72,7 @@
exclude_patterns = []
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = "sphinx"
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
@@ -82,34 +83,36 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = 'alabaster'
-highlight_language = 'python3'
+html_theme = "alabaster"
+highlight_language = "python3"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
- 'logo': 'logo.png',
- 'description': 'Load Testing Tool',
- 'github_user': 'tarekziade',
- 'github_repo': 'molotov',
- 'github_button': True,
- 'github_type': 'star',
- 'github_banner': True,
- 'travis_button': False,
- 'pre_bg': '#FFF6E5',
- 'note_bg': '#E5ECD1',
- 'note_border': '#BFCF8C',
- 'body_text': '#482C0A',
- 'sidebar_text': '#49443E',
- 'sidebar_header': '#4B4032',
+ "logo": "logo.png",
+ "description": "Load Testing Tool",
+ "github_user": "tarekziade",
+ "github_repo": "molotov",
+ "github_button": True,
+ "github_type": "star",
+ "github_banner": True,
+ "travis_button": False,
+ "pre_bg": "#FFF6E5",
+ "note_bg": "#E5ECD1",
+ "note_border": "#BFCF8C",
+ "body_text": "#482C0A",
+ "sidebar_text": "#49443E",
+ "sidebar_header": "#4B4032",
}
html_sidebars = {
- '**': [
- 'about.html', 'navigation.html', 'searchbox.html',
+ "**": [
+ "about.html",
+ "navigation.html",
+ "searchbox.html",
]
}
@@ -117,13 +120,13 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = ["_static"]
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
-htmlhelp_basename = 'Molotovdoc'
+htmlhelp_basename = "Molotovdoc"
# -- Options for LaTeX output ---------------------------------------------
@@ -132,15 +135,12 @@
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
-
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
-
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
-
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
@@ -150,8 +150,7 @@
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
- (master_doc, 'Molotov.tex', 'Molotov Documentation',
- 'Tarek Ziadé', 'manual'),
+ (master_doc, "Molotov.tex", "Molotov Documentation", "Tarek Ziadé", "manual"),
]
@@ -159,10 +158,7 @@
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
-man_pages = [
- (master_doc, 'molotov', 'Molotov Documentation',
- [author], 1)
-]
+man_pages = [(master_doc, "molotov", "Molotov Documentation", [author], 1)]
# -- Options for Texinfo output -------------------------------------------
@@ -171,10 +167,13 @@
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
- (master_doc, 'Molotov', 'Molotov Documentation',
- author, 'Molotov', 'One line description of project.',
- 'Miscellaneous'),
+ (
+ master_doc,
+ "Molotov",
+ "Molotov Documentation",
+ author,
+ "Molotov",
+ "One line description of project.",
+ "Miscellaneous",
+ ),
]
-
-
-
diff --git a/molotov/api.py b/molotov/api.py
index 357aaa1..5a0ac26 100644
--- a/molotov/api.py
+++ b/molotov/api.py
@@ -1,7 +1,6 @@
-import random
-import functools
import asyncio
-
+import functools
+import random
_SCENARIO = {}
diff --git a/molotov/dummy.py b/molotov/dummy.py
index baa9d42..5eb357e 100644
--- a/molotov/dummy.py
+++ b/molotov/dummy.py
@@ -1,9 +1,10 @@
""" Molotov-based test.
"""
-import molotov
import random
from time import sleep
+import molotov
+
@molotov.global_setup()
def starting(args):
diff --git a/molotov/quickstart/__init__.py b/molotov/quickstart/__init__.py
index 35e21e8..04a5e34 100644
--- a/molotov/quickstart/__init__.py
+++ b/molotov/quickstart/__init__.py
@@ -1,9 +1,9 @@
-import sys
-import shutil
-import os
import argparse
-from molotov import __version__
+import os
+import shutil
+import sys
+from molotov import __version__
_DEFAULTS = {"target_dir": "."}
_PREFIX = "> "
diff --git a/molotov/quickstart/loadtest.py b/molotov/quickstart/loadtest.py
index a963c09..fa0cd10 100644
--- a/molotov/quickstart/loadtest.py
+++ b/molotov/quickstart/loadtest.py
@@ -1,8 +1,8 @@
""" Molotov-based test.
"""
import json
-from molotov import scenario, setup, global_setup, teardown, global_teardown
+from molotov import global_setup, global_teardown, scenario, setup, teardown
# This is the service you want to load test
_API = "http://localhost:8080"
diff --git a/molotov/run.py b/molotov/run.py
index f644a0e..9d5b59f 100644
--- a/molotov/run.py
+++ b/molotov/run.py
@@ -1,17 +1,15 @@
-import os
-import sys
import argparse
+import os
import platform
-
+import sys
from importlib import import_module
-from importlib.util import spec_from_file_location, module_from_spec
+from importlib.util import module_from_spec, spec_from_file_location
-from molotov.runner import Runner
-from molotov.api import get_scenarios, get_scenario
from molotov import __version__
-from molotov.util import expand_options, OptionError, printable_error
+from molotov.api import get_scenario, get_scenarios
+from molotov.runner import Runner
from molotov.ui.console import Console
-
+from molotov.util import OptionError, expand_options, printable_error
PYPY = platform.python_implementation() == "PyPy"
@@ -43,9 +41,7 @@ def _parser():
help="Name of a single scenario to run once.",
)
- parser.add_argument(
- "--config", default=None, type=str, help="Point to a JSON config file."
- )
+ parser.add_argument("--config", default=None, type=str, help="Point to a JSON config file.")
parser.add_argument(
"--version",
@@ -66,31 +62,18 @@ def _parser():
"--verbose",
action="count",
default=0,
- help=(
- "Verbosity level. -v will display "
- "tracebacks. -vv requests and responses."
- ),
+ help=("Verbosity level. -v will display " "tracebacks. -vv requests and responses."),
)
- parser.add_argument(
- "-w", "--workers", help="Number of workers", type=int, default=1
- )
+ parser.add_argument("-w", "--workers", help="Number of workers", type=int, default=1)
- parser.add_argument(
- "--ramp-up", help="Ramp-up time in seconds", type=float, default=0.0
- )
+ parser.add_argument("--ramp-up", help="Ramp-up time in seconds", type=float, default=0.0)
- parser.add_argument(
- "--sizing", help="Autosizing", action="store_true", default=False
- )
+ parser.add_argument("--sizing", help="Autosizing", action="store_true", default=False)
- parser.add_argument(
- "--sizing-tolerance", help="Sizing tolerance", type=float, default=5.0
- )
+ parser.add_argument("--sizing-tolerance", help="Sizing tolerance", type=float, default=5.0)
- parser.add_argument(
- "--delay", help="Delay between each worker run", type=float, default=0.0
- )
+ parser.add_argument("--delay", help="Delay between each worker run", type=float, default=0.0)
parser.add_argument(
"--console-update",
@@ -99,21 +82,13 @@ def _parser():
default=0.2,
)
- parser.add_argument(
- "-p", "--processes", help="Number of processes", type=int, default=1
- )
+ parser.add_argument("-p", "--processes", help="Number of processes", type=int, default=1)
- parser.add_argument(
- "-d", "--duration", help="Duration in seconds", type=int, default=86400
- )
+ parser.add_argument("-d", "--duration", help="Duration in seconds", type=int, default=86400)
- parser.add_argument(
- "-r", "--max-runs", help="Maximum runs per worker", type=int, default=None
- )
+ parser.add_argument("-r", "--max-runs", help="Maximum runs per worker", type=int, default=None)
- parser.add_argument(
- "-q", "--quiet", action="store_true", default=False, help="Quiet"
- )
+ parser.add_argument("-q", "--quiet", action="store_true", default=False, help="Quiet")
parser.add_argument(
"-x",
@@ -139,9 +114,7 @@ def _parser():
help="Use simple console for feedback",
)
- parser.add_argument(
- "--statsd", help="Activates statsd", action="store_true", default=False
- )
+ parser.add_argument("--statsd", help="Activates statsd", action="store_true", default=False)
parser.add_argument(
"--statsd-address",
@@ -150,9 +123,7 @@ def _parser():
default="udp://localhost:8125",
)
- parser.add_argument(
- "--uvloop", help="Use uvloop", default=False, action="store_true"
- )
+ parser.add_argument("--uvloop", help="Use uvloop", default=False, action="store_true")
parser.add_argument(
"--use-extension",
@@ -298,9 +269,7 @@ def run(args, stream=None):
if args.single_mode:
if get_scenario(args.single_mode) is None:
- direct_print(
- stream, "Can't find %r in registered scenarii" % args.single_mode
- )
+ direct_print(stream, "Can't find %r in registered scenarii" % args.single_mode)
sys.exit(1)
res = Runner(args)()
diff --git a/molotov/runner.py b/molotov/runner.py
index 5b3c1d2..5f021e2 100644
--- a/molotov/runner.py
+++ b/molotov/runner.py
@@ -1,19 +1,20 @@
-import signal
import asyncio
+import functools
import os
+import signal
+
import multiprocess
-import functools
from molotov.api import get_fixture
from molotov.listeners import EventSender
-from molotov.stats import get_statsd_client
from molotov.shared import Counters, Tasks
+from molotov.stats import get_statsd_client
from molotov.util import (
cancellable_sleep,
- stop,
+ event_loop,
is_stopped,
set_timer,
- event_loop,
+ stop,
)
from molotov.worker import Worker
@@ -95,7 +96,7 @@ def _launch_processes(self):
if not args.quiet:
self.console.print("Forking %d processes" % args.processes)
jobs = []
- for i in range(args.processes):
+ for _i in range(args.processes):
p = multiprocess.Process(target=self._process)
jobs.append(p)
p.start()
@@ -205,9 +206,7 @@ def _stop(*args):
self.loop.run_until_complete(gathered)
finally:
if self.statsd is not None and not self.statsd.disconnected:
- self.loop.run_until_complete(
- self._tasks.ensure_future(self.statsd.close())
- )
+ self.loop.run_until_complete(self._tasks.ensure_future(self.statsd.close()))
self.loop.run_until_complete(self._tasks.cancel_all())
self.loop.close()
diff --git a/molotov/session.py b/molotov/session.py
index bf46d3c..d72ac2d 100644
--- a/molotov/session.py
+++ b/molotov/session.py
@@ -1,13 +1,12 @@
-from time import perf_counter
import socket
-from types import SimpleNamespace
from collections import namedtuple
+from time import perf_counter
+from types import SimpleNamespace
-from aiohttp.client import ClientSession, ClientRequest, ClientResponse
from aiohttp import TCPConnector, TraceConfig
+from aiohttp.client import ClientRequest, ClientResponse, ClientSession
-from molotov.listeners import StdoutListener, EventSender
-
+from molotov.listeners import EventSender, StdoutListener
_HOST = socket.gethostname()
@@ -37,11 +36,7 @@ def __init__(self, loop, console, verbose, statsd):
self.verbose = verbose
self.eventer = EventSender(
console,
- [
- StdoutListener(
- verbose=self.verbose, console=self.console, loop=self.loop
- )
- ],
+ [StdoutListener(verbose=self.verbose, console=self.console, loop=self.loop)],
)
self.on_request_start.append(self._request_start)
self.on_request_end.append(self._request_end)
@@ -49,9 +44,7 @@ def __init__(self, loop, console, verbose, statsd):
self.context.statsd = statsd
def _trace_config_ctx_factory(self, trace_request_ctx):
- return SimpleNamespace(
- trace_request_ctx=trace_request_ctx, context=self.context
- )
+ return SimpleNamespace(trace_request_ctx=trace_request_ctx, context=self.context)
def add_listener(self, listener):
return self.eventer.add_listener(listener)
@@ -103,7 +96,7 @@ def get_session(loop, console, verbose=0, statsd=None, **kw):
response_class=LoggedClientResponse,
connector=connector,
trace_configs=[trace_config],
- **kw
+ **kw,
)
return session
diff --git a/molotov/shared/tasks.py b/molotov/shared/tasks.py
index f190c54..38ee5fa 100644
--- a/molotov/shared/tasks.py
+++ b/molotov/shared/tasks.py
@@ -1,5 +1,5 @@
-import os
import asyncio
+import os
from collections import defaultdict
from collections.abc import MutableSequence
from contextlib import suppress
diff --git a/molotov/slave.py b/molotov/slave.py
index 0963494..40a0221 100644
--- a/molotov/slave.py
+++ b/molotov/slave.py
@@ -1,15 +1,17 @@
+import argparse
import json
import os
-import sys
-import argparse
-from subprocess import check_call
-import tempfile
import shutil
import site
+import sys
+import tempfile
+from subprocess import check_call
+
import pkg_resources
from molotov import __version__
-from molotov.run import main as run, _parser
+from molotov.run import _parser
+from molotov.run import main as run
def clone_repo(github):
@@ -73,13 +75,9 @@ def main():
"--virtualenv", type=str, default="virtualenv", help="Virtualenv executable."
)
- parser.add_argument(
- "--python", type=str, default=sys.executable, help="Python executable."
- )
+ parser.add_argument("--python", type=str, default=sys.executable, help="Python executable.")
- parser.add_argument(
- "--directory", type=str, default=None, help="Directory to run into."
- )
+ parser.add_argument("--directory", type=str, default=None, help="Directory to run into.")
parser.add_argument(
"--config",
@@ -122,9 +120,7 @@ def main():
# load deps into sys.path
pyver = "%d.%d" % (sys.version_info.major, sys.version_info.minor)
- site_pkg = os.path.join(
- args.directory, "venv", "lib", "python" + pyver, "site-packages"
- )
+ site_pkg = os.path.join(args.directory, "venv", "lib", "python" + pyver, "site-packages")
site.addsitedir(site_pkg)
pkg_resources.working_set.add_entry(site_pkg)
diff --git a/molotov/stats.py b/molotov/stats.py
index 8f69372..3f1f8f0 100644
--- a/molotov/stats.py
+++ b/molotov/stats.py
@@ -1,4 +1,5 @@
from urllib.parse import urlparse
+
from aiodogstatsd import Client
diff --git a/molotov/tests/example.py b/molotov/tests/example.py
index db3e358..07d2e7d 100644
--- a/molotov/tests/example.py
+++ b/molotov/tests/example.py
@@ -9,16 +9,16 @@
"""
import json
+
from molotov import (
- scenario,
- setup,
+ get_context,
global_setup,
global_teardown,
+ scenario,
+ setup,
teardown,
- get_context,
)
-
_API = "http://localhost:8080"
_HEADERS = {}
diff --git a/molotov/tests/example2.py b/molotov/tests/example2.py
index 747d745..2a9e8f2 100644
--- a/molotov/tests/example2.py
+++ b/molotov/tests/example2.py
@@ -5,7 +5,6 @@
"""
from molotov import scenario
-
_API = "http://localhost:8080"
diff --git a/molotov/tests/example3.py b/molotov/tests/example3.py
index 94b3c44..0002f0a 100644
--- a/molotov/tests/example3.py
+++ b/molotov/tests/example3.py
@@ -1,4 +1,4 @@
-from molotov import scenario, global_setup
+from molotov import global_setup, scenario
@global_setup()
diff --git a/molotov/tests/example6.py b/molotov/tests/example6.py
index bb25c1d..3dbce7d 100644
--- a/molotov/tests/example6.py
+++ b/molotov/tests/example6.py
@@ -4,9 +4,9 @@
the average response time.
"""
-import molotov
import time
+import molotov
_T = {}
diff --git a/molotov/tests/example7.py b/molotov/tests/example7.py
index f43885b..80766b0 100644
--- a/molotov/tests/example7.py
+++ b/molotov/tests/example7.py
@@ -3,9 +3,9 @@
This Molotov script uses events to display concurrency info
"""
-import molotov
import time
+import molotov
concurs = [] # [(timestamp, worker count)]
diff --git a/molotov/tests/example8.py b/molotov/tests/example8.py
index 1c0519e..1f171b0 100644
--- a/molotov/tests/example8.py
+++ b/molotov/tests/example8.py
@@ -4,9 +4,10 @@
"""
import json
-import molotov
import time
+import molotov
+
_T = {}
diff --git a/molotov/tests/example9.py b/molotov/tests/example9.py
index b081c2a..28bc8d5 100644
--- a/molotov/tests/example9.py
+++ b/molotov/tests/example9.py
@@ -1,9 +1,10 @@
"""
Molotov scripts can import modules from the same dir
"""
-from molotov import scenario
from mylib import get_url
+from molotov import scenario
+
@scenario(weight=1)
async def my_scenario(session):
diff --git a/molotov/tests/statsd.py b/molotov/tests/statsd.py
index 1d36d9a..589bd0b 100644
--- a/molotov/tests/statsd.py
+++ b/molotov/tests/statsd.py
@@ -1,8 +1,9 @@
-import multiprocess
import asyncio
-import signal
import functools
import os
+import signal
+
+import multiprocess
def debug(data):
diff --git a/molotov/tests/support.py b/molotov/tests/support.py
index 3e61563..8233dda 100644
--- a/molotov/tests/support.py
+++ b/molotov/tests/support.py
@@ -1,29 +1,29 @@
-import sys
-import signal
-import os
import asyncio
-import unittest
-import time
-from contextlib import contextmanager
import functools
+import http.server
+import os
+import signal
+import socketserver
+import sys
+import time
+import unittest
from collections import namedtuple
+from contextlib import contextmanager
from http.client import HTTPConnection
from io import StringIO
-import http.server
-import socketserver
-import pytest
from unittest.mock import patch
import multiprocess
+import pytest
from aiohttp.client_reqrep import URL
from multidict import CIMultiDict
-from molotov.api import _SCENARIO, _FIXTURES
+
from molotov import util
+from molotov.api import _FIXTURES, _SCENARIO
from molotov.run import PYPY
from molotov.session import LoggedClientRequest, LoggedClientResponse
-from molotov.ui.console import Console
from molotov.shared.counter import Counters
-
+from molotov.ui.console import Console
HERE = os.path.dirname(__file__)
diff --git a/molotov/tests/test_api.py b/molotov/tests/test_api.py
index a3d7de8..0044aad 100644
--- a/molotov/tests/test_api.py
+++ b/molotov/tests/test_api.py
@@ -1,4 +1,4 @@
-from molotov.api import pick_scenario, scenario, get_scenarios, setup
+from molotov.api import get_scenarios, pick_scenario, scenario, setup
from molotov.tests.support import TestLoop, async_test
diff --git a/molotov/tests/test_console.py b/molotov/tests/test_console.py
index dc7a306..1dae1de 100644
--- a/molotov/tests/test_console.py
+++ b/molotov/tests/test_console.py
@@ -1,13 +1,13 @@
-import unittest
import asyncio
-import sys
import os
import re
+import sys
+import unittest
+
import multiprocess
+from molotov.tests.support import catch_output, dedicatedloop
from molotov.ui.console import Console
-from molotov.tests.support import dedicatedloop, catch_output
-
OUTPUT = """\
one
@@ -27,7 +27,7 @@ def run_worker(input):
_PROC.append(os.getpid())
_CONSOLE.print("hello")
try:
- 3 + ""
+ 3 + "" # noqa
except Exception:
_CONSOLE.print_error("meh")
@@ -61,7 +61,7 @@ async def add_lines():
console.print("two")
console.print("3")
try:
- 1 + "e"
+ 1 + "e" # noqa
except Exception as e:
console.print_error(e)
console.print_error(e, sys.exc_info()[2])
diff --git a/molotov/tests/test_fmwk.py b/molotov/tests/test_fmwk.py
index 322eb06..fc1fe67 100644
--- a/molotov/tests/test_fmwk.py
+++ b/molotov/tests/test_fmwk.py
@@ -1,30 +1,30 @@
+import asyncio
import os
import signal
-import asyncio
-from molotov.session import get_session
-from molotov.runner import Runner
-from molotov.worker import Worker
-from molotov.util import get_var, set_var, json_request, request, stop_reason
from molotov.api import (
- scenario,
- setup,
+ events,
global_setup,
- teardown,
global_teardown,
+ scenario,
+ scenario_picker,
+ setup,
setup_session,
+ teardown,
teardown_session,
- scenario_picker,
- events,
)
+from molotov.runner import Runner
+from molotov.session import get_session
from molotov.tests.support import (
TestLoop,
async_test,
- dedicatedloop,
catch_sleep,
coserver,
+ dedicatedloop,
patch_errors,
)
+from molotov.util import get_var, json_request, request, set_var, stop_reason
+from molotov.worker import Worker
class TestFmwk(TestLoop):
diff --git a/molotov/tests/test_quickstart.py b/molotov/tests/test_quickstart.py
index f31f61c..5432de8 100644
--- a/molotov/tests/test_quickstart.py
+++ b/molotov/tests/test_quickstart.py
@@ -1,9 +1,9 @@
-import tempfile
-import shutil
import os
+import shutil
+import tempfile
-from molotov import quickstart, __version__, run
-from molotov.tests.support import set_args, TestLoop, dedicatedloop
+from molotov import __version__, quickstart, run
+from molotov.tests.support import TestLoop, dedicatedloop, set_args
class TestQuickStart(TestLoop):
diff --git a/molotov/tests/test_run.py b/molotov/tests/test_run.py
index 0517d59..27461c4 100644
--- a/molotov/tests/test_run.py
+++ b/molotov/tests/test_run.py
@@ -1,36 +1,35 @@
-import unittest
-import time
-import random
-import os
-import signal
import asyncio
-from unittest.mock import patch
+import io
+import json
+import os
+import random
import re
+import signal
+import time
+import unittest
from collections import defaultdict
-import json
-import io
+from unittest.mock import patch
import aiohttp
-from molotov.api import scenario, global_setup
+from molotov import __version__
+from molotov.api import global_setup, scenario
+from molotov.run import main, run
+from molotov.session import get_context
+from molotov.shared.counter import Counters
+from molotov.tests.statsd import run_server, stop_server
from molotov.tests.support import (
TestLoop,
+ catch_sleep,
+ co_catch_output,
coserver,
dedicatedloop,
+ dedicatedloop_noclose,
+ only_pypy,
set_args,
skip_pypy,
- only_pypy,
- catch_sleep,
- dedicatedloop_noclose,
- co_catch_output,
)
-from molotov.tests.statsd import run_server, stop_server
-from molotov.run import run, main
-from molotov.shared.counter import Counters
-from molotov.util import request, json_request, set_timer
-from molotov.session import get_context
-from molotov import __version__
-
+from molotov.util import json_request, request, set_timer
_HERE = os.path.dirname(__file__)
_CONFIG = os.path.join(_HERE, "molotov.json")
@@ -107,7 +106,7 @@ async def here_one(session):
async def here_two(session):
statsd = get_context(session).statsd
if statsd is not None:
- for i in range(10):
+ for _i in range(10):
statsd.increment("user.online")
await asyncio.sleep(0)
@@ -233,7 +232,7 @@ async def here_three(session):
def test_fail_mode_fail(self):
@scenario(weight=10)
async def here_three(session):
- assert False
+ raise AssertionError()
stdout, stderr, rc = self._test_molotov(
"-x",
diff --git a/molotov/tests/test_session.py b/molotov/tests/test_session.py
index 787a549..6b1064f 100644
--- a/molotov/tests/test_session.py
+++ b/molotov/tests/test_session.py
@@ -1,13 +1,21 @@
import gzip
+from unittest.mock import patch
+
from aiohttp.client_reqrep import ClientRequest
from yarl import URL
-from unittest.mock import patch
-from molotov.listeners import BaseListener
import molotov.session
+from molotov.listeners import BaseListener
from molotov.session import get_eventer
-from molotov.tests.support import coserver, Response, Request
-from molotov.tests.support import TestLoop, async_test, patch_print, patch_errors
+from molotov.tests.support import (
+ Request,
+ Response,
+ TestLoop,
+ async_test,
+ coserver,
+ patch_errors,
+ patch_print,
+)
class TestLoggedClientSession(TestLoop):
diff --git a/molotov/tests/test_sharedcounter.py b/molotov/tests/test_sharedcounter.py
index 605a90d..1bd732c 100644
--- a/molotov/tests/test_sharedcounter.py
+++ b/molotov/tests/test_sharedcounter.py
@@ -1,8 +1,9 @@
import os
import unittest
+
import multiprocess
-from molotov.shared.counter import Counters, Counter
+from molotov.shared.counter import Counter, Counters
# pre-forked variable
_DATA = Counters("test")
@@ -39,7 +40,7 @@ def _t():
self.assertRaises(NotImplementedError, _t)
def _c():
- Counter("ok") != 6.3
+ Counter("ok") != 6.3 # noqa
self.assertRaises(TypeError, _c)
diff --git a/molotov/tests/test_slave.py b/molotov/tests/test_slave.py
index 9469349..521e72f 100644
--- a/molotov/tests/test_slave.py
+++ b/molotov/tests/test_slave.py
@@ -1,15 +1,15 @@
import os
-import pytest
-from unittest import mock
-import tempfile
import subprocess
-from shutil import copytree, copyfile
+import tempfile
+from shutil import copyfile, copytree
+from unittest import mock
+
+import pytest
from molotov import __version__
from molotov.slave import main
from molotov.tests.support import TestLoop, dedicatedloop, set_args
-
_REPO = "https://github.com/loads/molotov"
NO_INTERNET = os.environ.get("NO_INTERNET") is not None
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
diff --git a/molotov/tests/test_util.py b/molotov/tests/test_util.py
index d60a357..e80cc8e 100644
--- a/molotov/tests/test_util.py
+++ b/molotov/tests/test_util.py
@@ -1,10 +1,10 @@
-from io import StringIO
-from tempfile import mkstemp
import json
-import unittest
import os
-from molotov.util import expand_options, OptionError, set_var, get_var, _VARS
+import unittest
+from io import StringIO
+from tempfile import mkstemp
+from molotov.util import _VARS, OptionError, expand_options, get_var, set_var
_HERE = os.path.dirname(__file__)
config = os.path.join(_HERE, "..", "..", "molotov.json")
diff --git a/molotov/ui/app.py b/molotov/ui/app.py
index fa06996..690642b 100644
--- a/molotov/ui/app.py
+++ b/molotov/ui/app.py
@@ -1,8 +1,9 @@
import asyncio
-import sys
-import shutil
import io
+import shutil
+import sys
+from prompt_toolkit import HTML
from prompt_toolkit.application import Application
from prompt_toolkit.layout import (
FormattedTextControl,
@@ -11,17 +12,15 @@
VSplit,
Window,
)
-from prompt_toolkit import HTML
from molotov import __version__
from molotov.ui.controllers import (
- TerminalController,
- SimpleController,
RunStatus,
+ SimpleController,
+ TerminalController,
create_key_bindings,
)
-
TITLE = HTML(
f"Molotov v{__version__} ~ Happy Breaking 🥛🔨 ~ Ctrl+C to abort"
)
diff --git a/molotov/ui/console.py b/molotov/ui/console.py
index 6313b8e..131533f 100644
--- a/molotov/ui/console.py
+++ b/molotov/ui/console.py
@@ -1,7 +1,7 @@
import os
-from molotov.util import printable_error
from molotov.ui.app import MolotovApp
+from molotov.util import printable_error
class Console:
diff --git a/molotov/ui/controllers.py b/molotov/ui/controllers.py
index 92a6dc5..49c44a2 100644
--- a/molotov/ui/controllers.py
+++ b/molotov/ui/controllers.py
@@ -1,10 +1,10 @@
-import multiprocess
-import queue
import os
+import queue
import signal
from datetime import datetime
import humanize
+import multiprocess
from prompt_toolkit import HTML
from prompt_toolkit.formatted_text import to_formatted_text
from prompt_toolkit.key_binding import KeyBindings
diff --git a/molotov/util.py b/molotov/util.py
index 459851d..bfcbd98 100644
--- a/molotov/util.py
+++ b/molotov/util.py
@@ -1,16 +1,15 @@
-from io import StringIO
-import traceback
-import sys
+import asyncio
import functools
import json
import os
-import asyncio
-import time
+import sys
import threading
+import time
+import traceback
+from io import StringIO
from aiohttp import ClientSession, __version__
-
_DNS_CACHE = {}
_STOP = False
_STOP_WHY = []
@@ -69,8 +68,8 @@ def expand_options(config, scenario, args):
if not isinstance(config, str):
try:
config = json.loads(config.read())
- except Exception:
- raise OptionError("Can't parse %r" % config)
+ except Exception as err:
+ raise OptionError("Can't parse %r" % config) from err
else:
if not os.path.exists(config):
raise OptionError("Can't find %r" % config)
@@ -78,8 +77,8 @@ def expand_options(config, scenario, args):
with open(config) as f:
try:
config = json.loads(f.read())
- except ValueError:
- raise OptionError("Can't parse %r" % config)
+ except ValueError as err:
+ raise OptionError("Can't parse %r" % config) from err
if "molotov" not in config:
raise OptionError("Bad config -- no molotov key")
@@ -161,9 +160,7 @@ def request(endpoint, verb="GET", session_options=None, **options):
def json_request(endpoint, verb="GET", session_options=None, **options):
"""Like :func:`molotov.request` but extracts json from the response."""
- req = functools.partial(
- _request, endpoint, verb, session_options, json=True, **options
- )
+ req = functools.partial(_request, endpoint, verb, session_options, json=True, **options)
return _run_in_fresh_loop(req)
diff --git a/molotov/worker.py b/molotov/worker.py
index 4bb6b8d..0f924aa 100644
--- a/molotov/worker.py
+++ b/molotov/worker.py
@@ -1,10 +1,10 @@
import asyncio
from inspect import isgenerator
+from molotov.api import get_fixture, get_scenario, next_scenario, pick_scenario
from molotov.listeners import EventSender
-from molotov.session import get_session, get_context
-from molotov.api import get_fixture, pick_scenario, get_scenario, next_scenario
-from molotov.util import cancellable_sleep, is_stopped, set_timer, get_timer, stop, now
+from molotov.session import get_context, get_session
+from molotov.util import cancellable_sleep, get_timer, is_stopped, now, set_timer, stop
class FixtureError(Exception):
@@ -74,7 +74,7 @@ async def setup(self):
options = await self._setup(self.wid, self.args)
except Exception as e:
self.console.print_error(e)
- raise FixtureError(str(e))
+ raise FixtureError(str(e)) from e
if options is None:
options = {}
@@ -92,7 +92,7 @@ async def session_setup(self, session):
await self._session_setup(self.wid, session)
except Exception as e:
self.console.print_error(e)
- raise FixtureError(str(e))
+ raise FixtureError(str(e)) from e
async def session_teardown(self, session):
if self._session_teardown is None:
@@ -133,9 +133,7 @@ async def _run(self):
self.print("Setting up session")
- async with get_session(
- self.loop, self.console, verbose, self.statsd, **options
- ) as session:
+ async with get_session(self.loop, self.console, verbose, self.statsd, **options) as session:
await asyncio.sleep(0)
get_context(session).args = self.args
get_context(session).worker_id = self.wid
diff --git a/ruff.toml b/ruff.toml
new file mode 100644
index 0000000..a885855
--- /dev/null
+++ b/ruff.toml
@@ -0,0 +1,8 @@
+select = ["E4", "E7", "E9", "F", "B", "Q", "I"]
+
+exclude = [
+ ".git",
+ "bin",
+]
+
+line-length = 100
diff --git a/setup.py b/setup.py
index 8f2e9dc..b1ae99b 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,6 @@
import sys
-from setuptools import setup, find_packages
+
+from setuptools import find_packages, setup
if sys.version_info < (3, 8):
raise ValueError("Requires Python 3.8 or superior")
diff --git a/tox.ini b/tox.ini
index dea7900..41c8b03 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
[tox]
downloadcache = {toxworkdir}/cache/
-envlist = py312,py311,py310,py39,py38,flake8,docs,pypy3
+envlist = py312,py311,py310,py39,py38,ruff,docs,pypy3
[testenv:py310]
passenv =
@@ -33,10 +33,12 @@ deps = -rtox-pypy-requirements.txt
commands =
pytest --random-order-bucket=global -sv molotov/tests
-[testenv:flake8]
-commands = flake8 molotov
+[testenv:ruff]
+commands =
+ ruff check setup.py molotov
+ ruf format setup.py molotov/*.py
deps =
- flake8
+ ruff
[testenv:docs]
deps =