Skip to content
This repository was archived by the owner on Apr 2, 2024. It is now read-only.
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
1 change: 1 addition & 0 deletions docs/source/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Glossary
The agent isn't sending itself the queries, it creates a worker which does
it instead.

users
virtual users
When running a test, you can chose the number of users you want to have in
parallel. This is called the number of virtual users.
57 changes: 57 additions & 0 deletions docs/source/guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,60 @@ the test is successful::
At the end of the test, you will be able to know how many times the counter
was incremented.


.. _randomness-section:

Testing random actions
----------------------

Since your test method will be called several times per :term:`user`s
(See :ref:`users and hits <users-hits-section>`), you may want to introduce
some entropy in order to simulate the behaviour of a real user.

A good practice is to rely on randomness to control the distribution of the
test actions::

import random
from loads.case import TestCase

WRITE_PERCENTAGE = 30

class TestAction(TestCase):

def test_api(self):
if random.randint(0, 100) < WRITE_PERCENTAGE:
self.test_write()
else:
self.test_read()


.. _authenticating-session-section:

Authenticated sessions
----------------------

If you want to map :term:`virtual users` to actual users on your remote server,
you shall perform authentication during the test initialization.

For example, using *Requests*::

import uuid
from requests import auth as requests_auth
from loads.case import TestCase

class TestAuthenticatedAction(TestCase):

def __init__(self, *args, **kwargs):
super(TestAuthenticatedAction, self).__init__(*args, **kwargs)

random_user = uuid.uuid4().hex
random_pwd = uuid.uuid4().hex

# Create the user on your remote server
# ...

self.auth = requests_auth.HTTPBasicAuth(random_user, random_pwd)

def test_api(self):
res = self.session.get('http://localhost:8000', auth=self.auth)
self.assertEqual(res.status_code, 200)
35 changes: 30 additions & 5 deletions docs/source/internals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@ to smoke test your service - or simply because you don't need
to send a huge load. That's the *non-distributed* mode.


.. _users-hits-section:

About users and hits
====================

Loads will *instantiate* your test class as many times as *users* specified.
Hence, any operations related to test suite initialization, such as
:ref:`authenticating the session <authenticating-session-section>` or creating
initial test data, shall be performed in the test ``__init__`` method.

Loads will then *run* your test method as many times as *hits* specified.
Unless your goal is to test the same specific usage scenario in parallel,
:ref:`relying on randomness <randomness-section>` to execute various different
actions might become relevant.

.. note::

Loads test methods are executed using *gevent*. Therefore the order of
execution of each hit is basically asynchronous and not deterministic.


What happens during a non-distributed run
=========================================

Expand All @@ -24,7 +45,9 @@ What happens during a non-distributed run
2. A `loads.case.TestResult` object is created. This object is a data
collector, it is passed to the test suite (`TestCase`), the loads `Session`
object and the websocket manager. Its very purpose is to collect the data
from these sources. You can read more in the section named `TestResult` below.
from these sources.

You can read more in the :ref:`TestResult section <testresult-section>`.

3. We create any number of outputs (standard output, html output, etc.) in the
runner and register them to the test_result object.
Expand All @@ -37,11 +60,11 @@ What happens during a non-distributed run

6. During the tests, both the requests' `Session`, the test case itself and the
websocket objects report their progress in real time to test_result. When
there is a need to disambiguate the calls, a loads_status object is passed
along.
there is a need to disambiguate the calls, a ``loads_status`` attribute is
available on the session object.

It contains data about the hits, the total number of users, the current
user and the current hit.
It is a tuple containing respectively the hits, the total number of users,
the current user and the current hit.

7. Each time a call is made to the test_result object to add data, it notifies
its list of observers to be sure they are up to date. This is helpful to
Expand Down Expand Up @@ -83,6 +106,8 @@ In more details:
can get them.


.. _testresult-section:

The TestResult object
=====================

Expand Down