Merge pull request #129 from GSA/queue-investigation

SMS provider cleanup
This commit is contained in:
Ryan Ahearn
2022-11-30 15:25:44 -05:00
committed by GitHub
7 changed files with 68 additions and 304 deletions

View File

@@ -49,7 +49,6 @@ lxml = "==4.9.1"
marshmallow = "==3.15.0"
marshmallow-sqlalchemy = "==0.28.1"
notifications-python-client = "==6.3.0"
notifications-utils = {editable = true, ref = "11b9d3dbde8d73910c05b0cb8e74d9f93b45a7b0", git = "https://github.com/GSA/notifications-utils"}
oscrypto = "==1.3.0"
psycopg2-binary = "==2.9.3"
pyjwt = "==2.4.0"
@@ -59,6 +58,7 @@ werkzeug = "~=2.1.1"
# gds metrics packages
prometheus-client = "==0.14.1"
gds-metrics = {version = "==0.2.4", ref = "6f1840a57b6fb1ee40b7e84f2f18ec229de8aa72", git = "https://github.com/alphagov/gds_metrics_python.git"}
notifications-utils = {editable = true, ref = "37ae9753c050851453d072994fb03b1415601716", git = "https://github.com/GSA/notifications-utils"}
[dev-packages]
flake8 = "==4.0.1"

124
Pipfile.lock generated
View File

