Revision 17:ea8865f488a0

View differences:

Makefile
1 1

  
2 2
LDFLAGS 	+= -lvamp-hostsdk -ldl
3
CXXFLAGS	+= -Wall -Wextra
3
CXXFLAGS	+= -g -Wall -Wextra
4 4

  
5 5
OBJECTS		:= vamp-plugin-tester.o Tester.o Test.o TestStaticData.o TestInputExtremes.o TestMultipleRuns.o TestOutputs.o TestDefaults.o TestInitialise.o
6 6

  
README
1

  
2
Vamp Plugin Tester
3
==================
4

  
5
This program tests Vamp audio feature extraction plugins
6
(http://vamp-plugins.org/) for certain common failure cases.
7

  
8
To test a single plugin, run vamp-plugin-tester with the name of your
9
plugin library and plugin identifier, separated by a colon.  For example,
10

  
11
  $ vamp-plugin-tester vamp-example-plugins:amplitudefollower
12

  
13
The plugin library must be installed in the Vamp plugin path (you
14
cannot give the path to the library file).
15

  
16
If you run vamp-plugin-tester with no arguments, it will test all
17
plugins found in your Vamp plugin path.
18

  
19

  
20
Options
21
=======
22

  
23
Supply the -v or --verbose option to tell vamp-plugin-tester to print
24
out the whole content of its returned feature log for diagnostic
25
purposes each time it prints an error or warning that arises from the
26
contents of a returned feature.
27

  
28
Supply the -n or --nondeterministic option to tell vamp-plugin-tester
29
that your plugins are expected to return different results each time
30
they are run.  The default behaviour is to treat different results on
31
separate runs with the same input data as an error.
32

  
33

  
34
Errors and Warnings
35
===================
36

  
37
Each test may cause one or several notes, warnings, or errors to be
38
printed.  A note is printed when behaviour is observed that may be
39
correct behaviour but that is not always anticipated by the plugin
40
developer.  A warning is printed when behaviour is observed that is
41
technically legal but that in practice most often happens by mistake.
42
An error is printed when behaviour is observed that cannot be correct.
43

  
44
vamp-plugin-tester prints all of its commentary to the standard
45
output.  Standard error is usually used for diagnostic output printed
46
by the plugins themselves.
47

  
48
In addition to reporting on tests, vamp-plugin-tester runs some tests
49
that are intended to provoke the plugin into unexpected behaviour such
50
as memory errors.  If vamp-plugin-tester crashes during a test, this
51
may be why.  Also, if you have access to a memory checker utility such
52
as valgrind, you are advised to run vamp-plugin-tester under it so as
53
to be informed of any memory errors that do not happen to cause
54
crashes.
55

  
56

  
57
Error and Warning Reference
58
===========================
59

  
60
 ** ERROR: Failed to load plugin
61

  
62
 The plugin could not be loaded.  Remember that the plugin must be
63
 installed in the Vamp plugin path.
64

  
65
 ** ERROR: (plugin|parameter|output) identifier <x> contains invalid characters
66

  
67
 An identifier contains characters other than the permitted set (ASCII
68
 lower and upper case letters, digits, "-" and "_" only).
69

  
70
 ** ERROR: <field> is empty
71

  
72
 A mandatory field, such as the name of a parameter or output,
73
 contains no text.
74

  
75
 ** WARNING: <field> is empty
76

  
77
 An optional field, such as the description of a parameter or output,
78
 contains no text.
79

  
80
 ** ERROR: Plugin parameter <x> maxValue <= minValue
81

  
82
 The minimum and maximum values given for a parameter are equal or in
83
 the wrong order.
84

  
85
 ** ERROR: Plugin parameter <x> defaultValue out of range
86

  
87
 The default value for a parameter is not within the range defined by
88
 the minimum and maximum values for the parameter.
89

  
90
 ** ERROR: Plugin parameter <x> is quantized, but quantize step is zero
91

  
92
 The quantizeStep value in a parameter with isQuantized true is set to
93
 zero.
94

  
95
 ** WARNING: Plugin parameter <x> value range is not a multiple of quantize step
96

  
97
 A parameter's stated maximum value is not one of the possible values
98
 obtained by adding multiples of the quantize step on to the minimum
99
 value.
100

  
101
 ** WARNING: Plugin parameter <x> has (more|fewer) value names than quantize steps
102

  
103
 A quantized parameter lists some value names for its quantize steps,
104
 but not the right number.
105
 
106
 ** WARNING: Plugin parameter <x> default value is not a multiple of quantize
107
 step beyond minimum
108

  
109
 The default value for a parameter is not a value that the user could
110
 actually obtain, if only offered the quantized values to choose from.
111

  
112
 ** ERROR: Data returned on nonexistent output
113

  
114
 The output number key for a returned feature is outside the range of
115
 outputs listed in the plugin's output descriptor list.
116

  
117
 ** NOTE: No results returned for output <x>
118

  
119
 The plugin returned no features on one of its outputs, when given a
120
 simple test file.  This may be perfectly reasonable behaviour, but
121
 you might like to know about it.
122

  
123
 ** NOTE: Plugin returns features with timestamps on OneSamplePerStep output
124
 ** NOTE: Plugin returns features with durations on OneSamplePerStep output
125

  
126
 Hosts will usually ignore timestamps and durations attached to any
127
 feature returned on a OneSamplePerStep output.
128

  
129
 ** ERROR: Plugin returns features with no timestamps on VariableSampleRate output
130

  
131
 Timestamps are mandatory on all features associated with a
132
 VariableSampleRate output.
133

  
134
 ** WARNING: Plugin returned one or more NaN/inf values
135

  
136
 The plugin returned features containing floating-point not-a-number
137
 or infinity values.  This warning may be associated with a test
138
 involving feeding some unexpected type of data to the plugin.
139
 
140
 ** ERROR: Consecutive runs with separate instances produce different results
141

  
142
 The plugin was constructed and run twice against the same input data,
143
 and returned different features each time.
144

  
145
 If you give the -n or --nondeterministic option, vamp-plugin-tester
146
 will downgrade this error to a note.
147

  
148
 ** ERROR: Consecutive runs with the same instance (using reset) produce different results
149

  
150
 The plugin was constructed, initialised, run against some input data,
151
 reset with a call to its reset() function, and run again against the
152
 same data; and it returned different features on each run.  This is
153
 often a sign of some simple error such as forgetting to implement
154
 reset().
155

  
156
 If you give the -n or --nondeterministic option, vamp-plugin-tester
157
 will downgrade this error to a note.
158

  
159
 ** ERROR: Simultaneous runs with separate instances produce different results
160

  
161
 Two instances of the plugin were constructed and run against the same
162
 input data, giving each block of data to one plugin's process call
163
 and then to the other's, "interleaving" the processing between the
164
 two instances (but within a single application thread); and the two
165
 instances returned different features.  This may indicate ill-advised
166
 use of static data shared between plugin instances.
167

  
168
 If you give the -n or --nondeterministic option, vamp-plugin-tester
169
 will downgrade this error to a note.
170

  
171
 ** WARNING: Consecutive runs with different starting timestamps produce the same result
172

  
173
 The plugin was run twice on the same audio data, but with different
174
 input timestamps, and it returned the same results each time.  While
175
 this is often unproblematic, it can indicate that a plugin failed to
176
 take the input timestamp into account when calculating its output
177
 timestamps (if any).
178

  
179
 If you give the -n or --nondeterministic option, vamp-plugin-tester
180
 will downgrade this warning to a note.
181

  
182
 ** ERROR: Explicitly setting current program to its supposed current value changes the results
183

  
184
 The plugin was constructed and run twice on the same data, once
185
 without changing its "program" setting, and again having set the
186
 program to the vaule returned by getCurrentProgram() (i.e. the same
187
 program that was supposed to be in effect already).  It returned
188
 different results for the two runs, suggesting that some internal
189
 data was changed in selectProgram in a way that differed from its
190
 default.
191

  
192
 If you give the -n or --nondeterministic option, vamp-plugin-tester
193
 will downgrade this error to a note.
194

  
195
 ** ERROR: Explicitly setting parameters to their supposed default values changes the results
196

  
197
 The plugin was constructed and run twice on the same data, once
198
 without changing any of its parameters, and again having set the
199
 parameters to their specified default values.  It returned different
200
 results for the two runs, suggesting that some internal data was
201
 changed when a parameter was set to its default, in a way that
202
 differed from the plugin's initially constructed state.
203

  
204
 If you give the -n or --nondeterministic option, vamp-plugin-tester
205
 will downgrade this error to a note.
206

  
207
 ** WARNING: Constructor takes some time to run: work should be deferred to initialise?
208

  
209
 The plugin took a long time to construct.  You should ensure that the
210
 constructor for the plugin runs as quickly as possible, because it
211
 may be called by a host that is only scanning the properties of all
212
 available plugins on startup.  Any serious initialisation work should
213
 be done in the initialise() function rather than the constructor.
214

  
215

  
TestInputExtremes.cpp
94 94
    if (allFeaturesValid(f)) {
95 95
        r.push_back(success());
96 96
    } else {
97
        r.push_back(warning("plugin returned one or more NaN/inf values"));
97
        r.push_back(warning("Plugin returned one or more NaN/inf values"));
98 98
        if (options & Verbose) dump(f);
99 99
    }
100 100
    return r;
......
111 111
    if (allFeaturesValid(fs)) {
112 112
        r.push_back(success());
113 113
    } else {
114
        r.push_back(warning("plugin returned one or more NaN/inf values"));
114
        r.push_back(warning("Plugin returned one or more NaN/inf values"));
115 115
    }
116 116
    return r;
117 117
}
......
141 141
    if (allFeaturesValid(f)) {
142 142
        r.push_back(success());
143 143
    } else {
144
        r.push_back(warning("plugin returned one or more NaN/inf values"));
144
        r.push_back(warning("Plugin returned one or more NaN/inf values"));
145 145
        if (options & Verbose) dump(f);
146 146
    }
