test_wmediumd.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. # wmediumd sanity checks
  2. # Copyright (c) 2015, Intel Deutschland GmbH
  3. #
  4. # This software may be distributed under the terms of the BSD license.
  5. # See README for more details.
  6. import tempfile, os, subprocess, errno, hwsim_utils
  7. from utils import HwsimSkip
  8. from test_ap_open import _test_ap_open
  9. from test_wpas_mesh import check_mesh_support, check_mesh_group_added
  10. from test_wpas_mesh import check_mesh_peer_connected, add_open_mesh_network
  11. from test_wpas_mesh import check_mesh_group_removed
  12. class LocalVariables:
  13. revs = []
  14. CFG = """
  15. ifaces :
  16. {
  17. ids = ["%s", "%s" ];
  18. links = (
  19. (0, 1, 30)
  20. );
  21. };
  22. """
  23. CFG2 = """
  24. ifaces :
  25. {
  26. ids = ["%s", "%s", "%s"];
  27. links = (
  28. (0, 1, 50),
  29. (0, 2, 50),
  30. (1, 2, -10)
  31. );
  32. };
  33. """
  34. def get_wmediumd_version():
  35. if len(LocalVariables.revs) > 0:
  36. return LocalVariables.revs;
  37. try:
  38. verstr = subprocess.check_output(['wmediumd', '-V'])
  39. except OSError, e:
  40. if e.errno == errno.ENOENT:
  41. raise HwsimSkip('wmediumd not available')
  42. raise
  43. vernum = verstr.split(' ')[1][1:]
  44. LocalVariables.revs = vernum.split('.')
  45. for i in range(0, len(LocalVariables.revs)):
  46. LocalVariables.revs[i] = int(LocalVariables.revs[i])
  47. while len(LocalVariables.revs) < 3:
  48. LocalVariables.revs += [0]
  49. return LocalVariables.revs;
  50. def require_wmediumd_version(major, minor, patch):
  51. revs = get_wmediumd_version()
  52. if revs[0] < major or revs[1] < minor or revs[2] < patch:
  53. raise HwsimSkip('wmediumd v%s.%s.%s is too old for this test' %
  54. (revs[0], revs[1], revs[2]))
  55. def output_wmediumd_log(p, params, data):
  56. log_file = open(os.path.abspath(os.path.join(params['logdir'],
  57. 'wmediumd.log')), 'a')
  58. log_file.write(data)
  59. log_file.close()
  60. def start_wmediumd(fn, params):
  61. try:
  62. p = subprocess.Popen(['wmediumd', '-c', fn],
  63. stdout=subprocess.PIPE,
  64. stderr=subprocess.STDOUT)
  65. except OSError, e:
  66. if e.errno == errno.ENOENT:
  67. raise HwsimSkip('wmediumd not available')
  68. raise
  69. logs = ''
  70. while True:
  71. line = p.stdout.readline()
  72. if not line:
  73. output_wmediumd_log(p, params, logs)
  74. raise Exception('wmediumd was terminated unexpectedly')
  75. if line.find('REGISTER SENT!') > -1:
  76. break
  77. logs += line
  78. return p
  79. def stop_wmediumd(p, params):
  80. p.terminate()
  81. p.wait()
  82. stdoutdata, stderrdata = p.communicate()
  83. output_wmediumd_log(p, params, stdoutdata)
  84. def test_wmediumd_simple(dev, apdev, params):
  85. """test a simple wmediumd configuration"""
  86. fd, fn = tempfile.mkstemp()
  87. try:
  88. f = os.fdopen(fd, 'w')
  89. f.write(CFG % (apdev[0]['bssid'], dev[0].own_addr()))
  90. f.close()
  91. p = start_wmediumd(fn, params)
  92. try:
  93. _test_ap_open(dev, apdev)
  94. finally:
  95. stop_wmediumd(p, params)
  96. # test that releasing hwsim works correctly
  97. _test_ap_open(dev, apdev)
  98. finally:
  99. os.unlink(fn)
  100. def test_wmediumd_path_simple(dev, apdev, params):
  101. """test a mesh path"""
  102. # 0 and 1 is connected
  103. # 0 and 2 is connected
  104. # 1 and 2 is not connected
  105. # 1 --- 0 --- 2
  106. # | |
  107. # +-----X-----+
  108. # This tests if 1 and 2 can communicate each other via 0.
  109. require_wmediumd_version(0, 3, 1)
  110. fd, fn = tempfile.mkstemp()
  111. try:
  112. f = os.fdopen(fd, 'w')
  113. f.write(CFG2 % (dev[0].own_addr(), dev[1].own_addr(),
  114. dev[2].own_addr()))
  115. f.close()
  116. p = start_wmediumd(fn, params)
  117. try:
  118. _test_wmediumd_path_simple(dev, apdev)
  119. finally:
  120. stop_wmediumd(p, params)
  121. finally:
  122. os.unlink(fn)
  123. def _test_wmediumd_path_simple(dev, apdev):
  124. for i in range(0, 3):
  125. check_mesh_support(dev[i])
  126. add_open_mesh_network(dev[i], freq="2462", basic_rates="60 120 240")
  127. # Check for mesh joined
  128. for i in range(0, 3):
  129. check_mesh_group_added(dev[i])
  130. state = dev[i].get_status_field("wpa_state")
  131. if state != "COMPLETED":
  132. raise Exception("Unexpected wpa_state on dev" + str(i) + ": " + state)
  133. mode = dev[i].get_status_field("mode")
  134. if mode != "mesh":
  135. raise Exception("Unexpected mode: " + mode)
  136. # Check for peer connected
  137. check_mesh_peer_connected(dev[0])
  138. check_mesh_peer_connected(dev[0])
  139. check_mesh_peer_connected(dev[1])
  140. check_mesh_peer_connected(dev[2])
  141. # Test connectivity 1->2 and 2->1
  142. hwsim_utils.test_connectivity(dev[1], dev[2])
  143. # Check mpath table on 0
  144. res, data = dev[0].cmd_execute(['iw', dev[0].ifname, 'mpath', 'dump'])
  145. if res != 0:
  146. raise Exception("iw command failed on dev0")
  147. if data.find(dev[1].own_addr() + ' ' + dev[1].own_addr()) == -1 or \
  148. data.find(dev[2].own_addr() + ' ' + dev[2].own_addr()) == -1:
  149. raise Exception("mpath not found on dev0:\n" + data)
  150. if data.find(dev[0].own_addr()) > -1:
  151. raise Exception("invalid mpath found on dev0:\n" + data)
  152. # Check mpath table on 1
  153. res, data = dev[1].cmd_execute(['iw', dev[1].ifname, 'mpath', 'dump'])
  154. if res != 0:
  155. raise Exception("iw command failed on dev1")
  156. if data.find(dev[0].own_addr() + ' ' + dev[0].own_addr()) == -1 or \
  157. data.find(dev[2].own_addr() + ' ' + dev[0].own_addr()) == -1:
  158. raise Exception("mpath not found on dev1:\n" + data)
  159. if data.find(dev[2].own_addr() + ' ' + dev[2].own_addr()) > -1 or \
  160. data.find(dev[1].own_addr()) > -1:
  161. raise Exception("invalid mpath found on dev1:\n" + data)
  162. # Check mpath table on 2
  163. res, data = dev[2].cmd_execute(['iw', dev[2].ifname, 'mpath', 'dump'])
  164. if res != 0:
  165. raise Exception("iw command failed on dev2")
  166. if data.find(dev[0].own_addr() + ' ' + dev[0].own_addr()) == -1 or \
  167. data.find(dev[1].own_addr() + ' ' + dev[0].own_addr()) == -1:
  168. raise Exception("mpath not found on dev2:\n" + data)
  169. if data.find(dev[1].own_addr() + ' ' + dev[1].own_addr()) > -1 or \
  170. data.find(dev[2].own_addr()) > -1:
  171. raise Exception("invalid mpath found on dev2:\n" + data)
  172. # remove mesh groups
  173. for i in range(0, 3):
  174. dev[i].mesh_group_remove()
  175. check_mesh_group_removed(dev[i])
  176. dev[i].dump_monitor()