1 /* $Id: url-mapping-test.cc,v 1.5 2005/04/10 17:04:04 atterer Exp $ -*- C++ -*-
3 |_) /| Copyright (C) 2003 | richard@
4 | \/¯| Richard Atterer | atterer.net
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2. See
8 the file COPYING for details.
10 Test for addServer(), addPart()
12 #test-deps job/url-mapping.o util/configfile.o util/md5sum.o util/glibc-md5.o
19 #include <configfile.hh>
23 #include <url-mapping.hh>
24 //______________________________________________________________________
28 // Record certain lines of the log
29 const char* const UNIT = "url-mapping";
31 bool unitEnabled = false; // Was the unit enabled with --debug?
32 void loggerPut(const string& unitName, unsigned char unitNameLen,
33 const char* format, int args, const Subst arg[]) {
34 if (unitName == UNIT) {
35 if (strncmp(format, "add", 6) != 0) {
36 logged += Subst::subst(format, args, arg);
39 if (!unitEnabled) return;
41 Logger::defaultPut(unitName, unitNameLen, format, args, arg);
44 Logger::setOutputFunction(&loggerPut);
45 Logger* l = Logger::enumerate();
46 while (l != 0 && strcmp(l->name(), UNIT) == 0)
47 l = Logger::enumerate(l);
48 Assert(l != 0); // Unit not found? Probably wasn't compiled with DEBUG
49 unitEnabled = l->enabled();
50 if (!unitEnabled) Logger::setEnabled(UNIT);
53 // Compare actual/expected log output
54 void expect(const char* s) {
56 msg("Error: Expected \"%1\", but got \"%2\"", s, logged);
62 const string base = "http://baseurl/";
65 void ap(UrlMap& m, const MD5& md, const char* s) {
67 ConfigFile::split(value, s, 0);
68 const char* result = m.addPart(base, md, value);
69 if (result != 0) msg("addPart: %1", result);
74 void as(UrlMap& m, const char* label, const char* s,
75 bool expectFailure = false) {
77 ConfigFile::split(value, s, 0);
78 const char* result = m.addServer(base, label, value);
79 if (result != 0) msg("addServer: %1", result);
80 Assert(expectFailure == (result != 0));
86 //______________________________________________________________________
90 as(m, "LabelA", "http://myserver.org/");
91 as(m, "LabelA", "ftp://mirror.myserver.org/");
92 as(m, "LabelB", "LabelC:subdirectory/");
93 as(m, "LabelC", "http://some.where.com/jigdo/");
94 ap(m, md[0], "X:part0");
95 ap(m, md[1], "X:part1");
96 ap(m, md[0], "LabelB:some/path/part2");
97 as(m, "X", "X=http://localhost:8000/~richard/ironmaiden/");
98 ap(m, md[2], "X:part2");
101 expect("Part AQIDBAUGBwgJCgsMDQ4PEA: X + `part0'\n"
102 "Part AQIDBAUGBwgJCgsMDQ4PEA: LabelB + `some/path/part2'\n"
103 "Part ERITFBUWFxgZGhscHR4fIA: X + `part1'\n"
104 "Part ISIjJCUmJygpKissLS4vMA: X + `part2'\n"
105 "Server LabelA: http + `//myserver.org/'\n"
106 "Server LabelA: ftp + `//mirror.myserver.org/'\n"
107 "Server LabelB: LabelC + `subdirectory/'\n"
108 "Server LabelC: http + `//some.where.com/jigdo/'\n"
109 "Server X: X=http + `//localhost:8000/~richard/ironmaiden/'\n"
110 "Server X=http: + `X=http:'\n"
111 "Server ftp: + `ftp:'\n"
112 "Server http: + `http:'\n");
120 as(m, "C", "foobar");
123 expect("Server A: http + `//baseurl/B'\n"
126 "Server C: http + `//baseurl/foobar'\n"
128 "Server http: + `http:'\n");
134 as(m, "asdf", "foo:x");
135 as(m, "foo", "asdf:y", true);
138 expect("Server asdf: foo + `x'\n"
139 "Server foo: + `y'\n"); // Not useful, avoids loop
150 as(m, "d", "a:", true);
153 expect("Server a: b + `'\n"
155 "Server bar: + `bar:'\n"
157 "Server d: foo + `'\n"
158 "Server d: + `'\n" // Not useful, avoids loop
159 "Server d: bar + `'\n"
160 "Server foo: + `foo:'\n");
162 //______________________________________________________________________
164 void expectEnum(PartUrlMapping* m, const char* expected) {
165 vector<UrlMapping*> best;
168 string s = m->enumerate(&best);
169 if (s.empty()) break;
170 if (!result.empty()) result += ' ';
173 if (result != expected) {
174 msg("Error: Expected \"%1\", but got \"%2\"", expected, result);
175 Assert(result == expected);
177 msg("OK, got \"%1\"", result);
180 /* NB: In the following tests, all mappings must have different
181 weights. Otherwise, different rounding errors in different implementations
182 will lead to a different output order, and make the tests fail. */
184 void score1() { // Single leaf object
187 v.push_back("fooboo/bar/baz");
188 m.addPart("", md[0], v);
190 expectEnum(m[md[0]], "fooboo/bar/baz");
193 void score2() { // Simple chain, 2 objects long
195 ap(m, md[0], "fooboo/bar/baz");
197 expectEnum(m[md[0]], "http://baseurl/fooboo/bar/baz");
200 void score3() { // Diamond-shaped graph
202 as(m, "Label", "Server:x/ --try-first=", true);
203 ap(m, md[0], "Label:some/path");
204 as(m, "Label", "Server:y/ --try-first");
205 as(m, "Server", "ftp://server.org:80/");
208 "ftp://server.org:80/y/some/path "
209 "ftp://server.org:80/x/some/path");
212 void score4() { // Full mesh, many leaf possibilities
214 ap(m, md[1], "A:a --try-first");
216 ap(m, md[1], "A:c --try-last");
217 ap(m, md[1], "A:d --try-first=3.0");
218 as(m, "A", "S:l --try-first=-13");
219 as(m, "A", "S:m --try-last=.222");
220 as(m, "A", "S:n --try-first=3.4");
221 as(m, "A", "S:o --try-first --try-first=6.5");
222 as(m, "S", "p://x/");
224 expectEnum(m[md[1]], "p://x/od p://x/oa p://x/ob p://x/oc p://x/nd p://x/na "
225 "p://x/nb p://x/md p://x/nc p://x/ma p://x/mb p://x/mc p://x/ld "
226 "p://x/la p://x/lb p://x/lc");
229 void score5() { // Full mesh, one leaf possibility
232 as(m, "A", "S:l --try-first=.1");
233 as(m, "A", "S:m --try-first=.21");
234 as(m, "A", "S:n --try-first=.32");
235 as(m, "A", "S:o --try-last=.222");
236 as(m, "S", "T:a --try-first=.4");
237 as(m, "S", "T:b --try-first=.5");
238 as(m, "S", "T:c --try-first=.6");
239 as(m, "S", "T:d --try-first=3.4");
240 as(m, "T", "http://x/");
242 expectEnum(m[md[1]], "http://x/dn. http://x/dm. http://x/dl. http://x/do. "
243 "http://x/cn. http://x/bn. http://x/cm. http://x/an. "
244 "http://x/bm. http://x/cl. http://x/am. http://x/bl. "
245 "http://x/al. http://x/co. http://x/bo. http://x/ao.");
247 //______________________________________________________________________
249 int main(int argc, char* argv[]) {
250 if (argc == 2) Logger::scanOptions(argv[1], argv[0]);
253 for (int i = 0; i < 10; ++i)
254 for (int j = 0; j < 16; ++j)
258 UrlMapping::setNoRandomInitialWeight();
265 msg("Graph build tests");