def test_migrate_sharded_model_with_specific_database_will_not_work(self):
        sut = ShardedRouter()

        with patch.object(TestModel, "django_sharding__database", 'blah', create=True):
            with patch.object(TestModel, "django_sharding__is_sharded", True, create=True):
                with self.assertRaises(InvalidMigrationException):
                    sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

        with patch.object(TestModel, "django_sharding__database", 'blah', create=True):
            with patch.object(TestModel, "django_sharding__is_sharded", False, create=True):
                sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

        with patch.object(TestModel, "django_sharding__database", None, create=True):
            with patch.object(TestModel, "django_sharding__is_sharded", True, create=True):
                sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

        sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')
Beispiel #2
0
    def test_migrate_sharded_model_with_specific_database_will_not_work(self):
        sut = ShardedRouter()

        with patch.object(TestModel,
                          "django_sharding__database",
                          'blah',
                          create=True):
            with patch.object(TestModel,
                              "django_sharding__is_sharded",
                              True,
                              create=True):
                with self.assertRaises(InvalidMigrationException):
                    sut.allow_migrate(db='default',
                                      app_label='tests',
                                      model_name='TestModel')

        with patch.object(TestModel,
                          "django_sharding__database",
                          'blah',
                          create=True):
            with patch.object(TestModel,
                              "django_sharding__is_sharded",
                              False,
                              create=True):
                sut.allow_migrate(db='default',
                                  app_label='tests',
                                  model_name='TestModel')

        with patch.object(TestModel,
                          "django_sharding__database",
                          None,
                          create=True):
            with patch.object(TestModel,
                              "django_sharding__is_sharded",
                              True,
                              create=True):
                sut.allow_migrate(db='default',
                                  app_label='tests',
                                  model_name='TestModel')

        sut.allow_migrate(db='default',
                          app_label='tests',
                          model_name='TestModel')
    def test_migrate_sharded_model_with_specific_database_will_not_work(self):
        sut = ShardedRouter()
        sut.get_specific_database_or_none = lambda self: 'default'
        sut.get_shard_group_if_sharded_or_none = lambda self: 'default'
        with self.assertRaises(InvalidMigrationException):
            sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

        sut.get_specific_database_or_none = lambda self: None
        sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

        sut.get_specific_database_or_none = lambda self: 'default'
        sut.get_shard_group_if_sharded_or_none = lambda self: None
        sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')
    def test_migrate_sharded_model_with_specific_database_will_not_work(self):
        sut = ShardedRouter()
        sut.get_specific_database_or_none = lambda self: 'default'
        sut.get_shard_group_if_sharded_or_none = lambda self: 'default'
        with self.assertRaises(InvalidMigrationException):
            sut.allow_migrate(db='default',
                              app_label='tests',
                              model_name='TestModel')

        sut.get_specific_database_or_none = lambda self: None
        sut.allow_migrate(db='default',
                          app_label='tests',
                          model_name='TestModel')

        sut.get_specific_database_or_none = lambda self: 'default'
        sut.get_shard_group_if_sharded_or_none = lambda self: None
        sut.allow_migrate(db='default',
                          app_label='tests',
                          model_name='TestModel')
