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 nftnl_ruleset *rs,
63 const char *filename, FILE *fp)
69 case TEST_XML_RULESET:
70 nftnl_ruleset_snprintf(out,
sizeof(out), rs,
71 NFTNL_OUTPUT_XML, NFTNL_OF_EVENT_NEW);
73 case TEST_JSON_RULESET:
74 nftnl_ruleset_snprintf(out,
sizeof(out), rs,
75 NFTNL_OUTPUT_JSON, NFTNL_OF_EVENT_NEW);
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 nftnl_parse_err *err)
116 fp = fopen(filename,
"r");
118 printf(
"unable to open file %s: %s\n", filename,
123 rs = nftnl_ruleset_alloc();
125 perror(
"nftnl_ruleset_alloc");
129 if (nftnl_ruleset_parse_file(rs, NFTNL_PARSE_JSON, fp, err) == 0)
130 ret = compare_test(TEST_JSON_RULESET, rs, filename, fp);
134 nftnl_ruleset_free(rs);
141 printf(
"parsing %s: ", filename);
142 printf(
"\033[31mFAILED\e[0m (%s)\n", strerror(errno));
143 nftnl_parse_perror(
"Reason", err);
147 static int execute_test(
const char *dir_name)
152 int ret = 0, exit_code = 0;
153 struct nftnl_parse_err *err;
155 d = opendir(dir_name);
161 err = nftnl_parse_err_alloc();
167 while ((dent = readdir(d)) != NULL) {
168 int len = strlen(dent->d_name);
170 if (strcmp(dent->d_name,
".") == 0 ||
171 strcmp(dent->d_name,
"..") == 0)
174 snprintf(path,
sizeof(path),
"%s/%s", dir_name, dent->d_name);
176 if (strcmp(&dent->d_name[len-5],
".json") == 0) {
177 if ((ret = test_json(path, err)) == 0) {
179 printf(
"parsing and validating %s: ",
181 printf(
"\033[32mOK\e[0m\n");
189 nftnl_parse_err_free(err);
197 static int execute_test_file(
const char *filename)
200 struct nftnl_parse_err *err;
203 err = nftnl_parse_err_alloc();
209 snprintf(path,
sizeof(path),
"%s", filename);
211 len = strlen(filename);
212 if (strcmp(&filename[len-5],
".json") == 0) {
213 if ((ret = test_json(path, err)) == 0) {
215 printf(
"parsing and validating %s: ",
217 printf(
"\033[32mOK\e[0m\n");
220 nftnl_parse_err_free(err);
224 nftnl_parse_err_free(err);
229 static void show_help(
const char *name)
232 "Usage: %s [option]\n"
235 " -d/--dir <directory> Check test files from <directory>.\n"
236 " -u/--update <directory> Update test files from <directory>.\n"
237 " -f/--file <file> Check test file <file>\n"
242 int main(
int argc,
char *argv[])
246 int option_index = 0;
247 static struct option long_options[] = {
248 {
"dir", required_argument, 0,
'd' },
249 {
"update", required_argument, 0,
'u' },
250 {
"file", required_argument, 0,
'f' },
260 val = getopt_long(argc, argv,
"d:u:f:", long_options,
268 ret = execute_test(optarg);
272 ret = execute_test(optarg);
275 ret = execute_test_file(optarg);