test_commands.py 3.9 KB

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