~bernanet84/bordergateway/test

« back to all changes in this revision

Viewing changes to doReport.pl

  • Committer: Luca Bernardini
  • Date: 2010-04-19 16:30:44 UTC
  • Revision ID: luca@luca-laptop-20100419163044-5cqg06blfopt3sch
Initial Import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl -w
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
#
 
17
# Authors : David Verbeiren from Intel Corporation - July 2007
 
18
#           Xavier Simonart from Intel Corporation - July 2007
 
19
#           Philippe Lecluse from Intel Corporation - July 2007
 
20
#           Patrice Buriez from Intel Corporation - June 2008
 
21
#
 
22
use Config;
 
23
use XML::Simple;
 
24
use IO::File;
 
25
use File::Copy;
 
26
use strict;
 
27
use Data::Dumper;
 
28
 
 
29
my $OutputFile = 'report.html';
 
30
my $InputFile = "report.xml";
 
31
my $ConfigFile = "reportConfig.xml";
 
32
my $IntroFile;
 
33
 
 
34
use constant { FAILED => 0, DOC_REACHED => 1, DOC_NOT_REACHED => 2 };
 
35
my @Month = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
 
36
 
 
37
my $OsWin = 0;
 
38
# Defaults (Linux assumed)
 
39
my $gnuplot = "gnuplot";
 
40
my $gnuplot_size = "size";
 
41
my $gnuplot_size_sep = ",";
 
42
 
 
43
my $CmdPath = $0;
 
44
my $PathSep = "/";
 
45
if ($Config{'osname'} eq "MSWin32") {
 
46
  $OsWin = 1;
 
47
  $gnuplot = "wgnuplot";
 
48
  $PathSep = "\\";
 
49
}
 
50
$CmdPath =~ s/(.)${PathSep}[^{$PathSep}]*$/$1/;
 
51
 
 
52
my @TempFiles = ();
 
53
my %MetricTable;
 
54
my $doc_ref;
 
55
 
 
56
my (@TotSAPS, @TotFailures);
 
57
my (%ColumnSAPS, %ColumnRetrans);
 
58
 
 
59
my $Report;
 
60
my $Result;
 
61
my $report_test_info = "";
 
62
my $report_expl = "";
 
63
 
 
64
my $t_read = 0, my $t_stat = 0, my $t_pict = 0, my $t_buildretrans = 0, my $t_buildsipp = 0;
 
65
my $t_buildcpumem = 0, my $t_buildsippcpu = 0, my $t_othergraphs = 0;
 
66
my $t_buildfilefromsource = 0;
 
67
my $lasterr = "";
 
68
my $do_fork = 1;
 
69
my $no_cleanup = 0;  # This is useful for troubleshooting (viewing gnuplot script files, plot data files...)
 
70
my @forked_pids = ();
 
71
 
 
72
$Report->{css} = "<style type=\"text/css\">\n" .
 
73
    " h1 { text-align:center; }\n" .
 
74
    " h2 { text-align:left; }\n" .
 
75
    " body { font: 10pt verdana, arial, helvetica; }\n" .
 
76
    " table { font: 9pt verdana, arial, helvetica; }\n" .
 
77
    " a.toc:link    { font: 7pt bold; color:#00F; text-decoration:none }\n" .
 
78
    " a.toc:active  { font: 7pt bold; color:#00F; text-decoration:none }\n" .
 
79
    " a.toc:visited { font: 7pt bold; color:#00F; text-decoration:none }\n" .
 
80
    " a.toc:hover   { font: 7pt bold; color:#F00; text-decoration:none }\n" .
 
81
    " div.centered { text-align:center; }\n" .
 
82
    " .step_info  { color:Purple; }\n" .
 
83
    " .step_box { background-color:#d3d3d3; }\n" .
 
84
    " .step_doc { background-color:Green; }\n" .
 
85
    " .step_ihs { background-color:Red; }\n" .
 
86
    " .table_title { background-color:#add8e6; }\n" .
 
87
    " a.b_index img {border: 0px}\n" .
 
88
    "</style>\n";
 
89
  
 
90
 
 
91
# Returns the number of CPUs on the local system
 
92
sub get_number_cpu
 
93
{
 
94
  if ($OsWin == 1) {
 
95
    return 1;
 
96
  } else {
 
97
    my $n = 0;
 
98
    open(DATA, "cat /proc/cpuinfo |") || die ("Can't open /proc/cpuinfo");
 
99
    while(<DATA>) {
 
100
      chomp;
 
101
      if (/processor\s*:\s*(\d*)/) {
 
102
        $n++;
 
103
      }
 
104
    }
 
105
    return $n;
 
106
  }
 
107
}
 
108
 
 
109
sub GetMilli
 
110
{
 
111
  use Time::HiRes qw(gettimeofday);
 
112
  my ($seconds, $milliseconds) = gettimeofday;
 
113
  return ($seconds * 1000) + $milliseconds/1000;
 
114
}
 
115
 
 
116
sub read_file
 
117
{
 
118
  my ($file) = @_;
 
119
  my @refer = ();
 
120
  my ($t1, $t2);
 
121
 
 
122
  $t1 = GetMilli();  
 
123
 
 
124
  if (!(-e $file)) {
 
125
    $lasterr = "File $file does not exist!";
 
126
    return;
 
127
  }
 
128
 
 
129
  open(DATA, "<$file");
 
130
  while(<DATA>) {
 
131
    chomp;
 
132
    if (/^\d/) {
 
133
      push(@refer, [split /[;]/]); # Used [] to create an array and return reference.
 
134
    }
 
135
  }
 
136
  close DATA;
 
137
  $t2 = GetMilli() - $t1;
 
138
  $t_read+=$t2;
 
139
  return \@refer;  
 
140
}
 
141
 
 
142
######################################################################################################################
 
143
# Returns Mean, Min, Max and Variance. Also calculates Mean per time unit and Histogram.
 
144
# INPUT 1: column number
 
145
# INPUT 2: Time unit. 1000000 == 1 second. Used to calculate mean per time unit.
 
146
# INPUT 3: Y unit. Used for mean, min, max, and variance.
 
147
# INPUT 4: step_ref: Reference to array of array. Lines are the different steps. Column hold rate, start, stop time.
 
148
# INPUT 5: Reference to array of data. First column is time, $n column holds the data.
 
149
# INPUT 6: Reference to Distribution variable. Not set if distribution does not need to be calculated.
 
150
#                                              Set to the granularity of the histogram.
 
151
# OUTPUT: References to Array for Min, then max, mean, variance. Those 4 arrays contain 1 lines per step.
 
152
#       : Reference to array containing the mean per time unit. One line per time unit (!!! not per step).
 
153
#       : Reference to array of array containing histogram. One line per value. One column per step.
 
154
######################################################################################################################
 
155
sub getstat
 
156
{
 
157
  my ($file, $n, $x_unit, $y_unit, $steps_ref, $do_mean, $do_dist, $skip, $do_percentile) = @_;
 
158
  my ($i, $t1);
 
159
 
 
160
  $t1 = GetMilli();
 
161
 
 
162
  my @stats = ();
 
163
  my @meanPerUnit = ();
 
164
  my @numPerUnit = ();
 
165
  my @histogram = ();
 
166
  my @histogram_large_values = ();
 
167
  my $n_elem_total = 0;   # Total number of measures used (all steps included)
 
168
 
 
169
  my $j = 0;
 
170
  my ($t, $k);
 
171
  my @data = ();
 
172
 
 
173
  my $n_steps = @{$steps_ref};
 
174
  
 
175
  if (($do_dist == 0) && ($do_percentile)) {
 
176
    $do_dist = 1;
 
177
  }
 
178
 
 
179
  # Initialize Histogram tables for large values, as will not be initialized if only small values are being used.
 
180
  for ($j=0;$j<@{$steps_ref};$j++) {
 
181
    $histogram_large_values[0][$j] = 0;
 
182
  }
 
183
  $j = 0;
 
184
  open(DATA, "<$file");
 
185
 
 
186
  while ($j < $n_steps) {
 
187
    my ($min, $max, $m, $v, $n_elem_in_step);
 
188
 
 
189
    # Skip time before start time
 
190
    while(<DATA>) {
 
191
      chomp;
 
192
      @data = split /[;]/;
 
193
      if (defined $data[$n]) {
 
194
        if ($do_mean) {
 
195
          $meanPerUnit[int(($data[0])/$x_unit)] += $data[$n];
 
196
          $numPerUnit[int(($data[0])/$x_unit)]++;
 
197
        }
 
198
        if ($data[0] >= $steps_ref->[$j]->{start_time}) {
 
199
          last;
 
200
        }
 
201
        #printf("Skipping data at $data[0] before start time($j) = $steps_ref->[$j]->{start_time})\n");              
 
202
      }
 
203
    }
 
204
    if (!defined $data[$n]) {
 
205
      # No data read for this step. No data read at all if $j == 0.
 
206
      last;
 
207
    }
 
208
    
 
209
    # Skip last second of the step (as many computations we do require full seconds)
 
210
    my $stop_for_step;
 
211
    if ($steps_ref->[$j]->{stop_time} - 1000 * $skip > $steps_ref->[$j]->{stop_time}) {
 
212
      $stop_for_step = $steps_ref->[$j]->{stop_time};
 
213
    } else {
 
214
      $stop_for_step = $steps_ref->[$j]->{stop_time} - 1000 * $skip;
 
215
    }
 
216
 
 
217
    if ($data[0] > $stop_for_step) {  # No other data left!
 
218
      $j++;
 
219
      next;
 
220
    }
 
221
 
 
222
    $min = $data[$n];
 
223
    $max = $data[$n];
 
224
    $m = $data[$n];
 
225
    $v = $data[$n]*$data[$n];
 
226
    $n_elem_in_step = 1;
 
227
 
 
228
    while(<DATA>) {
 
229
      chomp;
 
230
      @data = split /[;]/;
 
231
      if (!defined $data[$n]) {
 
232
        next;
 
233
      }
 
234
      if ($do_mean) {
 
235
        $meanPerUnit[int(($data[0])/$x_unit)] += $data[$n];
 
236
        $numPerUnit[int(($data[0])/$x_unit)]++;
 
237
      }
 
238
      if ($data[0] > $stop_for_step) {
 
239
        last;
 
240
      }
 
241
      # Mean, Variance, Mean and Max
 
242
      $m += $data[$n];
 
243
      $v += $data[$n]*$data[$n];
 
244
      if ($data[$n] < $min) {
 
245
        $min = $data[$n];
 
246
      }
 
247
      if ($data[$n] > $max) {
 
248
        $max = $data[$n];
 
249
      }
 
250
      $n_elem_in_step++;
 
251
      if ($do_dist) {
 
252
        # Histogram
 
253
        if (int($data[$n]/$do_dist) <= 10000) {
 
254
          $histogram[int($data[$n]/$do_dist)][$j]++;
 
255
        } else {
 
256
          $histogram_large_values[int($data[$n]/$do_dist/10)][$j]++;
 
257
        }
 
258
      }
 
259
    }
 
260
    #print("Step $j: Tot=$m for $n_elem_in_step elements\n");
 
261
    $min /= $y_unit;
 
262
    $max /= $y_unit;
 
263
    if ($n_elem_in_step) {
 
264
      $v = ($v - ($m*$m/($n_elem_in_step) ))/($n_elem_in_step)/$y_unit/$y_unit;
 
265
      $m = $m / ($n_elem_in_step)/$y_unit;
 
266
    } else {
 
267
      $v = 0;
 
268
      $m = 0;
 
269
    }
 
270
    
 
271
    #print ("Step $j: MIN=$min, MAX=$max, MEAN=$m, VAR=$v\n");
 
272
    $stats[$j]->{min} = $min;
 
273
    $stats[$j]->{max} = $max;
 
274
    $stats[$j]->{mean} = $m;
 
275
    $stats[$j]->{variance} = $v;
 
276
    $stats[$j]->{n_elem} = $n_elem_in_step;
 
277
    $n_elem_total += $n_elem_in_step;
 
278
    
 
279
    $j++;
 
280
  }
 
281
  close DATA;
 
282
 
 
283
  # Normalize histograms. Otherwise, histograms at low load will be hidden by histograms for high loads.
 
284
  if ($do_dist) {
 
285
    for ($j=0; $j<$n_steps; $j++) {
 
286
      for $k (0..@histogram-1) {
 
287
        if ($histogram[$k][$j]) {
 
288
          $histogram[$k][$j] = $histogram[$k][$j] / $stats[$j]->{n_elem};
 
289
        }
 
290
        else {
 
291
          $histogram[$k][$j] = 0;
 
292
        }
 
293
      }
 
294
      for $k (0..@histogram_large_values-1) {
 
295
        if ($histogram_large_values[$k][$j]) {
 
296
          $histogram_large_values[$k][$j] = $histogram_large_values[$k][$j] / $stats[$j]->{n_elem};
 
297
        }
 
298
        else {
 
299
          $histogram_large_values[$k][$j] = 0;
 
300
        }
 
301
      }
 
302
    }
 
303
  }
 
304
 
 
305
  # Now calculate the Mean per Time Unit, usually seconds.  
 
306
  if ($do_mean) {
 
307
    # Mean per time unit
 
308
    for $i (0..@numPerUnit-1) {
 
309
      if ($numPerUnit[$i]) {
 
310
        $meanPerUnit[$i] /= $numPerUnit[$i];
 
311
      }
 
312
    }
 
313
  }
 
314
 
 
315
  $t_stat += (GetMilli() - $t1);
 
316
  return(\@stats, $n_elem_total, \@meanPerUnit, \@histogram, \@histogram_large_values);
 
317
}
 
318
 
 
319
################################################################################
 
320
# Print to a file content of array of array pointed by a reference. 
 
321
# First column printed is index. Others columns are the array content.
 
322
# INPUT 1: file name
 
323
# INPUT 2: Reference to array of array.
 
324
# INPUT 3: Numbers of columns in file.
 
325
# INPUT 4: Unit for the Index
 
326
# INPUT 5: ScaleHistogram. If set, then all data starting from a certain point are set to 0.
 
327
#          This point is determined when all thedata after this point has a value which
 
328
#          is less than 1% of the maximum (all columns together) .
 
329
#          This  is useful for histograms, to prevent trying to plot extremely small value
 
330
#          (so small that we anyhow do not see them), which, at the end,
 
331
#          prevent to see the interesting part of the histogram. 
 
332
# OUTPUT: none.
 
333
################################################################################
 
334
sub print_ref
 
335
{
 
336
  my ($file, $refer, $n_col, $unit, $steps_ref) = @_;
 
337
  my ($i, $j, $k, $stop, $in_prereg);
 
338
  my $n_steps = @{$steps_ref};
 
339
 
 
340
  #print "print_ref(>$file)\n";
 
341
  open(OUT, ">$file");
 
342
  $i = 0;
 
343
  for ($j=0; $j<$n_steps; $j++) {
 
344
    $in_prereg = $steps_ref->[$j]->{prereg};
 
345
    if (@{$refer} < $steps_ref->[$j]->{stop_time}/1000) {
 
346
      $stop = @{$refer};
 
347
    } else {
 
348
      $stop = $steps_ref->[$j]->{stop_time}/1000;
 
349
    }
 
350
    while ($i < $stop) {
 
351
      $i++;  
 
352
      print(OUT ($i*$unit).";");
 
353
      for ($k=0;$k<$n_col;$k++) {
 
354
        if ($refer->[$i]->[$k]) {
 
355
          print(OUT "$refer->[$i]->[$k];");
 
356
        } else {
 
357
          print(OUT "0;");
 
358
        }
 
359
      }
 
360
      print (OUT "\n");
 
361
    }
 
362
    if ( (($j+1) < $n_steps) &&
 
363
         (($steps_ref->[$j+1]->{report} == 1) || ($steps_ref->[$j+1]->{prereg} != $in_prereg)) ) {
 
364
      print (OUT "\n");
 
365
    }
 
366
  }
 
367
  if (close(OUT) <= 0) {
 
368
    print("Error closing file: $!\n");
 
369
    exit(0);
 
370
  }
 
371
  push(@TempFiles, $file);
 
372
}
 
373
 
 
374
sub print_histograms
 
