Browse code

webkernel_test: add a test for uri_urldecode

Dario Rodriguez authored on 23/07/2014 20:36:55
Showing 1 changed files
... ...
@@ -31,6 +31,7 @@ char *socklib_sselect(test_action action);
31 31
 char *sbuf_memory(test_action action);
32 32
 char *webkernel_basic(test_action action);
33 33
 char *webkernel_dual(test_action action);
34
+char *webkernel_urldecode(test_action action);
34 35
 
35 36
 
36 37
 struct {
... ...
@@ -41,6 +42,7 @@ struct {
41 42
            {sbuf_memory},
42 43
            {webkernel_basic},
43 44
            {webkernel_dual},
45
+           {webkernel_urldecode},
44 46
           };
45 47
 
46 48
 int
... ...
@@ -632,3 +634,31 @@ Connection: keep-alive\r\n\
632 634
         return(STRING_OK);
633 635
 }
634 636
 
637
+/* webkernel_urldecode */
638
+char *
639
+webkernel_urldecode(test_action action)
640
+{
641
+	static struct {
642
+		char *encoded;
643
+		char *decoded;
644
+	} strs[]={{"my%40emailservice.com","my@emailservice.com"}};
645
+	int i;
646
+	char buf[1024];
647
+	static char myerror[1024];
648
+        if(action==test_name)
649
+                return("webkernel_urldecode");
650
+        else if(action==test_description)
651
+                return("check some strings against uri_urldecode");
652
+        /* run test */
653
+	for(i=0;i<(sizeof(strs)/sizeof(strs[0]));i++) {
654
+		strncpy(buf,strs[i].encoded,sizeof(buf));
655
+		buf[sizeof(buf)-1]='\0';
656
+		uri_urldecode(buf);
657
+		if(strcmp(buf,strs[i].decoded)!=0) {
658
+			snprintf(myerror,sizeof(myerror),"%s: incorrect decoding of string \"%s\" (\"%s\"!=\"%s\")\n",STRING_FAIL,strs[i].encoded,buf,strs[i].decoded);
659
+			myerror[sizeof(myerror)-1]='\0';
660
+			return(myerror);
661
+		}
662
+	}
663
+        return(STRING_OK);
664
+}
Browse code

webkernel: make wk_init expect a server fd instead of a port number

Dario Rodriguez authored on 15/07/2014 11:03:21
Showing 1 changed files
... ...
@@ -83,8 +83,8 @@ main(int argc, char *argv[])
83 83
         }
84 84
         if(totalfail!=0)
85 85
                 printf("Failed %i of %i tests.\n",totalfail,total);
86
-	else
87
-		printf("Passed %i of %i tests.\n",total,total);
86
+        else
87
+                printf("Passed %i of %i tests.\n",total,total);
88 88
         return((totalfail!=0)?1:0);
89 89
 }
90 90
 
... ...
@@ -399,6 +399,7 @@ webkernel_basic(test_action action)
399 399
         int fds[2];
400 400
         char buf[128];
401 401
         int usedbuf;
402
+        int serverfd;
402 403
         char test_request[]={"\
403 404
 GET /test.cgi HTTP/1.0\r\n\
404 405
 Host: localhost\r\n\
... ...
@@ -417,9 +418,10 @@ Connection: keep-alive\r\n\
417 418
         check=0;
418 419
         if((ssel=sselect_init())==NULL)
419 420
                 return(STRING_FAIL ": couln't alloc a sselect structure");
420
-        for(port=19747,off=0,check=0;(web=wk_init(port,ssel,NULL,webkernel_basichttp,NULL,NULL,&check))==NULL;off++,port++)
421
+        for(port=19747,off=0,check=0;(serverfd=ipv4_server(port))==-1;off++,port++)
421 422
                 ;
422
-        if(web==NULL) {
423
+        sock_setunsafe(serverfd);
424
+        if((web=wk_init(serverfd,ssel,NULL,webkernel_basichttp,NULL,NULL,&check))==NULL) {
423 425
                 webkernel_basicclose(&client,&ssel,&host,&web);
424 426
                 return(STRING_FAIL ": couln't find a free port to init webkernel");
425 427
         }
... ...
@@ -487,6 +489,7 @@ Connection: keep-alive\r\n\
487 489
         }
488 490
         close(client),client=-1;
489 491
         wk_free(web),web=NULL;
492
+        close(serverfd),serverfd=-1;
490 493
         sselect_free(ssel),ssel=NULL;
491 494
         free(host),host=NULL;
492 495
         return(STRING_OK);
... ...
@@ -517,6 +520,7 @@ webkernel_dual(test_action action)
517 520
         int off;
518 521
         int check;
519 522
         sselect *ssel;
523
+        int serverfd;
520 524
         int clients[2];
521 525
         int c;
522 526
         char *host;
... ...
@@ -544,9 +548,10 @@ Connection: keep-alive\r\n\
544 548
         check=0;
545 549
         if((ssel=sselect_init())==NULL)
546 550
                 return(STRING_FAIL ": couln't alloc a sselect structure");
547
-        for(port=19747,off=0;(web=wk_init(port,ssel,NULL,webkernel_basichttp,NULL,NULL,&check))==NULL;off++,port++)
551
+        for(port=19747,off=0;(serverfd=ipv4_server(port))==-1;off++,port++)
548 552
                 ;
549
-        if(web==NULL) {
553
+        sock_setunsafe(serverfd);
554
+        if((web=wk_init(serverfd,ssel,NULL,webkernel_basichttp,NULL,NULL,&check))==NULL) {
550 555
                 webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
551 556
                 return(STRING_FAIL ": couln't find a free port to init webkernel");
552 557
         }
... ...
@@ -621,6 +626,7 @@ Connection: keep-alive\r\n\
621 626
         for(c=0;c<(sizeof(clients)/sizeof(clients[0]));c++)
622 627
                 close(clients[c]),clients[c]=-1;
623 628
         wk_free(web),web=NULL;
629
+        close(serverfd),serverfd=-1;
624 630
         sselect_free(ssel),ssel=NULL;
625 631
         free(host),host=NULL;
626 632
         return(STRING_OK);
Browse code

webkernel_test: accept list of tests, add webkernel_dual

Dario Rodriguez authored on 02/07/2014 12:19:01
Showing 1 changed files
... ...
@@ -83,6 +83,8 @@ main(int argc, char *argv[])
83 83
         }
84 84
         if(totalfail!=0)
85 85
                 printf("Failed %i of %i tests.\n",totalfail,total);
86
+	else
87
+		printf("Passed %i of %i tests.\n",total,total);
86 88
         return((totalfail!=0)?1:0);
87 89
 }
