def setUp(self): self.not_active_schedule = factories.BackupScheduleFactory( is_active=False) backupable = factories.InstanceFactory(state=Instance.States.OFFLINE) self.schedule_for_execution = factories.BackupScheduleFactory( instance=backupable) self.schedule_for_execution.next_trigger_at = timezone.now( ) - timedelta(minutes=10) self.schedule_for_execution.save() self.future_schedule = factories.BackupScheduleFactory() self.future_schedule.next_trigger_at = timezone.now() + timedelta( minutes=2) self.future_schedule.save()
def test_update_next_trigger_at_with_provided_timezone(self): schedule = factories.BackupScheduleFactory(timezone='Europe/London') schedule.update_next_trigger_at() # next_trigger_at timezone and schedule's timezone must be equal. self.assertEqual(schedule.timezone, schedule.next_trigger_at.tzinfo.zone)
def test_update_next_trigger_at(self): now = timezone.now() schedule = factories.BackupScheduleFactory() schedule.schedule = '*/10 * * * *' schedule.update_next_trigger_at() self.assertTrue(schedule.next_trigger_at) self.assertGreater(schedule.next_trigger_at, now)
def test_backup_schedule_for_unstable_source_should_not_start(self): backupable = factories.InstanceFactory( state=models.Instance.States.ERRED) schedule = factories.BackupScheduleFactory(instance=backupable) backup = schedule.get_backend() self.assertEqual(backup.check_instance_state(), False) self.assertEqual(backup.create_backup(), None)
def setUp(self): super(BackupSchedulePermissionsTest, self).setUp() # objects self.customer = structure_factories.CustomerFactory() self.project = structure_factories.ProjectFactory( customer=self.customer) self.project_group = structure_factories.ProjectGroupFactory( customer=self.customer) self.project_group.projects.add(self.project) self.service = factories.OpenStackServiceFactory( customer=self.customer) self.spl = factories.OpenStackServiceProjectLinkFactory( service=self.service, project=self.project) self.instance = factories.InstanceFactory( service_project_link=self.spl) self.schedule = factories.BackupScheduleFactory(instance=self.instance) # users self.staff = structure_factories.UserFactory(username='******', is_staff=True) self.regular_user = structure_factories.UserFactory( username='******') self.project_admin = structure_factories.UserFactory(username='******') self.project.add_user(self.project_admin, structure_models.ProjectRole.ADMINISTRATOR) self.customer_owner = structure_factories.UserFactory(username='******') self.customer.add_user(self.customer_owner, structure_models.CustomerRole.OWNER) self.project_group_manager = structure_factories.UserFactory( username='******') self.project_group.add_user(self.project_group_manager, structure_models.ProjectGroupRole.MANAGER)
def test_create_backup(self): now = timezone.now() schedule = factories.BackupScheduleFactory(retention_time=3, instance=self.instance) backend = schedule.get_backend() backend.create_backup() backup = models.Backup.objects.get(backup_schedule=schedule) self.assertFalse(backup.kept_until is None) self.assertGreater(backup.kept_until, now - timedelta(days=schedule.retention_time))
def test_weekly_backup_schedule_next_trigger_at_is_correct(self): schedule = factories.BackupScheduleFactory(schedule='0 2 * * 4') cron = croniter('0 2 * * 4', datetime.datetime.now(tz=timezone(settings.TIME_ZONE))) next_backup = schedule.next_trigger_at self.assertEqual(next_backup, cron.get_next(datetime.datetime)) self.assertEqual(next_backup.weekday(), 3, 'Must be Thursday') for k, v in {'hour': 2, 'minute': 0, 'second': 0}.items(): self.assertEqual(getattr(next_backup, k), v, 'Must be 2:00am')
def test_daily_backup_schedule_next_trigger_at_is_correct(self): schedule = '0 2 * * *' today = datetime.datetime.now(tz=timezone(settings.TIME_ZONE)) expected = croniter(schedule, today).get_next(datetime.datetime) with mock.patch('nodeconductor.core.models.django_timezone' ) as mock_django_timezone: mock_django_timezone.now.return_value = today self.assertEqual( expected, factories.BackupScheduleFactory( schedule=schedule).next_trigger_at)
def test_schedule_activation_and_deactivation(self): schedule = factories.BackupScheduleFactory(is_active=False) # activate response = self.client.post( backup_schedule_url(schedule, action='activate')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue( models.BackupSchedule.objects.get(pk=schedule.pk).is_active) # deactivate response = self.client.post( backup_schedule_url(schedule, action='deactivate')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertFalse( models.BackupSchedule.objects.get(pk=schedule.pk).is_active)
def test_save(self): # new schedule schedule = factories.BackupScheduleFactory(next_trigger_at=None) self.assertGreater(schedule.next_trigger_at, timezone.now()) # schedule become active schedule.is_active = False schedule.next_trigger_at = None schedule.save() schedule.is_active = True schedule.save() self.assertGreater(schedule.next_trigger_at, timezone.now()) # schedule was changed schedule.next_trigger_at = None schedule.schedule = '*/10 * * * *' schedule.save() schedule = models.BackupSchedule.objects.get(id=schedule.id) self.assertGreater(schedule.next_trigger_at, timezone.now())
def get_users_and_expected_results(self): instance = factories.InstanceFactory() schedule = factories.BackupScheduleFactory(instance=instance) user_with_view_permission = structure_factories.UserFactory.create( is_staff=True, is_superuser=True) user_without_view_permission = structure_factories.UserFactory.create() return [ { 'user': user_with_view_permission, 'expected_results': [{ 'url': backup_schedule_url(schedule) }] }, { 'user': user_without_view_permission, 'expected_results': [] }, ]
def test_execute(self): # we have schedule schedule = factories.BackupScheduleFactory(maximal_number_of_backups=1, instance=self.instance) # with 2 ready backups old_backup1 = factories.BackupFactory(backup_schedule=schedule) old_backup2 = factories.BackupFactory(backup_schedule=schedule) # and 1 deleted deleted_backup = factories.BackupFactory( backup_schedule=schedule, state=models.Backup.States.DELETED) with patch('celery.app.base.Celery.send_task') as mocked_task: backend = schedule.get_backend() backend.execute() new_backup = models.Backup.objects.filter( backup_schedule=schedule, state=models.Backup.States.READY).order_by( 'created_at').last() # after execution old backups have to be deleted # new backup have to be created mocked_task.assert_has_calls([ call('nodeconductor.openstack.backup_start_create', (new_backup.uuid.hex, ), {}, countdown=2), call('nodeconductor.openstack.backup_start_delete', (old_backup1.uuid.hex, ), {}, countdown=2), call('nodeconductor.openstack.backup_start_delete', (old_backup2.uuid.hex, ), {}, countdown=2), ], any_order=True) # deleted backup have to stay deleted self.assertEqual(deleted_backup.state, models.Backup.States.DELETED) # and schedule time have to be changed self.assertGreater(schedule.next_trigger_at, timezone.now())
def test_update_next_trigger_at_with_default_timezone(self): schedule = factories.BackupScheduleFactory() schedule.update_next_trigger_at() # If timezone is not provided, default timezone must be set. self.assertEqual(settings.TIME_ZONE, schedule.timezone)
def test_backup_schedule_do_not_start_deactivation_of_not_active_schedule( self): schedule = factories.BackupScheduleFactory(is_active=False) response = self.client.post( backup_schedule_url(schedule, action='deactivate')) self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)