qa_server 7.2.1 → 7.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop_fixme.yml +3 -0
  3. data/.travis.yml +4 -5
  4. data/CHANGELOG.md +41 -0
  5. data/Rakefile +1 -1
  6. data/app/assets/stylesheets/qa_server/_check-status.scss +36 -0
  7. data/app/cache_processors/concerns/qa_server/cache_keys.rb +0 -5
  8. data/app/cache_processors/qa_server/cache_expiry_service.rb +13 -8
  9. data/app/cache_processors/qa_server/job_id_cache.rb +29 -0
  10. data/app/cache_processors/qa_server/performance_cache.rb +34 -34
  11. data/app/cache_processors/qa_server/performance_day_graph_cache.rb +27 -0
  12. data/app/cache_processors/qa_server/performance_month_graph_cache.rb +27 -0
  13. data/app/cache_processors/qa_server/performance_year_graph_cache.rb +27 -0
  14. data/app/cache_processors/qa_server/scenario_history_cache.rb +7 -7
  15. data/app/cache_processors/qa_server/scenario_history_graph_cache.rb +12 -17
  16. data/app/cache_processors/qa_server/scenario_run_cache.rb +8 -8
  17. data/app/cache_processors/qa_server/scenario_run_failures_cache.rb +7 -7
  18. data/app/cache_processors/qa_server/scenario_run_summary_cache.rb +7 -7
  19. data/app/controllers/concerns/qa_server/authority_validation_behavior.rb +49 -44
  20. data/app/controllers/qa_server/check_status_controller.rb +92 -22
  21. data/app/controllers/qa_server/fetch_controller.rb +36 -36
  22. data/app/controllers/qa_server/monitor_status_controller.rb +108 -108
  23. data/app/jobs/qa_server/history_graph_job.rb +28 -0
  24. data/app/jobs/qa_server/monitor_tests_job.rb +19 -39
  25. data/app/jobs/qa_server/performance_day_graph_job.rb +45 -0
  26. data/app/jobs/qa_server/performance_month_graph_job.rb +45 -0
  27. data/app/jobs/qa_server/performance_per_byte_job.rb +85 -0
  28. data/app/jobs/qa_server/performance_year_graph_job.rb +45 -0
  29. data/app/loggers/qa_server/scenario_logger.rb +74 -4
  30. data/app/models/concerns/qa_server/performance_history_data_keys.rb +8 -0
  31. data/app/models/qa_server/authority_scenario.rb +4 -4
  32. data/app/models/qa_server/authority_status.rb +2 -2
  33. data/app/models/qa_server/authority_status_failure.rb +1 -1
  34. data/app/models/qa_server/performance_history.rb +2 -2
  35. data/app/models/qa_server/scenario_run_history.rb +52 -52
  36. data/app/models/qa_server/scenario_run_registry.rb +2 -2
  37. data/app/models/qa_server/scenarios.rb +26 -26
  38. data/app/models/qa_server/search_scenario.rb +24 -13
  39. data/app/models/qa_server/term_scenario.rb +29 -29
  40. data/app/prepends/prepended_linked_data/find_term.rb +40 -40
  41. data/app/prepends/prepended_linked_data/search_query.rb +36 -36
  42. data/app/prepends/prepended_rdf/rdf_graph.rb +7 -7
  43. data/app/presenters/concerns/qa_server/monitor_status/performance_datatable_behavior.rb +32 -32
  44. data/app/presenters/concerns/qa_server/monitor_status/performance_graph_behavior.rb +64 -64
  45. data/app/presenters/qa_server/check_status_presenter.rb +63 -7
  46. data/app/presenters/qa_server/monitor_status/current_status_presenter.rb +9 -8
  47. data/app/services/concerns/qa_server/gruff_graph.rb +16 -16
  48. data/app/services/qa_server/authority_loader_service.rb +14 -14
  49. data/app/services/qa_server/authority_validator_service.rb +1 -0
  50. data/app/services/qa_server/database_migrator.rb +14 -14
  51. data/app/services/qa_server/history_graphing_service.rb +30 -30
  52. data/app/services/qa_server/performance_calculator_service.rb +80 -80
  53. data/app/services/qa_server/performance_datatable_service.rb +35 -35
  54. data/app/services/qa_server/performance_graph_data_service.rb +28 -28
  55. data/app/services/qa_server/performance_graphing_service.rb +58 -58
  56. data/app/services/qa_server/performance_per_byte_calculator_service.rb +88 -0
  57. data/app/services/qa_server/performance_per_byte_data_service.rb +41 -0
  58. data/app/services/qa_server/scenarios_loader_service.rb +1 -1
  59. data/app/services/qa_server/time_period_service.rb +21 -21
  60. data/app/validators/qa_server/scenario_validator.rb +99 -87
  61. data/app/validators/qa_server/search_scenario_validator.rb +67 -61
  62. data/app/validators/qa_server/term_scenario_validator.rb +20 -15
  63. data/app/views/qa_server/check_status/index.html.erb +120 -24
  64. data/app/views/qa_server/monitor_status/_test_summary.html.erb +1 -1
  65. data/config/i18n-tasks.yml +133 -0
  66. data/config/locales/qa_server.en.yml +16 -0
  67. data/lib/generators/qa_server/assets_generator.rb +4 -4
  68. data/lib/generators/qa_server/templates/config/authorities/linked_data/cerl_ld4l_cache.json +2 -2
  69. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_aat_ld4l_cache.json +62 -1
  70. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_tgn_ld4l_cache.json +45 -11
  71. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_ulan_ld4l_cache.json +104 -8
  72. data/lib/generators/qa_server/templates/config/authorities/linked_data/isni_ld4l_cache.json +90 -0
  73. data/lib/generators/qa_server/templates/config/authorities/linked_data/ligatus_ld4l_cache.json +133 -0
  74. data/lib/generators/qa_server/templates/config/authorities/linked_data/locnames_rwo2_ld4l_cache.json +248 -0
  75. data/lib/generators/qa_server/templates/config/authorities/linked_data/locnames_rwo3_ld4l_cache.json +248 -0
  76. data/lib/generators/qa_server/templates/config/authorities/linked_data/locnames_rwo_ld4l_cache.json +4 -4
  77. data/lib/generators/qa_server/templates/config/authorities/linked_data/locvocabs_ld4l_cache.json +117 -0
  78. data/lib/generators/qa_server/templates/config/authorities/linked_data/mesh_nlm_ld4l_cache.json +135 -3
  79. data/lib/generators/qa_server/templates/config/authorities/linked_data/oclcfast_direct.json +5 -0
  80. data/lib/generators/qa_server/templates/config/authorities/linked_data/oclcfast_ld4l_cache.json +2 -4
  81. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/agrovoc_direct_validation.yml +31 -0
  82. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/agrovoc_ld4l_cache_validation.yml +31 -0
  83. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/cerl_ld4l_cache_validation.yml +26 -14
  84. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/dbpedia_ld4l_cache_validation.yml +33 -0
  85. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/geonames_direct_validation.yml +35 -0
  86. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/geonames_ld4l_cache_validation.yml +55 -5
  87. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_aat_ld4l_cache_validation.yml +253 -0
  88. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_tgn_ld4l_cache_validation.yml +31 -1
  89. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_ulan_ld4l_cache_validation.yml +38 -1
  90. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/isni_ld4l_cache_validation.yml +10 -0
  91. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/ligatus_ld4l_cache_validation.yml +36 -0
  92. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locdemographics_ld4l_cache_validation.yml +69 -44
  93. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locgenres_ld4l_cache_validation.yml +22 -0
  94. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locnames_ld4l_cache_validation.yml +65 -0
  95. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locnames_rwo2_ld4l_cache_validation.yml +78 -0
  96. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locnames_rwo3_ld4l_cache_validation.yml +73 -0
  97. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locnames_rwo_ld4l_cache_validation.yml +71 -3
  98. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locperformance_ld4l_cache_validation.yml +6 -0
  99. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locsubjects_ld4l_cache_validation.yml +30 -0
  100. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locvocabs_ld4l_cache_validation.yml +430 -0
  101. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/mesh_nlm_ld4l_cache_validation.yml +54 -1
  102. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/nalt_ld4l_cache_validation.yml +37 -0
  103. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclc_fast_validation.yml +71 -5
  104. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclcfast_direct_validation.yml +73 -2
  105. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclcfast_ld4l_cache_validation.yml +73 -0
  106. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/rda_registry_ld4l_cache_validation.yml +307 -0
  107. data/lib/qa_server/configuration.rb +28 -24
  108. data/lib/qa_server/version.rb +1 -1
  109. data/qa_server.gemspec +6 -5
  110. data/spec/feature/accuracy_spec.rb +32 -0
  111. data/spec/i18n_spec.rb +36 -0
  112. data/spec/spec_helper.rb +4 -0
  113. metadata +74 -20
  114. data/app/cache_processors/qa_server/performance_daily_graph_cache.rb +0 -60
  115. data/app/cache_processors/qa_server/performance_hourly_graph_cache.rb +0 -65
  116. data/app/cache_processors/qa_server/performance_monthly_graph_cache.rb +0 -60