Beispiel #5
0
class RouterAllowMigrateTestCase(TransactionTestCase):
    def setUp(self):
        self.sut = ShardedRouter()

    def assert_allow_migrate(self,
                             app_label,
                             model_name,
                             can_migrate_default,
                             can_migrate_shard,
                             migratable_db=None):
        self.assertEqual(
            self.sut.allow_migrate(db='default',
                                   app_label=app_label,
                                   model_name=model_name), can_migrate_default)
        self.assertEqual(
            all([
                self.sut.allow_migrate(db='app_shard_001_replica_001',
                                       app_label=app_label,
                                       model_name=model_name),
                self.sut.allow_migrate(db='app_shard_001_replica_002',
                                       app_label=app_label,
                                       model_name=model_name),
            ]), False)
        self.assertEqual(
            all([
                self.sut.allow_migrate(db='app_shard_001',
                                       app_label=app_label,
                                       model_name=model_name),
                self.sut.allow_migrate(db='app_shard_002',
                                       app_label=app_label,
                                       model_name=model_name),
            ]), can_migrate_shard)
        if migratable_db:
            self.assertTrue(
                self.sut.allow_migrate(db=migratable_db,
                                       app_label=app_label,
                                       model_name=model_name))

    def test_model_name_passed_in(self):
        self.assertTrue(
            self.sut.allow_migrate(db='default',
                                   app_label='tests',
                                   model_name="User"))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001',
                                   app_label='tests',
                                   model_name="User"))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_002',
                                   app_label='tests',
                                   model_name="User"))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests',
                                   model_name="User"))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_002',
                                   app_label='tests',
                                   model_name="User"))

    def test_model_passed_in(self):
        from django.contrib.auth import get_user_model

        hints = {'model': get_user_model()}

        self.assertTrue(
            self.sut.allow_migrate(db='default',
                                   app_label='tests',
                                   model_name=None,
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001',
                                   app_label='tests',
                                   model_name=None,
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_002',
                                   app_label='tests',
                                   model_name=None,
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests',
                                   model_name=None,
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_002',
                                   app_label='tests',
                                   model_name=None,
                                   **hints))

    def test_app_passed_in(self):
        self.assertTrue(self.sut.allow_migrate(db='default',
                                               app_label='tests'))
        self.assertTrue(
            self.sut.allow_migrate(db='app_shard_001', app_label='tests'))
        self.assertTrue(
            self.sut.allow_migrate(db='app_shard_002', app_label='tests'))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests'))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_002',
                                   app_label='tests'))

    def test_force_migrate_on_databases(self):
        hints = {"force_migrate_on_databases": ["app_shard_001"]}
        self.assertFalse(
            self.sut.allow_migrate(db='default', app_label='tests', **hints))
        self.assertTrue(
            self.sut.allow_migrate(db='app_shard_001',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_002',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_002',
                                   app_label='tests',
                                   **hints))

    def test_force_migrate_on_databases_ignores_secondary(self):
        hints = {"force_migrate_on_databases": ["app_shard_001_replica_001"]}
        self.assertFalse(
            self.sut.allow_migrate(db='default', app_label='tests', **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_002',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_002',
                                   app_label='tests',
                                   **hints))

    def test_migrate_replica_will_not_work(self):
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests',
                                   model_name='TestModel'))
        self.assertTrue(
            self.sut.allow_migrate(db='app_shard_001',
                                   app_label='tests',
                                   model_name='TestModel'))

    def test_migrate_sharded_model_with_specific_database_will_not_work(self):
        sut = ShardedRouter()

        with patch.object(TestModel,
                          "django_sharding__database",
                          'blah',
                          create=True):
            with patch.object(TestModel,
                              "django_sharding__is_sharded",
                              True,
                              create=True):
                with self.assertRaises(InvalidMigrationException):
                    sut.allow_migrate(db='default',
                                      app_label='tests',
                                      model_name='TestModel')

        with patch.object(TestModel,
                          "django_sharding__database",
                          'blah',
                          create=True):
            with patch.object(TestModel,
                              "django_sharding__is_sharded",
                              False,
                              create=True):
                sut.allow_migrate(db='default',
                                  app_label='tests',
                                  model_name='TestModel')

        with patch.object(TestModel,
                          "django_sharding__database",
                          None,
                          create=True):
            with patch.object(TestModel,
                              "django_sharding__is_sharded",
                              True,
                              create=True):
                sut.allow_migrate(db='default',
                                  app_label='tests',
                                  model_name='TestModel')

        sut.allow_migrate(db='default',
                          app_label='tests',
                          model_name='TestModel')

    def test_django_model_only_allows_on_default(self):
        self.assert_allow_migrate(app_label='auth',
                                  model_name='Group',
                                  can_migrate_default=True,
                                  can_migrate_shard=False)

    def test_specific_database_only_on_datbase(self):
        self.assert_allow_migrate(app_label='tests',
                                  model_name='ShardedTestModelIDs',
                                  can_migrate_default=False,
                                  can_migrate_shard=False,
                                  migratable_db='app_shard_001')

    def test_specific_sharded_model_only_on_shards(self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='TestModel',
            can_migrate_default=False,
            can_migrate_shard=True,
        )

    def test_lookup_fallback_if_migration_directory_not_the_same_as_the_model(
            self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='auth.User',
            can_migrate_default=True,
            can_migrate_shard=False,
        )