375
{
 
376
  my ($file, $refer, $steps_ref, $unit, $ScaleHistogram) = @_;
 
377
  my ($i, $j, $k, $max_i, $max_h);
 
378
  my ($lastok, $firstok) = (@{$refer}, 0);
 
379
  my @h_reduced = ();
 
380
  $j = 0, $max_i = 0, $max_h = 0;
 
381
  
 
382
  if ($ScaleHistogram) {
 
383
    while ($j < @{$steps_ref}) {
 
384
      if ($steps_ref->[$j]->{show_histograms} != 0) {
 
385
        for $k (0..@{$refer}-1) {
 
386
          if ($refer->[$k][$j] >= $max_h) {
 
387
            $max_h = $refer->[$k][$j];
 
388
            $max_i = $k;
 
389
          }
 
390
        }
 
391
      }
 
392
      $j++;
 
393
    }
 
394
    $j = 0;
 
395
    $firstok = $max_i;
 
396
    while ($j < @{$steps_ref}) {
 
397
      if ($steps_ref->[$j]->{show_histograms} != 0) {
 
398
        for ($k=$max_i-1;$k>=0;$k--) {
 
399
          if ($refer->[$k][$j] > $max_h/200) {
 
400
            if ($k <= $firstok ) {
 
401
              $firstok = $k;
 
402
            }
 
403
          }
 
404
        }
 
405
      }
 
406
      $j++;
 
407
    }
 
408
    $j = 0;
 
409
    $lastok = $max_i;
 
410
    while ($j < @{$steps_ref}) {
 
411
      if ($steps_ref->[$j]->{show_histograms} != 0) {
 
412
        for $k ($max_i..@{$refer}-1) {
 
413
          if ($refer->[$k][$j] > $max_h/200) {
 
414
            if ($k > $lastok ) {
 
415
              $lastok = $k;
 
416
            }
 
417
          }
 
418
        }
 
419
      }
 
420
      $j++;
 
421
    }
 
422
  }
 
423
  open(OUT, ">$file");
 
424
  
 
425
  $firstok = $firstok-1 if ($firstok > 0);
 
426
  $lastok = $lastok+1 if ($lastok < @{$refer});
 
427
    
 
428
  for ($i=$firstok;$i<$lastok;$i++) {
 
429
    print(OUT ($i*$unit).";");
 
430
    for ($j=0;$j< @{$steps_ref};$j++) {      
 
431
      if ($steps_ref->[$j]->{show_histograms} != 0) {
 
432
        if ($refer->[$i]->[$j]) {
 
433
          print(OUT "$refer->[$i]->[$j];");
 
434
        } else {
 
435
          print(OUT "0;");
 
436
        }
 
437
      }
 
438
    }
 
439
    print (OUT "\n");
 
440
  }
 
441
  if (close(OUT) <= 0) {
 
442
    print("Error closing file: $!\n");
 
443
    exit(0);
 
444
  }
 
445
  push(@TempFiles, $file);
 
446
  return $lastok
 
447
}
 
448
 
 
449
################################################################################
 
450
# Print to a file content of array pointed by a reference. 
 
451
# First column printed is index. Others column is the array content.
 
452
# INPUT 1: file name
 
453
# INPUT 2: Reference to array of array.
 
454
# OUTPUT: none.
 
455
################################################################################
 
456
sub print_ref1
 
457
{
 
458
  my ($file, $d_refer, $unit, $steps_ref) = @_;
 
459
  my ($i, $j, $stop, $in_prereg);
 
460
  my $n_steps = @{$steps_ref};
 
461
 
 
462
  #print "print_ref1(>$file)\n";
 
463
  open(OUT, ">$file");
 
464
  $i = 0;
 
465
  for ($j=0; $j<$n_steps; $j++) {
 
466
    $in_prereg = $steps_ref->[$j]->{prereg};
 
467
    if (@{$d_refer} < $steps_ref->[$j]->{stop_time}/1000) {
 
468
      $stop = @{$d_refer};
 
469
    } else {
 
470
      $stop = $steps_ref->[$j]->{stop_time}/1000;
 
471
    }
 
472
    while ($i < $stop) {
 
473
      $i++;
 
474
      if (defined $d_refer->[$i]) {
 
475
        print(OUT $i*$unit.";$d_refer->[$i]\n");
 
476
      }
 
477
    }
 
478
    if ( (($j+1) < $n_steps) &&
 
479
         (($steps_ref->[$j+1]->{report} == 1) || ($steps_ref->[$j+1]->{prereg} != $in_prereg)) ) {
 
480
      print (OUT "\n");
 
481
    }
 
482
  }
 
483
  if (close(OUT) <= 0) {
 
484
    print("Error closing file: $!\n");
 
485
    exit(0);
 
486
  }
 
487
  push(@TempFiles, $file);
 
488
}
 
489
 
 
490
############################################################################################
 
491
# Get basic statistics and build Histogram. Print mean per time unit and histogram in a file
 
492
# INPUT 1: Index of sub-source (within 
 
493
# INPUT 1: File Name
 
494
# INPUT 2: column number
 
495
# INPUT 3: Time unit. 1000000 == 1 second. Used to calculate mean per time unit.
 
496
# INPUT 4: Y unit. Used for mean, variance, as well as histogram.
 
497
# INPUT 5: step_ref: Reference to arrayy of array. Lines are the different steps. Columl hold rate, start, stop time.
 
498
# OUTPUT : Reference to array of array containing raw data.
 
499
#        : References to Array for Min, then max, mean, variance. Those 4 arrays contain 1 lines per step.
 
500
############################################################################################
 
501
sub Analyze
 
502
{
 
503
  my ($file, $n, $x_unit, $y_unit, $steps_ref, $do_mean, $do_dist, $skip, $reportConfig, $do_percentile) = @_;
 
504
  my ($i, $j, $n_steps);
 
505
  my @perc = ();
 
506
 
 
507
  $n_steps = @{$steps_ref};
 
508
  # print ("*** Analyze $file column $n ***\n");
 
509
  
 
510
  if (!(-e "$file")) {
 
511
    $lasterr = "Failed to open $file";
 
512
    return 1;
 
513
  }
 
514
  if (!defined $y_unit) {
 
515
    printf("y_unit was not defined - now set to 1\n");
 
516
    $y_unit = 1;
 
517
  }
 
518
 
 
519
  # Number of percentile columns;
 
520
  my $n_percent = defined($reportConfig->{Percentile}->{Value}) ?
 
521
      @{$reportConfig->{Percentile}->{Value}} : 0;
 
522
 
 
523
  my ($stats_ref, $n_elem_total, $distri_mean_ref, $h_ref, $h2_ref)
 
524
    = getstat($file, $n-1, $x_unit, $y_unit, $steps_ref, $do_mean, $do_dist, $skip, $do_percentile);
 
525
 
 
526
  if ($n_elem_total == 0) {
 
527
    #print("No data in $file\n");
 
528
    return 1;
 
529
  }
 
530
 
 
531
  # Print Mean per time Unit
 
532
  if ($do_mean) {
 
533
    #print("printing Mean in file\n");
 
534
    print_ref1("$file-time.dat", $distri_mean_ref, $x_unit, $steps_ref);
 
535
  }
 
536
  if ($do_dist) {
 
537
    print_histograms("$file-hist.dat", $h_ref, $steps_ref, $do_dist, 1);   
 
538
  }
 
539
   
 
540
  if ($do_dist || $do_percentile) {
 
541
    # Get and print Probability  
 
542
    for ($i=@{$h2_ref}-2;$i>=0;$i--) {
 
543
      for ($j=0;$j<@{$steps_ref};$j++) {
 
544
        $h2_ref->[$i][$j] += $h2_ref->[$i+1][$j];
 
545
      }
 
546
    }
 
547
    for ($j=0;$j<@{$steps_ref};$j++) {
 
548
      $h_ref->[@{$h_ref}-1][$j] += $h2_ref->[0][$j];
 
549
    }
 
550
    for ($i=@{$h_ref}-2;$i>=0;$i--) {
 
551
      for ($j=0;$j<@{$steps_ref};$j++) {
 
552
        $h_ref->[$i][$j] += $h_ref->[$i+1][$j];
 
553
      }
 
554
    }
 
555
    for ($i=@{$h_ref}-1;$i>=0;$i--) {
 
556
      for ($j=0;$j<@{$steps_ref};$j++) {
 
557
        if ($h_ref->[0][$j]) {
 
558
          $h_ref->[$i][$j] = $h_ref->[$i][$j]/$h_ref->[0][$j];
 
559
        } else {
 
560
          $h_ref->[$i][$j] = 0;
 
561
        }
 
562
      }
 
563
    }
 
564
    for ($i=@{$h2_ref}-1;$i>=0;$i--) {
 
565
      for ($j=0;$j<@{$steps_ref};$j++) {
 
566
        if ($h2_ref->[0][$j]) {
 
567
          $h2_ref->[$i][$j] = $h2_ref->[$i][$j]/$h_ref->[0][$j];
 
568
        } else {
 
569
          $h2_ref->[$i][$j] = 0;
 
570
        }
 
571
      }
 
572
    }
 
573
    if ($do_dist) {
 
574
      print_histograms("$file-dist.dat", $h_ref, $steps_ref, $do_dist, 1);
 
575
    }
 
576
    if ($do_percentile) {    
 
577
      if (!defined $do_dist || $do_dist == 0) {
 
578
        $do_dist = 1;
 
579
      }
 
580
      for (my $k=0;$k<$n_percent;$k++) {
 
581
        if ($reportConfig->{Percentile}->{Value}->[$k]) {
 
582
          my $p = (100 - $reportConfig->{Percentile}->{Value}->[$k])/100;
 
583
          for ($j=0;$j<@{$steps_ref};$j++) {
 
584
            for ($i=@{$h2_ref}-1;$i>=0;$i--) {
 
585
              if ($h2_ref->[$i][$j] > $p) {
 
586
                $perc[$j][$k] = $i * $do_dist * 10/ $y_unit;
 
587
                last;
 
588
              }
 
589
            }
 
590
            if (!defined $perc[$j][$k]) {
 
591
              for ($i=@{$h_ref}-1;$i>=0;$i--) {
 
592
                if ($h_ref->[$i][$j] > $p) {
 
593
                  $perc[$j][$k] = $i * $do_dist /$y_unit;
 
594
                  last;
 
595
                }
 
596
              }
 
597
            }
 
598
          }
 
599
        }
 
600
      }
 
601
    }
 
602
  }
 
603
  return (0, $stats_ref, \@perc);
 
604
}
 
605
 
 
606
############################################################################################
 
607
# Plot the data using gnuplot
 
608
# INPUT 1: File Name containing input data
 
609
# INPUT 2: File name containing output png file.
 
610
# INPUT 3: Title of the graph.
 
611
# INPUT 4: X Axis legend.
 
612
# INPUT 5: Y Axis legend.
 
613
# INPUT 6: Point Size.
 
614
# INPUT 7: Time unit. Set to 1000000 == 1 second to plot data in seconds.
 
615
# INPUT 8: Y unit. To plot the data with a different Y axis scale.
 
616
# INPUT 9: Set to 1 if bezier must be plotted.
 
617
# INPUT 10: Number of data to plot on the same graph. Only if bezier not plotted.
 
618
# OUTPUT : none
 
619
############################################################################################
 
620
sub do_picture
 
621
{
 
622
  my ($picture, $title, $pointsize, $bezier, $datafile_ref, $columnx_ref, $columny_ref, $axis_ref,
 
623
      $unitx_ref, $unity_ref, $legend_ref, $steps_ref, $xml_ref, $do_column, $xscale, $logscaley1,
 
624
      $logscaley2) = @_;
 
625
  my $t1 = GetMilli();
 
626
  my ($i, $plotcmd, $draw, $scriptfile, $axe2, $script);
 
627
  $draw = "";
 
628
  $axe2 = "";
 
629
  $scriptfile = "$picture.gpl";
 
630
  $script = "";
 
631
 
 
632
  # Is there a secondary axis
 
633
  if ($axis_ref->[2]) {
 
634
    $script = "\tset y2label '$axis_ref->[2]'\n\tset y2tics\n";
 
635
    $axe2 = "axes x1y2";
 
636
  } 
 
637
  
 
638
  if ($bezier) {
 
639
    $plotcmd = "plot '$datafile_ref->[0]' using (\$"."$columnx_ref->[0]/$unitx_ref->[0]):(\$"."$columny_ref->[0]/$unity_ref->[0]) title '$legend_ref->[0]' with points ps 0.1 ";
 
640
    $plotcmd .= ",'$datafile_ref->[0]' using (\$"."$columnx_ref->[0]/$unitx_ref->[0]):(\$"."$columny_ref->[0]/$unity_ref->[0]) smooth bezier title ' bezier($legend_ref->[0])' with lines lt 2 lw 3";
 
641
 
 
642
    for ($i=1;$i<@{$columny_ref};$i++) {
 
643
      $plotcmd .= ",'$datafile_ref->[$i]' using (\$"."$columnx_ref->[$i]/$unitx_ref->[$i]):(\$"."$columny_ref->[$i]"."/$unity_ref->[$i]) $axe2 title ' $legend_ref->[$i]' with points lt ".(2*$i+1)." ps 0.1";      
 
644
      $plotcmd .= ",'$datafile_ref->[$i]' using (\$"."$columnx_ref->[$i]/$unitx_ref->[$i]):(\$"."$columny_ref->[$i]"."/$unity_ref->[$i]) $axe2 smooth bezier title ' bezier($legend_ref->[$i])' with lines lt ".(2*$i+2)." lw 3";
 
645
    }
 
646
  } else {
 
647
    if ((!defined $datafile_ref->[0]) || (!defined $unitx_ref->[0]) || (!defined $columny_ref->[0]) || (!defined $unity_ref->[0]) || (!defined $legend_ref->[0])) {
 
648
      print("(($datafile_ref->[0]) || ($unitx_ref->[0]) || ($columny_ref->[0]) || ($unity_ref->[0]) || ($legend_ref->[0]))\n");
 
649
    }
 
650
    $plotcmd = "plot '$datafile_ref->[0]' using (\$"."$columnx_ref->[0]/$unitx_ref->[0]):(\$"."$columny_ref->[0]/$unity_ref->[0]) title ' $legend_ref->[0]' with lines";
 
651
    for ($i=1;$i<@{$columny_ref};$i++) {
 
652
      $plotcmd .= " ,'$datafile_ref->[$i]' using (\$"."$columnx_ref->[$i]/$unitx_ref->[$i]):(\$"."$columny_ref->[$i]"."/$unity_ref->[$i]) $axe2 title ' $legend_ref->[$i]' with lines";
 
653
    }
 
654
  }
 
655
   
 
656
  if ($do_column) {
 
657
    my $prep_start = $steps_ref->[0]->{start_time}/1000;
 
658
    my $prep_stop = undef;
 
659
    my $ihs_transient_from = undef;
 
660
    my $ihs_transient_to = undef;
 
661
    my $in_prereg = 0;
 
662
 
 
663
    for ($i=0; $i<@{$steps_ref}; $i++) {
 
664
      my $last = ($i eq (@{$steps_ref}-1) ? 1 : 0);
 
665
 
 
666
      if (!defined($prep_stop)) {
 
667
        # Still in preration phases (pre-reg, stir)
 
668
        if ($steps_ref->[$i]->{prereg} != $in_prereg) {
 
669
          # Label preparation phases
 
670
          $draw .= "LABEL = \"  " . (($steps_ref->[$i]->{prereg} == 1) ? "pre-reg" : "stir") . "\"\n";
 
671
          $draw .= "set label ".($i+10)." at ".($steps_ref->[$i]->{start_time}/1000).",graph ".(0.95-0.05*$i)." textcolor lt 4 LABEL front left\n";
 
672
          # and draw a vertical line between pre-reg and stir phases
 
673
          if ($i gt 0) {
 
674
            my $x = $steps_ref->[$i-1]->{stop_time}/1000;
 
675
            $draw .= "set arrow from $x, graph 0 to $x, graph 1 nohead\n";
 
676
          }
 
677
        }
 
678
        $in_prereg = $steps_ref->[$i]->{prereg};
 
679
      }
 
680
 
 
681
      if (($steps_ref->[$i]->{prereg} == 0) && ($steps_ref->[$i]->{show_in_tables} == 1)) {
 
682
 
 
683
        # Grey background rectangle for preparation steps (pre-registration and stir phase)
 
684
        if (!defined($prep_stop)) {
 
685
          #print " Leaving preparation steps\n";
 
686
          $prep_stop = $steps_ref->[$i-1]->{stop_time}/1000;
 
687
          $draw .= "set object 1 rect from $prep_start, graph 0 to $prep_stop,graph 1 fc rgb '#E0E0E0#'\n";
 
688
        }
 
689
 
 
690
        if (defined($ihs_transient_from)) {
 
691
          my $to = $steps_ref->[$i]->{ihs_start_time}/1000;
 
692
          $draw .= "set object ".($i+2)." rect from $ihs_transient_from,graph 0 to $to,graph 1 fc rgb 'grey'\n";
 
693
          if ($last) {
 
694
            $draw .= "set object ".($i+3)." rect from ".($steps_ref->[$i]->{ihs_stop_time}/1000).
 
695
                ",graph 0 to 1000000,graph 1 fc rgb 'grey'\n";
 
696
          }
 
697
          $draw .= "set arrow from $to, graph 0 to $to, graph 1 nohead\n";
 
698
        }
 
699
        $ihs_transient_from = $steps_ref->[$i]->{ihs_stop_time}/1000;
 
700
 
 
701
        $draw .= "LABEL = \" ".$steps_ref->[$i]->{step_number}."\"\n";
 
702
        if ($steps_ref->[$i]->{over_ihs} == 0) {
 
703
          if ($steps_ref->[$i]->{is_doc_step} == 1) {
 
704
            $draw .= "set label ".($i+10)." at ".($steps_ref->[$i]->{ihs_start_time}/1000).",graph 0.95 textcolor lt 2 LABEL front left\n";
 
705
          } else {
 
706
            $draw .= "set label ".($i+10)." at ".($steps_ref->[$i]->{ihs_start_time}/1000).",graph 0.95 LABEL front left\n";
 
707
          }
 
708
        } else {
 
709
          $draw .= "set label ".($i+10)." at ".($steps_ref->[$i]->{ihs_start_time}/1000).",graph 0.95 textcolor lt 1 LABEL front left\n";
 
710
        }
 
711
      }
 
712
      else {
 
713
        $ihs_transient_from = $steps_ref->[$i]->{stop_time}/1000;
 
714
      }
 
715
    }
 
716
  }
 
717
 
 
718
  if ($logscaley1) {
 
719
    $draw .= "set log y\n";    
 
720
    $draw .= "set yrange [$logscaley1]\n"; 
 
721
  } else {
 
722
    $draw .= "set yrange [0:*]\n";
 
723
  }
 
724
  if ($axis_ref->[2]) {
 
725
    if ($logscaley2) {
 
726
      $draw .= "set log y2\n";    
 
727
      $draw .= "set y2range [$logscaley2]\n";
 
728
    } else {
 
729
      $draw .= "set y2range [0:*]\n";
 
730
    }
 
731
  }
 
732
  
 
733
  if ($xscale) {
 
734
    $draw .= "set xrange $xscale\n";
 
735
  } else {
 
736
    $draw .= "set xrange [0:*]\n";
 
737
  }
 
738
 
 
739
  $script = $script."
 
740
  set terminal png small $gnuplot_size $xml_ref->{size}->{x} $gnuplot_size_sep $xml_ref->{size}->{y}
 
741
  set output '$picture'
 
742
  set key outside right
 
743
  set grid
 
744
  set title '$title'
 
745
  set xlabel '$axis_ref->[0]'
 
746
  set ylabel '$axis_ref->[1]'
 
747
  set pointsize $pointsize
 
748
  set datafile separator ';'
 
749
  
 
750
  set grid noy2tics xtics nox2tics
 
751
  $draw;
 
752
  $plotcmd
 
753
  reset
 
754
  ";
 
755
 
 
756
  open(GP, ">$scriptfile");
 
757
  print GP $script;
 
758
  if (close(GP) <= 0) {
 
759
    print("Error closing file: $!\n");
 
760
    exit(0);
 
761
  }
 
762
 
 
763
  #printf("Doing $gnuplot $scriptfile\n");
 
764
  if ($do_fork) {
 
765
    my $pid_fork = fork;
 
766
    if ($pid_fork == 0) {
 
767
      die "cannot fork: $!" unless defined $pid_fork;
 
768
      exec ($gnuplot, $scriptfile);
 
769
      die "gnuplot failed to execute\n";
 
770
    }
 
771
    push(@forked_pids, $pid_fork);
 
772
    # print("Started under PID $pid_fork\n");
 
773
  } else {
 
774
    system($gnuplot, $scriptfile);
 
775
  }
 
776
  push(@TempFiles, $scriptfile);
 
777
  $t_pict += (GetMilli() - $t1);
 
778
}
 