88 90
 
... ...
@@ -362,16 +364,10 @@ webkernel_basichttp(wk *web, int connid, wk_uri *uri, void *userptr)
362 364
 {
363 365
 
364 366
         char reply_ok[]={"Ok"};
365
-#if 1
366
-        printf("CALLBACK! (check is %i, 0x%p), uri->path:%s\n",(*((int *)userptr)),(void *)userptr,uri->path);
367
-#endif
368 367
         if(strcmp(uri->path,"/test.cgi")==0) {
369 368
                 (*((int *)userptr))=(*((int *)userptr))+1;
370 369
                 wk_serve_buffer_as_file(web,connid,reply_ok,sizeof(reply_ok)-1,mime_getdefault("test.txt",NULL));
371 370
         }
372
-#if 1
373
-        printf("check is now %i\n",(*((int *)userptr)));
374
-#endif
375 371
         return(wkact_finished);
376 372
 }
377 373
 
... ...
@@ -496,6 +492,7 @@ Connection: keep-alive\r\n\
496 492
         return(STRING_OK);
497 493
 }
498 494
 
495
+/* webkernel_dual */
499 496
 void
500 497
 webkernel_dualclose(int *clients,int sizeclients,sselect **ssel, char **host, wk **web)
501 498
 {
... ...
@@ -512,7 +509,6 @@ webkernel_dualclose(int *clients,int sizeclients,sselect **ssel, char **host, wk
512 509
                 sselect_free(*ssel),*ssel=NULL;
513 510
 }
514 511
 
515
-
516 512
 char *
517 513
 webkernel_dual(test_action action)
518 514
 {
... ...
@@ -546,9 +542,6 @@ Connection: keep-alive\r\n\
546 542
         web=NULL;
547 543
         timeout=100;
548 544
         check=0;
549
-#if 1
550
-printf("\n");
551
-#endif
552 545
         if((ssel=sselect_init())==NULL)
553 546
                 return(STRING_FAIL ": couln't alloc a sselect structure");
554 547
         for(port=19747,off=0;(web=wk_init(port,ssel,NULL,webkernel_basichttp,NULL,NULL,&check))==NULL;off++,port++)
... ...
@@ -573,63 +566,33 @@ printf("\n");
573 566
                 ipv4_postconnect(clients[c]);
574 567
         }
575 568
         /* accept the connection */
576
-#if 1
577
-printf("0. fd[0]=%i, fd[1]=%i\n",clients[0],clients[1]);
578
-#endif
579
-#if 1
580
-printf("1. sselect_wait\n");
581
-#endif
582 569
         if(sselect_wait(ssel,timeout)!=1) {
583 570
                 webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
584 571
                 return(STRING_FAIL ": timeout on sselect_wait\n");
585 572
         }
586
-#if 1
587
-printf("2. wk_service\n");
588
-#endif
589 573
         wk_service(web);
590
-#if 1
591
-printf("3. sselect_getread\n");
592
-#endif
593 574
         if(sselect_getread(ssel,fds,sizeof(fds)/sizeof(fds[0]))==1) {
594 575
                 webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
595 576
                 return(STRING_FAIL ": wk_service hasn't serviced the server connection\n");
596 577
         }
597 578
         /* client does request into socket */
598
-#if 1
599
-printf("4. write\n");
600
-#endif
601 579
         for(c=0;c<(sizeof(clients)/sizeof(clients[0]));c++)
602 580
                 write(clients[c],test_request,sizeof(test_request)-1);
603 581
         /* socket-> callback_http -> reply_in_wk */
604
-#if 1
605
-printf("5. sselect_wait\n");
606
-#endif
607 582
         if(sselect_wait(ssel,timeout)!=2) {
608 583
                 webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
609 584
                 return(STRING_FAIL ": timeout on sselect_wait (after client request)\n");
610 585
         }
611
-#if 1
612
-printf("6. wk_service\n");
613
-#endif
614 586
         wk_service(web);
615
-#if 1
616
-printf("check is %i\n",check);
617
-#endif
618 587
         if(check!=2) {
619 588
                 webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
620 589
                 return(STRING_FAIL ": http callback was not called\n");
621 590
         }
622 591
         /* reply_in_wk -> socket */
623
-#if 1
624
-printf("7. sselect_wait\n");
625
-#endif
626 592
         if(sselect_wait(ssel,timeout)!=2) {
627 593
                 webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
628 594
                 return(STRING_FAIL ": (2) timeout on sselect_wait (after client request)\n");
629 595
         }
630
-#if 1
631
-printf("8. wk_service\n");
632
-#endif
633 596
         wk_service(web);
634 597
         /* client read availability */
635 598
         for(c=0;c<(sizeof(clients)/sizeof(clients[0]));c++)
Browse code

Fix clientblock and bufblock management. Fix wk_clientservicereadheader to consume input. Set keep-alive as default for HTTP/1.1 or greater connections

Dario Rodriguez authored on 02/07/2014 12:12:46
Showing 1 changed files
... ...
@@ -30,6 +30,7 @@ char *socklib_connect(test_action action);
30 30
 char *socklib_sselect(test_action action);
31 31
 char *sbuf_memory(test_action action);
32 32
 char *webkernel_basic(test_action action);
33
+char *webkernel_dual(test_action action);
33 34
 
34 35
 
35 36
 struct {
... ...
@@ -39,6 +40,7 @@ struct {
39 40
            {socklib_sselect},
40 41
            {sbuf_memory},
41 42
            {webkernel_basic},
43
+           {webkernel_dual},
42 44
           };
43 45
 
44 46
 int
... ...
@@ -48,8 +50,10 @@ main(int argc, char *argv[])
48 50
         int flagall;
49 51
         char *resstr;
50 52
         int total,totalfail;
51
-        if(argc==1 || strcmp(argv[argc-1],"--help")==0 || argc!=2) {
52
-                printf("Syntax:\n\t%s { --help | --list | test_name | all }\nNOTE: test_name is one of the tests listed in --list\n",argv[0]);
53
+        int n;
54
+        char *test;
55
+        if(argc==1 || strcmp(argv[argc-1],"--help")==0 || argc<2) {
56
+                printf("Syntax:\n\t%s { --help | --list | all | test_name [ test_name [...]] }\nNOTE: test_name is one of the tests listed in --list\n",argv[0]);
53 57
                 return(0);
54 58
         }
55 59
         if(strcmp(argv[argc-1],"--list")==0) {
... ...
@@ -58,8 +62,12 @@ main(int argc, char *argv[])
58 62
                 return(0);
59 63
         }
60 64
         flagall=(strcmp(argv[argc-1],"all")==0)?1:0;
61
-        for(total=totalfail=0,i=0;i<(sizeof(tests)/sizeof(tests[0]));i++) {
62
-                if(!flagall && strcmp(tests[i].test(test_name),argv[argc-1])!=0)
65
+        total=totalfail=0;
66
+        for(n=(flagall)?0:1;(flagall==0 && n<argc) || (flagall!=0 && n<(sizeof(tests)/sizeof(tests[0])));n++) {
67
+                test=(flagall!=0)?tests[n].test(test_name):argv[n];
68
+                for(i=0;i<(sizeof(tests)/sizeof(tests[0])) && strcmp(tests[i].test(test_name),test)!=0;i++)
69
+                        ;
70
+                if(i>=(sizeof(tests)/sizeof(tests[0])))
63 71
                         continue;
64 72
                 printf("%20s...",tests[i].test(test_name));
65 73
                 fflush(stdout);
... ...
@@ -69,7 +77,7 @@ main(int argc, char *argv[])
69 77
                 printf("%s\n",resstr);
70 78
 
71 79
         }
72
-        if(!flagall && i>=(sizeof(tests)/sizeof(tests[0]))) {
80
+        if(total==0) {
73 81
                 printf("ERROR: test not found\n");
74 82
                 return(1);
75 83
         }
... ...
@@ -353,12 +361,17 @@ wk_action
353 361
 webkernel_basichttp(wk *web, int connid, wk_uri *uri, void *userptr)
354 362
 {
355 363
 
356
-        *((int *)userptr)=0;
357 364
         char reply_ok[]={"Ok"};
365
+#if 1
366
+        printf("CALLBACK! (check is %i, 0x%p), uri->path:%s\n",(*((int *)userptr)),(void *)userptr,uri->path);
367
+#endif
358 368
         if(strcmp(uri->path,"/test.cgi")==0) {
359
-                *((int *)userptr)=1;
369
+                (*((int *)userptr))=(*((int *)userptr))+1;
360 370
                 wk_serve_buffer_as_file(web,connid,reply_ok,sizeof(reply_ok)-1,mime_getdefault("test.txt",NULL));
361 371
         }
372
+#if 1
373
+        printf("check is now %i\n",(*((int *)userptr)));
374
+#endif
362 375
         return(wkact_finished);
363 376
 }
364 377
 
... ...
@@ -452,7 +465,7 @@ Connection: keep-alive\r\n\
452 465
         /* reply_in_wk -> socket */
453 466
         if(sselect_wait(ssel,timeout)!=1) {
454 467
                 webkernel_basicclose(&client,&ssel,&host,&web);
455
-                return(STRING_FAIL ": timeout on sselect_wait (after client request)\n");
468
+                return(STRING_FAIL ": (2) timeout on sselect_wait (after client request)\n");
456 469
         }
457 470
         wk_service(web);
458 471
         /* client read availability */
... ...
@@ -483,3 +496,170 @@ Connection: keep-alive\r\n\
483 496
         return(STRING_OK);
484 497
 }
485 498
 
499
+void
500
+webkernel_dualclose(int *clients,int sizeclients,sselect **ssel, char **host, wk **web)
501
+{
502
+        int c;
503
+        for(c=0;c<sizeclients;c++) {
504
+                if(clients[c]!=-1)
505
+                        close(clients[c]),clients[c]=-1;
506
+        }
507
+        if(*host!=NULL)
508
+                free(*host),*host=NULL;
509
+        if(*web!=NULL)
510
+                wk_free(*web),*web=NULL;
511
+        if(*ssel!=NULL)
512
+                sselect_free(*ssel),*ssel=NULL;
513
+}
514
+
515
+
516
+char *
517
+webkernel_dual(test_action action)
518
+{
519
+        wk *web;
520
+        int port;
521
+        int off;
522
+        int check;
523
+        sselect *ssel;
524
+        int clients[2];
525
+        int c;
526
+        char *host;
527
+        long hostsize;
528
+        int timeout;
529
+        int fds[2];
530
+        char buf[128];
531
+        int usedbuf;
532
+        char test_request[]={"\
533
+GET /test.cgi HTTP/1.0\r\n\
534
+Host: localhost\r\n\
535
+Connection: keep-alive\r\n\
536
+\r\n\
537
+"};
538
+        if(action==test_name)
539
+                return("webkernel_dual");
540
+        else if(action==test_description)
541
+                return("webkernel multiple simultaneous connections");
542
+        for(c=0;c<(sizeof(clients)/sizeof(clients[0]));c++)
543
+                clients[c]=-1;
544
+        ssel=NULL;
545
+        host=NULL;
546
+        web=NULL;
547
+        timeout=100;
548
+        check=0;
549
+#if 1
550
+printf("\n");
551
+#endif
552
+        if((ssel=sselect_init())==NULL)
553
+                return(STRING_FAIL ": couln't alloc a sselect structure");
554
+        for(port=19747,off=0;(web=wk_init(port,ssel,NULL,webkernel_basichttp,NULL,NULL,&check))==NULL;off++,port++)
555
+                ;
556
+        if(web==NULL) {
557
+                webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
558
+                return(STRING_FAIL ": couln't find a free port to init webkernel");
559
+        }
560
+        if((host=ipv4_genip("localhost",&hostsize))==NULL) {
561
+                webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
562
+                return(STRING_FAIL ": couldn't resove localhost");
563
+        }
564
+        for(c=0;c<(sizeof(clients)/sizeof(clients[0]));c++) {
565
+                if((clients[c]=ipv4_preconnect(host,hostsize,port))==-1) {
566
+                        webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
567
+                        return(STRING_FAIL ": couldn't connect to server\n");
568
+                }
569
+                if(ipv4_connect(clients[c],timeout)==-1) {
570
+                        webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
571
+                                return(STRING_FAIL ": timeout on connect\n");
572
+                }
573
+                ipv4_postconnect(clients[c]);
574
+        }
575
+        /* accept the connection */
576
+#if 1
577
+printf("0. fd[0]=%i, fd[1]=%i\n",clients[0],clients[1]);
578
+#endif
579
+#if 1
580
+printf("1. sselect_wait\n");
581
+#endif
582
+        if(sselect_wait(ssel,timeout)!=1) {
583
+                webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
584
+                return(STRING_FAIL ": timeout on sselect_wait\n");
585
+        }
586
+#if 1
587
+printf("2. wk_service\n");
588
+#endif
589
+        wk_service(web);
590
+#if 1
591
+printf("3. sselect_getread\n");
592
+#endif
593
+        if(sselect_getread(ssel,fds,sizeof(fds)/sizeof(fds[0]))==1) {
594
+                webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
595
+                return(STRING_FAIL ": wk_service hasn't serviced the server connection\n");
596
+        }
597
+        /* client does request into socket */
598
+#if 1
599
+printf("4. write\n");
600
+#endif
601
+        for(c=0;c<(sizeof(clients)/sizeof(clients[0]));c++)
602
+                write(clients[c],test_request,sizeof(test_request)-1);
603
+        /* socket-> callback_http -> reply_in_wk */
604
+#if 1
605
+printf("5. sselect_wait\n");
606
+#endif
607
+        if(sselect_wait(ssel,timeout)!=2) {
608
+                webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
609
+                return(STRING_FAIL ": timeout on sselect_wait (after client request)\n");
610
+        }
611
+#if 1
612
+printf("6. wk_service\n");
613
+#endif
614
+        wk_service(web);
615
+#if 1
616
+printf("check is %i\n",check);
617
+#endif
618
+        if(check!=2) {
619
+                webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
620
+                return(STRING_FAIL ": http callback was not called\n");
621
+        }
622
+        /* reply_in_wk -> socket */
623
+#if 1
624
+printf("7. sselect_wait\n");
625
+#endif
626
+        if(sselect_wait(ssel,timeout)!=2) {
627
+                webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
628
+                return(STRING_FAIL ": (2) timeout on sselect_wait (after client request)\n");
629
+        }
630
+#if 1
631
+printf("8. wk_service\n");
632
+#endif
633
+        wk_service(web);
634
+        /* client read availability */
635
+        for(c=0;c<(sizeof(clients)/sizeof(clients[0]));c++)
636
+                sselect_addread(ssel,clients[c],NULL);
637
+        if(sselect_wait(ssel,timeout)!=2) {
638
+                webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
639
+                return(STRING_FAIL ": timeout on sselect_wait (to read client reply)\n");
640
+        }
641
+        wk_service(web);
642
+        if(sselect_getread(ssel,fds,sizeof(fds)/sizeof(fds[0]))!=2) {
643
+                webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
644
+                return(STRING_FAIL ": client read not detected\n");
645
+        }
646
+        /* read data */
647
+        for(c=0;c<(sizeof(clients)/sizeof(clients[0]));c++) {
648
+                if((usedbuf=read(clients[c],buf,sizeof(buf)-1))<0) {
649
+                        webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
650
+                        return(STRING_FAIL ": couldn't read reply\n");
651
+                }
652
+                buf[usedbuf]='\0';
653
+                if(usedbuf<2 || memcmp(buf+usedbuf-2,"Ok",2)!=0) {
654
+                        webkernel_dualclose(clients,sizeof(clients)/sizeof(clients[0]),&ssel,&host,&web);
655
+                        return(STRING_FAIL ": corrupted data in read on client\n");
656
+                }
657
+        }
658
+        for(c=0;c<(sizeof(clients)/sizeof(clients[0]));c++)
659
+                close(clients[c]),clients[c]=-1;
660
+        wk_free(web),web=NULL;
661
+        sselect_free(ssel),ssel=NULL;
662
+        free(host),host=NULL;
663
+        return(STRING_OK);
664
+}
665
+
Browse code

webkernel: get vars from GET request, partial implementation of vars for POST request.

Dario Rodriguez authored on 23/06/2014 20:31:46
Showing 1 changed files
... ...
@@ -388,7 +388,8 @@ webkernel_basic(test_action action)
388 388
         long hostsize;
389 389
         int timeout;
390 390
         int fds[2];
391
-        char buf;
391
+        char buf[128];
392
+        int usedbuf;
392 393
         char test_request[]={"\
393 394
 GET /test.cgi HTTP/1.0\r\n\
394 395
 Host: localhost\r\n\
... ...
@@ -407,7 +408,7 @@ Connection: keep-alive\r\n\
407 408
         check=0;
408 409
         if((ssel=sselect_init())==NULL)
409 410
                 return(STRING_FAIL ": couln't alloc a sselect structure");
410
-        for(port=19747,off=0,check=0;(web=wk_init(port,ssel,NULL,webkernel_basichttp,NULL,&check))==NULL;off++,port++)
411
+        for(port=19747,off=0,check=0;(web=wk_init(port,ssel,NULL,webkernel_basichttp,NULL,NULL,&check))==NULL;off++,port++)
411 412
                 ;
412 413
         if(web==NULL) {
413 414
                 webkernel_basicclose(&client,&ssel,&host,&web);
... ...
@@ -466,7 +467,12 @@ Connection: keep-alive\r\n\
466 467
                 return(STRING_FAIL ": client read not detected\n");
467 468
         }
468 469
         /* read data */
469
-        if(read(client,buf,2)!=2 || memcmp(buf,"Ok",2)!=0) {
470
+        if((usedbuf=read(client,buf,sizeof(buf)-1))<0) {
471
+                webkernel_basicclose(&client,&ssel,&host,&web);
472
+                return(STRING_FAIL ": couldn't read reply\n");
473
+        }
474
+        buf[usedbuf]='\0';
475
+        if(usedbuf<2 || memcmp(buf+usedbuf-2,"Ok",2)!=0) {
470 476
                 webkernel_basicclose(&client,&ssel,&host,&web);
471 477
                 return(STRING_FAIL ": corrupted data in read on client\n");
472 478
         }
Browse code

webkernel_test: webkernel basic test

Dario Rodriguez authored on 21/06/2014 09:42:38
Showing 1 changed files
... ...
@@ -29,6 +29,8 @@ char *test1(test_action action);
29 29
 char *socklib_connect(test_action action);
30 30
 char *socklib_sselect(test_action action);
31 31
 char *sbuf_memory(test_action action);
32
+char *webkernel_basic(test_action action);
33
+
32 34
 
33 35
 struct {
34 36
         char *(*test)(/* test_action action */);
... ...
@@ -36,6 +38,7 @@ struct {
36 38
            {socklib_connect},
37 39
            {socklib_sselect},
38 40
            {sbuf_memory},
41
+           {webkernel_basic},
39 42
           };
40 43
 
41 44
 int
... ...
@@ -75,6 +78,7 @@ main(int argc, char *argv[])
75 78
         return((totalfail!=0)?1:0);
76 79
 }
77 80
 
81
+/* test1 */
78 82
 char *
79 83
 test1(test_action action)
80 84
 {
... ...
@@ -86,6 +90,7 @@ test1(test_action action)
86 90
         return("ok");
87 91
 }
88 92
 
93
+/* socklib_connect */
89 94
 char *
90 95
 socklib_connect(test_action action)
91 96
 {
... ...
@@ -128,6 +133,7 @@ socklib_connect(test_action action)
128 133
         return(STRING_OK);
129 134
 }
130 135
 
136
+/* socklib_sselect */
131 137
 char *
132 138
 test_socketsinit(int *server, int *client, char **host, long *hostsize, int *port)
133 139
 {
... ...
@@ -275,6 +281,7 @@ socklib_sselect(test_action action)
275 281
         return(STRING_OK);
276 282
 }
277 283
 
284
+/* sbuf_memory */
278 285
 char *
279 286
 sbuf_memory(test_action action)
280 287
 {
... ...
@@ -341,3 +348,132 @@ sbuf_memory(test_action action)
341 348
         return(STRING_OK);
342 349
 }
343 350
 
351
+/* webkernel_basic */
352
+wk_action
353
+webkernel_basichttp(wk *web, int connid, wk_uri *uri, void *userptr)
354
+{
355
+
356
+        *((int *)userptr)=0;
357
+        char reply_ok[]={"Ok"};
358
+        if(strcmp(uri->path,"/test.cgi")==0) {
359
+                *((int *)userptr)=1;
360
+                wk_serve_buffer_as_file(web,connid,reply_ok,sizeof(reply_ok)-1,mime_getdefault("test.txt",NULL));
361
+        }
362
+        return(wkact_finished);
363
+}
364
+
365
+void
366
+webkernel_basicclose(int *client,sselect **ssel, char **host, wk **web)
367
+{
368
+        if(*client!=-1)
369
+                close(*client),*client=-1;
370
+        if(*host!=NULL)
371
+                free(*host),*host=NULL;
372
+        if(*web!=NULL)
373
+                wk_free(*web),*web=NULL;
374
+        if(*ssel!=NULL)
375
+                sselect_free(*ssel),*ssel=NULL;
376
+}
377
+
378
+char *
379
+webkernel_basic(test_action action)
380
+{
381
+        wk *web;
382
+        int port;
383
+        int off;
384
+        int check;
385
+        sselect *ssel;
386
+        int client;
387
+        char *host;
388
+        long hostsize;
389
+        int timeout;
390
+        int fds[2];
391
+        char buf;
392
+        char test_request[]={"\
393
+GET /test.cgi HTTP/1.0\r\n\
394
+Host: localhost\r\n\
395
+Connection: keep-alive\r\n\
396
+\r\n\
397
+"};
398
+        if(action==test_name)
399
+                return("webkernel_basic");
400
+        else if(action==test_description)
401
+                return("webkernel basic usage");
402
+        client=-1;
403
+        ssel=NULL;
404
+        host=NULL;
405
+        web=NULL;
406
+        timeout=100;
407
+        check=0;
408
+        if((ssel=sselect_init())==NULL)
409
+                return(STRING_FAIL ": couln't alloc a sselect structure");
410
+        for(port=19747,off=0,check=0;(web=wk_init(port,ssel,NULL,webkernel_basichttp,NULL,&check))==NULL;off++,port++)
411
+                ;
412
+        if(web==NULL) {
413
+                webkernel_basicclose(&client,&ssel,&host,&web);
414
+                return(STRING_FAIL ": couln't find a free port to init webkernel");
415
+        }
416
+        if((host=ipv4_genip("localhost",&hostsize))==NULL) {
417
+                webkernel_basicclose(&client,&ssel,&host,&web);
418
+                return(STRING_FAIL ": couldn't resove localhost");
419
+        }
420
+        if((client=ipv4_preconnect(host,hostsize,port))==-1) {
421
+                webkernel_basicclose(&client,&ssel,&host,&web);
422
+                return(STRING_FAIL ": couldn't connect to server\n");
423
+        }
424
+        if(ipv4_connect(client,timeout)==-1) {
425
+                webkernel_basicclose(&client,&ssel,&host,&web);
426
+                return(STRING_FAIL ": timeout on connect\n");
427
+        }
428
+        ipv4_postconnect(client);
429
+        /* accept the connection */
430
+        if(sselect_wait(ssel,timeout)!=1) {
431
+                webkernel_basicclose(&client,&ssel,&host,&web);
432
+                return(STRING_FAIL ": timeout on sselect_wait\n");
433
+        }
434
+        wk_service(web);
435
+        if(sselect_getread(ssel,fds,sizeof(fds)/sizeof(fds[0]))==1) {
436
+                webkernel_basicclose(&client,&ssel,&host,&web);
437
+                return(STRING_FAIL ": wk_service hasn't serviced the server connection\n");
438
+        }
439
+        /* client does request into socket */
440
+        write(client,test_request,sizeof(test_request)-1);
441
+        /* socket-> callback_http -> reply_in_wk */
442
+        if(sselect_wait(ssel,timeout)!=1) {
443
+                webkernel_basicclose(&client,&ssel,&host,&web);
444
+                return(STRING_FAIL ": timeout on sselect_wait (after client request)\n");
445
+        }
446
+        wk_service(web);
447
+        if(check!=1) {
448
+                webkernel_basicclose(&client,&ssel,&host,&web);
449
+                return(STRING_FAIL ": http callback was not called\n");
450
+        }
451
+        /* reply_in_wk -> socket */
452
+        if(sselect_wait(ssel,timeout)!=1) {
453
+                webkernel_basicclose(&client,&ssel,&host,&web);
454
+                return(STRING_FAIL ": timeout on sselect_wait (after client request)\n");
455
+        }
456
+        wk_service(web);
457
+        /* client read availability */
458
+        sselect_addread(ssel,client,NULL);
459
+        if(sselect_wait(ssel,timeout)!=1) {
460
+                webkernel_basicclose(&client,&ssel,&host,&web);
461
+                return(STRING_FAIL ": timeout on sselect_wait (to read client reply)\n");
462
+        }
463
+        wk_service(web);
464
+        if(sselect_getread(ssel,fds,sizeof(fds)/sizeof(fds[0]))!=1 || *fds!=client) {
465
+                webkernel_basicclose(&client,&ssel,&host,&web);
466
+                return(STRING_FAIL ": client read not detected\n");
467
+        }
468
+        /* read data */
469
+        if(read(client,buf,2)!=2 || memcmp(buf,"Ok",2)!=0) {
470
+                webkernel_basicclose(&client,&ssel,&host,&web);
471
+                return(STRING_FAIL ": corrupted data in read on client\n");
472
+        }
473
+        close(client),client=-1;
474
+        wk_free(web),web=NULL;
475
+        sselect_free(ssel),ssel=NULL;
476
+        free(host),host=NULL;
477
+        return(STRING_OK);
478
+}
479
+
Browse code

webkernel_test: sbuf_memory test

Dario Rodriguez authored on 20/06/2014 18:57:58
Showing 1 changed files
... ...
@@ -28,12 +28,14 @@ typedef enum test_action {
28 28
 char *test1(test_action action);
29 29
 char *socklib_connect(test_action action);
30 30
 char *socklib_sselect(test_action action);
31
+char *sbuf_memory(test_action action);
31 32
 
32 33
 struct {
33 34
         char *(*test)(/* test_action action */);
34 35
 } tests[]={{test1},
35 36
            {socklib_connect},
36 37
            {socklib_sselect},
38
+           {sbuf_memory},
37 39
           };
38 40
 
39 41
 int
... ...
@@ -273,3 +275,69 @@ socklib_sselect(test_action action)
273 275
         return(STRING_OK);
274 276
 }
275 277
 
278
+char *
279
+sbuf_memory(test_action action)
280
+{
281
+        int bufsize=2048;
282
+        const unsigned char data[]={0,2,4,1,2,4,1,76,91,147,135,253,121,56,5,9};
283
+        unsigned char moredata[16];
284
+        unsigned char *ptr;
285
+        const char *line,lines[]={"one\nand two\nthree"};
286
+        int i;
287
+        sbuf *buf;
288
+        if(action==test_name)
289
+                return("sbuf_memory");
290
+        else if(action==test_description)
291
+                return("memory operations with sbuf");
292
+        if((buf=sbuf_init(bufsize))==NULL)
293
+                return(STRING_FAIL ": couldn't alloc new sbuf");
294
+        if(sbuf_add(buf,(char *)data,sizeof(data))!=sizeof(data)) {
295
+                sbuf_free(buf),buf=NULL;
296
+                return(STRING_FAIL ": couldn't push data");
297
+        }
298
+        for(i=0;i<sizeof(moredata);i++)
299
+                moredata[i]=i;
300
+        if(sbuf_add(buf,(char *)moredata,sizeof(moredata))!=sizeof(moredata)) {
301
+                sbuf_free(buf),buf=NULL;
302
+                return(STRING_FAIL ": (2) couldn't push data");
303
+        }
304
+        if(sbuf_count(buf)!=(sizeof(data)+sizeof(moredata))) {
305
+                sbuf_free(buf),buf=NULL;
306
+                return(STRING_FAIL ": bad count");
307
+        }
308
+        for(i=0;i<sizeof(data);i++) {
309
+                if((ptr=(unsigned char *)sbuf_getbytes(buf,1))==NULL || *ptr!=data[i]) {
310
+                        sbuf_free(buf),buf=NULL;
311
+                        return(STRING_FAIL ": bad retrieval");
312
+                }
313
+        }
314
+        sbuf_discard(buf);
315
+        if((ptr=(unsigned char *)sbuf_getbytes(buf,sizeof(moredata)))==NULL || memcmp(ptr,moredata,sizeof(moredata))!=0) {
316
+                sbuf_free(buf),buf=NULL;
317
+                return(STRING_FAIL ": (2) bad retrieval");
318
+        }
319
+        if(sbuf_getbytes(buf,1)!=NULL) {
320
+                sbuf_free(buf),buf=NULL;
321
+                return(STRING_FAIL ": (3) bad retrieval");
322
+        }
323
+        sbuf_discard(buf);
324
+        if(sbuf_addstr(buf,lines)!=(sizeof(lines)-1)) {
325
+                sbuf_free(buf),buf=NULL;
326
+                return(STRING_FAIL ": (3) couldn't push data");
327
+        }
328
+        if((line=sbuf_getline(buf))==NULL || strcmp(line,"one")!=0) {
329
+                sbuf_free(buf),buf=NULL;
330
+                return(STRING_FAIL ": bad line retrieval");
331
+        }
332
+        if((line=sbuf_getline(buf))==NULL || strcmp(line,"and two")!=0) {
333
+                sbuf_free(buf),buf=NULL;
334
+                return(STRING_FAIL ": (2) bad line retrieval");
335
+        }
336
+        if(sbuf_getline(buf)!=NULL) {
337
+                sbuf_free(buf),buf=NULL;
338
+                return(STRING_FAIL ": (3) bad line retrieval");
339
+        }
340
+        sbuf_free(buf),buf=NULL;
341
+        return(STRING_OK);
342
+}
343
+
Browse code

webkernel_test: test socklib

Dario Rodriguez authored on 20/06/2014 10:28:42
Showing 1 changed files
... ...
@@ -18,7 +18,6 @@
18 18
 
19 19
 #define STRING_OK "ok"
20 20
 #define STRING_FAIL "fail"
21
-#define STRING_SEP ":"
22 21
 
23 22
 typedef enum test_action {
24 23
         test_name=0,
... ...
@@ -27,10 +26,15 @@ typedef enum test_action {
27 26
 } test_action;
28 27
 
29 28
 char *test1(test_action action);
29
+char *socklib_connect(test_action action);
30
+char *socklib_sselect(test_action action);
30 31
 
31 32
 struct {
32 33
         char *(*test)(/* test_action action */);
33
-} tests[]={{test1}};
34
+} tests[]={{test1},
35
+           {socklib_connect},
36
+           {socklib_sselect},
37
+          };
34 38
 
35 39
 int
36 40
 main(int argc, char *argv[])
... ...
@@ -80,4 +84,192 @@ test1(test_action action)
80 84
         return("ok");
81 85
 }
82 86
 
87
+char *
88
+socklib_connect(test_action action)
89
+{
90
+        int server,client;
91
+        char *host;
92
+        long hostsize;
93
+        int port;
94
+        int off;
95
+        int timeout=100;
96
+        if(action==test_name)
97
+                return("socklib_connect");
98
+        if(action==test_description)
99
+                return("listen and connect");
100
+        if((host=ipv4_genip("localhost",&hostsize))==NULL)
101
+                return(STRING_FAIL ": couldn't resove localhost");
102
+        for(server=-1,off=0,port=19747;off<1024;off++,port++) {
103
+                if((server=ipv4_serverbinded(host,hostsize,port))!=-1)
104
+                        break;
105
+        }
106
+        if(server==-1) {
107
+                free(host),host=NULL;
108
+                return(STRING_FAIL ": couldn't find empty port for server\n");
109
+        }
110
+        sock_setunsafe(server);
111
+        if((client=ipv4_preconnect(host,hostsize,port))==-1) {
112
+                close(server),server=-1;
113
+                free(host),host=NULL;
114
+                return(STRING_FAIL ": couldn't connect to server\n");
115
+        }
116
+        if(ipv4_connect(client,timeout)==-1) {
117
+                close(client),client=-1;
118
+                close(server),server=-1;
119
+                free(host),host=NULL;
120
+                return(STRING_FAIL ": timeout on connect\n");
121
+        }
122
+        ipv4_postconnect(client);
123
+        close(client),client=-1;
124
+        close(server),server=-1;
125
+        free(host),host=NULL;
126
+        return(STRING_OK);
127
+}
128
+
129
+char *
130
+test_socketsinit(int *server, int *client, char **host, long *hostsize, int *port)
131
+{
132
+        int timeout=100;
133
+        int off;
134
+        *server=*client=*port=-1;
135
+        *hostsize=0;
136
+        *host=NULL;
137
+        *port=-1;
138
+        if((*host=ipv4_genip("localhost",hostsize))==NULL)
139
+                return(STRING_FAIL ": couldn't resove localhost");
140
+        for(*server=-1,off=0,*port=19747;off<1024;off++,(*port)++) {
141
+                if((*server=ipv4_serverbinded(*host,*hostsize,*port))!=-1)
142
+                        break;
143
+        }
144
+        if(*server==-1) {
145
+                free(*host),*host=NULL;
146
+                return(STRING_FAIL ": couldn't find empty port for server\n");
147
+        }
148
+        sock_setunsafe(*server);
149
+        if((*client=ipv4_preconnect(*host,*hostsize,*port))==-1) {
150
+                close(*server),*server=-1;
151
+                free(*host),*host=NULL;
152
+                return(STRING_FAIL ": couldn't connect to server\n");
153
+        }
154
+        if(ipv4_connect(*client,timeout)==-1) {
155
+                close(*client),*client=-1;
156
+                close(*server),*server=-1;
157
+                free(*host),*host=NULL;
158
+                return(STRING_FAIL ": timeout on connect\n");
159
+        }
160
+        ipv4_postconnect(*client);
161
+        return(NULL);
162
+}
163
+
164
+void
165
+test_socketsfini(int *server, int *client, char **host, long *hostsize, int *port)
166
+{
167
+        if(*server!=-1)
168
+                close(*server),*server=-1;
169
+        if(*client!=-1)
170
+                close(*client),*client=-1;
171
+        if(*host!=NULL)
172
+                free(*host),*host=NULL;
173
+        *hostsize=0;
174
+        *port=-1;
175
+}
176
+
177
+char *
178
+socklib_sselect(test_action action)
179
+{
180
+        int server,client;
181
+        char *host;
182
+        long hostsize;
183
+        int port;
184
+        char *result;
185
+        char buf[128];
186
+        int readyfds[16];
187
+        sselect *ssel;
188
+        int timeout=100;
189
+        int workfd;
190
+        if(action==test_name)
191
+                return("socklib_sselect");
192
+        if(action==test_description)
193
+                return("select over sockets");
194
+        if((result=test_socketsinit(&server,&client,&host,&hostsize,&port))!=NULL) {
195
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
196
+                return(result);
197
+        }
198
+        if((ssel=sselect_init())==NULL) {
199
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
200
+                return(STRING_FAIL ": couldn't init sselect struct");
201
+        }
202
+        if(sselect_reset(ssel)!=0) {
203
+                sselect_free(ssel),ssel=NULL;
204
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
205
+                return(STRING_FAIL ": couldn't test the sselect reset function");
206
+        }
207
+        if(sselect_wait(ssel,timeout)!=0) {
208
+                sselect_free(ssel),ssel=NULL;
209
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
210
+                return(STRING_FAIL ": (1) was expecting a timeout, something else happened");
211
+        }
212
+        if(sselect_addread(ssel,server,buf)!=0) {
213
+                sselect_free(ssel),ssel=NULL;
214
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
215
+                return(STRING_FAIL ": couldn't add 'read serverfd' to the sselect");
216
+        }
217
+        if(sselect_wait(ssel,timeout)!=1) {
218
+                sselect_free(ssel),ssel=NULL;
219
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
220
+                return(STRING_FAIL ": (2) was expecting a ready-to-read, something else happened");
221
+        }
222
+        if((workfd=sock_accept(server))==-1) {
223
+                sselect_free(ssel),ssel=NULL;
224
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
225
+                return(STRING_FAIL ": couldn't accept connection");
226
+        }
227
+        write(client,".",1);
228
+        if(sselect_wait(ssel,timeout)!=0) {
229
+                sselect_free(ssel),ssel=NULL;
230
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
231
+                return(STRING_FAIL ": (2) was expecting a timeout, something else happened");
232
+        }
233
+        if(sselect_addread(ssel,workfd,&workfd)!=0) {
234
+                sselect_free(ssel),ssel=NULL;
235
+                close(workfd),workfd=-1;
236
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
237
+                return(STRING_FAIL ": couldn't add 'read workfd' to the sselect");
238
+        }
239
+        if(sselect_wait(ssel,timeout)!=1) {
240
+                sselect_free(ssel),ssel=NULL;
241
+                close(workfd),workfd=-1;
242
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
243
+                return(STRING_FAIL ": was expecting a something-to-read, something else happened");
244
+        }
245
+        if((sselect_getread(ssel,readyfds,sizeof(readyfds)/sizeof(readyfds[0])))!=1 || *readyfds!=workfd) {
246
+                sselect_free(ssel),ssel=NULL;
247
+                close(workfd),workfd=-1;
248
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
249
+                return(STRING_FAIL ": the list of ready-to-read fds is wrong");
250
+        }
251
+        if(sselect_getuserptr(ssel,workfd)!=&workfd) {
252
+                sselect_free(ssel),ssel=NULL;
253
+                close(workfd),workfd=-1;
254
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
255
+                return(STRING_FAIL ": Couldn't recover the userptr of workfd");
256
+        }
257
+        read(workfd,buf,1);
258
+        if(sselect_addwrite(ssel,client,buf)!=0) {
259
+                sselect_free(ssel),ssel=NULL;
260
+                close(workfd),workfd=-1;
261
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
262
+                return(STRING_FAIL ": couldn't add 'write clientfd' to the sselect");
263
+        }
264
+        if(sselect_wait(ssel,timeout)!=1) {
265
+                sselect_free(ssel),ssel=NULL;
266
+                close(workfd),workfd=-1;
267
+                test_socketsfini(&server,&client,&host,&hostsize,&port);
268
+                return(STRING_FAIL ": was expecting an ok-to-write, something else happened");
269
+        }
270
+        sselect_free(ssel),ssel=NULL;
271
+        close(workfd),workfd=-1;
272
+        test_socketsfini(&server,&client,&host,&hostsize,&port);
273
+        return(STRING_OK);
274
+}
83 275
 
Browse code

webkernel_test: initial implementation of the testing framework

Dario Rodriguez authored on 18/06/2014 11:18:10
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,83 @@
1
+/*
2
+ * webkernel_test.c
3
+ *
4
+ * Tests to stress the webkernel API.
5
+ *
6
+ * Author: Dario Rodriguez dario@softhome.net
7
+ * This program is dual licensed: MIT and in "the public domain".
8
+ */
9
+
10
+
11
+#include <stdio.h>
12
+#include <stdlib.h>
13
+#include <unistd.h>
14
+#include <string.h>
15
+#include "sbuf.h"
16
+#include "socklib.h"
17
+#include "webkernel.h"
18
+
19
+#define STRING_OK "ok"
20
+#define STRING_FAIL "fail"
21
+#define STRING_SEP ":"
22
+
23
+typedef enum test_action {
24
+        test_name=0,
25
+        test_description,
26
+        test_run
27
+} test_action;
28
+
29
+char *test1(test_action action);
30
+
31
+struct {
32
+        char *(*test)(/* test_action action */);
33
+} tests[]={{test1}};
34
+
35
+int
36
+main(int argc, char *argv[])
37
+{
38
+        int i;
39
+        int flagall;
40
+        char *resstr;
41
+        int total,totalfail;
42
+        if(argc==1 || strcmp(argv[argc-1],"--help")==0 || argc!=2) {
43
+                printf("Syntax:\n\t%s { --help | --list | test_name | all }\nNOTE: test_name is one of the tests listed in --list\n",argv[0]);
44
+                return(0);
45
+        }
46
+        if(strcmp(argv[argc-1],"--list")==0) {
47
+                for(i=0;i<(sizeof(tests)/sizeof(tests[0]));i++)
48
+                        printf("%s\n\t%s\n",tests[i].test(test_name),tests[i].test(test_description));
49
+                return(0);
50
+        }
51
+        flagall=(strcmp(argv[argc-1],"all")==0)?1:0;
52
+        for(total=totalfail=0,i=0;i<(sizeof(tests)/sizeof(tests[0]));i++) {
53
+                if(!flagall && strcmp(tests[i].test(test_name),argv[argc-1])!=0)
54
+                        continue;
55
+                printf("%20s...",tests[i].test(test_name));
56
+                fflush(stdout);
57
+                resstr=tests[i].test(test_run);
58
+                total++;
59
+                totalfail+=((memcmp(resstr,STRING_OK,strlen(STRING_OK))==0)?0:1);
60
+                printf("%s\n",resstr);
61
+
62
+        }
63
+        if(!flagall && i>=(sizeof(tests)/sizeof(tests[0]))) {
64
+                printf("ERROR: test not found\n");
65
+                return(1);
66
+        }
67
+        if(totalfail!=0)
68
+                printf("Failed %i of %i tests.\n",totalfail,total);
69
+        return((totalfail!=0)?1:0);
70
+}
71
+
72
+char *
73
+test1(test_action action)
74
+{
75
+        if(action==test_name)
76
+                return("test1");
77
+        else if(action==test_description)
78
+                return("test the testing framework");
79
+        /* run test */
80
+        return("ok");
81
+}
82
+
83
+