test.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "test/test.hh"
00041
00042 #ifdef GECODE_HAS_MTRACE
00043 #include <mcheck.h>
00044 #endif
00045
00046 #include <iostream>
00047
00048 #include <cstdlib>
00049 #include <cstring>
00050 #include <ctime>
00051 #include <vector>
00052 #include <utility>
00053
00054 namespace Test {
00055
00056
00057 std::ostringstream olog;
00058
00059
00060
00061
00062
00063 const Gecode::PropKind PropKinds::pks[] =
00064 {Gecode::PK_MEMORY,Gecode::PK_SPEED};
00065
00066
00067
00068
00069
00070
00071 Base::Base(const std::string& s)
00072 : _name(s) {
00073 if (_tests == NULL) {
00074 _tests = this; _next = NULL;
00075 } else {
00076
00077 Base* p = NULL;
00078 Base* c = _tests;
00079 while ((c != NULL) && (c->name() < s)) {
00080 p = c; c = c->_next;
00081 }
00082 if (c == NULL) {
00083 p->_next = this; _next = NULL;
00084 } else if (c == _tests) {
00085 _next = _tests; _tests = this;
00086 } else {
00087 p->_next = this; _next = c;
00088 }
00089 }
00090 }
00091
00092 Base* Base::_tests = NULL;
00093
00094 Base::~Base(void) {}
00095
00096 Gecode::Support::RandomGenerator Base::rand
00097 = Gecode::Support::RandomGenerator();
00098
00099 Options opt;
00100
00101 void report_error(std::string name) {
00102 std::cout << "Options: -seed " << opt.seed;
00103 if (opt.fixprob != opt.deffixprob)
00104 std::cout << " -fixprob " << opt.fixprob;
00105 std::cout << " -test " << name << std::endl;
00106 if (opt.log)
00107 std::cout << olog.str();
00108 }
00109
00110 std::vector<std::pair<bool, const char*> > testpat;
00111 const char* startFrom = NULL;
00112 bool list = false;
00113
00114 void
00115 Options::parse(int argc, char* argv[]) {
00116 int i = 1;
00117 while (i < argc) {
00118 if (!strcmp(argv[i],"-help") || !strcmp(argv[i],"--help")) {
00119 std::cerr << "Options for testing:" << std::endl
00120 << "\t-seed (unsigned int or \"time\") default: "
00121 << seed << std::endl
00122 << "\t\tseed for random number generator (unsigned int),"
00123 << std::endl
00124 << "\t\tor \"time\" for a random seed based on "
00125 << "current time" << std::endl
00126 << "\t-fixprob (unsigned int) default: "
00127 << fixprob << std::endl
00128 << "\t\t1/fixprob is the probability of computing a fixpoint"
00129 << std::endl
00130 << "\t-iter (unsigned int) default: " <<iter<< std::endl
00131 << "\t\tthe number of iterations" << std::endl
00132 << "\t-test (string) default: (none)" << std::endl
00133 << "\t\tsimple pattern for the tests to run" << std::endl
00134 << "\t\tprefixing the pattern with \"-\" negates the pattern"
00135 << std::endl
00136 << "\t\tmultiple pattern-options may be given" << std::endl
00137 << "\t-start (string) default: (none)" << std::endl
00138 << "\t\tsimple pattern for the first test to run" << std::endl
00139 << "\t-log"
00140 << std::endl
00141 << "\t\tlog execution of tests"
00142 << std::endl
00143 << "\t\tthe optional argument determines the style of the log"
00144 << std::endl
00145 << "\t\twith text as the default style"
00146 << std::endl
00147 << "\t-stop (boolean) default: "
00148 << (stop ? "true" : "false") << std::endl
00149 << "\t\tstop on first error or continue" << std::endl
00150 << "\t-reflection (boolean) default: "
00151 << (reflection ? "true" : "false") << std::endl
00152 << "\t\tuse reflection also for copying" << std::endl
00153 << "\t-list" << std::endl
00154 << "\t\toutput list of all test cases and exit" << std::endl
00155 ;
00156 exit(EXIT_SUCCESS);
00157 } else if (!strcmp(argv[i],"-seed")) {
00158 if (++i == argc) goto missing;
00159 if (!strcmp(argv[i],"time")) {
00160 seed = static_cast<unsigned int>(time(NULL));
00161 } else {
00162 seed = static_cast<unsigned int>(atoi(argv[i]));
00163 }
00164 } else if (!strcmp(argv[i],"-iter")) {
00165 if (++i == argc) goto missing;
00166 iter = static_cast<unsigned int>(atoi(argv[i]));
00167 } else if (!strcmp(argv[i],"-fixprob")) {
00168 if (++i == argc) goto missing;
00169 fixprob = static_cast<unsigned int>(atoi(argv[i]));
00170 } else if (!strcmp(argv[i],"-test")) {
00171 if (++i == argc) goto missing;
00172 if (argv[i][0] == '-')
00173 testpat.push_back(std::make_pair(true, argv[i] + 1));
00174 else
00175 testpat.push_back(std::make_pair(false, argv[i]));
00176 } else if (!strcmp(argv[i],"-start")) {
00177 if (++i == argc) goto missing;
00178 startFrom = argv[i];
00179 } else if (!strcmp(argv[i],"-log")) {
00180 log = true;
00181 } else if (!strcmp(argv[i],"-stop")) {
00182 if (++i == argc) goto missing;
00183 if(argv[i][0] == 't') {
00184 stop = true;
00185 } else if (argv[i][0] == 'f') {
00186 stop = false;
00187 }
00188 } else if (!strcmp(argv[i],"-reflection")) {
00189 if (++i == argc) goto missing;
00190 if(argv[i][0] == 't') {
00191 reflection = true;
00192 } else if (argv[i][0] == 'f') {
00193 reflection = false;
00194 }
00195 } else if (!strcmp(argv[i],"-list")) {
00196 list = true;
00197 }
00198 i++;
00199 }
00200 return;
00201 missing:
00202 std::cerr << "Erroneous argument (" << argv[i-1] << ")" << std::endl
00203 << " missing parameter" << std::endl;
00204 exit(EXIT_FAILURE);
00205 }
00206
00207 }
00208
00209 int
00210 main(int argc, char* argv[]) {
00211 using namespace Test;
00212 #ifdef GECODE_HAS_MTRACE
00213 mtrace();
00214 #endif
00215
00216 opt.parse(argc, argv);
00217
00218 if (list) {
00219 for (Base* t = Base::tests() ; t != NULL; t = t->next() ) {
00220 std::cout << t->name() << std::endl;
00221 }
00222 exit(EXIT_SUCCESS);
00223 }
00224
00225 Base::rand.seed(opt.seed);
00226
00227 bool started = startFrom == NULL ? true : false;
00228
00229 for (Base* t = Base::tests() ; t != NULL; t = t->next() ) {
00230 try {
00231 if (!started) {
00232 if (t->name().find(startFrom) != std::string::npos)
00233 started = true;
00234 else
00235 goto next;
00236 }
00237 if (testpat.size() != 0) {
00238 bool match_found = false;
00239 bool some_positive = false;
00240 for (unsigned int i = 0; i < testpat.size(); ++i) {
00241 if (testpat[i].first) {
00242 if (t->name().find(testpat[i].second) != std::string::npos)
00243 goto next;
00244 } else {
00245 some_positive = true;
00246 if (t->name().find(testpat[i].second) != std::string::npos)
00247 match_found = true;
00248 }
00249 }
00250 if (some_positive && !match_found) goto next;
00251 }
00252 std::cout << t->name() << " ";
00253 std::cout.flush();
00254 for (unsigned int i = opt.iter; i--; ) {
00255 opt.seed = Base::rand.seed();
00256 if (t->run()) {
00257 std::cout << '+';
00258 std::cout.flush();
00259 } else {
00260 std::cout << "-" << std::endl;
00261 report_error(t->name());
00262 if (opt.stop)
00263 return 1;
00264 }
00265 }
00266 std::cout << std::endl;
00267 } catch (Gecode::Exception e) {
00268 std::cout << "Exception in \"Gecode::" << e.what()
00269 << "." << std::endl
00270 << "Stopping..." << std::endl;
00271 report_error(t->name());
00272 if (opt.stop)
00273 return 1;
00274 }
00275 next:;
00276 }
00277 return 0;
00278 }
00279
00280 std::ostream&
00281 operator<<(std::ostream& os, const Test::ind& i) {
00282 for (int j=i.l; j--; )
00283 os << " ";
00284 return os;
00285 }
00286
00287