Skip to content

Commit

Permalink
refactored api. tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrei Pradan committed Mar 18, 2016
1 parent 52347aa commit 309b8b0
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ def check(request):

try:
distro = get_distribution(package_name)
value = '{project}=={version}'.format(
project=distro.project_name, version=distro.version)
except DistributionNotFound:
value = 'no distribution found for {}'.format(package_name)
return dict(error='no distribution found for {}'.format(package_name))

return value
return dict(name=distro.project_name, version=distro.version)
30 changes: 13 additions & 17 deletions src/heartbeat/checkers/databases.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from collections import OrderedDict
from django.db import connections, OperationalError


Expand All @@ -9,27 +10,22 @@ def check(request):


def get_connection_info(connection):
connection_info = OrderedDict()

engine = connection.settings_dict.get('ENGINE')
name = connection.settings_dict.get('NAME')
host = connection.settings_dict.get('HOST')
port = connection.settings_dict.get('PORT')
version = get_database_version(connection, engine) or ''

connection_info = {
connection.alias: {
'version': version,
'name': name,
'engine': engine,
'host': host,
'port': port,
}
}

connection_info['alias'] = connection.alias
connection_info['name'] = connection.settings_dict.get('NAME')
connection_info['engine'] = engine
connection_info['version'] = get_database_version(connection, engine)
connection_info['host'] = connection.settings_dict.get('HOST')
connection_info['port'] = connection.settings_dict.get('PORT')
return connection_info