@@ -13,12 +13,13 @@ module QaServer::MonitorStatus
13
13
 
14
14
  # @return [ActiveSupport::TimeWithZone] date time stamp of last test run
15
15
  def last_updated_dt
16
- @current_summary.run_dt_stamp
16
+ @current_summary ? @current_summary.run_dt_stamp : QaServer::TimeService.current_time
17
17
  end
18
18
 
19
19
  # @return [String] date with time of last test run
20
20
  def last_updated
21
- QaServer::TimeService.pretty_time(last_updated_dt)
21
+ return I18n.t('qa_server.monitor_status.summary.no_data') if @current_summary.blank?
22
+ I18n.t('qa_server.monitor_status.summary.last_updated', date: QaServer::TimeService.pretty_time(last_updated_dt))
22
23
  end
23
24
 
24
25
  # @return [ActiveSupport::TimeWithZone] date time stamp of first recorded test run
@@ -33,12 +34,12 @@ module QaServer::MonitorStatus
33
34
 
34
35
  # @return [Integer] number of loaded authorities
35
36
  def authorities_count
36
- @current_summary.authority_count
37
+ @current_summary ? @current_summary.authority_count : "N/A"
37
38
  end
38
39
 
39
40
  # @return [Integer] number of authorities with failing tests in the latest test run
