Skip to content

Commit

Permalink
Ensure that cli options specified with action=Highlander can only be …
Browse files Browse the repository at this point in the history
…set once, even if the set value is a default value. Add tests for action=Highlander. See borgbackup#7500 borgbackup#6269
  • Loading branch information
jorickert committed Apr 15, 2023
1 parent 9307f80 commit ba64122
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/borg/archiver/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,14 @@ def wrapper(self, args, repository, manifest, **kwargs):
class Highlander(argparse.Action):
"""make sure some option is only given once"""

def __init__(self, *args, **kwargs):
self.__called = False
super().__init__(*args, **kwargs)

def __call__(self, parser, namespace, values, option_string=None):
if getattr(namespace, self.dest, None) != self.default:
if self.__called:
raise argparse.ArgumentError(self, "There can be only one.")
self.__called = True
setattr(namespace, self.dest, values)


Expand Down
19 changes: 19 additions & 0 deletions src/borg/testsuite/archiver/argparsing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import argparse
import os.path

import pytest

from ...helpers import parse_storage_quota
Expand All @@ -11,6 +13,23 @@ def test_bad_filters(self):
self.cmd(f"--repo={self.repository_location}", "create", "test", "input")
self.cmd(f"--repo={self.repository_location}", "delete", "--first", "1", "--last", "1", fork=True, exit_code=2)

def test_highlander(self):
self.cmd(f"--repo={self.repository_location}", "rcreate", RK_ENCRYPTION)
self.cmd(f"--repo={self.repository_location}", "create", "--comment", "comment 1", "test-1", __file__)
error_msg = "There can be only one"
# Default umask value is 0077
# Test that it works with a one time specified default or custom value
output_default = self.cmd(f"--repo={self.repository_location}", "--umask", "0077", "rlist")
assert error_msg not in output_default
output_custom = self.cmd(f"--repo={self.repository_location}", "--umask", "0007", "rlist")
assert error_msg not in output_custom
# Test that all combinations of custom and default values fail
for first, second in [("0007", "0007"), ("0007", "0077"), ("0077", "0007"), ("0077", "0077")]:
output_custom = self.cmd(
f"--repo={self.repository_location}", "--umask", first, "--umask", second, "rlist", exit_code=2
)
assert error_msg in output_custom


def test_get_args():
archiver = Archiver()
Expand Down

0 comments on commit ba64122

Please sign in to comment.