qa_server 7.2.1 → 7.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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