40
41
  def failing_authorities_count
41
- @current_failure_data.map { |f| f[:authority_name] }.uniq.count
42
+ @current_failure_data ? @current_failure_data.map { |f| f[:authority_name] }.uniq.count : "N/A"
42
43
  end
43
44
 
44
45
  # @return [String] css style class representing whether all tests passed or any failed
@@ -48,17 +49,17 @@ module QaServer::MonitorStatus
48
49
 
49
50
  # @return [Integer] number of tests in the latest test run
50
51
  def tests_count
51
- @current_summary.total_scenario_count
52
+ @current_summary ? @current_summary.total_scenario_count : 0
52
53
  end
53
54
 
54
55
  # @return [Integer] number of passing tests in the latest test run
55
56
  def passing_tests_count
56
- @current_summary.passing_scenario_count
57
+ @current_summary ? @current_summary.passing_scenario_count : 0
57
58
  end
58
59
 
59
60
  # @return [Integer] number of failing tests in the latest test run
60
61
  def failing_tests_count
61
- @current_summary.failing_scenario_count
62
+ @current_summary ? @current_summary.failing_scenario_count : 0
62
63
  end
63
64
 
64
65
  # @return [String] css style class representing whether all tests passed or any failed
@@ -77,7 +78,7 @@ module QaServer::MonitorStatus
77
78
  # url: '/qa/search/linked_data/locnames_ld4l_cache/person?q=mark twain&maxRecords=4',
