pytest_mdns.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
  2. # SPDX-License-Identifier: Unlicense OR CC0-1.0
  3. import logging
  4. import pexpect
  5. import pytest
  6. from dnsfixture import DnsPythonWrapper
  7. # Configure logging
  8. logging.basicConfig(level=logging.INFO)
  9. logger = logging.getLogger(__name__)
  10. ipv6_enabled = False
  11. class MdnsConsole:
  12. def __init__(self, command):
  13. self.process = pexpect.spawn(command, encoding='utf-8')
  14. self.process.logfile = open('mdns_interaction.log', 'w') # Log all interactions
  15. self.process.expect('mdns> ', timeout=10)
  16. def send_input(self, input_data):
  17. logger.info(f'Sending to stdin: {input_data}')
  18. self.process.sendline(input_data)
  19. def get_output(self, expected_data):
  20. logger.info(f'Expecting: {expected_data}')
  21. self.process.expect(expected_data, timeout=10)
  22. output = self.process.before.strip()
  23. logger.info(f'Received from stdout: {output}')
  24. return output
  25. def terminate(self):
  26. self.send_input('exit')
  27. self.get_output('Exit')
  28. self.process.wait()
  29. self.process.close()
  30. assert self.process.exitstatus == 0
  31. @pytest.fixture(scope='module')
  32. def mdns_console():
  33. app = MdnsConsole('./build_linux_console/mdns_host.elf')
  34. yield app
  35. app.terminate()
  36. @pytest.fixture(scope='module')
  37. def dig_app():
  38. return DnsPythonWrapper()
  39. def test_mdns_init(mdns_console, dig_app):
  40. mdns_console.send_input('mdns_init -h hostname')
  41. mdns_console.get_output('MDNS: Hostname: hostname')
  42. dig_app.check_record('hostname.local', query_type='A', expected=True)
  43. if ipv6_enabled:
  44. dig_app.check_record('hostname.local', query_type='AAAA', expected=True)
  45. def test_add_service(mdns_console, dig_app):
  46. mdns_console.send_input('mdns_service_add _http _tcp 80 -i test_service')
  47. mdns_console.get_output('MDNS: Service Instance: test_service')
  48. mdns_console.send_input('mdns_service_lookup _http _tcp')
  49. mdns_console.get_output('PTR : test_service')
  50. dig_app.check_record('_http._tcp.local', query_type='PTR', expected=True)
  51. def test_remove_service(mdns_console, dig_app):
  52. mdns_console.send_input('mdns_service_remove _http _tcp')
  53. mdns_console.send_input('mdns_service_lookup _http _tcp')
  54. mdns_console.get_output('No results found!')
  55. dig_app.check_record('_http._tcp.local', query_type='PTR', expected=False)
  56. def test_delegate_host(mdns_console, dig_app):
  57. mdns_console.send_input('mdns_delegate_host delegated 1.2.3.4')
  58. dig_app.check_record('delegated.local', query_type='A', expected=True)
  59. def test_undelegate_host(mdns_console, dig_app):
  60. mdns_console.send_input('mdns_undelegate_host delegated')
  61. dig_app.check_record('delegated.local', query_type='A', expected=False)
  62. def test_add_delegated_service(mdns_console, dig_app):
  63. mdns_console.send_input('mdns_delegate_host delegated 1.2.3.4')
  64. dig_app.check_record('delegated.local', query_type='A', expected=True)
  65. mdns_console.send_input('mdns_service_add _test _tcp 80 -i local')
  66. mdns_console.get_output('MDNS: Service Instance: local')
  67. mdns_console.send_input('mdns_service_add _test2 _tcp 80 -i extern -h delegated')
  68. mdns_console.get_output('MDNS: Service Instance: extern')
  69. mdns_console.send_input('mdns_service_lookup _test _tcp')
  70. mdns_console.get_output('PTR : local')
  71. mdns_console.send_input('mdns_service_lookup _test2 _tcp -d')
  72. mdns_console.get_output('PTR : extern')
  73. dig_app.check_record('_test2._tcp.local', query_type='PTR', expected=True)
  74. dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True)
  75. def test_remove_delegated_service(mdns_console, dig_app):
  76. mdns_console.send_input('mdns_service_remove _test2 _tcp -h delegated')
  77. mdns_console.send_input('mdns_service_lookup _test2 _tcp -d')
  78. mdns_console.get_output('No results found!')
  79. dig_app.check_record('_test2._tcp.local', query_type='PTR', expected=False)
  80. # add the delegated service again, would be used in the TXT test
  81. mdns_console.send_input('mdns_service_add _test2 _tcp 80 -i extern -h delegated')
  82. mdns_console.get_output('MDNS: Service Instance: extern')
  83. def check_txt_for_service(instance, service, proto, mdns_console, dig_app, host=None, with_inst=False):
  84. for_host_arg = f'-h {host}' if host is not None else ''
  85. for_inst_arg = f'-i {instance}' if with_inst else ''
  86. mdns_console.send_input(f'mdns_service_txt_set {service} {proto} {for_host_arg} {for_inst_arg} key1 value1')
  87. dig_app.check_record(f'{instance}.{service}.{proto}.local', query_type='SRV', expected=True)
  88. dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key1=value1')
  89. mdns_console.send_input(f'mdns_service_txt_set {service} {proto} {for_host_arg} {for_inst_arg} key2 value2')
  90. dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key2=value2')
  91. mdns_console.send_input(f'mdns_service_txt_remove {service} {proto} {for_host_arg} {for_inst_arg} key2')
  92. dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=False, expect='key2=value2')
  93. dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key1=value1')
  94. mdns_console.send_input(f'mdns_service_txt_replace {service} {proto} {for_host_arg} {for_inst_arg} key3=value3 key4=value4')
  95. dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=False, expect='key1=value1')
  96. dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key3=value3')
  97. dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key4=value4')
  98. def test_update_txt(mdns_console, dig_app):
  99. check_txt_for_service('local', '_test', '_tcp', mdns_console=mdns_console, dig_app=dig_app)
  100. check_txt_for_service('local', '_test', '_tcp', mdns_console=mdns_console, dig_app=dig_app, with_inst=True)
  101. def test_update_delegated_txt(mdns_console, dig_app):
  102. check_txt_for_service('extern', '_test2', '_tcp', mdns_console=mdns_console, dig_app=dig_app, host='delegated')
  103. check_txt_for_service('extern', '_test2', '_tcp', mdns_console=mdns_console, dig_app=dig_app, host='delegated', with_inst=True)
  104. def test_service_port_set(mdns_console, dig_app):
  105. dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True, expect='80')
  106. mdns_console.send_input('mdns_service_port_set _test _tcp 81')
  107. dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True, expect='81')
  108. mdns_console.send_input('mdns_service_port_set _test2 _tcp -h delegated 82')
  109. dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True, expect='82')
  110. mdns_console.send_input('mdns_service_port_set _test2 _tcp -h delegated -i extern 83')
  111. dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True, expect='83')
  112. mdns_console.send_input('mdns_service_port_set _test2 _tcp -h delegated -i invalid_inst 84')
  113. mdns_console.get_output('ESP_ERR_NOT_FOUND')
  114. dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True, expect='83')
  115. def test_service_subtype(mdns_console, dig_app):
  116. dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True)
  117. mdns_console.send_input('mdns_service_subtype _test _tcp _subtest -i local')
  118. dig_app.check_record('_subtest._sub._test._tcp.local', query_type='PTR', expected=True)
  119. mdns_console.send_input('mdns_service_subtype _test2 _tcp _subtest2 -i extern -h delegated')
  120. dig_app.check_record('_subtest2._sub._test2._tcp.local', query_type='PTR', expected=True)
  121. def test_service_set_instance(mdns_console, dig_app):
  122. dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True)
  123. mdns_console.send_input('mdns_service_instance_set _test _tcp local2')
  124. dig_app.check_record('local2._test._tcp.local', query_type='SRV', expected=True)
  125. mdns_console.send_input('mdns_service_instance_set _test2 _tcp extern2 -h delegated')
  126. mdns_console.send_input('mdns_service_lookup _test2 _tcp -d')
  127. mdns_console.get_output('PTR : extern2')
  128. dig_app.check_record('extern2._test2._tcp.local', query_type='SRV', expected=True)
  129. mdns_console.send_input('mdns_service_instance_set _test2 _tcp extern3 -h delegated -i extern')
  130. mdns_console.get_output('ESP_ERR_NOT_FOUND')
  131. def test_service_remove_all(mdns_console, dig_app):
  132. mdns_console.send_input('mdns_service_remove_all')
  133. mdns_console.send_input('mdns_service_lookup _test2 _tcp -d')
  134. mdns_console.get_output('No results found!')
  135. mdns_console.send_input('mdns_service_lookup _test _tcp')
  136. mdns_console.get_output('No results found!')
  137. dig_app.check_record('_test._tcp.local', query_type='PTR', expected=False)
  138. if __name__ == '__main__':
  139. pytest.main(['-s', 'test_mdns.py'])