Exemple #1
0
 def test_task_server(self):
     # Create some stats
     t_now = datetime.utcnow()
     dm.save_object(SystemStats(
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, t_now - timedelta(minutes=5), t_now
     ))
     # We should now have stats
     sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60), t_now)
     self.assertGreater(len(sys_stats), 0)
     # Check current task list entries
     tasks = dm.list_objects(Task, order_field=Task.id)
     task_list_len = len(tasks)
     # Post a background task to purge the stats
     KEEP_SECS = 10
     task_obj = tm.add_task(
         None,
         'Purge system statistics',
         'purge_system_stats',
         {'before_time': t_now},
         Task.PRIORITY_NORMAL,
         'info', 'error',
         KEEP_SECS
     )
     self.assertIsNotNone(task_obj)
     # Check it really got added
     tasks = dm.list_objects(Task, order_field=Task.id)
     self.assertEqual(len(tasks), task_list_len + 1)
     task_list_len = len(tasks)
     # Post it again, make sure there is no dupe added
     dupe_task_obj = tm.add_task(
         None,
         'Purge system statistics',
         'purge_system_stats',
         {'before_time': t_now},
         Task.PRIORITY_NORMAL,
         'info', 'error',
         KEEP_SECS
     )
     self.assertIsNone(dupe_task_obj)
     # Check it really didn't get re-added
     tasks = dm.list_objects(Task, order_field=Task.id)
     self.assertEqual(len(tasks), task_list_len)
     task = tasks[-1]
     self.assertEqual(task.id, task_obj.id)
     # Wait for task completion
     tm.wait_for_task(task_obj.id, 20)
     # We should now have no stats
     t_now = datetime.utcnow()
     sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60), t_now)
     self.assertEqual(len(sys_stats), 0)
     # The completed task should only be removed after the delay we specified
     task = dm.get_object(Task, task_obj.id)
     self.assertIsNotNone(task)
     self.assertEqual(task.status, Task.STATUS_COMPLETE)
     # Wait for keep time + task server's poll time
     time.sleep(KEEP_SECS + 10)
     # Should now be gone
     task = dm.get_object(Task, task_obj.id)
     self.assertIsNone(task)
Exemple #2
0
 def test_task_server(self):
     # Create some stats
     t_now = datetime.utcnow()
     dm.save_object(
         SystemStats(1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                     t_now - timedelta(minutes=5), t_now))
     # We should now have stats
     sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60),
                                        t_now)
     self.assertGreater(len(sys_stats), 0)
     # Check current task list entries
     tasks = dm.list_objects(Task, order_field=Task.id)
     task_list_len = len(tasks)
     # Post a background task to purge the stats
     KEEP_SECS = 10
     task_obj = tm.add_task(None, 'Purge system statistics',
                            'purge_system_stats', {'before_time': t_now},
                            Task.PRIORITY_NORMAL, 'info', 'error',
                            KEEP_SECS)
     self.assertIsNotNone(task_obj)
     # Check it really got added
     tasks = dm.list_objects(Task, order_field=Task.id)
     self.assertEqual(len(tasks), task_list_len + 1)
     task_list_len = len(tasks)
     # Post it again, make sure there is no dupe added
     dupe_task_obj = tm.add_task(None, 'Purge system statistics',
                                 'purge_system_stats',
                                 {'before_time': t_now},
                                 Task.PRIORITY_NORMAL, 'info', 'error',
                                 KEEP_SECS)
     self.assertIsNone(dupe_task_obj)
     # Check it really didn't get re-added
     tasks = dm.list_objects(Task, order_field=Task.id)
     self.assertEqual(len(tasks), task_list_len)
     task = tasks[-1]
     self.assertEqual(task.id, task_obj.id)
     # Wait for task completion
     tm.wait_for_task(task_obj.id, 10)
     # We should now have no stats
     t_now = datetime.utcnow()
     sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60),
                                        t_now)
     self.assertEqual(len(sys_stats), 0)
     # The completed task should only be removed after the delay we specified
     task = dm.get_object(Task, task_obj.id)
     self.assertIsNotNone(task)
     self.assertEqual(task.status, Task.STATUS_COMPLETE)
     # Wait for keep time + task server's poll time
     time.sleep(KEEP_SECS + 10)
     # Should now be gone
     task = dm.get_object(Task, task_obj.id)
     self.assertIsNone(task)