78
79
  # err_message: 'Exception: Something went wrong.' }, ... ]
79
80
  def failures
80
- @current_failure_data
81
+ @current_failure_data ? @current_failure_data : []
81
82
  end
82
83
 
83
84
  # @return [Boolean] true if failure data exists for the latest test run; otherwise false
@@ -5,24 +5,24 @@ require 'gruff'
5
5
  # This module include provides graph methods for generating graphs with Gruff
6
6
  module QaServer
7
7
  module GruffGraph
8
- private
8
+ private
9
9
 
10
- # common path for displaying and writing
11
- def graph_relative_path
12
- File.join('qa_server', 'charts')
13
- end
10
+ # common path for displaying and writing
11
+ def graph_relative_path
12
+ File.join('qa_server', 'charts')
13
+ end
14
14
 
15
- # used for displaying in a view with <image> tag
16
- def graph_image_path
17
- File.join('/', graph_relative_path)
18
- end
15
+ # used for displaying in a view with <image> tag
16
+ def graph_image_path
17
+ File.join('/', graph_relative_path)
18
+ end
19
19
 
20
- # used for writing out the file
21
- def graph_full_path(graph_filename)
22
- path = Rails.root.join('public', graph_relative_path)
23
- # path = Rails.root.join('app', 'assets', 'images', graph_relative_path)
24
- FileUtils.mkdir_p path
25
- File.join(path, graph_filename)
26
- end
20
+ # used for writing out the file
21
+ def graph_full_path(graph_filename)
22
+ path = Rails.root.join('public', graph_relative_path)
23
+ # path = Rails.root.join('app', 'assets', 'images', graph_relative_path)
24
+ FileUtils.mkdir_p path
25
+ File.join(path, graph_filename)
26
+ end
27
27
  end
28
28
  end
@@ -22,24 +22,24 @@ module QaServer
22
22
  authority
23
23
  end
24
24
 
25
- private
25
+ private
26
26
 
27
- def authority_key(authority_name)
28
- authority_name.upcase.to_sym
29
- end
27
+ def authority_key(authority_name)
28
+ authority_name.upcase.to_sym
29
+ end
30
30
 
31
- def load_authority(authority_name, status_log)
32
- authority = Qa::Authorities::LinkedData::GenericAuthority.new(authority_key(authority_name))
33
- if authority.blank?
34
- if status_log.present?
35
- status_log.add(authority_name: authority_name,
36
- status: QaServer::ScenarioValidator::FAIL,
37
- error_message: "Unable to load authority '#{authority_name}'; cause: UNKNOWN")
38
- end
39
- return nil
31
+ def load_authority(authority_name, status_log)
32
+ authority = Qa::Authorities::LinkedData::GenericAuthority.new(authority_key(authority_name))
33
+ if authority.blank?
34
+ if status_log.present?
35
+ status_log.add(authority_name: authority_name,
36
+ status: QaServer::ScenarioValidator::FAIL,
37
+ error_message: "Unable to load authority '#{authority_name}'; cause: UNKNOWN")
40
38
  end
41
- authority
39
+ return nil
42
40
  end
41
+ authority
42
+ end
43
43
  end
44
44
  end
45
45
  end
@@ -14,6 +14,7 @@ module QaServer
14
14
 
15
15
  VALIDATE_CONNECTIONS = validator_class::VALIDATE_CONNECTION
16
16
  VALIDATE_ACCURACY = validator_class::VALIDATE_ACCURACY
17
+ VALIDATE_ACCURACY_COMPARISON = validator_class::VALIDATE_ACCURACY_COMPARISON
17
18
  ALL_VALIDATIONS = validator_class::ALL_VALIDATIONS
