podman

Форк
0
/
xref-helpmsgs-manpages.t 
410 строк · 14.4 Кб
1
# -*- perl -*-
2
#
3
# tests for xref-helpmsgs-manpages
4
#
5

6
use v5.20;
7
use strict;
8
use warnings;
9

10
use Clone                       qw(clone);
11
use File::Basename;
12
use File::Path                  qw(make_path);
13
use File::Temp                  qw(tempdir);
14
use FindBin;
15
use Test::More;
16
use Test::Differences;
17

18
plan tests => 10;
19

20
require_ok "$FindBin::Bin/xref-helpmsgs-manpages";
21

22

23
my $workdir = tempdir(basename($0) . ".XXXXXXXX", TMPDIR => 1, CLEANUP => 1);
24

25
# Copy man pages to tmpdir, so we can fiddle with them
26
my $doc_path = do {
27
    no warnings 'once';
28
    "$LibPod::CI::XrefHelpmsgsManpages::Markdown_Path";
29
};
30

31
make_path "$workdir/$doc_path"
32
    or die "Internal error: could not make_path $workdir/$doc_path";
33
system('rsync', '-a', "$doc_path/." => "$workdir/$doc_path/.") == 0
34
    or die "Internal error: could not rsync $doc_path to $workdir";
35

36
chdir $workdir
37
    or die "Internal error: could not cd $workdir: $!";
38

39
my @warnings_seen;
40
$SIG{__WARN__} = sub {
41
    my $msg = shift;
42
    chomp $msg;
43
    $msg =~ s/^xref-\S+?:\s+//;         # strip "$ME: "
44
    $msg =~ s!(^|\s+)$doc_path/!$1!g;   # strip "doc/source/markdown"
45
    $msg =~ s!:\d+:!:NNN:!;             # file line numbers can change
46
   push @warnings_seen, $msg;
47
};
48

49
# When we get errors (hopefully only when adding new functionality
50
# to this test!), this format is MUCH easier to read and copy-paste.
51
unified_diff;
52

53
# Helper function for running xref tests.
54
sub test_xref {
55
    my $name = shift;
56
    my $h = shift;
57
    my $m = shift;
58
    my $expect_by_help = shift;
59
    my $expect_by_man  = shift;
60

61
    @warnings_seen = ();
62
    LibPod::CI::XrefHelpmsgsManpages::xref_by_help($h, $m);
63
    eq_or_diff_text \@warnings_seen, $expect_by_help, "$name: xref_by_help()";
64

65
    @warnings_seen = ();
66
    LibPod::CI::XrefHelpmsgsManpages::xref_by_man($h, $m);
67
    eq_or_diff_text \@warnings_seen, $expect_by_man, "$name: xref_by_man()";
68
}
69

70
###############################################################################
71
# BEGIN Baseline tests
72
#
73
# Confirm that everything passes in the current tree
74

75
my $help = LibPod::CI::XrefHelpmsgsManpages::podman_help();
76
eq_or_diff_text \@warnings_seen, [], "podman_help() runs cleanly, no warnings";
77

78
@warnings_seen = ();
79
my $man = LibPod::CI::XrefHelpmsgsManpages::podman_man('podman');
80
eq_or_diff_text \@warnings_seen, [], "podman_man() runs cleanly, no warnings";
81

82
# If this doesn't pass, we've got big problems.
83
test_xref("baseline", $help, $man, [], []);
84

85
#use Data::Dump; dd $man; exit 0;
86

87
# END   Baseline tests
88
##########################################################################
89
# BEGIN fault injection tests on xref_by_man()
90
#
91
# These are really simple: only two different warnings.
92

93
my $hclone = clone($help);
94
my $mclone = clone($man);
95

96
delete $hclone->{network}{ls}{"--format"};
97
delete $hclone->{save};
98
$mclone->{"command-in-man"} = {};
99
$mclone->{"system"}{"subcommand-in-man"} = {};
100

101
# --format field documented in man page but not in autocomplete
102
delete $hclone->{events}{"--format"}{".HealthStatus"};
103

104
test_xref("xref_by_man injection", $hclone, $mclone,
105
          [],
106
          [
107
              "'podman ': 'command-in-man' in podman.1.md, but not in --help",
108
              "'podman events --format': '.HealthStatus' in podman-events.1.md, but not in command completion",
109
              "'podman network ls': --format options documented in man page, but not available via autocomplete",
110
              "'podman ': 'save' in podman.1.md, but not in --help",
111
              "'podman system': 'subcommand-in-man' in podman-system.1.md, but not in --help",
112
          ],
113
      );
