qa_server 6.2.0 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/app/cache_processors/concerns/qa_server/cache_keys.rb +15 -0
  4. data/app/cache_processors/qa_server/cache_expiry_service.rb +33 -0
  5. data/app/cache_processors/qa_server/performance_daily_graph_cache.rb +60 -0
  6. data/app/cache_processors/qa_server/performance_datatable_cache.rb +33 -0
  7. data/app/cache_processors/qa_server/performance_hourly_graph_cache.rb +65 -0
  8. data/app/cache_processors/qa_server/performance_monthly_graph_cache.rb +60 -0
  9. data/app/cache_processors/qa_server/scenario_history_cache.rb +35 -0
  10. data/app/cache_processors/qa_server/scenario_run_cache.rb +28 -0
  11. data/app/cache_processors/qa_server/scenario_run_failures_cache.rb +51 -0
  12. data/app/cache_processors/qa_server/scenario_run_summary_cache.rb +40 -0
  13. data/app/controllers/qa_server/monitor_status_controller.rb +39 -48
  14. data/app/jobs/qa_server/monitor_tests_job.rb +1 -1
  15. data/app/models/qa_server/scenario_run_history.rb +27 -84
  16. data/app/models/qa_server/scenario_run_registry.rb +1 -1
  17. data/app/services/qa_server/performance_datatable_service.rb +6 -9
  18. data/app/services/qa_server/performance_graph_data_service.rb +77 -154
  19. data/app/services/qa_server/performance_graphing_service.rb +34 -47
  20. data/lib/qa_server/version.rb +1 -1
  21. data/spec/{services/qa_server/monitor_cache_service_spec.rb → cache_processors/qa_server/cache_expiry_service_spec.rb} +1 -1
  22. metadata +15 -6
  23. data/app/services/qa_server/monitor_cache_service.rb +0 -22
  24. /data/app/{models → cache_processors}/qa_server/performance_cache.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b602ac44639871d5021eb47493edf93fb8abdc25
4
- data.tar.gz: bf9e6a5ece3786edab98ed79d1fc3edb8e54f8b7
3
+ metadata.gz: fb73032a8e4f6dfb0d782a8635d8f43668b63a06
4
+ data.tar.gz: a857cd62d41bc035a241419815e9fff67fdf1d5a
5
5
  SHA512:
6
- metadata.gz: ec1fec69f78b763fc7012c92118fddeb6e0f6ad98d53d9ae80d959f80f0c1373c435626452644294ecbcf1b1843ac37517af58a71e04ece333a9d14afa99486f
7
- data.tar.gz: d4e87a9c8157f8d03b3fdbc26ded7698f294cee41f9c7a2222355db878c26ab7e7d121d32dda69fbf1660f5b7942de7ec05688431a364b1e06f22b9b73967598
6
+ metadata.gz: 490cfcc14713a0fad8e3d5d60aa5d23a5699c5c3ab23359164848a8f5a3223bbf8fb2bbbffbd9f59b5220efed3eec4f4d63a8fece546dee916886f91a51f0287
7
+ data.tar.gz: '04027957aeb5955a65a4a5d23d4fd11c7b98827c650ba9b736512953fb10c260e11c9ad4f76de85991861706874eedd7e04bb523184c2a1693e079dc0317b142'
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ### 7.0.0 (2020-02-19)
2
+
3
+ * refactor of caching system to simplify the process
4
+ * rename monitor_cache_service to cache_expiry_service
5
+ * move generation of hourly graph to cache_processors
6
+ * move generation of daily and monthly graphs to cache_processors
7
+ * move performance datatable cache control to cache_processors
8
+ * move caching of summary and historical data to cache_processors
9
+ * move caching of test execution marker to cache_processors
10
+ * move performance cache of performance data to cache_processors
11
+
1
12
  ### 6.2.0 (2020-02-17)
2
13
 
