Example #1
0
    def test_request_post_fail(self):
        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        url = "http://localhost/asdfasdfwqerqwerzcxvzxcv"
        method = "POST"

        with self.assertRaises(SchedulerHTTPException):
            tasks.sendHTTPRequest(url=url, method=method)
Example #2
0
    def test_request_post_fail_flags(self):
        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        # Note: Calling this endpoint without the Content-Length error
        #       returns an error
        url = "http://example.com"
        method = "POST"

        with self.assertRaises(SchedulerHTTPException):
            tasks.sendHTTPRequest(url=url, method=method)
Example #3
0
    def test_get_active_tasks_with_limit(self):
        """ getActiveTasks must follow limit if it is set
        """

        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        data_past = {
            "scheduled_time": datetime.utcnow() - timedelta(days=1),
            "endpoint_url": "http://example.com",
            "endpoint_headers": None,
            "endpoint_body": "Test Body",
            "endpoint_method": "POST",
            "max_retry_count": 5
        }

        data_future = {
            "scheduled_time": datetime.utcnow() + timedelta(days=1),
            "endpoint_url": "http://example.com",
            "endpoint_headers": None,
            "endpoint_body": "Test Body",
            "endpoint_method": "POST",
            "max_retry_count": 5
        }

        # Clear DB for good measure
        tasks.deleteAllTasks()

        # Insert 8 tasks set in the past
        for x in xrange(8):
            tasks.createTask(
                scheduled_time=data_past["scheduled_time"],
                endpoint_url=data_past["endpoint_url"],
                endpoint_headers=data_past["endpoint_headers"],
                endpoint_body=data_past["endpoint_body"],
                endpoint_method=data_past["endpoint_method"],
                max_retry_count=data_past["max_retry_count"])

        # Insert 4 tasks set in the future
        for x in xrange(4):
            tasks.createTask(
                scheduled_time=data_future["scheduled_time"],
                endpoint_url=data_future["endpoint_url"],
                endpoint_headers=data_future["endpoint_headers"],
                endpoint_body=data_future["endpoint_body"],
                endpoint_method=data_future["endpoint_method"],
                max_retry_count=data_future["max_retry_count"])

        active_tasks = tasks.getActiveTasks(limit=5)
        self.assertEqual(len(active_tasks), 5)

        tasks.deleteAllTasks()
Example #4
0
    def test_get_active_tasks_empty(self):
        """ getActiveTasks must return an empty list if no task is currently
            active
        """

        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        tasks.deleteAllTasks()

        active_tasks = tasks.getActiveTasks()
        self.assertEqual(len(active_tasks), 0)
        self.assertIsInstance(active_tasks, list)
Example #5
0
    def test_request_post(self):
        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        url = "http://example.com"
        method = "POST"
        headers = {
            "Content-Length": 0
        }

        results = tasks.sendHTTPRequest(url=url,
                                        method=method,
                                        headers=headers)

        self.assertTrue(results)
Example #6
0
    def test_create_and_delete(self):
        print "\n[TestTasksCrud] - Create and Delete"

        data = {
            "scheduled_time": datetime.strptime("2020-01-01 00:00:00", "%Y-%m-%d %H:%M:%S"),
            "endpoint_url": "http://example.com/",
            "endpoint_headers": {
                "Content-Length": 0
            },
            "endpoint_body": "Test Body",
            "endpoint_method": "POST",
            "max_retry_count": 5
        }

        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        # Create test task
        task_uuid = tasks.createTask(
            scheduled_time=data["scheduled_time"],
            endpoint_url=data["endpoint_url"],
            endpoint_headers=data["endpoint_headers"],
            endpoint_body=data["endpoint_body"],
            endpoint_method=data["endpoint_method"],
            max_retry_count=data["max_retry_count"])

        self.assertIsInstance(task_uuid, str)

        # Check if the task created can be retrieved from the DB
        task_retrieved = tasks.getTaskByUUID(task_uuid)
        self.assertIsInstance(task_retrieved, Task)

        # Compare values
        self.assertEqual(task_retrieved.scheduled_time, data["scheduled_time"])
        self.assertEqual(task_retrieved.endpoint_url, data["endpoint_url"])
        self.assertEqual(task_retrieved.endpoint_headers, data["endpoint_headers"])
        self.assertEqual(task_retrieved.endpoint_body, data["endpoint_body"])
        self.assertEqual(task_retrieved.endpoint_method, data["endpoint_method"])
        self.assertEqual(task_retrieved.max_retry_count, data["max_retry_count"])

        # Check Default Values
        self.assertFalse(task_retrieved.is_sent)
        self.assertFalse(task_retrieved.is_failed)
        self.assertIsNone(task_retrieved.sent_date)
        self.assertEqual(task_retrieved.retry_count, 0)
        self.assertIsInstance(task_retrieved.created_date, datetime)
        self.assertIsNone(task_retrieved.last_retry_date)

        # Delete Task
        delete_return = tasks.deleteTaskByUUID(task_uuid)
        self.assertTrue(delete_return)

        # Confirm that deleted task is gone
        task_retrieved = tasks.getTaskByUUID(task_uuid)
        self.assertIsNone(task_retrieved)

        # Delete all tasks
        tasks.deleteAllTasks()