147 147
    return r;
......
173 173
    if (allFeaturesValid(f)) {
174 174
        r.push_back(success());
175 175
    } else {
176
        r.push_back(warning("plugin returned one or more NaN/inf values"));
176
        r.push_back(warning("Plugin returned one or more NaN/inf values"));
177 177
        if (options & Verbose) dump(f);
178 178
    }
179 179
    return r;
......
207 207
    if (allFeaturesValid(f)) {
208 208
        r.push_back(success());
209 209
    } else {
210
        r.push_back(warning("plugin returned one or more NaN/inf values"));
210
        r.push_back(warning("Plugin returned one or more NaN/inf values"));
211 211
        if (options & Verbose) dump(f);
212 212
    }
213 213
    return r;
......
241 241
    if (allFeaturesValid(f)) {
242 242
        r.push_back(success());
243 243
    } else {
244
        r.push_back(warning("plugin returned one or more NaN/inf values"));
244
        r.push_back(warning("Plugin returned one or more NaN/inf values"));
245 245
        if (options & Verbose) dump(f);
246 246
    }
247 247
    return r;
TestStaticData.cpp
62 62
    auto_ptr<Plugin> p(load(key));
63 63
    
64 64
    Results r;
65
    r.push_back(testIdentifier(p->getIdentifier(), "plugin identifier"));
