diff --git a/socorro/external/postgresql/adi.py b/socorro/external/postgresql/adi.py index f42782b759..6d1d54b0a9 100644 --- a/socorro/external/postgresql/adi.py +++ b/socorro/external/postgresql/adi.py @@ -63,7 +63,7 @@ def get(self, **kwargs): sql = """ SELECT - SUM(adu_count) AS adi_count, + SUM(adu_count)::BIGINT AS adi_count, adu_date AS date, pv.build_type, pv.version_string AS version @@ -87,10 +87,5 @@ def get(self, **kwargs): assert isinstance(params, dict) results = self.query(sql, params) - rows = [] - for row in results.zipped(): - row['date'] = row['date'].strftime('%Y-%m-%d') - # BIGINTs become Decimal which becomes floating point in JSON - row['adi_count'] = long(row['adi_count']) - rows.append(row) + rows = results.zipped() return {'hits': rows, 'total': len(rows)} diff --git a/socorro/middleware/middleware_app.py b/socorro/middleware/middleware_app.py index cfe1deed6b..8dc78fc5af 100755 --- a/socorro/middleware/middleware_app.py +++ b/socorro/middleware/middleware_app.py @@ -69,7 +69,6 @@ ), (r'/supersearch/(.*)', 'supersearch.SuperSearch'), (r'/util/(versions_info)/(.*)', 'util.Util'), - (r'/adi/(.*)', 'adi.ADI'), ) # certain items in a URL path should NOT be split by `+` diff --git a/socorro/unittest/external/postgresql/test_adi.py b/socorro/unittest/external/postgresql/test_adi.py index 549f8d505a..a00f79a38e 100644 --- a/socorro/unittest/external/postgresql/test_adi.py +++ b/socorro/unittest/external/postgresql/test_adi.py @@ -169,12 +169,11 @@ def test_get(self): versions=['40.0'], platforms=['Linux', 'Windows'], ) - start_formatted = start.strftime('%Y-%m-%d') eq_(stats['total'], 1) hit, = stats['hits'] eq_(hit, { 'adi_count': 64L + 16L, - 'date': start_formatted, + 'date': start.date(), 'version': '40.0', 'build_type': 'release' }) @@ -190,7 +189,7 @@ def test_get(self): hit, = stats['hits'] eq_(hit, { 'adi_count': 4 + 1L, - 'date': start_formatted, + 'date': start.date(), 'version': '39.0b1', 'build_type': 'release' }) diff --git a/webapp-django/crashstats/crashstats/models.py b/webapp-django/crashstats/crashstats/models.py index 036777cd1e..6cc33987f1 100644 --- a/webapp-django/crashstats/crashstats/models.py +++ b/webapp-django/crashstats/crashstats/models.py @@ -25,6 +25,7 @@ import socorro.external.postgresql.graphics_devices import socorro.external.postgresql.gccrashes import socorro.external.postgresql.crontabber_state +import socorro.external.postgresql.adi from socorrolib.app import socorro_app @@ -1704,7 +1705,7 @@ class AduBySignature(SocorroMiddleware): class ADI(SocorroMiddleware): - URL_PREFIX = '/adi/' + implementation = socorro.external.postgresql.adi.ADI required_params = ( ('start_date', datetime.date), diff --git a/webapp-django/crashstats/crashstats/tests/test_models.py b/webapp-django/crashstats/crashstats/tests/test_models.py index 7cd621bfb6..2657dc9fe9 100644 --- a/webapp-django/crashstats/crashstats/tests/test_models.py +++ b/webapp-django/crashstats/crashstats/tests/test_models.py @@ -1367,47 +1367,44 @@ def mocked_get(**options): assert 'Unknown' not in settings.DISPLAY_OS_NAMES eq_(r[1], {'code': 'unk', 'name': 'Unknown', 'display': False}) - @mock.patch('requests.get') - def test_adi(self, rget): + def test_adi(self): model = models.ADI api = model() - def mocked_get(url, params, **options): - assert '/adi/' in url + def mocked_get(**options): - ok_('product' in params) - eq_(params['product'], 'WaterWolf') + ok_('product' in options) + eq_(options['product'], 'WaterWolf') - ok_('versions' in params) - eq_(params['versions'], ['2.0']) + ok_('versions' in options) + eq_(options['versions'], ['2.0']) - ok_('start_date' in params) - ok_('end_date' in params) + ok_('start_date' in options) + ok_('end_date' in options) - return Response( - { - "hits": [ - { + return { + "hits": [ + { - "build_type": "aurora", - "adi_count": 12327, - "version": "2.0", - "date": "2015-08-12" + "build_type": "aurora", + "adi_count": 12327L, + "version": "2.0", + "date": datetime.date(2015, 8, 12), - }, - { - "build_type": "release", - "adi_count": 4, - "version": "2.0", - "date": "2015-08-12" + }, + { + "build_type": "release", + "adi_count": 4L, + "version": "2.0", + "date": datetime.date(2016, 8, 12), - } - ], - "total": 2 - } - ) + } + ], + "total": 2 + } + + models.ADI.implementation().get.side_effect = mocked_get - rget.side_effect = mocked_get r = api.get( product='WaterWolf', versions=['2.0'], diff --git a/webapp-django/crashstats/crashstats/tests/test_views.py b/webapp-django/crashstats/crashstats/tests/test_views.py index 4f74824d57..7873f4ab0b 100644 --- a/webapp-django/crashstats/crashstats/tests/test_views.py +++ b/webapp-django/crashstats/crashstats/tests/test_views.py @@ -860,28 +860,30 @@ def mocked_get(url, params, **options): def test_frontpage_json(self, rget): url = reverse('crashstats:frontpage_json') - def mocked_get(url, params, **options): - if '/adi/' in url: - end_date = timezone.now().date() - # the default is two weeks - start_date = end_date - datetime.timedelta(weeks=2) - - response = { - 'total': 4, - 'hits': [] - } - while start_date < end_date: - for version in ['20.0', '19.0']: - for build_type in ['beta', 'release']: - response['hits'].append({ - 'adi_count': random.randint(100, 1000), - 'build_type': build_type, - 'date': start_date.strftime('%Y-%m-%d'), - 'version': version - }) - start_date += datetime.timedelta(days=1) - return Response(response) + def mocked_adi_get(**options): + end_date = timezone.now().date() + # the default is two weeks + start_date = end_date - datetime.timedelta(weeks=2) + response = { + 'total': 4, + 'hits': [] + } + while start_date < end_date: + for version in ['20.0', '19.0']: + for build_type in ['beta', 'release']: + response['hits'].append({ + 'adi_count': long(random.randint(100, 1000)), + 'build_type': build_type, + 'date': start_date, + 'version': version + }) + start_date += datetime.timedelta(days=1) + return response + + models.ADI.implementation().get.side_effect = mocked_adi_get + + def mocked_get(url, params, **options): if '/products/build_types/' in url: return Response({ 'hits': { @@ -960,13 +962,15 @@ def mocked_supersearch_get(**params): def test_frontpage_json_bad_request(self, rget): url = reverse('crashstats:frontpage_json') - def mocked_get(url, params, **options): - if '/adi/' in url: - return Response({ - 'total': 4, - 'hits': [] - }) + def mocked_adi_get(**options): + return { + 'total': 4, + 'hits': [] + } + + models.ADI.implementation().get.side_effect = mocked_adi_get + def mocked_get(url, params, **options): if '/products/build_types/' in url: return Response({ 'hits': { @@ -1051,13 +1055,15 @@ def mocked_supersearch_get(**params): def test_frontpage_json_no_data_for_version(self, rget): url = reverse('crashstats:frontpage_json') - def mocked_get(url, params, **options): - if '/adi/' in url: - return Response({ - 'total': 4, - 'hits': [] - }) + def mocked_adi_get(**options): + return { + 'total': 4, + 'hits': [] + } + + models.ADI.implementation().get.side_effect = mocked_adi_get + def mocked_get(url, params, **options): if '/products/build_types/' in url: return Response({ 'hits': { @@ -2158,31 +2164,32 @@ def mocked_get(url, params, **options): def test_crashes_per_day(self, rget): url = reverse('crashstats:crashes_per_day') + def mocked_adi_get(**options): + eq_(options['versions'], ['20.0', '19.0']) + end_date = timezone.now().date() + # the default is two weeks + start_date = end_date - datetime.timedelta(weeks=2) + eq_(options['start_date'], start_date.strftime('%Y-%m-%d')) + eq_(options['end_date'], end_date.strftime('%Y-%m-%d')) + eq_(options['product'], 'WaterWolf') + eq_(options['platforms'], ['Windows', 'Mac OS X', 'Linux']) + response = { + 'total': 4, + 'hits': [] + } + while start_date < end_date: + for version in ['20.0', '19.0']: + for build_type in ['beta', 'release']: + response['hits'].append({ + 'adi_count': long(random.randint(100, 1000)), + 'build_type': build_type, + 'date': start_date, + 'version': version + }) + start_date += datetime.timedelta(days=1) + return response + def mocked_get(url, params, **options): - if '/adi/' in url: - eq_(params['versions'], ['20.0', '19.0']) - end_date = timezone.now().date() - # the default is two weeks - start_date = end_date - datetime.timedelta(weeks=2) - eq_(params['start_date'], start_date.strftime('%Y-%m-%d')) - eq_(params['end_date'], end_date.strftime('%Y-%m-%d')) - eq_(params['product'], 'WaterWolf') - eq_(params['platforms'], ['Windows', 'Mac OS X', 'Linux']) - response = { - 'total': 4, - 'hits': [] - } - while start_date < end_date: - for version in ['20.0', '19.0']: - for build_type in ['beta', 'release']: - response['hits'].append({ - 'adi_count': random.randint(100, 1000), - 'build_type': build_type, - 'date': start_date.strftime('%Y-%m-%d'), - 'version': version - }) - start_date += datetime.timedelta(days=1) - return Response(response) if '/products/build_types/' in url: return Response({ 'hits': { @@ -2195,6 +2202,8 @@ def mocked_get(url, params, **options): rget.side_effect = mocked_get + models.ADI.implementation().get.side_effect = mocked_adi_get + def mocked_supersearch_get(**params): eq_(params['product'], ['WaterWolf']) eq_(params['version'], ['20.0', '19.0']) @@ -2355,27 +2364,30 @@ def test_crashes_per_day_with_beta_versions(self, rget): url = reverse('crashstats:crashes_per_day') + def mocked_adi_get(**options): + eq_(options['versions'], ['19.0', '18.0b1', '18.0b']) + end_date = timezone.now().date() + # the default is two weeks + start_date = end_date - datetime.timedelta(weeks=2) + response = { + 'total': 4, + 'hits': [] + } + while start_date < end_date: + for version in ['18.0b1', '18.0b2', '19.0']: + for build_type in ['beta', 'release']: + response['hits'].append({ + 'adi_count': long(random.randint(100, 1000)), + 'build_type': build_type, + 'date': start_date, + 'version': version + }) + start_date += datetime.timedelta(days=1) + return response + + models.ADI.implementation().get.side_effect = mocked_adi_get + def mocked_get(url, params, **options): - if '/adi/' in url: - eq_(params['versions'], ['19.0', '18.0b1', '18.0b']) - end_date = timezone.now().date() - # the default is two weeks - start_date = end_date - datetime.timedelta(weeks=2) - response = { - 'total': 4, - 'hits': [] - } - while start_date < end_date: - for version in ['18.0b1', '18.0b2', '19.0']: - for build_type in ['beta', 'release']: - response['hits'].append({ - 'adi_count': random.randint(100, 1000), - 'build_type': build_type, - 'date': start_date.strftime('%Y-%m-%d'), - 'version': version - }) - start_date += datetime.timedelta(days=1) - return Response(response) if '/products/build_types/' in url: return Response({ 'hits': { diff --git a/webapp-django/crashstats/crashstats/views.py b/webapp-django/crashstats/crashstats/views.py index e0a17207b1..008ed8ea88 100644 --- a/webapp-django/crashstats/crashstats/views.py +++ b/webapp-django/crashstats/crashstats/views.py @@ -262,7 +262,9 @@ def add_version_to_adi(version, count, date, throttle): for group in adi_counts['hits']: version = group['version'] - date = group['date'] + # Make this a string so it can be paired with the facets 'term' + # key which is also a date in ISO format. + date = group['date'].isoformat() build_type = group['build_type'] count = group['adi_count'] throttle = product_build_types[build_type]