(file) Return to torturetest.c CVS log (file) Jump to this file's LXR Page (dir) Up to [CENS] / emstar / fusd / test

File: [CENS] / emstar / fusd / test / torturetest.c (download) / (as text)
Revision: 1.14, Fri Jul 11 21:29:40 2003 UTC (6 years, 4 months ago) by cerpa
Branch: MAIN
CVS Tags: scale_radio_channel, rdd_alpha_version_1, pregeonet, nims-lab-Sep07-2004, nims-jr-Sep05-04, mote, lessgps_release, kiss_release, fusd_with_no_daemon, fusd-1_10, copyright-07-11-03, bp_scale_radio_channel, audio_server, acoustic-05-18-06, ROUTING_EXPERIMENTAL, PRE_TOSNIC_FIX, PRE_NOMEGA_MOTENIC, PRE_MOTENIC_CLEANUP, PRE_CEILING_FIX, PRE_64BIT, MOTENIC_PRE_BUGFIX_20050415, LESSGPS_1_00, LAURA_CALIBRATION_EXPERIMENTS, KISS_1_0, HOSTMOTE_V_6_EXPERIMENTAL, HOSTMOTE_PROTOCOL_VERSION_7, HOSTMOTE_PROTOCOL_VERSION_6_WITH_HOSTMOAP, HOSTMOTE_PROTOCOL_VERSION_5_WITH_HOSTMOAP, HOSTMOTE_PROTOCOL_VERSION_5, HOSTMOTE_PROTOCOL_VERSION_4, HOSTMOTE_PROTOCOL_VERSION_3, HEAD, ESS_RELEASE_3_5, ESS_RELEASE_3_4, ESS_RELEASE_3_3, ESS_RELEASE_3_2, ESS_RELEASE_3_1, ESS_RELEASE_3_0, ESS_RELEASE_2_0, ESS_CONNECTIVITY, ESS_CENTROUTE_TESTING, ESS2-CMS-V1_5_pretest, ESS2-CMS-V1_4cMergeSympathy_2, ESS2-CMS-V1_4c, ESS2-CMS-V1_4b, ESS2-CMS-V1_4a, ESS2-CMS-V1_3, ESS2-CMS-V1_2, ESS2-CMS-V1_1, ESS2-CMS-V1_0, EMSTAR_RELEASE_2_5, EMSTAR_RELEASE_2_1_BRANCH, EMSTAR_RELEASE_2_1, EMSTAR_RELEASE_2_0_beta1, EMSTAR_RELEASE_2_0, EMSTAR_RELEASE_1_3_2, EMSTAR_RELEASE_1_3_1, EMSTAR_RELEASE_1_3, EMSTAR_RELEASE_1_2, EMSTAR_RELEASE_1_1, EMSTAR_RELEASE_1_0, EMSTAR_PRE_HTML, CYCLOPS_RELEASE_CANDIDATE_2_0, CYCLOPS_PRERELEASE_STABLE, CENTROUTE_EMSTAR_SOCKETS, BG_1_0, BANGLADESH_ARSENIC_1_2, BANGLADESH_ARSENIC_1_1, AMARSS_JR_DEPLOYMENT_6_05_07
Changes since 1.13: +24 -29 lines
added the copyright notice to all the source code in the cens repository

/*
 *
 * Copyright (c) 2003 The Regents of the University of California.  All 
 * rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Neither the name of the University nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
 

/*

  torturetest.c

  tests device creation and open, to test for memory leaks and locking
  problems

 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <signal.h>

#include "fusd.h"

/* open call fails every 100th time. */
int _open(struct fusd_file_info *file)
{
  static int counter = 0;
  if (counter++ % 100) return 0;
  return -81;
}


int _close(struct fusd_file_info *file)
{
  return 0;
}


#define HANDLEERROR(fd) \
if (((fd) < 0) && (errno != 81)) \
{fprintf(stderr, "%s: open error: %s\n", name, strerror(errno));exit(1);}

#define CLOSE(fd) \
if ((fd) >= 0) \
if (close(fd)<0) \
{fprintf(stderr, "%s: close error: %s\n", name, strerror(errno));exit(1);}

