108 lines
5.2 KiB
Python
108 lines
5.2 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||
|
import datetime
|
||
|
import json
|
||
|
|
||
|
from unittest.mock import patch
|
||
|
|
||
|
from odoo.tools import mute_logger
|
||
|
from odoo.tests.common import HttpCase, tagged
|
||
|
|
||
|
|
||
|
class ProfilingHttpCase(HttpCase):
|
||
|
|
||
|
@classmethod
|
||
|
def setUpClass(cls):
|
||
|
super().setUpClass()
|
||
|
# Trick: we patch db_connect() to make it return the registry; when the
|
||
|
# profiler calls cursor() on it, it gets a test cursor (with cls.cr as
|
||
|
# its actual cursor), which prevents the profiling data from being
|
||
|
# committed for real.
|
||
|
cls.patcher = patch('odoo.sql_db.db_connect', return_value=cls.registry)
|
||
|
cls.startClassPatcher(cls.patcher)
|
||
|
|
||
|
def profile_rpc(self, params=None):
|
||
|
params = params or {}
|
||
|
req = self.url_open(
|
||
|
'/web/dataset/call_kw/ir.profile/set_profiling', # use model and method in route has web client does
|
||
|
headers={'Content-Type': 'application/json'},
|
||
|
data=json.dumps({'params':{
|
||
|
'model': 'ir.profile',
|
||
|
'method': 'set_profiling',
|
||
|
'args': [],
|
||
|
'kwargs': params,
|
||
|
}})
|
||
|
)
|
||
|
req.raise_for_status()
|
||
|
return req.json()
|
||
|
|
||
|
@tagged('post_install', '-at_install', 'profiling')
|
||
|
class TestProfilingWeb(ProfilingHttpCase):
|
||
|
def test_profiling_enabled(self):
|
||
|
# since profiling will use a direct connection to the database patch 'db_connect' to ensure we are using the test cursor
|
||
|
self.authenticate('admin', 'admin')
|
||
|
last_profile = self.env['ir.profile'].search([], limit=1, order='id desc')
|
||
|
# Trying to start profiling when not enabled
|
||
|
self.env['ir.config_parameter'].set_param('base.profiling_enabled_until', '')
|
||
|
res = self.profile_rpc({'profile': 1})
|
||
|
self.assertEqual(res['result']['res_model'], 'base.enable.profiling.wizard')
|
||
|
self.assertEqual(last_profile, self.env['ir.profile'].search([], limit=1, order='id desc'))
|
||
|
|
||
|
# Enable profiling and start blank profiling
|
||
|
expiration = datetime.datetime.now() + datetime.timedelta(seconds=50)
|
||
|
self.env['ir.config_parameter'].set_param('base.profiling_enabled_until', expiration)
|
||
|
res = self.profile_rpc({'profile': 1})
|
||
|
self.assertTrue(res['result']['session'])
|
||
|
self.assertEqual(last_profile, self.env['ir.profile'].search([], limit=1, order='id desc'), "profiling route shouldn't have been profiled")
|
||
|
# Profile a page
|
||
|
res = self.url_open('/web/speedscope') # profile a light route
|
||
|
new_profile = self.env['ir.profile'].search([], limit=1, order='id desc')
|
||
|
self.assertNotEqual(last_profile, new_profile, "A new profile should have been created")
|
||
|
self.assertEqual(new_profile.name, '/web/speedscope?')
|
||
|
|
||
|
|
||
|
@tagged('post_install', '-at_install', 'profiling')
|
||
|
class TestProfilingModes(ProfilingHttpCase):
|
||
|
def test_profile_collectors(self):
|
||
|
expiration = datetime.datetime.now() + datetime.timedelta(seconds=50)
|
||
|
self.env['ir.config_parameter'].set_param('base.profiling_enabled_until', expiration)
|
||
|
|
||
|
self.authenticate('admin', 'admin')
|
||
|
res = self.profile_rpc({})
|
||
|
self.assertEqual(res['result']['collectors'], None)
|
||
|
res = self.profile_rpc({'profile': 1, 'collectors': ['sql', 'traces_async']})
|
||
|
self.assertEqual(sorted(res['result']['collectors']), ['sql', 'traces_async'])
|
||
|
res = self.profile_rpc({'collectors': ['sql']})
|
||
|
self.assertEqual(res['result']['collectors'], ['sql'],)
|
||
|
res = self.profile_rpc({'profile': 0})
|
||
|
res = self.profile_rpc({'profile': 1})
|
||
|
self.assertEqual(res['result']['collectors'], ['sql'],
|
||
|
"Enabling and disabling profiling shouldn't have change existing preferences")
|
||
|
|
||
|
|
||
|
@tagged('post_install', '-at_install', 'profiling')
|
||
|
class TestProfilingPublic(ProfilingHttpCase):
|
||
|
|
||
|
def test_public_user_profiling(self):
|
||
|
last_profile = self.env['ir.profile'].search([], limit=1, order='id desc')
|
||
|
self.env['ir.config_parameter'].set_param('base.profiling_enabled_until', '')
|
||
|
self.authenticate(None, None)
|
||
|
|
||
|
res = self.url_open('/web/set_profiling?profile=1')
|
||
|
self.assertEqual(res.status_code, 500)
|
||
|
self.assertEqual(res.text, 'error: Profiling is not enabled on this database. Please contact an administrator.')
|
||
|
|
||
|
expiration = datetime.datetime.now() + datetime.timedelta(seconds=50)
|
||
|
self.env['ir.config_parameter'].set_param('base.profiling_enabled_until', expiration)
|
||
|
res = self.url_open('/web/set_profiling?profile=1')
|
||
|
self.assertEqual(res.status_code, 200)
|
||
|
res = res.json()
|
||
|
self.assertTrue(res.pop('session'))
|
||
|
self.assertEqual(res, {"collectors": ["sql", "traces_async"], "params": {}})
|
||
|
self.assertEqual(last_profile, self.env['ir.profile'].search([], limit=1, order='id desc'), "profiling route shouldn't have been profiled")
|
||
|
|
||
|
res = self.url_open('/web/login') # profile /web/login to avoid redirections of /
|
||
|
new_profile = self.env['ir.profile'].search([], limit=1, order='id desc')
|
||
|
self.assertNotEqual(last_profile, new_profile, "A route should have been profiled")
|
||
|
self.assertEqual(new_profile.name, '/web/login?')
|