summaryrefslogtreecommitdiff
path: root/addons/test_mail/tests/test_performance.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/test_mail/tests/test_performance.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/test_mail/tests/test_performance.py')
-rw-r--r--addons/test_mail/tests/test_performance.py1021
1 files changed, 1021 insertions, 0 deletions
diff --git a/addons/test_mail/tests/test_performance.py b/addons/test_mail/tests/test_performance.py
new file mode 100644
index 00000000..6862160a
--- /dev/null
+++ b/addons/test_mail/tests/test_performance.py
@@ -0,0 +1,1021 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+import base64
+
+from odoo.addons.base.tests.common import TransactionCaseWithUserDemo
+from odoo.tests.common import users, warmup
+from odoo.tests import tagged
+from odoo.tools import mute_logger, formataddr
+
+
+@tagged('mail_performance')
+class BaseMailPerformance(TransactionCaseWithUserDemo):
+
+ def setUp(self):
+ super(BaseMailPerformance, self).setUp()
+ self._quick_create_ctx = {
+ 'no_reset_password': True,
+ 'mail_create_nolog': True,
+ 'mail_create_nosubscribe': True,
+ 'mail_notrack': True,
+ }
+ self.user_employee = self.env['res.users'].with_context(self._quick_create_ctx).create({
+ 'name': 'Ernest Employee',
+ 'login': 'emp',
+ 'email': 'e.e@example.com',
+ 'signature': '--\nErnest',
+ 'notification_type': 'inbox',
+ 'groups_id': [(6, 0, [self.env.ref('base.group_user').id, self.env.ref('base.group_partner_manager').id])],
+ })
+
+ # patch registry to simulate a ready environment
+ self.patch(self.env.registry, 'ready', True)
+
+
+@tagged('mail_performance')
+class TestMailPerformance(BaseMailPerformance):
+
+ def setUp(self):
+ super(TestMailPerformance, self).setUp()
+
+ self.res_partner_3 = self.env['res.partner'].create({
+ 'name': 'Gemini Furniture',
+ 'email': 'gemini.furniture39@example.com',
+ })
+ self.res_partner_4 = self.env['res.partner'].create({
+ 'name': 'Ready Mat',
+ 'email': 'ready.mat28@example.com',
+ })
+ self.res_partner_10 = self.env['res.partner'].create({
+ 'name': 'The Jackson Group',
+ 'email': 'jackson.group82@example.com',
+ })
+ self.res_partner_12 = self.env['res.partner'].create({
+ 'name': 'Azure Interior',
+ 'email': 'azure.Interior24@example.com',
+ })
+ self.env['mail.performance.thread'].create([
+ {
+ 'name': 'Object 0',
+ 'value': 0,
+ 'partner_id': self.res_partner_3.id,
+ }, {
+ 'name': 'Object 1',
+ 'value': 10,
+ 'partner_id': self.res_partner_3.id,
+ }, {
+ 'name': 'Object 2',
+ 'value': 20,
+ 'partner_id': self.res_partner_4.id,
+ }, {
+ 'name': 'Object 3',
+ 'value': 30,
+ 'partner_id': self.res_partner_10.id,
+ }, {
+ 'name': 'Object 4',
+ 'value': 40,
+ 'partner_id': self.res_partner_12.id,
+ }
+ ])
+
+ @users('__system__', 'demo')
+ @warmup
+ def test_read_mail(self):
+ """ Read records inheriting from 'mail.thread'. """
+ records = self.env['mail.performance.thread'].search([])
+ self.assertEqual(len(records), 5)
+
+ with self.assertQueryCount(__system__=2, demo=2):
+ # without cache
+ for record in records:
+ record.partner_id.country_id.name
+
+ with self.assertQueryCount(0):
+ # with cache
+ for record in records:
+ record.partner_id.country_id.name
+
+ with self.assertQueryCount(0):
+ # value_pc must have been prefetched, too
+ for record in records:
+ record.value_pc
+
+ @users('__system__', 'demo')
+ @warmup
+ def test_write_mail(self):
+ """ Write records inheriting from 'mail.thread' (no recomputation). """
+ records = self.env['mail.performance.thread'].search([])
+ self.assertEqual(len(records), 5)
+
+ with self.assertQueryCount(__system__=2, demo=2):
+ records.write({'name': 'X'})
+
+ @users('__system__', 'demo')
+ @warmup
+ def test_write_mail_with_recomputation(self):
+ """ Write records inheriting from 'mail.thread' (with recomputation). """
+ records = self.env['mail.performance.thread'].search([])
+ self.assertEqual(len(records), 5)
+
+ with self.assertQueryCount(__system__=2, demo=2):
+ records.write({'value': 42})
+
+ @users('__system__', 'demo')
+ @warmup
+ def test_write_mail_with_tracking(self):
+ """ Write records inheriting from 'mail.thread' (with field tracking). """
+ record = self.env['mail.performance.thread'].create({
+ 'name': 'Test',
+ 'track': 'Y',
+ 'value': 40,
+ 'partner_id': self.res_partner_12.id,
+ })
+
+ with self.assertQueryCount(__system__=3, demo=3):
+ record.track = 'X'
+
+ @users('__system__', 'demo')
+ @warmup
+ def test_create_mail(self):
+ """ Create records inheriting from 'mail.thread' (without field tracking). """
+ model = self.env['mail.performance.thread']
+
+ with self.assertQueryCount(__system__=2, demo=2):
+ model.with_context(tracking_disable=True).create({'name': 'X'})
+
+ @users('__system__', 'demo')
+ @warmup
+ def test_create_mail_with_tracking(self):
+ """ Create records inheriting from 'mail.thread' (with field tracking). """
+ with self.assertQueryCount(__system__=7, demo=7):
+ self.env['mail.performance.thread'].create({'name': 'X'})
+
+ @users('__system__', 'emp')
+ @warmup
+ def test_create_mail_simple(self):
+ with self.assertQueryCount(__system__=6, emp=6):
+ self.env['mail.test.simple'].create({'name': 'Test'})
+
+ @users('__system__', 'emp')
+ @warmup
+ def test_write_mail_simple(self):
+ rec = self.env['mail.test.simple'].create({'name': 'Test'})
+ with self.assertQueryCount(__system__=1, emp=1):
+ rec.write({
+ 'name': 'Test2',
+ 'email_from': 'test@test.com',
+ })
+
+
+@tagged('mail_performance')
+class TestMailAPIPerformance(BaseMailPerformance):
+
+ def setUp(self):
+ super(TestMailAPIPerformance, self).setUp()
+ self.customer = self.env['res.partner'].with_context(self._quick_create_ctx).create({
+ 'name': 'Test Customer',
+ 'email': 'customer.test@example.com',
+ })
+ self.user_test = self.env['res.users'].with_context(self._quick_create_ctx).create({
+ 'name': 'Paulette Testouille',
+ 'login': 'paul',
+ 'email': 'user.test.paulette@example.com',
+ 'notification_type': 'inbox',
+ 'groups_id': [(6, 0, [self.env.ref('base.group_user').id])],
+ })
+
+ # automatically follow activities, for backward compatibility concerning query count
+ self.env.ref('mail.mt_activities').write({'default': True})
+
+ def _create_test_records(self):
+ self.test_record_full = self.env['mail.test.ticket'].with_context(self._quick_create_ctx).create({
+ 'name': 'TestRecord',
+ 'customer_id': self.customer.id,
+ 'user_id': self.user_test.id,
+ 'email_from': 'nopartner.test@example.com',
+ })
+ self.test_template_full = self.env['mail.template'].create({
+ 'name': 'TestTemplate',
+ 'model_id': self.env['ir.model']._get('mail.test.ticket').id,
+ 'subject': 'About ${object.name}',
+ 'body_html': '<p>Hello ${object.name}</p>',
+ 'email_from': '${object.user_id.email_formatted | safe}',
+ 'partner_to': '${object.customer_id.id}',
+ 'email_to': '${("%s Customer <%s>" % (object.name, object.email_from)) | safe}',
+ })
+
+ @users('__system__', 'emp')
+ @warmup
+ def test_adv_activity(self):
+ model = self.env['mail.test.activity']
+
+ with self.assertQueryCount(__system__=6, emp=6):
+ model.create({'name': 'Test'})
+
+ @users('__system__', 'emp')
+ @warmup
+ @mute_logger('odoo.models.unlink')
+ def test_adv_activity_full(self):
+ record = self.env['mail.test.activity'].create({'name': 'Test'})
+ MailActivity = self.env['mail.activity'].with_context({
+ 'default_res_model': 'mail.test.activity',
+ })
+
+ with self.assertQueryCount(__system__=6, emp=6):
+ activity = MailActivity.create({
+ 'summary': 'Test Activity',
+ 'res_id': record.id,
+ 'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id,
+ })
+ #read activity_type to normalize cache between enterprise and community
+ #voip module read activity_type during create leading to one less query in enterprise on action_feedback
+ category = activity.activity_type_id.category
+
+ with self.assertQueryCount(__system__=16, emp=20):
+ activity.action_feedback(feedback='Zizisse Done !')
+
+ @users('__system__', 'emp')
+ @warmup
+ @mute_logger('odoo.models.unlink')
+ def test_adv_activity_mixin(self):
+ record = self.env['mail.test.activity'].create({'name': 'Test'})
+
+ with self.assertQueryCount(__system__=8, emp=8):
+ activity = record.action_start('Test Start')
+ #read activity_type to normalize cache between enterprise and community
+ #voip module read activity_type during create leading to one less query in enterprise on action_close
+ category = activity.activity_type_id.category
+
+ record.write({'name': 'Dupe write'})
+
+ with self.assertQueryCount(__system__=17, emp=20):
+ record.action_close('Dupe feedback')
+
+ self.assertEqual(record.activity_ids, self.env['mail.activity'])
+
+ @users('__system__', 'emp')
+ @warmup
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail')
+ def test_mail_composer(self):
+ self._create_test_records()
+ test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id)
+ customer_id = self.customer.id
+ with self.assertQueryCount(__system__=2, emp=2):
+ composer = self.env['mail.compose.message'].with_context({
+ 'default_composition_mode': 'comment',
+ 'default_model': test_record._name,
+ 'default_res_id': test_record.id,
+ }).create({
+ 'body': '<p>Test Body</p>',
+ 'partner_ids': [(4, customer_id)],
+ })
+
+ with self.assertQueryCount(__system__=32, emp=39):
+ composer.send_mail()
+
+ @users('__system__', 'emp')
+ @warmup
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail')
+ def test_mail_composer_nodelete(self):
+ self._create_test_records()
+ test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id)
+ customer_id = self.customer.id
+ with self.assertQueryCount(__system__=2, emp=2):
+ composer = self.env['mail.compose.message'].with_context({
+ 'default_composition_mode': 'comment',
+ 'default_model': test_record._name,
+ 'default_res_id': test_record.id,
+ 'mail_auto_delete': False,
+ }).create({
+ 'body': '<p>Test Body</p>',
+ 'partner_ids': [(4, customer_id)],
+ })
+
+ with self.assertQueryCount(__system__=25, emp=32):
+ composer.send_mail()
+
+ @users('__system__', 'emp')
+ @warmup
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ def test_mail_composer_w_template(self):
+ self._create_test_records()
+ test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id)
+ test_template = self.env['mail.template'].browse(self.test_template_full.id)
+ # TODO FIXME non deterministic, last check 25 Mar 2020. Runbot at most +7 compared to local.
+ with self.assertQueryCount(__system__=12, emp=14):
+ composer = self.env['mail.compose.message'].with_context({
+ 'default_composition_mode': 'comment',
+ 'default_model': test_record._name,
+ 'default_res_id': test_record.id,
+ 'default_template_id': test_template.id,
+ }).create({})
+ composer.onchange_template_id_wrapper()
+
+ with self.assertQueryCount(__system__=33, emp=40):
+ composer.send_mail()
+
+ # remove created partner to ensure tests are the same each run
+ self.env['res.partner'].sudo().search([('email', '=', 'nopartner.test@example.com')]).unlink()
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_message_assignation_email(self):
+ self.user_test.write({'notification_type': 'email'})
+ record = self.env['mail.test.track'].create({'name': 'Test'})
+ with self.assertQueryCount(__system__=37, emp=38):
+ record.write({
+ 'user_id': self.user_test.id,
+ })
+
+ @users('__system__', 'emp')
+ @warmup
+ def test_message_assignation_inbox(self):
+ record = self.env['mail.test.track'].create({'name': 'Test'})
+ with self.assertQueryCount(__system__=18, emp=21):
+ record.write({
+ 'user_id': self.user_test.id,
+ })
+
+ @users('__system__', 'emp')
+ @warmup
+ def test_message_log(self):
+ record = self.env['mail.test.simple'].create({'name': 'Test'})
+
+ with self.assertQueryCount(__system__=1, emp=1):
+ record._message_log(
+ body='<p>Test _message_log</p>',
+ message_type='comment')
+
+ @users('__system__', 'emp')
+ @warmup
+ def test_message_log_with_post(self):
+ record = self.env['mail.test.simple'].create({'name': 'Test'})
+
+ with self.assertQueryCount(__system__=3, emp=6):
+ record.message_post(
+ body='<p>Test message_post as log</p>',
+ subtype_xmlid='mail.mt_note',
+ message_type='comment')
+
+ @users('__system__', 'emp')
+ @warmup
+ def test_message_post_no_notification(self):
+ record = self.env['mail.test.simple'].create({'name': 'Test'})
+
+ with self.assertQueryCount(__system__=3, emp=6):
+ record.message_post(
+ body='<p>Test Post Performances basic</p>',
+ partner_ids=[],
+ message_type='comment',
+ subtype_xmlid='mail.mt_comment')
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_message_post_one_email_notification(self):
+ record = self.env['mail.test.simple'].create({'name': 'Test'})
+
+ with self.assertQueryCount(__system__=28, emp=31):
+ record.message_post(
+ body='<p>Test Post Performances with an email ping</p>',
+ partner_ids=self.customer.ids,
+ message_type='comment',
+ subtype_xmlid='mail.mt_comment')
+
+ @users('__system__', 'emp')
+ @warmup
+ def test_message_post_one_inbox_notification(self):
+ record = self.env['mail.test.simple'].create({'name': 'Test'})
+
+ with self.assertQueryCount(__system__=12, emp=17):
+ record.message_post(
+ body='<p>Test Post Performances with an inbox ping</p>',
+ partner_ids=self.user_test.partner_id.ids,
+ message_type='comment',
+ subtype_xmlid='mail.mt_comment')
+
+ @mute_logger('odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_message_subscribe_default(self):
+ record = self.env['mail.test.simple'].create({'name': 'Test'})
+
+ with self.assertQueryCount(__system__=6, emp=6):
+ record.message_subscribe(partner_ids=self.user_test.partner_id.ids)
+
+ with self.assertQueryCount(__system__=3, emp=3):
+ record.message_subscribe(partner_ids=self.user_test.partner_id.ids)
+
+ @mute_logger('odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_message_subscribe_subtypes(self):
+ record = self.env['mail.test.simple'].create({'name': 'Test'})
+ subtype_ids = (self.env.ref('test_mail.st_mail_test_simple_external') | self.env.ref('mail.mt_comment')).ids
+
+ with self.assertQueryCount(__system__=5, emp=5):
+ record.message_subscribe(partner_ids=self.user_test.partner_id.ids, subtype_ids=subtype_ids)
+
+ with self.assertQueryCount(__system__=2, emp=2):
+ record.message_subscribe(partner_ids=self.user_test.partner_id.ids, subtype_ids=subtype_ids)
+
+ @mute_logger('odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_message_track(self):
+ record = self.env['mail.performance.tracking'].create({'name': 'Zizizatestname'})
+ with self.assertQueryCount(__system__=3, emp=3):
+ record.write({'name': 'Zizizanewtestname'})
+ record.flush()
+
+ with self.assertQueryCount(__system__=5, emp=5):
+ record.write({'field_%s' % (i): 'Tracked Char Fields %s' % (i) for i in range(3)})
+ record.flush()
+
+ with self.assertQueryCount(__system__=6, emp=6):
+ record.write({'field_%s' % (i): 'Field Without Cache %s' % (i) for i in range(3)})
+ record.flush()
+ record.write({'field_%s' % (i): 'Field With Cache %s' % (i) for i in range(3)})
+ record.flush()
+
+
+@tagged('mail_performance')
+class TestMailComplexPerformance(BaseMailPerformance):
+
+ def setUp(self):
+ super(TestMailComplexPerformance, self).setUp()
+ self.user_portal = self.env['res.users'].with_context(self._quick_create_ctx).create({
+ 'name': 'Olivia Portal',
+ 'login': 'port',
+ 'email': 'p.p@example.com',
+ 'signature': '--\nOlivia',
+ 'notification_type': 'email',
+ 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])],
+ })
+
+ # setup mail gateway
+ self.env['ir.config_parameter'].sudo().set_param('mail.catchall.domain', 'example.com')
+ self.env['ir.config_parameter'].sudo().set_param('mail.catchall.alias', 'test-catchall')
+ self.env['ir.config_parameter'].sudo().set_param('mail.bounce.alias', 'test-bounce')
+
+ self.channel = self.env['mail.channel'].with_context(self._quick_create_ctx).create({
+ 'name': 'Listener',
+ })
+
+ # prepare recipients to test for more realistic workload
+ self.customer = self.env['res.partner'].with_context(self._quick_create_ctx).create({
+ 'name': 'Test Customer',
+ 'email': 'test@example.com'
+ })
+ self.container = self.env['mail.test.container'].with_context(mail_create_nosubscribe=True).create({
+ 'name': 'Test Container',
+ 'customer_id': self.customer.id,
+ 'alias_name': 'test-alias',
+ })
+ Partners = self.env['res.partner'].with_context(self._quick_create_ctx)
+ self.partners = self.env['res.partner']
+ for x in range(0, 10):
+ self.partners |= Partners.create({'name': 'Test %s' % x, 'email': 'test%s@example.com' % x})
+ self.container.message_subscribe(self.partners.ids, subtype_ids=[
+ self.env.ref('mail.mt_comment').id,
+ self.env.ref('test_mail.st_mail_test_container_child_full').id]
+ )
+ # `test_complex_mail_mail_send`
+ self.container.flush()
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_complex_mail_mail_send(self):
+ message = self.env['mail.message'].sudo().create({
+ 'subject': 'Test',
+ 'body': '<p>Test</p>',
+ 'author_id': self.env.user.partner_id.id,
+ 'email_from': self.env.user.partner_id.email,
+ 'model': 'mail.test.container',
+ 'res_id': self.container.id,
+ })
+ mail = self.env['mail.mail'].sudo().create({
+ 'body_html': '<p>Test</p>',
+ 'mail_message_id': message.id,
+ 'recipient_ids': [(4, pid) for pid in self.partners.ids],
+ })
+ mail_ids = mail.ids
+ with self.assertQueryCount(__system__=7, emp=7):
+ self.env['mail.mail'].sudo().browse(mail_ids).send()
+
+ self.assertEqual(mail.body_html, '<p>Test</p>')
+ self.assertEqual(mail.reply_to, formataddr(('%s %s' % (self.env.company.name, self.container.name), 'test-alias@example.com')))
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_complex_message_post(self):
+ self.container.message_subscribe(self.user_portal.partner_id.ids)
+ record = self.container.with_user(self.env.user)
+
+ with self.assertQueryCount(__system__=63, emp=64):
+ record.message_post(
+ body='<p>Test Post Performances</p>',
+ message_type='comment',
+ subtype_xmlid='mail.mt_comment')
+
+ self.assertEqual(record.message_ids[0].body, '<p>Test Post Performances</p>')
+ self.assertEqual(record.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id)
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_complex_message_post_template(self):
+ self.container.message_subscribe(self.user_portal.partner_id.ids)
+ record = self.container.with_user(self.env.user)
+ template_id = self.env.ref('test_mail.mail_test_container_tpl').id
+
+ with self.assertQueryCount(__system__=73, emp=75):
+ record.message_post_with_template(template_id, message_type='comment', composition_mode='comment')
+
+ self.assertEqual(record.message_ids[0].body, '<p>Adding stuff on %s</p>' % record.name)
+ self.assertEqual(record.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id | self.customer)
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_complex_message_subscribe(self):
+ pids = self.partners.ids
+ cids = self.channel.ids
+ subtypes = self.env.ref('mail.mt_comment') | self.env.ref('test_mail.st_mail_test_ticket_container_upd')
+ subtype_ids = subtypes.ids
+ rec = self.env['mail.test.ticket'].create({
+ 'name': 'Test',
+ 'container_id': False,
+ 'customer_id': False,
+ 'user_id': self.user_portal.id,
+ })
+ rec1 = rec.with_context(active_test=False) # to see inactive records
+
+ self.assertEqual(rec1.message_partner_ids, self.env.user.partner_id | self.user_portal.partner_id)
+ self.assertEqual(rec1.message_channel_ids, self.env['mail.channel'])
+
+ # subscribe new followers with forced given subtypes
+ with self.assertQueryCount(__system__=8, emp=8):
+ rec.message_subscribe(
+ partner_ids=pids[:4],
+ channel_ids=cids,
+ subtype_ids=subtype_ids
+ )
+
+ self.assertEqual(rec1.message_partner_ids, self.env.user.partner_id | self.user_portal.partner_id | self.partners[:4])
+ self.assertEqual(rec1.message_channel_ids, self.channel)
+
+ # subscribe existing and new followers with force=False, meaning only some new followers will be added
+ with self.assertQueryCount(__system__=6, emp=6):
+ rec.message_subscribe(
+ partner_ids=pids[:6],
+ channel_ids=cids,
+ subtype_ids=None
+ )
+
+ self.assertEqual(rec1.message_partner_ids, self.env.user.partner_id | self.user_portal.partner_id | self.partners[:6])
+ self.assertEqual(rec1.message_channel_ids, self.channel)
+
+ # subscribe existing and new followers with force=True, meaning all will have the same subtypes
+ with self.assertQueryCount(__system__=7, emp=7):
+ rec.message_subscribe(
+ partner_ids=pids,
+ channel_ids=cids,
+ subtype_ids=subtype_ids
+ )
+
+ self.assertEqual(rec1.message_partner_ids, self.env.user.partner_id | self.user_portal.partner_id | self.partners)
+ self.assertEqual(rec1.message_channel_ids, self.channel)
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_complex_tracking_assignation(self):
+ """ Assignation performance test on already-created record """
+ rec = self.env['mail.test.ticket'].create({
+ 'name': 'Test',
+ 'container_id': self.container.id,
+ 'customer_id': self.customer.id,
+ 'user_id': self.env.uid,
+ })
+ rec1 = rec.with_context(active_test=False) # to see inactive records
+ self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id)
+ with self.assertQueryCount(__system__=37, emp=38):
+ rec.write({'user_id': self.user_portal.id})
+ self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id)
+ # write tracking message
+ self.assertEqual(rec1.message_ids[0].subtype_id, self.env.ref('mail.mt_note'))
+ self.assertEqual(rec1.message_ids[0].notified_partner_ids, self.env['res.partner'])
+ # creation message
+ self.assertEqual(rec1.message_ids[1].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
+ self.assertEqual(rec1.message_ids[1].notified_partner_ids, self.partners)
+ self.assertEqual(len(rec1.message_ids), 2)
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_complex_tracking_subscription_create(self):
+ """ Creation performance test involving auto subscription, assignation, tracking with subtype and template send. """
+ container_id = self.container.id
+ customer_id = self.customer.id
+ user_id = self.user_portal.id
+
+ with self.assertQueryCount(__system__=108, emp=109):
+ rec = self.env['mail.test.ticket'].create({
+ 'name': 'Test',
+ 'container_id': container_id,
+ 'customer_id': customer_id,
+ 'user_id': user_id,
+ })
+
+ rec1 = rec.with_context(active_test=False) # to see inactive records
+ self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id)
+ # creation message
+ self.assertEqual(rec1.message_ids[0].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
+ self.assertEqual(rec1.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id)
+ self.assertEqual(len(rec1.message_ids), 1)
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_complex_tracking_subscription_subtype(self):
+ """ Write performance test involving auto subscription, tracking with subtype """
+ rec = self.env['mail.test.ticket'].create({
+ 'name': 'Test',
+ 'container_id': False,
+ 'customer_id': False,
+ 'user_id': self.user_portal.id,
+ })
+ rec1 = rec.with_context(active_test=False) # to see inactive records
+ self.assertEqual(rec1.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id)
+ self.assertEqual(len(rec1.message_ids), 1)
+ with self.assertQueryCount(__system__=77, emp=77):
+ rec.write({
+ 'name': 'Test2',
+ 'container_id': self.container.id,
+ })
+
+ self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id)
+ # write tracking message
+ self.assertEqual(rec1.message_ids[0].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
+ self.assertEqual(rec1.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id)
+ # creation message
+ self.assertEqual(rec1.message_ids[1].subtype_id, self.env.ref('mail.mt_note'))
+ self.assertEqual(rec1.message_ids[1].notified_partner_ids, self.env['res.partner'])
+ self.assertEqual(len(rec1.message_ids), 2)
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_complex_tracking_subscription_write(self):
+ """ Write performance test involving auto subscription, tracking with subtype and template send """
+ container_id = self.container.id
+ customer_id = self.customer.id
+ container2 = self.env['mail.test.container'].with_context(mail_create_nosubscribe=True).create({
+ 'name': 'Test Container 2',
+ 'customer_id': False,
+ 'alias_name': False,
+ })
+
+ rec = self.env['mail.test.ticket'].create({
+ 'name': 'Test',
+ 'container_id': container2.id,
+ 'customer_id': False,
+ 'user_id': self.user_portal.id,
+ })
+ rec1 = rec.with_context(active_test=False) # to see inactive records
+ self.assertEqual(rec1.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id)
+
+ with self.assertQueryCount(__system__=85, emp=85):
+ rec.write({
+ 'name': 'Test2',
+ 'container_id': container_id,
+ 'customer_id': customer_id,
+ })
+
+ self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id)
+ # write tracking message
+ self.assertEqual(rec1.message_ids[0].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
+ self.assertEqual(rec1.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id)
+ # creation message
+ self.assertEqual(rec1.message_ids[1].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
+ self.assertEqual(rec1.message_ids[1].notified_partner_ids, self.user_portal.partner_id)
+ self.assertEqual(len(rec1.message_ids), 2)
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('__system__', 'emp')
+ @warmup
+ def test_complex_tracking_template(self):
+ """ Write performance test involving assignation, tracking with template """
+ customer_id = self.customer.id
+ self.assertTrue(self.env.registry.ready, "We need to simulate that registery is ready")
+ rec = self.env['mail.test.ticket'].create({
+ 'name': 'Test',
+ 'container_id': self.container.id,
+ 'customer_id': False,
+ 'user_id': self.user_portal.id,
+ 'mail_template': self.env.ref('test_mail.mail_test_ticket_tracking_tpl').id,
+ })
+ rec1 = rec.with_context(active_test=False) # to see inactive records
+ self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id)
+
+ with self.assertQueryCount(__system__=29, emp=30):
+ rec.write({
+ 'name': 'Test2',
+ 'customer_id': customer_id,
+ 'user_id': self.env.uid,
+ })
+
+ # write template message (sent to customer, mass mailing kept for history)
+ self.assertEqual(rec1.message_ids[0].subtype_id, self.env['mail.message.subtype'])
+ self.assertEqual(rec1.message_ids[0].subject, 'Test Template')
+ # write tracking message
+ self.assertEqual(rec1.message_ids[1].subtype_id, self.env.ref('mail.mt_note'))
+ self.assertEqual(rec1.message_ids[1].notified_partner_ids, self.env['res.partner'])
+ # creation message
+ self.assertEqual(rec1.message_ids[2].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
+ self.assertEqual(rec1.message_ids[2].notified_partner_ids, self.partners | self.user_portal.partner_id)
+ self.assertEqual(len(rec1.message_ids), 3)
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('emp')
+ @warmup
+ def test_message_format(self):
+ """Test performance of `_message_format` and of `message_format` with
+ multiple messages with multiple attachments, different authors, various
+ notifications, and different tracking values.
+ Those messages might not make sense functionally but they are crafted to
+ cover as much of the code as possible in regard to number of queries.
+ """
+ name_field = self.env['ir.model.fields']._get(self.container._name, 'name')
+ customer_id_field = self.env['ir.model.fields']._get(self.container._name, 'customer_id')
+
+ messages = self.env['mail.message'].sudo().create([{
+ 'subject': 'Test 0',
+ 'body': '<p>Test 0</p>',
+ 'author_id': self.partners[0].id,
+ 'email_from': self.partners[0].email,
+ 'model': 'mail.test.container',
+ 'res_id': self.container.id,
+ 'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment'),
+ 'attachment_ids': [
+ (0, 0, {
+ 'name': 'test file 0 - %d' % j,
+ 'datas': 'data',
+ }) for j in range(2)
+ ],
+ 'notification_ids': [
+ (0, 0, {
+ 'res_partner_id': self.partners[3].id,
+ 'notification_type': 'inbox',
+ }),
+ (0, 0, {
+ 'res_partner_id': self.partners[4].id,
+ 'notification_type': 'email',
+ 'notification_status': 'exception',
+ }),
+ (0, 0, {
+ 'res_partner_id': self.partners[6].id,
+ 'notification_type': 'email',
+ 'notification_status': 'exception',
+ }),
+ ],
+ 'tracking_value_ids': [
+ (0, 0, {
+ 'field': name_field.id,
+ 'field_desc': 'Name',
+ 'old_value_char': 'old 0',
+ 'new_value_char': 'new 0',
+ }),
+ (0, 0, {
+ 'field': customer_id_field.id,
+ 'field_desc': 'Customer',
+ 'old_value_integer': self.partners[7].id,
+ 'new_value_integer': self.partners[8].id,
+ }),
+ ]
+ }, {
+ 'subject': 'Test 1',
+ 'body': '<p>Test 1</p>',
+ 'author_id': self.partners[1].id,
+ 'email_from': self.partners[1].email,
+ 'model': 'mail.test.container',
+ 'res_id': self.container.id,
+ 'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
+ 'attachment_ids': [
+ (0, 0, {
+ 'name': 'test file 1 - %d' % j,
+ 'datas': 'data',
+ }) for j in range(2)
+ ],
+ 'notification_ids': [
+ (0, 0, {
+ 'res_partner_id': self.partners[5].id,
+ 'notification_type': 'inbox',
+ }),
+ (0, 0, {
+ 'res_partner_id': self.partners[6].id,
+ 'notification_type': 'email',
+ 'notification_status': 'exception',
+ }),
+ ],
+ 'tracking_value_ids': [
+ (0, 0, {
+ 'field': name_field.id,
+ 'field_desc': 'Name',
+ 'old_value_char': 'old 1',
+ 'new_value_char': 'new 1',
+ }),
+ (0, 0, {
+ 'field': customer_id_field.id,
+ 'field_desc': 'Customer',
+ 'old_value_integer': self.partners[7].id,
+ 'new_value_integer': self.partners[8].id,
+ }),
+ ]
+ }])
+
+ with self.assertQueryCount(emp=5):
+ res = messages.message_format()
+ self.assertEqual(len(res), 2)
+ for message in res:
+ self.assertEqual(len(message['attachment_ids']), 2)
+
+ messages.flush()
+ messages.invalidate_cache()
+
+ with self.assertQueryCount(emp=17):
+ res = messages.message_format()
+ self.assertEqual(len(res), 2)
+ for message in res:
+ self.assertEqual(len(message['attachment_ids']), 2)
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('emp')
+ @warmup
+ def test_message_format_group_thread_name_by_model(self):
+ """Ensures the fetch of multiple thread names is grouped by model."""
+ records = []
+ for i in range(5):
+ records.append(self.env['mail.test.simple'].create({'name': 'Test'}))
+ records.append(self.env['mail.test.track'].create({'name': 'Test'}))
+
+ messages = self.env['mail.message'].create([{
+ 'model': record._name,
+ 'res_id': record.id
+ } for record in records])
+
+ with self.assertQueryCount(emp=4):
+ res = messages.message_format()
+ self.assertEqual(len(res), 6)
+
+ messages.flush()
+ messages.invalidate_cache()
+
+ with self.assertQueryCount(emp=14):
+ res = messages.message_format()
+ self.assertEqual(len(res), 6)
+
+
+@tagged('mail_performance')
+class TestMailHeavyPerformancePost(BaseMailPerformance):
+
+ def setUp(self):
+ super(TestMailHeavyPerformancePost, self).setUp()
+
+ # record
+ self.customer = self.env['res.partner'].with_context(self._quick_create_ctx).create({
+ 'name': 'customer',
+ 'email': 'customer@example.com',
+ })
+ self.record = self.env['mail.test.container'].with_context(mail_create_nosubscribe=True).create({
+ 'name': 'Test record',
+ 'customer_id': self.customer.id,
+ 'alias_name': 'test-alias',
+ })
+ # followers
+ self.user_follower_email = self.env['res.users'].with_context(self._quick_create_ctx).create({
+ 'name': 'user_follower_email',
+ 'login': 'user_follower_email',
+ 'email': 'user_follower_email@example.com',
+ 'notification_type': 'email',
+ 'groups_id': [(6, 0, [self.env.ref('base.group_user').id])],
+ })
+ self.user_follower_inbox = self.env['res.users'].with_context(self._quick_create_ctx).create({
+ 'name': 'user_follower_inbox',
+ 'login': 'user_follower_inbox',
+ 'email': 'user_follower_inbox@example.com',
+ 'notification_type': 'inbox',
+ 'groups_id': [(6, 0, [self.env.ref('base.group_user').id])],
+ })
+ self.partner_follower = self.env['res.partner'].with_context(self._quick_create_ctx).create({
+ 'name': 'partner_follower',
+ 'email': 'partner_follower@example.com',
+ })
+ self.record.message_subscribe([
+ self.partner_follower.id,
+ self.user_follower_inbox.partner_id.id,
+ self.user_follower_email.partner_id.id
+ ])
+
+ # partner_ids
+ self.user_inbox = self.env['res.users'].with_context(self._quick_create_ctx).create({
+ 'name': 'user_inbox',
+ 'login': 'user_inbox',
+ 'email': 'user_inbox@example.com',
+ 'notification_type': 'inbox',
+ 'groups_id': [(6, 0, [self.env.ref('base.group_user').id])],
+ })
+ self.user_email = self.env['res.users'].with_context(self._quick_create_ctx).create({
+ 'name': 'user_email',
+ 'login': 'user_email',
+ 'email': 'user_email@example.com',
+ 'notification_type': 'email',
+ 'groups_id': [(6, 0, [self.env.ref('base.group_user').id])],
+ })
+ self.partner = self.env['res.partner'].with_context(self._quick_create_ctx).create({
+ 'name': 'partner',
+ 'email': 'partner@example.com',
+ })
+ # channels user/partner
+ self.partner_channel_inbox = self.env['res.partner'].with_context(self._quick_create_ctx).create({
+ 'name': 'partner_channel_inbox',
+ 'email': 'partner_channel_inbox@example.com',
+ })
+ self.partner_channel_email = self.env['res.partner'].with_context(self._quick_create_ctx).create({
+ 'name': 'partner_channel_email',
+ 'email': 'partner_channel_email@example.com',
+ })
+ self.user_channel_inbox = self.env['res.users'].with_context(self._quick_create_ctx).create({
+ 'name': 'user_channel_inbox',
+ 'login': 'user_channel_inbox',
+ 'email': 'user_channel_inbox@example.com',
+ 'notification_type': 'inbox',
+ 'groups_id': [(6, 0, [self.env.ref('base.group_user').id])],
+ })
+ self.user_channel_email = self.env['res.users'].with_context(self._quick_create_ctx).create({
+ 'name': 'user_channel_email',
+ 'login': 'user_channel_email',
+ 'email': 'user_channel_email@example.com',
+ 'notification_type': 'inbox',
+ 'groups_id': [(6, 0, [self.env.ref('base.group_user').id])],
+ })
+ # channels
+ self.channel_inbox = self.env['mail.channel'].with_context(self._quick_create_ctx).create({
+ 'name': 'channel_inbox',
+ 'channel_partner_ids': [(4, self.partner_channel_inbox.id), (4, self.user_channel_inbox.partner_id.id)]
+ })
+ self.channel_email = self.env['mail.channel'].with_context(self._quick_create_ctx).create({
+ 'name': 'channel_email',
+ 'email_send': True,
+ 'channel_partner_ids': [(4, self.partner_channel_email.id), (4, self.user_channel_email.partner_id.id)]
+ })
+ self.vals = [{
+ 'datas': base64.b64encode(bytes("attachement content %s" % i, 'utf-8')),
+ 'name': 'fileText_test%s.txt' % i,
+ 'mimetype': 'text/plain',
+ 'res_model': 'mail.compose.message',
+ 'res_id': 0,
+ } for i in range(3)]
+
+ self.patch(self.env.registry, 'ready', True)
+
+ @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
+ @users('emp')
+ @warmup
+ def test_complete_message_post(self):
+ # aims to cover as much features of message_post as possible
+ partner_ids = [self.user_inbox.partner_id.id, self.user_email.partner_id.id, self.partner.id]
+ channel_ids = [self.channel_inbox.id, self.channel_email.id]
+ record = self.record.with_user(self.env.user)
+ attachements = [ # not linear on number of attachements
+ ('attach tuple 1', "attachement tupple content 1"),
+ ('attach tuple 2', "attachement tupple content 2", {'cid': 'cid1'}),
+ ('attach tuple 3', "attachement tupple content 3", {'cid': 'cid2'}),
+ ]
+ self.attachements = self.env['ir.attachment'].with_user(self.env.user).create(self.vals)
+ attachement_ids = self.attachements.ids
+ with self.assertQueryCount(emp=80):
+ self.cr.sql_log = self.warm and self.cr.sql_log_count
+ record.with_context({}).message_post(
+ body='<p>Test body <img src="cid:cid1"> <img src="cid:cid2"></p>',
+ subject='Test Subject',
+ message_type='notification',
+ subtype_xmlid=None,
+ partner_ids=partner_ids,
+ channel_ids=channel_ids,
+ parent_id=False,
+ attachments=attachements,
+ attachment_ids=attachement_ids,
+ add_sign=True,
+ model_description=False,
+ mail_auto_delete=True
+ )
+ self.cr.sql_log = False
+ self.assertTrue(record.message_ids[0].body.startswith('<p>Test body <img src="/web/image/'))
+ self.assertEqual(self.attachements.mapped('res_model'), [record._name for i in range(3)])
+ self.assertEqual(self.attachements.mapped('res_id'), [record.id for i in range(3)])
+ # self.assertEqual(record.message_ids[0].notified_partner_ids, [])