18
19
  DEFAULT_VALIDATION_TYPE = validator_class::DEFAULT_VALIDATION_TYPE
19
20
 
@@ -50,22 +50,22 @@ module QaServer
50
50
  end
51
51
  end
52
52
 
53
- private
53
+ private
54
54
 
55
- def migrations
56
- Dir.chdir(self.class.migrations_dir) { Dir.glob('db/migrate/[0-9]*_*.rb.erb') }.sort
57
- end
55
+ def migrations
56
+ Dir.chdir(self.class.migrations_dir) { Dir.glob('db/migrate/[0-9]*_*.rb.erb') }.sort
57
+ end
58
58
 
59
- def parse_basename_from(filename)
60
- # Add engine name to filename to mimic ``ActiveRecord::Migration.copy` behavior
61
- filename.slice(/(?<dateprefix>\d)+_(?<basename>.+)\.erb/, 'basename').sub('.', '.qa_server.')
62
- end
59
+ def parse_basename_from(filename)
60
+ # Add engine name to filename to mimic ``ActiveRecord::Migration.copy` behavior
61
+ filename.slice(/(?<dateprefix>\d)+_(?<basename>.+)\.erb/, 'basename').sub('.', '.qa_server.')
62
+ end
63
63
 
64
- def migration_version
65
- # Don't use AR migration versioning in Rails 4
66
- return if Rails.version < '5.0.0'
67
- # Specify the current major.minor version of Rails for AR migrations
68
- "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
69
- end
64
+ def migration_version
65
+ # Don't use AR migration versioning in Rails 4
66
+ return if Rails.version < '5.0.0'
67
+ # Specify the current major.minor version of Rails for AR migrations
68
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
69
+ end
70
70
  end
71
71
  end
@@ -29,41 +29,41 @@ module QaServer
29
29
  QaServer.config.monitor_logger.warn("FAILED to write historical graph at #{history_graph_image_path}") unless history_graph_image_exists?
30
30
  end
31
31
 
32
- private
32
+ private
33
33
 
34
- def create_gruff_graph(reworked_data, full_path)
35
- g = Gruff::SideStackedBar.new
36
- historical_graph_theme(g)
37
- g.labels = reworked_data[0]
38
- g.data('Fail', reworked_data[1])
39
- g.data('Pass', reworked_data[2])
40
- g.write full_path
41
- end
34
+ def create_gruff_graph(reworked_data, full_path)
35
+ g = Gruff::SideStackedBar.new
36
+ historical_graph_theme(g)
37
+ g.labels = reworked_data[0]
38
+ g.data('Fail', reworked_data[1])
39
+ g.data('Pass', reworked_data[2])
40
+ g.write full_path
41
+ end
42
42
 
43
- def historical_graph_theme(g)
44
- g.theme_pastel
45
- g.colors = ['#ffcccc', '#ccffcc']
46
- g.marker_font_size = 12
47
- g.x_axis_increment = 10
48
- end
43
+ def historical_graph_theme(g)
44
+ g.theme_pastel
45
+ g.colors = ['#ffcccc', '#ccffcc']
46
+ g.marker_font_size = 12
47
+ g.x_axis_increment = 10
48
+ end
49
49
 
50
- def historical_graph_full_path
51
- graph_full_path(HISTORICAL_GRAPH_FILENAME)
52
- end
50
+ def historical_graph_full_path
51
+ graph_full_path(HISTORICAL_GRAPH_FILENAME)
52
+ end
53
53
 
54
- def rework_historical_data_for_gruff(data)
55
- labels = {}
56
- pass_data = []
57
- fail_data = []
58
- i = 0
59
- data.each do |authname, authdata|
60
- labels[i] = authname
61
- i += 1
62
- fail_data << authdata[:bad]
63
- pass_data << authdata[:good]
64
- end
65
- [labels, fail_data, pass_data]
54
+ def rework_historical_data_for_gruff(data)
55
+ labels = {}
56
+ pass_data = []
57
+ fail_data = []
58
+ i = 0
59
+ data.each do |authname, authdata|
60
+ labels[i] = authname
61
+ i += 1
62
+ fail_data << authdata[:bad]
63
+ pass_data << authdata[:good]
66
64
  end