3
14
  * use authentication for refreshing monitor tests
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ # This module sets up the keys used to identify data in Rails.cache
3
+ module QaServer
4
+ module CacheKeys
5
+ SCENARIO_RUN_TEST_DATA_CACHE_KEY = "QaServer--CacheKeys--scenario_run_test_data"
6
+ SCENARIO_RUN_SUMMARY_DATA_CACHE_KEY = "QaServer--CacheKeys--scenario_run_summary_data"
7
+ SCENARIO_RUN_FAILURE_DATA_CACHE_KEY = "QaServer--CacheKeys--scenario_run_failure_data"
8
+ SCENARIO_RUN_HISTORY_DATA_CACHE_KEY = "QaServer--CacheKeys--scenario_run_history_data"
9
+
10
+ PERFORMANCE_DATATABLE_DATA_CACHE_KEY = "QaServer--Cache--performance_datatable_data"
11
+ PERFORMANCE_GRAPH_HOURLY_DATA_CACHE_KEY = "QaServer--CacheKeys--performance_graph_hourly_data"
12
+ PERFORMANCE_GRAPH_DAILY_DATA_CACHE_KEY = "QaServer--CacheKeys--performance_graph_daily_data"
13
+ PERFORMANCE_GRAPH_MONTHLY_DATA_CACHE_KEY = "QaServer--CacheKeys--performance_graph_monthly_data"
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ # Helper methods for caching for monitoring status.
3
+ module QaServer
4
+ class CacheExpiryService
5
+ class << self
6
+ # @return [Float] number of seconds until cache should expire
7
+ def cache_expiry
8
+ cache_expires_at - QaServer::TimeService.current_time
9
+ end
10
+
11
+ # @param key [String] cache key
12
+ # @param force [Boolean] if true, forces cache to regenerate by returning true; otherwise, uses cache expiry to determine whether cache has expired
13
+ # @return [Boolean] true if cache has expired or is being forced to expire
14
+ def cache_expired?(key:, force:, next_expiry:)
15
+ # will return true only if the full expiry has passed or force was requested
16
+ force = Rails.cache.fetch(key, expires_in: 5.minutes, race_condition_ttl: 30.seconds, force: force) { true }
17
+ # reset cache so it will next expired at expected time
18
+ Rails.cache.fetch(key, expires_in: next_expiry, race_condition_ttl: 30.seconds, force: true) { false }
19
+ force
20
+ end
21
+
22
+ private
23
+
24
+ # @return [ActiveSupport::TimeWithZone] DateTime at which cache should expire
25
+ def cache_expires_at
26
+ offset = QaServer.config.hour_offset_to_expire_cache
27
+ offset_time = QaServer::TimeService.current_time
28
+ offset_time = offset_time.tomorrow unless (offset_time + 5.minutes).hour < offset
29
+ offset_time.beginning_of_day + offset.hours - 5.minutes
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+ # Generate graphs for the past 30 days using cached data. Graphs are generated only if the cache has expired.
3
+ module QaServer
4
+ class PerformanceDailyGraphCache
5
+ class_attribute :authority_list_class, :graph_data_service, :graphing_service
6
+ self.authority_list_class = QaServer::AuthorityListerService
7
+ self.graph_data_service = QaServer::PerformanceGraphDataService
8
+ self.graphing_service = QaServer::PerformanceGraphingService
9
+
10
+ class << self
11
+ include QaServer::CacheKeys
12
+ include QaServer::PerformanceHistoryDataKeys
13
+
14
+ # Generates graphs for the past 30 days for :search, :fetch, and :all actions for each authority.
15
+ # @param force [Boolean] if true, run the tests even if the cache hasn't expired; otherwise, use cache if not expired
16
+ def generate_graphs(force: false)
17
+ return unless QaServer::CacheExpiryService.cache_expired?(key: cache_key_for_force, force: force, next_expiry: next_expiry)
18
+ QaServer.config.monitor_logger.debug("(QaServer::PerformanceDailyGraphCache) - GENERATING daily performance graphs (force: #{force})")
19
+ generate_graphs_for_authorities
20
+ end
21
+
22
+ private
23
+
24
+ def generate_graphs_for_authorities
25
+ auths = authority_list_class.authorities_list
26
+ generate_graphs_for_authority(authority_name: ALL_AUTH) # generates graph for all authorities
27
+ auths.each { |authname| generate_graphs_for_authority(authority_name: authname) }
28
+ end
29
+
30
+ def generate_graphs_for_authority(authority_name:)
31
+ [SEARCH, FETCH, ALL_ACTIONS].each_with_object({}) do |action, hash|
32
+ hash[action] = generate_30_day_graph(authority_name: authority_name, action: action)
33
+ end
34
+ end
35
+
36
+ def generate_30_day_graph(authority_name:, action:)
37
+ # real expiration or force caught by cache_expired? So if we are here, either the cache has expired
38
+ # or force was requested. We still expire the cache and use ttl to catch race conditions.
39
+ Rails.cache.fetch(cache_key_for_authority_action(authority_name: authority_name, action: action),
40
+ expires_in: next_expiry, race_condition_ttl: 1.hour, force: true) do
41
+ data = graph_data_service.calculate_last_30_days(authority_name: authority_name, action: action)
42
+ graphing_service.generate_daily_graph(authority_name: authority_name, action: action, data: data)
43
+ data
44
+ end
45
+ end
46
+
47
+ def cache_key_for_authority_action(authority_name:, action:)
48
+ "#{PERFORMANCE_GRAPH_DAILY_DATA_CACHE_KEY}--#{authority_name}--#{action}"
49
+ end
50
+
51
+ def cache_key_for_force
52
+ "#{PERFORMANCE_GRAPH_DAILY_DATA_CACHE_KEY}--force"
53
+ end
54
+
55
+ def next_expiry
56
+ QaServer::CacheExpiryService.cache_expiry
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ # Maintain a cache of data for the Performance Datatable
3
+ module QaServer
4
+ class PerformanceDatatableCache
5
+ include QaServer::CacheKeys
6
+
7
+ class_attribute :performance_data_service
8
+ self.performance_data_service = QaServer::PerformanceDatatableService
9
+
10
+ # Retrieve performance datatable data from the cache
11
+ # @param force [Boolean] if true, calculate the stats even if the cache hasn't expired; otherwise, use cache if not expired
12
+ # @returns [Hash] performance statistics for configured time period by action for each authority
13
+ # @example
14
+ # { all_authorities:
15
+ # { search:
16
+ # { retrieve_avg_ms: 12.3, graph_load_avg_ms: 2.1, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5,
17
+ # retrieve_10th_ms: 12.3, graph_load_10th_ms: 12.3, normalization_10th_ms: 4.2, full_request_10th_ms: 16.5,
18
+ # retrieve_90th_ms: 12.3, graph_load_90th_ms: 12.3, normalization_90th_ms: 4.2, full_request_90th_ms: 16.5 },
19
+ # fetch: { ... # same data as for search_stats },
20
+ # all: { ... # same data as for search_stats }
21
+ # },
22
+ # AGROVOC_LD4L_CACHE: { ... # same data for each authority }
23
+ # }
24
+ def self.data(force: false)
25
+ Rails.cache.fetch(PERFORMANCE_DATATABLE_DATA_CACHE_KEY,
26
+ expires_in: QaServer::CacheExpiryService.cache_expiry,
27
+ race_condition_ttl: 5.minutes, force: force) do
28
+ QaServer.config.monitor_logger.debug("(QaServer::PerformanceDatatableCache) - CALCULATING performance datatable stats (force: #{force})")
29
+ performance_data_service.calculate_datatable_data
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+ # Generate graphs for the past 24 hours using cached data. The last hour of data is always calculated and all graphs
3
+ # for are generated.
4
+ module QaServer
5
+ class PerformanceHourlyGraphCache
6
+ class_attribute :authority_list_class, :graph_data_service, :graphing_service
7
+ self.authority_list_class = QaServer::AuthorityListerService
8
+ self.graph_data_service = QaServer::PerformanceGraphDataService
9
+ self.graphing_service = QaServer::PerformanceGraphingService
10
+
11
+ class << self
12
+ include QaServer::CacheKeys
13
+ include QaServer::PerformanceHistoryDataKeys
14
+
15
+ # Generates graphs for the past 24 hours for :search, :fetch, and :all actions for each authority.
16
+ # @param force [Boolean] if true, run the tests even if the cache hasn't expired; otherwise, use cache if not expired
17
+ def generate_graphs(force: false)
18
+ QaServer.config.monitor_logger.debug("(QaServer::PerformanceHourlyGraphCache) - GENERATING hourly performance graphs (force: #{force})")
19
+ QaServer.config.performance_cache.write_all
20
+ generate_graphs_for_authorities(force: force)
21
+ end
22
+
23
+ private
24
+
25
+ def generate_graphs_for_authorities(force:)
26
+ auths = authority_list_class.authorities_list
27
+ generate_graphs_for_authority(authority_name: ALL_AUTH, force: force) # generates graph for all authorities
28
+ auths.each { |authname| generate_graphs_for_authority(authority_name: authname, force: force) }
29
+ end
30
+
31
+ def generate_graphs_for_authority(authority_name:, force:)
32
+ [SEARCH, FETCH, ALL_ACTIONS].each_with_object({}) do |action, hash|
33
+ hash[action] = generate_24_hour_graph(authority_name: authority_name, action: action, force: force)
34
+ end
35
+ end
36
+
37
+ def generate_24_hour_graph(authority_name:, action:, force:)
38
+ graph_created = false
39
+ data = Rails.cache.fetch(cache_key_for_authority_action(authority_name: authority_name, action: action),
40
+ expires_in: QaServer::TimeService.current_time.end_of_hour - QaServer::TimeService.current_time,
41
+ race_condition_ttl: 1.hour, force: force) do
42
+ data = graph_data_service.calculate_last_24_hours(authority_name: authority_name, action: action)
43
+ graphing_service.generate_hourly_graph(authority_name: authority_name, action: action, data: data)
44
+ graph_created = true
45
+ data
46
+ end
47
+ regen_last_hour_and_graph(authority_name: authority_name, action: action, data: data) unless graph_created
48
+ end
49
+
50
+ def regen_last_hour_and_graph(authority_name:, action:, data:)
51
+ Rails.cache.fetch(cache_key_for_authority_action(authority_name: authority_name, action: action),
52
+ expires_in: QaServer::TimeService.current_time.end_of_hour - QaServer::TimeService.current_time,
53
+ race_condition_ttl: 1.hour, force: true) do
54
+ data = graph_data_service.recalculate_last_hour(authority_name: authority_name, action: action, averages: data)
55
+ graphing_service.generate_hourly_graph(authority_name: authority_name, action: action, data: data)
56
+ data
57
+ end
58
+ end
59
+
60
+ def cache_key_for_authority_action(authority_name:, action:)
61
+ "#{PERFORMANCE_GRAPH_HOURLY_DATA_CACHE_KEY}--#{authority_name}--#{action}"
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+ # Generate graphs for the past 12 months using cached data. Graphs are generated only if the cache has expired.
3
+ module QaServer
4
+ class PerformanceMonthlyGraphCache
5
+ class_attribute :authority_list_class, :graph_data_service, :graphing_service
6
+ self.authority_list_class = QaServer::AuthorityListerService
7
+ self.graph_data_service = QaServer::PerformanceGraphDataService
8
+ self.graphing_service = QaServer::PerformanceGraphingService
9
+
10
+ class << self
11
+ include QaServer::CacheKeys
12
+ include QaServer::PerformanceHistoryDataKeys
13
+
14
+ # Generates graphs for the past 30 days for :search, :fetch, and :all actions for each authority.
15
+ # @param force [Boolean] if true, run the tests even if the cache hasn't expired; otherwise, use cache if not expired
16
+ def generate_graphs(force: false)
17
+ return unless QaServer::CacheExpiryService.cache_expired?(key: cache_key_for_force, force: force, next_expiry: next_expiry)
18
+ QaServer.config.monitor_logger.debug("(QaServer::PerformanceMonthlyGraphCache) - GENERATING monthly performance graphs (force: #{force})")
19
+ generate_graphs_for_authorities
20
+ end
21
+
22
+ private
23
+
24
+ def generate_graphs_for_authorities
25
+ auths = authority_list_class.authorities_list
26
+ generate_graphs_for_authority(authority_name: ALL_AUTH) # generates graph for all authorities
27
+ auths.each { |authname| generate_graphs_for_authority(authority_name: authname) }
28
+ end
29
+
30
+ def generate_graphs_for_authority(authority_name:)
31
+ [SEARCH, FETCH, ALL_ACTIONS].each_with_object({}) do |action, hash|
32
+ hash[action] = generate_12_month_graph(authority_name: authority_name, action: action)
33
+ end
34
+ end
35
+
36
+ def generate_12_month_graph(authority_name:, action:)
37
+ # real expiration or force caught by cache_expired? So if we are here, either the cache has expired
38
+ # or force was requested. We still expire the cache and use ttl to catch race conditions.
39
+ Rails.cache.fetch(cache_key_for_authority_action(authority_name: authority_name, action: action),
40
+ expires_in: next_expiry, race_condition_ttl: 1.hour, force: true) do
41
+ data = graph_data_service.calculate_last_12_months(authority_name: authority_name, action: action)
42
+ graphing_service.generate_monthly_graph(authority_name: authority_name, action: action, data: data)
43
+ data
44
+ end
45
+ end
46
+
47
+ def cache_key_for_authority_action(authority_name:, action:)
48
+ "#{PERFORMANCE_GRAPH_MONTHLY_DATA_CACHE_KEY}--#{authority_name}--#{action}"
49
+ end
50
+
51
+ def cache_key_for_force
52
+ "#{PERFORMANCE_GRAPH_MONTHLY_DATA_CACHE_KEY}--force"
53
+ end
54
+
55
+ def next_expiry
56
+ QaServer::CacheExpiryService.cache_expiry
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ # Maintain a cache of data for Authority Connection History table displayed on Monitor Status page
3
+ module QaServer
4
+ class ScenarioHistoryCache
5
+ class_attribute :scenario_history_class
6
+ self.scenario_history_class = QaServer::ScenarioRunHistory
7
+
8
+ class << self
9
+ include QaServer::CacheKeys
10
+
11
+ # Get a summary of the number of days passing/failing for scenario runs during configured time period
12
+ # @param force [Boolean] if true, run the tests even if the cache hasn't expired; otherwise, use cache if not expired
13
+ # @returns [Array<Hash>] count of days with passing/failing tests for each authority
14
+ # @example [auth_name, failing, passing]
15
+ # { 'agrovoc' => { good: 31, bad: 2 },
16
+ # 'geonames_ld4l_cache' => { good: 32, bad: 1 } }
17
+ def historical_summary(force: false)
18
+ Rails.cache.fetch(cache_key_for_historical_data, expires_in: next_expiry, race_condition_ttl: 30.seconds, force: force) do
19
+ QaServer.config.monitor_logger.debug("(QaServer::ScenarioHistoryCache) - CALCULATING HISTORY of scenario runs (force: force)")
20
+ scenario_history_class.historical_summary
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def cache_key_for_historical_data
27
+ SCENARIO_RUN_HISTORY_DATA_CACHE_KEY
28
+ end
29
+
30
+ def next_expiry
31
+ QaServer::CacheExpiryService.cache_expiry
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ # Maintain a cache controlling the execution of scenario tests.
3
+ module QaServer
4
+ class ScenarioRunCache
5
+ class << self
6
+ include QaServer::CacheKeys
7
+
8
+ # Run connection tests
9
+ def run_tests(force: false)
10
+ Rails.cache.fetch(cache_key_for_running_tests, expires_in: next_expiry, race_condition_ttl: 30.seconds, force: force) do
11
+ QaServer.config.monitor_logger.debug("(QaServer::ScenarioRunCache) - KICKING OFF TEST RUN (force: #{force})")
12
+ QaServer::MonitorTestsJob.perform_later
13
+ "Test run initiated at #{QaServer::TimeService.current_time}"
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def cache_key_for_running_tests
20
+ SCENARIO_RUN_TEST_DATA_CACHE_KEY
21
+ end
22
+
23
+ def next_expiry
24
+ QaServer::CacheExpiryService.cache_expiry
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+ # Maintain a cache of failure data for scenario runs
3
+ module QaServer
4
+ class ScenarioRunFailuresCache
5
+ class_attribute :scenario_history_class
6
+ self.scenario_history_class = QaServer::ScenarioRunHistory
7
+
8
+ class << self
9
+ include QaServer::CacheKeys
10
+
11
+ # Set of failures for a run
12
+ # @param run [QaServer::ScenarioRunRegistry]
13
+ # @returns [Array<Hash>] details for any failing scenarios in the run
14
+ # @example
15
+ # [ { status: :bad,
16
+ # authority_name: "geonames_ld4l_cache",
17
+ # subauthority_name: "area",
18
+ # service: "ld4l_cache",
19
+ # action: "search",
20
+ # url: "/qa/search/linked_data/geonames_ld4l_cache/area?q=France&maxRecords=4",
21
+ # err_message: "Unable to connect to authority",
22
+ # scenario_type: :connection
23
+ # run_time: 11.2 },
24
+ # { status: :unknown,
25
+ # authority_name: "oclcfast_ld4l_cache",
26
+ # subauthority_name: "Person",
27
+ # service: "ld4l_cache",
28
+ # action: "search",
29
+ # url: "/qa/search/linked_data/oclcfast_ld4l_cache/person?q=mark twain&maxRecords=4",
30
+ # err_message: "Not enough search results returned",
31
+ # scenario_type: :connection
32
+ # run_time: 0.123 } ]
33
+ def failures_for_run(run:)
34
+ Rails.cache.fetch(cache_key_for_run_failures(run.id), expires_in: next_expiry, race_condition_ttl: 30.seconds) do
35
+ QaServer.config.monitor_logger.debug("(QaServer::ScenarioRunFailuresCache) - CALCULATING FAILURES for scenario run #{run.id}")
36
+ scenario_history_class.run_failures(run_id: run.id)
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def cache_key_for_run_failures(id)
43
+ "#{SCENARIO_RUN_FAILURE_DATA_CACHE_KEY}--#{id}{"
44
+ end
45
+
46
+ def next_expiry
47
+ QaServer::CacheExpiryService.cache_expiry
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+ # Maintain a cache of summary test data for scenario runs
3
+ module QaServer
4
+ class ScenarioRunSummaryCache
5
+ class_attribute :scenario_history_class
6
+ self.scenario_history_class = QaServer::ScenarioRunHistory
7
+
8
+ class << self
9
+ include QaServer::CacheKeys
10
+
11
+ # Summary for a run
12
+ # @param run [QaServer::ScenarioRunRegistry]
13
+ # @returns [QaServer::ScenarioRunSummary] statistics on the requested run
14
+ # @example ScenarioRunSummary includes methods for accessing
15
+ # * run_id [Integer] e.g. 14
16
+ # * run_dt_stamp [ActiveSupport::TimeWithZone] e.g. Wed, 19 Feb 2020 16:01:07 UTC +00:00
17
+ # * authority_count [Integer] e.g. 22
18
+ # * failing_authority_count [Integer] e.g. 1
19
+ # * passing_scenario_count [Integer] e.g. 156
20
+ # * failing_scenario_count [Integer] e.g. 3
21
+ # * total_scenario_count [Integer] e.g. 159
22
+ def summary_for_run(run:)
23
+ Rails.cache.fetch(cache_key_for_run_summary(run.id), expires_in: next_expiry, race_condition_ttl: 30.seconds) do
24
+ QaServer.config.monitor_logger.debug("(QaServer::ScenarioRunSummaryCache) - CALCULATING SUMMARY for scenario run #{run.id}")
25
+ scenario_history_class.run_summary(scenario_run: run)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def cache_key_for_run_summary(id)
32
+ "#{SCENARIO_RUN_SUMMARY_DATA_CACHE_KEY}--#{id}"
33
+ end
34
+
35
+ def next_expiry
36
+ QaServer::CacheExpiryService.cache_expiry
37
+ end
38
+ end
39
+ end
40
+ end
@@ -7,78 +7,63 @@ module QaServer
7
7
  include QaServer::AuthorityValidationBehavior
