Пример #1
0
    def test_run_operation_creates_and_updates_task_marker(self):
        """ If we run one of our custom operations, then it should create the task marker in the DB
            and defer a task, then set the marker to 'is_finished' when done.
        """
        TestModel.objects.create()

        operation = operations.AddFieldData(
            "testmodel", "new_field",
            models.CharField(max_length=100, default="squirrel"))
        self.start_operation(operation)

        # Now check that the task marker has been created.
        # Usefully, calling database_forwards() on the operation will have caused it to set the
        # `identifier` attribute on itself, meaning we can now just call _get_task_marker()
        task_marker = datastore.Get([
            ShardedTaskMarker.get_key(operation.identifier,
                                      operation.namespace)
        ])[0]
        if task_marker is None:
            self.fail("Migration operation did not create its task marker")

        self.assertFalse(task_marker.get("is_finished"))
        self.assertNumTasksEquals(1)
        self.process_task_queues()

        # Now check that the task marker has been marked as finished
        task_marker = datastore.Get([
            ShardedTaskMarker.get_key(operation.identifier,
                                      operation.namespace)
        ])[0]
        self.assertTrue(task_marker["is_finished"])
        self.assertNumTasksEquals(0)
Пример #2
0
    def test_running_finished_operation_does_not_trigger_new_task(self):
        """ If we re-trigger an operation which has already been run and finished, it should simply
            return without starting a new task or updating the task marker.
        """
        TestModel.objects.create()

        operation = operations.AddFieldData(
            "testmodel", "new_field", models.CharField(max_length=100, default="squirrel")
        )
        # Run the operation and check that it finishes
        with sleuth.watch("djangae.db.migrations.operations.AddFieldData._start_task") as start:
            self.start_operation(operation)
            self.assertTrue(start.called)
        task_marker = datastore.Get(
            ShardedTaskMarker.get_key(operation.identifier, operation.namespace)
        )
        self.assertFalse(task_marker["is_finished"])
        self.assertNumTasksEquals(1)
        self.process_task_queues()
        task_marker = datastore.Get(
            ShardedTaskMarker.get_key(operation.identifier, operation.namespace)
        )
        self.assertTrue(task_marker["is_finished"])

        # Run the operation again.  It should see that's it's finished and just return immediately.
        self.assertNumTasksEquals(0)
        with sleuth.watch("djangae.db.migrations.operations.AddFieldData._start_task") as start:
            self.start_operation(operation, detonate=False)
            self.assertFalse(start.called)
        self.assertNumTasksEquals(0)
        task_marker = datastore.Get(
            ShardedTaskMarker.get_key(operation.identifier, operation.namespace)
        )
        self.assertTrue(task_marker["is_finished"])
Пример #3
0
    def test_running_finished_operation_does_not_trigger_new_task(self):
        """ If we re-trigger an operation which has already been run and finished, it should simply
            return without starting a new task or updating the task marker.
        """
        TestModel.objects.create()

        operation = operations.AddFieldData(
            "testmodel", "new_field", models.CharField(max_length=100, default="squirrel")
        )
        # Run the operation and check that it finishes
        with sleuth.watch("djangae.db.migrations.operations.AddFieldData._start_task") as start:
            self.start_operation(operation)
            self.assertTrue(start.called)
        task_marker = datastore.Get(
            ShardedTaskMarker.get_key(operation.identifier, operation.namespace)
        )
        self.assertFalse(task_marker["is_finished"])
        self.assertNumTasksEquals(1)
        self.process_task_queues()
        task_marker = datastore.Get(
            ShardedTaskMarker.get_key(operation.identifier, operation.namespace)
        )
        self.assertTrue(task_marker["is_finished"])

        # Run the operation again.  It should see that's it's finished and just return immediately.
        self.assertNumTasksEquals(0)
        with sleuth.watch("djangae.db.migrations.operations.AddFieldData._start_task") as start:
            self.start_operation(operation, detonate=False)
            self.assertFalse(start.called)
        self.assertNumTasksEquals(0)
        task_marker = datastore.Get(
            ShardedTaskMarker.get_key(operation.identifier, operation.namespace)
        )
        self.assertTrue(task_marker["is_finished"])
Пример #4
0
    def test_run_operation_creates_and_updates_task_marker(self):
        """ If we run one of our custom operations, then it should create the task marker in the DB
            and defer a task, then set the marker to 'is_finished' when done.
        """
        TestModel.objects.create()

        operation = operations.AddFieldData(
            "testmodel", "new_field", models.CharField(max_length=100, default="squirrel")
        )
        self.start_operation(operation)

        # Now check that the task marker has been created.
        # Usefully, calling database_forwards() on the operation will have caused it to set the
        # `identifier` attribute on itself, meaning we can now just call _get_task_marker()
        task_marker = datastore.Get(
            [ShardedTaskMarker.get_key(operation.identifier, operation.namespace)]
        )[0]
        if task_marker is None:
            self.fail("Migration operation did not create its task marker")

        self.assertFalse(task_marker.get("is_finished"))
        self.assertNumTasksEquals(1)
        self.process_task_queues()

        # Now check that the task marker has been marked as finished
        task_marker = datastore.Get(
            [ShardedTaskMarker.get_key(operation.identifier, operation.namespace)]
        )[0]
        self.assertTrue(task_marker["is_finished"])
        self.assertNumTasksEquals(0)
Пример #5
0
    def test_starting_operation_twice_does_not_trigger_task_twice(self):
        """ If we run an operation, and then try to run it again before the task has finished
            processing, then it should not trigger a second task.
        """
        TestModel.objects.create()

        operation = operations.AddFieldData(
            "testmodel", "new_field",
            models.CharField(max_length=100, default="squirrel"))
        self.start_operation(operation)

        task_marker = datastore.Get(
            ShardedTaskMarker.get_key(operation.identifier,
                                      operation.namespace))
        self.assertFalse(task_marker["is_finished"])

        # We expect there to be a task queued for processing the operation
        self.assertNumTasksEquals(1)
        # Now try to run it again
        self.start_operation(operation)
        # We expect there to still be the same number of tasks
        self.assertNumTasksEquals(1)
Пример #6
0
    def test_starting_operation_twice_does_not_trigger_task_twice(self):
        """ If we run an operation, and then try to run it again before the task has finished
            processing, then it should not trigger a second task.
        """
        TestModel.objects.create()

        operation = operations.AddFieldData(
            "testmodel", "new_field", models.CharField(max_length=100, default="squirrel")
        )
        self.start_operation(operation)

        task_marker = datastore.Get(
            ShardedTaskMarker.get_key(operation.identifier, operation.namespace)
        )
        self.assertFalse(task_marker["is_finished"])

        # We expect there to be a task queued for processing the operation
        self.assertNumTasksEquals(1)
        # Now try to run it again
        self.start_operation(operation)
        # We expect there to still be the same number of tasks
        self.assertNumTasksEquals(1)