def test_service_check(aggregator, redis_auth, redis_instance): redis_check = Redis('redisdb', {}, {}) redis_check.check(redis_instance) assert len(aggregator.service_checks('redis.can_connect')) == 1 sc = aggregator.service_checks('redis.can_connect')[0] assert sc.tags == ['foo:bar', 'redis_host:{}'.format(HOST), 'redis_port:6379', 'redis_role:master']
def test_aof_loading_metrics(aggregator, redis_instance): """AOF loading metrics are only available when redis is loading an AOF file. It is not possible to collect them using integration/e2e testing so let's mock redis output to assert that they are collected correctly (assuming that the redis output is formatted correctly).""" with mock.patch("redis.Redis") as redis: redis_check = Redis('redisdb', {}, [redis_instance]) conn = redis.return_value conn.config_get.return_value = {} conn.info = (lambda *args: [] if args else { 'role': 'foo', 'total_commands_processed': 0, 'loading_total_bytes': 42, 'loading_loaded_bytes': 43, 'loading_loaded_perc': 44, 'loading_eta_seconds': 45, }) redis_check._check_db() aggregator.assert_metric('redis.info.latency_ms') aggregator.assert_metric('redis.net.commands', 0) aggregator.assert_metric('redis.key.length', 0) aggregator.assert_metric('redis.aof.loading_total_bytes', 42) aggregator.assert_metric('redis.aof.loading_loaded_bytes', 43) aggregator.assert_metric('redis.aof.loading_loaded_perc', 44) aggregator.assert_metric('redis.aof.loading_eta_seconds', 45) aggregator.assert_all_metrics_covered()
def test_redis_auth_ok(aggregator, redis_auth): """ Test the check can authenticate and connect """ redis = Redis('redisdb', {}, {}) instance = {'host': HOST, 'port': PORT, 'password': PASSWORD} redis.check(instance) assert aggregator.metric_names, "No metrics returned"
def test_service_metadata(redis_instance): """ The Agent toolkit doesn't support service_metadata yet, so we use Mock """ redis_check = Redis('redisdb', {}, {}) redis_check._collect_metadata = mock.MagicMock() redis_check.check(redis_instance) redis_check._collect_metadata.assert_called_once()
def test_disabled_config_get(aggregator, redis_auth, redis_instance): redis_check = Redis('redisdb', {}, {}) with mock.patch.object(redis.client.Redis, 'config_get') as get: get.side_effect = redis.ResponseError() redis_check.check(redis_instance) assert len(aggregator.service_checks('redis.can_connect')) == 1 sc = aggregator.service_checks('redis.can_connect')[0] assert sc.tags == ['foo:bar', 'redis_host:{}'.format(HOST), 'redis_port:6379', 'redis_role:master']
def test_redis_auth_empty_pass(redis_auth): """ Test the check providing an empty password """ redis = Redis('redisdb', {}, {}) instance = {'host': HOST, 'port': PORT, 'password': ''} with pytest.raises(Exception, match=re.compile('authentication required|operation not permitted', re.I)): redis.check(instance)
def test_redis_auth_wrong_pass(aggregator, redis_auth): """ Test the check providing the wrong password """ redis = Redis('redisdb', {}, {}) instance = {'host': HOST, 'port': PORT, 'password': '******'} try: redis.check(instance) assert 0, "Check should raise an exception" except Exception as e: assert "invalid password" in str(e).lower()
def test_metadata(master_instance, datadog_agent): redis_check = Redis('redisdb', {}, {}) redis_check.check_id = 'test:123' redis_check.check(master_instance) major, minor = REDIS_VERSION.split('.') version_metadata = {'version.scheme': 'semver', 'version.major': major, 'version.minor': minor} datadog_agent.assert_metadata('test:123', version_metadata) # We parse the version set in tox which is X.Y so we don't # know `version.patch`, and therefore also `version.raw`. datadog_agent.assert_metadata_count(len(version_metadata) + 2)
def test_redis_auth_wrong_pass(redis_auth): """ Test the check providing the wrong password """ instance = {'host': HOST, 'port': PORT, 'password': '******'} redis = Redis('redisdb', {}, [instance]) try: redis.check(instance) assert 0, "Check should raise an exception" except Exception as e: msg = str(e).lower() assert ("invalid password" in msg) or ("wrongpass" in msg)
def test_redis_repl(aggregator, dd_environment, master_instance): master_db = redis.Redis(port=MASTER_PORT, db=14, host=HOST) replica_db = redis.Redis(port=REPLICA_PORT, db=14, host=HOST) master_db.flushdb() # Ensure the replication works before running the tests master_db.set('replicated:test', 'true') assert replica_db.get('replicated:test') == b'true' redis_check = Redis('redisdb', {}, [master_instance]) redis_check.check(master_instance) for name in REPLICA_METRICS: aggregator.assert_metric(name)
def test_redis_auth_empty_pass(aggregator, redis_auth): """ Test the check providing an empty password """ redis = Redis('redisdb', {}, {}) instance = {'host': HOST, 'port': PORT, 'password': ''} try: redis.check(instance) assert 0, "Check should raise an exception" except Exception as e: pre28_err = "noauth authentication required" post28_err = "operation not permitted" assert pre28_err in str(e).lower() or post28_err in str(e).lower()
def test_redis_default(aggregator, redis_auth, redis_instance): """ """ db = redis.Redis(port=PORT, db=14, password=PASSWORD, host=HOST) db.flushdb() db.lpush("test_list", 1) db.lpush("test_list", 2) db.lpush("test_list", 3) db.set("key1", "value") db.set("key2", "value") db.setex("expirekey", "expirevalue", 1000) redis_check = Redis('redisdb', {}, {}) redis_check.check(redis_instance) # check the aggregator received some metrics assert aggregator.metric_names, "No metrics returned" # check those metrics have the right tags expected = [ 'foo:bar', 'redis_host:{}'.format(HOST), 'redis_port:6379', 'redis_role:master' ] expected_db = expected + ['redis_db:db14'] assert aggregator.metric_names for name in aggregator.metric_names: if name in DB_TAGGED_METRICS: aggregator.assert_metric(name, tags=expected_db) elif name != 'redis.key.length': aggregator.assert_metric(name, tags=expected) aggregator.assert_metric('redis.key.length', 3, count=1, tags=expected + ['key:test_list']) # in the old tests these was explicitly asserted, keeping it like that assert 'redis.net.commands' in aggregator.metric_names version = db.info().get('redis_version') if StrictVersion(version) >= StrictVersion('2.6.0'): # instantaneous_ops_per_sec info is only available on redis>=2.6 assert 'redis.net.instantaneous_ops_per_sec' in aggregator.metric_names db.flushdb()
def test__check_key_lengths_multi_db(aggregator, redis_instance): """ Keys are stored across different databases """ redis_check = Redis('redisdb', {}, {}) c = redis_check._get_conn(redis_instance) tmp = deepcopy(redis_instance) # also add a specific key to the instance redis_instance['keys'].append('missing_key') # fill db 0 tmp['db'] = 0 conn = redis_check._get_conn(tmp) conn.flushdb() conn.lpush('test_foo', 'value1') conn.lpush('test_foo', 'value2') conn.lpush('test_bar', 'value1') # fill db 3 tmp['db'] = 3 conn = redis_check._get_conn(tmp) conn.flushdb() conn.lpush('test_foo', 'value3') conn.lpush('test_foo', 'value4') redis_check._check_key_lengths(c, redis_instance, []) aggregator.assert_metric('redis.key.length', count=4) aggregator.assert_metric('redis.key.length', value=2, tags=['key:test_foo', 'key_type:list', 'redis_db:db0']) aggregator.assert_metric('redis.key.length', value=2, tags=['key:test_foo', 'key_type:list', 'redis_db:db3']) aggregator.assert_metric('redis.key.length', value=1, tags=['key:test_bar', 'key_type:list', 'redis_db:db0']) aggregator.assert_metric('redis.key.length', value=0, tags=['key:missing_key'])
def test_slowlog(aggregator, redis_instance): db = redis.Redis(port=PORT, db=14, password=PASSWORD, host=HOST) # Tweaking Redis's config to have the test run faster db.config_set('slowlog-log-slower-than', 0) db.flushdb() # Generate some slow commands for i in range(100): db.lpush(TEST_KEY, random.random()) db.sort(TEST_KEY) assert db.slowlog_len() > 0 redis_check = Redis('redisdb', {}, {}) redis_check.check(redis_instance) expected_tags = ['foo:bar', 'redis_host:{}'.format(HOST), 'redis_port:6379', 'command:LPUSH'] aggregator.assert_metric('redis.slowlog.micros', tags=expected_tags)
def test__check_key_lengths_single_db(aggregator, redis_instance): """ Keys are stored in multiple databases but we collect data from one database only """ redis_check = Redis('redisdb', {}, {}) tmp = deepcopy(redis_instance) # fill db 0 tmp['db'] = 0 conn = redis_check._get_conn(tmp) conn.flushdb() conn.lpush('test_foo', 'value1') conn.lpush('test_foo', 'value2') # fill db 3 tmp['db'] = 3 conn = redis_check._get_conn(tmp) conn.flushdb() conn.lpush('test_foo', 'value3') conn.lpush('test_foo', 'value4') # collect only from 3 redis_instance['db'] = 3 redis_check._check_key_lengths(conn, redis_instance, []) # metric should be only one, not regarding the number of databases aggregator.assert_metric('redis.key.length', count=1) # that single metric should have value=2 aggregator.assert_metric('redis.key.length', value=2)
def test_custom_slowlog(aggregator, redis_instance): redis_instance['slowlog-max-len'] = 1 db = redis.Redis(port=PORT, db=14, password=PASSWORD, host=HOST) # Tweaking Redis's config to have the test run faster db.config_set('slowlog-log-slower-than', 0) db.flushdb() # Generate some slow commands for i in range(100): db.lpush(TEST_KEY, random.random()) db.sort(TEST_KEY) assert db.slowlog_len() > 0 redis_check = Redis('redisdb', {}, {}) redis_check.check(redis_instance) # Let's check that we didn't put more than one slowlog entry in the # payload, as specified in the above agent configuration assert len(aggregator.metrics('redis.slowlog.micros')) == 1
def test_redis_command_stats(aggregator, redis_instance): db = redis.Redis(port=PORT, db=14, password=PASSWORD, host=HOST) version = db.info().get('redis_version') if StrictVersion(version) < StrictVersion('2.6.0'): # Command stats only works with Redis >= 2.6.0 return redis_instance['command_stats'] = True redis_check = Redis('redisdb', {}, {}) redis_check.check(redis_instance) for name in STAT_METRICS: aggregator.assert_metric(name) # Check the command stats for INFO, since we know we've called it for m in aggregator.metrics('redis.command.calls'): if 'command:info' in m.tags: found = True break else: found = False assert found
def test__check_key_lengths_misconfig(aggregator, redis_instance): """ The check shouldn't send anything if misconfigured """ redis_check = Redis('redisdb', {}, {}) c = redis_check._get_conn(redis_instance) # `keys` param is missing del redis_instance['keys'] redis_check._check_key_lengths(c, redis_instance, []) assert len(list(aggregator.metrics('redis.key.length'))) == 0 # `keys` is not a list redis_instance['keys'] = 'FOO' redis_check._check_key_lengths(c, redis_instance, []) assert len(list(aggregator.metrics('redis.key.length'))) == 0 # `keys` is an empty list redis_instance['keys'] = [] redis_check._check_key_lengths(c, redis_instance, []) assert len(list(aggregator.metrics('redis.key.length'))) == 0
def test__get_conn(): check = Redis('redisdb', {}, {}, None) instance = {} # create a connection check._get_conn(instance) key1, conn1 = next(check.connections.iteritems()) # assert connection is cached check._get_conn(instance) key2, conn2 = next(check.connections.iteritems()) assert key2 == key1 assert conn2 == conn1 # disable cache and assert connection has changed instance['disable_connection_cache'] = True check._get_conn(instance) key2, conn2 = next(check.connections.iteritems()) assert key2 == key1 assert conn2 != conn1
def test_redis_replication_link_metric(aggregator, replica_instance, dd_environment): metric_name = 'redis.replication.master_link_down_since_seconds' redis_check = Redis('redisdb', {}, [replica_instance]) redis_check.check(replica_instance) aggregator.assert_metric(metric_name, value=0) # Test the same on the unhealthy host aggregator.reset() replica_instance['port'] = UNHEALTHY_REPLICA_PORT redis_check.check(replica_instance) metrics = aggregator.metrics(metric_name) assert len(metrics) == 1 assert metrics[0].value > 0
def test_redis_replication_service_check(aggregator, replica_instance, dd_environment): service_check_name = 'redis.replication.master_link_status' redis_check = Redis('redisdb', {}, [replica_instance]) redis_check.check(replica_instance) assert len(aggregator.service_checks(service_check_name)) == 1 # Healthy host assert aggregator.service_checks(service_check_name)[0].status == Redis.OK # Unhealthy host aggregator.reset() replica_instance['port'] = UNHEALTHY_REPLICA_PORT redis_check.check(replica_instance) assert len(aggregator.service_checks(service_check_name)) == 1 assert aggregator.service_checks(service_check_name)[0].status == Redis.CRITICAL
def test_init(): check = Redis('redisdb', {}, {}, None) assert check.connections == {} assert len(check.last_timestamp_seen) == 0
def check(): return lambda instance: Redis('redisdb', {}, [instance])
def check(): return Redis('redisdb', {}, {}, None)
def check(redis_instance): return Redis('redisdb', {}, [redis_instance])