Ticket #8138: django_transaction_tests.diff

File django_transaction_tests.diff, 6.9 KB (added by mremolt, 7 years ago)

Now doesn't touch _doctests.py

  • django/test/testcases.py

     
    5555        """Tries to do a 'xml-comparision' of want and got.  Plain string
    5656        comparision doesn't always work because, for example, attribute
    5757        ordering should not be important.
    58        
     58
    5959        Based on http://codespeak.net/svn/lxml/trunk/src/lxml/doctestcompare.py
    6060        """
    6161        _norm_whitespace_re = re.compile(r'[ \t\n][ \t\n]+')
     
    102102            wrapper = '<root>%s</root>'
    103103            want = wrapper % want
    104104            got = wrapper % got
    105            
     105
    106106        # Parse the want and got strings, and compare the parsings.
    107107        try:
    108108            want_root = parseString(want).firstChild
     
    169169        # side effects on other tests.
    170170        transaction.rollback_unless_managed()
    171171
    172 class TestCase(unittest.TestCase):
     172    def run(self, test, compileflags=None, out=None, clear_globs=True):
     173        """
     174        Wraps the parent run() and encloses it in a transaction.
     175        """
     176        transaction.enter_transaction_management()
     177        transaction.managed(True)
     178        result = doctest.DocTestRunner.run(self, test, compileflags, out, clear_globs)
     179        transaction.rollback()
     180        transaction.leave_transaction_management()
     181        return result
     182
     183class TransactionTestCase(unittest.TestCase):
    173184    def _pre_setup(self):
    174185        """Performs any pre-test setup. This includes:
    175186
    176187            * Flushing the database.
    177             * If the Test Case class has a 'fixtures' member, installing the 
     188            * If the Test Case class has a 'fixtures' member, installing the
    178189              named fixtures.
    179190            * If the Test Case class has a 'urls' member, replace the
    180191              ROOT_URLCONF with it.
     
    206217            import sys
    207218            result.addError(self, sys.exc_info())
    208219            return
    209         super(TestCase, self).__call__(result)
     220        super(TransactionTestCase, self).__call__(result)
    210221        try:
    211222            self._post_teardown()
    212223        except (KeyboardInterrupt, SystemExit):
     
    354365        self.failIf(template_name in template_names,
    355366            (u"Template '%s' was used unexpectedly in rendering the"
    356367             u" response") % template_name)
     368
     369
     370class TestCase(TransactionTestCase):
     371    """
     372    Does basically the same as TransactionTestCase, but surrounds every test
     373    with a transaction. You have to use TransactionTestCase, if you need
     374    transaction management inside a test.
     375    """
     376    def _pre_setup(self):
     377        transaction.enter_transaction_management()
     378        transaction.managed(True)
     379
     380        if hasattr(self, 'fixtures'):
     381            call_command('loaddata', *self.fixtures, **{
     382                                                        'verbosity': 0,
     383                                                        'no_commit': True
     384                                                        })
     385        if hasattr(self, 'urls'):
     386            self._old_root_urlconf = settings.ROOT_URLCONF
     387            settings.ROOT_URLCONF = self.urls
     388            clear_url_caches()
     389        mail.outbox = []
     390
     391    def _post_teardown(self):
     392        if hasattr(self, '_old_root_urlconf'):
     393            settings.ROOT_URLCONF = self._old_root_urlconf
     394            clear_url_caches()
     395        transaction.rollback()
     396        transaction.leave_transaction_management()
     397 No newline at end of file
  • django/core/management/commands/loaddata.py

     
    1414        make_option('--verbosity', action='store', dest='verbosity', default='1',
    1515            type='choice', choices=['0', '1', '2'],
    1616            help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
     17        make_option('--no-commit', action='store_false', dest='no_commit', default=False,
     18            help='Tells Django to not commit the loaded fixtures to the DB.'),
    1719    )
    1820    help = 'Installs the named fixture(s) in the database.'
    1921    args = "fixture [fixture ...]"
     
    2830
    2931        verbosity = int(options.get('verbosity', 1))
    3032        show_traceback = options.get('traceback', False)
     33        no_commit = options.get('no_commit', False)
    3134
    3235        # Keep a count of the installed objects and fixtures
    3336        fixture_count = 0
     
    4447
    4548        # Start transaction management. All fixtures are installed in a
    4649        # single transaction to ensure that all references are resolved.
    47         transaction.commit_unless_managed()
    48         transaction.enter_transaction_management()
    49         transaction.managed(True)
     50        if not no_commit:
     51            transaction.commit_unless_managed()
     52            transaction.enter_transaction_management()
     53            transaction.managed(True)
    5054
    5155        app_fixtures = [os.path.join(os.path.dirname(app.__file__), 'fixtures') for app in get_apps()]
    5256        for fixture_label in fixture_labels:
     
    133137                                (format, fixture_name, humanize(fixture_dir))
    134138
    135139
    136         # If any of the fixtures we loaded contain 0 objects, assume that an 
     140        # If any of the fixtures we loaded contain 0 objects, assume that an
    137141        # error was encountered during fixture loading.
    138142        if 0 in objects_per_fixture:
    139143            sys.stderr.write(
     
    142146            transaction.rollback()
    143147            transaction.leave_transaction_management()
    144148            return
    145            
    146         # If we found even one object in a fixture, we need to reset the 
     149
     150        # If we found even one object in a fixture, we need to reset the
    147151        # database sequences.
    148152        if object_count > 0:
    149153            sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
     
    152156                    print "Resetting sequences"
    153157                for line in sequence_sql:
    154158                    cursor.execute(line)
    155            
    156         transaction.commit()
    157         transaction.leave_transaction_management()
    158159
     160        if not no_commit:
     161            transaction.commit()
     162            transaction.leave_transaction_management()
     163
    159164        if object_count == 0:
    160165            if verbosity > 1:
    161166                print "No fixtures found."
    162167        else:
    163168            if verbosity > 0:
    164169                print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count)
    165                
     170
    166171        # Close the DB connection. This is required as a workaround for an
    167172        # edge case in MySQL: if the same connection is used to
    168173        # create tables, load data, and query, the query can return
    169174        # incorrect results. See Django #7572, MySQL #37735.
    170         connection.close()
     175        if not no_commit:
     176            connection.close()
Back to Top