qa_server 5.1.0 → 5.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 91196c2e5b8c6f31cb7c3e38e6fd7567cae793f8
4
- data.tar.gz: 3fa8f94c8f584a7e9110d5a046bc5abf234e9f28
3
+ metadata.gz: 26e45e1d4aa00f3f8fd82cdd24e412477ea2b448
4
+ data.tar.gz: c42568892610df1b1be0fae23b5bf5ae9dae2e3a
5
5
  SHA512:
6
- metadata.gz: 46dd223510421a7a72f1c1f507ea2e33b2dd1064595fafd783b17f9f555056cb44b5f6e744afd1b08dcbbbabe77fa309e73f5e7fe4d1c84280efa69dc443b45a
7
- data.tar.gz: bcecafa888be4eeaf4dc6bfb44acd6b4b70b4b239e8de64b12138945e6c8930b268ad40487d14da36d8e8ab7a7779df2f472c9c1e70efbf659ca5c7d3d17efc9
6
+ metadata.gz: 4e80f46f48200d0788b687ac06ae49d93ee2530bd511465fa4e0f2203cd468c81765b13098aff93116168b85491e292353d7f0dc0fdb80d2b68bb0ee6c054233
7
+ data.tar.gz: 94d8b59f177c37c7458495586b4c4334afb38d6e40cf8d1324ca3f5b823d3c3d73d87d636a724356d362556649e716cf51f411f4876e447a71e3fdf1358cbb0c
data/.rubocop.yml CHANGED
@@ -11,8 +11,14 @@ AllCops:
11
11
  - 'script/**/*'
12
12
  - 'spec/test_app_templates/**/*'
13
13
  - 'vendor/**/*'
14
- - 'lib/hyrax/specs/**/*'
14
+ - 'lib/qa_server/specs/**/*'
15
15
 
16
16
  Lint/ImplicitStringConcatenation:
17
17
  Exclude:
18
18
  - 'lib/generators/qa_server/**/*'
19
+
20
+ Metrics/BlockLength:
21
+ ExcludedMethods: ['included']
22
+ Exclude:
23
+ - 'qa_server.gemspec'
24
+ - 'spec/**/*.rb'
data/.rubocop_fixme.yml CHANGED
@@ -8,3 +8,7 @@ Lint/RescueException:
8
8
  Lint/UnusedMethodArgument:
9
9
  Exclude:
10
10
  - 'app/models/qa_server/authority_scenario.rb'
11
+
12
+ Style/SpecialGlobalVars:
13
+ Exclude:
14
+ - 'tasks/qa_server_dev.rake'
data/.travis.yml ADDED
@@ -0,0 +1,35 @@
1
+ language: ruby
2
+ sudo: required
3
+ dist: trusty
4
+
5
+ addons:
6
+ chrome: stable
7
+ cache:
8
+ bundler: true
9
+
10
+ before_install:
11
+ - gem update --system
12
+ - gem install bundler
13
+ - google-chrome-stable --headless --disable-gpu --no-sandbox --remote-debugging-port=9222 http://localhost &
14
+
15
+ rvm:
16
+ - 2.4.6
17
+ - 2.5.5
18
+ - 2.6.3
19
+
20
+ env:
21
+ global:
22
+ - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
23
+ - ENGINE_CART_RAILS_OPTIONS='--skip-git --skip-bundle --skip-listen --skip-spring --skip-yarn --skip-keeps --skip-action-cable --skip-coffee --skip-puma --skip-test'
24
+ # Travis should check every minor version in a range of supported versions, because
25
+ # rails does not follow sem-ver conventions, see http://guides.rubyonrails.org/maintenance_policy.html
26
+ # It should be sufficient to test only the latest of the patch versions for a minor version, they
27
+ # should be compatible across patch versions (only bug fixes are released in patch versions).
28
+ matrix:
29
+ - "RAILS_VERSION=5.1.7"
30
+ - "RAILS_VERSION=5.2.3"
31
+
32
+ services:
33
+ - redis-server
34
+ before_script:
35
+ - jdk_switcher use oraclejdk8
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ### 5.2.0 (2019-12-10)
2
+
3
+ * cache performance data saving once a day when monitoring runs
4
+ * set monitoring to expire at 3am ET by default (configurable)
5
+ * setup travis-ci to run
6
+
1
7
  ### 5.1.0 (2019-12-10)
2
8
 
3
9
  * allow suppression of performance data gathering
data/Gemfile CHANGED
@@ -1,11 +1,16 @@
1
1
  # frozen_string_literal: true
2
- source 'https://rubygems.org'
3
- git_source(:github) { |repo| "https://github.com/#{repo}.git" }
2
+ source "https://rubygems.org"
3
+ # git_source(:github) { |repo| "https://github.com/#{repo}.git" }
4
4
 
5
5
  # Declare your gem's dependencies in qa_server.gemspec.
6
6
  # Bundler will treat runtime dependencies like base dependencies, and
7
7
  # development dependencies will be added by default to the :development group.
8
- gemspec
8
+ gemspec path: File.expand_path('..', __FILE__)
9
+
10
+ group :development, :test do
11
+ gem 'coveralls', require: false
12
+ gem 'simplecov', require: false
13
+ end
9
14
 
10
15
  # Declare any dependencies that are still in development here instead of in
11
16
  # your gemspec. These might include edge Rails or gems from your path or
@@ -15,7 +20,6 @@ gemspec
15
20
  # To use a debugger
16
21
  # gem 'byebug', group: [:development, :test]
17
22
 
18
- # rubocop:disable Bundler/DuplicatedGem
19
23
  # BEGIN ENGINE_CART BLOCK
20
24
  # engine_cart: 1.1.0
21
25
  # engine_cart stanza: 0.10.0
@@ -31,6 +35,7 @@ if File.exist?(file)
31
35
  else
32
36
  Bundler.ui.warn "[EngineCart] Unable to find test application dependencies in #{file}, using placeholder dependencies"
33
37
 
38
+ # rubocop:disable Bundler/DuplicatedGem
34
39
  if ENV['RAILS_VERSION']
35
40
  if ENV['RAILS_VERSION'] == 'edge'
36
41
  gem 'rails', github: 'rails/rails'