8
8
 
9
9
  class_attribute :presenter_class,
10
- :scenario_run_registry_class,
11
- :scenario_history_class,
12
- :performance_history_class,
13
- :graphing_service_class
10
+ :scenario_run_registry_class
14
11
  self.presenter_class = QaServer::MonitorStatusPresenter
15
12
  self.scenario_run_registry_class = QaServer::ScenarioRunRegistry
16
- self.scenario_history_class = QaServer::ScenarioRunHistory
17
- self.performance_history_class = QaServer::PerformanceHistory
18
- self.graphing_service_class = QaServer::PerformanceGraphingService
19
13
 
20
14
  # Sets up presenter with data to display in the UI
21
15
  def index
22
16
  log_header
23
- latest_test_run
17
+ update_tests
18
+ update_performance_graphs
24
19
  commit_cache if commit_cache?
25
20
  @presenter = presenter_class.new(current_summary: latest_summary,
26
21
  current_failure_data: latest_failures,
27
22
  historical_summary_data: historical_data,
28
23
  performance_data: performance_table_data)
29
- update_performance_graphs
30
- QaServer.config.monitor_logger.debug("(#{self.class}##{__method__}) DONE rendering")
24
+ QaServer.config.monitor_logger.debug("~~~~~~~~ DONE rendering monitor status")
31
25
  render 'index', status: :internal_server_error if latest_summary.failing_authority_count.positive?
