diff --git a/.gitignore b/.gitignore index 5bcc2fec37..2c179642cb 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ node_modules/* venv/* *.swp *.log +!nagios.log *.pid *.deb *.rpm diff --git a/Rakefile b/Rakefile index dccecc7554..8336a3235a 100755 --- a/Rakefile +++ b/Rakefile @@ -49,7 +49,7 @@ unless ENV['TRAVIS'] end desc 'Setup a development environment for the Agent' -task "setup_env" do +task 'setup_env' do `mkdir -p venv` `wget -O venv/virtualenv.py https://raw.github.com/pypa/virtualenv/1.11.6/virtualenv.py` `python venv/virtualenv.py --no-site-packages --no-pip --no-setuptools venv/` @@ -64,23 +64,26 @@ end namespace :test do desc 'Run dogstatsd tests' task 'dogstatsd' do - sh 'nosetests tests/test_dogstatsd.py' + sh 'nosetests tests/core/test_dogstatsd.py' end desc 'Run performance tests' task 'performance' do - sh 'nosetests --with-xunit --xunit-file=nosetests-performance.xml tests/performance/benchmark*.py' + sh 'nosetests --with-xunit --xunit-file=nosetests-performance.xml tests/core/benchmark*.py' end desc 'cProfile unit tests (requires \'nose-cprof\')' task 'profile' do - sh 'nosetests --with-cprofile tests/performance/benchmark*.py' + sh 'nosetests --with-cprofile tests/core/benchmark*.py' end desc 'cProfile tests, then run pstats' task 'profile:pstats' => ['test:profile'] do sh 'python -m pstats stats.dat' end + + desc 'Display test coverage for checks' + task 'coverage' => 'ci:default:coverage' end desc 'Lint the code through pylint' diff --git a/checks/__init__.py b/checks/__init__.py index cd1afcb399..404eff738e 100644 --- a/checks/__init__.py +++ b/checks/__init__.py @@ -682,32 +682,6 @@ def agent_formatter(metric, value, timestamp, tags, hostname, device_name=None, return (metric, int(timestamp), value) -def run_check(name, path=None): - from tests.common import get_check - - # Read the config file - confd_path = path or os.path.join(get_confd_path(get_os()), '%s.yaml' % name) - - try: - f = open(confd_path) - except IOError: - raise Exception('Unable to open configuration at %s' % confd_path) - - config_str = f.read() - f.close() - - # Run the check - check, instances = get_check(name, config_str) - if not instances: - raise Exception('YAML configuration returned no instances.') - for instance in instances: - check.check(instance) - if check.has_events(): - print "Events:\n" - pprint(check.get_events(), indent=4) - print "Metrics:\n" - pprint(check.get_metrics(), indent=4) - def create_service_check(check_name, status, tags=None, timestamp=None, hostname=None, check_run_id=None, message=None): """ Create a service_check dict. See AgentCheck.service_check() for diff --git a/ci/default.rb b/ci/default.rb index 929259c9a9..3a3179bd9f 100644 --- a/ci/default.rb +++ b/ci/default.rb @@ -4,6 +4,37 @@ namespace :default do |flavor| task :before_install => ['ci:common:before_install'] + task :coverage do + ci_dir = File.dirname(__FILE__) + checks_dir = File.join(ci_dir, '..', 'checks.d') + tests_checks_dir = File.join(ci_dir, '..', 'tests', 'checks') + mock_dir = File.join(tests_checks_dir, 'mock') + integration_dir = File.join(tests_checks_dir, 'integration') + untested, mocked, perfects = [], [], [] + Dir.glob(File.join(checks_dir, '*.py')).each do |check| + check_name = /((\w|_)+).py$/.match(check)[1] + if File.exist?(File.join(integration_dir, "test_#{check_name}.py")) + perfects.push(check_name) + elsif File.exist?(File.join(mock_dir, "test_#{check_name}.py")) + mocked.push(check_name) + else + untested.push(check_name) + end + end + total_checks = (untested + mocked + perfects).length + unless untested.empty? + puts "Untested checks (#{untested.length}/#{total_checks})".red + puts '-----------------------'.red + untested.each { |check_name| puts check_name.red } + puts '' + end + unless mocked.empty? + puts "Mocked tests (#{mocked.length}/#{total_checks})".yellow + puts '--------------------'.yellow + mocked.each { |check_name| puts check_name.yellow } + end + end + task :install => ['ci:common:install'] task :before_script => ['ci:common:before_script'] @@ -12,7 +43,7 @@ sh %(find . -name '*.py' -not \\( -path '*.cache*' -or -path '*embedded*' -or -path '*venv*' \\) | xargs -n 1 pylint --rcfile=./.pylintrc) end - task :script => ['ci:common:script', :lint] do + task :script => ['ci:common:script', :coverage, :lint] do Rake::Task['ci:common:run_tests'].invoke('default') end diff --git a/ez_setup.py b/ez_setup.py index c57354577a..aa81b08f4e 100644 --- a/ez_setup.py +++ b/ez_setup.py @@ -100,9 +100,9 @@ def do_download(): try: import pkg_resources except ImportError: - return do_download() + return do_download() try: - pkg_resources.require("setuptools>="+version); return + pkg_resources.require("setuptools>="+version); return #pylint: disable=E1102 except pkg_resources.VersionConflict, e: if was_imported: print >>sys.stderr, ( @@ -225,7 +225,7 @@ def main(argv, version=DEFAULT_VERSION): req = "setuptools>="+version import pkg_resources try: - pkg_resources.require(req) + pkg_resources.require(req) #pylint: disable=E1102 except pkg_resources.VersionConflict: try: from setuptools.command.easy_install import main diff --git a/tests/cassandra/cfstats b/tests/cassandra/cfstats deleted file mode 100644 index 6bbbc0f8a9..0000000000 --- a/tests/cassandra/cfstats +++ /dev/null @@ -1,194 +0,0 @@ -Keyspace: system - Read Count: 10 - Read Latency: 5.4211 ms. - Write Count: 3 - Write Latency: 0.02766666666666667 ms. - Pending Tasks: 0 - Column Family: Schema - SSTable count: 2 - Space used (live): 16326 - Space used (total): 16326 - Memtable Columns Count: 0 - Memtable Data Size: 0 - Memtable Switch Count: 0 - Read Count: 3 - Read Latency: NaN ms. - Write Count: 0 - Write Latency: NaN ms. - Pending Tasks: 0 - Key cache capacity: 2 - Key cache size: 2 - Key cache hit rate: NaN - Row cache: disabled - Compacted row minimum size: 149 - Compacted row maximum size: 3311 - Compacted row mean size: 149 - - Column Family: Migrations - SSTable count: 1 - Space used (live): 12407 - Space used (total): 12407 - Memtable Columns Count: 0 - Memtable Data Size: 0 - Memtable Switch Count: 0 - Read Count: 0 - Read Latency: NaN ms. - Write Count: 0 - Write Latency: NaN ms. - Pending Tasks: 0 - Key cache capacity: 1 - Key cache size: 0 - Key cache hit rate: NaN - Row cache: disabled - Compacted row minimum size: 6866 - Compacted row maximum size: 8239 - Compacted row mean size: 6866 - - Column Family: IndexInfo - SSTable count: 0 - Space used (live): 0 - Space used (total): 0 - Memtable Columns Count: 0 - Memtable Data Size: 0 - Memtable Switch Count: 0 - Read Count: 0 - Read Latency: NaN ms. - Write Count: 0 - Write Latency: NaN ms. - Pending Tasks: 0 - Key cache capacity: 1 - Key cache size: 0 - Key cache hit rate: NaN - Row cache: disabled - Compacted row minimum size: 0 - Compacted row maximum size: 0 - Compacted row mean size: 0 - - Column Family: LocationInfo - SSTable count: 3 - Space used (live): 17890 - Space used (total): 17890 - Memtable Columns Count: 0 - Memtable Data Size: 0 - Memtable Switch Count: 2 - Read Count: 7 - Read Latency: NaN ms. - Write Count: 3 - Write Latency: NaN ms. - Pending Tasks: 0 - Key cache capacity: 3 - Key cache size: 3 - Key cache hit rate: NaN - Row cache: disabled - Compacted row minimum size: 124 - Compacted row maximum size: 310 - Compacted row mean size: 132 - - Column Family: HintsColumnFamily - SSTable count: 0 - Space used (live): 0 - Space used (total): 0 - Memtable Columns Count: 0 - Memtable Data Size: 0 - Memtable Switch Count: 0 - Read Count: 0 - Read Latency: NaN ms. - Write Count: 0 - Write Latency: NaN ms. - Pending Tasks: 0 - Key cache capacity: 1 - Key cache size: 0 - Key cache hit rate: NaN - Row cache: disabled - Compacted row minimum size: 0 - Compacted row maximum size: 0 - Compacted row mean size: 0 - ----------------- -Keyspace: Intake - Read Count: 0 - Read Latency: NaN ms. - Write Count: 0 - Write Latency: NaN ms. - Pending Tasks: 0 - Column Family: Events - SSTable count: 3 - Space used (live): 6623 - Space used (total): 6623 - Memtable Columns Count: 0 - Memtable Data Size: 0 - Memtable Switch Count: 0 - Read Count: 0 - Read Latency: NaN ms. - Write Count: 0 - Write Latency: NaN ms. - Pending Tasks: 0 - Key cache capacity: 200000 - Key cache size: 0 - Key cache hit rate: NaN - Row cache: disabled - Compacted row minimum size: 0 - Compacted row maximum size: 372 - Compacted row mean size: 103 - - Column Family: Encodings - SSTable count: 2 - Space used (live): 19497 - Space used (total): 19497 - Memtable Columns Count: 0 - Memtable Data Size: 0 - Memtable Switch Count: 0 - Read Count: 0 - Read Latency: NaN ms. - Write Count: 0 - Write Latency: NaN ms. - Pending Tasks: 0 - Key cache capacity: 200000 - Key cache size: 0 - Key cache hit rate: NaN - Row cache: disabled - Compacted row minimum size: 149 - Compacted row maximum size: 179 - Compacted row mean size: 149 - - Column Family: Metrics - SSTable count: 2 - Space used (live): 42521 - Space used (total): 42521 - Memtable Columns Count: 0 - Memtable Data Size: 0 - Memtable Switch Count: 0 - Read Count: 0 - Read Latency: NaN ms. - Write Count: 0 - Write Latency: NaN ms. - Pending Tasks: 0 - Key cache capacity: 200000 - Key cache size: 0 - Key cache hit rate: NaN - Row cache: disabled - Compacted row minimum size: 642 - Compacted row maximum size: 770 - Compacted row mean size: 642 - - Column Family: Processes - SSTable count: 2 - Space used (live): 352725 - Space used (total): 352725 - Memtable Columns Count: 0 - Memtable Data Size: 0 - Memtable Switch Count: 0 - Read Count: 0 - Read Latency: NaN ms. - Write Count: 0 - Write Latency: NaN ms. - Pending Tasks: 0 - Key cache capacity: 200000 - Key cache size: 0 - Key cache hit rate: NaN - Row cache: disabled - Compacted row minimum size: 5722 - Compacted row maximum size: 9887 - Compacted row mean size: 6866 - ----------------- diff --git a/tests/cassandra/info b/tests/cassandra/info deleted file mode 100644 index eda67b5944..0000000000 --- a/tests/cassandra/info +++ /dev/null @@ -1,5 +0,0 @@ -36299342986353445520010708318471778930 -Load : 457.02 KB -Generation No : 1295816448 -Uptime (seconds) : 95 -Heap Memory (MB) : 521.86 / 1019.88 diff --git a/tests/cassandra/info.8 b/tests/cassandra/info.8 deleted file mode 100644 index b2756ef327..0000000000 --- a/tests/cassandra/info.8 +++ /dev/null @@ -1,9 +0,0 @@ -Token : 51022655878160265769426795515063697984 -Gossip active : true -Load : 283.87 GB -Generation No : 1331653944 -Uptime (seconds) : 188319 -Heap Memory (MB) : 2527.04 / 3830.00 -Data Center : 28 -Rack : 76 -Exceptions : 0 diff --git a/tests/cassandra/info.opp b/tests/cassandra/info.opp deleted file mode 100644 index 68015ca7b7..0000000000 --- a/tests/cassandra/info.opp +++ /dev/null @@ -1,10 +0,0 @@ -Token : Token(bytes[56713727820156410577229101240436610842]) -Generation No : 1331653944 -Gossip active : true -Load : 283.87 GB -Generation No : 1331653944 -Uptime (seconds) : 188319 -Heap Memory (MB) : 2527.04 / 3830.00 -Data Center : 28 -Rack : 76 -Exceptions : 0 diff --git a/tests/cassandra/tpstats b/tests/cassandra/tpstats deleted file mode 100644 index 0202ce032e..0000000000 --- a/tests/cassandra/tpstats +++ /dev/null @@ -1,14 +0,0 @@ -Pool Name Active Pending Completed -ReadStage 0 0 1 -RequestResponseStage 0 0 0 -MutationStage 0 0 3 -ReadRepair 0 0 0 -GossipStage 0 0 0 -AntiEntropyStage 0 0 0 -MigrationStage 0 0 0 -MemtablePostFlusher 0 0 2 -StreamStage 0 0 0 -FlushWriter 0 0 2 -MiscStage 0 0 0 -FlushSorter 0 0 0 -InternalResponseStage 0 0 0 diff --git a/tests/cassandra/tpstats.8 b/tests/cassandra/tpstats.8 deleted file mode 100644 index 0ad1c0cbbc..0000000000 --- a/tests/cassandra/tpstats.8 +++ /dev/null @@ -1,25 +0,0 @@ -Pool Name Active Pending Completed Blocked All time blocked -ReadStage 0 0 13931979 0 0 -RequestResponseStage 0 0 61825583 0 0 -MutationStage 0 0 63053347 0 0 -ReadRepairStage 0 0 4197438 0 0 -ReplicateOnWriteStage 0 0 0 0 0 -GossipStage 0 0 2942066 0 0 -AntiEntropyStage 0 0 0 0 0 -MigrationStage 0 0 0 0 0 -MemtablePostFlusher 0 0 10938 0 0 -StreamStage 0 0 0 0 0 -FlushWriter 0 0 10938 0 12 -FILEUTILS-DELETE-POOL 0 0 1379 0 0 -MiscStage 0 0 0 0 0 -FlushSorter 0 0 0 0 0 -InternalResponseStage 0 0 0 0 0 -HintedHandoff 0 0 9 0 0 - -Message type Dropped -RANGE_SLICE 0 -READ_REPAIR 0 -BINARY 0 -READ 20234 -MUTATION 0 -REQUEST_RESPONSE 0 diff --git a/tests/checks/__init__.py b/tests/checks/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/common.py b/tests/checks/common.py similarity index 94% rename from tests/common.py rename to tests/checks/common.py index 9e88c5bfb8..8a31593579 100644 --- a/tests/common.py +++ b/tests/checks/common.py @@ -17,6 +17,7 @@ log = logging.getLogger('tests') + def get_check_class(name): checksd_path = get_checksd_path(get_os()) if checksd_path not in sys.path: @@ -37,6 +38,7 @@ def get_check_class(name): return check_class + def load_check(name, config, agentConfig): checksd_path = get_checksd_path(get_os()) if checksd_path not in sys.path: @@ -67,6 +69,7 @@ def load_check(name, config, agentConfig): except Exception as e: raise Exception("Check is using old API, {0}".format(e)) + def kill_subprocess(process_obj): try: process_obj.terminate() @@ -76,12 +79,13 @@ def kill_subprocess(process_obj): import ctypes PROCESS_TERMINATE = 1 handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, - process_obj.pid) + process_obj.pid) ctypes.windll.kernel32.TerminateProcess(handle, -1) ctypes.windll.kernel32.CloseHandle(handle) else: os.kill(process_obj.pid, signal.SIGKILL) + def get_check(name, config_str): checksd_path = get_checksd_path(get_os()) if checksd_path not in sys.path: @@ -102,10 +106,34 @@ def get_check(name, config_str): } return check_class.from_yaml(yaml_text=config_str, check_name=name, - agentConfig=agentConfig) - -def read_data_from_file(filename): - return open(os.path.join(os.path.dirname(__file__), 'data', filename)).read() + agentConfig=agentConfig) + + +class Fixtures(object): + + @staticmethod + def integration_name(): + for stack in inspect.stack(): + # stack[1] is the file path + file_name = os.path.basename(stack[1]) + if 'test_' in file_name: + # test_name.py + # 5 -3 + return file_name[5:-3] + raise Exception('No integration test file in stack') + + @staticmethod + def directory(): + return os.path.join(os.path.dirname(__file__), 'fixtures', + Fixtures.integration_name()) + + @staticmethod + def file(file_name): + return os.path.join(Fixtures.directory(), file_name) + + @staticmethod + def read_file(file_name): + return open(Fixtures.file(file_name)).read() class AgentCheckTest(unittest.TestCase): diff --git a/tests/cacti/whitelist.txt b/tests/checks/fixtures/cacti/whitelist.txt similarity index 100% rename from tests/cacti/whitelist.txt rename to tests/checks/fixtures/cacti/whitelist.txt diff --git a/tests/jmx_yamls/cassandra.yaml b/tests/checks/fixtures/cassandra/cassandra.yaml similarity index 100% rename from tests/jmx_yamls/cassandra.yaml rename to tests/checks/fixtures/cassandra/cassandra.yaml diff --git a/tests/ganglia.txt b/tests/checks/fixtures/ganglia/ganglia.txt similarity index 100% rename from tests/ganglia.txt rename to tests/checks/fixtures/ganglia/ganglia.txt diff --git a/tests/go_expvar/expvar_output b/tests/checks/fixtures/go_expvar/expvar_output similarity index 100% rename from tests/go_expvar/expvar_output rename to tests/checks/fixtures/go_expvar/expvar_output diff --git a/tests/host-perfdata b/tests/checks/fixtures/nagios/host-perfdata similarity index 100% rename from tests/host-perfdata rename to tests/checks/fixtures/nagios/host-perfdata diff --git a/tests/nagios.log b/tests/checks/fixtures/nagios/nagios.log similarity index 100% rename from tests/nagios.log rename to tests/checks/fixtures/nagios/nagios.log diff --git a/tests/service-perfdata b/tests/checks/fixtures/nagios/service-perfdata similarity index 100% rename from tests/service-perfdata rename to tests/checks/fixtures/nagios/service-perfdata diff --git a/tests/data/nginx_plus_in.json b/tests/checks/fixtures/nginx/nginx_plus_in.json similarity index 100% rename from tests/data/nginx_plus_in.json rename to tests/checks/fixtures/nginx/nginx_plus_in.json diff --git a/tests/data/nginx_plus_out.python b/tests/checks/fixtures/nginx/nginx_plus_out.python similarity index 100% rename from tests/data/nginx_plus_out.python rename to tests/checks/fixtures/nginx/nginx_plus_out.python diff --git a/tests/data/riakcs_in.json b/tests/checks/fixtures/riakcs/riakcs_in.json similarity index 100% rename from tests/data/riakcs_in.json rename to tests/checks/fixtures/riakcs/riakcs_in.json diff --git a/tests/data/riakcs_metrics.python b/tests/checks/fixtures/riakcs/riakcs_metrics.python similarity index 100% rename from tests/data/riakcs_metrics.python rename to tests/checks/fixtures/riakcs/riakcs_metrics.python diff --git a/tests/data/riakcs_out.python b/tests/checks/fixtures/riakcs/riakcs_out.python similarity index 100% rename from tests/data/riakcs_out.python rename to tests/checks/fixtures/riakcs/riakcs_out.python diff --git a/tests/jmx_yamls/solr.yaml b/tests/checks/fixtures/solr/solr.yaml similarity index 100% rename from tests/jmx_yamls/solr.yaml rename to tests/checks/fixtures/solr/solr.yaml diff --git a/tests/varnish/dump.xml b/tests/checks/fixtures/varnish/dump.xml similarity index 100% rename from tests/varnish/dump.xml rename to tests/checks/fixtures/varnish/dump.xml diff --git a/tests/varnish/v_dump b/tests/checks/fixtures/varnish/v_dump similarity index 100% rename from tests/varnish/v_dump rename to tests/checks/fixtures/varnish/v_dump diff --git a/tests/varnish/varnishadm_dump b/tests/checks/fixtures/varnish/varnishadm_dump similarity index 100% rename from tests/varnish/varnishadm_dump rename to tests/checks/fixtures/varnish/varnishadm_dump diff --git a/tests/checks/integration/__init__.py b/tests/checks/integration/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/test_apache.py b/tests/checks/integration/test_apache.py similarity index 97% rename from tests/test_apache.py rename to tests/checks/integration/test_apache.py index 9e975f2541..6a70cd5229 100644 --- a/tests/test_apache.py +++ b/tests/checks/integration/test_apache.py @@ -3,7 +3,7 @@ # project from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest @attr(requires='apache') diff --git a/tests/test_cassandra_jmx.py b/tests/checks/integration/test_cassandra.py similarity index 94% rename from tests/test_cassandra_jmx.py rename to tests/checks/integration/test_cassandra.py index 5c073b02ca..6e13b405b5 100644 --- a/tests/test_cassandra_jmx.py +++ b/tests/checks/integration/test_cassandra.py @@ -5,9 +5,8 @@ from aggregator import MetricsAggregator from dogstatsd import Server from util import PidFile -import os from jmxfetch import JMXFetch - +from tests.checks.common import Fixtures STATSD_PORT = 8121 @@ -21,7 +20,6 @@ def __init__(self, metrics_aggregator): self.finished = False self.start() - def run(self): while not self.finished: time.sleep(self.interval) @@ -32,6 +30,7 @@ def flush(self): if metrics: self.metrics = metrics + @attr(requires='cassandra') class JMXTestCase(unittest.TestCase): def setUp(self): @@ -43,7 +42,7 @@ def setUp(self): self.t1 = threading.Thread(target=self.server.start) self.t1.start() - confd_path = os.path.realpath(os.path.join(os.path.abspath(__file__), "..", "jmx_yamls")) + confd_path = Fixtures.directory() self.jmx_daemon = JMXFetch(confd_path, {'dogstatsd_port': STATSD_PORT}) self.t2 = threading.Thread(target=self.jmx_daemon.run) diff --git a/tests/test_couch.py b/tests/checks/integration/test_couch.py similarity index 96% rename from tests/test_couch.py rename to tests/checks/integration/test_couch.py index b63b24fe61..fd2725639c 100644 --- a/tests/test_couch.py +++ b/tests/checks/integration/test_couch.py @@ -1,4 +1,4 @@ -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest from nose.plugins.attrib import attr from checks import AgentCheck diff --git a/tests/test_elastic.py b/tests/checks/integration/test_elastic.py similarity index 99% rename from tests/test_elastic.py rename to tests/checks/integration/test_elastic.py index fbd5b697c1..58f8600e47 100644 --- a/tests/test_elastic.py +++ b/tests/checks/integration/test_elastic.py @@ -7,7 +7,7 @@ from nose.plugins.attrib import attr # project -from tests.common import AgentCheckTest, load_check +from tests.checks.common import AgentCheckTest, load_check from checks import AgentCheck from config import get_version diff --git a/tests/test_etcd.py b/tests/checks/integration/test_etcd.py similarity index 97% rename from tests/test_etcd.py rename to tests/checks/integration/test_etcd.py index a9ada0f75d..442b3ab36d 100644 --- a/tests/test_etcd.py +++ b/tests/checks/integration/test_etcd.py @@ -1,4 +1,4 @@ -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest from nose.plugins.attrib import attr from time import sleep from checks import AgentCheck diff --git a/tests/test_fluentd.py b/tests/checks/integration/test_fluentd.py similarity index 98% rename from tests/test_fluentd.py rename to tests/checks/integration/test_fluentd.py index 1b3d232f1e..5cc6c8fb25 100644 --- a/tests/test_fluentd.py +++ b/tests/checks/integration/test_fluentd.py @@ -3,7 +3,7 @@ from nose.plugins.attrib import attr logger = logging.getLogger(__file__) -from tests.common import load_check +from tests.checks.common import load_check @attr(requires='fluentd') class TestFluentd(unittest.TestCase): diff --git a/tests/test_gearman.py b/tests/checks/integration/test_gearmand.py similarity index 97% rename from tests/test_gearman.py rename to tests/checks/integration/test_gearmand.py index 762fdac86a..62c58597c8 100644 --- a/tests/test_gearman.py +++ b/tests/checks/integration/test_gearmand.py @@ -1,6 +1,6 @@ # Agent from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest # 3rd party from nose.plugins.attrib import attr @@ -28,7 +28,7 @@ def test_metrics(self): self.assertServiceCheck("gearman.can_connect", status=AgentCheck.OK, tags=service_checks_tags, count=1) self.coverage_report() - + def test_service_checks(self): config = { @@ -36,7 +36,7 @@ def test_service_checks(self): {'host': '127.0.0.1', 'port': 4730}, {'host': '127.0.0.1', 'port': 4731}] } - + self.assertRaises(Exception, self.run_check, config) service_checks_tags_ok = ['server:127.0.0.1', 'port:4730'] service_checks_tags_not_ok = ['server:127.0.0.1', 'port:4731'] diff --git a/tests/checks/integration/test_go_expvar.py b/tests/checks/integration/test_go_expvar.py new file mode 100644 index 0000000000..8ef8ac6e1f --- /dev/null +++ b/tests/checks/integration/test_go_expvar.py @@ -0,0 +1,98 @@ +from collections import defaultdict +from nose.plugins.attrib import attr +import time + +from tests.checks.common import AgentCheckTest + + +@attr(requires='go_expvar') +class TestGoExpVar(AgentCheckTest): + + CHECK_NAME = 'go_expvar' + + CHECK_GAUGES = [ + 'go_expvar.memstats.alloc', + 'go_expvar.memstats.heap_alloc', + 'go_expvar.memstats.heap_idle', + 'go_expvar.memstats.heap_inuse', + 'go_expvar.memstats.heap_objects', + 'go_expvar.memstats.heap_released', + 'go_expvar.memstats.heap_sys', + 'go_expvar.memstats.total_alloc', + ] + + CHECK_GAUGES_DEFAULT = [ + 'go_expvar.memstats.pause_ns.95percentile', + 'go_expvar.memstats.pause_ns.avg', + 'go_expvar.memstats.pause_ns.count', + 'go_expvar.memstats.pause_ns.max', + 'go_expvar.memstats.pause_ns.median', + ] + + CHECK_GAUGES_CUSTOM = {'go_expvar.last_user': '123456'} + + CHECK_RATES = [ + 'go_expvar.memstats.frees', + 'go_expvar.memstats.lookups', + 'go_expvar.memstats.mallocs', + 'go_expvar.memstats.num_gc', + 'go_expvar.memstats.pause_total_ns', + ] + + CHECK_RATES_CUSTOM = {'go_expvar.num_calls': 0} + + def __init__(self, *args, **kwargs): + AgentCheckTest.__init__(self, *args, **kwargs) + self.config = { + "instances": [{ + "expvar_url": 'http://localhost:8079/debug/vars', + 'tags': ['my_tag'], + 'metrics': [ + { + 'path': 'last_user' + }, + { + 'path': 'num_calls', + "type": "rate" + }, + ] + }] + } + + def _run_check_twice(self): + # To avoid the disparition of some gauges during the second check + mocks = {} + config = self.config + expvar_url = self.config['instances'][0]['expvar_url'] + + fake_last_gc_count = defaultdict(int) + mocks['_last_gc_count'] = fake_last_gc_count + + # Can't use run_check_twice due to specific metrics + self.run_check(config, mocks=mocks) + time.sleep(1) + # Reset it + del fake_last_gc_count[expvar_url] + + self.run_check(config, mocks=mocks) + + # Real integration test + def test_go_expvar(self): + self._run_check_twice() + + shared_tags = [ + 'my_tag', + 'expvar_url:{0}'.format(self.config['instances'][0]['expvar_url']) + ] + + for gauge in self.CHECK_GAUGES + self.CHECK_GAUGES_DEFAULT: + self.assertMetric(gauge, count=1, tags=shared_tags) + for rate in self.CHECK_RATES: + self.assertMetric(rate, count=1, tags=shared_tags) + + for gauge, value in self.CHECK_GAUGES_CUSTOM.iteritems(): + self.assertMetric(gauge, count=1, value=value, tags=shared_tags) + for rate, value in self.CHECK_RATES_CUSTOM.iteritems(): + self.assertMetric(rate, count=1, value=value, tags=shared_tags) + + self.coverage_report() diff --git a/tests/test_haproxy.py b/tests/checks/integration/test_haproxy.py similarity index 99% rename from tests/test_haproxy.py rename to tests/checks/integration/test_haproxy.py index cee20b1523..54ed305dbe 100644 --- a/tests/test_haproxy.py +++ b/tests/checks/integration/test_haproxy.py @@ -1,6 +1,6 @@ from checks import AgentCheck from nose.plugins.attrib import attr -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest from util import get_hostname diff --git a/tests/test_http_check.py b/tests/checks/integration/test_http_check.py similarity index 99% rename from tests/test_http_check.py rename to tests/checks/integration/test_http_check.py index 83425c3404..46409400e1 100644 --- a/tests/test_http_check.py +++ b/tests/checks/integration/test_http_check.py @@ -2,7 +2,7 @@ import mock from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest RESULTS_TIMEOUT = 5 diff --git a/tests/test_lighttpd.py b/tests/checks/integration/test_lighttpd.py similarity index 97% rename from tests/test_lighttpd.py rename to tests/checks/integration/test_lighttpd.py index 16326cd09e..24c7f048fb 100644 --- a/tests/test_lighttpd.py +++ b/tests/checks/integration/test_lighttpd.py @@ -1,7 +1,7 @@ from nose.plugins.attrib import attr from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest @attr(requires='lighttpd') diff --git a/tests/test_mcache.py b/tests/checks/integration/test_mcache.py similarity index 99% rename from tests/test_mcache.py rename to tests/checks/integration/test_mcache.py index a6a3666f34..4fb94b236f 100644 --- a/tests/test_mcache.py +++ b/tests/checks/integration/test_mcache.py @@ -4,7 +4,7 @@ import time from subprocess import Popen, PIPE -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest from checks import AgentCheck diff --git a/tests/test_mongo.py b/tests/checks/integration/test_mongo.py similarity index 99% rename from tests/test_mongo.py rename to tests/checks/integration/test_mongo.py index e23a27e50f..6d3ad1e156 100644 --- a/tests/test_mongo.py +++ b/tests/checks/integration/test_mongo.py @@ -4,7 +4,7 @@ import pymongo -from tests.common import load_check +from tests.checks.common import load_check PORT1 = 37017 PORT2 = 37018 diff --git a/tests/test_mysql.py b/tests/checks/integration/test_mysql.py similarity index 98% rename from tests/test_mysql.py rename to tests/checks/integration/test_mysql.py index afd5a1d8a6..191273f515 100644 --- a/tests/test_mysql.py +++ b/tests/checks/integration/test_mysql.py @@ -3,7 +3,7 @@ # project from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest @attr(requires='mysql') diff --git a/tests/test_nginx.py b/tests/checks/integration/test_nginx.py similarity index 90% rename from tests/test_nginx.py rename to tests/checks/integration/test_nginx.py index 0d0068286c..ce4bc08cf3 100644 --- a/tests/test_nginx.py +++ b/tests/checks/integration/test_nginx.py @@ -1,7 +1,8 @@ import unittest from nose.plugins.attrib import attr -from tests.common import load_check, read_data_from_file +from tests.checks.common import load_check, Fixtures + @attr(requires='nginx') class TestNginx(unittest.TestCase): @@ -29,7 +30,6 @@ def setUp(self): ] } - def test_nginx(self): nginx = load_check('nginx', self.config, self.agent_config) nginx.check(self.config['instances'][0]) @@ -45,8 +45,8 @@ def test_nginx(self): self.assertEquals(set(can_connect[i]['tags']), set(['host:localhost', 'port:44441']), service_checks) def test_nginx_plus(self): - test_data = read_data_from_file('nginx_plus_in.json') - expected = eval(read_data_from_file('nginx_plus_out.python')) + test_data = Fixtures.read_file('nginx_plus_in.json') + expected = eval(Fixtures.read_file('nginx_plus_out.python')) nginx = load_check('nginx', self.config, self.agent_config) parsed = nginx.parse_json(test_data) parsed.sort() diff --git a/tests/test_pgbouncer.py b/tests/checks/integration/test_pgbouncer.py similarity index 98% rename from tests/test_pgbouncer.py rename to tests/checks/integration/test_pgbouncer.py index 69558a643b..835a81fded 100644 --- a/tests/test_pgbouncer.py +++ b/tests/checks/integration/test_pgbouncer.py @@ -1,4 +1,4 @@ -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest import time import psycopg2 as pg diff --git a/tests/test_php_fpm.py b/tests/checks/integration/test_php_fpm.py similarity index 98% rename from tests/test_php_fpm.py rename to tests/checks/integration/test_php_fpm.py index fb8ec553d9..616e2fca3a 100644 --- a/tests/test_php_fpm.py +++ b/tests/checks/integration/test_php_fpm.py @@ -6,7 +6,7 @@ # project from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest # sample from /status?json # { diff --git a/tests/test_postgres.py b/tests/checks/integration/test_postgres.py similarity index 99% rename from tests/test_postgres.py rename to tests/checks/integration/test_postgres.py index 0f2553659f..30375d809c 100644 --- a/tests/test_postgres.py +++ b/tests/checks/integration/test_postgres.py @@ -6,7 +6,7 @@ # project from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest @attr(requires='postgres') diff --git a/tests/test_rabbitmq.py b/tests/checks/integration/test_rabbitmq.py similarity index 98% rename from tests/test_rabbitmq.py rename to tests/checks/integration/test_rabbitmq.py index 232fc1d43d..1f5f3e1174 100644 --- a/tests/test_rabbitmq.py +++ b/tests/checks/integration/test_rabbitmq.py @@ -2,7 +2,7 @@ from nose.plugins.attrib import attr # project -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest CONFIG = { 'init_config': {}, diff --git a/tests/test_redis.py b/tests/checks/integration/test_redisdb.py similarity index 99% rename from tests/test_redis.py rename to tests/checks/integration/test_redisdb.py index 9d323b00f2..4ba98d5571 100644 --- a/tests/test_redis.py +++ b/tests/checks/integration/test_redisdb.py @@ -7,7 +7,7 @@ import redis import random -from tests.common import load_check, AgentCheckTest +from tests.checks.common import load_check, AgentCheckTest logger = logging.getLogger() MAX_WAIT = 20 @@ -236,7 +236,7 @@ def test_slowlog(self): } db = redis.Redis(port=port, db=14) # Datadog's test db - + # Tweaking Redis's config to have the test run faster old_sl_thresh = db.config_get('slowlog-log-slower-than')['slowlog-log-slower-than'] db.config_set('slowlog-log-slower-than', 0) @@ -250,7 +250,7 @@ def test_slowlog(self): db.sort(test_key) self.assertTrue(db.slowlog_len() > 0) - + db.config_set('slowlog-log-slower-than', old_sl_thresh) self.run_check({"init_config": {}, "instances": [instance]}) @@ -288,10 +288,10 @@ def test_custom_slowlog(self): self.assertTrue(db.slowlog_len() > 0) self.run_check({"init_config": {}, "instances": [instance]}) - + assert self.metrics, "No metrics returned" - # Let's check that we didn't put more than one slowlog entry in the + # Let's check that we didn't put more than one slowlog entry in the # payload, as specified in the above agent configuration self.assertMetric("redis.slowlog.micros.count", tags=["command:SORT", "redis_host:localhost", "redis_port:{0}".format(port)], value=1.0) diff --git a/tests/test_riak.py b/tests/checks/integration/test_riak.py similarity index 98% rename from tests/test_riak.py rename to tests/checks/integration/test_riak.py index ee662ef71b..12bf90d869 100644 --- a/tests/test_riak.py +++ b/tests/checks/integration/test_riak.py @@ -1,6 +1,6 @@ from nose.plugins.attrib import attr import socket -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest @attr(requires='riak') diff --git a/tests/test_snmp.py b/tests/checks/integration/test_snmp.py similarity index 99% rename from tests/test_snmp.py rename to tests/checks/integration/test_snmp.py index a3774925db..811b34ce3c 100644 --- a/tests/test_snmp.py +++ b/tests/checks/integration/test_snmp.py @@ -5,7 +5,7 @@ # agent from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest # This test is dependent of having a fully open snmpd responding at localhost:161 # with an authentication by the Community String "public" diff --git a/tests/test_ssh_check.py b/tests/checks/integration/test_ssh_check.py similarity index 97% rename from tests/test_ssh_check.py rename to tests/checks/integration/test_ssh_check.py index d952217c0c..17708d9f78 100644 --- a/tests/test_ssh_check.py +++ b/tests/checks/integration/test_ssh_check.py @@ -1,6 +1,6 @@ import unittest from nose.plugins.attrib import attr -from tests.common import load_check +from tests.checks.common import load_check from checks import AgentCheck @attr(requires='ssh') diff --git a/tests/checks/integration/test_supervisord.py b/tests/checks/integration/test_supervisord.py new file mode 100644 index 0000000000..5d47533231 --- /dev/null +++ b/tests/checks/integration/test_supervisord.py @@ -0,0 +1,45 @@ +import os +from time import sleep + +from nose.plugins.attrib import attr +import unittest + +from tests.checks.common import get_check + + +@attr(requires='supervisord') +class TestSupervisordCheck(unittest.TestCase): + + def test_travis_supervisord(self): + """Integration test for supervisord check. Using a supervisord on Travis.""" + + # Load yaml config + config_str = open(os.environ['VOLATILE_DIR'] + '/supervisor/supervisord.yaml', 'r').read() + self.assertTrue(config_str is not None and len(config_str) > 0, msg=config_str) + + # init the check and get the instances + check, instances = get_check('supervisord', config_str) + self.assertTrue(check is not None, msg=check) + self.assertEquals(len(instances), 1) + + # Supervisord should run 3 programs for 30, 60 and 90 seconds + # respectively. The tests below will ensure that the process count + # metric is reported correctly after (roughly) 10, 40, 70 and 100 seconds + for i in range(4): + try: + # Run the check + check.check(instances[0]) + except Exception, e: + # Make sure that it ran successfully + self.assertTrue(False, msg=str(e)) + else: + up, down = 0, 0 + for name, timestamp, value, meta in check.get_metrics(): + if name == 'supervisord.process.count': + if 'status:up' in meta['tags']: + up = value + elif 'status:down' in meta['tags']: + down = value + self.assertEquals(up, 3 - i) + self.assertEquals(down, i) + sleep(10) diff --git a/tests/checks/integration/test_sysstat.py b/tests/checks/integration/test_sysstat.py new file mode 100644 index 0000000000..a329169289 --- /dev/null +++ b/tests/checks/integration/test_sysstat.py @@ -0,0 +1,21 @@ +import unittest +from nose.plugins.attrib import attr +import logging +import os + +logging.basicConfig(level=logging.DEBUG) +logger = logging.getLogger(__file__) + +from checks.system.unix import Cpu + + +@attr(requires='sysstat') +class TestSystem(unittest.TestCase): + + def testCPU(self): + global logger + logger.info(os.environ['PATH']) + cpu = Cpu(logger) + res = cpu.check({}) + # Make sure we sum up to 100% (or 99% in the case of macs) + assert abs(reduce(lambda a, b: a+b, res.values(), 0) - 100) <= 5, res diff --git a/tests/test_tokumx.py b/tests/checks/integration/test_tokumx.py similarity index 99% rename from tests/test_tokumx.py rename to tests/checks/integration/test_tokumx.py index cdabd167a6..4c9097c9bb 100644 --- a/tests/test_tokumx.py +++ b/tests/checks/integration/test_tokumx.py @@ -3,7 +3,7 @@ # project from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest GAUGES = [ diff --git a/tests/test_tomcat.py b/tests/checks/integration/test_tomcat.py similarity index 100% rename from tests/test_tomcat.py rename to tests/checks/integration/test_tomcat.py diff --git a/tests/test_varnish.py b/tests/checks/integration/test_varnish.py similarity index 92% rename from tests/test_varnish.py rename to tests/checks/integration/test_varnish.py index b9ca81cf95..f3826f01c5 100644 --- a/tests/test_varnish.py +++ b/tests/checks/integration/test_varnish.py @@ -1,19 +1,13 @@ -# stdlib -import os - # 3p from nose.plugins.attrib import attr # project -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest, Fixtures from utils.shell import which -VARNISH_DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'varnish') - - def mocked_varnishstatoutput(cmd): - return open(os.path.join(VARNISH_DATA_DIR, 'dump.xml'), 'r').read() + return Fixtures.read_file('dump.xml') COMMON_METRICS = [ @@ -97,10 +91,11 @@ def mocked_varnishstatoutput(cmd): 'varnish.SMF.s0.g_smf_frag', ] + +@attr(requires='varnish') class VarnishCheckTest(AgentCheckTest): CHECK_NAME = 'varnish' - @attr(requires='varnish') def test_check(self): varnishstat_path = which('varnishstat') self.assertTrue(varnishstat_path is not None, "Flavored testing should be run with a real varnish") diff --git a/tests/test_zookeeper.py b/tests/checks/integration/test_zk.py similarity index 98% rename from tests/test_zookeeper.py rename to tests/checks/integration/test_zk.py index db6a003dec..611524f889 100644 --- a/tests/test_zookeeper.py +++ b/tests/checks/integration/test_zk.py @@ -3,7 +3,7 @@ # project from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest @attr(requires='zookeeper') diff --git a/tests/checks/mock/__init__.py b/tests/checks/mock/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/test_activemq_xml.py b/tests/checks/mock/test_activemq_xml.py similarity index 99% rename from tests/test_activemq_xml.py rename to tests/checks/mock/test_activemq_xml.py index 1f9edbefbc..f933d1a770 100644 --- a/tests/test_activemq_xml.py +++ b/tests/checks/mock/test_activemq_xml.py @@ -2,7 +2,7 @@ import mock -from tests.common import get_check +from tests.checks.common import get_check class ActiveMQXMLTestCase(unittest.TestCase): diff --git a/tests/test_cacti.py b/tests/checks/mock/test_cacti.py similarity index 96% rename from tests/test_cacti.py rename to tests/checks/mock/test_cacti.py index edc6f579c2..4d7b5f1ae7 100644 --- a/tests/test_cacti.py +++ b/tests/checks/mock/test_cacti.py @@ -1,9 +1,8 @@ -from common import get_check +from tests.checks.common import get_check, Fixtures import unittest import os import logging -import subprocess import shutil log = logging.getLogger() @@ -16,7 +15,8 @@ mysql_user: root rrd_path: /tmp/cacti_test/rrds rrd_whitelist: %s -""" % (os.path.join(os.path.dirname(__file__), "cacti", "whitelist.txt")) +""" % Fixtures.file('whitelist.txt') + class TestCacti(unittest.TestCase): def setUp(self): diff --git a/tests/test_cassandra.py b/tests/checks/mock/test_cassandra.py similarity index 100% rename from tests/test_cassandra.py rename to tests/checks/mock/test_cassandra.py diff --git a/tests/test_couchbase.py b/tests/checks/mock/test_couchbase.py similarity index 98% rename from tests/test_couchbase.py rename to tests/checks/mock/test_couchbase.py index e893238fbc..2f92727ff6 100644 --- a/tests/test_couchbase.py +++ b/tests/checks/mock/test_couchbase.py @@ -1,5 +1,5 @@ import unittest -from tests.common import load_check +from tests.checks.common import load_check from checks import AgentCheck from nose.plugins.attrib import attr diff --git a/tests/test_directory.py b/tests/checks/mock/test_directory.py similarity index 99% rename from tests/test_directory.py rename to tests/checks/mock/test_directory.py index 8e67c00d9e..67dd2dead9 100644 --- a/tests/test_directory.py +++ b/tests/checks/mock/test_directory.py @@ -4,7 +4,7 @@ import shutil -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest class DirectoryTestCase(AgentCheckTest): diff --git a/tests/test_docker.py b/tests/checks/mock/test_docker.py similarity index 98% rename from tests/test_docker.py rename to tests/checks/mock/test_docker.py index 3d1d927b77..14cff8d014 100644 --- a/tests/test_docker.py +++ b/tests/checks/mock/test_docker.py @@ -2,7 +2,7 @@ from mock import patch -from tests.common import get_check_class +from tests.checks.common import get_check_class def _mocked_find_cgroup(*args, **kwargs): return diff --git a/tests/test_dogstatsd.py b/tests/checks/mock/test_dogstatsd.py similarity index 100% rename from tests/test_dogstatsd.py rename to tests/checks/mock/test_dogstatsd.py diff --git a/tests/test_ganglia.py b/tests/checks/mock/test_ganglia.py similarity index 83% rename from tests/test_ganglia.py rename to tests/checks/mock/test_ganglia.py index ff15cec58b..38d4fa9496 100644 --- a/tests/test_ganglia.py +++ b/tests/checks/mock/test_ganglia.py @@ -7,19 +7,19 @@ import profile import pstats import tempfile -from util import json, md5 import time import xml.etree.ElementTree as tree from cStringIO import StringIO from checks.ganglia import Ganglia +from tests.checks.common import Fixtures -TEST_FN = "tests/ganglia.txt" class TestGanglia(unittest.TestCase): def testSpeed(self): # Pretend to be gmetad and serve a large piece of content - server = subprocess.Popen("nc -l 8651 < %s" % TEST_FN, shell=True) + original_file = Fixtures.file('ganglia.txt') + server = subprocess.Popen("nc -l 8651 < %s" % original_file, shell=True) # Wait for 1 second time.sleep(1) @@ -30,7 +30,7 @@ def testSpeed(self): # p = pstats.Stats(pfile.name) # p.sort_stats('time').print_stats() parsed = StringIO(g.check({'ganglia_host': 'localhost', 'ganglia_port': 8651})) - original = open(TEST_FN) + original = Fixtures.file('ganglia.txt') x1 = tree.parse(parsed) x2 = tree.parse(original) # Cursory test diff --git a/tests/test_go_expvar.py b/tests/checks/mock/test_go_expvar.py similarity index 81% rename from tests/test_go_expvar.py rename to tests/checks/mock/test_go_expvar.py index b98fe82d9b..842fcfde5d 100644 --- a/tests/test_go_expvar.py +++ b/tests/checks/mock/test_go_expvar.py @@ -1,12 +1,9 @@ from collections import defaultdict import copy -from nose.plugins.attrib import attr -import os.path import simplejson as json import time - -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest, Fixtures def _get_data_mock(url): @@ -44,8 +41,6 @@ class TestGoExpVar(AgentCheckTest): 'go_expvar.memstats.by_size.1.mallocs': [] } - CHECK_GAUGES_CUSTOM = {'go_expvar.last_user': '123456'} - CHECK_RATES = [ 'go_expvar.memstats.frees', 'go_expvar.memstats.lookups', @@ -56,11 +51,9 @@ class TestGoExpVar(AgentCheckTest): CHECK_RATES_CUSTOM_MOCK = ['go_expvar.gc.pause'] - CHECK_RATES_CUSTOM = {'go_expvar.num_calls': 0} - def __init__(self, *args, **kwargs): AgentCheckTest.__init__(self, *args, **kwargs) - self._expvar_url = os.path.join(os.path.dirname(__file__), "go_expvar", "expvar_output") + self._expvar_url = Fixtures.file('expvar_output') self.mock_config = { "instances": [{ "expvar_url": self._expvar_url, @@ -103,11 +96,11 @@ def __init__(self, *args, **kwargs): }] } - def _run_check_twice(self, mock=False): + def _run_check_twice(self): # To avoid the disparition of some gauges during the second check - mocks = self.mocks.copy() if mock else {} - config = self.mock_config if mock else self.config - expvar_url = self._expvar_url if mock else self.config['instances'][0]['expvar_url'] + mocks = self.mocks.copy() + config = self.mock_config + expvar_url = self._expvar_url fake_last_gc_count = defaultdict(int) mocks['_last_gc_count'] = fake_last_gc_count @@ -121,7 +114,7 @@ def _run_check_twice(self, mock=False): self.run_check(config, mocks=mocks) def test_go_expvar_mocked(self): - self._run_check_twice(mock=True) + self._run_check_twice() shared_tags = ['optionaltag1', 'optionaltag2', 'expvar_url:{0}'.format(self._expvar_url)] @@ -201,25 +194,3 @@ def test_deep_get(self): results = self.check.deep_get(content, ['list', '.*', 'value'], []) self.assertEqual(sorted(results), sorted(expected)) - - # Real integration test - @attr(requires='go_expvar') - def test_go_expvar(self): - self._run_check_twice() - - shared_tags = [ - 'my_tag', - 'expvar_url:{0}'.format(self.config['instances'][0]['expvar_url']) - ] - - for gauge in self.CHECK_GAUGES + self.CHECK_GAUGES_DEFAULT: - self.assertMetric(gauge, count=1, tags=shared_tags) - for rate in self.CHECK_RATES: - self.assertMetric(rate, count=1, tags=shared_tags) - - for gauge, value in self.CHECK_GAUGES_CUSTOM.iteritems(): - self.assertMetric(gauge, count=1, value=value, tags=shared_tags) - for rate, value in self.CHECK_RATES_CUSTOM.iteritems(): - self.assertMetric(rate, count=1, value=value, tags=shared_tags) - - self.coverage_report() diff --git a/tests/test_iis.py b/tests/checks/mock/test_iis.py similarity index 99% rename from tests/test_iis.py rename to tests/checks/mock/test_iis.py index aee530dc95..aa1c494651 100644 --- a/tests/test_iis.py +++ b/tests/checks/mock/test_iis.py @@ -2,7 +2,7 @@ # project from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest Win32_PerfFormattedData_W3SVC_WebService_attr = { diff --git a/tests/test_java_jmx.py b/tests/checks/mock/test_java_jmx.py similarity index 98% rename from tests/test_java_jmx.py rename to tests/checks/mock/test_java_jmx.py index 205c567eda..c6d0c5b945 100644 --- a/tests/test_java_jmx.py +++ b/tests/checks/mock/test_java_jmx.py @@ -12,7 +12,7 @@ from dogstatsd import Server from util import PidFile from jmxfetch import JMXFetch -from common import AgentCheckTest +from tests.checks.common import AgentCheckTest # 3rd party import yaml diff --git a/tests/test_jenkins.py b/tests/checks/mock/test_jenkins.py similarity index 99% rename from tests/test_jenkins.py rename to tests/checks/mock/test_jenkins.py index a116d240e1..8c82c0b232 100644 --- a/tests/test_jenkins.py +++ b/tests/checks/mock/test_jenkins.py @@ -7,7 +7,7 @@ import logging import xml.etree.ElementTree as ET -from tests.common import get_check +from tests.checks.common import get_check logger = logging.getLogger(__file__) diff --git a/tests/test_nagios.py b/tests/checks/mock/test_nagios.py similarity index 98% rename from tests/test_nagios.py rename to tests/checks/mock/test_nagios.py index e278e424b4..d0bcd8f624 100644 --- a/tests/test_nagios.py +++ b/tests/checks/mock/test_nagios.py @@ -1,18 +1,16 @@ # stdlib -import os import tempfile import time # project -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest, Fixtures class NagiosTestCase(AgentCheckTest): CHECK_NAME = 'nagios' - - NAGIOS_TEST_LOG = os.path.join(os.path.dirname(__file__), "nagios.log") - NAGIOS_TEST_HOST = os.path.join(os.path.dirname(__file__), "host-perfdata") - NAGIOS_TEST_SVC = os.path.join(os.path.dirname(__file__), "service-perfdata") + NAGIOS_TEST_LOG = Fixtures.file('nagios.log') + NAGIOS_TEST_HOST = Fixtures.file('host-perfdata') + NAGIOS_TEST_SVC = Fixtures.file('service-perfdata') NAGIOS_TEST_HOST_TEMPLATE = "[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$" NAGIOS_TEST_SVC_TEMPLATE = "[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$" diff --git a/tests/test_postfix.py b/tests/checks/mock/test_postfix.py similarity index 98% rename from tests/test_postfix.py rename to tests/checks/mock/test_postfix.py index deda2b8f19..109bde53ce 100644 --- a/tests/test_postfix.py +++ b/tests/checks/mock/test_postfix.py @@ -1,4 +1,4 @@ -from common import get_check +from tests.checks.common import get_check from random import shuffle, sample import unittest diff --git a/tests/test_process.py b/tests/checks/mock/test_process.py similarity index 99% rename from tests/test_process.py rename to tests/checks/mock/test_process.py index 0df6b6284b..67d6ac4321 100644 --- a/tests/test_process.py +++ b/tests/checks/mock/test_process.py @@ -2,7 +2,7 @@ from nose.plugins.attrib import attr from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest @attr('process') diff --git a/tests/test_riakcs.py b/tests/checks/mock/test_riakcs.py similarity index 80% rename from tests/test_riakcs.py rename to tests/checks/mock/test_riakcs.py index ee5b9c1466..88faf91738 100644 --- a/tests/test_riakcs.py +++ b/tests/checks/mock/test_riakcs.py @@ -1,12 +1,14 @@ import unittest -from tests.common import load_check, read_data_from_file, AgentCheckTest +from tests.checks.common import load_check, Fixtures, AgentCheckTest from mock import Mock from socket import error from checks import AgentCheck + class RiakCSTest(AgentCheckTest): CHECK_NAME = "riakcs" + def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) self.config = {"instances": [{ @@ -14,20 +16,20 @@ def __init__(self, *args, **kwargs): "access_secret": "bar"}]} self.check = load_check(self.CHECK_NAME, self.config, {}) self.check._connect = Mock(return_value=(None, None, ["aggregation_key:localhost:8080"])) - self.check._get_stats = Mock(return_value=self.check.load_json(read_data_from_file("riakcs_in.json"))) + self.check._get_stats = Mock(return_value=self.check.load_json( + Fixtures.read_file('riakcs_in.json'))) def test_parser(self): - input_json = read_data_from_file("riakcs_in.json") - output_python = read_data_from_file("riakcs_out.python") + input_json = Fixtures.read_file('riakcs_in.json') + output_python = Fixtures.read_file('riakcs_out.python') self.assertEquals(self.check.load_json(input_json), eval(output_python)) def test_metrics(self): self.run_check(self.config) - expected = eval(read_data_from_file("riakcs_metrics.python")) + expected = eval(Fixtures.read_file('riakcs_metrics.python')) for m in expected: self.assertMetric(m[0], m[2], m[3].get('tags', [])) - def test_service_checks(self): self.check = load_check(self.CHECK_NAME, self.config, {}) self.assertRaises(error, lambda: self.run_check(self.config)) diff --git a/tests/test_solr.py b/tests/checks/mock/test_solr.py similarity index 95% rename from tests/test_solr.py rename to tests/checks/mock/test_solr.py index 34d9ba39aa..6ca8e75a74 100644 --- a/tests/test_solr.py +++ b/tests/checks/mock/test_solr.py @@ -8,6 +8,8 @@ import os from jmxfetch import JMXFetch +from tests.checks.common import Fixtures + STATSD_PORT = 8127 @@ -21,7 +23,6 @@ def __init__(self, metrics_aggregator): self.finished = False self.start() - def run(self): while not self.finished: time.sleep(self.interval) @@ -32,6 +33,7 @@ def flush(self): if metrics: self.metrics = metrics + @attr(requires='solr') class JMXTestCase(unittest.TestCase): def setUp(self): @@ -43,7 +45,7 @@ def setUp(self): self.t1 = threading.Thread(target=self.server.start) self.t1.start() - confd_path = os.path.realpath(os.path.join(os.path.abspath(__file__), "..", "jmx_yamls")) + confd_path = Fixtures.directory() self.jmx_daemon = JMXFetch(confd_path, {'dogstatsd_port': STATSD_PORT}) self.t2 = threading.Thread(target=self.jmx_daemon.run) self.t2.start() @@ -53,7 +55,6 @@ def tearDown(self): self.reporter.finished = True self.jmx_daemon.terminate() - def testTomcatMetrics(self): count = 0 while self.reporter.metrics is None: @@ -64,7 +65,6 @@ def testTomcatMetrics(self): metrics = self.reporter.metrics - self.assertTrue(type(metrics) == type([])) self.assertTrue(len(metrics) > 8, metrics) self.assertEquals(len([t for t in metrics if 'instance:solr_instance' in t['tags'] and t['metric'] == "jvm.thread_count"]), 1, metrics) diff --git a/tests/test_sqlserver.py b/tests/checks/mock/test_sqlserver.py similarity index 98% rename from tests/test_sqlserver.py rename to tests/checks/mock/test_sqlserver.py index f413c26725..b8717d08ca 100644 --- a/tests/test_sqlserver.py +++ b/tests/checks/mock/test_sqlserver.py @@ -2,7 +2,7 @@ import logging from nose.plugins.attrib import attr -from tests.common import get_check +from tests.checks.common import get_check logging.basicConfig() diff --git a/tests/test_supervisord.py b/tests/checks/mock/test_supervisord.py similarity index 90% rename from tests/test_supervisord.py rename to tests/checks/mock/test_supervisord.py index a1c35a109b..fbcbe24709 100644 --- a/tests/test_supervisord.py +++ b/tests/checks/mock/test_supervisord.py @@ -1,14 +1,11 @@ -import os from socket import socket -from time import sleep from mock import patch -from nose.plugins.attrib import attr import unittest import xmlrpclib from checks import AgentCheck -from tests.common import get_check +from tests.checks.common import get_check class TestSupervisordCheck(unittest.TestCase): @@ -225,41 +222,6 @@ def test_check(self): self.assert_service_checks(expected_service_checks, check.get_service_checks()) - @attr(requires='supervisord') - def test_travis_supervisord(self): - """Integration test for supervisord check. Using a supervisord on Travis.""" - - # Load yaml config - config_str = open(os.environ['VOLATILE_DIR'] + '/supervisor/supervisord.yaml', 'r').read() - self.assertTrue(config_str is not None and len(config_str) > 0, msg=config_str) - - # init the check and get the instances - check, instances = get_check('supervisord', config_str) - self.assertTrue(check is not None, msg=check) - self.assertEquals(len(instances), 1) - - # Supervisord should run 3 programs for 30, 60 and 90 seconds - # respectively. The tests below will ensure that the process count - # metric is reported correctly after (roughly) 10, 40, 70 and 100 seconds - for i in range(4): - try: - # Run the check - check.check(instances[0]) - except Exception, e: - # Make sure that it ran successfully - self.assertTrue(False, msg=str(e)) - else: - up, down = 0, 0 - for name, timestamp, value, meta in check.get_metrics(): - if name == 'supervisord.process.count': - if 'status:up' in meta['tags']: - up = value - elif 'status:down' in meta['tags']: - down = value - self.assertEquals(up, 3 - i) - self.assertEquals(down, i) - sleep(10) - # Unit Tests ########################################################### def test_build_message(self): @@ -469,4 +431,4 @@ def _validate_request(self, proc=None): 'Unauthorized', None) elif proc is not None and 'invalid' in proc: # Simulate xmlrpc exception for process not found - raise xmlrpclib.Fault(10, 'BAD_NAME') \ No newline at end of file + raise xmlrpclib.Fault(10, 'BAD_NAME') diff --git a/tests/test_system.py b/tests/checks/mock/test_sysstat.py similarity index 95% rename from tests/test_system.py rename to tests/checks/mock/test_sysstat.py index 636d5b85f6..9182b825a7 100644 --- a/tests/test_system.py +++ b/tests/checks/mock/test_sysstat.py @@ -1,7 +1,5 @@ import unittest -from nose.plugins.attrib import attr import logging -import os import sys logging.basicConfig(level=logging.DEBUG) @@ -9,9 +7,10 @@ from util import Platform from checks.system.unix import * -from common import get_check +from tests.checks.common import get_check from config import get_system_stats + class TestSystem(unittest.TestCase): def testUptime(self): @@ -21,15 +20,6 @@ def testUptime(self): self.assertTrue("system.uptime" in metrics) self.assertTrue(metrics["system.uptime"] > 0) - @attr(requires='sysstat') - def testCPU(self): - global logger - logger.info(os.environ['PATH']) - cpu = Cpu(logger) - res = cpu.check({}) - # Make sure we sum up to 100% (or 99% in the case of macs) - assert abs(reduce(lambda a,b:a+b, res.values(), 0) - 100) <= 5, res - def testLoad(self): global logger load = Load(logger) @@ -52,7 +42,7 @@ def testLoad(self): map auto_home 0 0 0 100% 0 0 100% /home localhost:/KJDS7Bgpbp1QglL9lBwOe6 487932936 487932936 0 100% 0 0 100% /Volumes/MobileBackups /dev/disk2s1 62309376 5013120 57296256 9% 0 0 100% /Volumes/NO name""" - + lion_df_k = """Filesystem 1024-blocks Used Available Capacity Mounted onto /dev/disk1 243966468 110040020 133670448 46% / devfs 187 187 0 100% /dev @@ -139,7 +129,7 @@ def testDfParser(self): assert res[3][:4] == ["/data2", 52403200, 40909112, 11494088], res[3] assert res[4][:4] == ["/data3", 52403200, 40909112, 11494088], res[4] assert res[-1][:4] == ["/var/lib/postgresql/9.1/index05", 31441920, 3519356, 27922564], res[-1] - + def test_collecting_disk_metrics(self): """Testing disk stats gathering""" if Platform.is_unix(): @@ -214,10 +204,10 @@ def testDiskLatency(self): # iostat -o -d -c 2 -w 1 # OS X 10.8.3 (internal SSD + USB flash attached) - darwin_iostat_output = """ disk0 disk1 - KB/t tps MB/s KB/t tps MB/s - 21.11 23 0.47 20.01 0 0.00 - 6.67 3 0.02 0.00 0 0.00 + darwin_iostat_output = """ disk0 disk1 + KB/t tps MB/s KB/t tps MB/s + 21.11 23 0.47 20.01 0 0.00 + 6.67 3 0.02 0.00 0 0.00 """ checker = IO(logger) results = checker._parse_darwin(darwin_iostat_output) @@ -262,6 +252,3 @@ def testNetwork(self): assert 'system.net.tcp.sent_packs' in metric_names assert 'system.net.tcp.rcv_packs' in metric_names - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_system_core.py b/tests/checks/mock/test_system_core.py similarity index 98% rename from tests/test_system_core.py rename to tests/checks/mock/test_system_core.py index 0ee44ba9e3..2a84c61e55 100644 --- a/tests/test_system_core.py +++ b/tests/checks/mock/test_system_core.py @@ -1,7 +1,7 @@ import mock import psutil -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest from util import Platform if Platform.is_mac(): diff --git a/tests/test_system_swap.py b/tests/checks/mock/test_system_swap.py similarity index 94% rename from tests/test_system_swap.py rename to tests/checks/mock/test_system_swap.py index e0b511a9bd..878387adac 100644 --- a/tests/test_system_swap.py +++ b/tests/checks/mock/test_system_swap.py @@ -1,6 +1,6 @@ import mock -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest class _PSUtilSwapStatsMock(object): def __init__(self, sin, sout): diff --git a/tests/test_teamcity.py b/tests/checks/mock/test_teamcity.py similarity index 98% rename from tests/test_teamcity.py rename to tests/checks/mock/test_teamcity.py index 13f6701476..995aa0516f 100644 --- a/tests/test_teamcity.py +++ b/tests/checks/mock/test_teamcity.py @@ -5,7 +5,7 @@ from mock import MagicMock, patch # project -from tests.common import load_check +from tests.checks.common import load_check CONFIG = { 'init_config': {}, diff --git a/tests/test_win32_event_log.py b/tests/checks/mock/test_win32_event_log.py similarity index 98% rename from tests/test_win32_event_log.py rename to tests/checks/mock/test_win32_event_log.py index 3e34afeb45..45d66d171f 100644 --- a/tests/test_win32_event_log.py +++ b/tests/checks/mock/test_win32_event_log.py @@ -2,7 +2,7 @@ import logging from nose.plugins.attrib import attr -from tests.common import get_check +from tests.checks.common import get_check logging.basicConfig() diff --git a/tests/test_windows_service.py b/tests/checks/mock/test_windows_service.py similarity index 98% rename from tests/test_windows_service.py rename to tests/checks/mock/test_windows_service.py index d003cb1de7..5cb5380d5b 100644 --- a/tests/test_windows_service.py +++ b/tests/checks/mock/test_windows_service.py @@ -3,7 +3,7 @@ # project from checks import AgentCheck -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest WinHttpAutoProxySvc_attr = { # Running Windows Service diff --git a/tests/test_wmi.py b/tests/checks/mock/test_wmi_check.py similarity index 99% rename from tests/test_wmi.py rename to tests/checks/mock/test_wmi_check.py index c28fb20b56..8fdbed4379 100644 --- a/tests/test_wmi.py +++ b/tests/checks/mock/test_wmi_check.py @@ -1,5 +1,5 @@ # project -from tests.common import AgentCheckTest +from tests.checks.common import AgentCheckTest Win32_OperatingSystem_attr = { diff --git a/tests/core/__init__.py b/tests/core/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/performance/benchmark_aggregator.py b/tests/core/benchmark_aggregator.py similarity index 100% rename from tests/performance/benchmark_aggregator.py rename to tests/core/benchmark_aggregator.py diff --git a/tests/core/fixtures/__init__.py b/tests/core/fixtures/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/badconfig.conf b/tests/core/fixtures/badconfig.conf similarity index 100% rename from tests/badconfig.conf rename to tests/core/fixtures/badconfig.conf diff --git a/tests/flare/datadog-agent-1.tar.bz2 b/tests/core/fixtures/flare/datadog-agent-1.tar.bz2 similarity index 100% rename from tests/flare/datadog-agent-1.tar.bz2 rename to tests/core/fixtures/flare/datadog-agent-1.tar.bz2 diff --git a/tests/target_module.py b/tests/core/fixtures/target_module.py similarity index 100% rename from tests/target_module.py rename to tests/core/fixtures/target_module.py diff --git a/tests/test_autorestart.py b/tests/core/test_autorestart.py similarity index 97% rename from tests/test_autorestart.py rename to tests/core/test_autorestart.py index 375178678c..0b0e74066f 100644 --- a/tests/test_autorestart.py +++ b/tests/core/test_autorestart.py @@ -1,14 +1,10 @@ import time import unittest -import logging import subprocess import shlex import os import signal -from nose.plugins.skip import SkipTest - -from daemon import AgentSupervisor class TestAutoRestart(unittest.TestCase): """ Test the auto-restart and forking of the agent """ diff --git a/tests/test_bucket_aggregator.py b/tests/core/test_bucket_aggregator.py similarity index 100% rename from tests/test_bucket_aggregator.py rename to tests/core/test_bucket_aggregator.py diff --git a/tests/test_check_status.py b/tests/core/test_check_status.py similarity index 98% rename from tests/test_check_status.py rename to tests/core/test_check_status.py index c6e0079f4b..68931b5f3f 100644 --- a/tests/test_check_status.py +++ b/tests/core/test_check_status.py @@ -11,34 +11,34 @@ def check(self, instance): raise Exception("failure") - def test_check_status_fail(): instances = [ {'pass':True}, {'pass':False}, {'pass':True} ] - + check = DummyAgentCheck('dummy_agent_check', {}, {}, instances) instance_statuses = check.run() assert len(instance_statuses) == 3 assert instance_statuses[0].status == STATUS_OK assert instance_statuses[1].status == STATUS_ERROR assert instance_statuses[2].status == STATUS_OK - + def test_check_status_pass(): instances = [ {'pass':True}, {'pass':True}, ] - + check = DummyAgentCheck('dummy_agent_check', {}, {}, instances) instances_status = check.run() assert len(instances_status) == 2 for i in instances_status: assert i.status == STATUS_OK + def test_persistence(): i1 = InstanceStatus(1, STATUS_OK) chk1 = CheckStatus("dummy", [i1], 1, 2) @@ -53,6 +53,7 @@ def test_persistence(): assert chk2.metric_count == 1 assert chk2.event_count == 2 + def test_persistence_fail(): # Assert remove doesn't crap out if a file doesn't exist. diff --git a/tests/test_common.py b/tests/core/test_common.py similarity index 99% rename from tests/test_common.py rename to tests/core/test_common.py index 35ce50aeb4..b080157306 100644 --- a/tests/test_common.py +++ b/tests/core/test_common.py @@ -11,16 +11,16 @@ AgentCheck, Check, CheckException, - CheckException, Infinity, UnknownValue, ) from checks.collector import Collector -from tests.common import load_check +from tests.checks.common import load_check from util import get_hostname logger = logging.getLogger() + class TestCore(unittest.TestCase): "Tests to validate the core check logic" @@ -193,7 +193,7 @@ def test_no_proxy(self): from requests.utils import get_environ_proxies import dogstatsd from os import environ as env - + env["http_proxy"] = "http://localhost:3128" env["https_proxy"] = env["http_proxy"] env["HTTP_PROXY"] = env["http_proxy"] diff --git a/tests/test_config.py b/tests/core/test_config.py similarity index 96% rename from tests/test_config.py rename to tests/core/test_config.py index 87823ae569..bc47475be1 100644 --- a/tests/test_config.py +++ b/tests/core/test_config.py @@ -1,4 +1,4 @@ -## -*- coding: latin-1 -*- +# -*- coding: latin-1 -*- import unittest import os import os.path @@ -8,11 +8,13 @@ from util import PidFile, is_valid_hostname, Platform, windows_friendly_colon_split + class TestConfig(unittest.TestCase): def testWhiteSpaceConfig(self): """Leading whitespace confuse ConfigParser """ - agentConfig = get_config(cfg_path=os.path.join(os.path.dirname(os.path.realpath(__file__)), "badconfig.conf")) + agentConfig = get_config(cfg_path=os.path.join(os.path.dirname(os.path.realpath(__file__)), + 'fixtures', 'badconfig.conf')) self.assertEquals(agentConfig["dd_url"], "https://app.datadoghq.com") self.assertEquals(agentConfig["api_key"], "1234") self.assertEquals(agentConfig["nagios_log"], "/var/log/nagios3/nagios.log") diff --git a/tests/test_count_type.py b/tests/core/test_count_type.py similarity index 100% rename from tests/test_count_type.py rename to tests/core/test_count_type.py diff --git a/tests/test_datadog.py b/tests/core/test_datadog.py similarity index 97% rename from tests/test_datadog.py rename to tests/core/test_datadog.py index baaebbf2a4..bb0ffe25f9 100644 --- a/tests/test_datadog.py +++ b/tests/core/test_datadog.py @@ -2,9 +2,8 @@ import unittest from tempfile import NamedTemporaryFile import re -import os -from checks.datadog import Dogstreams, EventDefaults, point_sorter +from checks.datadog import Dogstreams, EventDefaults log = logging.getLogger('datadog.test') @@ -55,7 +54,7 @@ def parse_line(self, line): "RECOVERY": "success" } def parse_events(logger, line): - """ Expecting lines like this: + """ Expecting lines like this: 2012-05-14 12:46:01 [ERROR] - host0 is down (broke its collarbone) """ match = log_event_pattern.match(line) @@ -78,7 +77,7 @@ class TailTestCase(unittest.TestCase): def setUp(self): self.log_file = NamedTemporaryFile() self.logger = logging.getLogger('test.dogstream') - + def _write_log(self, log_data): for data in log_data: print >> self.log_file, data @@ -101,7 +100,7 @@ def setUp(self): log.info("Test config: %s" % self.config) self.dogstream = Dogstreams.init(self.logger, self.config) self.maxDiff = None - + def test_dogstream_gauge(self): log_data = [ # bucket 0 @@ -116,21 +115,21 @@ def test_dogstream_gauge(self): ('test.metric.a', '1000000006', '7', 'metric_type=gauge'), ('test.metric.a', '1000000007', '8', 'metric_type=gauge'), ] - + expected_output = { "dogstream": [ ('test.metric.a', 1000000000, 5.0, self.gauge), ('test.metric.a', 1000000005, 8.0, self.gauge), ] } - + self._write_log((' '.join(data) for data in log_data)) actual_output = self.dogstream.check(self.config, move_end=False) self.assertEquals(expected_output, actual_output) for metric, timestamp, val, attr in expected_output['dogstream']: assert isinstance(val, float) - + def test_dogstream_counter(self): log_data = [ # bucket 0 @@ -145,14 +144,14 @@ def test_dogstream_counter(self): ('test.metric.a', '1000000006', '7', 'metric_type=counter'), ('test.metric.a', '1000000007', '8', 'metric_type=counter'), ] - + expected_output = { "dogstream": [ ('test.metric.a', 1000000000, 42, self.counter), ('test.metric.a', 1000000005, 27, self.counter), ] } - + self._write_log((' '.join(data) for data in log_data)) actual_output = self.dogstream.check(self.config, move_end=False) @@ -170,9 +169,9 @@ def test_dogstream_bad_input(self): expected_output = {"dogstream": [('test_metric.e', 1000000000, 10, self.gauge)] } - + self._write_log(log_data) - + actual_output = self.dogstream.check(self.config, move_end=False) self.assertEquals(expected_output, actual_output) @@ -188,7 +187,7 @@ def test_dogstream_ancient_function_plugin(self): ('test.metric.simple', 1100000000, 1, self.gauge)] } self._write_log(log_data) - plugdog = Dogstreams.init(self.logger, {'dogstreams': '%s:tests.test_datadog:parse_ancient_function_plugin' % self.log_file.name}) + plugdog = Dogstreams.init(self.logger, {'dogstreams': '{0}:{1}:parse_ancient_function_plugin'.format(self.log_file.name, __name__)}) actual_output = plugdog.check(self.config, move_end=False) def test_dogstream_function_plugin(self): @@ -204,7 +203,7 @@ def test_dogstream_function_plugin(self): } self._write_log(log_data) - statedog = Dogstreams.init(self.logger, {'dogstreams': '%s:tests.test_datadog:parse_function_plugin' % self.log_file.name}) + statedog = Dogstreams.init(self.logger, {'dogstreams': '{0}:{1}:parse_function_plugin'.format(self.log_file.name, __name__)}) actual_output = statedog.check(self.config, move_end=False) self.assertEquals(expected_output, actual_output) @@ -221,7 +220,7 @@ def test_dogstream_new_plugin(self): } self._write_log(log_data) - statedog = Dogstreams.init(self.logger, {'dogstreams': '%s:tests.test_datadog:ParseClassPlugin:foo:bar' % self.log_file.name}) + statedog = Dogstreams.init(self.logger, {'dogstreams': '{0}:{1}:ParseClassPlugin:foo:bar'.format(self.log_file.name, __name__)}) actual_output = statedog.check(self.config, move_end=False) self.assertEquals(expected_output, actual_output) @@ -280,10 +279,9 @@ def test_dogstream_events(self): ] } - self._write_log(log_data) - dogstream = Dogstreams.init(self.logger, {'dogstreams': '%s:tests.test_datadog:parse_events' % self.log_file.name}) + dogstream = Dogstreams.init(self.logger, {'dogstreams': '{0}:{1}:parse_events'.format(self.log_file.name, __name__)}) actual_output = dogstream.check(self.config, move_end=False) self.assertEquals(expected_output, actual_output) @@ -317,7 +315,7 @@ def test_dogstream_events_validation(self): self._write_log([repr(d) for d in log_data]) - dogstream = Dogstreams.init(self.logger, {'dogstreams': '%s:tests.test_datadog:repr_event_parser' % self.log_file.name}) + dogstream = Dogstreams.init(self.logger, {'dogstreams': '{0}:{1}:repr_event_parser'.format(self.log_file.name, __name__)}) actual_output = dogstream.check(self.config, move_end=False) self.assertEquals(expected_output, actual_output) diff --git a/tests/test_ec2.py b/tests/core/test_ec2.py similarity index 100% rename from tests/test_ec2.py rename to tests/core/test_ec2.py diff --git a/tests/test_emitter.py b/tests/core/test_emitter.py similarity index 100% rename from tests/test_emitter.py rename to tests/core/test_emitter.py diff --git a/tests/test_flare.py b/tests/core/test_flare.py similarity index 99% rename from tests/test_flare.py rename to tests/core/test_flare.py index 4fdb45871f..26b7fe35cd 100644 --- a/tests/test_flare.py +++ b/tests/core/test_flare.py @@ -18,6 +18,7 @@ def get_mocked_version(): def get_mocked_temp(): return os.path.join( os.path.dirname(os.path.realpath(__file__)), + 'fixtures', 'flare' ) diff --git a/tests/test_histogram.py b/tests/core/test_histogram.py similarity index 100% rename from tests/test_histogram.py rename to tests/core/test_histogram.py diff --git a/tests/test_laconic.py b/tests/core/test_laconic.py similarity index 100% rename from tests/test_laconic.py rename to tests/core/test_laconic.py diff --git a/tests/test_modules.py b/tests/core/test_modules.py similarity index 72% rename from tests/test_modules.py rename to tests/core/test_modules.py index f61963d4a9..e2101e9e8b 100644 --- a/tests/test_modules.py +++ b/tests/core/test_modules.py @@ -7,16 +7,18 @@ log = logging.getLogger('datadog.test') +TARGET_MODULE = 'tests.core.fixtures.target_module' default_target = 'DEFAULT' specified_target = 'SPECIFIED' has_been_mutated = False + class TestModuleLoad(unittest.TestCase): def setUp(self): sys.modules[__name__].has_been_mutated = True - if 'tests.target_module' in sys.modules: - del sys.modules['tests.target_module'] + if TARGET_MODULE in sys.modules: + del sys.modules[TARGET_MODULE] def tearDown(self): sys.modules[__name__].has_been_mutated = False @@ -27,16 +29,16 @@ def test_cached_module(self): def test_cache_population(self): """Python module cache should be populated""" - self.assertTrue(not 'tests.target_module' in sys.modules) - modules.load('tests.target_module') - self.assertTrue('tests.target_module' in sys.modules) + self.assertTrue(TARGET_MODULE not in sys.modules) + modules.load(TARGET_MODULE) + self.assertTrue(TARGET_MODULE in sys.modules) def test_modname_load_default(self): """When the specifier contains no module name, any provided default should be used""" self.assertEquals( modules.load( - 'tests.target_module', + TARGET_MODULE, 'default_target'), 'DEFAULT' ) @@ -46,7 +48,7 @@ def test_modname_load_specified(self): should be overridden""" self.assertEquals( modules.load( - 'tests.target_module:specified_target', + '{0}:specified_target'.format(TARGET_MODULE), 'default_target'), 'SPECIFIED' ) @@ -54,8 +56,9 @@ def test_modname_load_specified(self): def test_pathname_load_finds_package(self): """"Loading modules by absolute path should correctly set the name of the loaded module to include any package containing it.""" - m = modules.load(os.getcwd() + '/tests/target_module.py') - self.assertEquals(m.__name__, 'tests.target_module') + m = modules.load(os.path.join(os.getcwd(), + TARGET_MODULE.replace('.', '/'))) + self.assertEquals(m.__name__, TARGET_MODULE) if __name__ == '__main__': unittest.main() diff --git a/tests/test_service_checks.py b/tests/core/test_service_checks.py similarity index 99% rename from tests/test_service_checks.py rename to tests/core/test_service_checks.py index 72e15a81b9..cbb1dadbec 100644 --- a/tests/test_service_checks.py +++ b/tests/core/test_service_checks.py @@ -1,7 +1,7 @@ from Queue import Empty import unittest import time -from tests.common import load_check +from tests.checks.common import load_check import nose.tools as nt from config import AGENT_VERSION from util import headers as agent_headers diff --git a/tests/test_tail.py b/tests/core/test_tail.py similarity index 100% rename from tests/test_tail.py rename to tests/core/test_tail.py diff --git a/tests/test_transaction.py b/tests/core/test_transaction.py similarity index 100% rename from tests/test_transaction.py rename to tests/core/test_transaction.py diff --git a/tests/test_watchdog.py b/tests/core/test_watchdog.py similarity index 86% rename from tests/test_watchdog.py rename to tests/core/test_watchdog.py index b7b917e815..e89968a69b 100644 --- a/tests/test_watchdog.py +++ b/tests/core/test_watchdog.py @@ -5,12 +5,12 @@ from random import random, randrange import urllib as url import time -from nose.plugins.skip import SkipTest sys.path.append(os.getcwd()) from ddagent import Application from util import Watchdog + class TestWatchdog(unittest.TestCase): """Test watchdog in various conditions """ @@ -23,7 +23,7 @@ def test_watchdog(self): """ start = time.time() try: - subprocess.check_call(["python", "tests/test_watchdog.py", "busy"], stderr=subprocess.STDOUT) + subprocess.check_call(["python", __file__, "busy"], stderr=subprocess.STDOUT) raise Exception("Should have died with an error") except subprocess.CalledProcessError: duration = int(time.time() - start) @@ -33,7 +33,7 @@ def test_watchdog(self): subprocess.Popen(["nc", "-l", "31834"]) start = time.time() try: - subprocess.check_call(["python", "tests/test_watchdog.py", "net"]) + subprocess.check_call(["python", __file__, "net"]) raise Exception("Should have died with an error") except subprocess.CalledProcessError: duration = int(time.time() - start) @@ -42,7 +42,7 @@ def test_watchdog(self): # Normal loop, should run 5 times start = time.time() try: - subprocess.check_call(["python", "tests/test_watchdog.py", "normal"]) + subprocess.check_call(["python", __file__, "normal"]) duration = int(time.time() - start) self.assertTrue(duration < self.JITTER_FACTOR * 5) except subprocess.CalledProcessError: @@ -50,7 +50,7 @@ def test_watchdog(self): # Fast tornado, not killed start = time.time() - p = subprocess.Popen(["python", "tests/test_watchdog.py", "fast"]) + p = subprocess.Popen(["python", __file__, "fast"]) p.wait() duration = int(time.time() - start) # should die as soon as flush_trs has been called @@ -58,30 +58,33 @@ def test_watchdog(self): # Slow tornado, killed by the Watchdog start = time.time() - p = subprocess.Popen(["python", "tests/test_watchdog.py", "slow"]) + p = subprocess.Popen(["python", __file__, "slow"]) p.wait() duration = int(time.time() - start) self.assertTrue(duration < self.JITTER_FACTOR * 4) # Too much memory used, killed by Watchdog start = time.time() - p = subprocess.Popen(["python", "tests/test_watchdog.py", "memory"]) + p = subprocess.Popen(["python", __file__, "memory"]) p.wait() duration = int(time.time() - start) # process should be killed well before the restart interval of 30. assert duration < 20 + class MockTxManager(object): def flush(self): "Pretend to flush for a long time" time.sleep(5) sys.exit(0) + class MemoryHogTxManager(object): def flush(self): rand_data = [] while True: - rand_data.append('%030x' % randrange(256**15)) + rand_data.append('%030x' % randrange(256**15)) + class PseudoAgent(object): """Same logic as the agent, simplified""" @@ -120,7 +123,8 @@ def fast_tornado(self): def use_lots_of_memory(self): # Skip this step on travis - if os.environ.get('TRAVIS', False): return + if os.environ.get('TRAVIS', False): + return a = Application(12345, {"bind_host": "localhost"}) a._watchdog = Watchdog(30, 50) a._tr_manager = MemoryHogTxManager() diff --git a/tests/test_win32.py b/tests/core/test_win32.py similarity index 100% rename from tests/test_win32.py rename to tests/core/test_win32.py diff --git a/tests/functional/dogstatsd_functional.py b/tests/functional/dogstatsd_functional.py deleted file mode 100644 index 996a98d4e3..0000000000 --- a/tests/functional/dogstatsd_functional.py +++ /dev/null @@ -1,13 +0,0 @@ -""" -Functional tests for dogstatsd. -""" - - - - - - - - - -