def from_har_file(
        cls,
        path: Path,
        plugins: Sequence[Plugin],
        ts_plugins: Sequence[Plugin],
        short_name: bool,
        blacklist: Blacklist,
    ) -> "Scenario":
        """
        Creates a Scenario given a HAR file.

        :raise SkippableScenarioError: if path is unreadable or not a HAR file
        """
        try:
            with path.open() as file:
                har = json.load(file)
            requests = Request.all_from_har(har)
            tasks = Task.from_requests(requests, blacklist)

            # TODO: Remove this when Contract.OnTaskSequence is removed.
            tasks = plug.apply(ts_plugins, tasks)

            # TODO: Remove Task-to-Task2 conversion once both are merged.
            tasks = tuple(
                plug.apply(plugins, Task2.from_task(t)) for t in tasks)

            return Scenario(
                name=to_identifier(
                    path.with_suffix("").name if short_name else str(path)),
                children=tuple(tasks),
                origin=path,
                weight=cls.weight_from_path(path),
            )
        except (OSError, json.JSONDecodeError, UnicodeDecodeError) as err:
            raise SkippableScenarioError(path, err)
Beispiel #2
0
    def test_runs_plugins_in_succession_on_input(self):
        @plugin(Contract.OnTask)
        def plugin_a(x: str) -> str:
            return x + "a"

        @plugin(Contract.OnTask)
        def plugin_b(x: str) -> str:
            return x + "b"

        assert apply((plugin_a, plugin_b), "") == "ab"
        assert apply((plugin_b, plugin_a, plugin_b), "") == "bab"
Beispiel #3
0
def locustfile_lines(scenarios: Sequence[Scenario],
                     program_plugins: Sequence[Plugin]) -> Iterator[str]:
    """
    Converts the provided scenarios into a stream of Python statements
    and iterate on the resulting lines.
    """
    program = plug.apply(program_plugins, locust_program(scenarios))
    for stmt in program:
        for line in stmt.lines():
            yield str(line)
Beispiel #4
0
    def apply_plugins(self, plugins: Sequence[Plugin]) -> "Scenario":
        """
        Recursively builds a new scenario tree from the leaves by applying all
        plugins to each cloned scenario subtree.
        Does not do anything if plugins is empty.
        """
        if not plugins:
            return self

        children = [
            c.apply_plugins(plugins) if isinstance(c, Scenario) else c
            for c in self.children
        ]
        return plug.apply(plugins, self._replace(children=children))
    def apply_plugins(self, plugins: Sequence[Plugin]) -> "Scenario":
        """
        Recursively builds a new scenario tree from the leaves by applying all
        *plugins* to each cloned scenario subtree.

        Does not do anything if *plugins* is empty.

        :param plugins: the plugins to apply.
            See :ref:`Specifying-plugins` for details.
        """
        if not plugins:
            return self

        children = [
            c.apply_plugins(plugins) if isinstance(c, Scenario) else c
            for c in self.children
        ]
        return plug.apply(plugins, dataclasses.replace(self,
                                                       children=children))
Beispiel #6
0
    def test_return_plugin_result(self):
        @plugin(Contract.OnTask)
        def plugin_a(x: str) -> str:
            return x + "a"

        assert apply([plugin_a], "z") == "za"
Beispiel #7
0
 def test_return_init_unchanged_without_plugins(self):
     x = object()
     assert apply([], x) is x
    def test_it_renders_a_locustfile_template_with_plugin_change_task_name(
            self):
        @plugin(Contract.OnTask)
        def plugin_change_task_name(t: Task2) -> Task2:
            t.request.name = "changed_name"
            return t

        a_name = "some_task"
        a_request = MagicMock(spec=Request)
        a_request.method = HttpMethod.GET
        a_request.url = MagicMock(spec=SplitResult)
        a_request.url.scheme = "some_scheme"
        a_request.url.hostname = "some_hostname"
        a_request.url.path = "some_path"
        a_request.url.geturl()
        a_request.url.geturl.return_value = "some_url"
        a_request.headers = {"a": "b"}
        a_request.name = None
        task = plug.apply((plugin_change_task_name, ), Task(a_name, a_request))
        scenario = Scenario(name="SomeScenario", children=[task], origin=None)
        scenario_group = Scenario(name="ScenarioGroup",
                                  children=[scenario],
                                  weight=2,
                                  origin=None)
        script = locustfile([scenario_group])
        expected = string.Template(f"""
# File automatically generated by Transformer v{__version__}:
# https://github.com/zalando-incubator/Transformer
import re
from distutils.version import LooseVersion
from locust import __version__
LOCUST_MAJOR_VERSION = LooseVersion(__version__).version[0]
if LOCUST_MAJOR_VERSION >= 1:
    from locust import HttpUser
    from locust import SequentialTaskSet
    from locust import TaskSet
    from locust import task
    HttpLocust = HttpUser
    TaskSequence = SequentialTaskSet
    def seq_task(_):
        return task
else:
    from locust import HttpLocust
    from locust import TaskSequence
    from locust import TaskSet
    from locust import seq_task
    from locust import task
class ScenarioGroup(TaskSet):
    @task(1)
    class SomeScenario(TaskSequence):
        @seq_task(1)
        def some_task(self):
            response = self.client.get(url='some_url', name='changed_name', timeout=$TIMEOUT, allow_redirects=False, headers={{'a': 'b'}})
class LocustForScenarioGroup(HttpLocust):
    if LOCUST_MAJOR_VERSION >= 1:
        tasks = [ScenarioGroup]
    else:
        task_set = ScenarioGroup
    weight = 2
    min_wait = 0
    max_wait = 10
""").safe_substitute({"TIMEOUT": TIMEOUT})
        assert expected.strip() == script.strip()