def test_failed_job_consumers(self):
        from foundations_contrib.global_state import message_router
        from time import time

        project_name = self._faker.name()
        error_information = {"broken_data": self._random_name()}

        message = {
            "job_id": self._job_id,
            "error_information": error_information,
            "project_name": project_name,
        }
        message_router.push_message("fail_job", message)
        current_time = time()

        state = self._redis.get("jobs:{}:state".format(self._job_id))
        self.assertEqual(b"failed", state)

        error_information_key = "jobs:{}:error_information".format(
            self._job_id)
        state = self._get_and_deserialize(error_information_key)
        self.assertEqual(error_information, state)

        completed_time_key = "jobs:{}:completed_time".format(self._job_id)
        string_completed_time = self._redis.get(completed_time_key)
        completed_time = float(string_completed_time.decode())
        self.assertLess(current_time - completed_time, 5)
    def test_job_metric_consumers(self):
        from foundations_contrib.global_state import message_router
        from foundations_internal.fast_serializer import deserialize
        from foundations_contrib.utils import byte_string
        from time import time

        project_name = self._str_random_uuid()
        job_id = self._str_random_uuid()
        key = "best_metric_ever"
        value = 42

        message = {
            "project_name": project_name,
            "job_id": job_id,
            "key": key,
            "value": value,
        }

        message_router.push_message("job_metrics", message)
        current_time = time()

        job_metrics_key = "jobs:{}:metrics".format(job_id)
        job_metrics = self._redis.lrange(job_metrics_key, 0, -1)
        job_metrics = [deserialize(data) for data in job_metrics]
        first_job_metric = list(job_metrics)[0]

        self.assertLess(current_time - first_job_metric[0], 5)
        self.assertEqual(key, first_job_metric[1])
        self.assertEqual(value, first_job_metric[2])

        project_metrics_key = "project:{}:metrics".format(project_name)
        project_metric_name = self._redis.smembers(project_metrics_key)
        self.assertEqual(project_metric_name, set([byte_string(key)]))
    def test_completed_job_consumers(self):
        from foundations_contrib.global_state import message_router
        from foundations_contrib.utils import byte_string
        from time import time

        project_name = self._faker.name()

        message = {"job_id": self._job_id, "project_name": project_name}
        message_router.push_message("complete_job", message)
        current_time = time()

        state = self._redis.get("jobs:{}:state".format(self._job_id))
        self.assertEqual(b"completed", state)

        completed_time_key = "jobs:{}:completed_time".format(self._job_id)
        string_completed_time = self._redis.get(completed_time_key)
        completed_time = float(string_completed_time.decode())
        self.assertLess(current_time - completed_time, 5)

        # NOTE: [AM SR KD] Left in to re-enable slack notification later
        # notification = self._slack_message_for_job()
        # self.assertIsNotNone(notification)
        # self.assertIn('Completed', notification)

        completed_jobs_key = "projects:global:jobs:completed"
        running_and_completed_jobs = self._redis.smembers(completed_jobs_key)
        expected_jobs = set([byte_string(self._job_id)])
        self.assertEqual(expected_jobs, running_and_completed_jobs)