summaryrefslogtreecommitdiff
path: root/src/main.c
blob: 2e0f391de59a349b4dca9b4237c5166e0e170273 (plain)
    1 // 
    2 // Copyright (C) 2015 Aaron Ball <nullspoon@iohq.net>
    3 // 
    4 // Cnetbench is free software: you can redistribute it and/or modify
    5 // it under the terms of the GNU General Public License as published by
    6 // the Free Software Foundation, either version 3 of the License, or
    7 // (at your option) any later version.
    8 // 
    9 // Cnetbench is distributed in the hope that it will be useful,
   10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
   11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12 // GNU General Public License for more details.
   13 // 
   14 // You should have received a copy of the GNU General Public License
   15 // along with cnetbench.  If not, see <http://www.gnu.org/licenses/>.
   16 // 
   17 #include <stdlib.h>
   18 #include <stdio.h>
   19 #include <string.h>
   20 
   21 #include "common.h"
   22 #include "test.h"
   23 
   24 
   25 void get_help() {
   26   printf(
   27   "\n"
   28   "Cnetbench is a simple protocol-agnostic network benchmarking program.\n"
   29   "Simply put, it is a fire-hydrant of data and sends as much data as is\n"
   30   "allowed, and reports what those numbers are. This can be single stream\n"
   31   "or multiple concurrent data streams.\n"
   32   "\n"
   33   "Usage:\n\n"
   34   "  cnetbench -d <destination> -p <port> [-m <megabytes>] [-c <stream_count>]"
   35   "\n\n");
   36 }
   37 
   38 
   39 //
   40 // Prints test results in a friendly, human-readable format.
   41 //
   42 // @param t_test*     Test type containing test parameters
   43 // @param start_times Array of child start times, ordered by child process index
   44 // @param exit_times  Array of child exit times, ordered by child process index
   45 //
   46 void print_results(t_test *t,
   47                    struct timeval *start_times,
   48                    struct timeval *exit_times) {
   49   // Clear a little space
   50   printf("\n\n");
   51 
   52   long total_amount = t->amount * t->streams;
   53   double total_time = 0;
   54 
   55   for(int i = 0; i < t->streams; i++) {
   56     // calculate average transfer rate for this thread
   57 
   58     // Second difference, multiplied by 1000 to make room for microseconds
   59     double time_s = 1000 * (exit_times[i].tv_sec - start_times[i].tv_sec);
   60     // Microsecond difference
   61     double time_ms = exit_times[i].tv_usec - start_times[i].tv_usec;
   62     // Sum of microsecond and second differences
   63     double time = (time_s + time_ms) / 1000;
   64 
   65     // Append duration to the total duration of transfers.
   66     total_time += time;
   67 
   68     double avg = t->amount / time;
   69 
   70     printf("Fork %d/%d transferred %d MB in %.4f seconds, averaging %.2f MB/s\n",
   71       i + 1,
   72       t->streams,
   73       t->amount,
   74       time,
   75       avg
   76     );
   77   }
   78 
   79   printf("\n%d forks transferred a total of %ld MBs in %.2f parallel seconds\n",
   80     t->streams,
   81     total_amount,
   82     total_time
   83   );
   84 }
   85 
   86 
   87 //
   88 // Parses the program arguments and populates a t_test type with the values
   89 // specified by the user.
   90 // 
   91 // @param argc Number of arguments passed to the program (the main argc)
   92 // @param argv Arguments passed to the program (the main argv)
   93 // @param test T_test object to be populated
   94 //
   95 int parse_args(int argc, char *argv[], t_test *test) {
   96   int i = 1;
   97 
   98   char server = 0;
   99   char port = 0;
  100 
  101   while(i < argc) {
  102     if(strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--megabytes") == 0) {
  103       ++i;
  104       test->amount = atoi(argv[i]);
  105     } else if(strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--count") == 0) {
  106       ++i;
  107       test->streams = atoi(argv[i]);
  108     } else if(strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--dest") == 0) {
  109       ++i;
  110       strcpy(test->server, argv[i]);
  111       server = 1;
  112     } else if(strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--port") == 0) {
  113       ++i;
  114       test->port = atoi(argv[i]);
  115       port = 1;
  116     } else {
  117       get_help();
  118       return 1;
  119     }
  120     ++i;
  121   }
  122 
  123   if(server == 0) {
  124     printf("Please specify a destination server (-d,--dest) to test with.\n");
  125     return 1;
  126   }
  127   if(port == 0) {
  128     printf("Please specify a port (-p,--port) to run tests over.\n");
  129     return 1;
  130   }
  131 
  132   return 0;
  133 }
  134 
  135 
  136 //
  137 // Ye olde main
  138 //
  139 int main(int argc, char *argv[]) {
  140   t_test test;
  141 
  142   // Initialize the test object with defaults
  143   new_test(&test);
  144   // Parse program arguments
  145   int arg_status = parse_args(argc, argv, &test);
  146 
  147   if(arg_status > 0)
  148     return 1;
  149 
  150   struct timeval start_times[test.streams];
  151   struct timeval exit_times[test.streams];
  152 
  153   test_start_all(&test, start_times, exit_times);
  154   print_results(&test, start_times, exit_times);
  155 
  156   return 0;
  157 }

Generated by cgit