779
 
 
780
############################################################################################
 
781
# INPUT 1: h level
 
782
# INPUT 2: href name
 
783
# INPUT 3: href title
 
784
# OUTPUT : none
 
785
############################################################################################
 
786
sub AddHref
 
787
{
 
788
  my ($href_level, $href_name, $href_title) = @_;
 
789
  my $string;
 
790
  $string .= "<h$href_level><a name=\"$href_name\">$href_title</a> <a href=\"#REF_TABLE\" class=\"b_index\"><img src=\"b_index.png\" alt=\"Index\" title=\"Index\"/></a></h$href_level>\n";
 
791
  if ($href_level <4) {
 
792
    $Report->{toc} .="<dt><a class=\"toc\" href=\"#$href_name\">$href_title</a></dt>";
 
793
  } elsif ($href_level <6) {
 
794
    $Report->{toc} .="<dd><a class=\"toc\" href=\"#$href_name\">$href_title</a></dd>";
 
795
  } else {
 
796
    $Report->{toc} .="<dd><a class=\"toc\" href=\"#$href_name\">    $href_title</a></dd>";
 
797
  }
 
798
  return $string;
 
799
}
 
800
 
 
801
sub plot
 
802
{
 
803
  my ($use_case, $scenario, $c, $pids_ref, $steps_ref, $scenario_ref, $config, $xmlData,
 
804
      $reportConfig, $yscale, $runtime, $href_level, $href_str, $server_name_ref) = @_;
 
805
  my ($Filename_ref, $Columnx_ref, $Columny_ref, $i, $j, $k, $l, $saps_ref, $t1, $per, $do_percentile);
 
806
  my (@err, @stats_ref, @perc_ref, $title1, $picfile, $graph);
 
807
  
 
808
  my @files = ();
 
809
  my @columnx = (); my @columny = ();
 
810
  my @axis = ();
 
811
  my @unitx = (); my @unity = ();
 
812
  my @legend = ();
 
813
  my $html;
 
814
 
 
815
  $c->{UnitY} = 1 unless defined($c->{UnitY});
 
816
  if (defined($c->{TimeBasedGraph}) && !defined($c->{TimeBasedGraph}->{UnitY})) {
 
817
    $c->{TimeBasedGraph}->{UnitY} = 1;
 
818
  }
 
819
  if (defined($c->{MeanBasedGraph}) && !defined($c->{MeanBasedGraph}->{UnitY})) {
 
820
    $c->{MeanBasedGraph}->{UnitY} = 1;
 
821
  }
 
822
  
 
823
  my ($first, $title, $description, $h4, $skip);
 
824
  my ($source_ref, $failure_ref);
 
825
  $description = $c->{Description};
 
826
  $h4 = 0;
 
827
  $skip = 0;
 
828
 
 
829
  my $n_percent = defined($reportConfig->{Percentile}->{Value}) ?
 
830
      @{$reportConfig->{Percentile}->{Value}} : 0;
 
831
 
 
832
  if ($c->{Title}) {
 
833
    print ("$c->{Source} $scenario ready to be plotted\n");
 
834
    $title = "$c->{Title}";
 
835
    if ((($c->{DistrBasedGraph}) || ($c->{ProbaBasedGraph})) && (!defined $c->{DistAndHistoUnit})) {
 
836
      $c->{DistAndHistoUnit} = 1;
 
837
    }
 
838
    if (!defined $c->{DistAndHistoUnit}) {
 
839
      $c->{DistAndHistoUnit} = 0;
 
840
    }
 
841
    
 
842
    if ($scenario) {
 
843
      $title .= "($scenario scenario)";
 
844
    } elsif ($use_case) {
 
845
      $title .= "($use_case use case)";
 
846
    }
 
847
 
 
848
    ($Filename_ref, $Columnx_ref, $Columny_ref, $source_ref, $skip, $do_percentile) =
 
849
        BuildFileFromSource($c->{Source}, $use_case, $scenario, $pids_ref, $c, $server_name_ref, $xmlData, $n_percent);
 
850
    if (!defined $Filename_ref->[0]) {
 
851
      print ("$c->{Source} scenario is not defined and will not be plotted\n");
 
852
      return;
 
853
    }
 
854
    
 
855
    $html .=  "<p>$description</p>\n";
 
856
    
 
857
    for ($i=0; $i<@{$source_ref}; $i++) {
 
858
      ($err[$i], $stats_ref[$i], $perc_ref[$i]) =
 
859
          Analyze($Filename_ref->[$i], $Columny_ref->[$i], $c->{UnitX}, $c->{UnitY}, $steps_ref,
 
860
                  $c->{MeanBasedGraph}, $c->{DistAndHistoUnit}, $skip, $reportConfig, $do_percentile);
 
861
      if ($err[$i]) {
 
862
        print(" => nothing to plot ($lasterr)\n");
 
863
        $lasterr = "";
 
864
        if ($i == 0) {
 
865
          $Report->{graphs} .= $html if defined($html);
 
866
          return;
 
867
        }
 
868
      }
 
869
    }
 
870
    
 
871
    # Write to the report the measurement statistics.
 
872
    $html .=  "<table border=\"1\"><tr class=\"table_title\"><td>&nbsp</td><td>&nbsp</td>\n";
 
873
    for ($i=0;$i<@{$source_ref};$i++) {
 
874
      if ($err[$i] == 0) {
 
875
        my $ncol = 4;
 
876
        if ($source_ref->[$i] eq "Effective Load") {
 
877
          $ncol = 5;
 
878
        }
 
879
        if ($do_percentile) {
 
880
          $ncol += $n_percent;
 
881
        }
 
882
        $html .=  "<th colspan=\"$ncol\">$source_ref->[$i]</th>\n";        
 
883
      }
 
884
    }
 
885
    $html .=  "</tr>\n<tr class=\"table_title\">\n<th>Step</th><th>Requested Load</th>";
 
886
    for ($i=0; $i<@{$source_ref}; $i++) {
 
887
      if ($err[$i] == 0) {
 
888
        # Variance is only interesting for Effective load, to check Poisson
 
889
        if ($source_ref->[$i] eq "Effective Load") {
 
890
          $html .=  "<th>Mean</th><th>Variance</th><th>Standard Deviation</th><th>Minimum</th><th>Maximum</th>";
 
891
        } else {
 
892
          $html .=  "<th>Mean</th><th>Standard Deviation</th><th>Minimum</th><th>Maximum</th>";
 
893
        }
 
894
        if ($do_percentile) {
 
895
          for ($k=0; $k<$n_percent; $k++) {
 
896
            $html .= "<th>Percentile $reportConfig->{Percentile}->{Value}->[$k]</th>\n";
 
897
          }
 
898
        }
 
899
      }
 
900
    }
 
901
    $html .=  "</tr>\n";
 
902
    
 
903
    for ($j=0; $j<@{$steps_ref}; $j++) {
 
904
      my $step = $steps_ref->[$j];
 
905
      my $temp_buffer = "";
 
906
      if (defined($stats_ref[0]->[$j]->{min})) {
 
907
        if ($step->{show_in_tables}) {
 
908
          if ($step->{prereg} == 1) {
 
909
            if ($step->{over_ihs}) {
 
910
              $temp_buffer = sprintf("<tr class=\"step_info\"><td class=\"step_ihs\">Pre-reg</td>");
 
911
            } else {
 
912
              $temp_buffer = sprintf("<tr class=\"step_info\"><td class=\"step_box\">Pre-reg</td>");
 
913
            }
 
914
          } else {
 
915
            my $td_class;
 
916
            if ($step->{is_doc_step}) {
 
917
                $td_class = "step_doc";
 
918
            } elsif ($step->{over_ihs}) {
 
919
                $td_class = "step_ihs";
 
920
            } else {
 
921
                $td_class = "step_box";
 
922
            }
 
923
            $temp_buffer = sprintf("<tr><td class=\"%s\">%d</td>", $td_class,
 
924
                                   $step->{step_number});
 
925
          }
 
926
          $temp_buffer .= sprintf("<td>%d</td>", $step->{cps});
 
927
          for ($i=0; $i<@{$source_ref}; $i++) {
 
928
            if ($err[$i] == 0) {
 
929
              $temp_buffer .= sprintf("<td>%.2f</td>", $stats_ref[$i]->[$j]->{mean});
 
930
              if ($source_ref->[$i] eq "Effective Load") {
 
931
                $temp_buffer .= sprintf("<td>%.2f</td>", $stats_ref[$i]->[$j]->{variance});
 
932
              }
 
933
              $temp_buffer .= sprintf("<td>%.2f</td><td>%.2f</td><td>%.2f</td>",
 
934
                                      sqrt($stats_ref[$i]->[$j]->{variance}),
 
935
                                      $stats_ref[$i]->[$j]->{min}, $stats_ref[$i]->[$j]->{max});
 
936
              if ($do_percentile) {
 
937
                for ($per=0; $per<$n_percent; $per++) {
 
938
                  $temp_buffer .= sprintf("<td>%.1f</td>", $perc_ref[$i]->[$j][$per]);
 
939
                }
 
940
              }
 
941
            }
 
942
          }
 
943
          $temp_buffer .= sprintf("</tr>\n");
 
944
        }
 
945
      }
 
946
      $html .= $temp_buffer;
 
947
    }
 
948
    $html .=  "</table>\n";
 
949
  }
 
950
  
 
951
  # Fill in Summary
 
952
  my @failure;
 
953
  if ($c->{InSummary}) {
 
954
 
 
955
    if ($c->{Source} eq  "SAPS" ) {
 
956
      # SAPS must be before IHS in xml...
 
957
      for ($j=0;$j<@{$steps_ref};$j++) {
 
958
        if ($steps_ref->[$j]->{prereg} == 1) {
 
959
          $doc_ref->[$j] = 0;
 
960
        } else {
 
961
          $doc_ref->[$j] = $stats_ref[0]->[$j]->{mean};
 
962
        }
 
963
      }
 
964
    }
 
965
 
 
966
    if ($c->{Source} eq  "IHS" ) {
 
967
      for ($k=0;$k<@{$scenario_ref};$k++) {
 
968
        $failure_ref = $TotFailures[$k+1];
 
969
        $saps_ref = $TotSAPS[$k+1];
 
970
        # Check if any different from 0. If not, skip
 
971
        $j = 0;
 
972
        while ($steps_ref->[$j]) {
 
973
          if ($saps_ref->[$j] && $stats_ref[0]->[$j]->{mean} && $failure_ref->[$j]) {
 
974
            last;
 
975
          }
 
976
          $j++;
 
977
        }
 
978
        if ($steps_ref->[$j]) {
 
979
          $Report->{summary_tbl} .= "<tr><th class=\"step_box\"> IHS $scenario_ref->[$k] \%</th>";
 
980
          $j = 0;
 
981
          $first = 1;
 
982
          while ($steps_ref->[$j]) {
 
983
            if ($steps_ref->[$j]->{show_in_tables} eq 1) {
 
984
              if ($first) {
 
985
                $Report->{summary_tbl} .= "<td class=\"step_info\">";
 
986
                $first = 0;
 
987
              } else {
 
988
                $Report->{summary_tbl} .= "<td>";
 
989
              }
 
990
              if ($saps_ref->[$j] && $stats_ref[0]->[$j]->{mean}) {
 
991
                $Report->{summary_tbl} .= sprintf("%.2f</td>", $failure_ref->[$j] / $saps_ref->[$j] * 100);
 
992
              } else {
 
993
                $Report->{summary_tbl} .= "0.00</td>";
 
994
              }
 
995
            }
 
996
            $j++;
 
997
          }
 
998
          $Report->{summary_tbl} .= "</tr>\n";
 
999
        }
 
1000
      }
 
1001
      $j=0;
 
1002
      $Report->{summary_tbl} .= "<tr><th class=\"step_box\">$c->{InSummary}</th>";
 
1003
      $first = 1;
 
1004
      while ($steps_ref->[$j]) {
 
1005
        if ($steps_ref->[$j]->{show_in_tables} eq 1) {
 
1006
          if ($first) {
 
1007
            $Report->{summary_tbl} .= "<td class=\"step_info\">";
 
1008
            $first = 0;
 
1009
          } else {
 
1010
            $Report->{summary_tbl} .= "<td>";
 
1011
          }
 
1012
          $failure_ref = $TotFailures[0];
 
1013
          $saps_ref = $TotSAPS[0];
 
1014
          if ($stats_ref[0]->[$j]->{mean} && $saps_ref->[$j]) {
 
1015
            $Report->{summary_tbl} .= sprintf("%.2f</td>", $failure_ref->[$j] / $saps_ref->[$j] * 100);
 
1016
          } else {
 
1017
            $Report->{summary_tbl} .= "0.00</td>";
 
1018
          }
 
1019
        }
 
1020
        $j++;
 
1021
      }
 
1022
      $Report->{summary_tbl} .= "</tr>\n";
 
1023
      
 
1024
      # Find the DOC
 
1025
      my $doc = 0;
 
1026
      my $failure_step = -1;
 
1027
      for ($j=0; $j<@{$steps_ref}; $j++) {
 
1028
        if ($steps_ref->[$j]->{over_ihs} == 0) {
 
1029
          if (!defined $doc_ref->[$j]) {
 
1030
            printf("undefined doc_ref->[$j]\n");
 
1031
          }
 
1032
          if ($doc_ref->[$j] > $doc) {
 
1033
            $Result->{doc_step} = $j;
 
1034
            $doc = $doc_ref->[$j];
 
1035
          }
 
1036
        } else {
 
1037
          $failure_step = $j;
 
1038
          last;
 
1039
        }
 
1040
      }
 
1041
 
 
1042
      if ($failure_step > 0) {
 
1043
        $Result->{Status} = DOC_REACHED;
 
1044
        $Result->{DOC} = int($doc);
 
1045
        print("DOC = $doc\n");
 
1046
      } elsif ($failure_step == 0) {
 
1047
        $Result->{Status} = FAILED;
 
1048
        $Result->{DOC} = 0;
 
1049
        print("DOC = 0\n");
 
1050
      } else {
 
1051
        $Result->{Status} = DOC_NOT_REACHED;
 
1052
        $Result->{DOC} = int($doc);
 
1053
        print("DOC not reached = $doc\n");
 
1054
      }
 
1055
 
 
1056
    } else {
 
1057
      for ($i=0;$i<@{$source_ref};$i++) {
 
1058
        $j=0;
 
1059
        $Report->{summary_tbl} .= "<tr><th class=\"step_box\">$source_ref->[$i]</th>";
 
1060
        $first = 1;
 
1061
        while ($steps_ref->[$j]) {
 
1062
          if ($steps_ref->[$j]->{show_in_tables} eq 1) {
 
1063
            if ($first) {
 
1064
              $Report->{summary_tbl} .= "<td class=\"step_info\">";
 
1065
              $first = 0;
 
1066
            } else {
 
1067
              $Report->{summary_tbl} .= "<td>";
 
1068
            }
 
1069
            if (defined $stats_ref[$i]->[$j]->{mean}) {
 
1070
              $Report->{summary_tbl} .= sprintf("%.2f</td>", $stats_ref[$i]->[$j]->{mean});
 
1071
            }
 
1072
          }
 
1073
          $j++;
 
1074
        }
 
1075
        $Report->{summary_tbl} .= "</tr>\n";
 
1076
      }
 
1077
    }
 
1078
 
 
1079
    # SAPS measure yields "Effective Load" in the summary but we also include the ratios of
 
1080
    # the various scenarios as part of the data provided from the SAPS measure.
 
1081
    if (($c->{Source} eq  "SAPS") && $reportConfig->{DisplayRatio}) {
 
1082
      for ($k=0;$k<@{$scenario_ref};$k++) {
 
1083
        my $saps_per_s_ref = $TotSAPS[$k+1];
 
1084
        $saps_ref = $TotSAPS[0];
 
1085
        $j = 0;
 
1086
        while ($steps_ref->[$j]) {
 
1087
          if ($saps_ref->[$j] && $saps_per_s_ref->[$j]) {
 
1088
            last;
 
1089
          }
 
1090
          $j++;
 
1091
        }
 
1092
        if ($steps_ref->[$j]) {
 
1093
          $Report->{summary_tbl} .= "<tr><th class=\"step_box\"> Ratio $scenario_ref->[$k] \%</th>";
 
1094
          $j = 0;
 
1095
          $first = 1;
 
1096
          while ($steps_ref->[$j]) {
 
1097
            if ($steps_ref->[$j]->{show_in_tables} eq 1) {
 
1098
              if ($first) {
 
1099
                $Report->{summary_tbl} .= "<td class=\"step_info\">";
 
1100
                $first = 0;
 
1101
              } else {
 
1102
                $Report->{summary_tbl} .= "<td>";
 
1103
              }
 
1104
              if ($saps_ref->[$j] && $saps_per_s_ref->[$j]) {
 
1105
                $Report->{summary_tbl} .= sprintf("%.2f</td>", $saps_per_s_ref->[$j] / $saps_ref->[$j] * 100);
 
1106
              } else {
 
1107
                $Report->{summary_tbl} .= "0.00</td>";
 
1108
              }
 
1109
            }
 
1110
            $j++;
 
1111
          }
 
1112
          $Report->{summary_tbl} .= "</tr>\n";
 
1113
        }
 
1114
      }
 
1115
    }
 
1116
  }
 
1117
  
 
1118
  # Start preparing the graphs; call do_picture to really plot them
 
1119
  my ($Filename2_ref, $Columnx2_ref, $Columny2_ref);
 
1120
  if ($c->{TimeBasedGraph}) {
 
1121
    $h4++;
 
1122
    $picfile = "$c->{Source}".$use_case.$scenario."-normaltime.png";
 
1123
    $t1 = GetMilli();
 
1124
    if ($c->{TimeBasedGraph}->{Source}) {
 
1125
      ($Filename2_ref, $Columnx2_ref, $Columny2_ref, $do_percentile) =
 
1126
          BuildFileFromSource($c->{TimeBasedGraph}->{Source}, $use_case, $scenario, $pids_ref, $c, "", $xmlData, $n_percent);
 
1127
      @axis = ($c->{AxeX}, $c->{TimeBasedGraph}->{AxeY}, $c->{AxeY}); 
 
1128
      $files[0] = ($Filename2_ref->[0]); 
 
1129
      $columnx[0] = ($Columnx2_ref->[0]); 
 
1130
      $columny[0] = ($Columny2_ref->[0]); 
 
1131
      $unitx[0] = ($c->{UnitX});
 
1132
      $unity[0] = ($c->{TimeBasedGraph}->{UnitY});
 
1133
      $legend[0] = ($c->{TimeBasedGraph}->{LegendY});
 
1134
      for ($i=0;$i<@{$Filename_ref};$i++) {
 
1135
        $files[$i+1] = ($Filename_ref->[$i]); 
 
1136
        $columnx[$i+1] = ($Columnx_ref->[$i]); 
 
1137
        $columny[$i+1] = ($Columny_ref->[$i]); 
 
1138
        $unitx[$i+1] = ($c->{UnitX});
 
1139
        $unity[$i+1] = ($c->{UnitY});
 
1140
        $legend[$i+1] = ($source_ref->[$i]);
 
1141
      }
 
1142
    } else {
 
1143
      @axis = ($c->{AxeX}, $c->{AxeY}); 
 
1144
      for ($i=0;$i<@{$Filename_ref};$i++) {
 
1145
        $files[$i] = ($Filename_ref->[$i]); 
 
1146
        $columnx[$i] = ($Columnx_ref->[$i]); 
 
1147
        $columny[$i] = ($Columny_ref->[$i]); 
 
1148
        $unitx[$i] = ($c->{UnitX});
 
1149
        $unity[$i] = ($c->{UnitY});
 
1150
        $legend[$i] = ($source_ref->[$i]);
 
1151
      }
 
1152
    }
 
1153
    #$c->{TimeBasedGraph}->{Logscale} = "*:*" if (!defined $c->{TimeBasedGraph}->{Logscale});
 
1154
    do_picture($picfile, $title, 0.2, $c->{TimeBasedGraph}->{bezier}, \@files, \@columnx, \@columny, \@axis, \@unitx, \@unity, \@legend, $steps_ref, $reportConfig, 1, "[0:$yscale]", $c->{TimeBasedGraph}->{Logscale}, $c->{Logscale});
 
1155
    $html .= AddHref($href_level, $title, "$href_str.$h4 $title over time");
 
1156
    if (defined $c->{TimeBasedGraph}->{Description}) {
 
1157
      $html .= "<p>$c->{TimeBasedGraph}->{Description}</p>\n";
 
1158
    }
 
1159
    $html .= "<div class=\"centered\"><img src=\"$picfile\" alt=\"$picfile text\"/></div>\n";
 
1160
  }
 
1161
  if ($c->{MeanBasedGraph}) {
 
1162
    $h4++;
 
1163
    $title1 = "$title (Mean per second)";
 
1164
    my $picfile = "$c->{Source}".$use_case.$scenario."-meantime.png";
 
1165
    $t1 = GetMilli();
 
1166
    if ($c->{MeanBasedGraph}->{Source}) {
 
1167
      ($Filename2_ref, $Columnx2_ref, $Columny2_ref, $source_ref, $do_percentile) = BuildFileFromSource($c->{MeanBasedGraph}->{Source}, $use_case, $scenario, $pids_ref, $c, "", $xmlData, $n_percent);
 
1168
      @files = ($Filename2_ref->[0], "$Filename_ref->[0]-time.dat"); 
 
1169
      @columnx = ($Columnx2_ref->[0], $Columnx_ref->[0]); 
 
1170
      @columny = ($Columny2_ref->[0], $Columny_ref->[0]); 
 
1171
      @axis = ($c->{AxeX}, $c->{MeanBasedGraph}->{AxeY}, $c->{AxeY}); 
 
1172
      @unitx = ($c->{UnitX}, $c->{UnitX});
 
1173
      @unity = ($c->{MeanBasedGraph}->{UnitY}, $c->{UnitY});
 
1174
      @legend = ($c->{MeanBasedGraph}->{LegendY}, $c->{LegendY});
 
1175
    } else {
 
1176
      @files = ("$Filename_ref->[0]-time.dat"); 
 
1177
      @columnx = ($Columnx_ref->[0]); 
 
1178
      @columny = ($Columny_ref->[0]); 
 
1179
      @axis = ($c->{AxeX}, $c->{AxeY}); 
 
1180
      @unitx = ($c->{UnitX});
 
1181
      @unity = ($c->{UnitY});
 
1182
      @legend = ($c->{LegendY});
 
1183
    }
 
1184
    #$c->{MeanBasedGraph}->{Logscale} = "*:*" if (!defined $c->{MeanBasedGraph}->{Logscale});
 
1185
    do_picture($picfile, $title1, 0.4, $c->{MeanBasedGraph}->{bezier}, \@files, \@columnx, \@columny, \@axis, \@unitx, \@unity, \@legend, $steps_ref, $reportConfig, 1, "[0:$yscale]", $c->{MeanBasedGraph}->{Logscale}, $c->{Logscale});
 
1186
    $t_othergraphs += GetMilli() - $t1;
 
1187
    $html .= AddHref($href_level,$title1, "$href_str.$h4 $title1");
 
1188
    if (defined $c->{MeanBasedGraph}->{Description}) {
 
1189
      $html .= "<p>$c->{MeanBasedGraph}->{Description}</p>\n";
 
1190
    }
 
1191
    $html .= "<div class=\"centered\"><img src=\"$picfile\" alt=\"$picfile text\"/></div>\n";
 
1192
  }
 
1193
  $Report->{graphs} .= $html if defined($html);
 
1194
  
 
1195
  if ((($c->{DistrBasedGraph}) && ($c->{DistrBasedGraph}->{Theoritical}) &&
 
1196
       ($c->{DistrBasedGraph}->{Theoritical} eq "Poisson")) ||
 
1197
      (($c->{ProbaBasedGraph}) && ($c->{ProbaBasedGraph}->{Theoritical}) &&
 
1198
       ($c->{ProbaBasedGraph}->{Theoritical} eq "Poisson"))) {
 
1199
    BuildPoisson($steps_ref, $config);
 
1200
  }
 
1201
 
 
1202
  if (($c->{DistrBasedGraph}) &&
 
1203
      (($c->{DistrBasedGraph}->{Theoritical}) && ($c->{DistrBasedGraph}->{Theoritical} eq "Expo")) ||
 
1204
      (($c->{ProbaBasedGraph}) && ($c->{ProbaBasedGraph}->{Theoritical}) &&
 
1205
       ($c->{ProbaBasedGraph}->{Theoritical} eq "Expo"))) {
 
1206
    BuildExpo($steps_ref, $config);
 
1207
  }
 
1208
  
 
1209
  if ($c->{DistrBasedGraph}) {
 
1210
    $title1 = "$title Histogram";
 
1211
    $picfile = "$c->{Source}".$use_case.$scenario."-hist.png";
 
1212
    @files = ("$Filename_ref->[0]-hist.dat"); 
 
1213
    @axis = ($c->{AxeY}, "% of Occurence");
 
1214
    $graph = $c->{DistrBasedGraph};
 
1215
    $h4++;
 
1216
    if (($c->{DistrBasedGraph}) && ($c->{DistrBasedGraph}->{Theoritical}) && ($c->{DistrBasedGraph}->{Theoritical} eq "Poisson")) {
 
1217
      PlotHistoGraph($title1, $picfile, \@files, \@axis, $graph, $c->{UnitY}, $reportConfig, $steps_ref, $h4, $href_level, $href_str, "poisson.dat");
 
1218
    } elsif (($c->{DistrBasedGraph}) && ($c->{DistrBasedGraph}->{Theoritical}) && ($c->{DistrBasedGraph}->{Theoritical} eq "Expo")) {
 
1219
      PlotHistoGraph($title1, $picfile, \@files, \@axis, $graph, $c->{UnitY}, $reportConfig, $steps_ref, $h4, $href_level, $href_str, "expo.dat");
 
1220
    } else {
 
1221
      PlotHistoGraph($title1, $picfile, \@files, \@axis, $graph, $c->{UnitY}, $reportConfig, $steps_ref, $h4, $href_level, $href_str,"");
 
1222
    }
 
1223
  }
 
1224
  if ($c->{ProbaBasedGraph}) {
 
1225
    $title1 = "$title Probability";
 
1226
    $picfile = "$c->{Source}".$use_case.$scenario."-dist.png";
 
1227
    @files = ("$Filename_ref->[0]-dist.dat");     
 
1228
    @axis = ($c->{AxeY}, "Probability");    
 
1229
    $graph = $c->{ProbaBasedGraph};
 
1230
    $h4++;
 
1231
    if (($c->{ProbaBasedGraph}) && ($c->{ProbaBasedGraph}->{Theoritical}) && ($c->{ProbaBasedGraph}->{Theoritical} eq "Poisson")) {
 
1232
      PlotHistoGraph($title1, $picfile, \@files, \@axis, $graph, $c->{UnitY}, $reportConfig, $steps_ref, $h4, $href_level, $href_str, "poisson-hist.dat");
 
1233
    } elsif (($c->{ProbaBasedGraph}) && ($c->{ProbaBasedGraph}->{Theoritical}) && ($c->{ProbaBasedGraph}->{Theoritical} eq "Expo")) {
 
1234
      PlotHistoGraph($title1, $picfile, \@files, \@axis, $graph, $c->{UnitY}, $reportConfig, $steps_ref, $h4, $href_level, $href_str, "expo-hist.dat");
 
1235
    } else {
 
1236
      PlotHistoGraph($title1, $picfile, \@files, \@axis, $graph, $c->{UnitY}, $reportConfig, $steps_ref, $h4, $href_level, $href_str, "");
 
1237
    }
 
1238
  }
 
1239
}
 
