3 * This file contains tests for different config parsers and generators
4 * Build this file using `make tests`
8 #include "oscam-array.h"
9 #include "oscam-string.h"
10 #include "oscam-conf-chk.h"
11 #include "oscam-conf-mk.h"
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 *);
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
;
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
53 ok
= strcmp(vec
->out
, generated
) == 0;
55 ok
= strcmp(vec
->in
, generated
) == 0;
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
);
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" },
98 { .in
= "@123456:81" },
99 { .in
= "@123456:81;@000789:AA,BB,CC" },
101 { .in
= "81,82,83" },
102 { .in
= "81,82,83,84" },
103 { .in
= "0500@043800:70;0600@070800:11;0123@456789:01,02" },
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
= "" },
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" },
143 { .in
= "@123456:81" },
144 { .in
= "@123456:81;@000789:AA,BB,CC" },
146 { .in
= "81,82,83" },
147 { .in
= "81,82,83,84" },
148 { .in
= "0500@043800:70;0600@070800:11;0123@456789:01,02" },
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
= "" },
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')",
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" },
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
= "" },
197 run_parser_test(&tuntab_test
);
200 struct test_type ftab_test
=
202 .desc
= "Filters (ftab) (ACCOUNT: 'chid', 'ident'; READER: 'chid', 'ident', 'fallback_percaid', 'localcards')",
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" },
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
= "" },
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" },
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
= "" },
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')",
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" },
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
= "" },
316 run_parser_test(&caidtab_test
);