114

115
# END   fault injection tests on xref_by_man()
116
###############################################################################
117
# BEGIN fault injection tests on xref_by_help()
118
#
119
# These are much more complicated.
120

121
$hclone = clone($help);
122
$mclone = clone($man);
123

124
# --format is not documented in man page
125
delete $mclone->{"auto-update"}{"--format"};
126
# --format is documented, but without a table
127
$mclone->{container}{list}{"--format"} = 1;
128
# --format is documented, with a table, but entries are wrong
129
$mclone->{events}{"--format"}{".Attributes"} = 0;
130
$mclone->{events}{"--format"}{".Image"} = '...';
131
$mclone->{events}{"--format"}{".Status"} = 1;
132
$hclone->{events}{"--format"}{".Status"} = '...';
133
$mclone->{pod}{ps}{"--format"}{".Label"} = 3;
134
$mclone->{ps}{"--format"}{".Label"} = 0;
135
# --format is documented, with a table, but one entry missing
136
delete $mclone->{events}{"--format"}{".Type"};
137

138
# -l option is not documented
139
delete $mclone->{pod}{inspect}{"-l"};
140

141
# Command and subcommand in podman --help, but not in man pages
142
$hclone->{"new-command-in-help"} = {};
143
$hclone->{"secret"}{"subcommand-in-help"} = {};
144

145
# Can happen if podman-partlydocumented exists in --help, and is listed
146
# in podman.1.md, but does not have its own actual man page.
147
$hclone->{partlydocumented} = { "something" => 1 };
148
$mclone->{partlydocumented} = undef;
149

150
test_xref("xref_by_help() injection", $hclone, $mclone,
151
          [
152
              "'podman auto-update --help' lists '--format', which is not in podman-auto-update.1.md",
153
              "'podman container list': --format options are available through autocomplete, but are not documented in podman-ps.1.md",
154
              "'podman events --format {{.Attributes' is a nested structure. Please add '...' to man page.",
155
              "'podman events --format {{.Image' is a simple value, not a nested structure. Please remove '...' from man page.",
156
              "'podman events --format {{.Status' is a nested structure, but the man page documents it as a function?!?",
157
              "'podman events --format <TAB>' lists '.Type', which is not in podman-events.1.md",
158
              "'podman  --help' lists 'new-command-in-help', which is not in podman.1.md",
159
              "'podman partlydocumented' is not documented in man pages!",
160
              "'podman pod inspect --help' lists '-l', which is not in podman-pod-inspect.1.md",
161
              "'podman pod ps --format {{.Label' is a function that calls for 1 args; the man page lists 3. Please fix the man page.",
162
              "'podman ps --format {{.Label' is a function that calls for 1 args. Please investigate what those are, then add them to the man page. E.g., '.Label *bool*' or '.Label *path* *bool*'",
163
              "'podman secret --help' lists 'subcommand-in-help', which is not in podman-secret.1.md",
164
          ],
165
          [],
166
      );
167

168
# END   fault injection tests on xref_by_help()
169
###############################################################################
170
# BEGIN fault injection tests on podman_man()
171
#
172
# This function has a ton of sanity checks. To test them we need to
173
# perform minor surgery on lots of .md files: reordering lines,
174
# adding inconsistencies.
175
#
176

177
# Ordered list of the warnings we expect to see
178
my @expect_warnings;
179

180
# Helper function: given a filename and a function, reads filename
181
# line by line, invoking filter on each line and writing out the
182
# results.
183
sub sed {
184
    my $path   = shift;                 # in: filename (something.md)
185
    my $action = shift;                 # in: filter function
186

187
    # The rest of our arguments are the warnings introduced into this man page
188
    push @expect_warnings, @_;
189

190
    open my $fh_in, '<', "$doc_path/$path"
191
        or die "Cannot read $doc_path/$path: $!";
192
    my $tmpfile = "$doc_path/$path.tmp.$$";
193
    open my $fh_out, '>', $tmpfile
194
        or die "Cannot create $doc_path/$tmpfile: $!";
195

196
    while (my $line = <$fh_in>) {
197
        # This is what does all the magic
198
        print { $fh_out } $action->($line);
199
    }
200
    close $fh_in;
201
    close $fh_out
202
        or die "Error writing $doc_path/$tmpfile: $!";
203
    rename "$tmpfile" => "$doc_path/$path"
204
        or die "Could not rename $doc_path/$tmpfile: $!";
205
}
206