@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "adeddc01285ee3e46e1a1464cceffc5fd1d151c61f069642e1c716b8e9fd0507"
"sha256": "d652255c8ca6f6cb96778b0159228628816a114f867510bd4ce13a9e9692b101"
},
"pipfile-spec": 6,
"requires": {
@@ -476,11 +476,11 @@
},
"importlib-metadata": {
"hashes": [
"sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab",
"sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43"
"sha256:d5059f9f1e8e41f80e9c56c2ee58811450c31984dfa625329ffd7c0dad88a73b",
"sha256:d84d17e21670ec07990e1044a99efe8d615d860fd176fc29ef5c306068fda313"
],
"markers": "python_version < '3.10'",
"version": "==5.0.0"
"version": "==5.1.0"
},
"iso8601": {
"hashes": [
@@ -710,7 +710,7 @@
"notifications-utils": {
"editable": true,
"git": "https://github.com/GSA/notifications-utils",
"ref": "11b9d3dbde8d73910c05b0cb8e74d9f93b45a7b0"
"ref": "37ae9753c050851453d072994fb03b1415601716"
},
"orderedset": {
"hashes": [
@@ -736,10 +736,10 @@
},
"phonenumbers": {
"hashes": [
"sha256:93745d7afd38e246660bb601b07deac54eeb76c8e5e43f5e83333b0383a0a1e4",
"sha256:dbaea9e4005a976bcf18fbe2bb87cb9cd0a3f119136f04188ac412d7741cebf0"
"sha256:07a95c2f178687fd1c3f722cf792b3d33e3a225ae71577e500c99b28544cd6d0",
"sha256:7cadfe900e833857500b7bafa3e5a7eddc3263eb66b66a767870b33e44665f92"
],
"version": "==8.13.0"
"version": "==8.13.1"
},
"prometheus-client": {
"hashes": [
@@ -1048,11 +1048,11 @@
},
"setuptools": {
"hashes": [
"sha256:6211d2f5eddad8757bd0484923ca7c0a6302ebc4ab32ea5e94357176e0ca0840",
"sha256:d1eebf881c6114e51df1664bc2c9133d022f78d12d5f4f665b9191f084e2862d"
"sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54",
"sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"
],
"markers": "python_version >= '3.7'",
"version": "==65.6.0"
"version": "==65.6.3"
},
"shapely": {
"hashes": [
@@ -1187,11 +1187,11 @@
},
"urllib3": {
"hashes": [
"sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e",
"sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"
"sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc",
"sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'",
"version": "==1.26.12"
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
"version": "==1.26.13"
},
"vine": {
"hashes": [
@@ -1302,11 +1302,11 @@
},
"zipp": {
"hashes": [
"sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1",
"sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8"
"sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa",
"sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766"
],
"markers": "python_version >= '3.7'",
"version": "==3.10.0"
"version": "==3.11.0"
}
},
"develop": {
@@ -1493,43 +1493,43 @@
},
"cryptography": {
"hashes": [
"sha256:068147f32fa662c81aebab95c74679b401b12b57494872886eb5c1139250ec5d",
"sha256:06fc3cc7b6f6cca87bd56ec80a580c88f1da5306f505876a71c8cfa7050257dd",
"sha256:25c1d1f19729fb09d42e06b4bf9895212292cb27bb50229f5aa64d039ab29146",
"sha256:402852a0aea73833d982cabb6d0c3bb582c15483d29fb7085ef2c42bfa7e38d7",
"sha256:4e269dcd9b102c5a3d72be3c45d8ce20377b8076a43cbed6f660a1afe365e436",
"sha256:5419a127426084933076132d317911e3c6eb77568a1ce23c3ac1e12d111e61e0",
"sha256:554bec92ee7d1e9d10ded2f7e92a5d70c1f74ba9524947c0ba0c850c7b011828",
"sha256:5e89468fbd2fcd733b5899333bc54d0d06c80e04cd23d8c6f3e0542358c6060b",
"sha256:65535bc550b70bd6271984d9863a37741352b4aad6fb1b3344a54e6950249b55",
"sha256:6ab9516b85bebe7aa83f309bacc5f44a61eeb90d0b4ec125d2d003ce41932d36",
"sha256:6addc3b6d593cd980989261dc1cce38263c76954d758c3c94de51f1e010c9a50",
"sha256:728f2694fa743a996d7784a6194da430f197d5c58e2f4e278612b359f455e4a2",
"sha256:785e4056b5a8b28f05a533fab69febf5004458e20dad7e2e13a3120d8ecec75a",
"sha256:78cf5eefac2b52c10398a42765bfa981ce2372cbc0457e6bf9658f41ec3c41d8",
"sha256:7f836217000342d448e1c9a342e9163149e45d5b5eca76a30e84503a5a96cab0",
"sha256:8d41a46251bf0634e21fac50ffd643216ccecfaf3701a063257fe0b2be1b6548",
"sha256:984fe150f350a3c91e84de405fe49e688aa6092b3525f407a18b9646f6612320",
"sha256:9b24bcff7853ed18a63cfb0c2b008936a9554af24af2fb146e16d8e1aed75748",
"sha256:b1b35d9d3a65542ed2e9d90115dfd16bbc027b3f07ee3304fc83580f26e43249",
"sha256:b1b52c9e5f8aa2b802d48bd693190341fae201ea51c7a167d69fc48b60e8a959",
"sha256:bbf203f1a814007ce24bd4d51362991d5cb90ba0c177a9c08825f2cc304d871f",
"sha256:be243c7e2bfcf6cc4cb350c0d5cdf15ca6383bbcb2a8ef51d3c9411a9d4386f0",
"sha256:bfbe6ee19615b07a98b1d2287d6a6073f734735b49ee45b11324d85efc4d5cbd",
"sha256:c46837ea467ed1efea562bbeb543994c2d1f6e800785bd5a2c98bc096f5cb220",
"sha256:dfb4f4dd568de1b6af9f4cda334adf7d72cf5bc052516e1b2608b683375dd95c",
"sha256:ed7b00096790213e09eb11c97cc6e2b757f15f3d2f85833cd2d3ec3fe37c1722"
"sha256:0e70da4bdff7601b0ef48e6348339e490ebfb0cbe638e083c9c41fb49f00c8bd",
"sha256:10652dd7282de17990b88679cb82f832752c4e8237f0c714be518044269415db",
"sha256:175c1a818b87c9ac80bb7377f5520b7f31b3ef2a0004e2420319beadedb67290",
"sha256:1d7e632804a248103b60b16fb145e8df0bc60eed790ece0d12efe8cd3f3e7744",
"sha256:1f13ddda26a04c06eb57119caf27a524ccae20533729f4b1e4a69b54e07035eb",
"sha256:2ec2a8714dd005949d4019195d72abed84198d877112abb5a27740e217e0ea8d",
"sha256:2fa36a7b2cc0998a3a4d5af26ccb6273f3df133d61da2ba13b3286261e7efb70",
"sha256:2fb481682873035600b5502f0015b664abc26466153fab5c6bc92c1ea69d478b",
"sha256:3178d46f363d4549b9a76264f41c6948752183b3f587666aff0555ac50fd7876",
"sha256:4367da5705922cf7070462e964f66e4ac24162e22ab0a2e9d31f1b270dd78083",
"sha256:4eb85075437f0b1fd8cd66c688469a0c4119e0ba855e3fef86691971b887caf6",
"sha256:50a1494ed0c3f5b4d07650a68cd6ca62efe8b596ce743a5c94403e6f11bf06c1",
"sha256:53049f3379ef05182864d13bb9686657659407148f901f3f1eee57a733fb4b00",
"sha256:6391e59ebe7c62d9902c24a4d8bcbc79a68e7c4ab65863536127c8a9cd94043b",
"sha256:67461b5ebca2e4c2ab991733f8ab637a7265bb582f07c7c88914b5afb88cb95b",
"sha256:78e47e28ddc4ace41dd38c42e6feecfdadf9c3be2af389abbfeef1ff06822285",
"sha256:80ca53981ceeb3241998443c4964a387771588c4e4a5d92735a493af868294f9",
"sha256:8a4b2bdb68a447fadebfd7d24855758fe2d6fecc7fed0b78d190b1af39a8e3b0",
"sha256:8e45653fb97eb2f20b8c96f9cd2b3a0654d742b47d638cf2897afbd97f80fa6d",
"sha256:998cd19189d8a747b226d24c0207fdaa1e6658a1d3f2494541cb9dfbf7dcb6d2",
"sha256:a10498349d4c8eab7357a8f9aa3463791292845b79597ad1b98a543686fb1ec8",
"sha256:b4cad0cea995af760f82820ab4ca54e5471fc782f70a007f31531957f43e9dee",
"sha256:bfe6472507986613dc6cc00b3d492b2f7564b02b3b3682d25ca7f40fa3fd321b",
"sha256:c9e0d79ee4c56d841bd4ac6e7697c8ff3c8d6da67379057f29e66acffcd1e9a7",
"sha256:ca57eb3ddaccd1112c18fc80abe41db443cc2e9dcb1917078e02dfa010a4f353",
"sha256:ce127dd0a6a0811c251a6cddd014d292728484e530d80e872ad9806cfb1c5b3c"
],
"markers": "python_version >= '3.6'",
"version": "==38.0.3"
"version": "==38.0.4"
},
"cyclonedx-python-lib": {
"hashes": [
"sha256:39e9d36347d4dc736474ab4f3a7cd7bc91050c9315df698f83a6d8bbcb290744",
"sha256:3c79f32bb7d6ed34eac3308dbc8f2a77fbd1fd3779991173a147d866eaa7423e"
"sha256:48ae942a892e8385f4e0193d2e295a338df9ab864652081406c26f58085d2b35",
"sha256:a03b8f79f23aa95d37180b5d7bca81ef393b569e2d29e02f4817cfe4488e1ba2"
],
"markers": "python_version >= '3.6' and python_version < '4.0'",
"version": "==3.1.0"
"version": "==3.1.1"
},
"execnet": {
"hashes": [
@@ -1565,11 +1565,11 @@
},
"gitdb": {
"hashes": [
"sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd",
"sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"
"sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a",
"sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"
],
"markers": "python_version >= '3.6'",
"version": "==4.0.9"
"markers": "python_version >= '3.7'",
"version": "==4.0.10"
},
"gitpython": {
"hashes": [
@@ -1811,11 +1811,11 @@
},
"pip-audit": {
"hashes": [
"sha256:00ebef2a52884627f255b879135e28001de4378b8005318b66cc3a802459ee0a",
"sha256:d6d830bdbe3fd3efaf54f4a203451f286e75aecb7e44f9f84f7bfbd38aba26ac"
"sha256:a99f825ee431a89b89981c4e9e6eaacff5af3233783f2f5d79fe03306dc378ce",
"sha256:f87b37b6db5317a3f5ecebc202b5d4401958b5e4bd05b39d7b230bdc6f63c34b"
],
"index": "pypi",
"version": "==2.4.6"
"version": "==2.4.7"
},
"pip-requirements-parser": {
"hashes": [
@@ -2026,11 +2026,11 @@
},
"setuptools": {
"hashes": [
"sha256:6211d2f5eddad8757bd0484923ca7c0a6302ebc4ab32ea5e94357176e0ca0840",
"sha256:d1eebf881c6114e51df1664bc2c9133d022f78d12d5f4f665b9191f084e2862d"
"sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54",
"sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"
],
"markers": "python_version >= '3.7'",
"version": "==65.6.0"
"version": "==65.6.3"
},
"six": {
"hashes": [
@@ -2088,11 +2088,11 @@
},
"urllib3": {
"hashes": [
"sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e",
"sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"
"sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc",
"sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'",
"version": "==1.26.12"
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
"version": "==1.26.13"
},
"webencodings": {
"hashes": [

View File

@@ -32,13 +32,11 @@ from app.dao.jobs_dao import (
from app.dao.notifications_dao import (
dao_old_letters_with_created_status,
dao_precompiled_letters_still_pending_virus_check,
is_delivery_slow_for_providers,
letters_missing_from_sending_bucket,
notifications_not_yet_sent,
)
from app.dao.provider_details_dao import (
dao_adjust_provider_priority_back_to_resting_points,
dao_reduce_sms_provider_priority,
)
from app.dao.services_dao import (
dao_find_services_sending_to_tv_numbers,
@@ -95,28 +93,6 @@ def delete_invitations():
raise
@notify_celery.task(name='switch-current-sms-provider-on-slow-delivery')
def switch_current_sms_provider_on_slow_delivery():
"""
Reduce provider's priority if at least 30% of notifications took more than four minutes to be delivered
in the last ten minutes. If both providers are slow, don't do anything. If we changed the providers in the
last ten minutes, then don't update them again either.
"""
slow_delivery_notifications = is_delivery_slow_for_providers(
threshold=0.3,
created_at=datetime.utcnow() - timedelta(minutes=10),
delivery_time=timedelta(minutes=4),
)
# only adjust if some values are true and some are false - ie, don't adjust if all providers are fast or
# all providers are slow
if len(set(slow_delivery_notifications.values())) != 1:
for provider_name, is_slow in slow_delivery_notifications.items():
if is_slow:
current_app.logger.warning('Slow delivery notifications detected for provider {}'.format(provider_name))
dao_reduce_sms_provider_priority(provider_name, time_threshold=timedelta(minutes=10))
@notify_celery.task(name='tend-providers-back-to-middle')
def tend_providers_back_to_middle():
dao_adjust_provider_priority_back_to_resting_points()

View File

@@ -122,8 +122,9 @@ class Config(object):
FIRETEXT_INTERNATIONAL_API_KEY = getenv("FIRETEXT_INTERNATIONAL_API_KEY", "placeholder")
# these should always add up to 100%
SMS_PROVIDER_RESTING_POINTS = {
'mmg': 50,
'firetext': 50
'sns': 100,
'mmg': 0,
'firetext': 0
}
FIRETEXT_INBOUND_SMS_AUTH = json.loads(getenv('FIRETEXT_INBOUND_SMS_AUTH', '[]'))
MMG_INBOUND_SMS_AUTH = json.loads(getenv('MMG_INBOUND_SMS_AUTH', '[]'))
@@ -215,11 +216,6 @@ class Config(object):
'schedule': timedelta(minutes=66),
'options': {'queue': QueueNames.PERIODIC}
},
'switch-current-sms-provider-on-slow-delivery': {
'task': 'switch-current-sms-provider-on-slow-delivery',
'schedule': crontab(), # Every minute
'options': {'queue': QueueNames.PERIODIC}
},
'check-job-status': {
'task': 'check-job-status',
'schedule': crontab(),

View File

@@ -1,6 +1,4 @@
from datetime import datetime, timedelta
from itertools import groupby
from operator import attrgetter
from botocore.exceptions import ClientError
from flask import current_app
@@ -16,14 +14,14 @@ from notifications_utils.timezones import (
convert_local_timezone_to_utc,
convert_utc_to_local_timezone,
)
from sqlalchemy import and_, asc, desc, func, or_, union
from sqlalchemy import asc, desc, func, or_, union
from sqlalchemy.orm import joinedload
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.sql import functions
from sqlalchemy.sql.expression import case
from werkzeug.datastructures import MultiDict
from app import create_uuid, db, statsd_client
from app import create_uuid, db
from app.dao.dao_utils import autocommit
from app.letters.utils import LetterPDFNotFound, find_letter_pdf_in_s3
from app.models import (
@@ -32,7 +30,6 @@ from app.models import (
KEY_TYPE_TEST,
LETTER_TYPE,
NOTIFICATION_CREATED,
NOTIFICATION_DELIVERED,
NOTIFICATION_PENDING,
NOTIFICATION_PENDING_VIRUS_CHECK,
NOTIFICATION_PERMANENT_FAILURE,
@@ -44,7 +41,6 @@ from app.models import (
FactNotificationStatus,
Notification,
NotificationHistory,
ProviderDetails,
)
from app.utils import (
escape_special_characters,
@@ -453,61 +449,6 @@ def dao_timeout_notifications(cutoff_time, limit=100000):
return notifications
def is_delivery_slow_for_providers(
created_at,
threshold,
delivery_time,
):
"""
Returns a dict of providers and whether they are currently slow or not. eg:
{
'mmg': True,
'firetext': False
}
"""
slow_notification_counts = db.session.query(
ProviderDetails.identifier,
case(
[(
Notification.status == NOTIFICATION_DELIVERED,
(Notification.updated_at - Notification.sent_at) >= delivery_time
)],
else_=(datetime.utcnow() - Notification.sent_at) >= delivery_time
).label("slow"),
func.count().label('count')
).select_from(
ProviderDetails
).outerjoin(
Notification, and_(
Notification.notification_type == SMS_TYPE,
Notification.sent_by == ProviderDetails.identifier,
Notification.created_at >= created_at,
Notification.sent_at.isnot(None),
Notification.status.in_([NOTIFICATION_DELIVERED, NOTIFICATION_PENDING, NOTIFICATION_SENDING]),
Notification.key_type != KEY_TYPE_TEST
)
).filter(
ProviderDetails.notification_type == 'sms',
ProviderDetails.active
).order_by(
ProviderDetails.identifier
).group_by(
ProviderDetails.identifier,
"slow"
)
slow_providers = {}
for provider, rows in groupby(slow_notification_counts, key=attrgetter('identifier')):
rows = list(rows)
total_notifications = sum(row.count for row in rows)
slow_notifications = sum(row.count for row in rows if row.slow)
slow_providers[provider] = (slow_notifications / total_notifications >= threshold)
statsd_client.gauge(f'slow-delivery.{provider}.ratio', slow_notifications / total_notifications)
return slow_providers
@autocommit
def dao_update_notifications_by_reference(references, update_dict):
updated_count = Notification.query.filter(

View File

@@ -20,11 +20,9 @@ from app.celery.scheduled_tasks import (
delete_verify_codes,
replay_created_notifications,
run_scheduled_jobs,
switch_current_sms_provider_on_slow_delivery,
)
from app.config import QueueNames, TaskNames, Test
from app.dao.jobs_dao import dao_get_job_by_id
from app.dao.provider_details_dao import get_provider_details_by_identifier
from app.models import (
JOB_STATUS_ERROR,
JOB_STATUS_FINISHED,
@@ -37,19 +35,6 @@ from tests.app import load_example_csv
from tests.app.db import create_job, create_notification, create_template
def _create_slow_delivery_notification(template, provider='mmg'):
now = datetime.utcnow()
five_minutes_from_now = now + timedelta(minutes=5)
create_notification(
template=template,
status='delivered',
sent_by=provider,
updated_at=five_minutes_from_now,
sent_at=now,
)
def test_should_call_delete_codes_on_delete_verify_codes_task(notify_db_session, mocker):
mocker.patch('app.celery.scheduled_tasks.delete_codes_older_created_more_than_a_day_ago')
delete_verify_codes()
@@ -98,47 +83,6 @@ def test_should_update_all_scheduled_jobs_and_put_on_queue(sample_template, mock
])
@freeze_time('2017-05-01 14:00:00')
def test_switch_current_sms_provider_on_slow_delivery_switches_when_one_provider_is_slow(
mocker,
restore_provider_details,
):
is_slow_dict = {'mmg': False, 'firetext': True}
mock_is_slow = mocker.patch('app.celery.scheduled_tasks.is_delivery_slow_for_providers', return_value=is_slow_dict)
mock_reduce = mocker.patch('app.celery.scheduled_tasks.dao_reduce_sms_provider_priority')
# updated_at times are older than the 10 minute window
get_provider_details_by_identifier('mmg').updated_at = datetime(2017, 5, 1, 13, 49)
get_provider_details_by_identifier('firetext').updated_at = None
switch_current_sms_provider_on_slow_delivery()
mock_is_slow.assert_called_once_with(
threshold=0.3,
created_at=datetime(2017, 5, 1, 13, 50),
delivery_time=timedelta(minutes=4)
)
mock_reduce.assert_called_once_with('firetext', time_threshold=timedelta(minutes=10))
@freeze_time('2017-05-01 14:00:00')
@pytest.mark.parametrize('is_slow_dict', [
{'mmg': False, 'firetext': False},
{'mmg': True, 'firetext': True},
])
def test_switch_current_sms_provider_on_slow_delivery_does_nothing_if_no_need(
mocker,
restore_provider_details,
is_slow_dict
):
mocker.patch('app.celery.scheduled_tasks.is_delivery_slow_for_providers', return_value=is_slow_dict)
mock_reduce = mocker.patch('app.celery.scheduled_tasks.dao_reduce_sms_provider_priority')
get_provider_details_by_identifier('mmg').updated_at = datetime(2017, 5, 1, 13, 51)
switch_current_sms_provider_on_slow_delivery()
assert mock_reduce.called is False
def test_check_job_status_task_calls_process_incomplete_jobs(mocker, sample_template):
mock_celery = mocker.patch('app.celery.tasks.process_incomplete_jobs.apply_async')
job = create_job(template=sample_template, notification_count=3,

View File

@@ -25,7 +25,6 @@ from app.dao.notifications_dao import (
get_notifications_for_job,
get_notifications_for_service,
get_service_ids_with_notifications_on_date,
is_delivery_slow_for_providers,
notifications_not_yet_sent,
update_notification_status_by_id,
update_notification_status_by_reference,
@@ -36,12 +35,9 @@ from app.models import (
KEY_TYPE_TEAM,
KEY_TYPE_TEST,
NOTIFICATION_DELIVERED,
NOTIFICATION_PENDING,
NOTIFICATION_SENDING,
NOTIFICATION_SENT,
NOTIFICATION_STATUS_TYPES,
NOTIFICATION_STATUS_TYPES_FAILED,
NOTIFICATION_TEMPORARY_FAILURE,
SMS_TYPE,
Job,
Notification,
@@ -928,95 +924,6 @@ def test_should_exclude_test_key_notifications_by_default(
assert len(all_notifications) == 1
@pytest.mark.parametrize(
"normal_sending,slow_sending,normal_delivered,slow_delivered,threshold,expected_result",
[
(0, 0, 0, 0, 0.1, False),
(1, 0, 0, 0, 0.1, False),
(1, 1, 0, 0, 0.1, True),
(0, 0, 1, 1, 0.1, True),
(1, 1, 1, 1, 0.5, True),
(1, 1, 1, 1, 0.6, False),
(45, 5, 45, 5, 0.1, True),
]
)
@freeze_time("2018-12-04 12:00:00.000000")
def test_is_delivery_slow_for_providers(
notify_db_session,
sample_template,
normal_sending,
slow_sending,
normal_delivered,
slow_delivered,
threshold,
expected_result
):
normal_notification = partial(
create_notification,
template=sample_template,
sent_by='sns',
sent_at=datetime.now(),
updated_at=datetime.now()
)
slow_notification = partial(
create_notification,
template=sample_template,
sent_by='sns',
sent_at=datetime.now() - timedelta(minutes=5),
updated_at=datetime.now()
)
for _ in range(normal_sending):
normal_notification(status='sending')
for _ in range(slow_sending):
slow_notification(status='sending')
for _ in range(normal_delivered):
normal_notification(status='delivered')
for _ in range(slow_delivered):
slow_notification(status='delivered')
result = is_delivery_slow_for_providers(datetime.utcnow(), threshold, timedelta(minutes=4))
assert result == {
'firetext': False,
'mmg': False,
'sns': expected_result
}
@pytest.mark.skip(reason="Needs updating for TTS: Failing for unknown reason")
@pytest.mark.parametrize("options,expected_result", [
({"status": NOTIFICATION_DELIVERED, "sent_by": "mmg"}, True),
({"status": NOTIFICATION_PENDING, "sent_by": "mmg"}, True),
({"status": NOTIFICATION_SENDING, "sent_by": "mmg"}, True),
({"status": NOTIFICATION_TEMPORARY_FAILURE, "sent_by": "mmg"}, False),
({"status": NOTIFICATION_DELIVERED, "sent_by": "mmg", "sent_at": None}, False),
({"status": NOTIFICATION_DELIVERED, "sent_by": "mmg", "key_type": KEY_TYPE_TEST}, False),
({"status": NOTIFICATION_SENDING, "sent_by": "firetext"}, False),
({"status": NOTIFICATION_DELIVERED, "sent_by": "firetext"}, False),
])
@freeze_time("2018-12-04 12:00:00.000000")
def test_delivery_is_delivery_slow_for_providers_filters_out_notifications_it_should_not_count(
notify_db_session,
sample_template,
options,
expected_result
):
create_slow_notification_with = {
"template": sample_template,
"sent_at": datetime.now() - timedelta(minutes=5),
"updated_at": datetime.now(),
}
create_slow_notification_with.update(options)
create_notification(
**create_slow_notification_with
)
result = is_delivery_slow_for_providers(datetime.utcnow(), 0.1, timedelta(minutes=4))
assert result['mmg'] == expected_result
def test_dao_get_notifications_by_recipient(sample_template):
recipient_to_search_for = {