32
26
  end
33
27
 
34
28
  private
35
29
 
36
- # Sets @latest_test_run [QaServer::ScenarioRunRegistry]
37
- def latest_test_run
38
- @latest_test_run ||= latest_test_run_from_cache
30
+ def update_tests
31
+ QaServer::ScenarioRunCache.run_tests(force: refresh_tests?)
39
32
  end
40
33
 
41
- # cache of latest run; runs tests if cache is expired
42
- # @see #latest_test_run_from_temp_cache
43
- def latest_test_run_from_cache
44
- Rails.cache.fetch("#{self.class}/#{__method__}", expires_in: QaServer::MonitorCacheService.cache_expiry, race_condition_ttl: 5.minutes, force: refresh_tests?) do
45
- QaServer.config.monitor_logger.debug("(#{self.class}##{__method__}) get latest run of monitoring tests - cache expired or refresh requested (force: #{refresh_tests?})")
46
- QaServer::MonitorTestsJob.perform_later
47
- scenario_run_registry_class.latest_run
48
- end
34
+ # Sets @latest_test_run [QaServer::ScenarioRunRegistry]
35
+ def latest_test_run
36
+ @latest_test_run ||= scenario_run_registry_class.latest_run
49
37
  end
50
38
 
51
- # Sets @latest_summary [QaServer::ScenarioRunSummary]
39
+ # @returns [QaServer::ScenarioRunSummary] summary statistics on the latest run
52
40
  def latest_summary