65
+ [labels, fail_data, pass_data]
66
+ end
67
67
  end
68
68
  end
69
69
  end
@@ -40,85 +40,85 @@ module QaServer
40
40
  stats
41
41
  end
42
42
 
43
- private
44
-
45
- def calculate_load_stats(avg, low, high)
46
- stats[AVG_LOAD] = calculate_average(full_load_times) if avg
47
- stats[LOW_LOAD] = calculate_10th_percentile(full_load_times) if low
48
- stats[HIGH_LOAD] = calculate_90th_percentile(full_load_times) if high
49
- end
50
-
51
- def calculate_retrieve_stats(avg, low, high)
52
- stats[AVG_RETR] = calculate_average(retrieve_times) if avg
53
- stats[LOW_RETR] = calculate_10th_percentile(retrieve_times) if low
54
- stats[HIGH_RETR] = calculate_90th_percentile(retrieve_times) if high
55
- end
56
-
57
- def calculate_graph_load_stats(avg, low, high)
58
- stats[AVG_GRPH] = calculate_average(graph_load_times) if avg
59
- stats[LOW_GRPH] = calculate_10th_percentile(graph_load_times) if low
60
- stats[HIGH_GRPH] = calculate_90th_percentile(graph_load_times) if high
61
- end
62
-
63
- def calculate_normalization_stats(avg, low, high)
64
- stats[AVG_NORM] = calculate_average(norm_times) if avg
65
- stats[LOW_NORM] = calculate_10th_percentile(norm_times) if low
66
- stats[HIGH_NORM] = calculate_90th_percentile(norm_times) if high
67
- end
68
-
69
- def calculate_action_stats(avg, low, high)
70
- stats[AVG_ACTN] = calculate_average(action_times) if avg
71
- stats[LOW_ACTN] = calculate_10th_percentile(action_times) if low
72
- stats[HIGH_ACTN] = calculate_90th_percentile(action_times) if high
73
- end
74
-
75
- def tenth_percentile_count(times)
76
- percentile_count = (times.count * 0.1).round
77
- percentile_count = 1 if percentile_count.zero? && times.count > 1
78
- percentile_count
79
- end
80
-
81
- def times(column)
82
- where_clause = action.nil? ? "" : { "action" => action }
83
- records.where(where_clause).where.not(column => nil).order(column).pluck(column)
84
- end
85
-
86
- def full_load_times
87
- @full_load_times ||= times(:retrieve_plus_graph_load_time_ms)
88
- end
89
-
90
- def retrieve_times
91
- @retrieve_times ||= times(:retrieve_time_ms)
92
- end
93
-
94
- def graph_load_times
95
- @graph_load_times ||= times(:graph_load_time_ms)
96
- end
97
-
98
- def norm_times
99
- @norm_times ||= times(:normalization_time_ms)
100
- end
101
-
102
- def action_times
103
- @action_times ||= times(:action_time_ms)
104
- end
105
-
106
- def calculate_average(times)
107
- return 0 if times.count.zero?
108
- return times[0] if times.count == 1
109
- times.inject(0.0) { |sum, el| sum + el } / times.count
110
- end
111
-
112
- def calculate_10th_percentile(times)
113
- return 0 if times.count.zero?
114
- return times[0] if times.count == 1
115
- times[tenth_percentile_count(times) - 1]
116
- end
117
-
118
- def calculate_90th_percentile(times)
119
- return 0 if times.count.zero?
120
- return times[0] if times.count == 1
121
- times[times.count - tenth_percentile_count(times)]
122
- end
43
+ private
44
+
45
+ def calculate_load_stats(avg, low, high)
46
+ stats[AVG_LOAD] = calculate_average(full_load_times) if avg
47
+ stats[LOW_LOAD] = calculate_10th_percentile(full_load_times) if low
48
+ stats[HIGH_LOAD] = calculate_90th_percentile(full_load_times) if high
49
+ end
50
+
51
+ def calculate_retrieve_stats(avg, low, high)
52
+ stats[AVG_RETR] = calculate_average(retrieve_times) if avg
53
+ stats[LOW_RETR] = calculate_10th_percentile(retrieve_times) if low
54
+ stats[HIGH_RETR] = calculate_90th_percentile(retrieve_times) if high
55
+ end
56
+
57
+ def calculate_graph_load_stats(avg, low, high)
58
+ stats[AVG_GRPH] = calculate_average(graph_load_times) if avg
59
+ stats[LOW_GRPH] = calculate_10th_percentile(graph_load_times) if low
60
+ stats[HIGH_GRPH] = calculate_90th_percentile(graph_load_times) if high
61
+ end
62
+
63
+ def calculate_normalization_stats(avg, low, high)
64
+ stats[AVG_NORM] = calculate_average(norm_times) if avg
65
+ stats[LOW_NORM] = calculate_10th_percentile(norm_times) if low
66
+ stats[HIGH_NORM] = calculate_90th_percentile(norm_times) if high
67
+ end
68
+
69
+ def calculate_action_stats(avg, low, high)
70
+ stats[AVG_ACTN] = calculate_average(action_times) if avg
71
+ stats[LOW_ACTN] = calculate_10th_percentile(action_times) if low
72
+ stats[HIGH_ACTN] = calculate_90th_percentile(action_times) if high
73
+ end
74
+
75
+ def tenth_percentile_count(times)
76
+ percentile_count = (times.count * 0.1).round
77
+ percentile_count = 1 if percentile_count.zero? && times.count > 1
78
+ percentile_count
79
+ end
80
+
81
+ def times(column)
82
+ where_clause = action.nil? ? "" : { "action" => action }
83
+ records.where(where_clause).where.not(column => nil).order(column).pluck(column)
84
+ end
85
+
86
+ def full_load_times
87
+ @full_load_times ||= times(:retrieve_plus_graph_load_time_ms)
88
+ end
89
+
90
+ def retrieve_times
91
+ @retrieve_times ||= times(:retrieve_time_ms)
92
+ end
93
+
94
+ def graph_load_times
95
+ @graph_load_times ||= times(:graph_load_time_ms)
96
+ end
97
+
98
+ def norm_times
99
+ @norm_times ||= times(:normalization_time_ms)
100
+ end
101
+
102
+ def action_times
103
+ @action_times ||= times(:action_time_ms)
104
+ end
105
+
106
+ def calculate_average(times)
107
+ return 0 if times.count.zero?
108
+ return times[0] if times.count == 1
109
+ times.inject(0.0) { |sum, el| sum + el } / times.count
110
+ end
111
+
112
+ def calculate_10th_percentile(times)
113
+ return 0 if times.count.zero?
114
+ return times[0] if times.count == 1
115
+ times[tenth_percentile_count(times) - 1]
116
+ end
117
+
118
+ def calculate_90th_percentile(times)
119
+ return 0 if times.count.zero?
120
+ return times[0] if times.count == 1
121
+ times[times.count - tenth_percentile_count(times)]
122
+ end
123
123
  end
