# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging import platform import re import unittest logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__file__) from common import get_check from monasca_agent.collector.checks.system.unix import Cpu from monasca_agent.collector.checks.system.unix import Disk from monasca_agent.collector.checks.system.unix import IO from monasca_agent.collector.checks.system.unix import Memory class TestSystem(unittest.TestCase): def testCPU(self): global logger 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 lion_df_i = """Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted onto /dev/disk1 487932936 220080040 267340896 46% 27574003 33417612 45% / devfs 374 374 0 100% 648 0 100% /dev map -hosts 0 0 0 100% 0 0 100% /net 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 map -hosts 0 0 0 100% /net map auto_home 0 0 0 100% /home localhost:/KJDS7Bgpbp1QglL9lBwOe6 243966468 243966468 0 100% /Volumes/MobileBackups /dev/disk2s1 31154688 2506560 28648128 9% /Volumes/NO NAME""" linux_df_k = """Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 8256952 5600592 2236932 72% / none 3802316 124 3802192 1% /dev none 3943856 0 3943856 0% /dev/shm none 3943856 148 3943708 1% /var/run none 3943856 0 3943856 0% /var/lock none 3943856 0 3943856 0% /lib/init/rw /dev/sdb 433455904 305360 411132240 1% /mnt /dev/sdf 52403200 40909112 11494088 79% /data nfs:/abc/def/ghi/jkl/mno/pqr 52403200 40909112 11494088 79% /data2 /dev/sdg 52403200 40909112 11494088 79% /data3 tmpfs 14039440 256 14039184 1% /run /dev/xvdf1 209612800 144149992 65462808 69% /var/lib/postgresql/9.1/main /dev/xvdf2 209612800 2294024 207318776 2% /var/lib/postgresql/9.1/main/pg_xlog /dev/xvdf3 2086912 1764240 322672 85% /var/lib/postgresql/9.1/user_influence_history /dev/xvdf4 41922560 12262780 29659780 30% /var/lib/postgresql/9.1/entity_love /dev/xvdf5 10475520 3943856 6531664 38% /var/lib/postgresql/9.1/user_profile /dev/xvdf6 10475520 5903964 4571556 57% /var/lib/postgresql/9.1/entity_love_history /dev/xvdf7 8378368 33288 8345080 1% /var/lib/postgresql/9.1/_user_profile_queue /dev/xvdf8 41922560 6784964 35137596 17% /var/lib/postgresql/9.1/entity_entity /dev/xvdf9 2086912 33480 2053432 2% /var/lib/postgresql/9.1/event_framework_event_handler_queue /dev/xvdi1 2086912 33488 2053424 2% /var/lib/postgresql/9.1/user_communication_queue /dev/xvdi2 52403200 9960744 42442456 20% /var/lib/postgresql/9.1/affiliate_click_tracking /dev/xvdi3 31441920 9841092 21600828 32% /var/lib/postgresql/9.1/index01 /dev/xvdi4 31441920 10719884 20722036 35% /var/lib/postgresql/9.1/index02 /dev/xvdi5 31441920 9096476 22345444 29% /var/lib/postgresql/9.1/index03 /dev/xvdi6 31441920 6473916 24968004 21% /var/lib/postgresql/9.1/index04 /dev/xvdi7 31441920 3519356 27922564 12% /var/lib/postgresql/9.1/index05 """ linux_df_i = """Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda1 524288 171642 352646 33% / none 950579 2019 948560 1% /dev none 985964 1 985963 1% /dev/shm none 985964 66 985898 1% /var/run none 985964 3 985961 1% /var/lock none 985964 1 985963 1% /lib/init/rw /dev/sdb 27525120 147 27524973 1% /mnt /dev/sdf 46474080 478386 45995694 2% /data """ def testDfParser(self): global logger disk = Disk(logger) res = disk.parse_df_output(TestSystem.lion_df_k, 'darwin') assert res[0][:4] == ["/dev/disk1", 243966468, 110040020, 133670448], res[0] assert res[3][:4] == ["/dev/disk2s1", 31154688, 2506560, 28648128], res[3] res = disk.parse_df_output(TestSystem.lion_df_i, 'darwin', inodes=True) assert res[0][:4] == ["/dev/disk1", 60991615, 27574003, 33417612], res[0] # Test parsing linux output. res = disk.parse_df_output(TestSystem.linux_df_k, 'linux2') assert len(res) == 22 assert res[0][:4] == ["/dev/sda1", 8256952, 5600592, 2236932], res[0] assert res[2][:4] == ["/dev/sdf", 52403200, 40909112, 11494088], res[2] assert res[3][:4] == ["nfs:/abc/def/ghi/jkl/mno/pqr", 52403200, 40909112, 11494088], res[3] assert res[4][:4] == ["/dev/sdg", 52403200, 40909112, 11494088], res[4] # Test parsing linux output but filter some of the nodes. blacklist_re = re.compile('/dev/xvdi.*') res = disk.parse_df_output(TestSystem.linux_df_k, 'linux2', blacklist_re=blacklist_re) assert res[0][:4] == ["/dev/sda1", 8256952, 5600592, 2236932], res[0] assert len(res) == 15, len(res) res = disk.parse_df_output(TestSystem.linux_df_i, 'linux2', inodes=True) assert res[0][:4] == ["/dev/sda1", 524288, 171642, 352646], res[0] assert res[1][:4] == ["/dev/sdb", 27525120, 147, 27524973], res[1] assert res[2][:4] == ["/dev/sdf", 46474080, 478386, 45995694], res[2] res = disk.parse_df_output(TestSystem.linux_df_k, 'linux2', use_mount=True) assert res[0][:4] == ["/", 8256952, 5600592, 2236932], res[0] assert res[2][:4] == ["/data", 52403200, 40909112, 11494088], res[2] 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.system() == 'Linux': disk = Disk(logger, {}) res = disk.check() # Assert we have disk & inode stats assert len(res) == 2 assert list(res.keys())[0] assert list(res.keys())[1] def testMemory(self): global logger res = Memory(logger).check() if platform.system() == 'Linux': for k in ( "swapTotal", "swapFree", "swapPctFree", "swapUsed", "physTotal", "physFree", "physUsed", "physBuffers", "physCached", "physUsable", "physPctUsable", "physShared"): assert k in res, res assert res["swapTotal"] == res["swapFree"] + res["swapUsed"] assert res["physTotal"] == res["physFree"] + res["physUsed"] elif platform.system() == 'Darwin': for k in ("swapFree", "swapUsed", "physFree", "physUsed"): assert k in res, res def testDiskLatency(self): # example output from `iostat -d 1 2 -x -k` on # debian testing x86_64, from Debian package # sysstat@10.0.4-1 debian_iostat_output = """Linux 3.2.0-2-amd64 (fireflyvm) 05/29/2012 _x86_64_ (2 CPU) Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.44 2.58 5.79 2.84 105.53 639.03 172.57 0.17 19.38 1.82 55.26 0.66 0.57 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 """ global logger checker = IO(logger) results = checker._parse_linux2(debian_iostat_output) self.assertTrue('sda' in results) for key in ( 'io_read_req_sec', 'io_write_req_sec', 'io_read_kbytes_sec', 'io_write_kbytes_sec'): self.assertTrue(key in results['sda'], 'key %r not in results["sda"]' % key) self.assertEqual(results['sda'][key], '0.00') # example output from `iostat -d 1 d -x -k` on # centos 5.8 x86_64, from RPM package # sysstat@7.0.2; it differs from the above by # not having split-out r_await and w_await fields centos_iostat_output = """Linux 2.6.18-308.el5 (localhost.localdomain) 05/29/2012 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util sda 9.44 7.56 16.76 4.40 322.05 47.75 34.96 0.01 0.59 0.35 0.74 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 """ checker = IO(logger) results = checker._parse_linux2(centos_iostat_output) self.assertTrue('sda' in results) for key in ( 'io_read_req_sec', 'io_write_req_sec', 'io_read_kbytes_sec', 'io_write_kbytes_sec'): self.assertTrue(key in results['sda'], 'key %r not in results["sda"]' % key) self.assertEqual(results['sda'][key], '0.00') # 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 """ checker = IO(logger) results = checker._parse_darwin(darwin_iostat_output) self.assertTrue("disk0" in results.keys()) self.assertTrue("disk1" in results.keys()) self.assertEqual( results["disk0"], {'system.io.bytes_per_s': float(0.02 * 10 ** 6), } ) self.assertEqual( results["disk1"], {'system.io.bytes_per_s': float(0), } ) def testNetwork(self): config = """ init_config: instances: - collect_connection_state: true excluded_interfaces: - lo - lo0 """ check, instances = get_check('network', config) check.check(instances[0]) check.get_metrics() metric_names = [m[0] for m in check.aggregator.metrics] assert 'net_bytes_in' in metric_names assert 'net_bytes_out' in metric_names if __name__ == "__main__": unittest.main()