9 #include <libmnl/libmnl.h>
10 #include <libnftnl/ruleset.h>
11 #include <libnftnl/table.h>
12 #include <libnftnl/chain.h>
13 #include <libnftnl/rule.h>
14 #include <libnftnl/set.h>
21 static bool update =
false;
23 static void print_detail_error(
char *a,
char *b)
28 for (i = 0; i < strlen(b); i++) {
29 if (from == -1 && a[i] != b[i]) {
42 fprintf(stderr,
"from file: ");
43 for (i = k; i < from + 10; i++)
44 fprintf(stderr,
"%c", a[i]);
46 fprintf(stderr,
"\nfrom snprintf: ");
47 for (i = k; i < from + 10; i++)
48 fprintf(stderr,
"%c", b[i]);
51 fprintf(stderr,
"\n ");
52 for (i = k; i < from + 10; i++) {
58 fprintf(stderr,
"\n");
62 static int compare_test(uint32_t type,
struct nft_ruleset *rs,
63 const char *filename, FILE *fp)
69 case TEST_XML_RULESET:
70 nft_ruleset_snprintf(out,
sizeof(out), rs,
73 case TEST_JSON_RULESET:
74 nft_ruleset_snprintf(out,
sizeof(out), rs,
83 fgets(orig,
sizeof(orig), fp);
85 if (strncmp(orig, out, strlen(out)) == 0) {
87 printf(
"%s: No changes to update\n", filename);
92 printf(
"%s: Updating test file\n", filename);
93 fout = fopen(filename,
"w");
95 printf(
"unable to open file %s: %s\n", filename,
99 fprintf(fout,
"%s\n", out);
104 printf(
"validating %s: ", filename);
105 printf(
"\033[31mFAILED\e[0m\n");
106 print_detail_error(orig, out);
110 static int test_json(
const char *filename,
struct nft_parse_err *err)
116 fp = fopen(filename,
"r");
118 printf(
"unable to open file %s: %s\n", filename,
123 rs = nft_ruleset_alloc();
125 perror(
"nft_ruleset_alloc");
129 if (nft_ruleset_parse_file(rs, NFT_PARSE_JSON, fp, err) == 0)
130 ret = compare_test(TEST_JSON_RULESET, rs, filename, fp);
134 nft_ruleset_free(rs);
141 printf(
"parsing %s: ", filename);
142 printf(
"\033[31mFAILED\e[0m (%s)\n", strerror(errno));
143 nft_parse_perror(
"Reason", err);
147 static int test_xml(
const char *filename,
struct nft_parse_err *err)
153 fp = fopen(filename,
"r");
155 printf(
"unable to open file %s: %s\n", filename,
160 rs = nft_ruleset_alloc();
162 perror(
"nft_ruleset_alloc");
166 if (nft_ruleset_parse_file(rs, NFT_PARSE_XML, fp, err) == 0)
167 ret = compare_test(TEST_XML_RULESET, rs, filename, fp);
171 nft_ruleset_free(rs);
178 printf(
"parsing %s: ", filename);
179 printf(
"\033[31mFAILED\e[0m (%s)\n", strerror(errno));
180 nft_parse_perror(
"Reason", err);
184 static int execute_test(
const char *dir_name)
189 int ret = 0, exit_code = 0;
190 struct nft_parse_err *err;
192 d = opendir(dir_name);
198 err = nft_parse_err_alloc();
204 while ((dent = readdir(d)) != NULL) {
205 int len = strlen(dent->d_name);
207 if (strcmp(dent->d_name,
".") == 0 ||
208 strcmp(dent->d_name,
"..") == 0)
211 snprintf(path,
sizeof(path),
"%s/%s", dir_name, dent->d_name);
213 if (strcmp(&dent->d_name[len-4],
".xml") == 0) {
214 if ((ret = test_xml(path, err)) == 0) {
216 printf(
"parsing and validating %s: ",
218 printf(
"\033[32mOK\e[0m\n");
223 if (strcmp(&dent->d_name[len-5],
".json") == 0) {
224 if ((ret = test_json(path, err)) == 0) {
226 printf(
"parsing and validating %s: ",
228 printf(
"\033[32mOK\e[0m\n");
236 nft_parse_err_free(err);
244 static int execute_test_file(
const char *filename)
248 struct nft_parse_err *err;
250 err = nft_parse_err_alloc();
256 snprintf(path,
sizeof(path),
"%s", filename);
258 int len = strlen(filename);
259 if (strcmp(&filename[len-4],
".xml") == 0) {
260 if ((ret = test_xml(path, err)) == 0) {
262 printf(
"parsing and validating %s: ",
264 printf(
"\033[32mOK\e[0m\n");
267 nft_parse_err_free(err);
270 if (strcmp(&filename[len-5],
".json") == 0) {
271 if ((ret = test_json(path, err)) == 0) {
273 printf(
"parsing and validating %s: ",
275 printf(
"\033[32mOK\e[0m\n");
278 nft_parse_err_free(err);
282 nft_parse_err_free(err);
287 static void show_help(
const char *name)
290 "Usage: %s [option]\n"
293 " -d/--dir <directory> Check test files from <directory>.\n"
294 " -u/--update <directory> Update test files from <directory>.\n"
295 " -f/--file <file> Check test file <file>\n"
300 int main(
int argc,
char *argv[])
304 int option_index = 0;
305 static struct option long_options[] = {
306 {
"dir", required_argument, 0,
'd' },
307 {
"update", required_argument, 0,
'u' },
308 {
"file", required_argument, 0,
'f' },
318 val = getopt_long(argc, argv,
"d:u:f:", long_options,
326 ret = execute_test(optarg);
330 ret = execute_test(optarg);
333 ret = execute_test_file(optarg);