124
124
  end
@@ -32,48 +32,48 @@ module QaServer
32
32
  end
33
33
  end
34
34
 
35
- private
35
+ private
36
36
 
37
- def datatable_data_for_authority(authority_name: nil)
38
- [:search, :fetch, :all_actions].each_with_object({}) do |action, hash|
39
- hash[action] = data_table_stats(authority_name, action)
40
- end
37
+ def datatable_data_for_authority(authority_name: nil)
38
+ [:search, :fetch, :all_actions].each_with_object({}) do |action, hash|
39
+ hash[action] = data_table_stats(authority_name, action)
41
40
  end
41
+ end
42
42
 
43
- # Get statistics for data table.
44
- # @param auth_name [String] limit statistics to records for the given authority (default: all authorities)
45
- # @param action [Symbol] one of :search, :fetch, :all_actions
46
- # @returns [Hash] performance statistics for the datatable during the expected time period
47
- # @example
48
- # { retrieve_avg_ms: 12.3, graph_load_avg_ms: 2.1, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5,
49
- # retrieve_10th_ms: 12.3, graph_load_10th_ms: 12.3, normalization_10th_ms: 4.2, full_request_10th_ms: 16.5,
50
- # retrieve_90th_ms: 12.3, graph_load_90th_ms: 12.3, normalization_90th_ms: 4.2, full_request_90th_ms: 16.5 }
51
- def data_table_stats(auth_name, action)
52
- records = records_for_authority(auth_name)
53
- stats_calculator_class.new(records, action: action).calculate_stats_with_percentiles
54
- end
43
+ # Get statistics for data table.
44
+ # @param auth_name [String] limit statistics to records for the given authority (default: all authorities)
45
+ # @param action [Symbol] one of :search, :fetch, :all_actions
46
+ # @returns [Hash] performance statistics for the datatable during the expected time period
47
+ # @example
48
+ # { retrieve_avg_ms: 12.3, graph_load_avg_ms: 2.1, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5,
49
+ # retrieve_10th_ms: 12.3, graph_load_10th_ms: 12.3, normalization_10th_ms: 4.2, full_request_10th_ms: 16.5,
50
+ # retrieve_90th_ms: 12.3, graph_load_90th_ms: 12.3, normalization_90th_ms: 4.2, full_request_90th_ms: 16.5 }
51
+ def data_table_stats(auth_name, action)
52
+ records = records_for_authority(auth_name)
53
+ stats_calculator_class.new(records, action: action).calculate_stats_with_percentiles
54
+ end
55
55
 
