- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / tests.c
blob01d2c2622b70a5e84eecf88b424ed175ae02bbb9
1 /*
2 * OSCam self tests
3 * This file contains tests for different config parsers and generators
4 * Build this file using `make tests`
5 */
6 #include "globals.h"
8 #include "oscam-array.h"
9 #include "oscam-string.h"
10 #include "oscam-conf-chk.h"
11 #include "oscam-conf-mk.h"
13 struct test_vec
15 const char *in; // Input data
16 const char *out; // Expected output data (if out is NULL, then assume in == out)
19 typedef void (CHK_FN) (char *, void *);
20 typedef char *(MK_T_FN) (void *);
21 typedef void (CLEAR_FN)(void *);
22 typedef void (CLONE_FN)(void *, void *);
24 struct test_type
26 char *desc; // Test textual description
27 void *data; // Pointer to basic data structure
28 void *data_c; // Pointer to data structure that will hold cloned data (for clone_ tests)
29 size_t data_sz; // Data structure size
30 CHK_FN *chk_fn; // chk_XXX() func for the data type
31 MK_T_FN *mk_t_fn; // mk_t_XXX() func for the data type
32 CLEAR_FN *clear_fn; // clear_XXX() func for the data type
33 CLONE_FN *clone_fn; // clone_XXX() func for the data type
34 const struct test_vec *test_vec; // Array of test vectors
37 static void run_parser_test(struct test_type *t)
39 memset(t->data, 0, t->data_sz);
40 memset(t->data_c, 0, t->data_sz);
41 printf("%s\n", t->desc);
42 const struct test_vec *vec = t->test_vec;
43 while (vec->in)
45 bool ok;
46 printf(" Testing \"%s\"", vec->in);
47 char *input_setting = cs_strdup(vec->in);
48 t->chk_fn(input_setting, t->data);
49 t->clone_fn(t->data, t->data_c); // Check if 'clone' works
50 t->clear_fn(t->data); // Check if 'clear' works
51 char *generated = t->mk_t_fn(t->data_c); // Use cloned data
52 if (vec->out)
53 ok = strcmp(vec->out, generated) == 0;
54 else
55 ok = strcmp(vec->in, generated) == 0;
56 if (ok)
58 printf(" [OK]\n");
59 } else {
60 printf("\n");
61 printf(" === ERROR ===\n");
62 printf(" Input data: \"%s\"\n", vec->in);
63 printf(" Got result: \"%s\"\n", generated);
64 printf(" Expected out: \"%s\"\n", vec->out ? vec->out : vec->in);
65 printf("\n");
67 free_mk_t(generated);
68 free(input_setting);
69 fflush(stdout);
70 vec++;
72 t->clear_fn(t->data_c);
75 void run_all_tests(void)
77 ECM_WHITELIST ecm_whitelist, ecm_whitelist_c;
78 struct test_type ecm_whitelist_test =
80 .desc = "ECM whitelist setting (READER: 'ecmwhitelist')",
81 .data = &ecm_whitelist,
82 .data_c = &ecm_whitelist_c,
83 .data_sz = sizeof(ecm_whitelist),
84 .chk_fn = (CHK_FN *)&chk_ecm_whitelist,
85 .mk_t_fn = (MK_T_FN *)&mk_t_ecm_whitelist,
86 .clear_fn = (CLEAR_FN *)&ecm_whitelist_clear,
87 .clone_fn = (CLONE_FN *)&ecm_whitelist_clone,
88 .test_vec = (const struct test_vec[])
90 { .in = "0500@043800:70,6E,6C,66,7A,61,67,75,5D,6B;0600@070800:11,22,33,44,55,66;0700:AA,BB,CC,DD,EE;01,02,03,04;0123@456789:01,02,03,04" },
91 { .in = "0500@043800:70,6E,6C,66,7A,61,67,75,5D,6B" },
92 { .in = "0500@043800:70,6E,6C,66" },
93 { .in = "0500@043800:70,6E,6C" },
94 { .in = "0500@043800:70" },
95 { .in = "0500:81,82,83;0600:91" },
96 { .in = "0500:81,82" },
97 { .in = "0500:81" },
98 { .in = "@123456:81" },
99 { .in = "@123456:81;@000789:AA,BB,CC" },
100 { .in = "81" },
101 { .in = "81,82,83" },
102 { .in = "81,82,83,84" },
103 { .in = "0500@043800:70;0600@070800:11;0123@456789:01,02" },
104 { .in = "" },
105 { .in = "0500:81,32;0600:aa,bb", .out = "0500:81,32;0600:AA,BB" },
106 { .in = "500:1,2;60@77:a,b,z,,", .out = "0500:01,02;0060@000077:0A,0B" },
107 { .in = "@ff:81;@bb:11,22", .out = "@0000FF:81;@0000BB:11,22" },
108 { .in = "@:81", .out = "81" },
109 { .in = "81;zzs;;;;;ab", .out = "81,AB" },
110 { .in = ":@", .out = "" },
111 { .in = ",:,@,", .out = "" },
112 { .in = "@:", .out = "" },
113 { .in = "@:,,", .out = "" },
114 { .in = "@:;;;", .out = "" },
115 { .in = ",", .out = "" },
116 { .in = NULL },
119 run_parser_test(&ecm_whitelist_test);
121 ECM_HDR_WHITELIST ecm_hdr_whitelist, ecm_hdr_whitelist_c;
122 struct test_type ecm_hdr_whitelist_test =
124 .desc = "ECM header whitelist setting (READER: 'ecmhdrwhitelist')",
125 .data = &ecm_hdr_whitelist,
126 .data_c = &ecm_hdr_whitelist_c,
127 .data_sz = sizeof(ecm_hdr_whitelist),
128 .chk_fn = (CHK_FN *)&chk_ecm_hdr_whitelist,
129 .mk_t_fn = (MK_T_FN *)&mk_t_ecm_hdr_whitelist,
130 .clear_fn = (CLEAR_FN *)&ecm_hdr_whitelist_clear,
131 .clone_fn = (CLONE_FN *)&ecm_hdr_whitelist_clone,
132 .test_vec = (const struct test_vec[])
134 { .in = "1830@123456:80308F078D,81308F078D;1702@007878:807090C7000000011010008712078400,817090C7000000011010008713078400" },
135 { .in = "1830:80308F078D,81308F078D;1702:807090C7000000011010008712078400,817090C7000000011010008713078400" },
136 { .in = "813061006A00075C00,803061006A00075C00" },
137 { .in = "813061006A00075C00" },
138 { .in = "1122334455667788991011121314151617182021222324252627282930", .out = "1122334455667788991011121314151617182021" },
139 { .in = "9999@999999:1122334455667788991011121314151617182021,2233334455667788991011121314151617182021;AAAA@BBBBBB:1122334455667788991011121314151617182021" },
140 { .in = "0500:81,82,83;0600:91" },
141 { .in = "0500:81,82" },
142 { .in = "0500:81" },
143 { .in = "@123456:81" },
144 { .in = "@123456:81;@000789:AA,BB,CC" },
145 { .in = "81" },
146 { .in = "81,82,83" },
147 { .in = "81,82,83,84" },
148 { .in = "0500@043800:70;0600@070800:11;0123@456789:01,02" },
149 { .in = "" },
150 { .in = "00,82,83" },
151 { .in = "0500:81,32;0600:aa,bb", .out = "0500:81,32;0600:AA,BB" },
152 { .in = "@ff:81;@bb:11,22", .out = "@0000FF:81;@0000BB:11,22" },
153 { .in = "0500:,,,;0060@000077:,,;0700:,;0800", .out = "0800" },
154 { .in = "@:81", .out = "81" },
155 { .in = "81;zzs;;;;;ab", .out = "81,EF,AB" },
156 { .in = "1830@123456:", .out = "" },
157 { .in = "500:1,2;60@77:a,b,z,,", .out = "" },
158 { .in = ":@", .out = "" },
159 { .in = ",:,@,", .out = "" },
160 { .in = "@:", .out = "" },
161 { .in = "@:,,", .out = "" },
162 { .in = "@:;;;", .out = "" },
163 { .in = ",", .out = "" },
164 { .in = NULL },
167 run_parser_test(&ecm_hdr_whitelist_test);
169 TUNTAB tuntab, tuntab_c;
170 struct test_type tuntab_test =
172 .desc = "Beta tunnel (tuntab) (ACCOUNT: 'betatunnel')",
173 .data = &tuntab,
174 .data_c = &tuntab_c,
175 .data_sz = sizeof(tuntab),
176 .chk_fn = (CHK_FN *)&chk_tuntab,
177 .mk_t_fn = (MK_T_FN *)&mk_t_tuntab,
178 .clear_fn = (CLEAR_FN *)&tuntab_clear,
179 .clone_fn = (CLONE_FN *)&tuntab_clone,
180 .test_vec = (const struct test_vec[])
182 { .in = "1833.007A:1702,1833.007B:1702,1833.007C:1702,1833.007E:1702,1833.007F:1702,1833.0080:1702,1833.0081:1702,1833.0082:1702,1833.0083:1702,1833.0084:1702" },
183 { .in = "1833.007A:1702,1833.007B:1702,1833.007C:1702,1833.007E:1702" },
184 { .in = "1833.007A:1702" },
185 { .in = "" },
186 { .in = "1833.007A" },
187 { .in = "1833:1702", .out = "" },
188 { .in = "1833", .out = "" },
189 { .in = "zzzz.yyyy:tttt", .out = "" },
190 { .in = "zzzz.yyyy", .out = "" },
191 { .in = ",", .out = "" },
192 { .in = ".:", .out = "" },
193 { .in = ":.,", .out = "" },
194 { .in = NULL },
197 run_parser_test(&tuntab_test);
199 FTAB ftab, ftab_c;
200 struct test_type ftab_test =
202 .desc = "Filters (ftab) (ACCOUNT: 'chid', 'ident'; READER: 'chid', 'ident', 'fallback_percaid', 'localcards')",
203 .data = &ftab,
204 .data_c = &ftab_c,
205 .data_sz = sizeof(ftab),
206 .chk_fn = (CHK_FN *)&chk_ftab,
207 .mk_t_fn = (MK_T_FN *)&mk_t_ftab,
208 .clear_fn = (CLEAR_FN *)&ftab_clear,
209 .clone_fn = (CLONE_FN *)&ftab_clone,
210 .test_vec = (const struct test_vec[])
212 { .in = "0100:123456,234567;0200:345678,456789" },
213 { .in = "183D:000000,005411" },
214 { .in = "183D:000000" },
215 { .in = "0100:000012" },
216 { .in = "0100:000012;0604:0000BA,000101,00010E,000141" },
217 { .in = "1234:234567;0010:345678,876543" },
218 { .in = "" },
219 { .in = "0200:eeee,tyut,1234", .out = "0200:00EEEE,001234" },
220 { .in = "0200:eeee,tyut", .out = "0200:00EEEE" },
221 { .in = "1:0", .out = "0001:000000" },
222 { .in = "1:0,1,0", .out = "0001:000000,000001,000000" },
223 { .in = "0:0", .out = "" },
224 { .in = "zzzz:", .out = "" },
225 { .in = "yyyy:rrrr,qqqq", .out = "" },
226 { .in = ",", .out = "" },
227 { .in = ",;,", .out = "" },
228 { .in = ";;;", .out = "" },
229 { .in = ".:", .out = "" },
230 { .in = ":.,", .out = "" },
231 { .in = ":;.,", .out = "" },
232 { .in = ".:;,", .out = "" },
233 { .in = NULL },
236 run_parser_test(&ftab_test);
238 CAIDVALUETAB caidvaluetab, caidvaluetab_c;
239 struct test_type caidvaluetab_test =
241 .desc = "caidvaluetab (ACCOUNT: 'lb_nbest_percaid'; GLOBAL: 'lb_nbest_percaid', 'fallbacktimeout_percaid', 'lb_retrylimits', 'cacheex_mode1_delay')",
242 .data = &caidvaluetab,
243 .data_c = &caidvaluetab_c,
244 .data_sz = sizeof(caidvaluetab),
245 .chk_fn = (CHK_FN *)&chk_caidvaluetab,
246 .mk_t_fn = (MK_T_FN *)&mk_t_caidvaluetab,
247 .clear_fn = (CLEAR_FN *)&caidvaluetab_clear,
248 .clone_fn = (CLONE_FN *)&caidvaluetab_clone,
249 .test_vec = (const struct test_vec[])
251 { .in = "0100:4,0200:3,0300:2,0400:1" },
252 { .in = "0100:4,02:3,03:2,04:1,0500:9999" },
253 { .in = "0100:4" },
254 { .in = "01:4" },
255 { .in = "" },
256 { .in = "0500:10000", .out = "" },
257 { .in = "0200:eeee,tyut,1234", .out = "0200:0" },
258 { .in = "0200:eeee,tyut", .out = "0200:0" },
259 { .in = "1:0", .out = "01:0" },
260 { .in = "1:0,1,0", .out = "01:0" },
261 { .in = "0500:10000", .out = "" },
262 { .in = "0:0", .out = "" },
263 { .in = "zzzz:", .out = "" },
264 { .in = "yyyy:rrrr,qqqq", .out = "" },
265 { .in = ",", .out = "" },
266 { .in = ",:,", .out = "" },
267 { .in = ";:;", .out = "" },
268 { .in = ".:", .out = "" },
269 { .in = ":.,", .out = "" },
270 { .in = ":;.,", .out = "" },
271 { .in = ".:;,", .out = "" },
272 { .in = NULL },
275 run_parser_test(&caidvaluetab_test);
277 CAIDTAB caidtab, caidtab_c;
278 struct test_type caidtab_test =
280 .desc = "caidtab (ACCOUNT: 'caid'; READER: 'caid'; GLOBAL: 'lb_noproviderforcaid', 'double_check_caid', 'cwcycle_check_caid')",
281 .data = &caidtab,
282 .data_c = &caidtab_c,
283 .data_sz = sizeof(caidtab),
284 .chk_fn = (CHK_FN *)&chk_caidtab,
285 .mk_t_fn = (MK_T_FN *)&mk_t_caidtab,
286 .clear_fn = (CLEAR_FN *)&caidtab_clear,
287 .clone_fn = (CLONE_FN *)&caidtab_clone,
288 .test_vec = (const struct test_vec[])
290 { .in = "0200&FFEE:0300" },
291 { .in = "0200&FF00:0300,0400&00FF:0500" },
292 { .in = "0200&FF00:0300,0400,0500:0600,0600&FF0F:1234" },
293 { .in = "0400&FF00:0500,0600" },
294 { .in = "0702,0722" },
295 { .in = "0702&FFDF" },
296 { .in = "0100" },
297 { .in = "01" },
298 { .in = "" },
299 { .in = "0500:10000", .out = "0500" },
300 { .in = "1000&5FFFF5:0600", .out = "1000&FFF5:0600" },
301 { .in = "10000:10000", .out = "" },
302 { .in = "rrrr&zzzz:mmmm", .out = "" },
303 { .in = "0:0", .out = "" },
304 { .in = "zzzz:", .out = "" },
305 { .in = "yyyy:rrrr,qqqq", .out = "" },
306 { .in = ",", .out = "" },
307 { .in = ",:,", .out = "" },
308 { .in = "&:&", .out = "" },
309 { .in = ".:", .out = "" },
310 { .in = ":.,", .out = "" },
311 { .in = ":&.,", .out = "" },
312 { .in = ".:&,", .out = "" },
313 { .in = NULL },
316 run_parser_test(&caidtab_test);