53
- scenario_history_class.run_summary(scenario_run: latest_test_run, force: refresh_tests?)
41
+ QaServer::ScenarioRunSummaryCache.summary_for_run(run: latest_test_run)
54
42
  end
55
43
 
44
+ # @returns [Array<Hash>] scenario details for any failing scenarios in the latest run
45
+ # @see QaServer::ScenarioRunHistory#run_failures for structure of output
56
46
  def latest_failures
57
- scenario_history_class.run_failures(run_id: latest_test_run.id, force: refresh_tests?)
47
+ QaServer::ScenarioRunFailuresCache.failures_for_run(run: latest_test_run)
58
48
  end
59
49
 
60
- # Sets @historical_data [Array<Hash>]
50
+ # Get a summary level of historical data
51
+ # @returns [Array<Hash>] summary of passing/failing tests for each authority
52
+ # @see QaServer::ScenarioRunHistory#historical_summary for structure of output
61
53
  def historical_data
62
- scenario_history_class.historical_summary(force: refresh_history?)
54
+ QaServer::ScenarioHistoryCache.historical_summary(force: refresh_history?)
63
55
  end
64
56
 
65
- # Sets @performance_table_data [Hash<Hash>]
66
57
  def performance_table_data
67
- display_performance_datatable? ? performance_history_class.performance_table_data(force: refresh_performance?) : {}
58
+ return {} unless QaServer.config.display_performance_graph?
59
+ QaServer::PerformanceDatatableCache.data(force: refresh_performance_table?)
68
60
  end