def get_database_version(connection, engine):
if connection.settings_dict['ENGINE'] == 'django.db.backends.dummy':
return None
return
engines = {
'django.db.backends.postgresql_psycopg2': 'SELECT version();',
'django.db.backends.mysql': 'SELECT version();',
Expand All @@ -53,5 +49,5 @@ def execute_sql(connection, stmt):
return {'error': str(e)}

cursor.execute(stmt)
result = cursor.fetchone()
return result[0]
result = cursor.fetchone()[0]
return result
14 changes: 6 additions & 8 deletions src/heartbeat/checkers/memcached.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,19 @@


def check(request):
all_stats = {}
for cache_profile in settings.CACHES:
all_stats = []
for alias in settings.CACHES:
server_stats = []
if is_memcached_profile(cache_profile):
cache_backend = get_cache(cache_profile)
if is_memcached_profile(alias):
cache_backend = get_cache(alias)
for server, stats in cache_backend._cache.get_stats():
stats = debyteify(stats)
result = OrderedDict()
result['location'] = debyteify(server)
result['name'] = debyteify(server)
result['summary'] = get_summary(stats)
result['details'] = stats
server_stats.append(result)
all_stats[cache_profile] = server_stats
if not all_stats:
return {'error': 'No memcached profiles found'}
all_stats.append(dict(alias=alias, locations=server_stats))
return all_stats


Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions src/heartbeat/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ def default_checkers():
heartbeat['checkers'] = [
'heartbeat.checkers.distribution_list',
'heartbeat.checkers.debug_mode',
'heartbeat.checkers.python_version',
'heartbeat.checkers.python',
]
prepare_redis(heartbeat)
return heartbeat


def prepare_redis(heartbeat):
if 'heartbeat.checkers.redis_status' in heartbeat['checkers']:
if 'heartbeat.checkers.redis' in heartbeat['checkers']:
redis = getattr(settings, 'CACHEOPS_REDIS', None)
if redis is None:
raise ImproperlyConfigured(
Expand Down
2 changes: 1 addition & 1 deletion src/heartbeat/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ def details(request):
data = checker_module.check(request)
response.update({checker_name: data})

data = {'checkers': OrderedDict(sorted(response.items()))}
data = OrderedDict(sorted(response.items()))

return HttpResponse(json.dumps(data), content_type="application/json")
76 changes: 39 additions & 37 deletions tests/test_checkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ConnectionError(Exception):
if not settings.configured:
settings.configure()
from heartbeat.checkers import (
build_version, debug_mode, distribution_list, redis_status, databases,
build, debug_mode, distribution_list, redis, databases,
memcached)

from heartbeat import settings as heartbeat_settings
Expand All @@ -36,24 +36,24 @@ class TestCheckers(object):
def test_build_version_missing_package_name(self, pkg):
setattr(settings, 'HEARTBEAT', pkg)
with pytest.raises(ImproperlyConfigured) as e:
build_version.check(request=None)
build.check(request=None)
msg = 'Missing package_name key from heartbeat configuration'
assert msg in str(e)

@mock.patch('heartbeat.checkers.build_version.get_distribution')
@mock.patch('heartbeat.checkers.build.get_distribution')
def test_build_version_invalid_package_name(self, dist):
setattr(settings, 'HEARTBEAT', {'package_name': 'django'})
dist.side_effect = DistributionNotFound
distro = build_version.check(request=None)
assert distro == 'no distribution found for django'
distro = build.check(request=None)
assert distro == {'error': 'no distribution found for django'}

@mock.patch('heartbeat.checkers.build_version.get_distribution')
@mock.patch('heartbeat.checkers.build.get_distribution')
def test_build_version_with_valid_package_name(self, dist):
setattr(settings, 'HEARTBEAT', {'package_name': 'foo'})
dist.return_value.project_name = 'foo'
dist.return_value.version = '1.0.0'
distro = build_version.check(request=None)
assert distro == 'foo==1.0.0'
distro = build.check(request=None)
assert distro == {'name': 'foo', 'version': '1.0.0'}

@pytest.mark.parametrize('mode', [True, False])
def test_debug_mode(self, mode):
Expand All @@ -70,41 +70,37 @@ def test_get_distribution_list(self, dist_list):
assert {'version': '1.0.0', 'name': 1} in distro
assert {'version': '1.0.0', 'name': 2} in distro

@mock.patch('heartbeat.checkers.redis_status.redis.StrictRedis')
@mock.patch('heartbeat.checkers.redis.redis')
def test_redis_status(self, mock_redis):
setattr(settings, 'CACHEOPS_REDIS', {'host': 'foo', 'port': 1337})
mock_redis.return_value.ping.return_value = 'PONG'
mock_redis.return_value.info.return_value = {'redis_version': '1.0.0'}
status = redis_status.check(request=None)
mock_redis.StrictRedis.return_value.ping.return_value = 'PONG'
mock_redis.StrictRedis.return_value.info.return_value = {
'redis_version': '1.0.0'}
status = redis.check(request=None)
assert status['ping'] == 'PONG'
assert status['version'] == '1.0.0'

@mock.patch('heartbeat.checkers.redis_status.redis')
def test_redis_connection_error(self, mock_redis):
setattr(settings, 'CACHEOPS_REDIS', {'host': 'foo', 'port': 1337})
mock_ping = mock_redis.StrictRedis.return_value.ping
mock_ping.side_effect = ConnectionError('foo')
status = redis_status.check(request=None)
assert status['error'] == 'foo', status
# @mock.patch('heartbeat.checkers.redis.redis')
# def test_redis_connection_error(self, mock_redis):
# setattr(settings, 'CACHEOPS_REDIS', {'host': 'foo', 'port': 1337})
# mock_ping = mock_redis.StrictRedis.return_value.ping
# mock_ping.side_effect = ConnectionError('foo')
# status = redis.check(request=None)
# assert status['error'] == 'foo', status

@mock.patch('heartbeat.checkers.redis_status.redis')
@mock.patch('heartbeat.checkers.redis.redis')
def test_redis_import_error(self, mock_redis):
mock_redis.StrictRedis.side_effect = NameError
status = redis_status.check(request=None)
status = redis.check(request=None)
assert status['error'] == 'cannot import redis library'

def test_prepare_redis(self):
delattr(settings, 'CACHEOPS_REDIS')
HEARTBEAT = {'checkers': ['heartbeat.checkers.redis_status']}
HEARTBEAT = {'checkers': ['heartbeat.checkers.redis']}
with pytest.raises(ImproperlyConfigured) as e:
heartbeat_settings.prepare_redis(HEARTBEAT)
assert 'Missing CACHEOPS_REDIS in project settings' in str(e)

# def test_dummy_databases(self):
# dbs = databases.check(request=None)
# engine = dbs['databases'][0]['default']['engine']
# assert engine == 'django.db.backends.dummy'

def test_db_version(self):
import django
if django.VERSION >= (1, 7):
Expand All @@ -121,7 +117,8 @@ def test_db_version(self):
}
setattr(settings, 'DATABASES', dbs)
dbs = databases.check(request=None)
assert dbs[0]['default']['version'] == '1.0.0'
assert len(dbs) == 1
assert dbs[0]['version'] == '1.0.0'

@mock.patch('heartbeat.checkers.memcached.get_cache')
@pytest.mark.parametrize('backend', ['MemcachedCache', 'PyLibMCCache'])
Expand All @@ -138,23 +135,26 @@ def test_memcached(self, mock_get_cache, backend):
(server, stats)]
setattr(settings, 'CACHES', caches)
all_stats = memcached.check(request=None)
assert all_stats['foo'][0]['location'] == server
assert all_stats['foo'][0]['summary']['load'] == 10
assert all_stats['foo'][0]['details']['foo'] == 'bar'
assert len(all_stats['foo'][0]['details'].items()) == 5
assert len(all_stats) == 1
assert len(all_stats[0]['locations']) == 1
location = all_stats[0]['locations'][0]
assert location['name'] == server
assert location['summary']['load'] == 10
assert location['details']['foo'] == 'bar'
assert len(location['details'].items()) == 5

