/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to mandos-ctl

  • Committer: Teddy Hogeborn
  • Date: 2019-03-16 17:11:12 UTC
  • Revision ID: teddy@recompile.se-20190316171112-0tpfk9ved7a2a5x2
mandos-ctl: Refactor and add a few more tests

* mandos-ctl (main): Remove comment and add empty line.
  (rfc3339_duration_to_delta): Change ValueError exception message to
                               use \"{}\"" instead of "{!r}" so Python
                               2 and Python 3 output is the same.
  (Test_check_option_syntax.temporarily_suppress_stderr): Rename to
                                         "redirect_stderr_to_devnull".

  (Test_check_option_syntax
  .test_actions_except_is_enabled_are_ok_with_two_clients):  Rename to
             "test_two_clients_are_ok_with_actions_except_is_enabled".
  (Test_check_option_syntax
   .test_one_client_with_all_actions_except_is_enabled): New.
  (Test_check_option_syntax
   .test_two_clients_with_all_actions_except_is_enabled): - '' -

Show diffs side-by-side

added added

removed removed

Lines of Context:
125
125
                log.critical("Client not found on server: %r", name)
126
126
                sys.exit(1)
127
127
 
128
 
    # Run all commands on clients
129
128
    commands = commands_from_options(options)
 
129
 
130
130
    for command in commands:
131
131
        command.run(clients, bus, mandos_serv)
132
132
 
232
232
    >>> rfc3339_duration_to_delta("")
233
233
    Traceback (most recent call last):
234
234
    ...
235
 
    ValueError: Invalid RFC 3339 duration: u''
 
235
    ValueError: Invalid RFC 3339 duration: ""
236
236
    >>> # Must start with "P":
237
237
    >>> rfc3339_duration_to_delta("1D")
238
238
    Traceback (most recent call last):
239
239
    ...
240
 
    ValueError: Invalid RFC 3339 duration: u'1D'
 
240
    ValueError: Invalid RFC 3339 duration: "1D"
241
241
    >>> # Must use correct order
242
242
    >>> rfc3339_duration_to_delta("PT1S2M")
243
243
    Traceback (most recent call last):
244
244
    ...
245
 
    ValueError: Invalid RFC 3339 duration: u'PT1S2M'
 
245
    ValueError: Invalid RFC 3339 duration: "PT1S2M"
246
246
    >>> # Time needs time marker
247
247
    >>> rfc3339_duration_to_delta("P1H2S")
248
248
    Traceback (most recent call last):
249
249
    ...
250
 
    ValueError: Invalid RFC 3339 duration: u'P1H2S'
 
250
    ValueError: Invalid RFC 3339 duration: "P1H2S"
251
251
    >>> # Weeks can not be combined with anything else
252
252
    >>> rfc3339_duration_to_delta("P1D2W")
253
253
    Traceback (most recent call last):
254
254
    ...
255
 
    ValueError: Invalid RFC 3339 duration: u'P1D2W'
 
255
    ValueError: Invalid RFC 3339 duration: "P1D2W"
256
256
    >>> rfc3339_duration_to_delta("P2W2H")
257
257
    Traceback (most recent call last):
258
258
    ...
259
 
    ValueError: Invalid RFC 3339 duration: u'P2W2H'
 
259
    ValueError: Invalid RFC 3339 duration: "P2W2H"
260
260
    """
261
261
 
262
262
    # Parsing an RFC 3339 duration with regular expressions is not
333
333
                break
334
334
        else:
335
335
            # No currently valid tokens were found
336
 
            raise ValueError("Invalid RFC 3339 duration: {!r}"
 
336
            raise ValueError("Invalid RFC 3339 duration: \"{}\""
337
337
                             .format(duration))
338
338
    # End token found
339
339
    return value
872
872
                                                    ("records",
873
873
                                                     "output"))
874
874
 
 
875
 
875
876
class Test_string_to_delta(TestCaseWithAssertLogs):
876
877
    def test_handles_basic_rfc3339(self):
877
878
        self.assertEqual(string_to_delta("PT0S"),
930
931
    @contextlib.contextmanager
931
932
    def assertParseError(self):
932
933
        with self.assertRaises(SystemExit) as e:
933
 
            with self.temporarily_suppress_stderr():
 
934
            with self.redirect_stderr_to_devnull():
934
935
                yield
935
936
        # Exit code from argparse is guaranteed to be "2".  Reference:
936
937
        # https://docs.python.org/3/library
939
940
 
940
941
    @staticmethod
941
942
    @contextlib.contextmanager
942
 
    def temporarily_suppress_stderr():
 
943
    def redirect_stderr_to_devnull():
943
944
        null = os.open(os.path.devnull, os.O_RDWR)
944
945
        stderrcopy = os.dup(sys.stderr.fileno())
945
946
        os.dup2(null, sys.stderr.fileno())
1007
1008
            options.client = ["foo"]
1008
1009
            self.check_option_syntax(options)
1009
1010
 
1010
 
    def test_actions_except_is_enabled_are_ok_with_two_clients(self):
 
1011
    def test_one_client_with_all_actions_except_is_enabled(self):
 
1012
        options = self.parser.parse_args()
 
1013
        for action, value in self.actions.items():
 
1014
            if action == "is_enabled":
 
1015
                continue
 
1016
            setattr(options, action, value)
 
1017
        options.client = ["foo"]
 
1018
        self.check_option_syntax(options)
 
1019
 
 
1020
    def test_two_clients_with_all_actions_except_is_enabled(self):
 
1021
        options = self.parser.parse_args()
 
1022
        for action, value in self.actions.items():
 
1023
            if action == "is_enabled":
 
1024
                continue
 
1025
            setattr(options, action, value)
 
1026
        options.client = ["foo", "barbar"]
 
1027
        self.check_option_syntax(options)
 
1028
 
 
1029
    def test_two_clients_are_ok_with_actions_except_is_enabled(self):
1011
1030
        for action, value in self.actions.items():
1012
1031
            if action == "is_enabled":
1013
1032
                continue