1240
 
 
1241
sub PlotHistoGraph()
 
1242
{
 
1243
  my ($title1, $picfile, $files_ref, $axis_ref, $graph, $div_x, $reportConfig, $steps_ref,
 
1244
      $h4, $href_level, $href_str, $theo_file) = @_;
 
1245
  my $t1 = GetMilli();
 
1246
  my @unitx = (1); my @unity = ();
 
1247
  my @legend = ();
 
1248
  my @columnx = (1); my @columny = ();    
 
1249
  my $graph_nb = 0;
 
1250
  my $col = 1;
 
1251
  my $n_steps = @{$steps_ref};
 
1252
  my ($m, $html);
 
1253
 
 
1254
  for ($m=0; $m<$n_steps; $m++) {
 
1255
    if ($steps_ref->[$m]->{show_histograms} != 0) {
 
1256
      $col++;
 
1257
      $files_ref->[$graph_nb] = $files_ref->[0];
 
1258
      $columnx[$graph_nb] = 1;
 
1259
      $columny[$graph_nb] = $col;
 
1260
      $unitx[$graph_nb] = $div_x;
 
1261
      $unity[$graph_nb] = 1;
 
1262
      $legend[$graph_nb] = $steps_ref->[$m]->{label};
 
1263
      $graph_nb++;
 
1264
      if($theo_file ne "") {
 
1265
        $files_ref->[$graph_nb] = $theo_file;
 
1266
        $columnx[$graph_nb] = 1;
 
1267
        $columny[$graph_nb] = $col;
 
1268
        $unitx[$graph_nb] = $div_x;
 
1269
        $unity[$graph_nb] = 1;
 
1270
        $legend[$graph_nb] = "T (".$steps_ref->[$m]->{label}.")";
 
1271
        $graph_nb++;
 
1272
      }
 
1273
    }
 
1274
  }
 
1275
  # Maybe no graphs to plot - this would for instance be the case if only one failure step.
 
1276
  if ($graph_nb == 0) {
 
1277
    return;
 
1278
  }
 
1279
  $graph->{xscale} = "*" if (!defined $graph->{xscale}) ;
 
1280
  do_picture($picfile, $title1, 0.5, $graph->{bezier}, $files_ref, \@columnx, \@columny, $axis_ref,
 
1281
             \@unitx, \@unity, \@legend, $steps_ref, $reportConfig, 0, "[*:$graph->{xscale}]", $graph->{Logscale}, 0);
 
1282
  $t_othergraphs += GetMilli() - $t1;
 
1283
  $Report->{graphs} .= AddHref($href_level, $title1, "$href_str.$h4 $title1");
 
1284
  if (defined $graph->{Description}) {
 
1285
    $Report->{graphs} .= "<p>$graph->{Description}</p>\n";
 
1286
  }
 
1287
  $Report->{graphs} .= "<div class=\"centered\"><img src=\"$picfile\" alt=\"$picfile text\"/></div>\n";
 
1288
}
 
1289
 
 
1290
### Return Scenario name, id and column - need to add 3 columns for time, id and ihs
 
1291
sub ReadScenarios
 
