test_performances.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. import random
  4. from odoo.addons.crm.tests.test_crm_lead_assignment import TestLeadAssignCommon
  5. from odoo.tests.common import tagged
  6. from odoo.tools import mute_logger
  7. @tagged('lead_assign', 'crm_performance', 'post_install', '-at_install')
  8. class TestLeadAssignPerf(TestLeadAssignCommon):
  9. """ Test performances of lead assignment feature added in saas-14.2
  10. Assign process is a random process: randomizing teams leads to searching,
  11. assigning and de-duplicating leads in various order. As a lot of search
  12. are implied during assign process query counters may vary from run to run.
  13. "Heavy" performance test included here ranged from 6K to 6.3K queries. Either
  14. we set high counters maximum which makes those tests less useful. Either we
  15. avoid random if possible which is what we decided to do by setting the seed
  16. of random in tests.
  17. """
  18. @mute_logger('odoo.models.unlink', 'odoo.addons.crm.models.crm_team', 'odoo.addons.crm.models.crm_team_member')
  19. def test_assign_perf_duplicates(self):
  20. """ Test assign process with duplicates on partner. Allow to ensure notably
  21. that de duplication is effectively performed. """
  22. # fix the seed and avoid randomness
  23. random.seed(1940)
  24. leads = self._create_leads_batch(
  25. lead_type='lead',
  26. user_ids=[False],
  27. partner_ids=[self.contact_1.id, self.contact_2.id, False, False, False],
  28. count=200
  29. )
  30. # commit probability and related fields
  31. leads.flush_recordset()
  32. self.assertInitialData()
  33. # assign probability to leads (bypass auto probability as purpose is not to test pls)
  34. leads = self.env['crm.lead'].search([('id', 'in', leads.ids)]) # ensure order
  35. for idx in range(0, 5):
  36. sliced_leads = leads[idx:len(leads):5]
  37. for lead in sliced_leads:
  38. lead.probability = (idx + 1) * 10 * ((int(lead.priority) + 1) / 2)
  39. # commit probability and related fields
  40. leads.flush_recordset()
  41. # randomness: at least 1 query
  42. with self.with_user('user_sales_manager'):
  43. self.env['res.users'].has_group('base.group_user') # warmup the cache to avoid inconsistency between community an enterprise
  44. with self.assertQueryCount(user_sales_manager=1266): # crm 1187
  45. self.env['crm.team'].browse(self.sales_teams.ids)._action_assign_leads(work_days=2)
  46. # teams assign
  47. leads = self.env['crm.lead'].search([('id', 'in', leads.ids)]) # ensure order
  48. leads_st1 = leads.filtered_domain([('team_id', '=', self.sales_team_1.id)])
  49. leads_stc = leads.filtered_domain([('team_id', '=', self.sales_team_convert.id)])
  50. self.assertLessEqual(len(leads_st1), 128)
  51. self.assertLessEqual(len(leads_stc), 96)
  52. self.assertEqual(len(leads_st1) + len(leads_stc), len(leads)) # Make sure all lead are assigned
  53. # salespersons assign
  54. self.members.invalidate_model(['lead_month_count'])
  55. self.assertMemberAssign(self.sales_team_1_m1, 11) # 45 max on 2 days (3) + compensation (8.4)
  56. self.assertMemberAssign(self.sales_team_1_m2, 4) # 15 max on 2 days (1) + compensation (2.8)
  57. self.assertMemberAssign(self.sales_team_1_m3, 4) # 15 max on 2 days (1) + compensation (2.8)
  58. self.assertMemberAssign(self.sales_team_convert_m1, 8) # 30 max on 15 (2) + compensation (5.6)
  59. self.assertMemberAssign(self.sales_team_convert_m2, 15) # 60 max on 15 (4) + compsantion (11.2)
  60. @mute_logger('odoo.models.unlink', 'odoo.addons.crm.models.crm_team', 'odoo.addons.crm.models.crm_team_member')
  61. def test_assign_perf_no_duplicates(self):
  62. # fix the seed and avoid randomness
  63. random.seed(1945)
  64. leads = self._create_leads_batch(
  65. lead_type='lead',
  66. user_ids=[False],
  67. partner_ids=[False],
  68. count=100
  69. )
  70. # commit probability and related fields
  71. leads.flush_recordset()
  72. self.assertInitialData()
  73. # assign probability to leads (bypass auto probability as purpose is not to test pls)
  74. leads = self.env['crm.lead'].search([('id', 'in', leads.ids)]) # ensure order
  75. for idx in range(0, 5):
  76. sliced_leads = leads[idx:len(leads):5]
  77. for lead in sliced_leads:
  78. lead.probability = (idx + 1) * 10 * ((int(lead.priority) + 1) / 2)
  79. # commit probability and related fields
  80. leads.flush_recordset()
  81. # randomness: at least 1 query
  82. with self.with_user('user_sales_manager'):
  83. with self.assertQueryCount(user_sales_manager=585): # crm 584
  84. self.env['crm.team'].browse(self.sales_teams.ids)._action_assign_leads(work_days=2)
  85. # teams assign
  86. leads = self.env['crm.lead'].search([('id', 'in', leads.ids)]) # ensure order
  87. leads_st1 = leads.filtered_domain([('team_id', '=', self.sales_team_1.id)])
  88. leads_stc = leads.filtered_domain([('team_id', '=', self.sales_team_convert.id)])
  89. self.assertEqual(len(leads_st1) + len(leads_stc), 100)
  90. # salespersons assign
  91. self.members.invalidate_model(['lead_month_count'])
  92. self.assertMemberAssign(self.sales_team_1_m1, 11) # 45 max on 2 days (3) + compensation (8.4)
  93. self.assertMemberAssign(self.sales_team_1_m2, 4) # 15 max on 2 days (1) + compensation (2.8)
  94. self.assertMemberAssign(self.sales_team_1_m3, 4) # 15 max on 2 days (1) + compensation (2.8)
  95. self.assertMemberAssign(self.sales_team_convert_m1, 8) # 30 max on 15 (2) + compensation (5.6)
  96. self.assertMemberAssign(self.sales_team_convert_m2, 15) # 60 max on 15 (4) + compensation (11.2)
  97. @mute_logger('odoo.models.unlink', 'odoo.addons.crm.models.crm_team', 'odoo.addons.crm.models.crm_team_member')
  98. def test_assign_perf_populated(self):
  99. """ Test assignment on a more high volume oriented test set in order to
  100. have more insights on query counts. """
  101. # fix the seed and avoid randomness
  102. random.seed(1871)
  103. # create leads enough to have interesting counters
  104. _lead_count, _email_dup_count, _partner_count = 600, 50, 150
  105. leads = self._create_leads_batch(
  106. lead_type='lead',
  107. user_ids=[False],
  108. partner_count=_partner_count,
  109. country_ids=[self.env.ref('base.be').id, self.env.ref('base.fr').id, False],
  110. count=_lead_count,
  111. email_dup_count=_email_dup_count)
  112. # commit probability and related fields
  113. leads.flush_recordset()
  114. self.assertInitialData()
  115. # assign for one month, aka a lot
  116. self.env.ref('crm.ir_cron_crm_lead_assign').write({'interval_type': 'days', 'interval_number': 30})
  117. # create a third team
  118. sales_team_3 = self.env['crm.team'].create({
  119. 'name': 'Sales Team 3',
  120. 'sequence': 15,
  121. 'alias_name': False,
  122. 'use_leads': True,
  123. 'use_opportunities': True,
  124. 'company_id': False,
  125. 'user_id': False,
  126. 'assignment_domain': [('country_id', '!=', False)],
  127. })
  128. sales_team_3_m1 = self.env['crm.team.member'].create({
  129. 'user_id': self.user_sales_manager.id,
  130. 'crm_team_id': sales_team_3.id,
  131. 'assignment_max': 60,
  132. 'assignment_domain': False,
  133. })
  134. sales_team_3_m2 = self.env['crm.team.member'].create({
  135. 'user_id': self.user_sales_leads.id,
  136. 'crm_team_id': sales_team_3.id,
  137. 'assignment_max': 60,
  138. 'assignment_domain': False,
  139. })
  140. sales_team_3_m3 = self.env['crm.team.member'].create({
  141. 'user_id': self.user_sales_salesman.id,
  142. 'crm_team_id': sales_team_3.id,
  143. 'assignment_max': 15,
  144. 'assignment_domain': [('probability', '>=', 10)],
  145. })
  146. sales_teams = self.sales_teams | sales_team_3
  147. self.assertEqual(sum(team.assignment_max for team in sales_teams), 300)
  148. self.assertEqual(len(leads), 650)
  149. # assign probability to leads (bypass auto probability as purpose is not to test pls)
  150. leads = self.env['crm.lead'].search([('id', 'in', leads.ids)]) # ensure order
  151. for idx in range(0, 5):
  152. sliced_leads = leads[idx:len(leads):5]
  153. for lead in sliced_leads:
  154. lead.probability = (idx + 1) * 10 * ((int(lead.priority) + 1) / 2)
  155. # commit probability and related fields
  156. leads.flush_recordset()
  157. # randomness
  158. with self.with_user('user_sales_manager'):
  159. with self.assertQueryCount(user_sales_manager=6280): # crm 6226 / com 6276 / ent 6278
  160. self.env['crm.team'].browse(sales_teams.ids)._action_assign_leads(work_days=30)
  161. # teams assign
  162. leads = self.env['crm.lead'].search([('id', 'in', leads.ids)])
  163. self.assertEqual(leads.team_id, sales_teams)
  164. self.assertEqual(leads.user_id, sales_teams.member_ids)
  165. # salespersons assign
  166. self.members.invalidate_model(['lead_month_count'])
  167. self.assertMemberAssign(self.sales_team_1_m1, 45) # 45 max on one month
  168. self.assertMemberAssign(self.sales_team_1_m2, 15) # 15 max on one month
  169. self.assertMemberAssign(self.sales_team_1_m3, 15) # 15 max on one month
  170. self.assertMemberAssign(self.sales_team_convert_m1, 30) # 30 max on one month
  171. self.assertMemberAssign(self.sales_team_convert_m2, 60) # 60 max on one month
  172. self.assertMemberAssign(sales_team_3_m1, 60) # 60 max on one month
  173. self.assertMemberAssign(sales_team_3_m2, 60) # 60 max on one month
  174. self.assertMemberAssign(sales_team_3_m3, 15) # 15 max on one month