class GasLoadTester::ChartBuilder

Constants

DEFAULT_PAGE_HEAD
DEFAULT_PAGE_TAIL

Attributes

body[RW]
description[RW]
file_name[RW]
header[RW]

Public Class Methods

new(args = {}) click to toggle source
# File lib/gas_load_tester/chart_builder.rb, line 23
def initialize(args = {})
  args ||= {}
  args[:file_name] ||= args['file_name']
  args[:header] ||= args['header']
  args[:description] ||= args['description']
  self.file_name = args[:file_name]
  self.header = args[:header]
  self.description = args[:description]
end

Public Instance Methods

build_body(test) click to toggle source
# File lib/gas_load_tester/chart_builder.rb, line 44
def build_body(test)
  header_part = build_headpart || ""

  sum_body = build_sum_test(test)

  self.body = DEFAULT_PAGE_HEAD + header_part + sum_body + DEFAULT_PAGE_TAIL
end
build_group_body(group_test) click to toggle source
# File lib/gas_load_tester/chart_builder.rb, line 52
def build_group_body(group_test)
  header_part = build_headpart || ""

  sum_group_body = group_test.tests.select{|test|
    test.is_run?
  }.collect{|test|
    build_sum_test(test)
  }.join('<hr style="margin-top: 70px; margin-bottom: 70px;">')

  sum_group_table = build_sum_group_table(group_test)

  self.body = DEFAULT_PAGE_HEAD + header_part + sum_group_table + sum_group_body + DEFAULT_PAGE_TAIL
end
save() click to toggle source
# File lib/gas_load_tester/chart_builder.rb, line 33
def save
  file_name = self.file_name
  if file_name == ""
    file_name = "load_result_"+Time.now.to_i.to_s+".html"
  elsif !file_name.end_with?(".html")
    file_name = file_name+".html"
  end
  File.open(file_name, 'w') { |file| file.write(self.body) }
  file_name
end

Private Instance Methods

build_chart(test) click to toggle source
# File lib/gas_load_tester/chart_builder.rb, line 212
def build_chart(test)
  clients_data = {}
  pass_data = {}
  error_data = {}
  average_time_data = {}
  test.results.each{|key, values|
    clients_data[Time.at(key).utc.strftime("%H:%M:%S")] = values.count
    pass_data[Time.at(key).utc.strftime("%H:%M:%S")] = values.select{|val| val.pass }.count
    error_data[Time.at(key).utc.strftime("%H:%M:%S")] = values.select{|val| !val.pass }.count
    if RUBY_VERSION >= "2.4.0"
      val = values.collect(&:time).sum.fdiv(values.size)*1000
    else
      val = values.collect(&:time).inject(0){|sum,x| sum + x }.fdiv(values.size)*1000
    end
    val = 0 if val.to_f.nan?
    val = 0 if val.infinite?
    average_time_data[Time.at(key).utc.strftime("%H:%M:%S")] = val
  }

  line_chart(
    [
      {
        name: 'Clients/sec',
        data: clients_data
      },
      {
        name: 'Passed',
        data: pass_data
      },
      {
        name: 'Error',
        data: error_data
      },
      {
        name: 'Average',
        data: average_time_data
      }
    ],
    {
      adapter: "google",
      "colors": ["#FFD919", "#23FF39", "#FF2A27", "#433DFF"],
      "library": {
        title: "Load test's result (Client: #{test.client}, Time: #{test.time} sec.)",
        legend: {position: 'top'},
        vAxes: {
          0 => {logScale: false, title: 'User (concurrent)'},
          1 => {logScale: false, title: 'Time (ms)', textStyle: {color: 'blue'}}
        },
        series: {
          0 => {targetAxisIndex: 0 },
          1 => {targetAxisIndex: 0 },
          2 => {targetAxisIndex: 0 },
          3 => {targetAxisIndex: 1 },
        }
      }
    }
  )