int main(int argc, char *argv[])
{
  int i, j;
  int num;
  int retval;
  char **devs;
  pid_t *pids;

  // init function table
  fusd_file_operations_t
    fops = {_open, 
	    _close,
	    NULL,
	    NULL,
	    NULL,
	    NULL,
	    NULL};

  if (argc != 2) {
    fprintf(stderr, "usage: %s <number-devices-to-create>\n", argv[0]);
    exit(0);
  }

  num = atoi(argv[1]);

  devs = (char**)malloc(sizeof(char *)*num);
  pids = (pid_t *)malloc(sizeof(pid_t)*num);


  // create device names
  for (i=0; i<num; i++) {
    char dev[30];
    sprintf(dev,"/dev/fusd-test/test%d",i);
    devs[i] = strdup(dev);
  }

  /* create devices; 2 devices handled per process */
  for (i=0; i<num; i+=2) {
    int fork2 = fork();

    if (fork2 == 0) {

      if (fusd_register(devs[i], 0666, 0, &fops) < 0) {
	perror("Register failed");
	exit(1);
      } else {
	printf("pid %d: serving %s\n", getpid(), devs[i]);
      }

      i++;

      if (i < num) {
	if (fusd_register(devs[i], 0666, 0, &fops) < 0) {
	  perror("Register failed");
	  exit(1);
	} else {
	  printf("pid %d: serving %s\n", getpid(), devs[i]);
	}
      }
      
      /* run the devices */
      fusd_run();
    }
    
  }


  /* clients */
  for (i=0; i<num; i++) {
    int fork2 = fork();

    if (fork2 > 0) {
      pids[i] = fork2;
    } else if (fork2 == 0) {
      int fd, *fds;
      struct timeval tv;
      char name[50];


      if ((fds = (int*)malloc(sizeof(int)*num)) == NULL) {
	fprintf(stderr, "malloc failure");
	exit(1);
      }

      //      sleep((1+num/10) * (2+i/5));
      sleep(10);
      printf("pid %d: client starting...\n", getpid());
      sprintf(name, "client (pid %d)", getpid());
      
      // randomize
      gettimeofday(&tv, NULL);
      srandom(tv.tv_usec);
      for (i=0; i<num*5; i++) {
	int j = random() % num;
	char *tmp = devs[j];
	devs[j] = devs[0];
	devs[0] = tmp;
      }
      
      
      for (j=0; j<num; j++) {
	printf("loop (%d) %d\n", getpid(), j);
	
	/* open and close each device */
	for (i=0; i<num; i++) {
	  //printf("opening %s\n", sdevs[i]);
	  fd = open(devs[i], O_RDWR);
	  HANDLEERROR(fd);
	  CLOSE(fd);
	  if (random() % 2) usleep(20000);
	}      
	
	/* open random device num x */
	for (i=0; i<num; i++) {
	  fds[i] = open(devs[0], O_RDWR);
	  HANDLEERROR(fds[i]);
	  if (random() % 2) usleep(20000);
	}      
	
	/* CLOSE that device, open a new one */
	for (i=0; i<num; i++) {
	  CLOSE(fds[i]);
	  fds[i] = open(devs[i], O_RDWR);
	  HANDLEERROR(fds[i]);
	  if (random() % 2) usleep(20000);
	}      
	
	/* open and close each device */
	for (i=num-1; i>=0; i--) {
	  fd = open(devs[i], O_RDWR);
	  HANDLEERROR(fd);
	  CLOSE(fd);
	  CLOSE(fds[i]);
	  if (random() % 2) usleep(20000);
	}      
	
      }
      
      // leave some stuff open..
      /* open random device num x */
      for (i=0; i<num; i++) {
	fd = open(devs[i], O_RDWR);
	HANDLEERROR(fd);
	fd = open(devs[0], O_RDWR);
	HANDLEERROR(fd);
      }      
      
      printf("done (%d) well, we finished..\n", getpid());
      exit(0);
    }
    
  }

  /* now wait for all the clients to finish */
  retval = 1;

  for (;;) {
    int pid, status;
    int i, j;

    for (i = 0; i < num; i++) {
      pid = wait(&status);

      for (j = 0; j < num; j++) {
	if (pids[j] == pid) {
	  pids[j] = -1;
	  fprintf(stderr, "master: pid %d finished\n", pid);
	  break;
	}
      }

      if (j >= num) {
	fprintf(stderr, "master: nonclient pid %d exited\n", pid);
	goto done;
      }

      if (WEXITSTATUS(status)) {
	fprintf(stderr, "master: uh oh, client %d reported retval %d\n",
		pid, WEXITSTATUS(status));
	goto done;
      }

    }

    fprintf(stderr, "master: all clients exited successfully\n");
    retval = 0;
    goto done;
  }

 done:
  signal(SIGINT, SIG_IGN);
  kill(0, SIGINT);
  exit(retval);
}



CENS CVS Mailing List
Powered by
ViewCVS 0.9.2