Skip to content

nseinlet/OdooLocust

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OdooLocust

An Odoo load testing solution, using odoolib and Locust. Locust API changed a bit, and OdooLocust follow this change.

Links

HowTo

To load test Odoo, you create tests like you'll have done it with Locust:

from locust import task, between
from OdooLocust.OdooLocustUser import OdooLocustUser


class Seller(OdooLocustUser):
    wait_time = between(0.1, 10)
    database = "test_db"
    login = "admin"
    password = "secret_password"
    port = 443
    protocol = "jsonrpcs"

    @task(10)
    def read_partners(self):
        cust_model = self.client.get_model('res.partner')
        cust_ids = cust_model.search([])
        prtns = cust_model.read(cust_ids)

    @task(5)
    def read_products(self):
        prod_model = self.client.get_model('product.product')
        ids = prod_model.search([])
        prods = 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', 'ipad')])

        order_id = 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}),
                          ]
        })
        so_model.action_button_confirm([order_id])

The host on which run the load is defined in locust.conf file, either in your project folder or home folder, as explained in Locust doc: https://docs.locust.io/en/stable/configuration.html#configuration-file

host=localhost
users = 100
spawn-rate = 10

then you run your locust tests the usual way:

locust -f my_file.py

Generic test

This version is shipped with a generic TaskSet task, OdooTaskSet, and an OdooGenericTaskSet, designed to test form/list/kanban/search of a given model. To use this version, create this simple test file:

from OdooLocust.OdooLocustUser import OdooLocustUser
from locust import task, between
from OdooLocust import OdooTaskSet


class Lead(OdooTaskSet.OdooGenericTaskSet):
    model_name = 'crm.lead'

class Partner(OdooTaskSet.OdooGenericTaskSet):
    model_name = 'res.partner'

class GenericTest(OdooLocustUser):
    wait_time = between(0.1, 1)
    database = "my_db"
    login = "admin"
    password = "secure_password"
    port = 443
    protocol = "jsonrpcs"

    @task(10)
    def read_partners(self):
        cust_model = self.client.get_model('res.partner')
        cust_ids = cust_model.search([], limit=80)
        prtns = cust_model.read(cust_ids, ['name'])

    tasks = {Lead: 1, Partner: 5}

This will create a task which will test the crm.lead form,list,kanban and search views, and one for res.partner. Of course you can add your own methods to this class, like a lead creation.

And you finally run your locust tests the usual way:

locust -f my_file.py

CRM test

This version is shipped with some CRM tests.

# -*- coding: utf-8 -*-
from OdooLocust import OdooLocustUser, crm

class OdooCom(OdooLocustUser.OdooLocustUser):
    host = "erp.mycompany.com"
    database = "my_db"
    login = "admin"
    password = "secure_password"
    port = 443
    protocol = "jsonrpcs"

    tasks = {crm.partner.ResPartner: 1, crm.lead.CrmLead: 2, crm.quotation.SaleOrder: 1}

Test with workers

As Locust use greenlet, you're using one core of your computer. If this is a limiting factor, it's possible to use multiple workers. It's also possible to run a headless test, to automate it. This sh file run a headless test, without asking host, users, ... using an Odoo load test file called load_odoo.py:

#!/bin/bash
if [ -z "$3" ]
  then
      echo "No argument supplied"
      echo "start_workers.sh nbr_workers concurrency time"
      exit 1
fi
x=1
while [ $x -le $1 ]
do
  locust -f load_odoo.py --worker --only-summary > /dev/null 2>&1 &
  x=$(( $x + 1 ))
done
locust -f load_odoo.py --headless --users $2 --spawn-rate $2 --run-time $3m --master --expect-workers=$1