Exemplo n.º 1
0
    def test_migrate_with_dry_run_flag(self, mock_file_config, initialize, mocked_apply_migration,
                                       getLogger):
        """
        Test that when a dry run is performed, no migrations actually occur.
        """
        logger = MagicMock()
        getLogger.return_value = logger

        # Make sure we start out with a clean slate
        self.assertEquals(MigrationTracker.objects().count(), 0)
        # Make sure that our mock works. There are three valid packages.
        self.assertEquals(len(models.get_migration_packages()), 4)
        # Set all versions back to 0
        for package in models.get_migration_packages():
            package._migration_tracker.version = 0
            package._migration_tracker.save()
        result = manage.main()

        # Test that none of the mock objects were actually called
        migration_modules_called = [
            mock_call[1][1].name for mock_call in mocked_apply_migration.mock_calls]
        self.assertEquals(0, len(migration_modules_called))
        self.assertEquals(1, result)
        for package in models.get_migration_packages():
            self.assertEqual(package.current_version, 0)

        initialize.assert_called_once_with(max_timeout=1)
Exemplo n.º 2
0
    def test_current_version_too_high(self, mocked_file_config, initialize, getLogger):
        """
        Set the current package version higher than latest available version, then sit back and eat
        popcorn.
        """
        logger = MagicMock()
        getLogger.return_value = logger

        # Make sure we start out with a clean slate
        self.assertEquals(MigrationTracker.objects().count(), 0)
        # Make sure that our mock works. There are four valid packages.
        self.assertEquals(len(models.get_migration_packages()), 4)
        # Set all versions to ridiculously high values
        for package in models.get_migration_packages():
            package._migration_tracker.version = 9999999
            package._migration_tracker.save()
        error_code = manage.main()
        self.assertEqual(error_code, os.EX_DATAERR)

        # There should have been a critical log about the Exception
        expected_messages = (
            'The database for migration package unit.server.db.migration_packages.'
            'platform is at version 9999999, which is larger than the latest version available, 1.')
        critical_messages = ''.join([mock_call[1][0] for mock_call in logger.critical.mock_calls])
        for msg in expected_messages:
            self.assertTrue(msg in critical_messages)

        initialize.assert_called_once_with(max_timeout=1)
Exemplo n.º 3
0
    def test_current_version_too_high(self, mocked_file_config, initialize, getLogger):
        """
        Set the current package version higher than latest available version, then sit back and eat
        popcorn.
        """
        logger = MagicMock()
        getLogger.return_value = logger

        # Make sure we start out with a clean slate
        self.assertEquals(MigrationTracker.objects().count(), 0)
        # Make sure that our mock works and sees the right number of packages
        self.assertEquals(len(models.get_migration_packages()), 5)
        # Set all versions to ridiculously high values
        for package in models.get_migration_packages():
            package._migration_tracker.version = 9999999
            package._migration_tracker.save()
        error_code = manage.main()
        self.assertEqual(error_code, os.EX_DATAERR)

        # There should have been a critical log about the Exception
        expected_messages = (
            'The database for migration package unit.server.db.migration_packages.'
            'platform is at version 9999999, which is larger than the latest version available, 1.')
        critical_messages = ''.join([mock_call[1][0] for mock_call in logger.critical.mock_calls])
        for msg in expected_messages:
            self.assertTrue(msg in critical_messages)

        initialize.assert_called_once_with(max_timeout=1)
Exemplo n.º 4
0
    def test_migrate_with_new_packages(self, initialize, start_logging_mock,
                                       logger_mock, mocked_stdout,
                                       mocked_stderr):
        """
        Adding new packages to a system that doesn't have any trackers should advance
        each package to the latest available version, applying all migrate() functions along the
        way.
        """
        # Make sure we start out with a clean slate
        self.assertEquals(MigrationTracker.objects().count(), 0)
        # Make sure that our mock works. There are four valid packages.
        self.assertEquals(len(models.get_migration_packages()), 4)
        manage.main()

        for package in models.get_migration_packages():
            if 'raise_exception' in str(package):
                # The Exception raising package should get to version 1, because version 2 raises
                self.assertEqual(package.current_version, 1)
            elif 'z' in str(package):
                self.assertEquals(package.current_version, 0)
            else:
                # All other packages should reach their top versions
                self.assertEqual(package.current_version,
                                 package.latest_available_version)

        initialize.assert_called_once_with(max_timeout=1)
