annotate TestStaticData.cpp @ 80:f84e12a1553c tip

Update server certificate fingerprints
author Chris Cannam
date Wed, 14 Aug 2019 14:58:48 +0100
parents 69e7d4e1e68c
children
rev   line source
cannam@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@0 2
cannam@0 3 /*
cannam@0 4 Vamp Plugin Tester
cannam@0 5 Chris Cannam, cannam@all-day-breakfast.com
cannam@0 6 Centre for Digital Music, Queen Mary, University of London.
Chris@42 7 Copyright 2009-2014 QMUL.
cannam@0 8
cannam@0 9 This program loads a Vamp plugin and tests its susceptibility to a
cannam@0 10 number of common pitfalls, including handling of extremes of input
cannam@0 11 data. If you can think of any additional useful tests that are
cannam@0 12 easily added, please send them to me.
cannam@0 13
cannam@0 14 Permission is hereby granted, free of charge, to any person
cannam@0 15 obtaining a copy of this software and associated documentation
cannam@0 16 files (the "Software"), to deal in the Software without
cannam@0 17 restriction, including without limitation the rights to use, copy,
cannam@0 18 modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@0 19 of the Software, and to permit persons to whom the Software is
cannam@0 20 furnished to do so, subject to the following conditions:
cannam@0 21
cannam@0 22 The above copyright notice and this permission notice shall be
cannam@0 23 included in all copies or substantial portions of the Software.
cannam@0 24
cannam@0 25 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@0 26 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@0 27 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@0 28 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@0 29 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@0 30 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@0 31 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@0 32
cannam@0 33 Except as contained in this notice, the names of the Centre for
cannam@0 34 Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@0 35 shall not be used in advertising or otherwise to promote the sale,
cannam@0 36 use or other dealings in this Software without prior written
cannam@0 37 authorization.
cannam@0 38 */
cannam@0 39
cannam@0 40 #include "TestStaticData.h"
cannam@0 41
cannam@0 42 #include <vamp-hostsdk/Plugin.h>
Chris@35 43 #include <vamp-hostsdk/PluginLoader.h>
cannam@0 44 using namespace Vamp;
Chris@35 45 using namespace Vamp::HostExt;
cannam@0 46
cannam@0 47 #include <memory>
cannam@0 48 using namespace std;
cannam@0 49
cannam@0 50 #include <cmath>
cannam@0 51
cannam@0 52 Tester::TestRegistrar<TestIdentifiers>
Chris@39 53 TestIdentifiers::m_registrar("A1", "Invalid identifiers");
cannam@0 54
cannam@0 55 Tester::TestRegistrar<TestEmptyFields>
Chris@39 56 TestEmptyFields::m_registrar("A2", "Empty metadata fields");
cannam@0 57
cannam@0 58 Tester::TestRegistrar<TestValueRanges>
Chris@39 59 TestValueRanges::m_registrar("A3", "Inappropriate value extents");
cannam@0 60
Chris@35 61 Tester::TestRegistrar<TestCategory>
Chris@79 62 TestCategory::m_registrar("A4", "Missing category");
Chris@35 63
cannam@0 64 Test::Results
cannam@14 65 TestIdentifiers::test(string key, Options)
cannam@0 66 {
cannam@0 67 auto_ptr<Plugin> p(load(key));
cannam@0 68
cannam@0 69 Results r;
cannam@17 70 r.push_back(testIdentifier(p->getIdentifier(), "Plugin identifier"));
cannam@0 71
cannam@0 72 Plugin::ParameterList params = p->getParameterDescriptors();
cannam@0 73 for (int i = 0; i < (int)params.size(); ++i) {
cannam@17 74 r.push_back(testIdentifier(params[i].identifier, "Parameter identifier"));
cannam@0 75 }
cannam@0 76
cannam@0 77 Plugin::OutputList outputs = p->getOutputDescriptors();
cannam@0 78 for (int i = 0; i < (int)outputs.size(); ++i) {
cannam@17 79 r.push_back(testIdentifier(outputs[i].identifier, "Output identifier"));
cannam@0 80 }
cannam@0 81
cannam@0 82 return r;
cannam@0 83 }
cannam@0 84
cannam@0 85 Test::Result
cannam@0 86 TestIdentifiers::testIdentifier(string identifier, string desc)
cannam@0 87 {
cannam@0 88 for (int i = 0; i < (int)identifier.length(); ++i) {
cannam@0 89 char c = identifier[i];
cannam@0 90 if (c >= 'a' && c <= 'z') continue;
cannam@0 91 if (c >= 'A' && c <= 'Z') continue;
cannam@0 92 if (c >= '0' && c <= '9') continue;
cannam@0 93 if (c == '_' || c == '-') continue;
cannam@0 94 return error
cannam@0 95 (desc + " \"" + identifier +
cannam@0 96 "\" contains invalid character(s); permitted are: [a-zA-Z0-9_-]");
cannam@0 97 }
cannam@0 98 return success();
cannam@0 99 }
cannam@0 100
cannam@0 101 Test::Results
cannam@14 102 TestEmptyFields::test(string key, Options)
cannam@0 103 {
cannam@0 104 auto_ptr<Plugin> p(load(key));
cannam@0 105
cannam@0 106 Results r;
cannam@0 107
cannam@17 108 r.push_back(testMandatory(p->getName(), "Plugin name"));
cannam@17 109 r.push_back(testRecommended(p->getDescription(), "Plugin description"));
cannam@17 110 r.push_back(testRecommended(p->getMaker(), "Plugin maker"));
cannam@17 111 r.push_back(testRecommended(p->getCopyright(), "Plugin copyright"));
cannam@0 112
cannam@0 113 Plugin::ParameterList params = p->getParameterDescriptors();
cannam@0 114 for (int i = 0; i < (int)params.size(); ++i) {
cannam@0 115 r.push_back(testMandatory
cannam@0 116 (params[i].name,
cannam@17 117 "Plugin parameter \"" + params[i].identifier + "\" name"));
cannam@0 118 r.push_back(testRecommended
cannam@0 119 (params[i].description,
cannam@17 120 "Plugin parameter \"" + params[i].identifier + "\" description"));
cannam@0 121 }
cannam@0 122
cannam@0 123 Plugin::OutputList outputs = p->getOutputDescriptors();
cannam@0 124 for (int i = 0; i < (int)outputs.size(); ++i) {
cannam@0 125 r.push_back(testMandatory
cannam@0 126 (outputs[i].name,
cannam@17 127 "Plugin output \"" + outputs[i].identifier + "\" name"));
cannam@0 128 r.push_back(testRecommended
cannam@0 129 (outputs[i].description,
cannam@17 130 "Plugin output \"" + outputs[i].identifier + "\" description"));
cannam@0 131 }
cannam@0 132
cannam@0 133 return r;
cannam@0 134 }
cannam@0 135
cannam@0 136 Test::Result
cannam@0 137 TestEmptyFields::testMandatory(string text, string desc)
cannam@0 138 {
cannam@0 139 if (text == "") {
cannam@0 140 return error(desc + " is empty");
cannam@0 141 }
cannam@0 142 return success();
cannam@0 143 }
cannam@0 144
cannam@0 145 Test::Result
cannam@0 146 TestEmptyFields::testRecommended(string text, string desc)
cannam@0 147 {
cannam@0 148 if (text == "") {
cannam@0 149 return warning(desc + " is empty");
Chris@54 150 } else if (text == "Licence information not available." ||
Chris@54 151 text == "VamPy Plugin." ||
Chris@54 152 text == "Not given. (Hint: Implement getDescription method.)" ||
Chris@54 153 text == "VamPy Plugin (Noname)") {
Chris@54 154 return warning(desc + " is missing (returns VamPy boilerplate text)");
cannam@0 155 }
cannam@0 156 return success();
cannam@0 157 }
cannam@0 158
cannam@0 159 Test::Results
cannam@14 160 TestValueRanges::test(string key, Options)
cannam@0 161 {
cannam@0 162 auto_ptr<Plugin> p(load(key));
cannam@0 163
cannam@0 164 Results r;
cannam@0 165
cannam@0 166 Plugin::ParameterList params = p->getParameterDescriptors();
cannam@0 167 for (int i = 0; i < (int)params.size(); ++i) {
cannam@0 168 Plugin::ParameterDescriptor &pd(params[i]);
cannam@17 169 string pfx("Plugin parameter \"" + pd.identifier + "\"");
cannam@0 170 float min = pd.minValue;
cannam@0 171 float max = pd.maxValue;
cannam@0 172 float deft = pd.defaultValue;
cannam@0 173 if (max <= min) {
cannam@0 174 r.push_back(error(pfx + " maxValue <= minValue"));
cannam@0 175 }
cannam@0 176 if (deft < min || deft > max) {
cannam@0 177 r.push_back(error(pfx + " defaultValue out of range"));
cannam@0 178 }
cannam@0 179 if (pd.isQuantized) {
cannam@0 180 if (pd.quantizeStep == 0.f) {
cannam@0 181 r.push_back(error(pfx + " is quantized, but quantize step is zero"));
cannam@0 182 } else {
cannam@0 183
cannam@0 184 float epsilon = 0.00001f;
cannam@0 185 int qty = int((max - min) / pd.quantizeStep + 0.5);
cannam@0 186 float target = min + pd.quantizeStep * qty;
cannam@0 187 if (fabsf(max - target) > epsilon) {
cannam@0 188 r.push_back(warning(pfx + " value range is not a multiple of quantize step"));
cannam@0 189 }
cannam@0 190
cannam@0 191 if (!pd.valueNames.empty()) {
cannam@0 192 if ((int)pd.valueNames.size() < qty+1) {
cannam@0 193 r.push_back(warning(pfx + " has fewer value names than quantize steps"));
cannam@0 194 } else if ((int)pd.valueNames.size() > qty+1) {
cannam@0 195 r.push_back(warning(pfx + " has more value names than quantize steps"));
cannam@0 196 }
cannam@0 197 }
cannam@0 198
cannam@0 199 qty = int((deft - min) / pd.quantizeStep + 0.5);
cannam@0 200 target = min + pd.quantizeStep * qty;
cannam@0 201 if (fabsf(deft - target) > epsilon) {
cannam@0 202 r.push_back(warning(pfx + " default value is not a multiple of quantize step beyond minimum"));
cannam@0 203 }
cannam@0 204 }
cannam@0 205 }
cannam@0 206 }
cannam@0 207
cannam@0 208 return r;
cannam@0 209 }
cannam@0 210
Chris@35 211 Test::Results
Chris@35 212 TestCategory::test(string key, Options)
Chris@35 213 {
Chris@35 214 PluginLoader::PluginCategoryHierarchy hierarchy =
Chris@35 215 PluginLoader::getInstance()->getPluginCategory(key);
Chris@35 216
Chris@35 217 Results r;
cannam@0 218
Chris@35 219 if (hierarchy.empty()) {
Chris@35 220 r.push_back(warning("Plugin category missing or cannot be loaded (no .cat file?)"));
Chris@35 221 }
Chris@35 222
Chris@35 223 return r;
Chris@35 224 }
Chris@35 225