test_wmediumd.py 6.4 KB

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