summaryrefslogtreecommitdiff
path: root/python/samba/tests/samba_tool/help.py
blob: f631e2420d1863568a1d72be492156baa3063626 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# Unix SMB/CIFS implementation.
# Copyright (C) Catalyst IT Ltd 2017.
#
# Originally written by Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import os
import re
from samba.tests.samba_tool.base import SambaToolCmdTest
from samba.tests import BlackboxProcessError, BINDIR
from samba.tests import check_help_consistency
from samba.common import get_string
from samba import version
from pathlib import Path


class HelpTestCase(SambaToolCmdTest):
    """Tests for samba-tool help and --help

    We test for consistency and lack of crashes."""

    def _find_sub_commands(self, args):
        self.runcmd(*args)

    def test_help_tree(self):
        # we call actual subprocesses, because we are probing the
        # actual help output where there is no sub-command. Don't copy
        # this if you have an actual command: for that use
        # self.runcmd() or self.runsubcmd().
        known_commands = [[]]
        failed_commands = []
        undocumented = []
        with open(Path(BINDIR) / '../docs-xml/manpages/samba-tool.8.xml') as f:
            man = f.read()

        for i in range(4):
            new_commands = []
            for c in known_commands:
                if ' '.join(c) not in man:
                    undocumented.append(c)
                line = ' '.join(['samba-tool'] + c + ['--help'])
                try:
                    output = self.check_output(line)
                except BlackboxProcessError as e:
                    output = e.stdout
                    failed_commands.append(c)
                output = get_string(output)
                tail = output.partition('Available subcommands:')[2]
                subcommands = re.findall(r'^\s*([\w-]+)\s+-', tail,
                                         re.MULTILINE)
                for s in subcommands:
                    new_commands.append(c + [s])

                # check that `samba-tool help X Y` == `samba-tool X Y --help`
                line = ' '.join(['samba-tool', 'help'] + c)
                try:
                    output2 = self.check_output(line)
                except BlackboxProcessError as e:
                    output2 = e.stdout
                    failed_commands.append(c)

                output2 = get_string(output2)
                self.assertEqual(output, output2)

                err = check_help_consistency(output,
                                             options_start='Options:',
                                             options_end='Available subcommands:')
                if err is not None:
                    self.fail("consistency error with %s:\n%s" % (line, err))

            if not new_commands:
                break

            known_commands = new_commands

        self.assertEqual(failed_commands, [])

        if undocumented:
            print("-=" * 36)
            print("\nPlease update `man samba-tool`!\n")
            print("Some samba-tool subcommands seem to missing from the man-page!")
            print("To help fix this, below are Docbook-like snippets based on the ")
            print("--help text. Please modify these to be correct (both as XML and")
            print("as content) and add them to docs-xml/manpages/samba-tool.8.xml")
            print("Remember, you can explain things more deeply in a man-page,")
            print("but you can also trim off common options that have already been")
            print("explained.")
            print()
            env = dict(os.environ)
            env['SAMBATOOL_HELP_IS_XML'] = '1'
            for c in undocumented:
                line = ' '.join(['samba-tool'] + c + ['--help'])
                print(f" <!-- SAMBATOOL_HELP_IS_XML=1 {line} -->")
                try:
                    output = self.check_output(line, env=env)
                except BlackboxProcessError as e:
                    print(f"<!-- {e} ->")
                print(output.decode())
                print()
            print("-=" * 36)
            self.fail("Some commands are undocumented. See test output for help")

    def test_bad_password_option(self):
        """Do we get a warning with an invalid --pass option?"""
        (result, out, err) = self.run_command(["samba-tool",
                                               "processes",
                                               "--pass-the-salt-please",
                                               "pleeease"])
        self.assertIn("if '--pass-the-salt-please' is not misspelt", err)
        self.assertIn("the appropriate list in is_password_option", err)

    def test_version(self):
        """Does --version work?"""
        (result, out, err) = self.run_command(["samba-tool", "--version"])
        self.assertEqual(version, out.strip())

    def test_sub_command_version(self):
        """Does --version work in a sub-command?"""
        (result, out, err) = self.run_command(["samba-tool", "spn", "--version"])
        self.assertEqual(version, out.strip())

    def test_leaf_command_version(self):
        """Does --version work in a leaf command?"""
        (result, out, err) = self.run_command(["samba-tool", "contact", "edit",
                                               "--version"])
        self.assertEqual(version, out.strip())

    def test_help_version(self):
        """Is version mentioned in --help?"""
        (result, out, err) = self.run_command(["samba-tool", "spn", "--help"])
        self.assertIn(version, out)

    def test_version_beats_help(self):
        """Does samba-tool --help --version print version?"""
        (result, out, err) = self.run_command(["samba-tool", "spn", "--help", "-V"])
        self.assertEqual(version, out.strip())
        (result, out, err) = self.run_command(["samba-tool", "--help", "-V"])
        self.assertEqual(version, out.strip())
        (result, out, err) = self.run_command(["samba-tool", "dns", "-V", "--help"])
        self.assertEqual(version, out.strip())