test_mkdfu.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
  5. # SPDX-License-Identifier: Apache-2.0
  6. from __future__ import unicode_literals
  7. import collections
  8. import filecmp
  9. import json
  10. import os
  11. import shutil
  12. import sys
  13. import tempfile
  14. import time
  15. import unittest
  16. import pexpect
  17. current_dir = os.path.dirname(os.path.realpath(__file__))
  18. mkdfu_path = os.path.join(current_dir, '..', 'mkdfu.py')
  19. class TestMkDFU(unittest.TestCase):
  20. def common_test(self, json_input=None, file_args=[], output_to_compare=None, part_size=None):
  21. '''
  22. - json_input - input JSON file compatible with mkdfu.py - used when not None
  23. - file_args - list of (address, path_to_file) tuples
  24. - output_to_compare - path to the file containing the expected output - tested when not None
  25. - part_size - partition size - used when not None
  26. '''
  27. with tempfile.NamedTemporaryFile(delete=False) as f_out:
  28. self.addCleanup(os.unlink, f_out.name)
  29. args = [mkdfu_path, 'write',
  30. '-o', f_out.name,
  31. '--pid', '2',
  32. '--flash-size', '4MB']
  33. if part_size:
  34. args += ['--part-size', str(part_size)]
  35. if json_input:
  36. args += ['--json', json_input]
  37. for addr, f_path in file_args:
  38. args += [str(addr), f_path]
  39. p = pexpect.spawn(sys.executable, args, timeout=10, encoding='utf-8')
  40. self.addCleanup(p.terminate, force=True)
  41. p.expect_exact('Adding flash chip parameters file with flash_size = 4MB')
  42. for addr, f_path in sorted(file_args, key=lambda e: e[0]):
  43. p.expect_exact('Adding {} at {}'.format(f_path, hex(addr)))
  44. p.expect_exact('"{}" has been written. You may proceed with DFU flashing.'.format(f_out.name))
  45. # Need to wait for the process to end because the output file is closed when mkdfu exits.
  46. # Do non-blocking wait instead of the blocking p.wait():
  47. for _ in range(10):
  48. if not p.isalive():
  49. break
  50. time.sleep(0.5)
  51. else:
  52. p.terminate()
  53. if output_to_compare:
  54. self.assertTrue(filecmp.cmp(f_out.name, os.path.join(current_dir, output_to_compare)), 'Output files are different')
  55. class TestHelloWorldExample(TestMkDFU):
  56. '''
  57. tests with images prepared in the "1" subdirectory
  58. '''
  59. def test_with_json(self):
  60. with tempfile.NamedTemporaryFile(mode='w', dir=os.path.join(current_dir, '1'), delete=False) as f:
  61. self.addCleanup(os.unlink, f.name)
  62. bins = [('0x1000', '1.bin'), ('0x8000', '2.bin'), ('0x10000', '3.bin')]
  63. json.dump({'flash_files': collections.OrderedDict(bins)}, f)
  64. self.common_test(json_input=f.name, output_to_compare='1/dfu.bin')
  65. def test_without_json(self):
  66. self.common_test(file_args=[(0x1000, '1/1.bin'),
  67. (0x8000, '1/2.bin'),
  68. (0x10000, '1/3.bin')],
  69. output_to_compare='1/dfu.bin')
  70. def test_filenames(self):
  71. temp_dir = tempfile.mkdtemp(prefix='very_long_directory_name' * 8)
  72. self.addCleanup(shutil.rmtree, temp_dir, ignore_errors=True)
  73. with tempfile.NamedTemporaryFile(prefix='ľščťžýáíéěř\u0420\u043e\u0441\u0441\u0438\u044f',
  74. dir=temp_dir,
  75. delete=False) as f:
  76. bootloader = f.name
  77. shutil.copyfile(os.path.join(current_dir, '1', '1.bin'), bootloader)
  78. self.common_test(file_args=[(0x1000, bootloader),
  79. (0x8000, os.path.join(current_dir, '1', '2.bin')),
  80. (0x10000, os.path.join(current_dir, '1', '3.bin'))])
  81. class TestSplit(TestMkDFU):
  82. '''
  83. tests with images prepared in the "2" subdirectory
  84. "2/dfu.bin" was prepared with:
  85. mkdfu.py write --part-size 5 --pid 2 --flash-size 4MB -o 2/dfu.bin 0 bin
  86. where the content of "bin" is b"\xce" * 10
  87. '''
  88. def test_split(self):
  89. temp_dir = tempfile.mkdtemp(dir=current_dir)
  90. self.addCleanup(shutil.rmtree, temp_dir, ignore_errors=True)
  91. with open(os.path.join(temp_dir, 'bin'), 'wb') as f:
  92. self.addCleanup(os.unlink, f.name)
  93. f.write(b'\xce' * 10)
  94. self.common_test(file_args=[(0, f.name)],
  95. part_size=5,
  96. output_to_compare='2/dfu.bin')
  97. if __name__ == '__main__':
  98. unittest.main()