1292
{
 
1293
  my $config = shift;
 
1294
  my ($use_case, $s, $m, @rtd_list);
 
1295
 
 
1296
  my @scenarios = keys %{$config->{scenario}};
 
1297
  @scenarios = sort {$config->{scenario}->{$a}->{id} <=> $config->{scenario}->{$b}->{id}} @scenarios;
 
1298
  for ($s=0; $s < @scenarios; $s++) {
 
1299
    if (defined $config->{scenario}->{$scenarios[$s]}->{use_case}) {
 
1300
      $use_case = $config->{scenario}->{$scenarios[$s]}->{use_case};
 
1301
    } else {
 
1302
      $use_case = "no_use_case";
 
1303
    }
 
1304
    $^W = 0; # Disable Warnings in XMLin, as multiple rtd_info param in some scenarios like ims_uas.xml
 
1305
    my $scenario_xml = XMLin($scenarios[$s].".xml", forcearray => ['metric']);
 
1306
    $^W = 1; # Re-enable warnings
 
1307
    my $metric = $scenario_xml->{info}->{metric};
 
1308
    $m = 0;
 
1309
    while ($$metric[$m]) {
 
1310
      push(@rtd_list, [$$metric[$m]->{ref}, $s, $m, $config->{scenario}->{$scenarios[$s]}->{clientmode},
 
1311
                       $scenarios[$s], $use_case]);
 
1312
      #print ("name=$$metric[$m]->{ref}, rtd=$$metric[$m]->{rtd}, id=$s, column=$m, name=$scenarios[$s]\n");
 
1313
      $m++;
 
1314
    }
 
1315
  }
 
1316
  return (\@rtd_list, \@scenarios);
 
1317
}
 
1318
 
 
1319
sub BuildFileFromSource
 
1320
{
 
1321
  my ($source, $use_case, $scenario_name, $pids, $meas, $server_name_ref, $xmlData, $n_percent) = @_;
 
1322
  my ($i, $j, $n_SUT, $filename);
 
1323
  my $t_b = GetMilli();
 
1324
  my @columnx = (1);
 
1325
  my @columny = (2);
 
1326
  my @filename = ("");
 
1327
  my @Failures = ();
 
1328
  my @IHS = ();
 
1329
  my @Source = ($source);
 
1330
  my $skip = 0;
 
1331
  my $do_percentile = 1;
 
1332
  
 
1333
 
 
1334
  if ($source eq "IHS") {
 
1335
    $do_percentile = 0;
 
1336
    $filename[0] = "IHS.dat";   
 
1337
    if ($scenario_name ne "") {
 
1338
      $Source[0] = "IHS per scenario %";      
 
1339
      $columny[0] = $ColumnSAPS{$scenario_name};
 
1340
    } else  {
 
1341
      if (defined $ColumnSAPS{$use_case}) {
 
1342
        $Source[0] = "IHS per use_case %";            
 
1343
        $columny[0] = $ColumnSAPS{$use_case};
 
1344
      } else {
 
1345
        $Source[0] = "Global IHS %";        
 
1346
        print(" => use_case $use_case not defined in report.xml => using total SAPS instead\n");    
 
1347
        $columny[0] = $ColumnSAPS{""};
 
1348
      }
 
1349
    }
 
1350
    $skip = 1;
 
1351
  } elsif ($source eq "CPU") {
 
1352
    $do_percentile = 0;
 
1353
    if (defined $xmlData->{remote}->{system}) {
 
1354
      $n_SUT = @{$xmlData->{remote}->{system}};
 
1355
      for ($i=0;$i< $n_SUT;$i++) {
 
1356
        $filename[$i] = "cpumem2_$i.csv";
 
1357
        $Source[$i] = "CPU $xmlData->{remote}->{system}->[$i]->{server}";
 
1358
        $columnx[$i] = 1;
 
1359
        $columny[$i] = 2;
 
1360
      }
 
1361
    }
 
1362
    $skip = 0;
 
1363
  } elsif ($source eq "MEM") {
 
1364
    $do_percentile = 0;
 
1365
    if (defined $xmlData->{remote}->{system}) {
 
1366
      $n_SUT = @{$xmlData->{remote}->{system}};
 
1367
      $do_percentile = 0;
 
1368
      for ($i=0;$i< $n_SUT;$i++) {
 
1369
        $filename[$i] = "cpumem2_$i.csv";
 
1370
        $Source[$i] = "Memory $xmlData->{remote}->{system}->[$i]->{server}";
 
1371
        $columnx[$i] = 1;
 
1372
        $columny[$i] = 3;
 
1373
      }
 
1374
    }
 
1375
    $skip = 0;
 
1376
  } elsif ($source eq "ALL-SIPP-CPU") {
 
1377
    my %cpuserver;
 
1378
    $do_percentile = 0;
 
1379
    $j = 0;
 
1380
    for ($i=0;$i< @{$pids};$i++) {
 
1381
      if (!defined $cpuserver{$server_name_ref->[$i]}) {
 
1382
        $filename[$j] = "sipp_".$pids->[$i]."_cpumem2.csv";
 
1383
        $columnx[$j] = 1;
 
1384
        $columny[$j] = 2;
 
1385
        $cpuserver{$server_name_ref->[$i]} = "server_name_ref->[$i]";
 
1386
        $Source[$j] = "SIPP CPU $server_name_ref->[$i]";
 
1387
        $j++;
 
1388
      }
 
1389
    }
 
1390
    $skip = 0;
 
1391
  } elsif ($source eq "ALL-SIPP-MEM") {
 
1392
    my %memserver;
 
1393
    $do_percentile = 0;
 
1394
    $j = 0;
 
1395
    for ($i=0;$i< @{$pids};$i++) {
 
1396
      if (!defined $memserver{$server_name_ref->[$i]}) {
 
1397
        $filename[$j] = "sipp_".$pids->[$i]."_cpumem2.csv";
 
1398
        $columnx[$j] = 1;
 
1399
        $columny[$j] = 3;
 
1400
        $memserver{$server_name_ref->[$i]} = "server_name_ref->[$i]";
 
1401
        $Source[$j] = "SIPP MEM $server_name_ref->[$i]";
 
1402
        $j++;
 
1403
      }
 
1404
    }
 
1405
    $skip = 0;
 
1406
  } elsif ($source eq "SIPP-MEM") {
 
1407
    $do_percentile = 0;
 
1408
    $filename[0] = "sipp_".$pids->[$meas->{Id}]."_cpumem2.csv";
 
1409
    $Source[0] = "SIPP MEM TS$meas->{Id}";
 
1410
    $columny[0] = 3;
 
1411
    $skip = 0;
 
1412
  } elsif ($source eq "SIPP-CPU") {
 
1413
    $do_percentile = 0;
 
1414
    $filename[0] = "sipp_".$pids->[$meas->{Id}]."_cpumem2.csv";
 
1415
    $Source[0] = "SIPP CPU TS$meas->{Id}";
 
1416
    $skip = 0;
 
1417
  } elsif ($source eq "SAPS") {
 
1418
    $Source[0] = "Effective Load";
 
1419
    $filename[0] = "SAPS.dat";
 
1420
    if ($scenario_name ne "") {
 
1421
      $columny[0] = $ColumnSAPS{$scenario_name};
 
1422
    } else  {
 
1423
      if (defined $ColumnSAPS{$use_case}) {
 
1424
        $columny[0] = $ColumnSAPS{$use_case};
 
1425
      } else {
 
1426
        print(" => use_case $use_case not defined in report.xml => using total SAPS instead\n");    
 
1427
        $columny[0] = $ColumnSAPS{""};
 
1428
      }
 
1429
    }
 
1430
    if (!defined $columny[0]) {
 
1431
      print("*** $use_case $scenario_name unknown exiting\n");
 
1432
      exit(1);
 
1433
    }
 
1434
    $skip = 1;
 
1435
  } elsif ($source eq "RETRANSMIT") {
 
1436
    $filename[0] = "retrans.dat";
 
1437
    $columny[0] = $ColumnRetrans{$scenario_name};
 
1438
    $skip = 1;
 
1439
  } elsif ($source eq "DELAY-SAPS") {
 
1440
    $filename[0] = "DELAY-SAPS.dat";    
 
1441
  } else {
 
1442
    $Source[0] = "$source (msec)";
 
1443
    if ($scenario_name ne "") {
 
1444
      $filename[0] = $source."_".$scenario_name.".dat";
 
1445
      if (!(-e $filename[0])) {
 
1446
        # If there is only one scenario for this metric, this is normal.
 
1447
        if (defined $MetricTable{$source}) {
 
1448
          if ( (my @scenarios = @{$MetricTable{$source}}) == 1) {
 
1449
            if ($scenarios[0]->{s_name} eq $scenario_name) {
 
1450
              $filename[0] = $source.".dat";
 
1451
            }
 
1452
          } else {
 
1453
            print("Failed to open $filename[0]\n");
 
1454
            $filename[0] = "";
 
1455
          }
 
1456
        } else {
 
1457
          print("Failed to open $filename[0]\n");
 
1458
          $filename[0] = "";
 
1459
        }
 
1460
      }
 
1461
    } elsif ($use_case ne "") {
 
1462
      $filename[0] = $source."_".$use_case.".dat";
 
1463
      if (!(-e $filename[0])) {
 
1464
        $filename[0] = $source.".dat";
 
1465
      }
 
1466
    } else {
 
1467
      $filename[0] = $source.".dat";
 
1468
    }
 
1469
  }
 
1470
  $t_buildfilefromsource += GetMilli() - $t_b;
 
1471
  print(" => ($source, $scenario_name, $use_case) using $filename[0], $columny[0]\n");
 
1472
  return (\@filename, \@columnx, \@columny, \@Source, $skip, $do_percentile);
 
1473
}
 
1474
 
 
1475
####################################################################################################
 
1476
# Insert empty lines between steps in an existing data file. This allows gnuplot to start a new
 
1477
# Bezier curve for each step. Not doing so would cause the start of the BEzier for step n to be
 
1478
# - sometimes heavily - influenced by the end of step n-1.
 
1479
# Note: This function is only used for files that already exist and just need this change before
 
1480
# being fed to gnuplot. Functions that build data files to be plotted have this bit of
 
1481
# functionality embedded.
 
1482
####################################################################################################
 
1483
sub AddStepSeparator
 
1484
{
 
1485
  my ($steps_ref, $in_file, $out_file) = @_;
 
1486
  my ($t, $j);
 
1487
 
 
1488
  if (!(-e $in_file)) {
 
1489
    return;
 
1490
  }
 
1491
  #print("Building $in_file\n");
 
1492
  $j = 0;
 
1493
  open(DATA, "<$in_file");
 
1494
  open(OUT, ">$out_file");
 
1495
  while(<DATA>) {
 
1496
    ($t) = split /[;]/; 
 
1497
    #print "AddStepSep t=$t step[$j]->stop_time=".$steps_ref->[$j]->{stop_time}."\n";
 
1498
    while ($t > $steps_ref->[$j]->{stop_time}) {
 
1499
      $j++;
 
1500
      print OUT "\n";
 
1501
      if ($j >= @{$steps_ref}) {
 
1502
        close DATA;
 
1503
        if (close(OUT) <= 0) {
 
1504
          print("Error closing file: $!\n");
 
1505
          exit(0);
 
1506
        }
 
1507
        return;
 
1508
      }
 
1509
    }
 
1510
    print OUT $_;
 
1511
  }
 
1512
  close DATA;
 
1513
  if (close(OUT) <= 0) {
 
1514
    print("Error closing file: $!\n");
 
1515
    exit(0);
 
1516
  }
 
1517
}
 
1518
 
 
1519
sub BuildCPUMEM
 
1520
{
 
1521
  my ($xmlData, $steps_ref) = @_;
 
1522
  my $t = GetMilli();
 
1523
  if (defined $xmlData->{remote}->{system}) {
 
1524
    my $n_SUT = @{$xmlData->{remote}->{system}};  
 
1525
    for (my $i = 0;$i < $n_SUT;$i++) {
 
1526
      AddStepSeparator($steps_ref, "cpumem_$i.csv", "cpumem2_$i.csv");    
 
1527
    }
 
1528
  }
 
1529
  $t_buildcpumem = GetMilli() - $t;
 
1530
}
 
1531
 
 
1532
sub BuildSippCPU
 
1533
{
 
1534
  my ($xmlData, $steps_ref) = @_;
 
1535
  my $t = GetMilli();
 
1536
  my $config = $xmlData->{configuration};  
 
1537
  for (my $i=0; $i < 100; $i++) {
 
1538
    my $name = "TS$i";
 
1539
    if ($config->{system}->{$name}) {
 
1540
      my $system = $config->{system}->{$name};
 
1541
      my $pid = $config->{system}->{$name}->{id};
 
1542
      my $file = "sipp_".$pid."_cpumem.csv";
 
1543
      my $file2 = "sipp_".$pid."_cpumem2.csv";
 
1544
      AddStepSeparator($steps_ref, "$file", "$file2");
 
1545
    }
 
1546
  }
 
1547
  $t_buildsippcpu = GetMilli() - $t;
 
1548
}
 
1549
 
 
1550
sub BuildRetrans
 
1551
{
 
1552
  my ($rtd_ref, $scenario_ref, $testStopTime) = @_;
 
1553
  my ($t, $t1, $t2, $i, $s);
 
1554
  my $n_scenarios = @{$scenario_ref};
 
1555
  my $tb = GetMilli();
 
1556
  my $filename = "retrans.dat";
 
1557
  my @n = ();
 
1558
  my $tot = 0;
 
1559
  if (!(-e "sipp_retrans.csv")) {
 
1560
    print("Failed to open sipp_retrans.csv\n");
 
1561
    return;
 
1562
  }
 
1563
  my $a_ref = read_file("sipp_retrans.csv");
 
1564
  my $n_elems = @{$a_ref};
 
1565
 
 
1566
  print("Building retrans with stop=$testStopTime, n=$n_elems\n");  
 
1567
  open (OUT, ">retrans.dat");
 
1568
  # Write to the file for each seconds the nb of retransmit, with 1 column per scenario
 
1569
  $t = 0;
 
1570
  for ($i=0;$i<$n_elems;$i++) {
 
1571
    $t2 = int ($a_ref->[$i][0]/1000);
 
1572
    # Write 0  for the time not printed in the file
 
1573
    for ($t1=$t;$t1<$t2;$t1++) {
 
1574
      print (OUT 1000*$t1.";0;");
 
1575
      for($s=0;$s<$n_scenarios;$s++) {
 
1576
        print (OUT "0;");
 
1577
      }
 
1578
      print (OUT "\n");
 
1579
    }
 
1580
    for ($s=0;$s<@{$rtd_ref};$s++) {
 
1581
      $n[$rtd_ref->[$s][1]] = 0;
 
1582
    }
 
1583
    $n[$a_ref->[$i][1]] = $a_ref->[$i][2]+ $a_ref->[$i][3];
 
1584
    $tot = $a_ref->[$i][2]+ $a_ref->[$i][3];
 
1585
    while(($i+1<$n_elems) && (int($a_ref->[$i+1][0]/1000) == $t2)) {
 
1586
      $i++;
 
1587
      $n[$a_ref->[$i][1]] += $a_ref->[$i][2] + $a_ref->[$i][3];
 
1588
      $tot+= $a_ref->[$i][2] + $a_ref->[$i][3];
 
1589
    }
 
1590
    print (OUT 1000*$t2.";$tot;");
 
1591
    for($s=0;$s<$n_scenarios;$s++) {
 
1592
      if (defined $n[$s]) {
 
1593
        print (OUT $n[$s].";");
 
1594
      } else {
 
1595
        print (OUT "0;");
 
1596
      }
 
1597
    }
 
1598
    print (OUT "\n");
 
1599
    $t = $t2+1;
 
1600
  }
 
1601
  while ($t <= $testStopTime) {
 
1602
    print (OUT 1000*$t.";0;");
 
1603
    for($s=0;$s<$n_scenarios;$s++) {
 
1604
      print (OUT "0;");
 
1605
    }
 
1606
    print (OUT "\n");
 
1607
    $t++;
 
1608
  }
 
1609
  $ColumnRetrans{""} = 2; # 1 as gnuplot starts with 1; 1 for time
 
1610
  for ($i=0;$i<@{$rtd_ref};$i++) {
 
1611
    $ColumnRetrans{$rtd_ref->[$i][4]} = $rtd_ref->[$i][1]+3; # 1 as gnuplot starts with 1; 1 for time. 1 for All scenarios grouped.
 
1612
  }
 
1613
  if (close(OUT) <= 0) {
 
1614
    print("Error closing file: $!\n");
 
1615
    exit(0);
 
1616
  }
 
1617
  push (@TempFiles, $filename);
 
1618
  $t_buildretrans = GetMilli() - $tb;
 
1619
  printf("Build retransmit from sipp.csv took %.2f sec\n", $t_buildretrans/1000);
 
1620
}
 
1621
 
 
1622
sub GetMetricName
 
1623
{
 
1624
  my ($rtd_ref, $id) = @_;
 
1625
  for (my $i=0;$i<@{$rtd_ref};$i++) {
 
1626
    my $metric_name = $rtd_ref->[$i][0];
 
1627
    my $metric_id = $rtd_ref->[$i][2];
 
1628
    if ($id == $rtd_ref->[$i][2]) {
 
1629
      print("id=$id, metric=$metric_name\n");
 
1630
      return $metric_name;
 
1631
    }
 
1632
  }
 
1633
  return;
 
1634
}
 
1635
 
 
1636
sub BuildFromSipp
 