Example #7
0
class SchedHTTPService(Daemon):
    def setupDaemon(self, config, logger):
        self.config = config
        self.logger = logger

        self.db_engine = create_engine(
            self.config.DATABASE_URI,
            poolclass=self.config.SQLALCHEMY_POOLCLASS,
            pool_size=20,
            max_overflow=0,
            pool_recycle=3600,  # Recycle connections every 1 hr
            echo=self.config.SQLALCHEMY_ECHO)

        self.tasks = TaskLogic(db_engine=self.db_engine)
        return True

    def start(self):
        logging.info("Sched HTTP Service Started")
        Daemon.start(self)

    def stop(self):
        logging.info("Sched HTTP Service Terminated")
        Daemon.stop(self)

    def run(self):
        while True:
            active_tasks = self.tasks.getActiveTasks()
            self.logger.info("Active Tasks: %s: %s" % (len(active_tasks), str(active_tasks)))

            for task in active_tasks:
                self.logger.info("Task: %s", task.uuid)
                self.logger.info("Retries: %s", task.retry_count)
                try:
                    self.tasks.callTaskHTTPEndpoint(task)
                    self.logger.info("Sent! %s: %s" % (task.uuid, task.endpoint_url))
                except SchedulerHTTPException, e:
                    self.logger.exception("Error: %s", e.value)
                except:
                    self.logger.exception("Error in calling task!")
Example #8
0
    def setupDaemon(self, config, logger):
        self.config = config
        self.logger = logger

        self.db_engine = create_engine(
            self.config.DATABASE_URI,
            poolclass=self.config.SQLALCHEMY_POOLCLASS,
            pool_size=20,
            max_overflow=0,
            pool_recycle=3600,  # Recycle connections every 1 hr
            echo=self.config.SQLALCHEMY_ECHO)

        self.tasks = TaskLogic(db_engine=self.db_engine)
        return True
Example #9
0
    def test_update(self):
        print "\n[TestTasksCrud] - Update"

        data = {
            "scheduled_time": datetime.strptime("2020-01-01 00:00:00", "%Y-%m-%d %H:%M:%S"),
            "endpoint_url": "http://example.com",
            "endpoint_headers": None,
            "endpoint_body": "Test Body",
            "endpoint_method": "POST",
            "max_retry_count": 5
        }

        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        # Create original task
        original_uuid = tasks.createTask(
            scheduled_time=data["scheduled_time"],
            endpoint_url=data["endpoint_url"],
            endpoint_headers=data["endpoint_headers"],
            endpoint_body=data["endpoint_body"],
            endpoint_method=data["endpoint_method"],
            max_retry_count=data["max_retry_count"])

        # Compare original task values
        original_task = tasks.getTaskByUUID(task_uuid=original_uuid)
        self.assertEqual(original_task.scheduled_time, data["scheduled_time"])
        self.assertEqual(original_task.endpoint_url, data["endpoint_url"])
        self.assertEqual(original_task.endpoint_headers, data["endpoint_headers"])
        self.assertEqual(original_task.endpoint_body, data["endpoint_body"])
        self.assertEqual(original_task.endpoint_method, data["endpoint_method"])
        self.assertEqual(original_task.max_retry_count, data["max_retry_count"])

        # Update task scheduled_time
        new_scheduled_time = datetime.strptime("2020-01-03 00:00:00", "%Y-%m-%d %H:%M:%S")
        tasks.updateTask(original_uuid, {
            "scheduled_time": new_scheduled_time,
            })

        updated_task = tasks.getTaskByUUID(task_uuid=original_uuid)
        self.assertEqual(updated_task.scheduled_time, new_scheduled_time)

        # Delete all tasks
        tasks.deleteAllTasks()
