test_commands.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import copy
  2. from flexmock import flexmock
  3. import borgmatic.borg.info
  4. import borgmatic.borg.list
  5. import borgmatic.borg.rlist
  6. import borgmatic.borg.transfer
  7. import borgmatic.commands.arguments
  8. def assert_command_does_not_duplicate_flags(command, *args, **kwargs):
  9. '''
  10. Assert that the given Borg command sequence does not contain any duplicated flags, e.g.
  11. "--match-archives" twice anywhere in the command.
  12. '''
  13. flag_counts = {}
  14. for flag_name in command:
  15. if not flag_name.startswith('--'):
  16. continue
  17. if flag_name in flag_counts:
  18. flag_counts[flag_name] += 1
  19. else:
  20. flag_counts[flag_name] = 1
  21. assert flag_counts == {
  22. flag_name: 1 for flag_name in flag_counts
  23. }, f"Duplicate flags found in: {' '.join(command)}"
  24. def fuzz_argument(arguments, argument_name):
  25. '''
  26. Given an argparse.Namespace instance of arguments and an argument name in it, copy the arguments
  27. namespace and set the argument name in the copy with a fake value. Return the copied arguments.
  28. This is useful for "fuzzing" a unit under test by passing it each possible argument in turn,
  29. making sure it doesn't blow up or duplicate Borg arguments.
  30. '''
  31. arguments_copy = copy.copy(arguments)
  32. value = getattr(arguments_copy, argument_name)
  33. setattr(arguments_copy, argument_name, not value if isinstance(value, bool) else 'value')
  34. return arguments_copy
  35. def test_transfer_archives_command_does_not_duplicate_flags_or_raise():
  36. arguments = borgmatic.commands.arguments.parse_arguments(
  37. 'transfer', '--source-repository', 'foo'
  38. )['transfer']
  39. flexmock(borgmatic.borg.transfer).should_receive('execute_command').replace_with(
  40. assert_command_does_not_duplicate_flags
  41. )
  42. for argument_name in dir(arguments):
  43. if argument_name.startswith('_'):
  44. continue
  45. borgmatic.borg.transfer.transfer_archives(
  46. False, 'repo', {}, '2.3.4', fuzz_argument(arguments, argument_name)
  47. )
  48. def test_make_list_command_does_not_duplicate_flags_or_raise():
  49. arguments = borgmatic.commands.arguments.parse_arguments('list')['list']
  50. for argument_name in dir(arguments):
  51. if argument_name.startswith('_'):
  52. continue
  53. command = borgmatic.borg.list.make_list_command(
  54. 'repo', {}, '2.3.4', fuzz_argument(arguments, argument_name)
  55. )
  56. assert_command_does_not_duplicate_flags(command)
  57. def test_make_rlist_command_does_not_duplicate_flags_or_raise():
  58. arguments = borgmatic.commands.arguments.parse_arguments('rlist')['rlist']
  59. for argument_name in dir(arguments):
  60. if argument_name.startswith('_'):
  61. continue
  62. command = borgmatic.borg.rlist.make_rlist_command(
  63. 'repo', {}, '2.3.4', fuzz_argument(arguments, argument_name)
  64. )
  65. assert_command_does_not_duplicate_flags(command)
  66. def test_display_archives_info_command_does_not_duplicate_flags_or_raise():
  67. arguments = borgmatic.commands.arguments.parse_arguments('info')['info']
  68. flexmock(borgmatic.borg.info).should_receive('execute_command_and_capture_output').replace_with(
  69. assert_command_does_not_duplicate_flags
  70. )
  71. flexmock(borgmatic.borg.info).should_receive('execute_command').replace_with(
  72. assert_command_does_not_duplicate_flags
  73. )
  74. for argument_name in dir(arguments):
  75. if argument_name.startswith('_'):
  76. continue
  77. borgmatic.borg.info.display_archives_info(
  78. 'repo', {}, '2.3.4', fuzz_argument(arguments, argument_name)
  79. )