431
438
class RemoveCmd(Command):
432
439
def run_on_one_client(self, client, properties):
440
log.debug("D-Bus: %s:%s:%s.RemoveClient(%r)", busname,
441
server_path, server_interface,
442
str(client.__dbus_object_path__))
433
443
self.mandos.RemoveClient(client.__dbus_object_path__)
435
445
class ApproveCmd(Command):
436
446
def run_on_one_client(self, client, properties):
447
log.debug("D-Bus: %s:%s.Approve(True)",
448
client.__dbus_object_path__, client_interface)
437
449
client.Approve(dbus.Boolean(True),
438
450
dbus_interface=client_interface)
440
452
class DenyCmd(Command):
441
453
def run_on_one_client(self, client, properties):
454
log.debug("D-Bus: %s:%s.Approve(False)",
455
client.__dbus_object_path__, client_interface)
442
456
client.Approve(dbus.Boolean(False),
443
457
dbus_interface=client_interface)
1330
1355
def test_is_enabled_short(self):
1331
1356
self.assert_command_from_args(["-V", "foo"], IsEnabledCmd)
1358
def test_deny_before_remove(self):
1359
options = self.parser.parse_args(["--deny", "--remove", "foo"])
1360
check_option_syntax(self.parser, options)
1361
commands = commands_from_options(options)
1362
self.assertEqual(len(commands), 2)
1363
self.assertIsInstance(commands[0], DenyCmd)
1364
self.assertIsInstance(commands[1], RemoveCmd)
1366
def test_deny_before_remove_reversed(self):
1367
options = self.parser.parse_args(["--remove", "--deny", "--all"])
1368
check_option_syntax(self.parser, options)
1369
commands = commands_from_options(options)
1370
self.assertEqual(len(commands), 2)
1371
self.assertIsInstance(commands[0], DenyCmd)
1372
self.assertIsInstance(commands[1], RemoveCmd)
1375
class Test_check_option_syntax(unittest.TestCase):
1376
# This mostly corresponds to the definition from has_actions() in
1377
# check_option_syntax()
1379
# The actual values set here are not that important, but we do
1380
# at least stick to the correct types, even though they are
1384
"bump_timeout": True,
1385
"start_checker": True,
1386
"stop_checker": True,
1390
"timeout": datetime.timedelta(),
1391
"extended_timeout": datetime.timedelta(),
1392
"interval": datetime.timedelta(),
1393
"approved_by_default": True,
1394
"approval_delay": datetime.timedelta(),
1395
"approval_duration": datetime.timedelta(),
1397
"secret": io.BytesIO(b"x"),
1403
self.parser = argparse.ArgumentParser()
1404
add_command_line_options(self.parser)
1406
@contextlib.contextmanager
1407
def assertParseError(self):
1408
with self.assertRaises(SystemExit) as e:
1409
with self.temporarily_suppress_stderr():
1411
# Exit code from argparse is guaranteed to be "2". Reference:
1412
# https://docs.python.org/3/library/argparse.html#exiting-methods
1413
self.assertEqual(e.exception.code, 2)
1416
@contextlib.contextmanager
1417
def temporarily_suppress_stderr():
1418
null = os.open(os.path.devnull, os.O_RDWR)
1419
stderrcopy = os.dup(sys.stderr.fileno())
1420
os.dup2(null, sys.stderr.fileno())
1426
os.dup2(stderrcopy, sys.stderr.fileno())
1427
os.close(stderrcopy)
1429
def check_option_syntax(self, options):
1430
check_option_syntax(self.parser, options)
1432
def test_actions_requires_client_or_all(self):
1433
for action, value in self.actions.items():
1434
options = self.parser.parse_args()
1435
setattr(options, action, value)
1436
with self.assertParseError():
1437
self.check_option_syntax(options)
1439
def test_actions_conflicts_with_verbose(self):
1440
for action, value in self.actions.items():
1441
options = self.parser.parse_args()
1442
setattr(options, action, value)
1443
options.verbose = True
1444
with self.assertParseError():
1445
self.check_option_syntax(options)
1447
def test_dump_json_conflicts_with_verbose(self):
1448
options = self.parser.parse_args()
1449
options.dump_json = True
1450
options.verbose = True
1451
with self.assertParseError():
1452
self.check_option_syntax(options)
1454
def test_dump_json_conflicts_with_action(self):
1455
for action, value in self.actions.items():
1456
options = self.parser.parse_args()
1457
setattr(options, action, value)
1458
options.dump_json = True
1459
with self.assertParseError():
1460
self.check_option_syntax(options)
1462
def test_all_can_not_be_alone(self):
1463
options = self.parser.parse_args()
1465
with self.assertParseError():
1466
self.check_option_syntax(options)
1468
def test_all_is_ok_with_any_action(self):
1469
for action, value in self.actions.items():
1470
options = self.parser.parse_args()
1471
setattr(options, action, value)
1473
self.check_option_syntax(options)
1475
def test_is_enabled_fails_without_client(self):
1476
options = self.parser.parse_args()
1477
options.is_enabled = True
1478
with self.assertParseError():
1479
self.check_option_syntax(options)
1481
def test_is_enabled_works_with_one_client(self):
1482
options = self.parser.parse_args()
1483
options.is_enabled = True
1484
options.client = ["foo"]
1485
self.check_option_syntax(options)
1487
def test_is_enabled_fails_with_two_clients(self):
1488
options = self.parser.parse_args()
1489
options.is_enabled = True
1490
options.client = ["foo", "barbar"]
1491
with self.assertParseError():
1492
self.check_option_syntax(options)
1335
1496
def should_only_run_tests():