sysinfo_test.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. # Copyright (C) 2012 Internet Systems Consortium.
  2. #
  3. # Permission to use, copy, modify, and distribute this software for any
  4. # purpose with or without fee is hereby granted, provided that the above
  5. # copyright notice and this permission notice appear in all copies.
  6. #
  7. # THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
  8. # DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
  9. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  10. # INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
  12. # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  13. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  14. # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. from isc.sysinfo import *
  16. import os
  17. import unittest
  18. import platform
  19. import subprocess
  20. import time
  21. def _my_testcase_platform_system():
  22. return 'BIND10Testcase'
  23. def _my_linux_platform_system():
  24. return 'Linux'
  25. def _my_linux_os_sysconf(key):
  26. if key == 'SC_NPROCESSORS_CONF':
  27. return 42
  28. assert False, 'Unhandled key'
  29. class MyLinuxFile:
  30. def __init__(self, filename):
  31. self._filename = filename
  32. def read(self):
  33. if self._filename == '/proc/sys/kernel/hostname':
  34. return 'myhostname'
  35. elif self._filename == '/proc/version':
  36. return 'An SMP version string'
  37. elif self._filename == '/proc/uptime':
  38. return '86400.75 139993.71'
  39. elif self._filename == '/proc/loadavg':
  40. return '0.1 0.2 0.3 0.4'
  41. else:
  42. assert False, 'Unhandled filename'
  43. def readlines(self):
  44. if self._filename == '/proc/meminfo':
  45. return ['MemTotal: 3083872 kB',
  46. 'MemFree: 870492 kB',
  47. 'Buffers: 27412 kB',
  48. 'Cached: 1303860 kB',
  49. 'SwapTotal: 4194300 kB',
  50. 'SwapFree: 3999464 kB']
  51. else:
  52. assert False, 'Unhandled filename'
  53. def close(self):
  54. return
  55. def __enter__(self):
  56. return self
  57. def __exit__(self, type, value, traceback):
  58. return
  59. def _my_linux_open(filename):
  60. return MyLinuxFile(filename)
  61. def _my_linux_subprocess_check_output(command):
  62. assert type(command) == list, 'command argument is not a list'
  63. if command == ['lsb_release', '-a']:
  64. return b'Description: My Distribution\n'
  65. elif command == ['ip', 'addr']:
  66. return b'qB2osV6vUOjqm3P/+tQ4d92xoYz8/U8P9v3KWRpNwlI=\n'
  67. elif command == ['ip', 'route']:
  68. return b'VGWAS92AlS14Pl2xqENJs5P2Ihe6Nv9g181Mu6Zz+aQ=\n'
  69. elif command == ['ip', '-f', 'inet6', 'route']:
  70. return b'XfizswwNA9NkXz6K36ZExpjV08Y5IXkHI8jjDSV+5Nc=\n'
  71. elif command == ['netstat', '-s']:
  72. return b'osuxbrcc1g9VgaF4yf3FrtfodrfATrbSnjhqhuQSAs8=\n'
  73. elif command == ['netstat', '-apn']:
  74. return b'Z+w0lwa02/T+5+EIio84rrst/Dtizoz/aL9Im7J7ESA=\n'
  75. else:
  76. assert False, 'Unhandled command'
  77. def _my_openbsd_platform_system():
  78. return 'OpenBSD'
  79. def _my_openbsd_os_sysconf(key):
  80. if key == 'SC_NPROCESSORS_CONF':
  81. return 53
  82. assert False, 'Unhandled key'
  83. def _my_openbsd_subprocess_check_output(command):
  84. assert type(command) == list, 'command argument is not a list'
  85. if command == ['hostname']:
  86. return b'blowfish.example.com\n'
  87. elif command == ['sysctl', '-n', 'kern.boottime']:
  88. return bytes(str(int(time.time() - 76632)), 'utf-8')
  89. elif command == ['sysctl', '-n', 'vm.loadavg']:
  90. return b'0.7 0.9 0.8'
  91. elif command == ['sysctl', '-n', 'hw.physmem']:
  92. return b'543214321'
  93. elif command == ['vmstat']:
  94. return b' procs memory page disks traps cpu\n r b w avm fre flt re pi po fr sr wd0 cd0 int sys cs us sy id\n 0 0 0 121212 123456 47 0 0 0 0 0 2 0 2 80 14 0 1 99\n'
  95. elif command == ['swapctl', '-s', '-k']:
  96. return b'total: 553507 1K-blocks allocated, 2 used, 553505 available'
  97. elif command == ['ifconfig']:
  98. return b'qB2osV6vUOjqm3P/+tQ4d92xoYz8/U8P9v3KWRpNwlI=\n'
  99. elif command == ['route', '-n', 'show']:
  100. return b'XfizswwNA9NkXz6K36ZExpjV08Y5IXkHI8jjDSV+5Nc=\n'
  101. elif command == ['netstat', '-s']:
  102. return b'osuxbrcc1g9VgaF4yf3FrtfodrfATrbSnjhqhuQSAs8=\n'
  103. elif command == ['netstat', '-an']:
  104. return b'Z+w0lwa02/T+5+EIio84rrst/Dtizoz/aL9Im7J7ESA=\n'
  105. else:
  106. assert False, 'Unhandled command'
  107. class SysInfoTest(unittest.TestCase):
  108. def test_sysinfo(self):
  109. """Test that the various methods on SysInfo exist and return data."""
  110. s = SysInfo()
  111. self.assertEqual(-1, s.get_num_processors())
  112. self.assertEqual('Unknown', s.get_endianness())
  113. self.assertEqual('', s.get_platform_hostname())
  114. self.assertEqual('Unknown', s.get_platform_name())
  115. self.assertEqual('Unknown', s.get_platform_version())
  116. self.assertEqual('Unknown', s.get_platform_machine())
  117. self.assertFalse(s.get_platform_is_smp())
  118. self.assertEqual(-1, s.get_uptime())
  119. self.assertEqual([-1.0, -1.0, -1.0], s.get_loadavg())
  120. self.assertEqual(-1, s.get_mem_total())
  121. self.assertEqual(-1, s.get_mem_free())
  122. self.assertEqual(-1, s.get_mem_cached())
  123. self.assertEqual(-1, s.get_mem_buffers())
  124. self.assertEqual(-1, s.get_mem_swap_total())
  125. self.assertEqual(-1, s.get_mem_swap_free())
  126. self.assertEqual('Unknown', s.get_platform_distro())
  127. self.assertEqual('Unknown\n', s.get_net_interfaces())
  128. self.assertEqual('Unknown\n', s.get_net_routing_table())
  129. self.assertEqual('Unknown\n', s.get_net_stats())
  130. self.assertEqual('Unknown\n', s.get_net_connections())
  131. def test_sysinfo_factory(self):
  132. """Test that SysInfoFromFactory returns a valid system-specific
  133. SysInfo implementation."""
  134. old_platform_system = platform.system
  135. platform.system = _my_testcase_platform_system
  136. s = SysInfoFromFactory()
  137. self.assertEqual(-1, s.get_num_processors())
  138. self.assertEqual('bigrastafarian', s.get_endianness())
  139. self.assertEqual('', s.get_platform_hostname())
  140. self.assertEqual('b10test', s.get_platform_name())
  141. self.assertEqual('Unknown', s.get_platform_version())
  142. self.assertEqual('Unknown', s.get_platform_machine())
  143. self.assertFalse(s.get_platform_is_smp())
  144. self.assertEqual(131072, s.get_uptime())
  145. self.assertEqual([-1.0, -1.0, -1.0], s.get_loadavg())
  146. self.assertEqual(-1, s.get_mem_total())
  147. self.assertEqual(-1, s.get_mem_free())
  148. self.assertEqual(-1, s.get_mem_cached())
  149. self.assertEqual(-1, s.get_mem_buffers())
  150. self.assertEqual(-1, s.get_mem_swap_total())
  151. self.assertEqual(-1, s.get_mem_swap_free())
  152. self.assertEqual('Unknown', s.get_platform_distro())
  153. self.assertEqual('Unknown\n', s.get_net_interfaces())
  154. self.assertEqual('Unknown\n', s.get_net_routing_table())
  155. self.assertEqual('Unknown\n', s.get_net_stats())
  156. self.assertEqual('Unknown\n', s.get_net_connections())
  157. platform.system = old_platform_system
  158. def test_sysinfo_linux(self):
  159. """Tests the Linux implementation of SysInfo. Note that this
  160. tests deep into the implementation, and not just the
  161. interfaces."""
  162. # Don't run this test on platform other than Linux as some
  163. # system calls may not even be available.
  164. osname = platform.system()
  165. if osname != 'Linux':
  166. return
  167. # Save and replace existing implementations of library functions
  168. # with mock ones for testing.
  169. old_platform_system = platform.system
  170. platform.system = _my_linux_platform_system
  171. old_os_sysconf = os.sysconf
  172. os.sysconf = _my_linux_os_sysconf
  173. old_open = __builtins__.open
  174. __builtins__.open = _my_linux_open
  175. old_subprocess_check_output = subprocess.check_output
  176. subprocess.check_output = _my_linux_subprocess_check_output
  177. s = SysInfoFromFactory()
  178. self.assertEqual(42, s.get_num_processors())
  179. self.assertEqual('myhostname', s.get_platform_hostname())
  180. self.assertTrue(s.get_platform_is_smp())
  181. self.assertEqual(86401, s.get_uptime())
  182. self.assertEqual([0.1, 0.2, 0.3], s.get_loadavg())
  183. self.assertEqual(3157884928, s.get_mem_total())
  184. self.assertEqual(891383808, s.get_mem_free())
  185. self.assertEqual(1335152640, s.get_mem_cached())
  186. self.assertEqual(28069888, s.get_mem_buffers())
  187. self.assertEqual(4294963200, s.get_mem_swap_total())
  188. self.assertEqual(4095451136, s.get_mem_swap_free())
  189. self.assertEqual('My Distribution', s.get_platform_distro())
  190. # These test that the corresponding tools are being called (and
  191. # no further processing is done on this data). Please see the
  192. # implementation functions at the top of this file.
  193. self.assertEqual('qB2osV6vUOjqm3P/+tQ4d92xoYz8/U8P9v3KWRpNwlI=\n', s.get_net_interfaces())
  194. self.assertEqual('VGWAS92AlS14Pl2xqENJs5P2Ihe6Nv9g181Mu6Zz+aQ=\n\nXfizswwNA9NkXz6K36ZExpjV08Y5IXkHI8jjDSV+5Nc=\n', s.get_net_routing_table())
  195. self.assertEqual('osuxbrcc1g9VgaF4yf3FrtfodrfATrbSnjhqhuQSAs8=\n', s.get_net_stats())
  196. self.assertEqual('Z+w0lwa02/T+5+EIio84rrst/Dtizoz/aL9Im7J7ESA=\n', s.get_net_connections())
  197. # Restore original implementations.
  198. platform.system = old_platform_system
  199. os.sysconf = old_os_sysconf
  200. __builtins__.open = old_open
  201. subprocess.check_output = old_subprocess_check_output
  202. def test_sysinfo_openbsd(self):
  203. """Tests the OpenBSD implementation of SysInfo. Note that this
  204. tests deep into the implementation, and not just the
  205. interfaces."""
  206. # Don't run this test on platform other than Openbsd as some
  207. # system calls may not even be available.
  208. osname = platform.system()
  209. if osname != 'OpenBSD':
  210. return
  211. # Save and replace existing implementations of library functions
  212. # with mock ones for testing.
  213. old_platform_system = platform.system
  214. platform.system = _my_openbsd_platform_system
  215. old_os_sysconf = os.sysconf
  216. os.sysconf = _my_openbsd_os_sysconf
  217. old_subprocess_check_output = subprocess.check_output
  218. subprocess.check_output = _my_openbsd_subprocess_check_output
  219. s = SysInfoFromFactory()
  220. self.assertEqual(53, s.get_num_processors())
  221. self.assertEqual('blowfish.example.com', s.get_platform_hostname())
  222. self.assertFalse(s.get_platform_is_smp())
  223. self.assertLess(abs(76632 - s.get_uptime()), 4)
  224. self.assertEqual([0.7, 0.9, 0.8], s.get_loadavg())
  225. self.assertEqual(543214321, s.get_mem_total())
  226. self.assertEqual(543214321 - (121212 * 1024), s.get_mem_free())
  227. self.assertEqual(-1, s.get_mem_cached())
  228. self.assertEqual(-1, s.get_mem_buffers())
  229. self.assertEqual(566791168, s.get_mem_swap_total())
  230. self.assertEqual(566789120, s.get_mem_swap_free())
  231. self.assertRegexpMatches(s.get_platform_distro(), '^OpenBSD\s+.*')
  232. # These test that the corresponding tools are being called (and
  233. # no further processing is done on this data). Please see the
  234. # implementation functions at the top of this file.
  235. self.assertEqual('qB2osV6vUOjqm3P/+tQ4d92xoYz8/U8P9v3KWRpNwlI=\n', s.get_net_interfaces())
  236. self.assertEqual('XfizswwNA9NkXz6K36ZExpjV08Y5IXkHI8jjDSV+5Nc=\n', s.get_net_routing_table())
  237. self.assertEqual('osuxbrcc1g9VgaF4yf3FrtfodrfATrbSnjhqhuQSAs8=\n', s.get_net_stats())
  238. self.assertEqual('Z+w0lwa02/T+5+EIio84rrst/Dtizoz/aL9Im7J7ESA=\n', s.get_net_connections())
  239. # Restore original implementations.
  240. platform.system = old_platform_system
  241. os.sysconf = old_os_sysconf
  242. subprocess.check_output = old_subprocess_check_output
  243. if __name__ == "__main__":
  244. unittest.main()