56
- def expected_time_period
57
- QaServer.config.performance_datatable_default_time_period
58
- end
56
+ def expected_time_period
57
+ QaServer.config.performance_datatable_default_time_period
58
+ end
59
59
 
60
- def records_for_authority(auth_name)
61
- case expected_time_period
62
- when :day
63
- QaServer.config.performance_cache.write_all # only need to write if just using today's data
64
- performance_data_class.where(QaServer::TimePeriodService.where_clause_for_last_24_hours(auth_name: auth_name))
65
- when :month
66
- performance_data_class.where(QaServer::TimePeriodService.where_clause_for_last_30_days(auth_name: auth_name))
67
- when :year
68
- performance_data_class.where(QaServer::TimePeriodService.where_clause_for_last_12_months(auth_name: auth_name))
69
- else
70
- all_records(auth_name)
71
- end
60
+ def records_for_authority(auth_name)
61
+ case expected_time_period
62
+ when :day
63
+ QaServer.config.performance_cache.write_all # only need to write if just using today's data
64
+ performance_data_class.where(QaServer::TimePeriodService.where_clause_for_last_24_hours(auth_name: auth_name))
65
+ when :month
66
+ performance_data_class.where(QaServer::TimePeriodService.where_clause_for_last_30_days(auth_name: auth_name))
67
+ when :year
68
+ performance_data_class.where(QaServer::TimePeriodService.where_clause_for_last_12_months(auth_name: auth_name))
69
+ else
70
+ all_records(auth_name)
72
71
  end
72
+ end
73
73
 
74
- def all_records(auth_name)
75
- auth_name.nil? ? performance_data_class.all : performance_data_class.where(authority: auth_name)
76
- end
74
+ def all_records(auth_name)
75
+ auth_name.nil? ? performance_data_class.all : performance_data_class.where(authority: auth_name)
76
+ end
77
77
  end
78
78
  end
79
79
  end