diff options
| author | Jeremy Kersten <jke@odoo.com> | 2019-07-11 17:00:30 +0000 |
|---|---|---|
| committer | Jeremy Kersten <jke@odoo.com> | 2019-07-24 09:03:13 +0000 |
| commit | 8a80efd7cd9f564338c6ca6c72e49f6890190b4c (patch) | |
| tree | 5cb228f1488e4b062a4ccec5adfccca4de2b25b6 /addons/gamification/tests | |
| parent | 78b09d82fb16181c3ae2e4964f3cff30b76424db (diff) | |
[FIX] gamification: perf on write karma_min on gamification.karma.rank
This commits avoid to call recompute when you write on the rank without
touch the karma_min value.
On write on karma_min, we have 2 cases:
- Rank order are the same, just need to recompute the rank for the user
that could be impacted. Eg. if karma_min changes from 45 to 50, we need
to recheck for all user between 45 and 50 their new rank.
- Rank order are not the same, we need to recompute for all users.
(could be still improved if needed)
When you recompute the rank on a list of users, depending of the number of
users (bulk if more than 3 * number of rank) we check for each user what is
the new rank, or for each rank whats is the new users.
task-internal
No way to edit a rank on the prod server. Lock sql -> crash server
closes odoo/odoo#34835
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Diffstat (limited to 'addons/gamification/tests')
| -rw-r--r-- | addons/gamification/tests/__init__.py | 1 | ||||
| -rw-r--r-- | addons/gamification/tests/test_recompute_rank.py | 128 |
2 files changed, 129 insertions, 0 deletions
diff --git a/addons/gamification/tests/__init__.py b/addons/gamification/tests/__init__.py index 0219f6754d0..a6a599bf6c8 100644 --- a/addons/gamification/tests/__init__.py +++ b/addons/gamification/tests/__init__.py @@ -2,3 +2,4 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import test_challenge +from . import test_recompute_rank diff --git a/addons/gamification/tests/test_recompute_rank.py b/addons/gamification/tests/test_recompute_rank.py new file mode 100644 index 00000000000..c82fb4759fd --- /dev/null +++ b/addons/gamification/tests/test_recompute_rank.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests import common +from unittest.mock import patch + + +class TestComputeRankCommon(common.TransactionCase): + + def setUp(self): + super(TestComputeRankCommon, self).setUp() + + def _patched_send_mail(*args, **kwargs): + pass + + self.User = self.env['res.users'].with_context(no_reset_password=True, mail_create_nosubscribe=True) + self.users = self.User + + patch_email = patch('odoo.addons.mail.models.mail_template.MailTemplate.send_mail', _patched_send_mail) + patch_email.start() + for k in range(-5, 1030, 30): + self.users += self.User.create({ + 'name': str(k), + 'login': "test_recompute_rank_%s" % k, + 'karma': k, + }) + + self.env['gamification.karma.rank'].search([]).unlink() + + self.rank_1 = self.env['gamification.karma.rank'].create({ + 'name': 'rank 1', + 'karma_min': 0, + }) + + self.rank_2 = self.env['gamification.karma.rank'].create({ + 'name': 'rank 2', + 'karma_min': 250, + }) + + self.rank_3 = self.env['gamification.karma.rank'].create({ + 'name': 'rank 3', + 'karma_min': 500, + }) + self.rank_4 = self.env['gamification.karma.rank'].create({ + 'name': 'rank 4', + 'karma_min': 1000, + }) + + patch_email.stop() + + +class test_recompute(TestComputeRankCommon): + + def test_00_initial_compute(self): + + self.assertEqual(len(self.users), 35) + + self.assertEqual( + len(self.rank_1.user_ids & self.users), + len([u for u in self.users if u.karma >= self.rank_1.karma_min and u.karma < self.rank_2.karma_min]) + ) + self.assertEqual( + len(self.rank_2.user_ids & self.users), + len([u for u in self.users if u.karma >= self.rank_2.karma_min and u.karma < self.rank_3.karma_min]) + ) + self.assertEqual( + len(self.rank_3.user_ids & self.users), + len([u for u in self.users if u.karma >= self.rank_3.karma_min and u.karma < self.rank_4.karma_min]) + ) + self.assertEqual( + len(self.rank_4.user_ids & self.users), + len([u for u in self.users if u.karma >= self.rank_4.karma_min]) + ) + + def test_01_switch_rank(self): + + self.assertEqual(len(self.users), 35) + + self.rank_3.karma_min = 100 + # rank_1 -> rank_3 -> rank_2 -> rank_4 + + self.assertEqual( + len(self.rank_1.user_ids & self.users), + len([u for u in self.users if u.karma >= self.rank_1.karma_min and u.karma < self.rank_3.karma_min]) + ) + self.assertEqual( + len(self.rank_3.user_ids & self.users), + len([u for u in self.users if u.karma >= self.rank_3.karma_min and u.karma < self.rank_2.karma_min]) + ) + self.assertEqual( + len(self.rank_2.user_ids & self.users), + len([u for u in self.users if u.karma >= self.rank_2.karma_min and u.karma < self.rank_4.karma_min]) + ) + self.assertEqual( + len(self.rank_4.user_ids & self.users), + len([u for u in self.users if u.karma >= self.rank_4.karma_min]) + ) + + def test_02_update_rank_without_switch(self): + number_of_users = False + + def _patched_recompute_rank(_self, *args, **kwargs): + nonlocal number_of_users + number_of_users = len(_self & self.users) + + patch_bulk = patch('odoo.addons.gamification.models.res_users.Users._recompute_rank', _patched_recompute_rank) + patch_bulk.start() + self.rank_3.karma_min = 700 + self.assertEqual(number_of_users, 7, "Should just recompute for the 7 users between 500 and 700") + patch_bulk.stop() + + def test_03_test_bulk_call(self): + self.assertEqual(len(self.users), 35) + + def _patched_check_in_bulk(*args, **kwargs): + raise + + patch_bulk = patch('odoo.addons.gamification.models.res_users.Users._recompute_rank_bulk', _patched_check_in_bulk) + patch_bulk.start() + + # call on 5 users should not trigger the bulk function + self.users[0:5]._recompute_rank() + + # call on 50 users should trigger the bulk function + with self.assertRaises(Exception): + self.users[0:50]._recompute_rank() + + patch_bulk.stop() |