class RouterAllowMigrateTestCase(TestCase):

    def setUp(self):
        self.sut = ShardedRouter()

    def assert_allow_migrate(self, app_label, model_name, can_migrate_default, can_migrate_shard, migratable_db=None):
        self.assertEqual(self.sut.allow_migrate(db='default', app_label=app_label, model_name=model_name), can_migrate_default)
        self.assertEqual(
            all([
                self.sut.allow_migrate(db='app_shard_001_replica_001', app_label=app_label, model_name=model_name),
                self.sut.allow_migrate(db='app_shard_001_replica_002', app_label=app_label, model_name=model_name),
            ]),
            False
        )
        self.assertEqual(
            all([
                self.sut.allow_migrate(db='app_shard_001', app_label=app_label, model_name=model_name),
                self.sut.allow_migrate(db='app_shard_002', app_label=app_label, model_name=model_name),
            ]),
            can_migrate_shard
        )
        if migratable_db:
            self.assertTrue(self.sut.allow_migrate(db=migratable_db, app_label=app_label, model_name=model_name))

    def test_requires_model_name_to_be_passed_in(self):
        with self.assertRaises(InvalidMigrationException):
            self.sut.allow_migrate(db='default', app_label='tests')

        self.sut.allow_migrate(db='default', app_label='tests', model_name='User')
        hints = {'model_name': 'User'}
        self.sut.allow_migrate(db='default', app_label='tests', **hints)

    def test_requires_model_to_be_passed_in(self):
        from django.contrib.auth import get_user_model
        with self.assertRaises(InvalidMigrationException):
            self.sut.allow_migrate(db='default', app_label='tests')

        hints = {'model': get_user_model()}
        self.sut.allow_migrate(db='default', app_label='tests', model_name=None, **hints)

    def test_migrate_replica_will_not_work(self):
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_001', app_label='tests', model_name='TestModel'))
        self.assertTrue(self.sut.allow_migrate(db='app_shard_001', app_label='tests', model_name='TestModel'))

    def test_migrate_sharded_model_with_specific_database_will_not_work(self):
        sut = ShardedRouter()
        sut.get_specific_database_or_none = lambda self: 'default'
        sut.get_shard_group_if_sharded_or_none = lambda self: 'default'
        with self.assertRaises(InvalidMigrationException):
            sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

        sut.get_specific_database_or_none = lambda self: None
        sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

        sut.get_specific_database_or_none = lambda self: 'default'
        sut.get_shard_group_if_sharded_or_none = lambda self: None
        sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

    def test_django_model_only_allows_on_default(self):
        self.assert_allow_migrate(
            app_label='auth',
            model_name='Group',
            can_migrate_default=True,
            can_migrate_shard=False
        )

    def test_specific_database_only_on_datbase(self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='ShardedTestModelIDs',
            can_migrate_default=False,
            can_migrate_shard=False,
            migratable_db='app_shard_001'
        )

    def test_specific_sharded_model_only_on_shards(self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='TestModel',
            can_migrate_default=False,
            can_migrate_shard=True,
        )

    def test_lookup_fallback_if_migration_directory_not_the_same_as_the_model(self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='auth.User',
            can_migrate_default=True,
            can_migrate_shard=False,
        )
