#34852 closed Bug (invalid)
Django Unit Tests break when using replicated MySQL Cluster v8.0.28
Reported by: | Aaron Blair | Owned by: | Can Huynh |
---|---|---|---|
Component: | Testing framework | Version: | 4.1 |
Severity: | Normal | Keywords: | Test MySQL Cluster |
Cc: | Pieter Cardillo Kwok | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
When running unit tests, the internal testing of a db for using transactions breaks when using MySQL Cluster server v8.0.28 because that db version requires a primary key for tables, and this line in https://github.com/django/django/blob/main/django/db/backends/base/features.py breaks it :
@cached_property def supports_transactions(self): """Confirm support for transactions.""" with self.connection.cursor() as cursor: cursor.execute("CREATE TABLE ROLLBACK_TEST (X INT)")
We have been patch-fixing that file as follows:
<- cursor.execute("CREATE TABLE ROLLBACK_TEST (X INT PRIMARY KEY)")
---
-> cursor.execute("CREATE TABLE ROLLBACK_TEST (X INT)")
Attachments (3)
Change History (19)
comment:1 by , 15 months ago
Description: | modified (diff) |
---|
comment:2 by , 15 months ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:3 by , 15 months ago
comment:4 by , 15 months ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
follow-up: 9 comment:6 by , 15 months ago
Replying to Can Huynh:
Can I get an instruction on how to reproduce this issue?
Install MySQL Cluster server v8.0.28 onto multiple (say 3) servers and start replication.
Install Django (any version that uses cursor.execute("CREATE TABLE ROLLBACK_TEST (X INT)") in django.db.backends.base.features.py this exists on 4.1 but it was there for several versions previous to 4.1 as well)
Create any model that uses autocreate id as pk (ie do not specify an id or pk field)
Write any unit test bases on django.test.TestCase for the model which accesses the db
Run the unit test
comment:7 by , 15 months ago
Cc: | added |
---|
comment:8 by , 14 months ago
Hi, I have attempted to install MySQL Cluster v8.0.28 but it doesn't seem to be working. I may have done it incorrectly. I tried doing this locally and on AWS but was not successful. Are you able to provide me instructions/resources on how to install this so I can continue with this ticket?
by , 14 months ago
Attachment: | test_case.png added |
---|
by , 14 months ago
Attachment: | test_output.png added |
---|
follow-ups: 10 11 comment:9 by , 14 months ago
Replying to Aaron Blair:
Can you guide me on how you set up your unit test and what your test output looked like, if possible? I have attached my test suits and test output, please let me know if there is anything I need to modify. Thank you in advance and sorry for being inactive for a long time.
Replying to Can Huynh:
Can I get an instruction on how to reproduce this issue?
Install MySQL Cluster server v8.0.28 onto multiple (say 3) servers and start replication.
Install Django (any version that uses cursor.execute("CREATE TABLE ROLLBACK_TEST (X INT)") in django.db.backends.base.features.py this exists on 4.1 but it was there for several versions previous to 4.1 as well)
Create any model that uses autocreate id as pk (ie do not specify an id or pk field)
Write any unit test bases on django.test.TestCase for the model which accesses the db
Run the unit test
comment:10 by , 13 months ago
Replying to Can Huynh:
A very simple example:
my_app.models:
from django.db import models class Company(models.Model): name = models.CharField(max_length=30, unique=True)
my_app/tests/test_models_myapp.py:
from django.test import TestCase from my_app.models import Company class CompanyModelTest(TestCase): def test_saving_and_retrieving_items(self): company = Company() company.name = "ACompany" company.save() companies = Company.objects.all() self.assertEqual(companies.count(), 1) first_company = companies[0] self.assertEqual(first_company.name, "ACompany")
Replying to Aaron Blair:
Can you guide me on how you set up your unit test and what your test output looked like, if possible? I have attached my test suits and test output, please let me know if there is anything I need to modify. Thank you in advance and sorry for being inactive for a long time.
by , 13 months ago
Attachment: | unittest_app_models.png added |
---|
follow-up: 13 comment:12 by , 13 months ago
Here is my model file. I have tried applying your recommendation to my test case, and I still cannot make the test fail. I have tried with the most recent version, the 4.1 version, and the fix that I changed locally ie: cursor.execute("CREATE TABLE ROLLBACK_TEST (X INT PRIMARY KEY)")
I think that I didn't install and setup MySQL Cluster correctly but I am not sure how to verify it
comment:13 by , 13 months ago
That model looks fine. As long as you have multiple mysql cluster servers of version 8.0.28 and they have replication set up with each other, it will break tests without the the fix. Remove the fix, and check that replication is set up with the mysql cluster servers. (Log into one of them add use the command - select * from performance_schema.replication_group_members; - be sure all servers are listed as ONLINE state and PRIMARY role).
Replying to Can Huynh:
Here is my model file. I have tried applying your recommendation to my test case, and I still cannot make the test fail. I have tried with the most recent version, the 4.1 version, and the fix that I changed locally ie: cursor.execute("CREATE TABLE ROLLBACK_TEST (X INT PRIMARY KEY)")
I think that I didn't install and setup MySQL Cluster correctly but I am not sure how to verify it
follow-up: 15 comment:14 by , 12 months ago
Easy pickings: | unset |
---|---|
Resolution: | → invalid |
Status: | assigned → closed |
Triage Stage: | Accepted → Unreviewed |
The django.db.backends.mysql
backend has its own implementation of DatabaseFeatures.supports_transactions
and doesn't use the default one. I don't think there is anything to fix in Django itself.
comment:15 by , 10 months ago
Thank you for the update!
Replying to Mariusz Felisiak:
The
django.db.backends.mysql
backend has its own implementation ofDatabaseFeatures.supports_transactions
and doesn't use the default one. I don't think there is anything to fix in Django itself.
comment:16 by , 10 months ago
Sorry for not responding for so long. Life got in the way, and thanks @Mariusz Felisiak
Can I try this issue?