Testez la montée en charge d'Odoo avec LOCUST

Locust est un framework de test de montée en charge open source (sous licence MIT), facile à utiliser, distribué, écrit en Python. Il permet de définir le comportement des utilisateurs avec du code Python, simuler plusieurs millions d'utilisateurs simultanés, définir et maîtriser la montée en charge et peut être configuré en multi-machines.
Locust est facile à installer et sa documentation est bien fournie.
Dans ce mini tutoriel, nous allons utiliser Locust pour tester la montée en charge d'Odoo et pour cela, nous allons nous baser sur OdooLocust, un package python basé sur odoolib et locust.
Installation
Dans un environnement virtuel python, nous allons installer locustio
, locust
et odoo-client-lib
.
virtualenv sandbox --python=python3.5
source sandbox/bin/activate
pip install odoo-client-lib==1.2.2 locustio locust
Nous allons également installer OdooLocust
git clone https://github.com/anybox/OdooLocust.git
cd OdooLocust/
sandbox/bin/python setup.py install
Scénario
Sur une version 12.0 d'Odoo communautaire, nous allons effectuer le scénario suivant:
- Lire les ID des partenaires
- Lire les ID des Produits
- Créer un bon de commande
Ci-dessous, le contenu du fichier odoo_locust.py
utilisé
from locust import task, TaskSet
class SellerTaskSet(TaskSet):
@task(10)
def read_partners(self):
cust_model = self.client.get_model('res.partner')
cust_ids = cust_model.search([])
cust_model.read(cust_ids)
@task(5)
def read_products(self):
prod_model = self.client.get_model('product.product')
ids = prod_model.search([])
prod_model.read(ids)
@task(20)
def create_so(self):
prod_model = self.client.get_model('product.product')
cust_model = self.client.get_model('res.partner')
so_model = self.client.get_model('sale.order')
cust_id = cust_model.search([('name', 'ilike', 'fletch')])[0]
prod_ids = prod_model.search([('name', 'ilike', 'drawer')])
so_model.create({
'partner_id': cust_id,
'order_line': [(0, 0, {'product_id': prod_ids[0],
'product_uom_qty':1}),
(0, 0, {'product_id': prod_ids[1],
'product_uom_qty':2})],
})
@task
utilise un argument de pondération facultatif qui peut être utilisé pour spécifier le taux d’exécution de la tâche. Dans l'exemple ci-dessus, la 3e tâche (create_so) sera exécutée deux fois plus que la 1ere tâche (read_partners) et 4 fois plus que la 2e tâche (read_products)
Maintenant, nous allons définir les paramètres qui seront utilisés par Locust dans un fichier nommé profile.py
from OdooLocust import OdooLocust
from odoo_locust import SellerTaskSet
class Seller(OdooLocust.OdooLocust):
# Odoo options
host = "127.0.0.1"
database = "locust"
login = "admin"
password = "admin"
# Locust options
min_wait = 100
max_wait = 1000
weight = 3
task_set = SellerTaskSet
Explications
host, database
,login
,password
: addresse IP du serveur, nom de la base de données, login et mot de passe de l'utilisateur Odoo.max_wait = 1000
: temps de pondération maximum entre l'exécution des tâchesmin_wait = 100
: temps de pondération minimum entre l'exécution des tâches- La classe
SellerTaskSet
définit le comportement d'exécution weight = 3
: Cette attribut permet de définir la probabilité de sélection. Ceci est nécessaire lorsqu'on a plusieurs classes Locust (ce qui n'est pas notre cas). Plus cette valeur est élevée, plus la chance d'être choisi est grande.
Supposons, par exemple, que les utilisateurs web soient trois fois plus fréquents que les utilisateurs mobiles:
class WebUserLocust(Locust):
weight = 3
...
class MobileUserLocust(Locust):
weight = 1
...
Exécution
Exécutez le fichier python profile.py
avec la commande suivante
locust -f profile.py Seller

Maintenant, allez à l'addresse http://127.0.0.1:8089 sur votre navigateur web.

Dans l'interface ci-dessus, Locust a besoin de deux données pour commencer à stresser odoo.
- Nombre d'utilisateurs à simuler
- Taux d'éclosion: à quelle vitesse veulent-ils engendrer les utilisateurs
Example:
Number of users to simulate
: 10 | Hatch rate (user spawned / second)
: 2
Lorsque nous commençons le test de charge avec cette configuration, Locust génère deux nouveaux utilisateurs toutes les secondes jusqu'à ce qu'il atteigne le nombre total d'utilisateurs à simuler (ce qui est 10 dans ce cas). Après 05 secondes, vous aurez un essaim de 10 utilisateurs simulés.
Pour contrôler le nombre de demandes par seconde, vous devrez définir un max_wait
en conséquence.
Le résultat du test pour l'exemple ci-dessus est le suivant.




Allez plus loin...
Les tableaux générés par Locust sont agréables, mais nous préférerions voir les résultats sur un graphique. Ce problème est connu et plusieurs personnes souhaitent ajouter une interface graphique à Locust. Plusieurs propositions permettant d'afficher des graphiques de données sur Locust ont déjà été faites. Dans cet exemple, nous allons utiliser la bibliothèque de visualisation interactive Python Bokeh.
Son installation est simple:
pip install bokeh
Voici un exemple d'exécution du serveur Bokeh.
Nous pouvons obtenir des données Locust au format JSON
en visitant http://localhost:8089/stats/request. Ces données devraient ressembler à ceci:
{
"current_response_time_percentile_50": 260,
"current_response_time_percentile_95": 4200,
"errors": [],
"fail_ratio": 0.0,
"state": "running",
"stats": [
{
"avg_content_length": 28.0,
"avg_response_time": 139.6,
"current_rps": 0.0,
"max_response_time": 269,
"median_response_time": 120,
"method": "Odoo JsonRPC",
"min_response_time": 86,
"name": "common : login",
"num_failures": 0,
"num_requests": 10
},
{
"avg_content_length": 181.4791389848525,
"avg_response_time": 1161.0988572947117,
"current_rps": 7.4,
"max_response_time": 7959,
"median_response_time": 220,
"method": null,
"min_response_time": 17,
"name": "Total",
"num_failures": 0,
"num_requests": 7526
}
],
"total_rps": 7.4,
"user_count": 10
}
Pour afficher ces données sur des graphiques interactifs, nous allons créer un script python basé sur l'utilisation de la bibliothèque de visualisation python Bokeh, et le placer dans le répertoire dans lequel se trouve notre fichier profile.py
Un exemple de script est disponible ici. Ci-dessous, le résultat