class RouterAllowMigrateTestCase(TransactionTestCase):

    def setUp(self):
        self.sut = ShardedRouter()

    def assert_allow_migrate(self, app_label, model_name, can_migrate_default, can_migrate_shard, migratable_db=None):
        self.assertEqual(self.sut.allow_migrate(db='default', app_label=app_label, model_name=model_name), can_migrate_default)
        self.assertEqual(
            all([
                self.sut.allow_migrate(db='app_shard_001_replica_001', app_label=app_label, model_name=model_name),
                self.sut.allow_migrate(db='app_shard_001_replica_002', app_label=app_label, model_name=model_name),
            ]),
            False
        )
        self.assertEqual(
            all([
                self.sut.allow_migrate(db='app_shard_001', app_label=app_label, model_name=model_name),
                self.sut.allow_migrate(db='app_shard_002', app_label=app_label, model_name=model_name),
            ]),
            can_migrate_shard
        )
        if migratable_db:
            self.assertTrue(self.sut.allow_migrate(db=migratable_db, app_label=app_label, model_name=model_name))

    def test_model_name_passed_in(self):
        self.assertTrue(self.sut.allow_migrate(db='default', app_label='tests', model_name="User"))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001', app_label='tests', model_name="User"))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_002', app_label='tests', model_name="User"))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_001', app_label='tests', model_name="User"))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_002', app_label='tests', model_name="User"))

    def test_model_passed_in(self):
        from django.contrib.auth import get_user_model

        hints = {'model': get_user_model()}

        self.assertTrue(self.sut.allow_migrate(db='default', app_label='tests', model_name=None, **hints))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001', app_label='tests', model_name=None, **hints))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_002', app_label='tests', model_name=None, **hints))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_001', app_label='tests', model_name=None, **hints))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_002', app_label='tests', model_name=None, **hints))

    def test_app_passed_in(self):
        self.assertTrue(self.sut.allow_migrate(db='default', app_label='tests'))
        self.assertTrue(self.sut.allow_migrate(db='app_shard_001', app_label='tests'))
        self.assertTrue(self.sut.allow_migrate(db='app_shard_002', app_label='tests'))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_001', app_label='tests'))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_002', app_label='tests'))

    def test_force_migrate_on_databases(self):
        hints = {"force_migrate_on_databases": ["app_shard_001"]}
        self.assertFalse(self.sut.allow_migrate(db='default', app_label='tests', **hints))
        self.assertTrue(self.sut.allow_migrate(db='app_shard_001', app_label='tests', **hints))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_002', app_label='tests', **hints))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_001', app_label='tests', **hints))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_002', app_label='tests', **hints))

    def test_force_migrate_on_databases_ignores_secondary(self):
        hints = {"force_migrate_on_databases": ["app_shard_001_replica_001"]}
        self.assertFalse(self.sut.allow_migrate(db='default', app_label='tests', **hints))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001', app_label='tests', **hints))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_002', app_label='tests', **hints))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_001', app_label='tests', **hints))
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_002', app_label='tests', **hints))

    def test_migrate_replica_will_not_work(self):
        self.assertFalse(self.sut.allow_migrate(db='app_shard_001_replica_001', app_label='tests', model_name='TestModel'))
        self.assertTrue(self.sut.allow_migrate(db='app_shard_001', app_label='tests', model_name='TestModel'))

    def test_migrate_sharded_model_with_specific_database_will_not_work(self):
        sut = ShardedRouter()

        with patch.object(TestModel, "django_sharding__database", 'blah', create=True):
            with patch.object(TestModel, "django_sharding__is_sharded", True, create=True):
                with self.assertRaises(InvalidMigrationException):
                    sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

        with patch.object(TestModel, "django_sharding__database", 'blah', create=True):
            with patch.object(TestModel, "django_sharding__is_sharded", False, create=True):
                sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

        with patch.object(TestModel, "django_sharding__database", None, create=True):
            with patch.object(TestModel, "django_sharding__is_sharded", True, create=True):
                sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

        sut.allow_migrate(db='default', app_label='tests', model_name='TestModel')

    def test_django_model_only_allows_on_default(self):
        self.assert_allow_migrate(
            app_label='auth',
            model_name='Group',
            can_migrate_default=True,
            can_migrate_shard=False
        )

    def test_specific_database_only_on_datbase(self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='ShardedTestModelIDs',
            can_migrate_default=False,
            can_migrate_shard=False,
            migratable_db='app_shard_001'
        )

    def test_specific_sharded_model_only_on_shards(self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='TestModel',
            can_migrate_default=False,
            can_migrate_shard=True,
        )

    def test_lookup_fallback_if_migration_directory_not_the_same_as_the_model(self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='auth.User',
            can_migrate_default=True,
            can_migrate_shard=False,
        )