207
# Start filtering.
208

209
# podman-attach is a deliberate choice here: it also serves as the man page
210
# for podman-container-attach. Prior to 2023-12-20 we would read the file
211
# twice, issuing two warnings, which is anti-helpful. Here we confirm that
212
# the dup-removing code works.
213
sed('podman-attach.1.md', sub {
214
        my $line = shift;
215
        $line =~ s/^(%\s+podman)-(attach\s+1)/$1 $2/;
216
        $line;
217
    },
218

219
    "podman-attach.1.md:NNN: wrong title line '% podman attach 1'; should be '% podman-attach 1'",
220
);
221

222

223
# Tests for broken command-line options
224
# IMPORTANT NOTE: podman-exec precedes podman-container (below),
225
# because podman-exec.1.md is actually read while podman-container.1.md
226
# is still processing; so these messages are printed earlier:
227
#   podman-container.1.md  -> list of subcommands -> exec -> read -exec.1.md
228
# Sorry for the confusion.
229
sed('podman-exec.1.md', sub {
230
        my $line = shift;
231

232
        if ($line =~ /^#### \*\*--env\*\*/) {
233
            $line = $line . "\ndup dup dup\n\n" . $line;
234
        }
235
        elsif ($line =~ /^#### \*\*--privileged/) {
236
            $line = "#### \*\*--put-me-back-in-order\*\*\n\nbogus option\n\n" . $line;
237
        }
238
        elsif ($line =~ /^#### \*\*--tty\*\*/) {
239
            chomp $line;
240
            $line .= " xyz\n";
241
        }
242
        elsif ($line =~ /^#### \*\*--workdir\*\*/) {
243
            $line = <<"END_FOO";
244
#### **--workdir**=*dir*, **-w**
245

246
blah blah bogus description
247

248
#### **--yucca**=*cactus*|*starch*|*both*
249

250
blah blah
251

252
#### **--zydeco**=*true* | *false*
253

254
END_FOO
255
        }
256

257
        return $line;
258
    },
259

260
    "podman-exec.1.md:NNN: flag '--env' is a dup",
261
    "podman-exec.1.md:NNN: --privileged should precede --put-me-back-in-order",
262
    "podman-exec.1.md:NNN: could not parse ' xyz' in option description",
263
    "podman-exec.1.md:NNN: please rewrite as ', **-w**=*dir*'",
264
    "podman-exec.1.md:NNN: values must be space-separated: '=*cactus*|*starch*|*both*'",
265
    "podman-exec.1.md:NNN: Do not enumerate true/false for boolean-only options",
266
);
267

268

269
# Tests for subcommands in a table
270
sed('podman-container.1.md', sub {
271
        my $line = shift;
272

273
        # "podman container diff": force an out-of-order error
274
        state $diff;
275
        if ($line =~ /^\|\s+diff\s+\|/) {
276
            $diff = $line;
277
            return '';
278
        }
279
        if ($diff) {
280
            $line .= $diff;
281
            $diff = undef;
282
        }
283

284
        # "podman init": force a duplicate-command error
285
        if ($line =~ /^\|\s+init\s+\|/) {
286
            $line .= $line;
287
        }
288

289
        # "podman container port": force a wrong-man-page error
290
        if ($line =~ /^\|\s+port\s+\|/) {
291
            $line =~ s/-port\.1\.md/-top.1.md/;
292
        }
293

294
        return $line;
295
    },
296

297
    "podman-container.1.md:NNN: 'exec' and 'diff' are out of order",
298
    "podman-container.1.md:NNN: duplicate subcommand 'init'",
299
    # FIXME: this is not technically correct; it could be the other way around.
300
    "podman-container.1.md:NNN: 'podman-port' should be 'podman-top' in '[podman-port(1)](podman-top.1.md)'",
301
);
302

303