Example #10
0
    def test_increment_retry_count_on_fail(self):
        """ On failed call to HTTP Endpoint,
            the service must increment retry_count on db
            the last_retry_date field should also be updated

            This test tests the setTaskSendAttemptAsFail function manually
        """
        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        data_past = {
            "scheduled_time": datetime.utcnow() - timedelta(hours=1),
            "endpoint_url": "http://example.com",
            "endpoint_headers": {
                "Content-Length": 0
            },
            "endpoint_body": "Test Body",
            "endpoint_method": "POST",
            "max_retry_count": 5
        }

        task_uuid = tasks.createTask(
            scheduled_time=data_past["scheduled_time"],
            endpoint_url=data_past["endpoint_url"],
            endpoint_headers=data_past["endpoint_headers"],
            endpoint_body=data_past["endpoint_body"],
            endpoint_method=data_past["endpoint_method"],
            max_retry_count=data_past["max_retry_count"])

        tasks.setTaskSendAttemptAsFail(task_uuid)

        task_after = tasks.getTaskByUUID(task_uuid)
        self.assertEqual(task_after.retry_count, 1)
        self.assertIsInstance(task_after.last_retry_date, datetime)

        old_retry_date = task_after.last_retry_date

        tasks.setTaskSendAttemptAsFail(task_uuid)

        task_after2 = tasks.getTaskByUUID(task_uuid)
        self.assertEqual(task_after2.retry_count, 2)
        self.assertIsInstance(task_after2.last_retry_date, datetime)
        self.assertNotEqual(task_after2.last_retry_date, old_retry_date)
Example #11
0
    def test_call_task_http_endpoint_fail(self):
        """ On failed call to HTTP Endpoint,
            the service must increment retry_count on db
            the last_retry_date field should also be updated

            This test tests the setTaskSendAttemptAsFail function via
            actual HTTP call fails
        """

        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        data_past = {
            "scheduled_time": datetime.utcnow() - timedelta(hours=1),
            "endpoint_url": "http://localhost/qwerpoiuasddfjasld",
            "endpoint_body": "Test Body",
            "endpoint_method": "POST",
            "max_retry_count": 5
        }

        task_uuid = tasks.createTask(
            scheduled_time=data_past["scheduled_time"],
            endpoint_url=data_past["endpoint_url"],
            endpoint_headers=None,
            endpoint_body=data_past["endpoint_body"],
            endpoint_method=data_past["endpoint_method"],
            max_retry_count=data_past["max_retry_count"])

        task = tasks.getTaskByUUID(task_uuid)
        print task.uuid
        print task.endpoint_url
        print str(task.endpoint_headers)

        with self.assertRaises(SchedulerHTTPException):
            tasks.callTaskHTTPEndpoint(task)

        task_after_call = tasks.getTaskByUUID(task_uuid)
        self.assertFalse(task_after_call.is_sent)
        self.assertIsNone(task_after_call.sent_date)
        self.assertEqual(task_after_call.retry_count, 1)
        self.assertIsInstance(task_after_call.last_retry_date, datetime)

        tasks.deleteAllTasks()
Example #12
0
    def test_count_and_delete_all(self):
        print "\n[TestTasksCrud] - Count and Delete All"
        data = {
            "scheduled_time": datetime.strptime("2020-01-01 00:00:00", "%Y-%m-%d %H:%M:%S"),
            "endpoint_url": "http://example.com",
            "endpoint_headers": None,
            "endpoint_body": "Test Body",
            "endpoint_method": "POST",
            "max_retry_count": 5
        }

        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        # Delete current tasks in the test database
        delete_results = tasks.deleteAllTasks()

        # Get current task count
        task_count = tasks.getTaskCount()
        self.assertIsInstance(task_count, int)
        self.assertEqual(task_count, 0)

        # Insert dummy data
        for x in xrange(5):
            tasks.createTask(
                scheduled_time=data["scheduled_time"],
                endpoint_url=data["endpoint_url"],
                endpoint_headers=data["endpoint_headers"],
                endpoint_body=data["endpoint_body"],
                endpoint_method=data["endpoint_method"],
                max_retry_count=data["max_retry_count"])

        # Get new task count
        task_count2 = tasks.getTaskCount()
        self.assertEqual(task_count2, (task_count + 5))

        # Delete all tasks
        delete_results = tasks.deleteAllTasks()
        self.assertTrue(delete_results)
        task_count3 = tasks.getTaskCount()
        self.assertEqual(task_count3, 0)
Example #13
0
    def test_call_task_http_endpoint(self):
        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        data_past = {
            "scheduled_time": datetime.utcnow() - timedelta(hours=1),
            "endpoint_url": "http://example.com",
            "endpoint_headers": {
                "Content-Length": 0
            },
            "endpoint_body": "Test Body",
            "endpoint_method": "POST",
            "max_retry_count": 5
        }

        task_uuid = tasks.createTask(
            scheduled_time=data_past["scheduled_time"],
            endpoint_url=data_past["endpoint_url"],
            endpoint_headers=data_past["endpoint_headers"],
            endpoint_body=data_past["endpoint_body"],
            endpoint_method=data_past["endpoint_method"],
            max_retry_count=data_past["max_retry_count"])

        task = tasks.getTaskByUUID(task_uuid)
        self.assertFalse(task.is_sent)
        self.assertFalse(task.is_failed)
        self.assertIsNone(task.sent_date)
        self.assertEqual(task.retry_count, 0)

        results = tasks.callTaskHTTPEndpoint(task)
        self.assertTrue(results)

        task_after_call = tasks.getTaskByUUID(task_uuid)
        self.assertTrue(task_after_call.is_sent)
        self.assertIsInstance(task_after_call.sent_date, datetime)

        tasks.deleteAllTasks()