class RouterAllowMigrateTestCase(TestCase):
    def setUp(self):
        self.sut = ShardedRouter()

    def assert_allow_migrate(self,
                             app_label,
                             model_name,
                             can_migrate_default,
                             can_migrate_shard,
                             migratable_db=None):
        self.assertEqual(
            self.sut.allow_migrate(db='default',
                                   app_label=app_label,
                                   model_name=model_name), can_migrate_default)
        self.assertEqual(
            all([
                self.sut.allow_migrate(db='app_shard_001_replica_001',
                                       app_label=app_label,
                                       model_name=model_name),
                self.sut.allow_migrate(db='app_shard_001_replica_002',
                                       app_label=app_label,
                                       model_name=model_name),
            ]), False)
        self.assertEqual(
            all([
                self.sut.allow_migrate(db='app_shard_001',
                                       app_label=app_label,
                                       model_name=model_name),
                self.sut.allow_migrate(db='app_shard_002',
                                       app_label=app_label,
                                       model_name=model_name),
            ]), can_migrate_shard)
        if migratable_db:
            self.assertTrue(
                self.sut.allow_migrate(db=migratable_db,
                                       app_label=app_label,
                                       model_name=model_name))

    def test_requires_model_name_to_be_passed_in(self):
        with self.assertRaises(InvalidMigrationException):
            self.sut.allow_migrate(db='default', app_label='tests')

        self.sut.allow_migrate(db='default',
                               app_label='tests',
                               model_name='User')
        hints = {'model_name': 'User'}
        self.sut.allow_migrate(db='default', app_label='tests', **hints)

    def test_requires_model_to_be_passed_in(self):
        from django.contrib.auth import get_user_model
        with self.assertRaises(InvalidMigrationException):
            self.sut.allow_migrate(db='default', app_label='tests')

        hints = {'model': get_user_model()}
        self.sut.allow_migrate(db='default',
                               app_label='tests',
                               model_name=None,
                               **hints)

    def test_migrate_replica_will_not_work(self):
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests',
                                   model_name='TestModel'))
        self.assertTrue(
            self.sut.allow_migrate(db='app_shard_001',
                                   app_label='tests',
                                   model_name='TestModel'))

    def test_migrate_sharded_model_with_specific_database_will_not_work(self):
        sut = ShardedRouter()
        sut.get_specific_database_or_none = lambda self: 'default'
        sut.get_shard_group_if_sharded_or_none = lambda self: 'default'
        with self.assertRaises(InvalidMigrationException):
            sut.allow_migrate(db='default',
                              app_label='tests',
                              model_name='TestModel')

        sut.get_specific_database_or_none = lambda self: None
        sut.allow_migrate(db='default',
                          app_label='tests',
                          model_name='TestModel')

        sut.get_specific_database_or_none = lambda self: 'default'
        sut.get_shard_group_if_sharded_or_none = lambda self: None
        sut.allow_migrate(db='default',
                          app_label='tests',
                          model_name='TestModel')

    def test_django_model_only_allows_on_default(self):
        self.assert_allow_migrate(app_label='auth',
                                  model_name='Group',
                                  can_migrate_default=True,
                                  can_migrate_shard=False)

    def test_specific_database_only_on_datbase(self):
        self.assert_allow_migrate(app_label='tests',
                                  model_name='ShardedTestModelIDs',
                                  can_migrate_default=False,
                                  can_migrate_shard=False,
                                  migratable_db='app_shard_001')

    def test_specific_sharded_model_only_on_shards(self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='TestModel',
            can_migrate_default=False,
            can_migrate_shard=True,
        )

    def test_lookup_fallback_if_migration_directory_not_the_same_as_the_model(
            self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='auth.User',
            can_migrate_default=True,
            can_migrate_shard=False,
        )