end
build_error_table(test) click to toggle source
# File lib/gas_load_tester/chart_builder.rb, line 271
def build_error_table(test)
  errors = test.results.collect{|key,values| values.select{|node| node.pass == false}}.flatten
  errors = errors.group_by{|error| "#{error.error.class.to_s}: #{error.error.message}" }
  
  "<div style=\"width: 100%; display: flex; margin-top: 30px;\">
     <div style=\"width: 20%;\">
     </div>
     <div style=\"width: 100%;\">
       <table style=\"width:100%; border: 1px solid black; border-collapse: collapse; text-align: center;\">
         <tr style=\"border: 1px solid black; border-collapse: collapse;\">
           <th width=\"80%\">Error</th>
           <th width=\"20%\">Count</th> 
         </tr>
         #{errors.collect{|_key, _values| 
           "<tr style=\"border: 1px solid black; border-collapse: collapse;\">
              <td>#{_key}</td>
              <td>#{_values.count}</td>
            </tr>"
         }.join}
       </table>
     </div>
     <div style=\"width: 20%;\">
     </div>
   </div>"
end
build_headpart() click to toggle source
# File lib/gas_load_tester/chart_builder.rb, line 68
def build_headpart
  "<div style=\"width: 100%;text-align: center;margin-top: 50px;\">
     #{ header.nil? ? "" : "<span style=\"font-weight: bold;font-size: 20px;\">#{ header }</span>" }
     #{ description.nil? ? "" : description.split("\n").collect{|text| "<p>#{text.to_s}</p>" }.join }
   </div><hr style=\"margin-top: 70px; margin-bottom: 70px;\">" if !self.header.nil? || !self.description.nil?
end
build_sum_group_table(group_test) click to toggle source
# File lib/gas_load_tester/chart_builder.rb, line 75
def build_sum_group_table(group_test)
  "<div style=\"width: 100%; text-align: center; margin-top: 20px; margin-bottom: 20px;\">
     <span style=\"align: center; font-weight: bold; font-size: 20px;\">Comparison summary</span>
   </div>

   <div style=\"width: 100%; display: flex; margin-top: 30px;\">
     <div style=\"width: 20%;\">
     </div>
     <div style=\"width: 100%;\">
       <table style=\"width:100%; border: 1px solid black; border-collapse: collapse; text-align: center;\">
         <tr style=\"border: 1px solid black; border-collapse: collapse;\">
           <th width=\"10%\" style=\"border: 1px solid black; border-collapse: collapse;\">client</th>
           <th width=\"10%\" style=\"border: 1px solid black; border-collapse: collapse;\">time (sec)</th>
           <th width=\"10%\" style=\"border: 1px solid black; border-collapse: collapse;\">clients/sec</th>
           <th width=\"10%\" style=\"border: 1px solid black; border-collapse: collapse;\">average_time (ms)</th>
           <th width=\"15%\" style=\"border: 1px solid black; border-collapse: collapse;\">min_time (ms)</th>
           <th width=\"15%\" style=\"border: 1px solid black; border-collapse: collapse;\">max_time (ms)</th>
           <th width=\"15%\" style=\"border: 1px solid black; border-collapse: collapse;\">success</th>
           <th width=\"15%\" style=\"border: 1px solid black; border-collapse: collapse;\">error</th>
         </tr>
            #{
              group_data = group_test.tests.select{|test| test.is_run? }.collect{|test|
                [
                  test.client,
                  test.time,
                  test.summary_avg_time.round(4),
                  test.summary_min_time.round(4),
                  test.summary_max_time.round(4),
                  test.summary_success,
                  test.summary_error,
                  test.request_per_second.round(2)
                ]
              }
              min_avg = group_data.collect{|test_data| test_data[2] }.sort.first
              max_avg = group_data.collect{|test_data| test_data[2] }.sort.last
              min_min = group_data.collect{|test_data| test_data[3] }.sort.first
              max_min = group_data.collect{|test_data| test_data[3] }.sort.last
              min_max = group_data.collect{|test_data| test_data[4] }.sort.first
              max_max = group_data.collect{|test_data| test_data[4] }.sort.last
              group_data.collect{|test_data|
                test_data[5] = test_data[0] if test_data[5] > test_data[0]
                "<tr style=\"border: 1px solid black; border-collapse: collapse;\">
                   <td style=\"border: 1px solid black; border-collapse: collapse;\">#{test_data[0]}</td>
                   <td style=\"border: 1px solid black; border-collapse: collapse;\">#{test_data[1]}</td>
                   <td style=\"border: 1px solid black; border-collapse: collapse;\">#{test_data[7]}</td>
                   <td style=\"border: 1px solid black; border-collapse: collapse; #{ 
                     if test_data[2] == min_avg
                       "color: green; font-weight:bold;"
                     elsif test_data[2] == max_avg
                       "color: red; font-weight:bold;"
                     end
                   }\">#{test_data[2]}</td>
                   <td style=\"border: 1px solid black; border-collapse: collapse; #{
                     if test_data[3] == min_min
                       "color: green; font-weight:bold;"
                     elsif test_data[3] == max_min
                       "color: red; font-weight:bold;"
                     end
                   }\">#{test_data[3]}</td>
                   <td style=\"border: 1px solid black; border-collapse: collapse; #{
                     if test_data[4] == min_max
                       "color: green; font-weight:bold;"
                     elsif test_data[4] == max_max
                       "color: red; font-weight:bold;"
                     end
                   }\">#{test_data[4]}</td>
                   <td style=\"border: 1px solid black; border-collapse: collapse; #{
                     "color: green; font-weight:bold;" if test_data[0] == test_data[5]
                   }\">#{test_data[5]}</td>
                   <td style=\"border: 1px solid black; border-collapse: collapse; #{
                     test_data[6] > 0 ? "color: red; font-weight:bold;" : "color: green; font-weight:bold;"
                   }\">#{test_data[6]}</td>
                 </tr>"
              }.join
            }
       </table>
     </div>
     <div style=\"width: 20%;\">
     </div>
   </div>
   <hr style=\"margin-top: 70px; margin-bottom: 70px;\">"