1637
{
 
1638
  my ($rtd_ref, $scenario_ref, $steps_ref) = @_;
 
1639
  my (@allMetricNames, @allUseCaseNames);
 
1640
  my $n_scenarios = @{$scenario_ref};
 
1641
  my %file, my @file, my %uc_file;
 
1642
  my ($i, $j, $tn, $t0, $s, $int_time, $fh, $testStopTime, $t_init, @uid, $filename);
 
1643
  my @SAPS = (); my @Failures = (); my @IHS = ();
 
1644
  my %uc_table, my %m_uc_table;
 
1645
  my ($n_metrics, $n_per_scen_metrics, $n_per_uc_metrics);
 
1646
  my $metric_name;
 
1647
 
 
1648
  my $t_b = GetMilli();
 
1649
 
 
1650
  $| = 1;  # Unbufferred output so we can show progress bar
 
1651
 
 
1652
  for ($i=0;$i<@{$rtd_ref};$i++) {
 
1653
    $metric_name = $rtd_ref->[$i][0];
 
1654
    my $scenario_name = $rtd_ref->[$i][4];
 
1655
    my $use_case = $rtd_ref->[$i][5];
 
1656
    my $sc_id = $rtd_ref->[$i][1];
 
1657
    my $metric_id = $rtd_ref->[$i][2];
 
1658
    $allMetricNames[$sc_id][$metric_id] = $metric_name;
 
1659
    $allUseCaseNames[$sc_id] = $use_case;
 
1660
    $filename = ">$metric_name"."_$scenario_name.dat";    
 
1661
    $ColumnSAPS{$rtd_ref->[$i][4]} = $rtd_ref->[$i][1]+3; # 1 as gnuplot starts with 1; 1 for time. 1 for All scenarios grouped.
 
1662
    my $el = {s_id => $sc_id, m_id => $metric_id, s_name => $scenario_name, m_name => $metric_name};
 
1663
    push @{$MetricTable{$metric_name}}, $el;    
 
1664
    push @{$uc_table{$use_case}}, $el;    
 
1665
    push @{$m_uc_table{$metric_name}{$use_case}}, $el;    
 
1666
  }
 
1667
  
 
1668
  $n_metrics = keys %MetricTable;
 
1669
  $n_per_scen_metrics = 0;
 
1670
  $n_per_uc_metrics = 0;
 
1671
 
 
1672
  # Create scenario_id to use_case_id array. This will be used in the "big loop" to quickly find the use_case_id.
 
1673
  my $use_case_id = 0;
 
1674
  for ($s=0;$s<$n_scenarios;$s++) {
 
1675
    $uid[$s] = 0;
 
1676
  }
 
1677
  foreach my $uc (sort keys %uc_table) {
 
1678
    foreach my $el (@{$uc_table{$uc}}) {
 
1679
      $uid[$el->{s_id}] = $use_case_id;
 
1680
    }
 
1681
    $use_case_id++;    
 
1682
  }
 
1683
  my $n_use_cases = $use_case_id;
 
1684
 
 
1685
  # Open metric related files - metric per scenario, and general metric
 
1686
  foreach my $metric_name (sort keys %MetricTable) {
 
1687
    $filename = ">$metric_name.dat";
 
1688
    push (@TempFiles, $filename);
 
1689
    open $file{$metric_name}, $filename;
 
1690
    print("File=$filename, Name=>$metric_name, m_id=>".$MetricTable{$metric_name}->[0]->{m_id}."\n");
 
1691
    my @per_scenario = @{$MetricTable{$metric_name}};
 
1692
    if (@per_scenario > 1) {
 
1693
      # We also need per scenario metric
 
1694
      $n_per_scen_metrics++;
 
1695
      foreach my $el (@per_scenario) {
 
1696
        $filename = ">$metric_name"."_$el->{s_name}.dat";
 
1697
        push (@TempFiles, $filename);
 
1698
        open $file[$el->{s_id}][$el->{m_id}], $filename;
 
1699
        print("File=$filename, Name=>$metric_name, m_id=>$el->{m_id}, " .
 
1700
              "scenario_name=>$el->{s_name} , s_id=>$el->{s_id}, uid = $uid[$el->{s_id}]\n");
 
1701
      }
 
1702
    }
 
1703
  }
 
1704
  $n_per_uc_metrics = 0;
 
1705
  foreach my $metric (keys %m_uc_table) {
 
1706
    foreach my $use_case (keys %{$m_uc_table{$metric}}) {
 
1707
      foreach my $el (@{$m_uc_table{$metric}{$use_case}}) {
 
1708
        $ColumnSAPS{$use_case} = $n_scenarios + 3 + $uid[$el->{s_id}];
 
1709
        if (@{$m_uc_table{$metric}{$use_case}} >  1) {
 
1710
          $n_per_uc_metrics++;
 
1711
          $filename = ">$metric"."_".$use_case.".dat";
 
1712
          push (@TempFiles, $filename);
 
1713
          open $uc_file{$metric}{$use_case}, $filename;
 
1714
          print("File=$filename, Name=>$metric, m_id=>$el->{m_id}, scenario_name=>$el->{s_name}, " .
 
1715
                "s_id=>$el->{s_id}, uid = $uid[$el->{s_id}]\n");
 
1716
        }
 
1717
      }
 
1718
    }
 
1719
  }
 
1720
  $ColumnSAPS{""} = 2; # 1 as gnuplot starts with 1; 1 for time
 
1721
 
 
1722
  print("$n_metrics metrics in total; $n_use_cases use cases\n");
 
1723
  print("$n_per_scen_metrics 'per scenario' metrics\n");
 
1724
  print("$n_per_uc_metrics 'per use case' metrics\n");
 
1725
 
 
1726
  open(DELAYSAPS, ">DELAY-SAPS.dat");
 
1727
  push (@TempFiles, "DELAY-SAPS.dat");
 
1728
  
 
1729
  if (!(-e "sipp.csv")) {
 
1730
    print("Failed to open sipp.csv - exiting\n");
 
1731
    exit(1);
 
1732
  }
 
1733
 
 
1734
  # Do not load the whole sipp.csv in memory, as can be very big...  
 
1735
  my $file = "sipp.csv";
 
1736
  my @data = ();
 
1737
  my ($t1, $t2);
 
1738
  
 
1739
  $t1 = GetMilli();
 
1740
  
 
1741
  open(DATA, "<$file");
 
1742
  my $first_line = <DATA>;
 
1743
  ($t0) = split(/[;]/, $first_line);
 
1744
  
 
1745
  my $pos = -3;
 
1746
  my $char = "";
 
1747
  while($char ne "\n") {
 
1748
    seek(DATA, $pos, SEEK_END);
 
1749
    read(DATA, $char, 1);
 
1750
    $pos--;
 
1751
  }
 
1752
  my $last_line = <DATA> ;
 
1753
  ($tn) = split(/[;]/, $last_line);
 
1754
 
 
1755
  seek(DATA, 0, SEEK_SET);
 
1756
 
 
1757
  my $n_steps = @{$steps_ref};
 
1758
  $t_init = $t0 - 1000 * int($t0/1000);
 
1759
 
 
1760
  $j = 0;
 
1761
  $i = 0;
 
1762
 
 
1763
  $testStopTime = int($tn/1000);
 
1764
 
 
1765
  Initialize(\@SAPS, $testStopTime+1, $n_scenarios+2+$n_use_cases);
 
1766
  Initialize(\@IHS, $testStopTime+1, $n_scenarios+2+$n_use_cases);
 
1767
  Initialize(\@Failures, $testStopTime+1, $n_scenarios+2+$n_use_cases);
 
1768
  Initialize(\@TotSAPS, $n_scenarios+2+$n_use_cases, $n_steps);
 
1769
  Initialize(\@TotFailures, $n_scenarios+2+$n_use_cases, $n_steps);
 
1770
  
 
1771
  # Make sure we have same number of lines in saps and failures, ihs...  
 
1772
  # Otherwise, if IHS of last measure is 0, could be skipped, hence resulting in bad IHS.
 
1773
  $Failures[int($tn/1000)][0] = 0;  
 
1774
 
 
1775
  while(<DATA>) {
 
1776
    @data = split /[;]/;
 
1777
  
 
1778
    # Skip measures before start time if any
 
1779
    if ($data[0] >= $steps_ref->[$j]->{start_time}) {
 
1780
      last;
 
1781
    }
 
1782
    printf("Skipping first data\n");    
 
1783
  }
 
1784
 
 
1785
  printf("Now looking at step $j...");
 
1786
  my ($t, $sc_id);
 
1787
  my $in_prereg = $steps_ref->[$j]->{prereg};
 
1788
  LOOP:
 
1789
  while(<DATA>) {
 
1790
    ($t, $sc_id, @data) = split /[;]/;
 
1791
 
 
1792
    while ($t > $steps_ref->[$j]->{stop_time}) {
 
1793
      $j++;
 
1794
      
 
1795
      if ($j >= @{$steps_ref}) {
 
1796
        print("\nData after last step - skipping");
 
1797
        last LOOP;
 
1798
      }
 
1799
      printf("$j...");
 
1800
 
 
1801
      # Metrics
 
1802
      if (($steps_ref->[$j]->{report} == 1) || ($in_prereg != $steps_ref->[$j]->{prereg})) {
 
1803
        # Put an empty line in gnuplot data files so Bezier curves stop in between consecutive steps
 
1804
        # This avoids that the Bezier for data in step n is influenced by the last data points in step n-1
 
1805
        foreach my $sc_ref (@file) {
 
1806
          foreach my $ffh (@{$sc_ref}) {
 
1807
            print($ffh "\n") if (defined $ffh);
 
1808
          }
 
1809
        }
 
1810
        foreach $metric_name (keys %file) {
 
1811
          $fh = $file{$metric_name};
 
1812
          print $fh "\n" if (defined $fh);
 
1813
        }
 
1814
        foreach $metric_name (keys(%uc_file)) {
 
1815
          foreach my $use_case_name (keys( %{$uc_file{$metric_name}} )) {
 
1816
            $fh = $uc_file{$metric_name}{$use_case_name};
 
1817
            print($fh "\n") if (defined $fh);
 
1818
          }
 
1819
        }
 
1820
      }
 
1821
      $in_prereg = $steps_ref->[$j]->{prereg};
 
1822
 
 
1823
      # Skipping data between stop_time and start_time
 
1824
      if ($t < $steps_ref->[$j]->{start_time}) {
 
1825
        #printf("\nskipping data after stop_time (step ".($j-1).") and before start_time (step $j)\n");
 
1826
        next LOOP;
 
1827
      }
 
1828
      $t0 = $t;
 
1829
    }
 
1830
    $int_time = int(($t-$t_init)/1000);
 
1831
    # SAPS
 
1832
    $SAPS[$int_time][$sc_id+1]++;
 
1833
    if (($t >= $steps_ref->[$j]->{ihs_start_time}) && ($t <= $steps_ref->[$j]->{ihs_stop_time})) {
 
1834
      $TotSAPS[$sc_id+1][$j]++;
 
1835
    }
 
1836
    # DELAY-SAPS
 
1837
    print (DELAYSAPS "$t;", $t-$t0."\n");
 
1838
    $t0 = $t;
 
1839
    # IHS
 
1840
    if ($data[0] != 1) {
 
1841
      $Failures[$int_time][$sc_id+1]++;
 
1842
      if (($t >= $steps_ref->[$j]->{ihs_start_time}) && ($t <= $steps_ref->[$j]->{ihs_stop_time})) {
 
1843
        $TotFailures[$sc_id+1][$j]++;
 
1844
      }
 
1845
    }
 
1846
    # Metrics
 
1847
    for (my $k=1;$k<@data;$k++){
 
1848
      if (defined $data[$k]) {
 
1849
        $fh = $file[$sc_id][$k-1];
 
1850
        print($fh "$t;$data[$k]\n") if (defined $fh);
 
1851
 
 
1852
        $metric_name = $allMetricNames[$sc_id][$k-1];
 
1853
        if (defined $metric_name) {
 
1854
          $fh = $file{$metric_name};
 
1855
          print($fh "$t;$data[$k]\n") if (defined $fh);
 
1856
 
 
1857
          my $use_case_name = $allUseCaseNames[$sc_id];
 
1858
          $fh = $uc_file{$metric_name}{$use_case_name};
 
1859
          print($fh "$t;$data[$k]\n") if (defined $fh);
 
1860
        }
 
1861
      }
 
1862
    }
 
1863
  }
 
1864
  close (DATA);
 
1865
  print("\n");
 
1866
  
 
1867
  # Calculate Total SAPS and Failures, adding all scenarios
 
1868
  for ($t=0;$t<=$testStopTime;$t++) {
 
1869
    for ($s=0;$s<$n_scenarios;$s++) {
 
1870
      $SAPS[$t][0] += $SAPS[$t][$s+1];
 
1871
      $SAPS[$t][$n_scenarios+$uid[$s]+1] += $SAPS[$t][$s+1];
 
1872
      $Failures[$t][0] += $Failures[$t][$s+1];
 
1873
      $Failures[$t][$n_scenarios+$uid[$s]+1] += $Failures[$t][$s+1];
 
1874
    }
 
1875
  }
 
1876
 
 
1877
  # Calculate Total SA and Failures per steps, adding all scenarios
 
1878
  for ($j=0;$j<@{$steps_ref};$j++) {
 
1879
    for ($s=0;$s<$n_scenarios;$s++) {
 
1880
      $TotSAPS[0][$j] += $TotSAPS[$s+1][$j];
 
1881
      $TotSAPS[$n_scenarios+$uid[$s]+1][$j] += $TotSAPS[$s+1][$j];
 
1882
      $TotFailures[0][$j] += $TotFailures[$s+1][$j];
 
1883
      $TotFailures[$n_scenarios+$uid[$s]+1][$j] += $TotFailures[$s+1][$j];
 
1884
    }
 
1885
  }
 
1886
  
 
1887
  for ($i=0;$i<@Failures;$i++) {
 
1888
    for ($j=0;$j<$n_scenarios+1+$n_use_cases;$j++) {
 
1889
      if ($SAPS[$i][$j] && $Failures[$i][$j]) {
 
1890
        $IHS[$i][$j] = 100 * ($Failures[$i][$j] / $SAPS[$i][$j]);
 
1891
      } else {
 
1892
        $IHS[$i][$j] = 0;
 
1893
      }
 
1894
    }
 
1895
  }
 
1896
  
 
1897
  for ($i=0;$i<@{$rtd_ref};$i++) {
 
1898
    my $sc_id = $rtd_ref->[$i][1];
 
1899
    my $m_id = $rtd_ref->[$i][2];
 
1900
    $fh = $file[$sc_id][$m_id];
 
1901
    if (defined $fh) {
 
1902
      if (close($fh) <= 0) {
 
1903
        print("Error closing file: $!\n");
 
1904
        exit(0);
 
1905
      }
 
1906
    } 
 
1907
    $metric_name = $allMetricNames[$sc_id][$m_id];
 
1908
    $fh = $file{$metric_name};
 
1909
    if (defined $fh) {
 
1910
      if (close($fh) <= 0) {
 
1911
        print("Error closing file $fh: $!\n");
 
1912
        exit(0);
 
1913
      }
 
1914
      $file{$metric_name} = undef;
 
1915
    } 
 
1916
  }
 
1917
  
 
1918
  print_ref("SAPS.dat", \@SAPS, $n_scenarios+1+$n_use_cases, 1000, $steps_ref);
 
1919
  print_ref("IHS.dat", \@IHS, $n_scenarios+1+$n_use_cases, 1000, $steps_ref);
 
1920
  print_ref("Failures.dat", \@Failures, $n_scenarios+1+$n_use_cases, 1000, $steps_ref);
 
1921
  
 
1922
  $t_buildsipp = GetMilli() - $t_b;
 
1923
  printf("Building Temporary Files from sipp.csv took %.2f s\n", $t_buildsipp/1000);
 
1924
  return $testStopTime;
 
1925
}
 
1926
 
 
1927
sub Initialize
 
1928
{
 
1929
  my ($arr_ref, $x, $y) = @_;
 
1930
  my ($t, $s);
 
1931
  for ($t=0;$t<$x;$t++) {
 
1932
    for ($s=0;$s<$y;$s++) {
 
1933
      $arr_ref->[$t][$s] = 0;
 
1934
    }
 
1935
  }
 
1936
}
 
1937
 
 
1938
sub BuildExpo
 
1939
{
 
1940
  my ($steps_ref, $config) = @_;
 
1941
  my ($i, $k, $lambda, $max, $minlambda);
 
1942
  my @e = ();
 
1943
  my @q = ();
 
1944
      
 
1945
  $minlambda = $steps_ref->[0]->{cps};            
 
1946
  for ($i=1;$i<@{$steps_ref};$i++) {
 
1947
    $lambda = $steps_ref->[$i]->{cps};      
 
1948
    if ($lambda < $minlambda) {
 
1949
      $minlambda = $lambda
 
1950
    }
 
1951
  }
 
1952
  for ($i=0;$i<@{$steps_ref};$i++) {
 
1953
    $lambda = $steps_ref->[$i]->{cps};
 
1954
    $max = 10000 / $minlambda; # So that min value divided by max value below 1e-4
 
1955
    $q[0][$i] = 1;
 
1956
    for ($k=0;$k<$max;$k++) {
 
1957
      $e[$k][$i] = exp(-$lambda * ($k) / 1000) - exp(-$lambda * ($k+1) / 1000); 
 
1958
      $q[$k][$i] = exp(-$lambda * $k / 1000);
 
1959
    }
 
1960
  }
 
1961
  print_histograms("expo.dat", \@e, $steps_ref, 1, 1);
 
1962
  print_histograms("expo-hist.dat", \@q, $steps_ref, 1, 1);
 
1963
}
 