def test_memcached_with_no_profiles(self):
setattr(settings, 'CACHES', dict())
all_stats = memcached.check(request=None)
assert all_stats['error'] == 'No memcached profiles found'
assert len(all_stats) == 0

def test_memcached_with_no_memcached_profiles(self):
caches = {
'foo': {'BACKEND': 'django.core.cache.backends.db.DatabaseCache'}
}
setattr(settings, 'CACHES', caches)
all_stats = memcached.check(request=None)
assert all_stats['error'] == 'No memcached profiles found'
assert len(all_stats) == 0

@mock.patch('heartbeat.checkers.memcached.get_cache')
def test_memcached_with_different_cache_backends(self, mock_get_cache):
Expand All @@ -170,6 +170,8 @@ def test_memcached_with_different_cache_backends(self, mock_get_cache):
[(server, stats)])
setattr(settings, 'CACHES', caches)
all_stats = memcached.check(request=None)
assert len(all_stats.items()) == 1
assert all_stats['bar'][0]['location'] == server
assert all_stats['bar'][0]['details']['foo'] == 'bar'
assert len(all_stats) == 1
assert len(all_stats[0]['locations']) == 1
location = all_stats[0]['locations'][0]
assert location['name'] == server
assert location['details']['foo'] == 'bar'
4 changes: 2 additions & 2 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def test_200OK(self):
assert response.status_code == 200
assert response['content-type'] == 'application/json'
json_response = json.loads(response.content.decode('utf-8'))
assert json_response['checkers']['test_views']['ping'] == 'pong'
assert json_response['test_views']['ping'] == 'pong'

def test_with_invalid_basic_auth_credentials(self):
self.factory.defaults.pop('HTTP_AUTHORIZATION')
Expand Down Expand Up @@ -84,7 +84,7 @@ def test_disabled_auth(self):
assert response.status_code == 200
assert response['content-type'] == 'application/json'
json_response = json.loads(response.content.decode('utf-8'))
assert json_response['checkers']['test_views']['ping'] == 'pong'
assert json_response['test_views']['ping'] == 'pong'

def test(self):
self.heartbeat['auth'].update({'username': 'blow', 'password': 'fish'})
Expand Down

0 comments on commit 309b8b0

Please sign in to comment.