qa_server 5.1.0 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
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