65
    r.push_back(testIdentifier(p->getIdentifier(), "Plugin identifier"));
66 66

  
67 67
    Plugin::ParameterList params = p->getParameterDescriptors();
68 68
    for (int i = 0; i < (int)params.size(); ++i) {
69
        r.push_back(testIdentifier(params[i].identifier, "parameter identifier"));
69
        r.push_back(testIdentifier(params[i].identifier, "Parameter identifier"));
70 70
    }
71 71

  
72 72
    Plugin::OutputList outputs = p->getOutputDescriptors();
73 73
    for (int i = 0; i < (int)outputs.size(); ++i) {
74
        r.push_back(testIdentifier(outputs[i].identifier, "output identifier"));
74
        r.push_back(testIdentifier(outputs[i].identifier, "Output identifier"));
75 75
    }
76 76

  
77 77
    return r;
......
100 100

  
101 101
    Results r;
102 102

  
103
    r.push_back(testMandatory(p->getName(), "plugin name"));
104
    r.push_back(testRecommended(p->getDescription(), "plugin description"));
105
    r.push_back(testRecommended(p->getMaker(), "plugin maker"));
106
    r.push_back(testRecommended(p->getCopyright(), "plugin copyright"));
103
    r.push_back(testMandatory(p->getName(), "Plugin name"));
104
    r.push_back(testRecommended(p->getDescription(), "Plugin description"));
105
    r.push_back(testRecommended(p->getMaker(), "Plugin maker"));
106
    r.push_back(testRecommended(p->getCopyright(), "Plugin copyright"));
107 107
    
108 108
    Plugin::ParameterList params = p->getParameterDescriptors();
109 109
    for (int i = 0; i < (int)params.size(); ++i) {
110 110
        r.push_back(testMandatory
111 111
                    (params[i].name,
112
                     "plugin parameter \"" + params[i].identifier + "\" name"));
112
                     "Plugin parameter \"" + params[i].identifier + "\" name"));
113 113
        r.push_back(testRecommended
114 114
                    (params[i].description,
115
                     "plugin parameter \"" + params[i].identifier + "\" description"));
115
                     "Plugin parameter \"" + params[i].identifier + "\" description"));
116 116
    }
117 117
    
118 118
    Plugin::OutputList outputs = p->getOutputDescriptors();
119 119
    for (int i = 0; i < (int)outputs.size(); ++i) {
120 120
        r.push_back(testMandatory
121 121
                    (outputs[i].name,
122
                     "plugin output \"" + outputs[i].identifier + "\" name"));
122
                     "Plugin output \"" + outputs[i].identifier + "\" name"));
123 123
        r.push_back(testRecommended
124 124
                    (outputs[i].description,
125
                     "plugin output \"" + outputs[i].identifier + "\" description"));
125
                     "Plugin output \"" + outputs[i].identifier + "\" description"));
126 126
    }
127 127

  
128 128
    return r;
......
156 156
    Plugin::ParameterList params = p->getParameterDescriptors();
157 157
    for (int i = 0; i < (int)params.size(); ++i) {
158 158
        Plugin::ParameterDescriptor &pd(params[i]);
159
        string pfx("plugin parameter \"" + pd.identifier + "\"");
159
        string pfx("Plugin parameter \"" + pd.identifier + "\"");
160 160
        float min = pd.minValue;
161 161
        float max = pd.maxValue;
162 162
        float deft = pd.defaultValue;
Tester.cpp
181 181
            }
182 182
        }
183 183
    } catch (Test::FailedToLoadPlugin) {
184
        std::cout << "ERROR: Failed to load plugin (key = \"" << m_key
184
        std::cout << " ** ERROR: Failed to load plugin (key = \"" << m_key
185 185
                  << "\")" << std::endl;
186 186
    }
187 187

  

Also available in: Unified diff