1
2 #include "config.h"
3 #include <fcntl.h>
4 #ifdef STDC_HEADERS
5 #include <stdlib.h>
6 #endif
7 #include <stdio.h>
8 #ifdef HAVE_UNISTD_H
9 #include <unistd.h>
10 #endif
11 #ifdef HAVE_MEMORY_H
12 #include <memory.h>
13 #endif
14 #ifdef HAVE_MALLOC_H
15 #include <malloc.h>
16 #endif
17 #include <string.h>
18 #include <assert.h>
19 #include "ffs.h"
20
21 #include "test_funcs.h"
22
23 static void test_receive(char *buffer, int buf_size, int finished,
24 int test_level);
25 static void test_all_receive(char *buffer, int buf_size, int finished);
26 static void write_buffer(char *buf, int size);
27 static void read_test_only();
28
29 static int write_output = 0;
30 static char *output_file = NULL;
31 static char *read_file = NULL;
32 static int fail = 0;
33 static char *test_only = NULL;
34
35 static FFSContext rcv_context = NULL;
36 static int verbose = 0;
37 static FMContext loaded_FMcontext = NULL;
38
39 int
main(argc,argv)40 main(argc, argv)
41 int argc;
42 char **argv;
43 {
44 FMContext src_context;
45 FFSBuffer encode_buffer;
46 char *xfer_buffer;
47 int buf_size;
48 int i;
49 struct node nodes[10];
50 struct visit_table v;
51 FMFormat node_ioformat, psa_ioformat, reader_register_ioformat;
52
53 init_written_data();
54
55 for (i=1; i<argc; i++) {
56 if (strcmp(argv[i], "-w") == 0) {
57 output_file = argv[++i];
58 write_output++;
59 } else if (strcmp(argv[i], "-r") == 0) {
60 read_file = argv[++i];
61 } else if (strcmp(argv[i], "-v") == 0) {
62 verbose++;
63 } else if (strcmp(argv[i], "-t") == 0) {
64 test_only = argv[++i];
65 } else {
66 printf("Unknown argument %s\n", argv[i]);
67 printf("Usage:\n\t-w\t write test output\n");
68 printf("\t-r file\t rest/process test data in <file>\n");
69 printf("\t-t test\t test only format <test>\n");
70 exit(1);
71 }
72 }
73
74 if (read_file) {
75 read_test_only();
76 free_written_data();
77 if (rcv_context != NULL) {
78 free_FFSContext(rcv_context);
79 rcv_context = NULL;
80 }
81 if (loaded_FMcontext) {
82 free_FMcontext(loaded_FMcontext);
83 }
84 if (fail) exit(1);
85 exit(0);
86 }
87 src_context = create_FMcontext();
88 encode_buffer = create_FFSBuffer();
89
90 node_ioformat = register_data_format(src_context, node_format_list);
91 psa_ioformat = register_data_format(src_context, pointer_to_static_format_list);
92 reader_register_ioformat = register_data_format(src_context, reader_register_format_list);
93
94 for (i = 0; i < sizeof(nodes)/sizeof(nodes[0]); i++) {
95 nodes[i].node_num = i;
96 nodes[i].link1 = nodes[i].link2 = NULL;
97 }
98
99 for (i=0; i < sizeof(nodes)/sizeof(nodes[0]) - 1; i++) {
100 nodes[i].link1 = &nodes[i+1];
101 }
102 /* nodes[0].link2 = &nodes[sizeof(nodes)/sizeof(nodes[0])-1];*/
103 v.node_count = 0;
104 nodes[0].node_num = calc_signature(&nodes[0], &v);
105 xfer_buffer = FFSencode(encode_buffer, node_ioformat,
106 &nodes[0], &buf_size);
107 test_all_receive(xfer_buffer, buf_size, 0);
108 write_buffer(xfer_buffer, buf_size);
109
110 nodes[0].link2 = NULL;
111 nodes[sizeof(nodes)/sizeof(nodes[0]) - 1].link1 = &nodes[2];
112 v.node_count = 0;
113 nodes[0].node_num = 0;
114 nodes[0].node_num = calc_signature(&nodes[0], &v);
115 xfer_buffer = FFSencode(encode_buffer, node_ioformat,
116 &nodes[0], &buf_size);
117 test_all_receive(xfer_buffer, buf_size, 0);
118 write_buffer(xfer_buffer, buf_size);
119
120 for (i=0; i < sizeof(nodes)/sizeof(nodes[0]) - 1; i++) {
121 nodes[i].link1 = nodes[i].link2 = NULL;
122 }
123 nodes[0].link1 = &nodes[1];
124 nodes[0].link2 = &nodes[2];
125 nodes[1].link1 = &nodes[3];
126 nodes[1].link2 = &nodes[4];
127 nodes[2].link1 = &nodes[5];
128 nodes[2].link2 = &nodes[6];
129 nodes[3].link1 = &nodes[7];
130 nodes[3].link2 = &nodes[8];
131 nodes[4].link1 = &nodes[9];
132
133 v.node_count = 0;
134 nodes[0].node_num = 0;
135 nodes[0].node_num = calc_signature(&nodes[0], &v);
136 xfer_buffer = FFSencode(encode_buffer, node_ioformat,
137 &nodes[0], &buf_size);
138 test_all_receive(xfer_buffer, buf_size, 0);
139 write_buffer(xfer_buffer, buf_size);
140
141 xfer_buffer = FFSencode(encode_buffer, psa_ioformat,
142 &psa, &buf_size);
143 test_all_receive(xfer_buffer, buf_size, 0);
144 write_buffer(xfer_buffer, buf_size);
145
146 xfer_buffer = FFSencode(encode_buffer, reader_register_ioformat,
147 &reader_register, &buf_size);
148 test_all_receive(xfer_buffer, buf_size, 0);
149 write_buffer(xfer_buffer, buf_size);
150
151
152 free_FMcontext(src_context);
153 free_FFSBuffer(encode_buffer);
154 src_context = NULL;
155 test_all_receive(NULL, 0, 1);
156 write_buffer(NULL, 0);
157
158 free_written_data();
159 if (rcv_context != NULL) {
160 free_FFSContext(rcv_context);
161 rcv_context = NULL;
162 }
163 if (loaded_FMcontext) {
164 free_FMcontext(loaded_FMcontext);
165 }
166 if (fail) exit(1);
167 return 0;
168 }
169
170 /* NT needs O_BINARY, but it doesn't exist elsewhere */
171 #ifndef O_BINARY
172 #define O_BINARY 0
173 #endif
174
175 static char *
get_buffer(size_p)176 get_buffer(size_p)
177 int *size_p;
178 {
179 static int file_fd = 0;
180 static char *buffer = NULL;
181 char *tmp_buffer;
182 static int last_size = -1;
183 unsigned short ssize;
184 int to_read;
185 int tmp_size;
186 unsigned char csize;
187 unsigned int beef = 0xdeadbeef;
188
189 if (read_file == NULL) exit(1);
190
191 if (loaded_FMcontext == NULL) {
192 loaded_FMcontext = create_local_FMcontext();
193 }
194 if (file_fd == 0) {
195 file_fd = open(read_file, O_RDONLY|O_BINARY, 0777);
196 buffer = malloc(1);
197 }
198 if (last_size != -1) {
199 if (memcmp(buffer+last_size, &beef, 4) != 0) {
200 printf("memory overwrite error\n");
201 }
202 }
203 if (read(file_fd, &csize, 1) != 1) exit(1); /* low byte of 2-byte size */
204 ssize = csize;
205 if (read(file_fd, &csize, 1) != 1) exit(1); /* high byte of 2-byte size */
206 ssize += ((csize << 8) & 0xff00);
207 to_read = ssize;
208 buffer = realloc(buffer, to_read+4);
209 tmp_buffer = buffer;
210 while((tmp_size = read(file_fd, tmp_buffer, to_read)) != to_read) {
211 if (tmp_size == 0) {
212 free(buffer);
213 return NULL;
214 } else if (tmp_size == -1) {
215 perror("Read failure");
216 free(buffer);
217 return NULL;
218 }
219 to_read -= tmp_size;
220 tmp_buffer += tmp_size;
221 }
222 last_size = ssize;
223 memcpy(buffer+last_size, &beef, 4);
224 if (ssize == 0) {
225 free(buffer);
226 close(file_fd);
227 file_fd = 0;
228 return NULL;
229 } else {
230 *size_p = ssize;
231 return buffer;
232 }
233 }
234
235 static void
read_test_only()236 read_test_only()
237 {
238 char *input;
239 int size;
240 while ((input = get_buffer(&size)) != NULL) {
241 test_all_receive(input, size, 0);
242 }
243 test_all_receive(NULL, 0, 1);
244 free(input);
245 if (rcv_context != NULL) {
246 free_FFSContext(rcv_context);
247 rcv_context = NULL;
248 }
249 }
250
251 static FFSTypeHandle node_ioformat;
252 static FFSTypeHandle psa_ioformat;
253 static FFSTypeHandle reader_register_ioformat;
254
255 static void
set_targets(context)256 set_targets(context)
257 FFSContext context;
258 {
259 node_ioformat = FFSset_fixed_target(context, node_format_list);
260 psa_ioformat = FFSset_fixed_target(context, pointer_to_static_format_list);
261 reader_register_ioformat = FFSset_fixed_target(context, reader_register_format_list);
262 }
263
base_size_func(FFSContext context,char * src,int rec_len,int native_struct_size)264 int base_size_func(FFSContext context, char *src, int rec_len,
265 int native_struct_size)
266 {
267 return native_struct_size;
268 }
269
total_size_func(FFSContext context,char * src,int rec_len,int native_struct_size)270 int total_size_func(FFSContext context, char *src, int rec_len,
271 int native_struct_size)
272 {
273 return FFS_est_decode_length(context, src, rec_len);
274 }
275
276 static int
decode_in_place(FFSContext context,char * src,int src_len,void * dest)277 decode_in_place(FFSContext context, char *src, int src_len, void *dest)
278 {
279 if (FFSdecode_in_place_possible(FFSTypeHandle_from_encode(context, src))) {
280 int ret, header_len;
281 char *real_dest;
282 ret = FFSdecode_in_place(context, src, (void**)&real_dest);
283 header_len = real_dest - src;
284 memcpy(dest, real_dest, src_len - header_len);
285 return ret;
286 } else {
287 return FFSdecode_to_buffer(context, src, dest);
288 }
289 }
290
291 static int
decode_IOcontext_wrapper(FFSContext context,char * src,int src_len,void * dest)292 decode_IOcontext_wrapper(FFSContext context, char *src, int src_len, void *dest)
293 {
294 return FFSdecode(context, src, dest);
295 }
296
297 static int
decode_to_buffer_IOcontext_wrapper(FFSContext context,char * src,int src_len,void * dest)298 decode_to_buffer_IOcontext_wrapper(FFSContext context, char *src, int src_len,
299 void *dest)
300 {
301 return FFSdecode_to_buffer(context, src, dest);
302 }
303
304 typedef int (*size_func_t)(FFSContext context, char *src, int buf_size,
305 int nativ_struct);
306
307 typedef int (*decode_func_t)(FFSContext context, char *src, int src_len,
308 void *dest);
309
310 size_func_t size_funcs[] = {base_size_func, total_size_func, total_size_func};
311 decode_func_t decode_funcs[] = {decode_IOcontext_wrapper,
312 decode_to_buffer_IOcontext_wrapper,
313 decode_in_place};
314
315
316 #define NUM_TESTS 3
317
318 static void
test_all_receive(buffer,buf_size,finished)319 test_all_receive(buffer, buf_size, finished)
320 char *buffer;
321 int buf_size;
322 int finished;
323 {
324 int test_type = 0;
325 char *tmp_buffer = malloc(buf_size);
326 for ( test_type = 0; test_type < NUM_TESTS; test_type++) {
327 memcpy(tmp_buffer, buffer, buf_size);
328 test_receive(tmp_buffer, buf_size, finished, test_type);
329 }
330 free(tmp_buffer);
331 }
332
333 static void*
get_mem(size)334 get_mem(size)
335 int size;
336 {
337 char *buffer;
338 unsigned int beef = 0xdeadbeef;
339
340 buffer = malloc(size+4);
341 memcpy(buffer+size, &beef, 4);
342 return buffer;
343 }
344
345 static void
check_mem(size,buffer)346 check_mem(size, buffer)
347 int size;
348 char *buffer;
349 {
350 unsigned int beef = 0xdeadbeef;
351 if (memcmp(buffer+size, &beef, 4) != 0) {
352 printf("memory overwrite error\n");
353 }
354 }
355
356
357 static void
test_receive(buffer,buf_size,finished,test_level)358 test_receive(buffer, buf_size, finished, test_level)
359 char *buffer;
360 int buf_size;
361 int finished;
362 int test_level;
363 {
364 static FFSContext c = NULL;
365 static int node_rec_count[NUM_TESTS] = {0,0,0};
366
367 static int unknown_rec_count[NUM_TESTS] = {0,0,0};
368 size_func_t size_func = size_funcs[test_level];
369 decode_func_t decode_func = decode_funcs[test_level];
370 if (c == NULL) {
371 c = create_FFSContext();
372 rcv_context = c;
373 set_targets(rcv_context);
374 }
375 if (!finished) {
376 /* char *comment;*/
377 FFSTypeHandle buffer_format = FFS_target_from_encode(rcv_context, buffer);
378
379 if (buffer_format == NULL) {
380 printf("No format!\n");
381 exit(1);
382 }
383 if (((test_only == NULL) || (strcmp(test_only, "node") == 0)) &&
384 (buffer_format == node_ioformat)) {
385 int size = size_func(rcv_context, buffer, buf_size,
386 sizeof(add_rec));
387 node_ptr read_data = get_mem(size);
388 struct visit_table v;
389 int signature, calculated_sig;
390 memset(read_data, 0, size);
391 if (!decode_func(rcv_context, buffer, buf_size, read_data))
392 printf("decode failed, decode msg format\n");
393 signature = read_data->node_num;
394 read_data->node_num = 0;
395 v.node_count = 0;
396 calculated_sig = calc_signature(read_data, &v);
397 if (signature != calculated_sig) {
398 printf("Node sig not right, calculated %d, expected %d\n",
399 calculated_sig, signature);
400 fail++;
401 }
402 check_mem(size, (char*)read_data);
403 free(read_data);
404 node_rec_count[test_level]++;
405 } else if (((test_only == NULL) || (strcmp(test_only, "psa") == 0)) &&
406 (buffer_format == psa_ioformat)) {
407 int size = size_func(rcv_context, buffer, buf_size,
408 sizeof(add_rec));
409 pointer_to_static_array_ptr read_data = get_mem(size);
410 memset(read_data, 0, size);
411 if (!decode_func(rcv_context, buffer, buf_size, read_data))
412 printf("decode failed, pointer_to_static_array data failed\n");
413 if (!pointer_to_static_rec_eq(read_data, &psa)) {
414 printf("Pointer to static array failure\n");
415 fail++;
416 }
417 check_mem(size, (char*)read_data);
418 free(read_data);
419 } else if (((test_only == NULL) || (strcmp(test_only, "reader_register") == 0)) &&
420 (buffer_format == reader_register_ioformat)) {
421 int size = size_func(rcv_context, buffer, buf_size,
422 sizeof(add_rec));
423 struct _reader_register_msg *read_data = get_mem(size);
424 memset(read_data, 0, size);
425 if (!decode_func(rcv_context, buffer, buf_size, read_data))
426 printf("decode failed, pointer_to_static_array data failed\n");
427 if (!reader_register_rec_eq(read_data, &reader_register)) {
428 printf("Pointer to reader_register failure\n");
429 fail++;
430 }
431 check_mem(size, (char*)read_data);
432 free(read_data);
433 } else if (test_only == NULL) {
434 printf("discarding a record\n");
435 unknown_rec_count[test_level]++;
436 }
437 } else {
438 /* finished */
439 if (test_level == 0) {
440 free_FFSContext(rcv_context);
441 rcv_context = NULL;
442 }
443 if (test_only != NULL) return;
444 if (node_rec_count[test_level] != 3) {
445 printf("Missed node, level %d\n", test_level);
446 fail++;
447 }
448 if (unknown_rec_count[test_level] != 0) {
449 printf("Got unknown\n");
450 fail++;
451 }
452 }
453 }
454
455 static void
write_buffer(buf,size)456 write_buffer(buf, size)
457 char *buf;
458 int size;
459 {
460 static int file_fd = 0;
461 unsigned short ssize;
462 unsigned char csize;
463 if (output_file == NULL) return;
464
465 if (file_fd == 0) {
466 file_fd = open(output_file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0777);
467 }
468 printf("Writing buffer of size %d\n", size);
469 ssize = size;
470 csize = ssize & 0xff;
471 if (write(file_fd, &csize, 1) != 1) exit(1);/* low byte of 2-byte size */
472 csize = ((ssize >> 8) & 0xff);
473 if (write(file_fd, &csize, 1) != 1) exit(1);/* high byte of 2-byte size */
474 if (write(file_fd, buf, size) != size) exit(1);
475 }
476