304
# Tests for --format specifiers in a table
305
sed('podman-image-inspect.1.md', sub {
306
        my $line = shift;
307

308
        state $digest;
309
        if ($line =~ /^\|\s+\.Digest\s+\|/) {
310
            $digest = $line;
311
            return '';
312
        }
313
        if ($digest) {
314
            $line .= $digest;
315
            $digest = undef;
316
        }
317

318
        if ($line =~ /^\|\s+\.ID\s+\|/) {
319
            $line = $line . $line;
320
        }
321

322
        $line =~ s/^\|\s+\.Parent\s+\|/| .Parent BAD-ARG |/;
323
        $line =~ s/^\|\s+\.Size\s+\|/| .Size *arg1* arg2 |/;
324

325
        return $line;
326
    },
327

328
    "podman-image-inspect.1.md:NNN: format specifier '.Digest' should precede '.GraphDriver'",
329
    "podman-image-inspect.1.md:NNN: format specifier '.ID' is a dup",
330
    "podman-image-inspect.1.md:NNN: unknown args 'BAD-ARG' for '.Parent'. Valid args are '...' for nested structs or, for functions, one or more asterisk-wrapped argument names.",
331
    "podman-image-inspect.1.md:NNN: unknown args '*arg1* arg2' for '.Size'. Valid args are '...' for nested structs or, for functions, one or more asterisk-wrapped argument names.",
332
);
333

334

335
# Tests for SEE ALSO section
336
sed('podman-version.1.md', sub {
337
        my $line = shift;
338

339
        if ($line =~ /^## SEE ALSO/) {
340
            $line .= "**foo**,**bar**"
341
                . ", **baz**baz**"
342
                . ", missingstars"
343
                . ", **[podman-info(1)](podman-cp.1.md)**"
344
                . ", **[podman-foo(1)](podman-wait.1.md)**"
345
                . ", **[podman-x](podman-bar.1.md)**"
346
                . ", **podman-logs(1)**"
347
                . ", **podman-image-rm(1)**"
348
                . ", **sdfsdf**"
349
                . "\n";
350
        }
351

352
        return $line;
353
    },
354

355
    "podman-version.1.md:NNN: please add space after comma: '**foo**,**bar**'",
356
    "podman-version.1.md:NNN: invalid token 'baz**baz'",
357
    "podman-version.1.md:NNN: 'missingstars' should be bracketed by '**'",
358
    "podman-version.1.md:NNN: inconsistent link podman-info(1) -> podman-cp.1.md, expected podman-info.1.md",
359
    "podman-version.1.md:NNN: invalid link podman-foo(1) -> podman-wait.1.md",
360
    "podman-version.1.md:NNN: could not parse 'podman-x' as 'manpage(N)'",
361
    "podman-version.1.md:NNN: 'podman-logs(1)' should be '[podman-logs(1)](podman-logs.1.md)'",
362
    "podman-version.1.md:NNN: 'podman-image-rm(1)' refers to a command alias; please use the canonical command name instead",
363
    "podman-version.1.md:NNN: invalid token 'sdfsdf'"
364
);
365

366

367
# Tests for --filter specifiers
368
sed('podman-volume-prune.1.md', sub {
369
        my $line = shift;
370

371
        if ($line =~ /^\|\s+driver\s+\|/) {
372
            $line = "| name! | sdfsdf |\n" . $line;
373
        }
374
        if ($line =~ /^\|\s+opt\s+\|/) {
375
            $line .= $line;
376
        }
377

378
        return $line;
379
    },
380

381
    "podman-volume-prune.1.md:NNN: filter 'name!' only allowed immediately after its positive",
382
    "podman-volume-prune.1.md:NNN: filter specifier 'opt' is a dup",
383
);
384

385
# DONE with fault injection. Reread man pages and verify warnings.
386
@warnings_seen = ();
387
{
388
    no warnings 'once';
389
    %LibPod::CI::XrefHelpmsgsManpages::Man_Seen = ();
390
}
391
$man = LibPod::CI::XrefHelpmsgsManpages::podman_man('podman');
392
eq_or_diff_text \@warnings_seen, \@expect_warnings, "podman_man() with faults";
393

394
# END   fault injection tests on podman_man()
395
###############################################################################
396
# BEGIN fault injection tests on podman_help()
397
#
398
# Nope, this is not likely to happen. In order to do this we'd need to:
399
#
400
#   * instrument podman and cobra to emit fake output; or
401
#   * write a podman wrapper that selectively munges output; or
402
#   * write a dummy podman that generates the right form of (broken) output.
403
#
404
# podman_help() has few sanity checks, and those are unlikely, so doing this
405
# is way more effort than it's worth.
406
#
407
# END   fault injection tests on podman_help()
408
###############################################################################
409

410
1;
411

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.