1964
 
 
1965
sub BuildPoisson
 
1966
{
 
1967
  my ($steps_ref, $config) = @_;
 
1968
  my ($i, $k, $lambda, $max);
 
1969
  my @p = (); my @q = ();
 
1970
  my $maxlambda = 0;
 
1971
 
 
1972
  for ($i=0;$i<@{$steps_ref};$i++) {
 
1973
    $lambda = $steps_ref->[$i]->{cps};
 
1974
    if ($lambda > $maxlambda) {
 
1975
      $maxlambda = $lambda;
 
1976
    }
 
1977
  }
 
1978
  $max = 2*$maxlambda + 200;
 
1979
     
 
1980
  for ($i=0;$i<@{$steps_ref};$i++) {
 
1981
    $lambda = $steps_ref->[$i]->{cps};        
 
1982
    if ($steps_ref->[$i]->{distribution} ne "poisson") {    
 
1983
      for ($k=0;$k<=$max;$k++) {
 
1984
        $p[$k][$i] = 0;
 
1985
        $q[$k][$i] = 0;
 
1986
      }
 
1987
    } else {
 
1988
      $p[0][$i] = exp(-$lambda);
 
1989
      my $temp = 1;
 
1990
      $q[0][$i] = 1;
 
1991
      my $div = 50;
 
1992
      my $mult = 0;
 
1993
      for ($k=1;$k<=$max;$k++) {
 
1994
        $temp = $temp * $lambda / $k;
 
1995
        $p[$k][$i] = $temp * exp(-($lambda / $div * ($div - $mult)));
 
1996
        if (($k >= $lambda*$mult/$div) && ($mult < $div)){
 
1997
          $temp = $temp * exp(-$lambda / $div);
 
1998
          $mult++;
 
1999
        }
 
2000
        $q[$k][$i] = $q[$k-1][$i] - $p[$k-1][$i];
 
2001
      }
 
2002
    }
 
2003
  }
 
2004
  
 
2005
  print_histograms("poisson.dat", \@p, $steps_ref, 1, 1);
 
2006
  print_histograms("poisson-hist.dat", \@q, $steps_ref, 1, 1);
 
2007
}
 
2008
 
 
2009
sub do_appendix
 
2010
{
 
2011
  my ($xmlData, $reportConfig, $ims_bench) = @_;
 
2012
  my ($i);
 
2013
  my $config = $xmlData->{configuration};
 
2014
 
 
2015
  $Report->{appendix} .= AddHref(3, "Appendix", "Appendix");
 
2016
 
 
2017
  if (defined $ims_bench) {
 
2018
    $Report->{appendix} .= "<p>The test was run based on the following IMS benchmark parameters.</p>\n";
 
2019
    $Report->{appendix} .=  "<table border=\"1\">\n";
 
2020
    $Report->{appendix} .=  "<tr class=\"table_title\"><th>Parameter Name<th>Parameter Value<th>Parameter Info</tr>\n";
 
2021
    # Traffic_time_profile
 
2022
    my @all_profiles = keys %{$ims_bench};
 
2023
    foreach my $profile (@all_profiles) {
 
2024
      my @all_var = keys %{$ims_bench->{$profile}->{param}};
 
2025
      foreach my $var (@all_var) {
 
2026
        $Report->{appendix} .= "<tr><td>$var</td><td>";
 
2027
        $Report->{appendix} .= $ims_bench->{$profile}->{param}->{$var}->{value} . "</td><td>\n";
 
2028
        if (defined($ims_bench->{$profile}->{param}->{$var}->{info})) {
 
2029
          $Report->{appendix} .= $ims_bench->{$profile}->{param}->{$var}->{info};
 
2030
        }
 
2031
        else {
 
2032
          $Report->{appendix} .= "&nbsp;";
 
2033
        }
 
2034
        $Report->{appendix} .= "</tr>\n";
 
2035
      }
 
2036
    }
 
2037
    $Report->{appendix} .= "</table>\n";
 
2038
  }
 
2039
  $Report->{appendix} .= "<p><br>The following information is also available for the test</p>";
 
2040
  $Report->{appendix} .= "<table border=\"1\">\n";
 
2041
  $Report->{appendix} .= "<tr class=\"table_title\"><th>Parameter Name<th>Parameter Value<th>Parameter Info</tr>\n";
 
2042
  $Report->{appendix} .= "<tr><td>rand_seed</td><td>$config->{param}->{rand_seed}->{value}</td>\n";
 
2043
  $Report->{appendix} .= " <td>Value used to initialize the random number generators</td></tr>\n";
 
2044
  $Report->{appendix} .= "<tr><td>prep_offset</td><td>$config->{param}->{prep_offset}->{value}</td>\n";
 
2045
  $Report->{appendix} .= " <td>Time (ms) for scenario preparation (user reservation, etc.) prior to actual execution</td></tr>\n";
 
2046
  $Report->{appendix} .= "<tr><td>highest_measured_time_offset</td>\n";
 
2047
  $Report->{appendix} .= " <td>$config->{param}->{highest_measured_time_offset}->{value}</td>\n";
 
2048
  $Report->{appendix} .= " <td>Highest time offset observed at startup between any test system and the manager (microseconds)</td></tr>\n";
 
2049
  $Report->{appendix} .= "</table>\n<br>\n";
 
2050
  
 
2051
  $Report->{appendix} .=  "<table border=\"1\">\n";
 
2052
  $Report->{appendix} .=  "<tr class=\"table_title\"><th>System<th>Command Line</tr>\n";
 
2053
  for ($i=0; $i < 100; $i++) {
 
2054
    my $name = "TS$i";
 
2055
    my $system = $config->{system}->{$name};
 
2056
    if (defined($system)) {
 
2057
      $Report->{appendix} .= "<tr><td>$name</td><td>$system->{cmdline}</td></tr>\n";
 
2058
    }
 
2059
  }
 
2060
  my $manager = $xmlData->{manager}->{system}->[0];
 
2061
  $Report->{appendix} .= "<tr><td>Manager</td><td>".$manager->{cmdline}."</td></tr>\n";
 
2062
  if (defined $xmlData->{remote}->{system}) {
 
2063
    my $n_SUT = @{$xmlData->{remote}->{system}};
 
2064
    for ($i=0; $i < $n_SUT; $i++) {
 
2065
      $Report->{appendix} .= "<tr><td>SUT ".(1+$i)."</td><td>".$xmlData->{remote}->{system}->[$i]->{cmdline}."</td></tr>\n";
 
2066
    }  
 
2067
  }
 
2068
  $Report->{appendix} .=  "</table>\n";
 
2069
}
 
2070
 
 
2071
############################################################################################
 
2072
# Write the html file
 
2073
# INPUT 1: xml configuration file name
 
2074
# OUTPUT : none
 
2075
############################################################################################
 
2076
sub do_report
 