Example #14
0
    def test_get_active_tasks_no_is_sent(self):
        """ Tasks with the is_sent flag should not be included in getActiveTasks
            results
        """
        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        data_past = {
            "scheduled_time": datetime.utcnow() - timedelta(hours=1),
            "endpoint_url": "http://example.com",
            "endpoint_headers": None,
            "endpoint_body": "Test Body",
            "endpoint_method": "POST",
            "max_retry_count": 5
        }

        task_uuid = tasks.createTask(
            scheduled_time=data_past["scheduled_time"],
            endpoint_url=data_past["endpoint_url"],
            endpoint_headers=data_past["endpoint_headers"],
            endpoint_body=data_past["endpoint_body"],
            endpoint_method=data_past["endpoint_method"],
            max_retry_count=data_past["max_retry_count"])

        task_uuid2 = tasks.createTask(
            scheduled_time=data_past["scheduled_time"],
            endpoint_url=data_past["endpoint_url"],
            endpoint_headers=data_past["endpoint_headers"],
            endpoint_body=data_past["endpoint_body"],
            endpoint_method=data_past["endpoint_method"],
            max_retry_count=data_past["max_retry_count"])

        active_tasks = tasks.getActiveTasks()
        self.assertEqual(len(active_tasks), 2)

        # Send first task
        task1 = tasks.getTaskByUUID(task_uuid)
        tasks.callTaskHTTPEndpoint(task1)

        active_tasks_after_call = tasks.getActiveTasks()
        self.assertEqual(len(active_tasks_after_call), 1)
        self.assertEqual(active_tasks_after_call[0].uuid, task_uuid2)

        # Send second task
        task2 = tasks.getTaskByUUID(task_uuid2)
        tasks.callTaskHTTPEndpoint(task2)

        active_tasks_after_call2 = tasks.getActiveTasks()
        self.assertEqual(len(active_tasks_after_call2), 0)

        tasks.deleteAllTasks()
Example #15
0
    def test_get_active_tasks_retry_limit(self):
        """ Only tasks that are below their retry limits should be
            returned by getActiveTasks
        """
        engine = create_engine('sqlite:///db/test.db', echo=False)
        tasks = TaskLogic(db_engine=engine)

        tasks.deleteAllTasks()

        data_past = {
            "scheduled_time": datetime.utcnow() - timedelta(hours=1),
            "endpoint_url": "http://asdfasdfasdfasd/asdfasdfwqerqwerzcxvzxcv",
            "endpoint_headers": None,
            "endpoint_body": "Test Body",
            "endpoint_method": "POST",
            "max_retry_count": 3
        }

        task_uuid = tasks.createTask(
            scheduled_time=data_past["scheduled_time"],
            endpoint_url=data_past["endpoint_url"],
            endpoint_headers=data_past["endpoint_headers"],
            endpoint_body=data_past["endpoint_body"],
            endpoint_method=data_past["endpoint_method"],
            max_retry_count=data_past["max_retry_count"])

        tasks.createTask(
            scheduled_time=data_past["scheduled_time"],
            endpoint_url=data_past["endpoint_url"],
            endpoint_headers=data_past["endpoint_headers"],
            endpoint_body=data_past["endpoint_body"],
            endpoint_method=data_past["endpoint_method"],
            max_retry_count=data_past["max_retry_count"])

        # First attempt
        task1 = tasks.getTaskByUUID(task_uuid)
        with self.assertRaises(SchedulerHTTPException):
            tasks.callTaskHTTPEndpoint(task1)
        active_tasks1 = tasks.getActiveTasks()
        self.assertEqual(len(active_tasks1), 2)

        # Second attempt
        task2 = tasks.getTaskByUUID(task_uuid)
        with self.assertRaises(SchedulerHTTPException):
            tasks.callTaskHTTPEndpoint(task2)
        active_tasks2 = tasks.getActiveTasks()
        self.assertEqual(len(active_tasks2), 2)

        # Third attempt MUST NOT return the failing task anymore
        task3 = tasks.getTaskByUUID(task_uuid)
        with self.assertRaises(SchedulerHTTPException):
            tasks.callTaskHTTPEndpoint(task3)
        active_tasks3 = tasks.getActiveTasks()
        self.assertEqual(len(active_tasks3), 1)

        # Verify that task's is_failed flag is True after max attempt
        failed_task = tasks.getTaskByUUID(task_uuid)
        self.assertTrue(failed_task.is_failed)