end
build_sum_test(test) click to toggle source
# File lib/gas_load_tester/chart_builder.rb, line 158
def build_sum_test(test)
  chart_body = build_chart(test)
  summary_body = build_summary(test)
  error_body = build_error_table(test)

  chart_body + summary_body + error_body
end
build_summary(test) click to toggle source
# File lib/gas_load_tester/chart_builder.rb, line 166
def build_summary(test)
  min_time = test.summary_min_time
  max_time = test.summary_max_time
  avg_time = test.summary_avg_time
  success = test.summary_success
  error = test.summary_error

  "<div style=\"width: 100%; text-align: center; margin-top: 20px; margin-bottom: 20px;\">
     <span style=\"align: center; font-weight: bold;\">Summary</span>
   </div>
   <div style=\"width: 100%; display: flex;\">
     <div style=\"width: 100%;\">
     </div>
     <div id=\"summary_time\" style=\"width: 100%; align: center;\">
       <table style=\"width: 100%;\">
         <tbody>
           <tr>
             <th style=\"font-weight: bold;\">Average</th>
             <td>#{avg_time.round(4)} ms</td>
           </tr>
           <tr>
             <th style=\"font-weight: bold;\">Min/Max</th>
             <td>#{min_time.round(4)} / #{max_time.round(4)} ms</td>
           </tr>
         </tbody>
       </table>
     </div>
     <div id=\"summary_data\" style=\"width: 100%; align: center;\">
       <table style=\"width: 100%;\">
         <tbody>
           <tr>
             <th style=\"font-weight: bold;\">Success</th>
             <td>#{success}</td>
           </tr>
           <tr>
             <th style=\"font-weight: bold;\">Error</th>
             <td>#{error}</td>
           </tr>
         </tbody>
       </table>
     </div>
     <div style=\"width: 100%;\">
     </div>
   </div>"
end