-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathREADME.devel-tests
125 lines (94 loc) · 4.75 KB
/
README.devel-tests
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
<!-- To convert to html: pandoc -o foo.html README.devel-test -->
About This README
=================
This document describes how to add, extend, or fix individual
rpmgrill test plugins. It is targeted to commando developers:
those who simply want to jump in, write some test code, dash
back out, nobody gets hurt. You must be familiar with Fedora
build processes, with RPM and specfile development (to a degree;
you don't need to be Panu), and be willing to dabble in Perl.
No Perl expertise needed, just the ability to learn by example.
You will need some basic familiarity with rpmgrill and its
invocation; see README.AAA_FIRST.
Overview
========
All plugins live under the `lib/RPM/Grill/Plugin/` subdirectory.
All plugins work the same way:
1. Someone (rpmgrill) invokes the plugin's **->analyze()** method. No args.
`$self` will be an `RPM::Grill::Plugin::Xxxxx` object, where `Xxxxx`
is the plugin package name.
2. `analyze()` examines RPMs and invokes **`->gripe()`** when it
detects a problem.
That's it. `analyze()` then returns; as of this writing (Sept 2012)
its return values is ignored. `analyze()` can even die: the calling code
will trap it and mark the test as failed.
Zeroth Decision: Can You Piggyback?
-----------------------------------
Before you start writing code: does your test fit into any of the
existing plugins? You can save development effort as well as run time
by adding your logic to one of the existing tests. Keep reading, but
keep in mind the possibility of adding on to an existing test.
First Decision: What to Analyze
-------------------------------
To date, most plugins work in one of two ways:
a) check something in the SRPM, e.g. the specfile
b) check something in all (or possibly a subset of) built RPMs.
(there are some exceptions: `BuildLog.pm`, which examines log files
outside of the built RPMs; `VirusCheck.pm` which simply checks files
without knowing or caring about their RPMness. If that's what you need,
go peruse them and skip this section.)
If you're checking the specfile, you'll probably want a loop like:
for my $line ($self->specfile->lines) { ... }
See `Patches.pm` and `SpecFileEncoding.pm` for examples.
For almost anything else, you'll want to start with a loop such as:
for my $rpm ($self->rpms) {
for my $f ($rpm->files) {
$self->_do_something_with( $f );
}
}
See `Setxid.pm` for a simple example of this type of test;
or `Manifest.pm` for a more complex one.
Second Decision: How/What to Gripe
----------------------------------
The heart of rpmgrill is the gripe messages. These are collected
by rpmgrill, and preserved in such a way that another tool can store
into a database for presenting to developers. A minimal call looks like:
$self->gripe({
code => 'MyGripeCode',
diag => "This is a human-readable message complaining about $file",
});
Those are the crucial elements: `code` is a StudlyCaps error code
unique to this gripe (or, in some special cases, shared among a
very few gripes); `diag` is a human-readable string explaining
the warning and perhaps giving context (e.g. filename).
When applicable, you might want to include `arch` and/or `subpackage`.
These will be included automatically if you use `$rpm->gripe()` or
`$f->gripe()` (instead of `$self`).
Context ... well, I didn't really get it right. I'm sorry. The gist
is that you can use it to specify a filename, or an excerpt from a file
(such as a log file or a bad config entry), and/or a line number:
$self->gripe({
code => '...', diag => '...',
context => {
path => '/path/to/file',
excerpt => $excerpt,
} });
The problem is that sometimes 'path' is a specfile; and that
sometimes you're complaining *about* a path (e.g. 'Fedora in Filename')
and sometimes about something *in* the file. And sometimes you
want to aggregate files together into one message ('The following
files have such-and-such a problem: ...'), sometimes you don't.
Testing
=======
The test scaffolding is clunky. I'm sorry. But you're going to write
regression tests anyway, because that's the kind of person you are.
Each plugin `Xxxxx` has a corresponding subdirectory `t/RPM/Grill/Plugin/Xxxxx`
containing one or more `NNfoo.t` scripts. Each of those does some setup,
invokes the plugin (or perhaps a function inside the plugin), then
checks results. This is complicated because of all the setup needed
by each plugin (populated RPM::Grill object) and because of the
structure of the gripes.
I recommend starting with `t/RPM/Grill/Plugin/ManPages/10basic.t`.
At this writing (September 2012) it's the cleanest test script and
the only one using `t/lib/FakeTree.pm`, a reusable library for
doing the RPM::Grill setup work.