69
61
 
70
62
  def update_performance_graphs
71
- return unless display_performance_graph?
72
- data = performance_history_class.performance_graph_data(force: refresh_performance?)
73
- graphing_service_class.create_performance_graphs(performance_data: data)
74
- end
75
-
76
- def display_performance_datatable?
77
- @display_performance_datatable ||= QaServer.config.display_performance_datatable?
78
- end
79
-
80
- def display_performance_graph?
81
- @display_performance_graph ||= QaServer.config.display_performance_graph?
63
+ return unless QaServer.config.display_performance_graph?
64
+ QaServer::PerformanceHourlyGraphCache.generate_graphs(force: refresh_performance_graphs?)
65
+ QaServer::PerformanceDailyGraphCache.generate_graphs(force: refresh_performance_graphs?)
66
+ QaServer::PerformanceMonthlyGraphCache.generate_graphs(force: refresh_performance_graphs?)
82
67
  end
83
68
 
84
69
  def refresh?
@@ -91,18 +76,23 @@ module QaServer
91
76
  end
92
77
 
93
78
  def refresh_tests?
94
- return false unless refresh?
95
- refresh_all? || params[:refresh].casecmp?('tests')
79
+ refresh? ? (refresh_all? || params[:refresh].casecmp?('tests')) : false
96
80
  end