Exemplo n.º 5
0
    def test_migrate_with_dry_run_flag(self, mock_file_config, initialize,
                                       mocked_apply_migration, getLogger):
        """
        Test that when a dry run is performed, no migrations actually occur.
        """
        logger = MagicMock()
        getLogger.return_value = logger

        # Make sure we start out with a clean slate
        self.assertEquals(MigrationTracker.objects().count(), 0)
        # Make sure that our mock works. There are three valid packages.
        self.assertEquals(len(models.get_migration_packages()), 4)
        # Set all versions back to 0
        for package in models.get_migration_packages():
            package._migration_tracker.version = 0
            package._migration_tracker.save()
        result = manage.main()

        # Test that none of the mock objects were actually called
        migration_modules_called = [
            mock_call[1][1].name
            for mock_call in mocked_apply_migration.mock_calls
        ]
        self.assertEquals(0, len(migration_modules_called))
        self.assertEquals(1, result)
        for package in models.get_migration_packages():
            self.assertEqual(package.current_version, 0)

        initialize.assert_called_once_with(max_timeout=1)
Exemplo n.º 6
0
    def test_migrate(self, mock_file_config, initialize,
                     mocked_apply_migration, getLogger):
        """
        Let's set all the packages to be at version 0, and then check that the migrations get
        called in the correct order.
        """

        logger = MagicMock()
        getLogger.return_value = logger

        # Make sure we start out with a clean slate
        self.assertEquals(MigrationTracker.objects().count(), 0)
        # Make sure that our mock works. There are three valid packages.
        self.assertEquals(len(models.get_migration_packages()), 4)
        # Set all versions back to 0
        for package in models.get_migration_packages():
            package._migration_tracker.version = 0
            package._migration_tracker.save()
        manage.main()

        # There should have been a critical log about the Exception
        expected_messages = (
            'Applying migration '
            'unit.server.db.migration_packages.raise_exception.0002_oh_no failed.\n\n'
            'Halting migrations due to a migration failure.',
            "Bet you didn\'t see this coming.")
        critical_messages = ''.join(
            [mock_call[1][0] for mock_call in logger.critical.mock_calls])
        for msg in expected_messages:
            self.assertTrue(msg in critical_messages)

        migration_modules_called = [
            mock_call[1][1].name
            for mock_call in mocked_apply_migration.mock_calls
        ]
        # Note that none of the migrations that don't meet our criteria show up in this list. Also,
        # Note that migration_packages.raise_exception.0003_shouldnt_run doesn't appear
        # since migration_packages.raise_exception.0002_oh_no raised an Exception. Note
        # also that even though the raise_exception package raised an Exception, we still run all
        # the z migrations because we don't want one package to break another.
        expected_migration_modules_called = [
            'unit.server.db.migration_packages.platform.0001_stuff_and_junk',
            'unit.server.db.migration_packages.raise_exception.0001_works_fine',
            'unit.server.db.migration_packages.raise_exception.0002_oh_no'
        ]
        self.assertEquals(migration_modules_called,
                          expected_migration_modules_called)
        # Assert that our precious versions have been updated correctly
        for package in models.get_migration_packages():
            if package.name == 'unit.server.db.migration_packages.platform':
                self.assertEqual(package.current_version,
                                 package.latest_available_version)
            elif package.name == 'unit.server.db.migration_packages.raise_exception':
                # The raised Exception should have prevented us from getting past version 1
                self.assertEquals(package.current_version, 1)
            else:
                # raise_exception should cause the migrations to stop
                self.assertEqual(package.current_version, 0)

        initialize.assert_called_once_with(max_timeout=1)
Exemplo n.º 7
0
    def __init__(self, python_package):
        """
        Initialize the MigrationPackage to represent the Python migration package passed in.

        :param python_package: The Python package this object should represent
        :type  python_package: package
        """
        self._package = python_package
        self.allow_fast_forward = getattr(python_package, 'allow_fast_forward',
                                          False)
        self.duration = None

        try:
            self._migration_tracker = MigrationTracker.objects().get(
                name=self.name)
        except DoesNotExist:
            self._migration_tracker = MigrationTracker(name=self.name)
            self._migration_tracker.save()

        # Calculate the latest available version
        available_versions = self.available_versions
        if available_versions:
            self.latest_available_version = available_versions[-1]
        else:
            self.latest_available_version = 0
