LCOV - code coverage report
Current view: top level - tests - test_web_api.c (source / functions) Hit Total Coverage
Test: deployctl-0.3.15.2.96a2d Code Coverage Lines: 57 57 100.0 %
Date: 2018-06-22 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  test_web_api.c
       3             :  Created by Danny Goossen, Gioxa Ltd on 26/3/17.
       4             : 
       5             :  MIT License
       6             : 
       7             :  Copyright (c) 2017 deployctl, Gioxa Ltd.
       8             : 
       9             :  Permission is hereby granted, free of charge, to any person obtaining a copy
      10             :  of this software and associated documentation files (the "Software"), to deal
      11             :  in the Software without restriction, including without limitation the rights
      12             :  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      13             :  copies of the Software, and to permit persons to whom the Software is
      14             :  furnished to do so, subject to the following conditions:
      15             : 
      16             :  The above copyright notice and this permission notice shall be included in all
      17             :  copies or substantial portions of the Software.
      18             : 
      19             :  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      20             :  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      21             :  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      22             :  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      23             :  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      24             :  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      25             :  SOFTWARE.
      26             : 
      27             :  */
      28             : #include "../src/deployd.h"
      29             : #include "test_web_api.h"
      30             : 
      31             : 
      32             : /*------------------------------------------------------------------------
      33             :  *
      34             :  * Signal handler
      35             :  *
      36             :  *------------------------------------------------------------------------*/
      37             : 
      38           6 : static void signal_handler(sig)
      39             : int sig;
      40             : {
      41             :    int i;
      42             :    switch(sig) {
      43             : 
      44             :       case SIGSTOP:
      45             :       case SIGQUIT:
      46             :       case SIGINT:
      47             :       case SIGTERM:
      48             :       case SIGSEGV:
      49           6 :         debug ("\nsighandler: Signal %d : %s !!!\n",sig,strsignal(sig));
      50     6291468 :          for (i=getdtablesize();i>=0;--i)
      51             :          {
      52     6291462 :             close(i); /* close all descriptors */
      53             :          }
      54           6 :          exit(0);
      55             :          break;
      56             :    }
      57             : // LCOV_EXCL_START
      58             : // should never come here, and if, makes nod difference
      59             : }
      60             : // LCOV_EXCL_STOP
      61             : /**********************************************************************************
      62             :  * Test web server, returns 0 on success.
      63             :  * forks and keeps running in background with pid: child_pid
      64             :  *       Listens on localhost:<port>
      65             :  *
      66             :  * Stop with : stop_test_web(child_pid);
      67             :  *
      68             :  * webserver contains 4 buffers
      69             :  *
      70             :  * char request[1024] => format with %d for port in Host header:
      71             :  * e.g: "GET /test "HTTP/1.1\r\nHost: localhost:%d\r\n .... "
      72             :  *
      73             :  * char reply_header[1024]: format as printf=> first %d for port, %d for content length, %s for content
      74             :  * e.g : "HTTP/1.1 200 OK\r\nServer: testweb/0.0.1\r\nContent-Length:%d\r\n\r\n%s"
      75             :  * char reply_content[1024]; content as per above
      76             :  *
      77             :  * char reply_fail[1024] :=> response on failure
      78             :  *
      79             :  * if request == request=> response is reply... else reply_fail
      80             :  *
      81             :  **********************************************************************************/
      82             : 
      83             : 
      84           6 : int webserver( pid_t * child_pid, u_int16_t * port, webserver_t * webserver, int id)
      85             : {
      86             :    // first bind!
      87           6 :    int bind_result=0;
      88           6 :    int fd = socket(AF_INET, SOCK_STREAM, 0);
      89             : 
      90             :    struct sockaddr_in serv_addr;
      91           6 :    bzero((char *) &serv_addr, sizeof(serv_addr));
      92             : 
      93             :    // configure server information
      94           6 :    serv_addr.sin_family = AF_INET;
      95           6 :    serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
      96           6 :    serv_addr.sin_port = ntohs(0);
      97           6 :    bind_result=bind(fd,(struct sockaddr *) &serv_addr, sizeof(serv_addr));
      98           6 :    if (bind_result!=SOCKET_ERROR )
      99             :    {
     100           6 :       socklen_t size = sizeof(serv_addr);
     101           6 :       getsockname(fd, (struct sockaddr *) &serv_addr, &size);
     102           6 :       *port = ntohs(serv_addr.sin_port);
     103             :       // then fork
     104           6 :       *child_pid = fork();
     105             : 
     106          12 :       if(*child_pid == 0)
     107             :       {
     108             :          //the child
     109           6 :          int fds=INVALID_SOCKET;
     110           6 :          signal(SIGKILL,&signal_handler); /* catch kill signal */
     111           6 :          signal(SIGTERM,&signal_handler); /* catch kill signal */
     112           6 :          signal(SIGSTOP,&signal_handler); /* catch kill signal */
     113           6 :          signal(SIGQUIT,&signal_handler); /* catch kill signal */
     114           6 :          signal(SIGSEGV,&signal_handler); /* catch kill signal */
     115             :          // socket and bind
     116           6 :          listen(fd, 1);
     117           6 :          int accept_error=0;
     118             :          while (1) {
     119          13 :             fds=accept(fd, NULL,NULL);
     120           7 :             if (fds==INVALID_SOCKET ) accept_error=errno;
     121           7 :             if (fds==INVALID_SOCKET && accept_error==EINTR) continue;
     122           7 :             if (fds==INVALID_SOCKET && accept_error!=EINTR) break;
     123           7 :             debug("child: got a connection\n");
     124           7 :             size_t read_size=0;
     125           7 :             size_t write_size=0;
     126             :             char * buff[0x10000];
     127             : 
     128           7 :             usleep(1000); // make sure client has sent it!! so only one read for the whole buff.
     129             :             do{
     130           7 :                read_size=recv(fds, buff, 0x10000, 0);
     131             :             }
     132             :             // LCOV_EXCL_START
     133             :             //  never get to it
     134             :             while (read_size==0 && (read_size!=SOCKET_ERROR || (read_size==SOCKET_ERROR && errno==EINTR) ));
     135             :             // LCOV_EXCL_STOP
     136             : 
     137           7 :             buff[read_size]=0;
     138           7 :             debug("Child : received \n>>>%s<<<\n",buff);
     139             :             // get the port correct in request
     140             :             char temp[1024];
     141           7 :             sprintf(temp, webserver->request,*port);
     142           7 :             debug("Child : >>>cmp2\n>>>%s<<<\n==\n>>>%s<<<\n",temp,buff);
     143           7 :             if (strcmp((const char* )buff, temp)==0){
     144           6 :                sprintf((char *)buff, webserver->reply_header,strlen(webserver->reply_content),webserver->reply_content);
     145             :             }
     146             :             else {
     147           1 :                sprintf((char *)buff, "%s",webserver->reply_fail);
     148             :             }
     149           7 :             write_size=write(fds,(char *)buff,strlen((char*)buff));
     150           7 :             read_size=0;
     151             :          }
     152             :           // LCOV_EXCL_START
     153             :          // should never come here
     154             :          exit(0);
     155             :          // LCOV_EXCL_STOP
     156             :       }
     157           6 :       else if (*child_pid>0)
     158             :       {
     159             :       // the parent
     160             :          //close the accept filehandle and return return
     161           6 :          close(fd);
     162           6 :          return 0;
     163             :       }
     164             :    }
     165             :    // LCOV_EXCL_START
     166             :    // should never come here
     167             :    return -1;
     168             :    // LCOV_EXCL_STOP
     169             : }
     170             : 
     171           6 : int stop_test_web(pid_t child_pid)
     172             : {
     173             :    //kill
     174           6 :    kill(child_pid,SIGQUIT); // TODO need to check with WHOANG
     175           6 :    usleep(100000);
     176           6 :    int status=0;
     177           6 :    pid_t w = waitpid(child_pid,&status, 0);
     178           6 :    if (w==-1) { sock_error("waitpid"); return 1; }
     179           6 :    else if (WIFEXITED(status))
     180             :    {
     181           6 :        error("exit webserver w error: %d\n",WEXITSTATUS(status));
     182             :    }
     183             :    // LCOV_EXCL_START
     184             :    // we never get here
     185             :    else { return 1; }
     186             :    // LCOV_EXCL_STOP
     187           6 :    return 0;
     188             : }

Generated by: LCOV version 1.10