97
81
 
98
82
  def refresh_history?
99
- return false unless refresh?
100
- refresh_all? || params[:refresh].casecmp?('history')
83
+ refresh? ? (refresh_all? || params[:refresh].casecmp?('history')) : false
101
84
  end
102
85
 
103
86
  def refresh_performance?
104
- return false unless refresh?
105
- refresh_all? || params[:refresh].casecmp?('performance')
87
+ refresh? ? (refresh_all? || params[:refresh].casecmp?('performance')) : false
88
+ end
89
+
90
+ def refresh_performance_table?
91
+ refresh? ? (refresh_performance? || params[:refresh].casecmp?('performance_table')) : false
92
+ end
93
+
94
+ def refresh_performance_graphs?
95
+ refresh? ? (refresh_performance? || params[:refresh].casecmp?('performance_graphs')) : false
106
96
  end
107
97
 
108
98
  def commit_cache?
@@ -124,9 +114,10 @@ module QaServer
124
114
  end
125
115
 
126
116
  def log_header
127
- QaServer.config.monitor_logger.debug("------------------------------------- monitor status ---------------------------------")
128
- QaServer.config.monitor_logger.debug("(#{self.class}##{__method__}) monitor status page request (refresh_tests? # #{refresh_tests?}, " \
129
- "refresh_history? # #{refresh_history?}, refresh_performance? # #{refresh_performance?})")
117
+ QaServer.config.monitor_logger.debug("------------------------------------ monitor status -----------------------------------")
118
+ QaServer.config.monitor_logger.debug("refresh_all? #{refresh_all?}, refresh_tests? #{refresh_tests?}, refresh_history? #{refresh_history?}")
119
+ QaServer.config.monitor_logger.debug("refresh_performance? #{refresh_performance?}, refresh_performance_table? #{refresh_performance_table?}, " \
120
+ "refresh_performance_graphs? #{refresh_performance_graphs?})")
130
121
  end
131
122
  end
132
123
  end
@@ -10,7 +10,7 @@ module QaServer
10
10
  self.scenario_run_registry_class = QaServer::ScenarioRunRegistry
11
11
 
12
12
  def perform
13
- Rails.cache.fetch("QaServer::MonitorStatusController/latest_test_run_from_cache", expires_in: QaServer::MonitorCacheService.cache_expiry, race_condition_ttl: 5.minutes, force: true) do
13
+ Rails.cache.fetch("QaServer::MonitorStatusController/latest_test_run_from_cache", expires_in: QaServer::CacheExpiryService.cache_expiry, race_condition_ttl: 5.minutes, force: true) do
14
14
  job_id = SecureRandom.uuid
15
15
  monitor_tests_job_id = job_id unless monitor_tests_job_id
16
16
  run_tests if monitor_tests_job_id == job_id # avoid race conditions