@@ -41,6 +46,8 @@ else
41
46
  end
42
47
 
43
48
  case ENV['RAILS_VERSION']
49
+ when /^5.[12]/
50
+ gem 'sass-rails', '~> 5.0'
44
51
  when /^4.2/
45
52
  gem 'coffee-rails', '~> 4.1.0'
46
53
  gem 'responders', '~> 2.0'
@@ -48,8 +55,8 @@ else
48
55
  when /^4.[01]/
49
56
  gem 'sass-rails', '5.1.6'
50
57
  end
58
+ # rubocop:enable Bundler/DuplicatedGem
51
59
  end
52
60
  # END ENGINE_CART BLOCK
53
- # rubocop:enable Bundler/DuplicatedGem
54
61
 
55
62
  eval_gemfile File.expand_path('spec/test_app_templates/Gemfile.extra', File.dirname(__FILE__)) unless File.exist?(file)
@@ -44,11 +44,7 @@ module QaServer
44
44
  end
45
45
 
46
46
  def expired?
47
- @expired ||= latest_summary.blank? || latest_summary.run_dt_stamp < yesterday_midnight_et
48
- end
49
-
50
- def yesterday_midnight_et
51
- (DateTime.yesterday.midnight.to_time + 4.hours).to_datetime.in_time_zone("Eastern Time (US & Canada)")
47
+ @expired ||= latest_summary.blank? || latest_summary.run_dt_stamp < QaServer.monitoring_expires_at
52
48
  end
53
49
 
54
50
  def historical_summary_data(refresh: false)
@@ -116,8 +112,8 @@ module QaServer
116
112
  end
117
113
 
118
114
  def refresh_performance?
119
- return false unless refresh?
120
- refresh_all? || params[:refresh].casecmp?('performance')
115
+ return false unless refresh? || expired?
116
+ refresh_all? || params[:refresh].casecmp?('performance') || expired?
121
117
  end
122
118
  end
123
119
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+ # Model to hold performance data in memory and ultimately write it out to the database
3
+ module QaServer
4
+ class PerformanceCache
5
+ def initialize
6
+ @cache = {}
7
+ end
8
+
9
+ def new_entry(authority:, action:)
10
+ entry = { dt_stamp: QaServer.current_time,
11
+ authority: authority,
12
+ action: action }
13
+ id = SecureRandom.uuid
14
+ @cache[id] = entry
15
+ id
16
+ end
17
+
18
+ def update(id:, updates: {})
19
+ return false unless id && @cache.key?(id)
20
+ entry = @cache[id]
21
+ @cache[id] = entry.merge(updates)
22
+ end
23
+
24
+ def destroy(id)
25
+ @cache.delete(id)
26
+ end
27
+
28
+ def write_all
29
+ size_before = @cache.size
30
+ @cache.each do |id, entry|
31
+ next if incomplete? entry
32
+ QaServer::PerformanceHistory.create(dt_stamp: entry[:dt_stamp], authority: entry[:authority],
33
+ action: entry[:action], action_time_ms: entry[:action_time_ms],
34
+ size_bytes: entry[:size_bytes], retrieve_time_ms: entry[:retrieve_time_ms],
35
+ graph_load_time_ms: entry[:graph_load_time_ms],
36
+ normalization_time_ms: entry[:normalization_time_ms])
37
+ @cache.delete(id)
38
+ end
39
+ Rails.logger.warn("0 of #{size_before} performance data records were saved") if size_before.positive? && (size_before == @cache.size)
40
+ Rails.logger.info("#{size_before - @cache.size} of #{size_before} performance data records were saved") if size_before.positive? && (size_before > @cache.size)
41
+ end
42
+
43
+ def log(id:)
44
+ Rails.logger.info("*** performance data for id: #{id} ***")
45
+ Rails.logger.info(@cache[id].to_yaml)
46
+ end
47
+
48
+ private
49
+
50
+ def incomplete?(entry)
51
+ required_keys.each { |k| return true unless entry.key? k }
52
+ false
53
+ end
54
+
55
+ def required_keys
56
+ [:dt_stamp,
57
+ :authority,
58
+ :action,
59
+ :action_time_ms,
60
+ :size_bytes,
61
+ :retrieve_time_ms,
62
+ :graph_load_time_ms,
63
+ :normalization_time_ms]
64
+ end
65
+ end
66
+ end
@@ -18,9 +18,10 @@ module QaServer
18
18
  # Save a scenario result
19
19
  # @param authority [String] name of the authority
20
20
  # @param action [Symbol] type of action being evaluated (e.g. :fetch, :search)
21
+ # @param dt_stamp [Time] defaults to current time in preferred time zone
21
22
  # @return ActveRecord::Base for the new performance history record