Exemple #3
0
 def post(self, function_name):
     """ Launches a system task """
     # Validate function name
     if getattr(tasks, function_name, None) is None:
         raise DoesNotExistError(function_name)
     # Requires super user
     permissions_engine.ensure_permitted(SystemPermissions.PERMIT_SUPER_USER, get_session_user())
     # API parameters depend on the function
     params = self._get_validated_parameters(function_name, request.form)
     # Set remaining parameters for the task
     (description, task_params, priority, log_level, error_log_level, keep_secs) = self._get_task_data(
         function_name, params
     )
     # Queue the task
     db_task = task_engine.add_task(
         get_session_user(), description, function_name, task_params, priority, log_level, error_log_level, keep_secs
     )
     if db_task is None:
         raise AlreadyExistsError("Task is already running")
     # Decode the params before returning
     db_task.params = cPickle.loads(db_task.params)
     tdict = object_to_dict(db_task)
     if tdict.get("user") is not None:
         # Do not give out anything password related
         del tdict["user"]["password"]
     return make_api_success_response(tdict)
Exemple #4
0
 def test_task_result_none(self):
     # Test no return value
     task_obj = tm.add_task(None, 'Test return values', 'test_result_task',
                            {
                                'raise_exception': False,
                                'return_value': None
                            }, Task.PRIORITY_NORMAL, 'info', 'error', 5)
     self.assertIsNotNone(task_obj)
     tm.wait_for_task(task_obj.id, 10)
     task_obj = tm.get_task(task_obj.id, decode_attrs=True)
     self.assertIsNone(task_obj.result)
     dm.delete_object(task_obj)
Exemple #5
0
 def test_task_result_object(self):
     # Test normal return value
     task_obj = tm.add_task(
         None, 'Test return values', 'test_result_task',
         {'raise_exception': False, 'return_value': {'my_bool': True}},
         Task.PRIORITY_NORMAL, 'info', 'error', 5
     )
     self.assertIsNotNone(task_obj)
     tm.wait_for_task(task_obj.id, 20)
     task_obj = tm.get_task(task_obj.id, decode_attrs=True)
     self.assertEqual(task_obj.result, {'my_bool': True})
     dm.delete_object(task_obj)
Exemple #6
0
 def test_task_cancel(self):
     task_obj = tm.add_task(None, 'Test task cancelling',
                            'test_result_task', {
                                'raise_exception': False,
                                'return_value': None
                            }, Task.PRIORITY_LOW, 'info', 'error', 0)
     self.assertIsNotNone(task_obj)
     self.assertGreater(task_obj.id, 0)
     # Yes, this could be a fragile test if the task server gets to it first
     # It has worked the first 5 times in a row I've tried it, so fingers crossed
     self.assertTrue(tm.cancel_task(task_obj))
     task_obj = tm.get_task(task_obj.id)
     self.assertIsNone(task_obj)
Exemple #7
0
 def test_task_result_exception(self):
     # Test exception raised
     task_obj = tm.add_task(
         None, 'Test return values', 'test_result_task',
         {'raise_exception': True, 'return_value': None},
         Task.PRIORITY_NORMAL, 'info', 'error', 5
     )
     self.assertIsNotNone(task_obj)
     tm.wait_for_task(task_obj.id, 20)
     task_obj = tm.get_task(task_obj.id, decode_attrs=True)
     self.assertIsInstance(task_obj.result, ValueError)
     self.assertEqual(repr(task_obj.result), repr(ValueError('An error happened')))
     dm.delete_object(task_obj)