Beispiel #9
0
class RouterAllowMigrateTestCase(TransactionTestCase):
    databases = '__all__'

    def setUp(self):
        self.sut = ShardedRouter()

    def assert_allow_migrate(self,
                             app_label,
                             model_name,
                             can_migrate_default,
                             can_migrate_shard,
                             migratable_db=None):
        self.assertEqual(
            self.sut.allow_migrate(db='default',
                                   app_label=app_label,
                                   model_name=model_name), can_migrate_default)
        self.assertEqual(
            all([
                self.sut.allow_migrate(db='app_shard_001_replica_001',
                                       app_label=app_label,
                                       model_name=model_name),
                self.sut.allow_migrate(db='app_shard_001_replica_002',
                                       app_label=app_label,
                                       model_name=model_name),
            ]), False)
        self.assertEqual(
            all([
                self.sut.allow_migrate(db='app_shard_001',
                                       app_label=app_label,
                                       model_name=model_name),
                self.sut.allow_migrate(db='app_shard_002',
                                       app_label=app_label,
                                       model_name=model_name),
            ]), can_migrate_shard)
        if migratable_db:
            self.assertTrue(
                self.sut.allow_migrate(db=migratable_db,
                                       app_label=app_label,
                                       model_name=model_name))

    def test_model_name_passed_in(self):
        self.assertTrue(
            self.sut.allow_migrate(db='default',
                                   app_label='tests',
                                   model_name="User"))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001',
                                   app_label='tests',
                                   model_name="User"))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_002',
                                   app_label='tests',
                                   model_name="User"))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests',
                                   model_name="User"))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_002',
                                   app_label='tests',
                                   model_name="User"))

    def test_model_passed_in(self):

        hints = {'model': get_user_model()}

        self.assertTrue(
            self.sut.allow_migrate(db='default',
                                   app_label='tests',
                                   model_name=None,
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001',
                                   app_label='tests',
                                   model_name=None,
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_002',
                                   app_label='tests',
                                   model_name=None,
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests',
                                   model_name=None,
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_002',
                                   app_label='tests',
                                   model_name=None,
                                   **hints))

    def test_app_passed_in(self):
        self.assertTrue(self.sut.allow_migrate(db='default',
                                               app_label='tests'))
        self.assertTrue(
            self.sut.allow_migrate(db='app_shard_001', app_label='tests'))
        self.assertTrue(
            self.sut.allow_migrate(db='app_shard_002', app_label='tests'))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests'))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_002',
                                   app_label='tests'))

    def test_force_migrate_on_databases(self):
        hints = {"force_migrate_on_databases": ["app_shard_001"]}
        self.assertFalse(
            self.sut.allow_migrate(db='default', app_label='tests', **hints))
        self.assertTrue(
            self.sut.allow_migrate(db='app_shard_001',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_002',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_002',
                                   app_label='tests',
                                   **hints))

    def test_force_migrate_on_databases_ignores_secondary(self):
        hints = {"force_migrate_on_databases": ["app_shard_001_replica_001"]}
        self.assertFalse(
            self.sut.allow_migrate(db='default', app_label='tests', **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_002',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests',
                                   **hints))
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_002',
                                   app_label='tests',
                                   **hints))

    def test_migrate_replica_will_not_work(self):
        self.assertFalse(
            self.sut.allow_migrate(db='app_shard_001_replica_001',
                                   app_label='tests',
                                   model_name='TestModel'))
        self.assertTrue(
            self.sut.allow_migrate(db='app_shard_001',
                                   app_label='tests',
                                   model_name='TestModel'))

    def test_migrate_sharded_model_with_specific_database_will_not_work(self):
        sut = ShardedRouter()

        with patch.object(TestModel,
                          "django_sharding__database",
                          'blah',
                          create=True):
            with patch.object(TestModel,
                              "django_sharding__is_sharded",
                              True,
                              create=True):
                with self.assertRaises(InvalidMigrationException):
                    sut.allow_migrate(db='default',
                                      app_label='tests',
                                      model_name='TestModel')

        with patch.object(TestModel,
                          "django_sharding__database",
                          'blah',
                          create=True):
            with patch.object(TestModel,
                              "django_sharding__is_sharded",
                              False,
                              create=True):
                sut.allow_migrate(db='default',
                                  app_label='tests',
                                  model_name='TestModel')

        with patch.object(TestModel,
                          "django_sharding__database",
                          None,
                          create=True):
            with patch.object(TestModel,
                              "django_sharding__is_sharded",
                              True,
                              create=True):
                sut.allow_migrate(db='default',
                                  app_label='tests',
                                  model_name='TestModel')

        sut.allow_migrate(db='default',
                          app_label='tests',
                          model_name='TestModel')

    def test_django_model_only_allows_on_default(self):
        self.assert_allow_migrate(app_label='auth',
                                  model_name='Group',
                                  can_migrate_default=True,
                                  can_migrate_shard=False)

    def test_specific_database_only_on_datbase(self):
        self.assert_allow_migrate(app_label='tests',
                                  model_name='ShardedTestModelIDs',
                                  can_migrate_default=False,
                                  can_migrate_shard=False,
                                  migratable_db='app_shard_001')

    def test_specific_sharded_model_only_on_shards(self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='TestModel',
            can_migrate_default=False,
            can_migrate_shard=True,
        )

    def test_lookup_fallback_if_migration_directory_not_the_same_as_the_model(
            self):
        self.assert_allow_migrate(
            app_label='tests',
            model_name='auth.User',
            can_migrate_default=True,
            can_migrate_shard=False,
        )

    @override_settings(DJANGO_SHARDING_SETTINGS={
        "DELETED_MODELS": {
            "deleted.Whatever": {
                "database": "app_shard_002"
            }
        }
    })
    def test_deleted_model_in_settings__specific_database(self):
        self.assertFalse(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='default',
                                   app_label='deleted',
                                   **{}))
        self.assertTrue(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='app_shard_002',
                                   app_label='deleted',
                                   **{}))

        self.assertFalse(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='default',
                                   app_label='deleted',
                                   **{}))
        self.assertTrue(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='app_shard_002',
                                   app_label='deleted',
                                   **{}))

    @override_settings(DJANGO_SHARDING_SETTINGS={
        "DELETED_MODELS": {
            "deleted.Whatever": {
                "shard_group": "default"
            }
        }
    })
    def test_deleted_model_in_settings__shard_group(self):
        self.assertFalse(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='default',
                                   app_label='deleted',
                                   **{}))
        self.assertTrue(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='app_shard_001',
                                   app_label='deleted',
                                   **{}))
        self.assertTrue(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='app_shard_002',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='app_shard_001_replica_001',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='app_shard_001_replica_002',
                                   app_label='deleted',
                                   **{}))

        self.assertFalse(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='default',
                                   app_label='deleted',
                                   **{}))
        self.assertTrue(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='app_shard_001',
                                   app_label='deleted',
                                   **{}))
        self.assertTrue(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='app_shard_002',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='app_shard_001_replica_001',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='app_shard_001_replica_002',
                                   app_label='deleted',
                                   **{}))

    @override_settings(DJANGO_SHARDING_SETTINGS={
        "DELETED_MODELS": {
            "deleted.Whatever": None
        }
    })
    def test_deleted_model_in_settings__unsharded(self):
        self.assertTrue(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='default',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='app_shard_001',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='app_shard_002',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='app_shard_001_replica_001',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="deleted.Whatever",
                                   db='app_shard_001_replica_002',
                                   app_label='deleted',
                                   **{}))

        self.assertTrue(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='default',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='app_shard_001',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='app_shard_002',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='app_shard_001_replica_001',
                                   app_label='deleted',
                                   **{}))
        self.assertFalse(
            self.sut.allow_migrate(model_name="Whatever",
                                   db='app_shard_001_replica_002',
                                   app_label='deleted',
                                   **{}))