Line data Source code
1 : /* TLD library -- Test the TLD library by including the tld.c file.
2 : * Copyright (c) 2011-2018 Made to Order Software Corp. All Rights Reserved
3 : *
4 : * Permission is hereby granted, free of charge, to any person obtaining a
5 : * copy of this software and associated documentation files (the
6 : * "Software"), to deal in the Software without restriction, including
7 : * without limitation the rights to use, copy, modify, merge, publish,
8 : * distribute, sublicense, and/or sell copies of the Software, and to
9 : * permit persons to whom the Software is furnished to do so, subject to
10 : * the following conditions:
11 : *
12 : * The above copyright notice and this permission notice shall be included
13 : * in all copies or substantial portions of the Software.
14 : *
15 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 : * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 : * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 : * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 : * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 : */
23 :
24 : /** \file
25 : * \brief Test the tld.c, tld_data.c, and tld_domain_to_lowercase.c functions.
26 : *
27 : * This file implements various tests that can directly access the internal
28 : * functions of the tld.c, tld_data.c, and tld_domain_to_lowercase.c
29 : * files.
30 : *
31 : * For that purpose we directly include those files in this test. This
32 : * is why the test is not actually linked against the library, it
33 : * includes it within itself.
34 : */
35 :
36 : #include "tld.c"
37 : #include "tld_data.c"
38 : #include "tld_domain_to_lowercase.c"
39 :
40 : #include <stdlib.h>
41 : #include <string.h>
42 :
43 : int err_count = 0;
44 : int verbose = 0;
45 :
46 1 : void test_compare()
47 : {
48 : struct data
49 : {
50 : const char *a;
51 : const char *b;
52 : int n;
53 : int r;
54 : };
55 1 : struct data d[] = {
56 : { "uj", "uk", 2, -1 },
57 : { "uk", "uk", 2, 0 },
58 : { "ul", "uk", 2, 1 },
59 :
60 : { "uj", "ukmore", 2, -1 },
61 : { "uk", "ukstuff", 2, 0 },
62 : { "ul", "ukhere", 2, 1 },
63 :
64 : { "uk1", "ukmore", 2, 1 },
65 : { "uk2", "ukstuff", 2, 1 },
66 : { "uk3", "ukhere", 2, 1 },
67 :
68 : { "uk1", "uk.", 3, 1 },
69 : { "uk2", "uk.", 3, 1 },
70 : { "uk3", "uk.", 3, 1 },
71 :
72 : { "uk1", ".uk", 3, 1 },
73 : { "uk2", ".uk", 3, 1 },
74 : { "uk3", ".uk", 3, 1 },
75 :
76 : { "uk", "uk1", 3, -1 },
77 : { "uk", "uk22", 4, -1 },
78 : { "uk", "uk333", 5, -1 },
79 :
80 : { "uk1", "uk", 2, 1 },
81 : { "uk22", "uk", 2, 1 },
82 : { "uk333", "uk", 2, 1 },
83 : };
84 : int i, r, max;
85 : char *s, *vd, *u;
86 :
87 1 : max = sizeof(d) / sizeof(d[0]);
88 22 : for(i = 0; i < max; ++i)
89 : {
90 21 : r = cmp(d[i].a, d[i].b, d[i].n);
91 21 : if(r != d[i].r) {
92 0 : fprintf(stderr, "error: cmp() failed with \"%s\" / \"%s\", expected %d and got %d [1]\n",
93 : d[i].a, d[i].b, d[i].r, r);
94 0 : ++err_count;
95 : }
96 :
97 : // create a version with uppercase and try again
98 21 : s = strdup(d[i].b);
99 101 : for(u = s; *u != '\0'; ++u)
100 : {
101 80 : if(*u >= 'a' && *u <= 'z')
102 : {
103 68 : *u &= 0x5F;
104 : }
105 : }
106 21 : vd = tld_domain_to_lowercase(s);
107 21 : r = cmp(d[i].a, d[i].b, d[i].n);
108 21 : if(r != d[i].r) {
109 0 : fprintf(stderr, "error: cmp() failed with \"%s\" / \"%s\", expected %d and got %d (with domain to lowercase) [2]\n",
110 : d[i].a, d[i].b, d[i].r, r);
111 0 : ++err_count;
112 : }
113 21 : free(vd);
114 21 : free(s);
115 : }
116 1 : }
117 :
118 1 : void test_search()
119 : {
120 : struct search_info
121 : {
122 : int f_start;
123 : int f_end;
124 : const char * f_tld;
125 : int f_length;
126 : int f_result;
127 : };
128 1 : struct search_info d[] = {
129 : /*
130 : * This table is very annoying since each time the data changes
131 : * it gets out of sync. On the other hand that's the best way
132 : * to make sure our tests work like in the real world.
133 : */
134 :
135 : /* get the .uk offset */
136 : { 8117, 9731, "uk", 2, 9613 },
137 :
138 : /* get each offset of the .uk 2nd level domain */
139 : { 7895, 7921, "ac", 2, 7895 },
140 : { 7895, 7921, "barsy", 5, 7896 },
141 : { 7895, 7921, "bl", 2, 7897 },
142 : { 7895, 7921, "british-library", 15, 7898 },
143 : { 7895, 7921, "co", 2, 7899 },
144 : { 7895, 7921, "gov", 3, 7900 },
145 : { 7895, 7921, "govt", 4, 7901 },
146 : { 7895, 7921, "icnet", 5, 7902 },
147 : { 7895, 7921, "jet", 3, 7903 },
148 : { 7895, 7921, "lea", 3, 7904 },
149 : { 7895, 7921, "ltd", 3, 7905 },
150 : { 7895, 7921, "me", 2, 7906 },
151 : { 7895, 7921, "mil", 3, 7907 },
152 : { 7895, 7921, "mod", 3, 7908 },
153 : { 7895, 7921, "national-library-scotland", 25, 7909 },
154 : { 7895, 7921, "nel", 3, 7910 },
155 : { 7895, 7921, "net", 3, 7911 },
156 : { 7895, 7921, "nhs", 3, 7912 },
157 : { 7895, 7921, "nic", 3, 7913 },
158 : { 7895, 7921, "nls", 3, 7914 },
159 : { 7895, 7921, "org", 3, 7915 },
160 : { 7895, 7921, "orgn", 4, 7916 },
161 : { 7895, 7921, "parliament", 10, 7917 },
162 : { 7895, 7921, "plc", 3, 7918 },
163 : { 7895, 7921, "police", 6, 7919 },
164 : { 7895, 7921, "sch", 3, 7920 },
165 :
166 : /* test with a few invalid TLDs for .uk */
167 : { 7895, 7921, "com", 3, -1 },
168 : { 7895, 7921, "aca", 3, -1 },
169 : { 7895, 7921, "aac", 3, -1 },
170 : { 7895, 7921, "ca", 2, -1 },
171 : { 7895, 7921, "cn", 2, -1 },
172 : { 7895, 7921, "cp", 2, -1 },
173 : { 7895, 7921, "cz", 2, -1 },
174 :
175 : /* get the .vu offset */
176 : { 8117, 9731, "vu", 2, 9660 },
177 :
178 : /* get the 2nd level .vu offsets */
179 : { 8044, 8049, "com", 3, 8044 },
180 : { 8044, 8049, "edu", 3, 8045 },
181 : { 8044, 8049, "gov", 3, 8046 },
182 : { 8044, 8049, "net", 3, 8047 },
183 : { 8044, 8049, "org", 3, 8048 },
184 :
185 : /* test with a few .vu 2nd level domains that do not exist */
186 : { 8044, 8049, "nom", 3, -1 },
187 : { 8044, 8049, "sch", 3, -1 },
188 :
189 : /* verify ordering of mari, mari-el, and marine (from .ru) */
190 : { 7297, 7437, "mari", 4, 7361 },
191 : { 7297, 7437, "mari-el", 7, 7362 },
192 : { 7297, 7437, "marine", 6, 7363 },
193 : };
194 :
195 : size_t i;
196 :
197 1 : size_t const max = sizeof(d) / sizeof(d[0]);
198 46 : for(i = 0; i < max; ++i)
199 : {
200 45 : int const r = search(d[i].f_start, d[i].f_end, d[i].f_tld, d[i].f_length);
201 45 : if(r != d[i].f_result)
202 : {
203 0 : fprintf(stderr, "error: test_search() failed with \"%s\", expected %d and got %d [3]\n",
204 : d[i].f_tld, d[i].f_result, r);
205 0 : ++err_count;
206 : }
207 : }
208 1 : }
209 :
210 :
211 621 : void test_search_array(int start, int end)
212 : {
213 : int i, r;
214 :
215 : /* now test all from the arrays */
216 10352 : for(i = start; i < end; ++i)
217 : {
218 9731 : if(verbose)
219 : {
220 0 : printf("{%d..%d} i = %d, [%s]\n", start, end, i, tld_descriptions[i].f_tld);
221 : }
222 9731 : r = search(start, end, tld_descriptions[i].f_tld, strlen(tld_descriptions[i].f_tld));
223 9731 : if(r != i)
224 : {
225 0 : fprintf(stderr, "error: test_search_array() failed with \"%s\", expected %d and got %d [4]\n",
226 : tld_descriptions[i].f_tld, i, r);
227 0 : ++err_count;
228 : }
229 9731 : if(tld_descriptions[i].f_start_offset != USHRT_MAX)
230 : {
231 620 : test_search_array(tld_descriptions[i].f_start_offset,
232 620 : tld_descriptions[i].f_end_offset);
233 : }
234 : }
235 621 : }
236 :
237 1 : void test_search_all()
238 : {
239 1 : test_search_array(tld_start_offset, tld_end_offset);
240 1 : }
241 :
242 :
243 1 : int main(int argc, char *argv[])
244 : {
245 1 : fprintf(stderr, "testing internal tld version %s\n", tld_version());
246 :
247 1 : if(argc > 1)
248 : {
249 0 : if(strcmp(argv[1], "-v") == 0)
250 : {
251 0 : verbose = 1;
252 : }
253 : }
254 :
255 : /* call all the tests, one by one
256 : * failures are "recorded" in the err_count global variable
257 : * and the process stops with an error message and exit(1)
258 : * if err_count is not zero.
259 : */
260 1 : test_compare();
261 1 : test_search();
262 1 : test_search_all();
263 :
264 1 : if(err_count)
265 : {
266 0 : fprintf(stderr, "%d error%s occured.\n",
267 0 : err_count, err_count != 1 ? "s" : "");
268 : }
269 1 : exit(err_count ? 1 : 0);
270 : }
271 :
272 : /* vim: ts=4 sw=4
273 : */
|