Opened 14 months ago

Closed 10 months ago

Last modified 9 months ago

#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 Aaron Blair)

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)

test_case.png (142.0 KB ) - added by Can Huynh 12 months ago.
test_output.png (22.9 KB ) - added by Can Huynh 12 months ago.
unittest_app_models.png (98.0 KB ) - added by Can Huynh 12 months ago.

Download all attachments as: .zip

Change History (19)

comment:1 by Aaron Blair, 14 months ago

Description: modified (diff)

comment:2 by Claude Paroz, 14 months ago

Triage Stage: UnreviewedAccepted

comment:3 by Can Huynh, 14 months ago

Can I try this issue?

comment:4 by Aaron Blair, 14 months ago

Owner: changed from nobody to Can Huynh
Status: newassigned

comment:5 by Can Huynh, 14 months ago

Can I get an instruction on how to reproduce this issue?

in reply to:  5 ; comment:6 by Aaron Blair, 14 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 Pieter Cardillo Kwok, 14 months ago

Cc: Pieter Cardillo Kwok added

comment:8 by Can Huynh, 13 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 Can Huynh, 12 months ago

Attachment: test_case.png added

by Can Huynh, 12 months ago

Attachment: test_output.png added

in reply to:  6 ; comment:9 by Can Huynh, 12 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

in reply to:  9 comment:10 by Aaron Blair, 12 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.


in reply to:  9 comment:11 by Aaron Blair, 12 months ago

Replying to Can Huynh:
Can you add your unittest_app.models.py?

by Can Huynh, 12 months ago

Attachment: unittest_app_models.png added

comment:12 by Can Huynh, 12 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


in reply to:  12 comment:13 by Aaron Blair, 12 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

Last edited 12 months ago by Aaron Blair (previous) (diff)

comment:14 by Mariusz Felisiak, 10 months ago

Easy pickings: unset
Resolution: invalid
Status: assignedclosed
Triage Stage: AcceptedUnreviewed

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.

in reply to:  14 comment:15 by Can Huynh, 9 months ago

Thank you for the update!

Replying to Mariusz Felisiak:

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:16 by Can Huynh, 9 months ago

Sorry for not responding for so long. Life got in the way, and thanks @Mariusz Felisiak

Note: See TracTickets for help on using tickets.
Back to Top