318 lines
12 KiB
C
318 lines
12 KiB
C
/*
|
|
* OSCam self tests
|
|
* This file contains tests for different config parsers and generators
|
|
* Build this file using `make tests`
|
|
*/
|
|
#include "globals.h"
|
|
|
|
#include "oscam-array.h"
|
|
#include "oscam-string.h"
|
|
#include "oscam-conf-chk.h"
|
|
#include "oscam-conf-mk.h"
|
|
|
|
struct test_vec
|
|
{
|
|
const char *in; // Input data
|
|
const char *out; // Expected output data (if out is NULL, then assume in == out)
|
|
};
|
|
|
|
typedef void (CHK_FN) (char *, void *);
|
|
typedef char *(MK_T_FN) (void *);
|
|
typedef void (CLEAR_FN)(void *);
|
|
typedef void (CLONE_FN)(void *, void *);
|
|
|
|
struct test_type
|
|
{
|
|
char *desc; // Test textual description
|
|
void *data; // Pointer to basic data structure
|
|
void *data_c; // Pointer to data structure that will hold cloned data (for clone_ tests)
|
|
size_t data_sz; // Data structure size
|
|
CHK_FN *chk_fn; // chk_XXX() func for the data type
|
|
MK_T_FN *mk_t_fn; // mk_t_XXX() func for the data type
|
|
CLEAR_FN *clear_fn; // clear_XXX() func for the data type
|
|
CLONE_FN *clone_fn; // clone_XXX() func for the data type
|
|
const struct test_vec *test_vec; // Array of test vectors
|
|
};
|
|
|
|
static void run_parser_test(struct test_type *t)
|
|
{
|
|
memset(t->data, 0, t->data_sz);
|
|
memset(t->data_c, 0, t->data_sz);
|
|
printf("%s\n", t->desc);
|
|
const struct test_vec *vec = t->test_vec;
|
|
while (vec->in)
|
|
{
|
|
bool ok;
|
|
printf(" Testing \"%s\"", vec->in);
|
|
char *input_setting = cs_strdup(vec->in);
|
|
t->chk_fn(input_setting, t->data);
|
|
t->clone_fn(t->data, t->data_c); // Check if 'clone' works
|
|
t->clear_fn(t->data); // Check if 'clear' works
|
|
char *generated = t->mk_t_fn(t->data_c); // Use cloned data
|
|
if (vec->out)
|
|
ok = strcmp(vec->out, generated) == 0;
|
|
else
|
|
ok = strcmp(vec->in, generated) == 0;
|
|
if (ok)
|
|
{
|
|
printf(" [OK]\n");
|
|
} else {
|
|
printf("\n");
|
|
printf(" === ERROR ===\n");
|
|
printf(" Input data: \"%s\"\n", vec->in);
|
|
printf(" Got result: \"%s\"\n", generated);
|
|
printf(" Expected out: \"%s\"\n", vec->out ? vec->out : vec->in);
|
|
printf("\n");
|
|
}
|
|
free_mk_t(generated);
|
|
free(input_setting);
|
|
fflush(stdout);
|
|
vec++;
|
|
}
|
|
t->clear_fn(t->data_c);
|
|
}
|
|
|
|
void run_all_tests(void)
|
|
{
|
|
ECM_WHITELIST ecm_whitelist, ecm_whitelist_c;
|
|
struct test_type ecm_whitelist_test =
|
|
{
|
|
.desc = "ECM whitelist setting (READER: 'ecmwhitelist')",
|
|
.data = &ecm_whitelist,
|
|
.data_c = &ecm_whitelist_c,
|
|
.data_sz = sizeof(ecm_whitelist),
|
|
.chk_fn = (CHK_FN *)&chk_ecm_whitelist,
|
|
.mk_t_fn = (MK_T_FN *)&mk_t_ecm_whitelist,
|
|
.clear_fn = (CLEAR_FN *)&ecm_whitelist_clear,
|
|
.clone_fn = (CLONE_FN *)&ecm_whitelist_clone,
|
|
.test_vec = (const struct test_vec[])
|
|
{
|
|
{ .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" },
|
|
{ .in = "0500@043800:70,6E,6C,66,7A,61,67,75,5D,6B" },
|
|
{ .in = "0500@043800:70,6E,6C,66" },
|
|
{ .in = "0500@043800:70,6E,6C" },
|
|
{ .in = "0500@043800:70" },
|
|
{ .in = "0500:81,82,83;0600:91" },
|
|
{ .in = "0500:81,82" },
|
|
{ .in = "0500:81" },
|
|
{ .in = "@123456:81" },
|
|
{ .in = "@123456:81;@000789:AA,BB,CC" },
|
|
{ .in = "81" },
|
|
{ .in = "81,82,83" },
|
|
{ .in = "81,82,83,84" },
|
|
{ .in = "0500@043800:70;0600@070800:11;0123@456789:01,02" },
|
|
{ .in = "" },
|
|
{ .in = "0500:81,32;0600:aa,bb", .out = "0500:81,32;0600:AA,BB" },
|
|
{ .in = "500:1,2;60@77:a,b,z,,", .out = "0500:01,02;0060@000077:0A,0B" },
|
|
{ .in = "@ff:81;@bb:11,22", .out = "@0000FF:81;@0000BB:11,22" },
|
|
{ .in = "@:81", .out = "81" },
|
|
{ .in = "81;zzs;;;;;ab", .out = "81,AB" },
|
|
{ .in = ":@", .out = "" },
|
|
{ .in = ",:,@,", .out = "" },
|
|
{ .in = "@:", .out = "" },
|
|
{ .in = "@:,,", .out = "" },
|
|
{ .in = "@:;;;", .out = "" },
|
|
{ .in = ",", .out = "" },
|
|
{ .in = NULL },
|
|
},
|
|
};
|
|
run_parser_test(&ecm_whitelist_test);
|
|
|
|
ECM_HDR_WHITELIST ecm_hdr_whitelist, ecm_hdr_whitelist_c;
|
|
struct test_type ecm_hdr_whitelist_test =
|
|
{
|
|
.desc = "ECM header whitelist setting (READER: 'ecmhdrwhitelist')",
|
|
.data = &ecm_hdr_whitelist,
|
|
.data_c = &ecm_hdr_whitelist_c,
|
|
.data_sz = sizeof(ecm_hdr_whitelist),
|
|
.chk_fn = (CHK_FN *)&chk_ecm_hdr_whitelist,
|
|
.mk_t_fn = (MK_T_FN *)&mk_t_ecm_hdr_whitelist,
|
|
.clear_fn = (CLEAR_FN *)&ecm_hdr_whitelist_clear,
|
|
.clone_fn = (CLONE_FN *)&ecm_hdr_whitelist_clone,
|
|
.test_vec = (const struct test_vec[])
|
|
{
|
|
{ .in = "1830@123456:80308F078D,81308F078D;1702@007878:807090C7000000011010008712078400,817090C7000000011010008713078400" },
|
|
{ .in = "1830:80308F078D,81308F078D;1702:807090C7000000011010008712078400,817090C7000000011010008713078400" },
|
|
{ .in = "813061006A00075C00,803061006A00075C00" },
|
|
{ .in = "813061006A00075C00" },
|
|
{ .in = "1122334455667788991011121314151617182021222324252627282930", .out = "1122334455667788991011121314151617182021" },
|
|
{ .in = "9999@999999:1122334455667788991011121314151617182021,2233334455667788991011121314151617182021;AAAA@BBBBBB:1122334455667788991011121314151617182021" },
|
|
{ .in = "0500:81,82,83;0600:91" },
|
|
{ .in = "0500:81,82" },
|
|
{ .in = "0500:81" },
|
|
{ .in = "@123456:81" },
|
|
{ .in = "@123456:81;@000789:AA,BB,CC" },
|
|
{ .in = "81" },
|
|
{ .in = "81,82,83" },
|
|
{ .in = "81,82,83,84" },
|
|
{ .in = "0500@043800:70;0600@070800:11;0123@456789:01,02" },
|
|
{ .in = "" },
|
|
{ .in = "00,82,83" },
|
|
{ .in = "0500:81,32;0600:aa,bb", .out = "0500:81,32;0600:AA,BB" },
|
|
{ .in = "@ff:81;@bb:11,22", .out = "@0000FF:81;@0000BB:11,22" },
|
|
{ .in = "0500:,,,;0060@000077:,,;0700:,;0800", .out = "0800" },
|
|
{ .in = "@:81", .out = "81" },
|
|
{ .in = "81;zzs;;;;;ab", .out = "81,EF,AB" },
|
|
{ .in = "1830@123456:", .out = "" },
|
|
{ .in = "500:1,2;60@77:a,b,z,,", .out = "" },
|
|
{ .in = ":@", .out = "" },
|
|
{ .in = ",:,@,", .out = "" },
|
|
{ .in = "@:", .out = "" },
|
|
{ .in = "@:,,", .out = "" },
|
|
{ .in = "@:;;;", .out = "" },
|
|
{ .in = ",", .out = "" },
|
|
{ .in = NULL },
|
|
},
|
|
};
|
|
run_parser_test(&ecm_hdr_whitelist_test);
|
|
|
|
TUNTAB tuntab, tuntab_c;
|
|
struct test_type tuntab_test =
|
|
{
|
|
.desc = "Beta tunnel (tuntab) (ACCOUNT: 'betatunnel')",
|
|
.data = &tuntab,
|
|
.data_c = &tuntab_c,
|
|
.data_sz = sizeof(tuntab),
|
|
.chk_fn = (CHK_FN *)&chk_tuntab,
|
|
.mk_t_fn = (MK_T_FN *)&mk_t_tuntab,
|
|
.clear_fn = (CLEAR_FN *)&tuntab_clear,
|
|
.clone_fn = (CLONE_FN *)&tuntab_clone,
|
|
.test_vec = (const struct test_vec[])
|
|
{
|
|
{ .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" },
|
|
{ .in = "1833.007A:1702,1833.007B:1702,1833.007C:1702,1833.007E:1702" },
|
|
{ .in = "1833.007A:1702" },
|
|
{ .in = "" },
|
|
{ .in = "1833.007A" },
|
|
{ .in = "1833:1702", .out = "" },
|
|
{ .in = "1833", .out = "" },
|
|
{ .in = "zzzz.yyyy:tttt", .out = "" },
|
|
{ .in = "zzzz.yyyy", .out = "" },
|
|
{ .in = ",", .out = "" },
|
|
{ .in = ".:", .out = "" },
|
|
{ .in = ":.,", .out = "" },
|
|
{ .in = NULL },
|
|
},
|
|
};
|
|
run_parser_test(&tuntab_test);
|
|
|
|
FTAB ftab, ftab_c;
|
|
struct test_type ftab_test =
|
|
{
|
|
.desc = "Filters (ftab) (ACCOUNT: 'chid', 'ident'; READER: 'chid', 'ident', 'fallback_percaid', 'localcards')",
|
|
.data = &ftab,
|
|
.data_c = &ftab_c,
|
|
.data_sz = sizeof(ftab),
|
|
.chk_fn = (CHK_FN *)&chk_ftab,
|
|
.mk_t_fn = (MK_T_FN *)&mk_t_ftab,
|
|
.clear_fn = (CLEAR_FN *)&ftab_clear,
|
|
.clone_fn = (CLONE_FN *)&ftab_clone,
|
|
.test_vec = (const struct test_vec[])
|
|
{
|
|
{ .in = "0100:123456,234567;0200:345678,456789" },
|
|
{ .in = "183D:000000,005411" },
|
|
{ .in = "183D:000000" },
|
|
{ .in = "0100:000012" },
|
|
{ .in = "0100:000012;0604:0000BA,000101,00010E,000141" },
|
|
{ .in = "1234:234567;0010:345678,876543" },
|
|
{ .in = "" },
|
|
{ .in = "0200:eeee,tyut,1234", .out = "0200:00EEEE,001234" },
|
|
{ .in = "0200:eeee,tyut", .out = "0200:00EEEE" },
|
|
{ .in = "1:0", .out = "0001:000000" },
|
|
{ .in = "1:0,1,0", .out = "0001:000000,000001,000000" },
|
|
{ .in = "0:0", .out = "" },
|
|
{ .in = "zzzz:", .out = "" },
|
|
{ .in = "yyyy:rrrr,qqqq", .out = "" },
|
|
{ .in = ",", .out = "" },
|
|
{ .in = ",;,", .out = "" },
|
|
{ .in = ";;;", .out = "" },
|
|
{ .in = ".:", .out = "" },
|
|
{ .in = ":.,", .out = "" },
|
|
{ .in = ":;.,", .out = "" },
|
|
{ .in = ".:;,", .out = "" },
|
|
{ .in = NULL },
|
|
},
|
|
};
|
|
run_parser_test(&ftab_test);
|
|
|
|
CAIDVALUETAB caidvaluetab, caidvaluetab_c;
|
|
struct test_type caidvaluetab_test =
|
|
{
|
|
.desc = "caidvaluetab (ACCOUNT: 'lb_nbest_percaid'; GLOBAL: 'lb_nbest_percaid', 'fallbacktimeout_percaid', 'lb_retrylimits', 'cacheex_mode1_delay')",
|
|
.data = &caidvaluetab,
|
|
.data_c = &caidvaluetab_c,
|
|
.data_sz = sizeof(caidvaluetab),
|
|
.chk_fn = (CHK_FN *)&chk_caidvaluetab,
|
|
.mk_t_fn = (MK_T_FN *)&mk_t_caidvaluetab,
|
|
.clear_fn = (CLEAR_FN *)&caidvaluetab_clear,
|
|
.clone_fn = (CLONE_FN *)&caidvaluetab_clone,
|
|
.test_vec = (const struct test_vec[])
|
|
{
|
|
{ .in = "0100:4,0200:3,0300:2,0400:1" },
|
|
{ .in = "0100:4,02:3,03:2,04:1,0500:9999" },
|
|
{ .in = "0100:4" },
|
|
{ .in = "01:4" },
|
|
{ .in = "" },
|
|
{ .in = "0500:10000", .out = "" },
|
|
{ .in = "0200:eeee,tyut,1234", .out = "0200:0" },
|
|
{ .in = "0200:eeee,tyut", .out = "0200:0" },
|
|
{ .in = "1:0", .out = "01:0" },
|
|
{ .in = "1:0,1,0", .out = "01:0" },
|
|
{ .in = "0500:10000", .out = "" },
|
|
{ .in = "0:0", .out = "" },
|
|
{ .in = "zzzz:", .out = "" },
|
|
{ .in = "yyyy:rrrr,qqqq", .out = "" },
|
|
{ .in = ",", .out = "" },
|
|
{ .in = ",:,", .out = "" },
|
|
{ .in = ";:;", .out = "" },
|
|
{ .in = ".:", .out = "" },
|
|
{ .in = ":.,", .out = "" },
|
|
{ .in = ":;.,", .out = "" },
|
|
{ .in = ".:;,", .out = "" },
|
|
{ .in = NULL },
|
|
},
|
|
};
|
|
run_parser_test(&caidvaluetab_test);
|
|
|
|
CAIDTAB caidtab, caidtab_c;
|
|
struct test_type caidtab_test =
|
|
{
|
|
.desc = "caidtab (ACCOUNT: 'caid'; READER: 'caid'; GLOBAL: 'lb_noproviderforcaid', 'double_check_caid', 'cwcycle_check_caid')",
|
|
.data = &caidtab,
|
|
.data_c = &caidtab_c,
|
|
.data_sz = sizeof(caidtab),
|
|
.chk_fn = (CHK_FN *)&chk_caidtab,
|
|
.mk_t_fn = (MK_T_FN *)&mk_t_caidtab,
|
|
.clear_fn = (CLEAR_FN *)&caidtab_clear,
|
|
.clone_fn = (CLONE_FN *)&caidtab_clone,
|
|
.test_vec = (const struct test_vec[])
|
|
{
|
|
{ .in = "0200&FFEE:0300" },
|
|
{ .in = "0200&FF00:0300,0400&00FF:0500" },
|
|
{ .in = "0200&FF00:0300,0400,0500:0600,0600&FF0F:1234" },
|
|
{ .in = "0400&FF00:0500,0600" },
|
|
{ .in = "0702,0722" },
|
|
{ .in = "0702&FFDF" },
|
|
{ .in = "0100" },
|
|
{ .in = "01" },
|
|
{ .in = "" },
|
|
{ .in = "0500:10000", .out = "0500" },
|
|
{ .in = "1000&5FFFF5:0600", .out = "1000&FFF5:0600" },
|
|
{ .in = "10000:10000", .out = "" },
|
|
{ .in = "rrrr&zzzz:mmmm", .out = "" },
|
|
{ .in = "0:0", .out = "" },
|
|
{ .in = "zzzz:", .out = "" },
|
|
{ .in = "yyyy:rrrr,qqqq", .out = "" },
|
|
{ .in = ",", .out = "" },
|
|
{ .in = ",:,", .out = "" },
|
|
{ .in = "&:&", .out = "" },
|
|
{ .in = ".:", .out = "" },
|
|
{ .in = ":.,", .out = "" },
|
|
{ .in = ":&.,", .out = "" },
|
|
{ .in = ".:&,", .out = "" },
|
|
{ .in = NULL },
|
|
},
|
|
};
|
|
run_parser_test(&caidtab_test);
|
|
}
|