22
- def create_record(authority:, action:)
23
- create(dt_stamp: Time.now.getlocal,
23
+ def create_record(authority:, action:, dt_stamp: QaServer.current_time)
24
+ create(dt_stamp: dt_stamp,
24
25
  authority: authority,
25
26
  action: action)
26
27
  end
@@ -65,6 +66,7 @@ module QaServer
65
66
  # }
66
67
  def performance_data(datatype: :datatable)
67
68
  return if datatype == :none
69
+ QaServer.config.performance_cache.write_all
68
70
  data = calculate_data(datatype)
69
71
  graphing_service_class.create_performance_graphs(performance_data: data) if calculate_graphdata? datatype
70
72
  data
@@ -124,7 +126,7 @@ module QaServer
124
126
 
125
127
  def records_for_last_24_hours(auth_name)
126
128
  return unless expected_time_period == :day
127
- end_hour = Time.now.getlocal
129
+ end_hour = QaServer.current_time
128
130
  start_hour = end_hour - 23.hours
129
131
  where_clause = { dt_stamp: start_hour..end_hour }
130
132
  records_for_authority(auth_name, where_clause)
@@ -132,7 +134,7 @@ module QaServer
132
134
 
133
135
  def records_for_last_30_days(auth_name)
134
136
  return unless expected_time_period == :month
135
- end_day = Time.now.getlocal
137
+ end_day = QaServer.current_time
136
138
  start_day = end_day - 29.days
137
139
  where_clause = { dt_stamp: start_day..end_day }
138
140
  records_for_authority(auth_name, where_clause)
@@ -140,7 +142,7 @@ module QaServer
140
142
 
141
143
  def records_for_last_12_months(auth_name)
142
144
  return unless expected_time_period == :year
143
- end_month = Time.now.getlocal
145
+ end_month = QaServer.current_time
144
146
  start_month = end_month - 11.months
145
147
  where_clause = { dt_stamp: start_month..end_month }
146
148
  records_for_authority(auth_name, where_clause)
@@ -2,20 +2,20 @@
2
2
  module PrependedLinkedData::FindTerm
3
3
  # Override Qa::Authorities::LinkedData::FindTerm#find method
4
4
  # @return [Hash] single term results in requested format
5
- def find(id, request_header: {}, language: nil, replacements: {}, subauth: nil, format: nil, performance_data: false) # rubocop:disable Metrics/ParameterLists
5
+ def find(id, request_header: {}, language: nil, replacements: {}, subauth: nil, format: nil, performance_data: false) # rubocop:disable Metrics/ParameterLists, Metrics/CyclomaticComplexity
6
6
  return super if QaServer.config.suppress_performance_gathering
7
7
 
8
- start_time_s = Time.now.to_f
8
+ start_time_s = QaServer.current_time_s
9
9
  request_header = build_request_header(language: language, replacements: replacements, subauth: subauth, format: format, performance_data: performance_data) if request_header.empty?
10
10
  saved_performance_data = performance_data || request_header[:performance_data]
11
11
  request_header[:performance_data] = true
12
- ph_record = QaServer::PerformanceHistory.create_record(authority: authority_name, action: 'fetch')
13
- @phid = ph_record.id
12
+
13
+ @phid = QaServer.config.performance_cache.new_entry(authority: authority_name, action: 'fetch')
14
14
  begin
15
15
  full_results = super
16
16
  update_performance_history_record(full_results, start_time_s)
17
17
  rescue Exception => e # rubocop:disable Lint/RescueException
18
- ph_record.destroy
18
+ QaServer.config.performance_cache.destroy(@phid)
19
19
  raise e
20
20
  end
21
21
  saved_performance_data || !full_results.is_a?(Hash) ? full_results : full_results[:results]
@@ -24,25 +24,25 @@ module PrependedLinkedData::FindTerm
24
24
  private
25
25
 
26
26
  def update_performance_history_record(full_results, start_time_s)
27
- ph_record = QaServer::PerformanceHistory.find(@phid)
28
- return ph_record.destroy unless full_results.is_a?(Hash) && full_results.key?(:performance)
29
- ph_record.action_time_ms = (Time.now.to_f - start_time_s) * 1000
30
- ph_record.size_bytes = full_results[:performance][:fetched_bytes]
31
- ph_record.retrieve_plus_graph_load_time_ms = full_results[:performance][:fetch_time_s] * 1000
32
- ph_record.normalization_time_ms = full_results[:performance][:normalization_time_s] * 1000
33
- ph_record.save
27
+ return QaServer.config.performance_cache.destroy(@phid) unless full_results.is_a?(Hash) && full_results.key?(:performance)
28
+ updates = { action_time_ms: (QaServer.current_time_s - start_time_s) * 1000,
29
+ size_bytes: full_results[:performance][:fetched_bytes],
30
+ retrieve_plus_graph_load_time_ms: full_results[:performance][:fetch_time_s] * 1000,
31
+ normalization_time_ms: full_results[:performance][:normalization_time_s] * 1000 }
32
+ QaServer.config.performance_cache.update(id: @phid, updates: updates)
33
+ QaServer.config.performance_cache.log(id: @phid)
34
34
  end
35
35
 
36
36
  # Override to append performance history record id into the URL to allow access to the record in RDF::Graph
37
37
  def load_graph(url:)
38
38
  return super if QaServer.config.suppress_performance_gathering
39
39
 
40
- access_start_dt = Time.now.utc
40
+ access_start_dt = QaServer.current_time
41
41
 
42
42
  url += "&phid=#{@phid}"
43
43
  @full_graph = graph_service.load_graph(url: url)
44
44
 
45
- access_end_dt = Time.now.utc
45
+ access_end_dt = QaServer.current_time
46
46
  @access_time_s = access_end_dt - access_start_dt
47
47
  @fetched_size = full_graph.triples.to_s.size if performance_data?
48
48
  Rails.logger.info("Time to receive data from authority: #{access_time_s}s")
@@ -5,17 +5,17 @@ module PrependedLinkedData::SearchQuery
5
5
  def search(query, request_header: {}, language: nil, replacements: {}, subauth: nil, context: false, performance_data: false) # rubocop:disable Metrics/ParameterLists
6
6
  return super if QaServer.config.suppress_performance_gathering
7
7
 
8
- start_time_s = Time.now.to_f
8
+ start_time_s = QaServer.current_time_s
9
9
  request_header = build_request_header(language: language, replacements: replacements, subauth: subauth, context: context, performance_data: performance_data) if request_header.empty?
10
10
  saved_performance_data = performance_data || request_header[:performance_data]
11
11
  request_header[:performance_data] = true
12
- ph_record = QaServer::PerformanceHistory.create_record(authority: authority_name, action: 'search')
13
- @phid = ph_record.id
12
+
13
+ @phid = QaServer.config.performance_cache.new_entry(authority: authority_name, action: 'search')
14
14
  begin
15
15
  full_results = super
16
16
  update_performance_history_record(full_results, start_time_s)
17
17
  rescue Exception => e # rubocop:disable Lint/RescueException
18
- ph_record.destroy
18
+ QaServer.config.performance_cache.destroy(@phid)
19
19
  raise e
20
20
  end
21
21
  requested_results(full_results, saved_performance_data)
@@ -24,25 +24,25 @@ module PrependedLinkedData::SearchQuery
24
24
  private
25
25
 
26
26
  def update_performance_history_record(full_results, start_time_s)
27
- ph_record = QaServer::PerformanceHistory.find(@phid)
28
- return ph_record.destroy unless full_results.is_a?(Hash) && full_results.key?(:performance)
29
- ph_record.action_time_ms = (Time.now.to_f - start_time_s) * 1000
30
- ph_record.size_bytes = full_results[:performance][:fetched_bytes]
31
- ph_record.retrieve_plus_graph_load_time_ms = full_results[:performance][:fetch_time_s] * 1000
32
- ph_record.normalization_time_ms = full_results[:performance][:normalization_time_s] * 1000
33
- ph_record.save
27
+ return QaServer.config.performance_cache.destroy(@phid) unless full_results.is_a?(Hash) && full_results.key?(:performance)
28
+ updates = { action_time_ms: (QaServer.current_time_s - start_time_s) * 1000,
29
+ size_bytes: full_results[:performance][:fetched_bytes],
30
+ retrieve_plus_graph_load_time_ms: full_results[:performance][:fetch_time_s] * 1000,
31
+ normalization_time_ms: full_results[:performance][:normalization_time_s] * 1000 }
32
+ QaServer.config.performance_cache.update(id: @phid, updates: updates)
33
+ QaServer.config.performance_cache.log(id: @phid)
34
34
  end
35
35
 
36
36
  # Override to append performance history record id into the URL to allow access to the record in RDF::Graph
37
37
  def load_graph(url:)
38
38
  return super if QaServer.config.suppress_performance_gathering
39
39
 
40
- access_start_dt = Time.now.utc
40
+ access_start_dt = QaServer.current_time
41
41
 
42
42
  url += "&phid=#{@phid}"
43
43
  @full_graph = graph_service.load_graph(url: url)
44
44
 
45
- access_end_dt = Time.now.utc
45
+ access_end_dt = QaServer.current_time
46
46
  @access_time_s = access_end_dt - access_start_dt
47
47
  @fetched_size = full_graph.triples.to_s.size if performance_data?
48
48
  Rails.logger.info("Time to receive data from authority: #{access_time_s}s")
@@ -16,13 +16,13 @@ module PrependedRdf::RdfGraph
16
16
 
17
17
  raise TypeError, "#{self} is immutable" if immutable?
18
18
  phid, real_url = parse_phid(url)
19
- ph_record = QaServer::PerformanceHistory.find(phid)
19
+ performance_udpates = {}
20
20
  start_time_s = Time.now.to_f
21
21
 
22
22
  reader = RDF::Reader.open(real_url, { base_uri: real_url }.merge(options))
23
23
 
24
24
  end_time_s = Time.now.to_f
25
- ph_record.retrieve_time_ms = (end_time_s - start_time_s) * 1000
25
+ performance_udpates[:retrieve_time_ms] = (end_time_s - start_time_s) * 1000
26
26
  QaServer.config.performance_tracker.write "#{format('%.6f', end_time_s - start_time_s)}, " # read data
27
27
 
28
28
  start_time_s = Time.now.to_f
@@ -41,8 +41,8 @@ module PrependedRdf::RdfGraph
41
41
  end
42
42
 
43
43
  end_time_s = Time.now.to_f
44
- ph_record.graph_load_time_ms = (end_time_s - start_time_s) * 1000
45
- ph_record.save
44
+ performance_udpates[:graph_load_time_ms] = (end_time_s - start_time_s) * 1000
45
+ QaServer.config.performance_cache.update(id: phid, updates: performance_udpates)
46
46
  QaServer.config.performance_tracker.write "#{format('%.6f', end_time_s - start_time_s)}, " # load graph
47
47
  end
48
48
 
@@ -106,7 +106,7 @@ module QaServer::MonitorStatus
106
106
 
107
107
  def unsupported_action?(stats)
108
108
  values = stats.values
109
- return true if values.all? &:zero?
109
+ return true if values.all?(&:zero?)
110
110
  values.any? { |v| v.respond_to?(:nan?) && v.nan? }
111
111
  end
112
112
 
@@ -82,7 +82,7 @@ module QaServer
82
82
 
83
83
  def rework_performance_data_for_gruff(performance_data, label_key)
84
84
  labels = {}
85
- full_load_data = []
85
+ # full_load_data = []
86
86
  retrieve_data = []
87
87
  graph_load_data = []
88
88
  normalization_data = []
@@ -100,7 +100,9 @@ module QaServer
100
100
  # create the graph using the old :load stat when both :retrieve and :graph_load are 0. If the value truly
101
101
  # is 0, then :load will also be 0.
102
102
  # NOTE: It's ok to use AVG_RETR for the retrieve data point because it is 0.
103
+ # rubocop:disable Style/TernaryParentheses
103
104
  (data[STATS][AVG_RETR].zero? && data[STATS][AVG_GRPH].zero?) ? data[STATS][AVG_LOAD] : data[STATS][AVG_GRPH]
105
+ # rubocop:enable Style/TernaryParentheses
104
106
  end
105
107
 
106
108
  def performance_graph_theme(g, x_axis_label)
@@ -59,15 +59,15 @@ module QaServer
59
59
  # Runs the test in the block passed by the specific scenario type.
60
60
  # @return [Symbol] :good (PASS) or :unknown (UNKNOWN) based on whether enough results were returned
61
61
  def test_connection(min_expected_size: MIN_EXPECTED_SIZE, scenario_type_name:)
62
- dt_start = Time.now.utc
62
+ dt_start = QaServer.current_time
63
63
  results = yield if block_given?
64
- dt_end = Time.now.utc
64
+ dt_end = QaServer.current_time
65
65
  actual_size = results.to_s.length
66
66
  status = actual_size > min_expected_size ? PASS : UNKNOWN
67
67
  errmsg = status == PASS ? '' : "#{scenario_type_name.capitalize} scenario unknown status; cause: Results actual size (#{actual_size} < expected size (#{min_expected_size})"
68
68
  log(status: status, error_message: errmsg, normalization_run_time: (dt_end - dt_start)) # TODO: need to get run times from results
69
69
  rescue Exception => e
70
- dt_end = Time.now.utc
70
+ dt_end = QaServer.current_time
71
71
  log(status: FAIL, error_message: "Exception executing #{scenario_type_name} scenario; cause: #{e.message}", request_run_time: (dt_end - dt_start))
72
72
  end
73
73
 
@@ -40,9 +40,9 @@ module QaServer
40
40
 
41
41
  # Runs the accuracy test and log results
42
42
  def test_accuracy(subject_uri:, expected_by_position:)
43
- dt_start = Time.now.utc
43
+ dt_start = QaServer.current_time
44
44
  results = yield if block_given?
45
- dt_end = Time.now.utc
45
+ dt_end = QaServer.current_time
46
46
  if results.blank?
47
47
  log(status: UNKNOWN, errmsg: "Search position scenario failed; cause: no results found", expected: expected_by_position, target: subject_uri, request_run_time: (dt_end - dt_start))
48
48
  return
@@ -50,7 +50,7 @@ module QaServer
50
50
 
51
51
  check_position(results, subject_uri, expected_by_position, total_run_time: (dt_end - dt_start)) # TODO: need to get run times from results
52
52
  rescue Exception => e
53
- dt_end = Time.now.utc
53
+ dt_end = QaServer.current_time
54
54
  log(status: FAIL, errmsg: "Exception executing search position scenario; cause: #{e.message}",
55
55
  expected: expected_by_position, target: subject_uri, request_run_time: (dt_end - dt_start))
56
56
  end
@@ -1,6 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
  module QaServer
3
3
  class Configuration
4
+ # Preferred time zone for reporting historical data and performance data
5
+ # @param [String] time zone name
6
+ # @see https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html for possible values of TimeZone names
7
+ attr_writer :preferred_time_zone_name
8
+ def preferred_time_zone_name
9
+ @preferred_time_zone_name ||= 'Eastern Time (US & Canada)'
10
+ end
11
+
12
+ # Preferred hour to run monitoring tests
13
+ # @param [Integer] count of hours from midnight (0-23 with 0=midnight)
14
+ # @example
15
+ # For preferred_time_zone_name of ET, use 3 for slow down at midnight PT/3am ET
16
+ # For preferred_time_zone_name of PT, use 0 for slow down at midnight PT/3am ET
17
+ attr_writer :hour_offset_to_run_monitoring_tests
18
+ def hour_offset_to_run_monitoring_tests
19
+ @hour_offset_to_run_monitoring_tests ||= 3
20
+ end
21
+
4
22
  # Displays a graph of historical test data when true
5
23
  # @param [Boolean] display history graph when true
6
24
  attr_writer :display_historical_graph
@@ -122,5 +140,9 @@ module QaServer
122
140
  def suppress_performance_gathering
123
141
  @suppress_performance_gathering ||= false
124
142
  end
143
+
144
+ def performance_cache
145
+ @performance_cache ||= QaServer::PerformanceCache.new
146
+ end
125
147
  end
126
148
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module QaServer
3
- VERSION = '5.1.0'
3
+ VERSION = '5.2.0'
4
4
  end
data/lib/qa_server.rb CHANGED
@@ -21,4 +21,17 @@ module QaServer
21
21
 
22
22
  @config
23
23
  end
24
+
25
+ def self.current_time
26
+ Time.now.in_time_zone(QaServer.config.preferred_time_zone_name)
27
+ end
28
+
29
+ def self.current_time_s
30
+ current_time.to_f
31
+ end
32
+
33
+ def self.monitoring_expires_at
34
+ offset = QaServer.config.hour_offset_to_run_monitoring_tests
35
+ (current_time - offset.hours).beginning_of_day + offset.hours
36
+ end
24
37
  end
data/qa_server.gemspec CHANGED
@@ -34,10 +34,24 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency 'better_errors' # provide debugging command line in
35
35
  spec.add_development_dependency 'binding_of_caller' # provides deep stack info used by better_errors
36
36
  spec.add_development_dependency 'bixby', '~> 1.0.0' # rubocop styleguide
37
- # spec.add_development_dependency 'capybara', '~> 2.13'
37
+ # spec.add_development_dependency "capybara", '~> 3.29'
38
+ # spec.add_development_dependency 'capybara-maleficent', '~> 0.3.0'
39
+ # spec.add_development_dependency 'chromedriver-helper', '~> 2.1'
38
40
  spec.add_development_dependency 'engine_cart', '~> 2.0'
41
+ spec.add_development_dependency "factory_bot", '~> 4.4'
42
+ spec.add_development_dependency 'simplecov'
43
+ spec.add_development_dependency 'sqlite3'
44
+ spec.add_development_dependency 'rails-controller-testing', '~> 1'
39
45
  spec.add_development_dependency 'rspec-activemodel-mocks', '~> 1.0'
40
46
  spec.add_development_dependency 'rspec-its', '~> 1.1'
41
47
  spec.add_development_dependency 'rspec-rails', '~> 3.1'
42
- # spec.add_development_dependency 'selenium-webdriver'
48
+ spec.add_development_dependency 'selenium-webdriver'
49
+ spec.add_development_dependency 'webdrivers', '~> 3.0'
50
+ spec.add_development_dependency 'webmock'
51
+
52
+ ########################################################
53
+ # Temporarily pinned dependencies. INCLUDE EXPLANATIONS.
54
+ #
55
+ # Pin sass-rails to 5.x because rails 5.x apps have this same dependency in their generated Gemfiles
56
+ spec.add_dependency 'sass-rails', '~> 5.0'
43
57
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe QaServer do
5
+ # rubocop:disable RSpec/MessageChain
6
+ let(:timezone_name) { 'Eastern Time (US & Canada)' }
7
+ describe '.current_time' do
8
+ before do
9
+ allow(described_class).to receive_message_chain(:config, :preferred_time_zone_name).and_return(timezone_name)
10
+ allow(Time).to receive(:now).and_return(DateTime.parse('2019-12-11 05:00:00 -0500').in_time_zone(timezone_name))
11
+ end
12
+
13
+ it 'returns the time in the preferred time zone' do
14
+ puts 'Running QaServer.current_time spec'
15
+ expect(described_class.current_time.zone).to eq 'EST'
16
+ end
17
+ end
18
+
19
+ describe '.monitoring_expires_at' do
20
+ before do
21
+ allow(described_class).to receive_message_chain(:config, :hour_offset_to_run_monitoring_tests).and_return(3)
22
+ end
23
+
24
+ context 'when current hour is after offset time' do
25
+ before do
26
+ allow(described_class).to receive(:current_time).and_return(DateTime.parse('2019-12-11 05:00:00 -0500').in_time_zone(timezone_name))
27
+ end
28
+
29
+ it 'returns expiration on current date at offset time' do
30
+ puts 'Running QaServer.monitoring_expires_at when current hour is after offset time spec'
31
+ expect(described_class.monitoring_expires_at).to eq DateTime.parse('2019-12-11 03:00:00 -0500').in_time_zone(timezone_name)
32
+ end
33
+ end
34
+
35
+ context 'when current hour is before offset time' do
36
+ before do
37
+ allow(described_class).to receive(:current_time).and_return(DateTime.parse('2019-12-11 01:00:00 -0500').in_time_zone(timezone_name))
38
+ end
39
+
40
+ it 'returns expiration on previous date at offset time' do
41
+ puts 'Running QaServer.monitoring_expires_at when current hour is before offset time spec'
42
+ expect(described_class.monitoring_expires_at).to eq DateTime.parse('2019-12-10 03:00:00 -0500').in_time_zone(timezone_name)
43
+ end
44
+ end
45
+ end
46
+ # rubocop:enable RSpec/MessageChain
47
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,283 +1,64 @@
1
1
  # frozen_string_literal: true
2
- ENV["RAILS_ENV"] ||= 'test'
3
- require "bundler/setup"
2
+ require 'linkeddata'
3
+ require 'json'
4
+ require 'engine_cart'
5
+ require 'simplecov'
6
+ require 'coveralls'
7
+ require 'byebug' unless ENV['TRAVIS']
4
8
 
5
- def coverage_needed?
6
- ENV['COVERAGE'] || ENV['TRAVIS']
7
- end
9
+ ENV["RAILS_ENV"] ||= "test"
8
10
 
9
- if coverage_needed?
10
- require 'simplecov'
11
- require 'coveralls'
12
- SimpleCov.root(File.expand_path('../..', __FILE__))
13
- SimpleCov.formatter = Coveralls::SimpleCov::Formatter
14
- SimpleCov.start('rails') do
15
- add_filter '/.internal_test_app'
16
- add_filter '/lib/generators'
17
- add_filter '/spec'
18
- add_filter '/tasks'
19
- add_filter '/lib/qa_server/version.rb'
20
- add_filter '/lib/qa_server/engine.rb'
21
- end
22
- SimpleCov.command_name 'spec'
11
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
12
+ SimpleCov.start('rails') do
13
+ add_filter '/.internal_test_app'
14
+ add_filter '/lib/generators'
15
+ add_filter '/spec'
16
+ add_filter '/tasks'
17
+ add_filter '/lib/qa/version.rb'
18
+ add_filter '/lib/qa/engine.rb'
23
19
  end
20
+ SimpleCov.command_name 'spec'
24
21
 
25
- require 'factory_bot'
26
- require 'engine_cart'
27
22
  EngineCart.load_application!
23
+ Coveralls.wear!
28
24
 
29
- # require 'devise'
30
- # require 'devise/version'
31
- # require 'mida'
32
- require 'rails-controller-testing'
33
25
  require 'rspec/rails'
34
- require 'rspec/its'
35
- require 'rspec/matchers'
36
- require 'rspec/active_model/mocks'
37
- require 'capybara/rspec'
38
- require 'capybara/rails'
39
- require 'selenium-webdriver'
40
- # require 'equivalent-xml'
41
- # require 'equivalent-xml/rspec_matchers'
42
- # require 'database_cleaner' # TODO: Explore whether to include database cleaner
43
-
44
- unless ENV['SKIP_MALEFICENT']
45
- # See https://github.com/jeremyf/capybara-maleficent
46
- # Wrap Capybara matchers with sleep intervals to reduce fragility of specs.
47
- require 'capybara/maleficent/spindle'
48
-
49
- Capybara::Maleficent.config do |c|
50
- # Quieting down maleficent's logging
51
- logger = Logger.new(STDOUT)
52
- logger.level = Logger::INFO
53
- c.logger = logger
54
- end
55
- end
56
-
57
- # Require supporting ruby files from spec/support/ and subdirectories. Note: engine, not Rails.root context.
58
- Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each { |f| require f }
59
-
60
26
  require 'webmock/rspec'
61
- WebMock.disable_net_connect!(allow_localhost: true)
27
+ # require 'pry'
62
28
 
63
- require 'i18n/debug' if ENV['I18N_DEBUG']
64
- require 'byebug' unless ENV['TRAVIS']
29
+ # Requires supporting ruby files with custom matchers and macros, etc,
30
+ # in spec/support/ and its subdirectories.
31
+ Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each { |f| require f }
65
32
 
66
- # @note In January 2018, TravisCI disabled Chrome sandboxing in its Linux
67
- # container build environments to mitigate Meltdown/Spectre
68
- # vulnerabilities, at which point Qa Server could no longer use the
69
- # Capybara-provided :selenium_chrome_headless driver (which does not
70
- # include the `--no-sandbox` argument).
71
- Capybara.register_driver :selenium_chrome_headless_sandboxless do |app|
72
- browser_options = ::Selenium::WebDriver::Chrome::Options.new
73
- browser_options.args << '--headless'
74
- browser_options.args << '--disable-gpu'
75
- browser_options.args << '--no-sandbox'
76
- Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
77
- end
33
+ RSpec.configure do |config|
34
+ config.fixture_path = File.expand_path("../fixtures", __FILE__)
78
35
 
79
- Capybara.default_driver = :rack_test # This is a faster driver
80
- Capybara.javascript_driver = :selenium_chrome_headless_sandboxless # This is slower
36
+ config.use_transactional_fixtures = true
81
37
 
82
- # ActiveJob::Base.queue_adapter = :test
38
+ # If true, the base class of anonymous controllers will be inferred
39
+ # automatically. This will be the default behavior in future versions of
40
+ # rspec-rails.
41
+ config.infer_base_class_for_anonymous_controllers = false
83
42
 
84
- # require 'http_logger'
85
- # HttpLogger.logger = Logger.new(STDOUT)
86
- # HttpLogger.ignore = [/localhost:8983\/solr/]
87
- # HttpLogger.colorize = false
43
+ # Run specs in random order to surface order dependencies. If you find an
44
+ # order dependency and want to debug it, you can fix the order by providing
45
+ # the seed, which is printed after each run.
46
+ # --seed 1234
47
+ config.order = "random"
88
48
 
89
- # if defined?(ClamAV)
90
- # ClamAV.instance.loaddb
91
- # else
92
- # class ClamAV
93
- # include Singleton
94
- # def scanfile(_f)
95
- # 0
96
- # end
97
- #
98
- # def loaddb
99
- # nil
100
- # end
101
- # end
102
- # end
49
+ # Disable Webmock if we choose so we can test against the authorities, instead of their mocks
50
+ WebMock.disable! if ENV["WEBMOCK"] == "disabled"
103
51
 
104
- # class JsonStrategy
105
- # def initialize
106
- # @strategy = FactoryBot.strategy_by_name(:create).new
107
- # end
108
- #
109
- # delegate :association, to: :@strategy
110
- #
111
- # def result(evaluation)
112
- # @strategy.result(evaluation).to_json
113
- # end
114
- # end
115
- #
116
- # FactoryBot.register_strategy(:json, JsonStrategy)
117
- # FactoryBot.definition_file_paths = [File.expand_path("../factories", __FILE__)]
118
- # FactoryBot.find_definitions
52
+ config.infer_spec_type_from_file_location!
53
+ end
119
54
 
120
- module EngineRoutes
121
- def self.included(base)
122
- base.routes { QaServer::Engine.routes }
123
- end
55
+ def webmock_fixture(fixture)
56
+ File.new File.expand_path(File.join("../fixtures", fixture), __FILE__)
57
+ end
124
58
 
125
- def main_app
126
- Rails.application.class.routes.url_helpers
59
+ # returns the file contents
60
+ def load_fixture_file(fname)
61
+ File.open(Rails.root.join('spec', 'fixtures', fname)) do |f|
62
+ return f.read
127
63
  end
128
64
  end
129
-
130
- # require 'shoulda/matchers'
131
- # require 'shoulda/callback/matchers'
132
- # Shoulda::Matchers.configure do |config|
133
- # config.integrate do |with|
134
- # with.test_framework :rspec
135
- # with.library :rails
136
- # end
137
- # end
138
-
139
- # require 'active_fedora/cleaner'
140
- # RSpec.configure do |config|
141
- # config.disable_monkey_patching!
142
- # config.include Shoulda::Matchers::ActiveRecord, type: :model
143
- # config.include Shoulda::Matchers::ActiveModel, type: :form
144
- # config.include Shoulda::Callback::Matchers::ActiveModel
145
- # config.full_backtrace = true if ENV['TRAVIS']
146
- # config.expect_with :rspec do |c|
147
- # c.syntax = :expect
148
- # end
149
- #
150
- # # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
151
- # config.fixture_path = File.expand_path("../fixtures", __FILE__)
152
- #
153
- # config.use_transactional_fixtures = false
154
- #
155
- # config.before :suite do
156
- # DatabaseCleaner.clean_with(:truncation)
157
- # # Noid minting causes extra LDP requests which slow the test suite.
158
- # QaServer.config.enable_noids = false
159
- # end
160
- #
161
- # config.before do |example|
162
- # if example.metadata[:type] == :feature && Capybara.current_driver != :rack_test
163
- # DatabaseCleaner.strategy = :truncation
164
- # else
165
- # DatabaseCleaner.strategy = :transaction
166
- # DatabaseCleaner.start
167
- # end
168
- #
169
- # # using :workflow is preferable to :clean_repo, use the former if possible
170
- # # It's important that this comes after DatabaseCleaner.start
171
- # ensure_deposit_available_for(user) if example.metadata[:workflow]
172
- # if example.metadata[:clean_repo]
173
- # ActiveFedora::Cleaner.clean!
174
- # # The JS is executed in a different thread, so that other thread
175
- # # may think the root path has already been created:
176
- # ActiveFedora.fedora.connection.send(:init_base_path) if example.metadata[:js]
177
- # end
178
- # QaServer.config.nested_relationship_reindexer = if example.metadata[:with_nested_reindexing]
179
- # # Use the default relationship reindexer (and the cascading reindexing of child documents)
180
- # QaServer.config.default_nested_relationship_reindexer
181
- # else
182
- # # Don't use the nested relationship reindexer. This slows everything down quite a bit.
183
- # ->(id:, extent:) {}
184
- # end
185
- # end
186
-
187
- # config.include(ControllerLevelHelpers, type: :view)
188
- # config.before(:each, type: :view) { initialize_controller_helpers(view) }
189
- #
190
- # config.before(:all, type: :feature) do
191
- # # Assets take a long time to compile. This causes two problems:
192
- # # 1) the profile will show the first feature test taking much longer than it
193
- # # normally would.
194
- # # 2) The first feature test will trigger rack-timeout
195
- # #
196
- # # Precompile the assets to prevent these issues.
197
- # visit "/assets/application.css"
198
- # visit "/assets/application.js"
199
- # end
200
- #
201
- # config.after do
202
- # DatabaseCleaner.clean
203
- # end
204
- #
205
- # # If true, the base class of anonymous controllers will be inferred
206
- # # automatically. This will be the default behavior in future versions of
207
- # # rspec-rails.
208
- # config.infer_base_class_for_anonymous_controllers = false
209
- #
210
- # config.include Shoulda::Matchers::Independent
211
- #
212
- # if Devise::VERSION >= '4.2'
213
- # config.include Devise::Test::ControllerHelpers, type: :controller
214
- # else
215
- # config.include Devise::TestHelpers, type: :controller
216
- # end
217
- #
218
- # config.include EngineRoutes, type: :controller
219
- # config.include Warden::Test::Helpers, type: :request
220
- # config.include Warden::Test::Helpers, type: :feature
221
- # config.after(:each, type: :feature) do
222
- # Warden.test_reset!
223
- # Capybara.reset_sessions!
224
- # page.driver.reset!
225
- # end
226
- #
227
- # config.include Capybara::RSpecMatchers, type: :input
228
- # config.include InputSupport, type: :input
229
- # config.include FactoryBot::Syntax::Methods
230
- # config.include OptionalExample
231
- #
232
- # config.infer_spec_type_from_file_location!
233
- #
234
- # config.expect_with :rspec do |expectations|
235
- # expectations.include_chain_clauses_in_custom_matcher_descriptions = true
236
- # end
237
- #
238
- # config.formatter = 'LoggingFormatter'
239
- # config.default_formatter = 'doc' if config.files_to_run.one?
240
- #
241
- # config.order = :random
242
- # Kernel.srand config.seed
243
- #
244
- # config.shared_context_metadata_behavior = :apply_to_host_groups
245
- #
246
- # config.filter_run_when_matching :focus
247
- #
248
- # config.example_status_persistence_file_path = 'spec/examples.txt'
249
- #
250
- # config.profile_examples = 10
251
- #
252
- # # Use this example metadata when you want to perform jobs inline during testing.
253
- # #
254
- # # describe '#my_method`, :perform_enqueued do
255
- # # ...
256
- # # end
257
- # #
258
- # # If you pass an `Array` of job classes, they will be treated as the filter list.
259
- # #
260
- # # describe '#my_method`, perform_enqueued: [MyJobClass] do
261
- # # ...
262
- # # end
263
- # #
264
- # # Limit to specific job classes with:
265
- # #
266
- # # ActiveJob::Base.queue_adapter.filter = [JobClass]
267
- # #
268
- # config.before(:example, :perform_enqueued) do |example|
269
- # ActiveJob::Base.queue_adapter.filter =
270
- # example.metadata[:perform_enqueued].try(:to_a)
271
- #
272
- # ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
273
- # ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = true
274
- # end
275
- #
276
- # config.after(:example, :perform_enqueued) do
277
- # ActiveJob::Base.queue_adapter.filter = nil
278
- # ActiveJob::Base.queue_adapter.enqueued_jobs = []
279
- # ActiveJob::Base.queue_adapter.performed_jobs = []
280
- #
281
- # ActiveJob::Base.queue_adapter.perform_enqueued_jobs = false
282
- # ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = false
283
- # end
@@ -1,17 +1,23 @@
1
1
  # frozen_string_literal: true
2
- require 'rspec/core/rake_task'
2
+ require 'bundler/gem_tasks'
3
3
  require 'engine_cart/rake_task'
4
+ require 'rspec/core/rake_task'
4
5
  require 'rubocop/rake_task'
5
6
 
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
6
9
  desc 'Run style checker'
7
10
  RuboCop::RakeTask.new(:rubocop) do |task|
11
+ task.requires << 'rubocop-rspec'
8
12
  task.fail_on_error = true
9
13
  end
10
14
 
11
- RSpec::Core::RakeTask.new(:spec)
12
-
13
- desc 'Generate the engine_cart and spin up test servers and run specs'
14
- task ci: ['rubocop', 'engine_cart:generate'] do
15
- puts 'running continuous integration'
16
- Rake::Task['spec_with_app_load'].invoke
15
+ desc "Run continuous integration build"
16
+ task ci: ['engine_cart:generate'] do
17
+ Rake::Task['spec'].invoke
17
18
  end
19
+
20
+ desc 'Run continuous integration build'
21
+ task ci: ['rubocop', 'spec']
22
+
23
+ task default: :ci
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qa_server
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.0
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - E. Lynette Rayle
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-10 00:00:00.000000000 Z
11
+ date: 2019-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -122,6 +122,62 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '2.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: factory_bot
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '4.4'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '4.4'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: sqlite3
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rails-controller-testing
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '1'
125
181
  - !ruby/object:Gem::Dependency
126
182
  name: rspec-activemodel-mocks
127
183
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +220,62 @@ dependencies:
164
220
  - - "~>"
165
221
  - !ruby/object:Gem::Version
166
222
  version: '3.1'
223
+ - !ruby/object:Gem::Dependency
224
+ name: selenium-webdriver
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: webdrivers
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: '3.0'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - "~>"
249
+ - !ruby/object:Gem::Version
250
+ version: '3.0'
251
+ - !ruby/object:Gem::Dependency
252
+ name: webmock
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - ">="
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
265
+ - !ruby/object:Gem::Dependency
266
+ name: sass-rails
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - "~>"
270
+ - !ruby/object:Gem::Version
271
+ version: '5.0'
272
+ type: :runtime
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - "~>"
277
+ - !ruby/object:Gem::Version
278
+ version: '5.0'
167
279
  description: A rails engine with questioning authority gem installed to serve as an
168
280
  authority search server with normalized results.
169
281
  email:
@@ -177,6 +289,7 @@ files:
177
289
  - ".gitignore"
178
290
  - ".rubocop.yml"
179
291
  - ".rubocop_fixme.yml"
292
+ - ".travis.yml"
180
293
  - CHANGELOG.md
181
294
  - Gemfile
182
295
  - LICENSE
@@ -209,6 +322,7 @@ files:
209
322
  - app/models/qa_server/authority_scenario.rb
210
323
  - app/models/qa_server/authority_status.rb
211
324
  - app/models/qa_server/authority_status_failure.rb
325
+ - app/models/qa_server/performance_cache.rb
212
326
  - app/models/qa_server/performance_history.rb
213
327
  - app/models/qa_server/scenario_run_history.rb
214
328
  - app/models/qa_server/scenario_run_registry.rb
@@ -329,6 +443,7 @@ files:
329
443
  - lib/tasks/qa_server_tasks.rake
330
444
  - qa_server.gemspec
331
445
  - spec/.gitignore
446
+ - spec/lib/qa_server_spec.rb
332
447
  - spec/rails_helper.rb
333
448
  - spec/spec_helper.rb
334
449
  - spec/test_app_templates/Gemfile.extra
@@ -360,6 +475,7 @@ specification_version: 4
360
475
  summary: Authority Lookup Server
361
476
  test_files:
362
477
  - spec/.gitignore
478
+ - spec/lib/qa_server_spec.rb
363
479
  - spec/rails_helper.rb
364
480
  - spec/spec_helper.rb
365
481
  - spec/test_app_templates/Gemfile.extra