Exemplo n.º 8
0
    def test_migrate(self, mock_file_config, initialize, mocked_apply_migration, getLogger):
        """
        Let's set all the packages to be at version 0, and then check that the migrations get
        called in the correct order.
        """

        logger = MagicMock()
        getLogger.return_value = logger

        # Make sure we start out with a clean slate
        self.assertEquals(MigrationTracker.objects().count(), 0)
        # Make sure that our mock works. There are three valid packages.
        self.assertEquals(len(models.get_migration_packages()), 4)
        # Set all versions back to 0
        for package in models.get_migration_packages():
            package._migration_tracker.version = 0
            package._migration_tracker.save()
        manage.main()

        # There should have been a critical log about the Exception
        expected_messages = (
            'Applying migration '
            'unit.server.db.migration_packages.raise_exception.0002_oh_no failed.\n\n'
            'Halting migrations due to a migration failure.',
            "Bet you didn\'t see this coming."
        )
        critical_messages = ''.join([mock_call[1][0] for mock_call in logger.critical.mock_calls])
        for msg in expected_messages:
            self.assertTrue(msg in critical_messages)

        migration_modules_called = [
            mock_call[1][1].name for mock_call in mocked_apply_migration.mock_calls]
        # Note that none of the migrations that don't meet our criteria show up in this list. Also,
        # Note that migration_packages.raise_exception.0003_shouldnt_run doesn't appear
        # since migration_packages.raise_exception.0002_oh_no raised an Exception. Note
        # also that even though the raise_exception package raised an Exception, we still run all
        # the z migrations because we don't want one package to break another.
        expected_migration_modules_called = [
            'unit.server.db.migration_packages.platform.0001_stuff_and_junk',
            'unit.server.db.migration_packages.raise_exception.0001_works_fine',
            'unit.server.db.migration_packages.raise_exception.0002_oh_no']
        self.assertEquals(migration_modules_called, expected_migration_modules_called)
        # Assert that our precious versions have been updated correctly
        for package in models.get_migration_packages():
            if package.name == 'unit.server.db.migration_packages.platform':
                self.assertEqual(package.current_version, package.latest_available_version)
            elif package.name == 'unit.server.db.migration_packages.raise_exception':
                # The raised Exception should have prevented us from getting past version 1
                self.assertEquals(package.current_version, 1)
            else:
                # raise_exception should cause the migrations to stop
                self.assertEqual(package.current_version, 0)

        initialize.assert_called_once_with(max_timeout=1)
Exemplo n.º 9
0
    def __init__(self, python_package):
        """
        Initialize the MigrationPackage to represent the Python migration package passed in.

        :param python_package: The Python package this object should represent
        :type  python_package: package
        """
        self._package = python_package
        self.allow_fast_forward = getattr(python_package, 'allow_fast_forward', False)

        try:
            self._migration_tracker = MigrationTracker.objects().get(name=self.name)
        except DoesNotExist:
            self._migration_tracker = MigrationTracker(name=self.name)
            self._migration_tracker.save()

        # Calculate the latest available version
        available_versions = self.available_versions
        if available_versions:
            self.latest_available_version = available_versions[-1]
        else:
            self.latest_available_version = 0
Exemplo n.º 10
0
    def test_migrate_with_new_packages(self, initialize, start_logging_mock, logger_mock,
                                       mocked_stdout, mocked_stderr):
        """
        Adding new packages to a system that doesn't have any trackers should advance
        each package to the latest available version, applying no migrate() functions along the
        way.
        """
        # Make sure we start out with a clean slate
        self.assertEquals(MigrationTracker.objects().count(), 0)
        # Make sure that our mock works. There are five valid packages.
        self.assertEquals(len(models.get_migration_packages()), 5)
        manage.main()

        for package in models.get_migration_packages():
            if 'raise_exception' in str(package):
                # The Exception raising package should get to version 3, despite the fact that
                # version 2 raises an exception, because new trackers get fast-forwarded.
                self.assertEqual(package.current_version, 3)
            else:
                # All other packages should reach their top versions
                self.assertEqual(package.current_version, package.latest_available_version)

        initialize.assert_called_once_with(max_timeout=1)
Exemplo n.º 11
0
    def __init__(self, python_package):
        """
        Initialize the MigrationPackage to represent the Python migration package passed in.

        :param python_package: The Python package this object should represent
        :type  python_package: package
        """
        self._package = python_package
        # This is an object representation of the DB object that keeps track of the migration
        # version that has been applied

        try:
            self._migration_tracker = MigrationTracker.objects().get(name=self.name)
        except DoesNotExist:
            self._migration_tracker = MigrationTracker(name=self.name)
            self._migration_tracker.save()

        # Calculate the latest available version
        available_versions = self.available_versions
        if available_versions:
            self.latest_available_version = available_versions[-1]
        else:
            self.latest_available_version = 0
Exemplo n.º 12
0
    def __init__(self, python_package):
        """
        Initialize the MigrationPackage to represent the Python migration package passed in.

        :param python_package: The Python package this object should represent
        :type  python_package: package
        """
        self._package = python_package
        # This is an object representation of the DB object that keeps track of the migration
        # version that has been applied

        try:
            self._migration_tracker = MigrationTracker.objects().get(name=self.name)
        except DoesNotExist:
            self._migration_tracker = MigrationTracker(name=self.name)
            self._migration_tracker.save()

        # Calculate the latest available version
        available_versions = self.available_versions
        if available_versions:
            self.latest_available_version = available_versions[-1]
        else:
            self.latest_available_version = 0
Exemplo n.º 13
0
 def clean(self):
     super(MigrationTest, self).clean()
     # Make sure each test doesn't have any lingering MigrationTrackers
     MigrationTracker.objects().delete()