user3050866
user3050866

Reputation: 33

shell script running test cases for my code

My program accepts many options.
And I have to write a shell script to test my program.

The shell script must run my program multiple times and every time it must pass different options and different arguments for an option.

For example:

    #!/bin/bash
echo "CS111 " > testing.txt
echo "is " >> testing.txt
echo "intersting " >> testing.txt
echo "even " >> testing.txt
echo "though " >> testing.txt
echo "it " >> testing.txt
echo "is " >> testing.txt
echo "time " >> testing.txt
echo "consuming " >> testting.txt
echo "and " >> testing.txt
echo "hard " >> testing.txt

./simpsh \
--verbose \
--rdonly in.txt \
--append --wronly out.txt \
--wronly err.txt \
--command 0 1 2 sort testing

./simpsh \
--verbose\ 
--rdonly in.txt \
--append --wronly out.txt \
--wronly err.txt \
--command 0 1 2 sort

The first test will be executed, but then there is an error 127.

This is my code:

#include <stdio.h>     
#include <stdlib.h>    
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

int main(int argc, char **argv)
{
  int c;
  int oflag = 0;
  int *fd;
  int fdCount = 0;
  int pipefd[2];
  int p;
  int verbose = 0;
  while (1) {
    static struct option long_options[] = {
      {"append",no_argument,0,'a'},
      {"cloexec",no_argument,0,'b'},
      {"creat",  no_argument,0,'c'},
      {"directory",no_argument,0,'d'},
      {"dsync",no_argument,0,'e'},
      {"excl",no_argument,0,'f'},
      {"nofollow",no_argument,0,'g'},
      {"nonblock",no_argument, 0,'h'},
      {"rsync",no_argument,0,'i'},
      {"sync",no_argument,0,'j'},
      {"trunc",no_argument,0,'k'},
      {"rdonly",required_argument,0,'l'},
      {"rdwr",required_argument,0,'m'},
      {"wronly",required_argument,0,'n'},
      {"pipe",no_argument,0,'o'},
      {"command",required_argument,0,'p'},
      {"wait",no_argument,0,'q'},
      {"close",required_argument,0,'r'},
      {"verbose",no_argument,0,'s'},
      {"profile",no_argument,0,'t'},
      {"abort",no_argument,0,'u'},
      {"catch",required_argument,0,'v'},
      {"ignore",required_argument,0,'w'},
      {"default",required_argument,0,'x'},
      {"pause",no_argument,0,'y'},
      };
    c = getopt_long(argc, argv, "abcdefghijkl:m:n:op:qr:stuv:w:x:y", long_options, NULL);
    if (c == -1)
      break;
    switch (c) {
    case 'a':
      if(verbose)
    printf("O_APPEND\n");
      oflag = oflag | O_APPEND;
      break;
    case 'b':
      if(verbose)
    printf("O_CLOEXEC\n");
      oflag = oflag | O_CLOEXEC;
      break;
    case 'c':
      if(verbose)
    printf("O_CREAT\n");
      oflag = oflag | O_CREAT;
      break;
    case 'd':
      if(verbose)
    printf("O_DIRECTORY\n");
      oflag = oflag | O_DIRECTORY;
      break;
    case 'e':
      if(verbose)
    printf("O_DSYNC\n");
      oflag = oflag | O_DSYNC;
      break;
    case 'f':
      if(verbose)
    printf("O_EXCL\n");
      oflag = oflag | O_EXCL;
      break;
    case 'g':
      if(verbose)
    printf("O_NOFOLLOW\n");
      oflag = oflag | O_NOFOLLOW;
      break;
    case 'h':
      if(verbose)
    printf("O_NONBLOCK\n");
      oflag = oflag | O_NONBLOCK;
      break;
    case 'i':
      if(verbose)
    printf("O_RSYNC\n");
      oflag = oflag | O_RSYNC;
      break;
    case 'j':
      if(verbose)
    printf("O_SYNC\n");
      oflag = oflag | O_SYNC;
      break;
    case 'k':
      if(verbose)
    printf("O_TRUNC\n");
      oflag = oflag | O_TRUNC;
      break;
    case 'l':
      if(optarg){
    if(fdCount == 0)
      fd = (int *)malloc(sizeof(int));
    else
      fd = (int *)realloc(fd, (fdCount  + 1)* sizeof(int));
    if(verbose)
      printf("O_RDONLY %s\n", optarg);
    fd[fdCount] = open(optarg, oflag | O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
    oflag = 0;
    if(fd[fdCount] == -1){
      fprintf(stderr, "%s cannot be opened/created", optarg);
      exit(1);
    }
    else
      fdCount++;
      }
      break;
    case 'm':
       if(optarg){
    if(fdCount == 0)
      fd = (int *)malloc(sizeof(int));
    else
      fd = (int *)realloc(fd, (fdCount + 1)* sizeof(int));
    if(verbose)
      printf("O_RDWR %s\n", optarg);
    fd[fdCount] = open(optarg, oflag | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
    oflag = 0;
    if(fd[fdCount] == -1){
      fprintf(stderr, "%s cannot be opened/created", optarg);
      exit(2);
    }
    else
      fdCount++;
       }
      break;
    case 'n':
      if(optarg){
    if(fdCount == 0)
      fd = (int *)malloc(sizeof(int));
    else
      fd = (int *)realloc(fd, (fdCount + 1)* sizeof(int));
    if(verbose)
      printf("O_WRONLY %s\n", optarg);
    fd[fdCount] = open(optarg, oflag | O_WRONLY, S_IRWXU | S_IRWXG | S_IRWXO);
    oflag = 0;
    if(fd[fdCount] == -1){
      fprintf(stderr, "%s cannot be opened/created", optarg);
      exit(3);
    }
    else
      fdCount++;
       }
      break;
    case 'o':
      if(verbose)
    printf("pipe\n");
      p = pipe(pipefd);
      if(p == -1){
    fprintf(stderr, "The pipe wasn't made.\n");
    exit(5);
      }
      else{
    if(fdCount == 0)
      fd = (int *)malloc(2 * sizeof(int));
    else
      fd = (int *)realloc(fd, (fdCount + 2) * sizeof(int));
    fdCount = fdCount + 2;
    fd[fdCount - 2] = pipefd[0];
    fd[fdCount - 1] = pipefd[1];
      }
      break;
    case 'p':
      if(optarg){
    if(verbose){
      printf("command ");
      int vi = optind -1;
      for( vi = optind - 1; vi < argc && *argv[vi] != '-'; vi++)
        printf("%s ", argv[vi]);
      printf("\n");
    }
    pid_t pid = fork();
    if(pid == 0){
      int fdin;
      int fdout;
      int fderr;
      int i = 0;
      char **arg;
      int index;
      for(index = optind-1; index < argc && *argv[index] != '-'; index++, i++){
        switch(i){
        case 0:
          fdin = atoi(argv[index]);
          break;
        case 1:
          fdout = atoi(argv[index]);
          break;
        case 2:
          fderr = atoi(argv[index]);
          break;
        default:
          if(i - 3 == 0)
        arg = (char**)malloc(sizeof(char));
          else
        arg = (char**)realloc(arg, ((i - 3) + 1)* sizeof(char));
          arg[i - 3] = strdup(argv[index]);
        }
      }
      dup2(fd[fdin],0);
      close(fd[fdin]);
      dup2(fd[fdout],1);
      close(fd[fdout]);
      dup2(fd[fderr],2);
      close(fd[fderr]);
      execvp(arg[0], arg);
    }
    else if(pid == -1){
      fprintf(stderr, "The new proccess isn't created by fork()\n");
      exit(6);
    }
      }
      break;
    case 'q':
      break;
    case 'r':
      break;
    case 's':
      verbose = 1;
      break;
    case 't':
      break;
    case 'u':
      break;
    case 'v':
      break;
    case 'w':
      break;
    case 'x':
      break;
    case 'y':
      break;
    default:
      fprintf(stderr, "An option is misstyped or has no argument\n");
      exit(4);
    }
  }
  exit(0);
}

Upvotes: 0

Views: 500

Answers (1)

Fred
Fred

Reputation: 6995

Return code 127 indicates the command was not found.

It is likely myprogram is not found inside the current directory you execute your test script from.

Try changing to the directory where your program is located, or calling it with a full path.

Also, remember bash ignores commands that fail unless you activate the "-e" flag or trap errors and handle them explicitly. When building a test script (or any script for that matter), allowing silent failure could lead to bad surprises down the road.

Upvotes: 1

Related Questions