Exemple #8
0
 def put(self, folder_id):
     """ Moves or renames a disk folder """
     params = self._get_validated_parameters(request.form)
     # Run this as a background task in case it takes a long time
     task = task_engine.add_task(get_session_user(),
                                 'Move disk folder %d' % folder_id,
                                 'move_folder', {
                                     'folder_id': folder_id,
                                     'path': params['path']
                                 }, Task.PRIORITY_HIGH, 'info', 'error', 10)
     if task is None:  # Task already submitted
         return make_api_success_response(task_accepted=True)
     else:
         return self._task_response(task, 30)
Exemple #9
0
 def test_task_result_exception(self):
     # Test exception raised
     task_obj = tm.add_task(None, 'Test return values', 'test_result_task',
                            {
                                'raise_exception': True,
                                'return_value': None
                            }, Task.PRIORITY_NORMAL, 'info', 'error', 5)
     self.assertIsNotNone(task_obj)
     tm.wait_for_task(task_obj.id, 10)
     task_obj = tm.get_task(task_obj.id, decode_attrs=True)
     self.assertIsInstance(task_obj.result, ValueError)
     self.assertEqual(repr(task_obj.result),
                      repr(ValueError('An error happened')))
     dm.delete_object(task_obj)
Exemple #10
0
 def post(self, folio_id):
     db_session = data_engine.db_get_session()
     try:
         # Get the portfolio
         folio = data_engine.get_portfolio(folio_id, _db_session=db_session)
         if folio is None:
             raise DoesNotExistError(str(folio_id))
         # Check permissions
         permissions_engine.ensure_portfolio_permitted(
             folio, FolioPermission.ACCESS_EDIT, get_session_user())
         # Block the export now if it would create an empty zip file
         if len(folio.images) == 0:
             raise ParameterError(
                 'this portfolio is empty and cannot be published')
         # Create a folio-export record and start the export as a background task
         params = self._get_validated_object_parameters(request.form)
         folio_export = FolioExport(folio, params['description'],
                                    params['originals'],
                                    params['image_parameters'],
                                    params['expiry_time'])
         data_engine.add_portfolio_history(folio,
                                           get_session_user(),
                                           FolioHistory.ACTION_PUBLISHED,
                                           folio_export.describe(True),
                                           _db_session=db_session,
                                           _commit=False)
         folio_export = data_engine.save_object(folio_export,
                                                refresh=True,
                                                _db_session=db_session,
                                                _commit=True)
         export_task = task_engine.add_task(
             get_session_user(), 'Export portfolio %d / export %d' %
             (folio.id, folio_export.id), 'export_portfolio', {
                 'export_id': folio_export.id,
                 'ignore_errors': False
             }, Task.PRIORITY_NORMAL, 'info', 'error', 60)
         # Update and return the folio-export record with the task ID
         folio_export.task_id = export_task.id
         data_engine.save_object(folio_export,
                                 _db_session=db_session,
                                 _commit=True)
         return make_api_success_response(object_to_dict(
             _prep_folioexport_object(folio, folio_export),
             _omit_fields + ['portfolio']),
                                          task_accepted=True)
     finally:
         db_session.close()
Exemple #11
0
 def delete(self, folder_id):
     """ Deletes a disk folder """
     # v4.1 #10 delete_folder() doesn't care whether it exists, but we want the
     #          API to return a "not found" if the folder doesn't exist on disk
     #          (and as long as the database is already in sync with that)
     db_folder = data_engine.get_folder(folder_id)
     if db_folder is None:
         raise DoesNotExistError(str(folder_id))
     if not path_exists(db_folder.path, require_directory=True
                        ) and db_folder.status == Folder.STATUS_DELETED:
         raise DoesNotExistError(db_folder.path)
     # Run this as a background task in case it takes a long time
     task = task_engine.add_task(get_session_user(),
                                 'Delete disk folder %d' % folder_id,
                                 'delete_folder', {'folder_id': folder_id},
                                 Task.PRIORITY_HIGH, 'info', 'error', 10)
     if task is None:  # Task already submitted
         return make_api_success_response(task_accepted=True)
     else:
         return self._task_response(task, 30)