2077
{
 
2078
  my ($xmlData, $reportConfig, $rtd_ref, $scenario_ref, $ims_bench) = @_;
 
2079
  my $config = $xmlData->{configuration};
 
2080
    
 
2081
  my ($Filename, $Filename2, $i, $datafile, $s);
 
2082
 
 
2083
  $xmlData->{data}->{info}->{start_time}->{content} =~ /([0-9]*)-([0-9]*)-([0-9]*)\s*([0-9]*):([0-9]*).*/;
 
2084
  $Report->{date} = "$3-".$Month[$2-1]."-$1 $4:$5";
 
2085
  print "Test Date: ".$Report->{date}."\n";
 
2086
 
 
2087
  my $runtime = $xmlData->{data}->{info}->{run_time}->{value} / 1000;
 
2088
  print ("Test Duration: $runtime\n");
 
2089
 
 
2090
  my ($n_SUT, $ip, @sipp_server_name);
 
2091
  $n_SUT = 0;
 
2092
  if (defined $xmlData->{remote}->{system}) {
 
2093
    $n_SUT = @{$xmlData->{remote}->{system}};
 
2094
  }
 
2095
  print("Number of SUTs: $n_SUT\n");
 
2096
  my $sut_list = "";
 
2097
  for ($i=0; $i<$n_SUT; $i++) {
 
2098
    $sut_list .= ", " if ($i > 0);
 
2099
    $sut_list .= $xmlData->{remote}->{system}->[$i]->{server};
 
2100
  }
 
2101
  $Report->{title} = "Test Report ($sut_list)";
 
2102
 
 
2103
  # Test Systems Info
 
2104
  $report_test_info .= "\n<p>The following systems and parameters were used for the test. ";
 
2105
  if (defined $ims_bench) {
 
2106
    $report_test_info .= "The full list of IMS benchmark parameters can be found in <a href=\"#Appendix\">Appendix</a>.\n";
 
2107
  }
 
2108
  $report_test_info .= "<table cellspacing=\"20\" ><tr><td vAlign=top>\n";
 
2109
  $report_test_info .= "<table border=\"1\">\n";
 
2110
  $report_test_info .= "<tr class=\"table_title\"><th>Role</th><th>Server</th><th>IP</th><th>Nb Users</th></tr>\n";
 
2111
  for ($i=0; $i < $n_SUT; $i++) {
 
2112
    $ip = $xmlData->{remote}->{system}->[$i]->{ip};  
 
2113
    if (defined $ip) {
 
2114
      $report_test_info .= "<tr><td>SUT ".(1+$i)."</td><td>".$xmlData->{remote}->{system}->[$i]->{server}."</td><td>".($ip)."</td><td>&nbsp</td></tr>\n";
 
2115
    } else {
 
2116
      $report_test_info .= "<tr><td>SUT ".(1+$i)."</td><td>".$xmlData->{remote}->{system}->[$i]->{server}."</td><td>&nbsp</td><td>&nbsp</td></tr>\n";
 
2117
    }
 
2118
  }
 
2119
  my $manager = $xmlData->{manager};
 
2120
  my @pids;
 
2121
  ($ip = $manager->{system}->[0]->{ip}) =~ /IP4:([^:]*)/;  
 
2122
  $report_test_info .= "<tr><td>Manager</td><td>".$manager->{system}->[0]->{server}."</td><td>".$1."</td><td>&nbsp</td></tr>\n";
 
2123
  $config->{numTS} = 0;
 
2124
  for ($i=0; $i < 100; $i++) {
 
2125
    my $name = "TS$i";
 
2126
    if ($config->{system}->{$name}) {
 
2127
      my $system = $config->{system}->{$name};
 
2128
      $ip = $system->{ip};
 
2129
      $report_test_info .= "<tr><td>$name</td><td>$system->{server}</td><td>$ip</td><td>$system->{users}</td></tr>\n";
 
2130
      push(@pids, $system->{id});
 
2131
      push(@sipp_server_name, $system->{server});
 
2132
      $config->{numTS}++;
 
2133
    }
 
2134
  }
 
2135
  print "Number of Test Systems: $config->{numTS}\n";
 
2136
  $report_test_info .=  "</table>\n";
 
2137
  $report_test_info .=  "</td>\n<td vAlign=top><table border=\"1\">\n";
 
2138
  $report_test_info .=  "<tr class=\"table_title\"><th>Parameter Name</th><th>Parameter Value</th><th>Parameter Info</th></tr>\n";
 
2139
  $report_test_info .=  "<tr><td>RingTime<td>$config->{scen_param}->{RingTime}->{value}<td>Ringing Time (ms)</tr>\n";
 
2140
  $report_test_info .=  "<tr><td>HoldTime</td><td>$config->{scen_param}->{HoldTime}->{value}<td>Conversation Time (ms)</tr>\n";
 
2141
  if (defined($config->{scen_param}->{RegistrationExpire})) {
 
2142
    $report_test_info .=  "<tr><td>RegistrationExpire<td>$config->{scen_param}->{RegistrationExpire}->{value}<td>Registration Timeout (ms)</tr>\n";
 
2143
  }
 
2144
  $report_test_info .=  "<tr><td>TransientTime<td>".(($config->{param}->{transient_time}->{value})/1000)."<td>Time after the start of a step for which data is ignored (in seconds)</tr>\n";
 
2145
  $report_test_info .=  "</table></td></tr></table>\n";
 
2146
  $report_test_info .= "</p>";
 
2147
 
 
2148
  # Quick preliminary analyzis of the steps to classify them as pre-registration steps, real
 
2149
  # steps, etc. and flag them as to be reported or not, etc.
 
2150
  my $run = $xmlData->{run};
 
2151
  my $stepDef = $xmlData->{data}->{step};
 
2152
  my $r = 0;
 
2153
  my $n_steps;
 
2154
  my $step_display_number = 1; # Step number as displayed (steps with report="no" are not displayed as actual steps)
 
2155
  while ($$run[$r]) {
 
2156
    $s=0;
 
2157
    while ($$stepDef[$s]) {
 
2158
      if ($$stepDef[$s]->{run} == $r) {
 
2159
        my $step = $stepDef->[$s];
 
2160
        $step->{show_in_tables} = 1;
 
2161
        $step->{report} = 1;
 
2162
        $step->{show_histograms} = 1;
 
2163
        $step->{prereg} = 0;
 
2164
        $step->{step_number} = 0;
 
2165
        $step->{over_ihs} = 0;
 
2166
        $step->{is_doc_step} = 0;
 
2167
        $step->{label} = "";
 
2168
 
 
2169
        if ( defined($reportConfig->{DisplayConstantHistograms}) &&
 
2170
             ($reportConfig->{DisplayConstantHistograms} == 0) &&
 
2171
             (defined($step->{distribution}) && ($step->{distribution} eq "constant")) ) {
 
2172
          $step->{report} = 0;
 
2173
          $step->{show_histograms} = 0;
 
2174
        } elsif ((defined $reportConfig->{DisplayFailureStepHistograms}) &&
 
2175
                 ($reportConfig->{DisplayFailureStepHistograms} == 0) &&
 
2176
                 (defined $step->{failure}) && ($step->{failure} > 0)) {
 
2177
          $step->{show_histograms} = 0;
 
2178
        } elsif ($$run[$r]->{report} eq "no") {
 
2179
          $step->{report} = 0;
 
2180
          $step->{show_in_tables} = 0;
 
2181
          $step->{show_histograms} = 0;
 
2182
        }
 
2183
 
 
2184
        if (($r == 0) && ($$run[$r]->{sync_mode} eq "off")) {
 
2185
          # We consider the first run with a sync_mode Off to be a Pre-registration phase
 
2186
          $step->{prereg} = 1;
 
2187
          $step->{label} = "pre-reg";
 
2188
        }
 
2189
 
 
2190
        if ($stepDef->[$s]->{report} == 1) {
 
2191
          $stepDef->[$s]->{step_number} = $step_display_number++;
 
2192
          $stepDef->[$s]->{label} = "step ".$stepDef->[$s]->{step_number};
 
2193
        }
 
2194
 
 
2195
      }
 
2196
      $s++;
 
2197
    }
 
2198
    $n_steps = $s;
 
2199
    $r++;
 
2200
  }
 
2201
  print "Number of steps: $n_steps\n";
 
2202
 
 
2203
  my $testStopTime = BuildFromSipp($rtd_ref, $scenario_ref, $stepDef);
 
2204
  BuildRetrans($rtd_ref, $scenario_ref, $testStopTime);
 
2205
  BuildCPUMEM($xmlData, $stepDef);
 
2206
  BuildSippCPU($xmlData, $stepDef);
 
2207
 
 
2208
  # Remove empty steps at the end of a run
 
2209
  my ($saps_ref, $failure_ref);
 
2210
  $saps_ref = $TotSAPS[0];
 
2211
  for ($s=$n_steps-1; $s>=0; $s--) {
 
2212
    if ($saps_ref->[$s] == 0) {
 
2213
      $stepDef->[$s]->{report} = 0;
 
2214
      $stepDef->[$s]->{show_in_tables} = 0;
 
2215
      $stepDef->[$s]->{show_histograms} = 0;
 
2216
    } else {
 
2217
      last;
 
2218
    }
 
2219
  }
 
2220
 
 
2221
  # Flag which steps are over IHS threshold
 
2222
  for (my $k=0;$k<@{$scenario_ref};$k++) {
 
2223
    my $scen_max_ihs = $config->{scenario}->{$scenario_ref->[$k]}->{max_ihs};
 
2224
    $failure_ref = $TotFailures[$k+1];
 
2225
    $saps_ref = $TotSAPS[$k+1];
 
2226
#printf "scenario %i '%s'\tmax_ihs=%.2f\n", $k, $scenario_ref->[$k], $scen_max_ihs;
 
2227
    for ($s=0; $s<$n_steps; $s++) {
 
2228
      my $max_ihs = $scen_max_ihs;
 
2229
      if (   defined($run->[$stepDef->[$s]->{run}]->{use_scen_max_ihs})
 
2230
          && ($run->[$stepDef->[$s]->{run}]->{use_scen_max_ihs} eq "no")
 
2231
          && defined($run->[$stepDef->[$s]->{run}]->{max_global_ihs}) ) {
 
2232
        $max_ihs = $run->[$stepDef->[$s]->{run}]->{max_global_ihs};
 
2233
      }
 
2234
      if (($saps_ref->[$s]) && ($failure_ref->[$s] / $saps_ref->[$s] * 100 >= $max_ihs)) {
 
2235
        $stepDef->[$s]->{over_ihs} = 1;
 
2236
      }
 
2237
#printf "\tstep %i\tsaps=%5i fail=%5i ihs=%.2f\trun=%i use_scen_max_ihs=%3s max_global_ihs=%.2f\tover_ihs=%i\n", $s, $saps_ref->[$s], $failure_ref->[$s], ($saps_ref->[$s] ? ($failure_ref->[$s] / $saps_ref->[$s] * 100) : 0), $stepDef->[$s]->{run}, $run->[$stepDef->[$s]->{run}]->{use_scen_max_ihs}, (defined($run->[$stepDef->[$s]->{run}]->{max_global_ihs}) ? $run->[$stepDef->[$s]->{run}]->{max_global_ihs} : 0), $stepDef->[$s]->{over_ihs};
 
2238
    }
 
2239
  }
 
2240
 
 
2241
  # Identify the step giving the DOC (benchmark score; highest SAPS)
 
2242
  for ($s=0; $s<$n_steps; $s++) {
 
2243
    if (($s > 0) && ($stepDef->[$s]->{over_ihs} == 1) && ($stepDef->[$s-1]->{over_ihs} == 0)) {
 
2244
      # Previous step was OK, this one is not
 
2245
      $stepDef->[$s-1]->{is_doc_step} = 1;
 
2246
    }
 
2247
  }
 
2248
 
 
2249
  # Start preparing summary table (we'll fill in most data during plot() invocations though)
 
2250
  $Report->{summary_tbl} .= "<table border=\"1\">\n";
 
2251
  $Report->{summary_tbl} .= "<tr class=\"table_title\">";
 
2252
  $Report->{summary_tbl} .= "<th>&nbsp</th>";
 
2253
 
 
2254
  # Column headers in steps summary table
 
2255
  for ($s=0; $s<$n_steps; $s++) {
 
2256
    if ($stepDef->[$s]->{prereg} == 1) {
 
2257
      if ($stepDef->[$s]->{over_ihs} == 1) {
 
2258
        $Report->{summary_tbl} .= "<th class=\"step_ihs\">Pre-registration</th>";
 
2259
      } else {
 
2260
        $Report->{summary_tbl} .= "<th>Pre-registration</th>";
 
2261
      }
 
2262
    }
 
2263
    elsif ($stepDef->[$s]->{report} == 1) {
 
2264
      if ($stepDef->[$s]->{is_doc_step} == 1) {
 
2265
        $Report->{summary_tbl} .= "<th class=\"step_doc\">";
 
2266
      } elsif ($stepDef->[$s]->{over_ihs} == 1) {
 
2267
        $Report->{summary_tbl} .= "<th class=\"step_ihs\">";
 
2268
      } else {
 
2269
        $Report->{summary_tbl} .= "<th>";
 
2270
      }
 
2271
      $Report->{summary_tbl} .= "Step ".$stepDef->[$s]->{step_number}."</th>";
 
2272
    }
 
2273
 
 
2274
    print("Step $s (run $stepDef->[$s]->{run}) report=".$stepDef->[$s]->{report} .
 
2275
          " show_in_tables=".$stepDef->[$s]->{show_in_tables} .
 
2276
          " show_histograms=".$stepDef->[$s]->{show_histograms} .
 
2277
          "\n   doc_step=".$stepDef->[$s]->{is_doc_step} .
 
2278
          " over_ihs=".$stepDef->[$s]->{over_ihs} .
 
2279
          " label=\"".$stepDef->[$s]->{label}."\"\n");
 
2280
  }
 
2281
  $Report->{summary_tbl} .= "</tr>\n";
 
2282
 
 
2283
  $Report->{summary_tbl} .= "<tr><th class=\"step_box\">Requested load</th>"; 
 
2284
  my $first = 1;
 
2285
  for ($i=0;$i<$n_steps;$i++) {
 
2286
    if ($stepDef->[$i]->{show_in_tables} == 1) {
 
2287
      if ($first == 1) {
 
2288
        $Report->{summary_tbl} .= "<td class=\"step_info\">";
 
2289
        $first = 0;
 
2290
      } else {
 
2291
        $Report->{summary_tbl} .= "<td>";
 
2292
      }
 
2293
      $Report->{summary_tbl} .=  $stepDef->[$i]->{cps}."</td>";
 
2294
    }
 
2295
  }
 
2296
  $Report->{summary_tbl} .= "</tr>\n";
 
2297
 
 
2298
  # Table of contents
 
2299
  my ($h3, $h4);
 
2300
  $h3 = 0; $h4 = 0;
 
2301
 
 
2302
  my $yscale = $runtime;
 
2303
  #print Dumper($reportConfig);
 
2304
  if ($reportConfig->{DisplayFailureStep}) {
 
2305
    if ($stepDef->[$n_steps-1]->{stop_time} > $runtime) {
 
2306
      $yscale = $stepDef->[$n_steps-1]->{stop_time} / 1000;
 
2307
      print("Failure step will be displayed: runtime changed from $runtime to $yscale\n");      
 
2308
    } else {
 
2309
      print("Failure step displayed: runtime not changed\n");
 
2310
    }
 
2311
  }
 
2312
  if ($testStopTime < $yscale) {
 
2313
    $yscale = $testStopTime;
 
2314
  }
 
2315
 
 
2316
  # Graphs not part of a use_case like CPU, SAPS or metric covering all use_cases
 
2317
  my $measDef = $reportConfig->{measure};
 
2318
  $i = 0;
 
2319
  my $j = $i;
 
2320
  while ($$measDef[$i]) {
 
2321
    if (!defined $$measDef[$i]->{Ignore}) {
 
2322
      if ($$measDef[$i]->{Title}) {
 
2323
        $Report->{graphs} .= AddHref(3, $$measDef[$i]->{Title}, ($j+1)." $$measDef[$i]->{Title}");
 
2324
        $j++;
 
2325
      }
 
2326
      plot("", "", $$measDef[$i], \@pids, $stepDef, $scenario_ref, $config, $xmlData,
 
2327
           $reportConfig, $yscale, $runtime, 4, $j, \@sipp_server_name);
 
2328
      $h3++;
 
2329
    }
 
2330
    $i++;
 
2331
  }
 
2332
 
 
2333
  # Graphs specific to one use_case; typically metrics or IHS. Note that the metric filename only contains
 
2334
  # the use_case name if the metric was part of multiple use_cases
 
2335
  my @use_cases = keys %{$reportConfig->{use_case}};
 
2336
  my @scenarios = keys %{$config->{scenario}};
 
2337
  my $n_scenarios = @scenarios;
 
2338
  foreach my $use_case (@use_cases) {
 
2339
    #print Dumper($reportConfig->{use_case});
 
2340
    if (!defined $reportConfig->{use_case}->{$use_case}->{Ignore}) {
 
2341
      $Report->{graphs} .= AddHref(3, $use_case, ($h3)." $use_case");
 
2342
      $h4 = 1;
 
2343
      $i = 0;
 
2344
      $measDef = $reportConfig->{use_case}->{$use_case}->{measure};
 
2345
      while ($$measDef[$i]) {
 
2346
        if (!defined $$measDef[$i]->{Ignore}) {
 
2347
          $Report->{graphs} .= AddHref(5, $$measDef[$i]->{Title}, "$h3.$h4 $$measDef[$i]->{Title}");
 
2348
          plot($use_case, "", $$measDef[$i], \@pids, $stepDef, $scenario_ref, $config, $xmlData,
 
2349
               $reportConfig, $yscale, $runtime, 5, "$h3.$h4", \@sipp_server_name);
 
2350
          $h4++;
 
2351
        }
 
2352
        $i++;
 
2353
      }
 
2354
      foreach my $scenario (@scenarios) {
 
2355
        #print("checking $scenario for use_case $use_case\n");
 
2356
        if ($reportConfig->{use_case}->{$use_case}->{scenario}->{$scenario}) {
 
2357
          $i = 0;
 
2358
          $measDef = $reportConfig->{use_case}->{$use_case}->{scenario}->{$scenario}->{measure};
 
2359
          while ($$measDef[$i]) {
 
2360
            if (!defined $$measDef[$i]->{Ignore}) {
 
2361
              $Report->{graphs} .= AddHref(5, "$scenario : ".$$measDef[$i]->{Title},
 
2362
                                        "$h3.$h4 $scenario : $$measDef[$i]->{Title}");
 
2363
              plot($use_case, $scenario, $$measDef[$i], \@pids, $stepDef, $scenario_ref, $config,
 
2364
                   $xmlData, $reportConfig, $yscale, $runtime, 5, "$h3.$h4", \@sipp_server_name);
 
2365
              $h4++;
 
2366
            }
 
2367
            $i++;
 
2368
          }      
 
2369
        }
 
2370
      }
 
2371
      $h3++;
 
2372
    }
 
2373
  }
 
2374
 
 
2375
  $Report->{summary_tbl} .= "</table>\n";
 
2376
  do_appendix($xmlData, $reportConfig, $ims_bench);
 
2377
 
 
2378
  # Dump what we have collected
 
2379
  open (HTML, ">$OutputFile");
 
2380
  print HTML '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">'."\n";
 
2381
  print HTML "<html lang=\"EN-US\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n";
 
2382
  print HTML "<title>".$Report->{title}."</title>\n";
 
2383
  print HTML $Report->{css};
 
2384
  print HTML "</head>\n";
 
2385
  print HTML "<body>\n";
 
2386
  print HTML "<div style=\"background-color: #D4E6EA\">";
 
2387
  print HTML "<table border=\"0\" cellpadding=\"0\"><tr><td ><img src=\"logo.png\" alt=\"\"/></td><td>\n";
 
2388
  print HTML "<h1>".$Report->{title}."</h1></td></tr></table>\n";
 
2389
  print HTML "</div>\n";
 
2390
 
 
2391
  print HTML "<h2>Summary</h2>\n";
 
2392
 
 
2393
  print HTML $reportConfig->{report_intro};
 
2394
  print HTML "<p>The test was started on ".$Report->{date}.", and the total time for the test execution was ";
 
2395
  print HTML "<b>".int($runtime/3600)."h ".int(($runtime%3600)/60)."m ".($runtime % 60)."s</b>. ";
 
2396
  if ($Result->{Status} == DOC_REACHED) {
 
2397
    print HTML "The <b>Design Objective Capacity (DOC)</b> is <b>$Result->{DOC}</b> scenarios per second.";
 
2398
  } elsif ($Result->{Status} == FAILED) {
 
2399
    print HTML "No Successfull step has been performed! ";
 
2400
    print HTML "=> <b>The <b>Design Objective Capacity (DOC)</b> is 0 scenario per second</b>.";
 
2401
  } else {
 
2402
    print HTML "The <b>Design Objective Capacity (DOC)</b> has <b>not been reached</b>. ";
 
2403
    print HTML "The DOC is <b>&gt;= $Result->{DOC}</b> scenarios per second.";
 
2404
  }
 
2405
  print HTML "</p>\n";
 
2406
 
 
2407
  print HTML $report_test_info;
 
2408
  print HTML $reportConfig->{summary_table_intro};
 
2409
  print HTML $Report->{summary_tbl};
 
2410
 
 
2411
  print HTML $reportConfig->{measurements_intro};
 
2412
  print HTML $report_expl;
 
2413
  print HTML "<hr><p><a name=\"REF_TABLE\"></a></p><dl>".$Report->{toc}."</dl><hr>";
 
2414
  print HTML $Report->{graphs};
 
2415
  print HTML "\n<hr>\n";
 
2416
  print HTML $Report->{appendix};
 
2417
  printf HTML "</body>\n";
 
2418
  printf HTML "</html>\n";
 
2419
  if (close (HTML) <= 0) {
 
2420
    print("Error closing file: $!\n");
 
2421
    exit(0);
 
2422
  }
 
2423
 
 
2424
  # Copy necessary picture files
 
2425
  my @picFiles = ("logo.png", "b_index.png");
 
2426
  foreach my $picFile (@picFiles) {
 
2427
    if (! -e $picFile) {
 
2428
      my $fn = $CmdPath.$PathSep.$picFile;
 
2429
      copy($fn, $picFile) or die "File \"$fn\" cannot be copied.";
 
2430
    }
 
2431
  }
 
2432
  
 
2433
  my $n_pids = @forked_pids;
 
2434
  print("Waiting for all ($n_pids) gnuplot fork to be completed\n");
 
2435
  foreach my $pid (@forked_pids) {
 
2436
    waitpid($pid, 0);
 
2437
  }
 
2438
 
 
2439
  system($CmdPath.$PathSep.'html2mht.pl report.html> report.mht');
 
2440
}
 
2441
 
 
2442
my $t_start = GetMilli();
 
2443
my $ims_bench_name = undef;
 
2444
my $ims_bench = undef;
 
2445
 
 
2446
my $n_args = @ARGV;
 
2447
for (my $i=0;$i<$n_args;$i++) {
 
2448
  if ($ARGV[$i] eq "-r") {
 
2449
    $InputFile = $ARGV[++$i];
 
2450
  } elsif ($ARGV[$i] eq "-c") {
 
2451
    $ConfigFile = $ARGV[++$i];
 
2452
  } elsif ($ARGV[$i] eq "-b") {
 
2453
    $IntroFile = $ARGV[++$i];
 
2454
  } elsif ($ARGV[$i] =~ /-F(.*)/) {
 
2455
    $do_fork = $1;
 
2456
  } elsif ($ARGV[$i] eq "-i") {
 
2457
    $ims_bench_name = $ARGV[++$i];
 
2458
  } elsif (($ARGV[$i] =~ /-\?/) || ($ARGV[$i] eq "-h") || ($ARGV[$i] eq "--help")) {
 
2459
    #      01234567890123456789012345678901234567890123456789012345678901234567890123456789
 
2460
    print("\n");
 
2461
    print(" Syntax: doReport.pl [-r <report_file>] [-c <report_config_file>]\n");
 
2462
    print("                     [-b <bench_info_html>] [-i <ims_bench_file>] [-F<0|1>]\n\n");
 
2463
    print(" -r specifies the raw benchmark report file (default: report.xml) resulting\n");
 
2464
    print("    from the run you want to generate a graphical report for.\n");
 
2465
    print(" -c specifies the configuration file for this script (default: reportConfig.xml)\n");
 
2466
    print(" -b specifies an optional benchmark info HTML fragment file to include as\n");
 
2467
    print("    introduction in the report (a default generic sentence is otherwise provided)\n");
 
2468
    print(" -i specifies the ims_bench config file (in case the benchmark run was \n");
 
2469
    print("    configured using the ims_bench script), containing IMS benchmark parameters.\n");
 
2470
    print(" -F specifies whether gnuplot should be forked (to benefit from multiple CPU\n");
 
2471
    print("    cores). -F0 disables the forking (default: enabled)\n");
 
2472
    print(" -? to get this help.\n");
 
2473
    exit(0);
 
2474
  } else {
 
2475
    print("Invalid argument: $ARGV[$i]\n");
 
2476
    print("Use $0 -? to get help\n");
 
2477
    exit(0);
 
2478
  }
 
2479
}
 
2480
 
 
2481
print("Loading data from $InputFile\n");
 
2482
 
 
2483
my $xmlData = XMLin($InputFile, forcearray => [ qw(run step system scenario) ]);
 
2484
if (! -e $ConfigFile) {
 
2485
  $ConfigFile = $CmdPath.$PathSep.$ConfigFile;
 
2486
}
 
2487
my $reportConfig = XMLin($ConfigFile, forcearray => [ qw(measure scenario ts use_case) ]);
 
2488
if (defined($IntroFile)) {
 
2489
  open(INTRO, $IntroFile) or die "Cannot open specified intro file: $IntroFile";
 
2490
  $reportConfig->{report_intro} = do { local( $/ ) ; <INTRO> };
 
2491
  if (close(INTRO) <= 0) {
 
2492
    print("Error closing file: $!\n");
 
2493
    exit(0);
 
2494
  }
 
2495
}
 
2496
if (defined $ims_bench_name) {
 
2497
  $ims_bench = XMLin($ims_bench_name);
 
2498
}
 
2499
my ($rtd_ref, $scenario_ref) = ReadScenarios($xmlData->{configuration});
 
2500
do_report($xmlData, $reportConfig, $rtd_ref, $scenario_ref, $ims_bench);
 
2501
my $t_tot = GetMilli() - $t_start;
 
2502
for (my $i=0;$i<@TempFiles;$i++) {
 
2503
  unlink($TempFiles[$i]) unless $no_cleanup;
 
2504
}
 
2505
print ("\nTook $t_tot milliseconds\n");
 
2506
print ("Read the files=>$t_read\n");
 
2507
print ("GetStatistics=>$t_stat\n");
 
2508
print ("All pictures=>$t_pict\n");
 
2509
print ("BuildSource=>$t_buildfilefromsource\n");
 
2510
print ("BuildSipp=>$t_buildsipp\n");
 
2511
print ("BuildRetrans=>$t_buildretrans\n");
 
2512
print ("BuildCpuMem=>$t_buildcpumem\n");
 
2513
print ("BuildSippCPU=>$t_buildsippcpu\n");