qa_server 2.2.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,253 @@
1
+ # frozen_string_literal: true
2
+ # This presenter class provides performance data needed by the view that monitors status of authorities.
3
+ module QaServer::MonitorStatus
4
+ class PerformancePresenter # rubocop:disable Metrics/ClassLength
5
+ class_attribute :performance_history_class
6
+ self.performance_history_class = QaServer::PerformanceHistory
7
+
8
+ include QaServer::MonitorStatus::GruffGraph
9
+
10
+ ALL_AUTHS = performance_history_class::PERFORMANCE_ALL_KEY
11
+ STATS = performance_history_class::PERFORMANCE_STATS_KEY
12
+
13
+ FOR_LIFETIME = performance_history_class::PERFORMANCE_FOR_LIFETIME_KEY
14
+ FOR_DAY = performance_history_class::PERFORMANCE_FOR_DAY_KEY
15
+ BY_HOUR = performance_history_class::PERFORMANCE_BY_HOUR_KEY
16
+ FOR_MONTH = performance_history_class::PERFORMANCE_FOR_MONTH_KEY
17
+ BY_DAY = performance_history_class::PERFORMANCE_BY_DAY_KEY
18
+ FOR_YEAR = performance_history_class::PERFORMANCE_FOR_YEAR_KEY
19
+ BY_MONTH = performance_history_class::PERFORMANCE_BY_MONTH_KEY
20
+
21
+ SUM_LOAD = performance_history_class::SUM_LOAD_TIME_KEY
22
+ SUM_NORMALIZATION = performance_history_class::SUM_NORMALIZATION_TIME_KEY
23
+ SUM_FULL_REQUEST = performance_history_class::SUM_FULL_REQUEST_TIME_KEY
24
+ MIN_LOAD = performance_history_class::MIN_LOAD_TIME_KEY
25
+ MIN_NORMALIZATION = performance_history_class::MIN_NORMALIZATION_TIME_KEY
26
+ MIN_FULL_REQUEST = performance_history_class::MIN_FULL_REQUEST_TIME_KEY
27
+ MAX_LOAD = performance_history_class::MAX_LOAD_TIME_KEY
28
+ MAX_NORMALIZATION = performance_history_class::MAX_NORMALIZATION_TIME_KEY
29
+ MAX_FULL_REQUEST = performance_history_class::MAX_FULL_REQUEST_TIME_KEY
30
+ AVG_LOAD = performance_history_class::AVG_LOAD_TIME_KEY
31
+ AVG_NORMALIZATION = performance_history_class::AVG_NORMALIZATION_TIME_KEY
32
+ AVG_FULL_REQUEST = performance_history_class::AVG_FULL_REQUEST_TIME_KEY
33
+
34
+ # @param performance_data [Hash<Hash>] performance data
35
+ def initialize(performance_data:)
36
+ @performance_data = performance_data
37
+ end
38
+
39
+ attr_reader :performance_data
40
+
41
+ def performance_data?
42
+ performance_data.present?
43
+ end
44
+
45
+ def display_performance?
46
+ display_performance_graph? || display_performance_datatable?
47
+ end
48
+
49
+ def display_performance_graph?
50
+ QaServer.config.display_performance_graph?
51
+ end
52
+
53
+ def display_performance_datatable?
54
+ QaServer.config.display_performance_datatable?
55
+ end
56
+
57
+ def performance_data_authority_name(entry)
58
+ entry.keys.first
59
+ end
60
+
61
+ def performance_for_day_graph
62
+ performance_graph_file(rework_performance_data_for_gruff(all_authorities_performance_data[FOR_DAY], BY_HOUR),
63
+ performance_for_day_graph_full_path,
64
+ performance_for_day_graph_filename,
65
+ I18n.t('qa_server.monitor_status.performance.x_axis_hour'))
66
+ end
67
+
68
+ def performance_for_month_graph
69
+ performance_graph_file(rework_performance_data_for_gruff(all_authorities_performance_data[FOR_MONTH], BY_DAY),
70
+ performance_for_month_graph_full_path,
71
+ performance_for_month_graph_filename,
72
+ I18n.t('qa_server.monitor_status.performance.x_axis_day'))
73
+ end
74
+
75
+ def performance_for_year_graph
76
+ performance_graph_file(rework_performance_data_for_gruff(all_authorities_performance_data[FOR_YEAR], BY_MONTH),
77
+ performance_for_year_graph_full_path,
78
+ performance_for_year_graph_filename,
79
+ I18n.t('qa_server.monitor_status.performance.x_axis_month'))
80
+ end
81
+
82
+ def lifetime_stats(authority_data)
83
+ authority_data[FOR_LIFETIME]
84
+ end
85
+
86
+ def min_load(stats)
87
+ format_stat stats[MIN_LOAD]
88
+ end
89
+
90
+ def min_normalization(stats)
91
+ format_stat stats[MIN_NORMALIZATION]
92
+ end
93
+
94
+ def min_full_request(stats)
95
+ format_stat stats[MIN_FULL_REQUEST]
96
+ end
97
+
98
+ def max_load(stats)
99
+ format_stat stats[MAX_LOAD]
100
+ end
101
+
102
+ def max_normalization(stats)
103
+ format_stat stats[MAX_NORMALIZATION]
104
+ end
105
+
106
+ def max_full_request(stats)
107
+ format_stat stats[MAX_FULL_REQUEST]
108
+ end
109
+
110
+ def avg_load(stats)
111
+ format_stat stats[AVG_LOAD]
112
+ end
113
+
114
+ def avg_normalization(stats)
115
+ format_stat stats[AVG_NORMALIZATION]
116
+ end
117
+
118
+ def avg_full_request(stats)
119
+ format_stat stats[AVG_FULL_REQUEST]
120
+ end
121
+
122
+ def min_load_style(stats)
123
+ performance_style_class(stats, MIN_LOAD)
124
+ end
125
+
126
+ def min_normalization_style(stats)
127
+ performance_style_class(stats, MIN_NORMALIZATION)
128
+ end
129
+
130
+ def min_full_request_style(stats)
131
+ performance_style_class(stats, MIN_FULL_REQUEST)
132
+ end
133
+
134
+ def max_load_style(stats)
135
+ performance_style_class(stats, MAX_LOAD)
136
+ end
137
+
138
+ def max_normalization_style(stats)
139
+ performance_style_class(stats, MAX_NORMALIZATION)
140
+ end
141
+
142
+ def max_full_request_style(stats)
143
+ performance_style_class(stats, MAX_FULL_REQUEST)
144
+ end
145
+
146
+ def avg_load_style(stats)
147
+ performance_style_class(stats, AVG_LOAD)
148
+ end
149
+
150
+ def avg_normalization_style(stats)
151
+ performance_style_class(stats, AVG_NORMALIZATION)
152
+ end
153
+
154
+ def avg_full_request_style(stats)
155
+ performance_style_class(stats, AVG_FULL_REQUEST)
156
+ end
157
+
158
+ private
159
+
160
+ def all_authorities_performance_data
161
+ performance_data[ALL_AUTHS]
162
+ end
163
+
164
+ def format_stat(stat)
165
+ format("%0.1f", stat)
166
+ end
167
+
168
+ def performance_style_class(stats, stat_key)
169
+ return "status-bad" if max_threshold_exceeded(stats, stat_key)
170
+ return "status-unknown" if min_threshold_not_met(stats, stat_key)
171
+ "status-neutral"
172
+ end
173
+
174
+ MAX_THRESHOLD = 1000 # ms
175
+ def max_threshold_exceeded(stats, stat_key)
176
+ return true if stats[stat_key] > MAX_THRESHOLD
177
+ false
178
+ end
179
+
180
+ MIN_THRESHOLD = 500 # ms
181
+ def min_threshold_not_met(stats, stat_key)
182
+ return true unless stats[stat_key] < MIN_THRESHOLD
183
+ false
184
+ end
185
+
186
+ def performance_graph_theme(g, x_axis_label)
187
+ g.theme_pastel
188
+ g.colors = ['#81adf4', '#8696b0', '#06578a']
189
+ g.marker_font_size = 12
190
+ g.x_axis_increment = 10
191
+ g.x_axis_label = x_axis_label
192
+ g.y_axis_label = I18n.t('qa_server.monitor_status.performance.y_axis_ms')
193
+ g.dot_radius = 3
194
+ g.line_width = 2
195
+ g.minimum_value = 0
196
+ g.maximum_value = 1000
197
+ end
198
+
199
+ def graph_filename(authority_name, time_period)
200
+ "performance_of_#{authority_name}_for_#{time_period}_graph.png"
201
+ end
202
+
203
+ def performance_for_day_graph_filename
204
+ graph_filename(ALL_AUTHS, :day)
205
+ end
206
+
207
+ def performance_for_day_graph_full_path
208
+ graph_full_path(performance_for_day_graph_filename)
209
+ end
210
+
211
+ def performance_for_month_graph_filename
212
+ graph_filename(ALL_AUTHS, :month)
213
+ end
214
+
215
+ def performance_for_month_graph_full_path
216
+ graph_full_path(performance_for_month_graph_filename)
217
+ end
218
+
219
+ def performance_for_year_graph_filename
220
+ graph_filename(ALL_AUTHS, :year)
221
+ end
222
+
223
+ def performance_for_year_graph_full_path
224
+ graph_full_path(performance_for_year_graph_filename)
225
+ end
226
+
227
+ def rework_performance_data_for_gruff(performance_data, label_key)
228
+ labels = {}
229
+ load_data = []
230
+ normalization_data = []
231
+ full_request_data = []
232
+ performance_data.each do |i, data|
233
+ labels[i] = data[label_key]
234
+ load_data << data[STATS][AVG_LOAD]
235
+ normalization_data << data[STATS][AVG_NORMALIZATION]
236
+ full_request_data << data[STATS][AVG_FULL_REQUEST]
237
+ end
238
+ [labels, load_data, normalization_data, full_request_data]
239
+ end
240
+
241
+ def performance_graph_file(performance_data, performance_graph_full_path, performance_graph_filename, x_axis_label)
242
+ g = Gruff::Line.new
243
+ performance_graph_theme(g, x_axis_label)
244
+ g.title = ''
245
+ g.labels = performance_data[0]
246
+ g.data(I18n.t('qa_server.monitor_status.performance.load_time_ms'), performance_data[1])
247
+ g.data(I18n.t('qa_server.monitor_status.performance.normalization_time_ms'), performance_data[2])
248
+ g.data(I18n.t('qa_server.monitor_status.performance.full_request_time_ms'), performance_data[3])
249
+ g.write performance_graph_full_path
250
+ File.join(graph_relative_path, performance_graph_filename)
251
+ end
252
+ end
253
+ end
@@ -1,321 +1,34 @@
1
1
  # frozen_string_literal: true
2
-
3
- require 'fileutils'
4
- require 'gruff'
5
-
6
2
  # This presenter class provides all data needed by the view that monitors status of authorities.
7
3
  module QaServer
8
- class MonitorStatusPresenter # rubocop:disable Metrics/ClassLength
9
- class_attribute :performance_history_class
10
- self.performance_history_class = QaServer::PerformanceHistory
11
-
12
- HISTORICAL_AUTHORITY_NAME_IDX = 0
13
- HISTORICAL_FAILURE_COUNT_IDX = 1
14
- HISTORICAL_PASSING_COUNT_IDX = 2
15
-
16
- PERFORMANCE_FOR_DAY_KEY = performance_history_class::PERFORMANCE_FOR_DAY_KEY
17
- PERFORMANCE_BY_HOUR_KEY = performance_history_class::PERFORMANCE_BY_HOUR_KEY
18
- PERFORMANCE_FOR_MONTH_KEY = performance_history_class::PERFORMANCE_FOR_MONTH_KEY
19
- PERFORMANCE_BY_DAY_KEY = performance_history_class::PERFORMANCE_BY_DAY_KEY
20
- PERFORMANCE_FOR_YEAR_KEY = performance_history_class::PERFORMANCE_FOR_YEAR_KEY
21
- PERFORMANCE_BY_MONTH_KEY = performance_history_class::PERFORMANCE_BY_MONTH_KEY
22
- LOAD_TIME_KEY = performance_history_class::LOAD_TIME_KEY
23
- NORMALIZATION_TIME_KEY = performance_history_class::NORMALIZATION_TIME_KEY
24
- COMBINED_TIME_KEY = performance_history_class::COMBINED_TIME_KEY
4
+ class MonitorStatusPresenter
5
+ extend Forwardable
25
6
 
26
7
  # @param current_summary [ScenarioRunSummary] summary status of the latest run of test scenarios
27
8
  # @param current_data [Array<Hash>] current set of failures for the latest test run, if any
28
9
  # @param historical_summary_data [Array<Hash>] summary of past failuring runs per authority to drive chart
29
10
  # @param performance_data [Hash<Hash>] performance data
30
11
  def initialize(current_summary:, current_failure_data:, historical_summary_data:, performance_data:)
31
- @current_summary = current_summary
32
- @current_failure_data = current_failure_data
33
- @historical_summary_data = historical_summary_data
34
- @performance_data = performance_data
35
- end
36
-
37
- # @return [String] date of last test run
38
- def last_updated
39
- @current_summary.run_dt_stamp.in_time_zone("Eastern Time (US & Canada)").strftime("%m/%d/%y - %I:%M %p")
40
- end
41
-
42
- # @return [String] date of first recorded test run
43
- def first_updated
44
- QaServer::ScenarioRunRegistry.first.dt_stamp.in_time_zone("Eastern Time (US & Canada)").strftime("%m/%d/%y - %I:%M %p")
45
- end
46
-
47
- # @return [Integer] number of loaded authorities
48
- def authorities_count
49
- @current_summary.authority_count
50
- end
51
-
52
- # @return [Integer] number of authorities with failing tests in the latest test run
53
- def failing_authorities_count
54
- @current_failure_data.map { |f| f[:authority_name] }.uniq.count
55
- end
56
-
57
- # @return [String] css style class representing whether all tests passed or any failed
58
- def authorities_count_style
59
- failures? ? 'status-bad' : 'status-good'
60
- end
61
-
62
- # @return [Integer] number of tests in the latest test run
63
- def tests_count
64
- @current_summary.total_scenario_count
65
- end
66
-
67
- # @return [Integer] number of passing tests in the latest test run
68
- def passing_tests_count
69
- @current_summary.passing_scenario_count
70
- end
71
-
72
- # @return [Integer] number of failing tests in the latest test run
73
- def failing_tests_count
74
- @current_summary.failing_scenario_count
75
- end
76
-
77
- # @return [String] css style class representing whether all tests passed or any failed
78
- def failing_tests_style
79
- failures? ? 'summary-status-bad' : 'status-good'
80
- end
81
-
82
- # @return [Array<Hash>] A list of failures data in the latest test run, if any
83
- # @example
84
- # [ { status: :FAIL,
85
- # status_label: 'X',
86
- # authority_name: 'LOCNAMES_LD4L_CACHE',
87
- # subauthority_name: 'person',
88
- # service: 'ld4l_cache',
89
- # action: 'search',
90
- # url: '/qa/search/linked_data/locnames_ld4l_cache/person?q=mark twain&maxRecords=4',
91
- # err_message: 'Exception: Something went wrong.' }, ... ]
92
- def failures
93
- @current_failure_data
94
- end
95
-
96
- # @return [Boolean] true if failure data exists for the latest test run; otherwise false
97
- def failures?
98
- failing_tests_count.positive?
99
- end
100
-
101
- # @return [Array<Hash>] historical test data to be displayed (authname, failing, passing)
102
- # @example
103
- # [ [ 'agrovoc', 0, 24 ],
104
- # [ 'geonames_ld4l_cache', 2, 22 ] ... ]
105
- def historical_summary
106
- @historical_summary_data
107
- end
108
-
109
- # @return [Boolean] true if historical test data exists; otherwise false
110
- def history?
111
- return true if @historical_summary_data.present?
112
- false
113
- end
114
-
115
- def historical_graph
116
- # g = Gruff::SideStackedBar.new('800x400')
117
- g = Gruff::SideStackedBar.new
118
- historical_graph_theme(g)
119
- g.title = ''
120
- historical_data = rework_historical_data_for_gruff
121
- g.labels = historical_data[0]
122
- g.data('Fail', historical_data[1])
123
- g.data('Pass', historical_data[2])
124
- g.write historical_graph_full_path
125
- File.join(graph_relative_path, historical_graph_filename)
126
- end
127
-
128
- # @return [String] the name of the css style class to use for the status cell based on the status of the scenario test.
129
- def status_style_class(status)
130
- "status-#{status[:status]}"
131
- end
132
-
133
- # @return [String] the name of the css style class to use for the status cell based on the status of the scenario test.
134
- def status_label(status)
135
- case status[:status]
136
- when :good
137
- QaServer::ScenarioRunHistory::GOOD_MARKER
138
- when :bad
139
- QaServer::ScenarioRunHistory::BAD_MARKER
140
- when :unknown
141
- QaServer::ScenarioRunHistory::UNKNOWN_MARKER
142
- end
143
- end
144
-
145
- def historical_data_authority_name(historical_entry)
146
- historical_entry[QaServer::MonitorStatusPresenter::HISTORICAL_AUTHORITY_NAME_IDX]
147
- end
148
-
149
- def days_authority_passing(historical_entry)
150
- historical_entry[QaServer::MonitorStatusPresenter::HISTORICAL_PASSING_COUNT_IDX]
151
- end
152
-
153
- def days_authority_failing(historical_entry)
154
- historical_entry[QaServer::MonitorStatusPresenter::HISTORICAL_FAILURE_COUNT_IDX]
155
- end
156
-
157
- def days_authority_tested(historical_entry)
158
- days_authority_passing(historical_entry) + days_authority_failing(historical_entry)
159
- end
160
-
161
- def percent_authority_failing(historical_entry)
162
- days_authority_failing(historical_entry).to_f / days_authority_tested(historical_entry)
163
- end
164
-
165
- def percent_authority_failing_str(historical_entry)
166
- "#{percent_authority_failing(historical_entry) * 100}%"
167
- end
168
-
169
- def failure_style_class(historical_entry)
170
- return "status-neutral" if days_authority_failing(historical_entry) <= 0
171
- return "status-unknown" if percent_authority_failing(historical_entry) < 0.1
172
- "status-bad"
173
- end
174
-
175
- def passing_style_class(historical_entry)
176
- return "status-bad" if days_authority_passing(historical_entry) <= 0
177
- "status-good"
178
- end
179
-
180
- def display_history_details?
181
- display_historical_graph? || display_historical_datatable?
182
- end
183
-
184
- def display_historical_graph?
185
- QaServer.config.display_historical_graph?
186
- end
187
-
188
- def display_historical_datatable?
189
- QaServer.config.display_historical_datatable?
190
- end
191
-
192
- def performance_data?
193
- @performance_data.present?
194
- end
195
-
196
- def performance_for_day_graph
197
- performance_graph_file(rework_performance_data_for_gruff(@performance_data[PERFORMANCE_FOR_DAY_KEY], :hour),
198
- performance_for_day_graph_full_path,
199
- performance_for_day_graph_filename,
200
- I18n.t('qa_server.monitor_status.performance.x_axis_hour'))
201
- end
202
-
203
- def performance_for_month_graph
204
- performance_graph_file(rework_performance_data_for_gruff(@performance_data[PERFORMANCE_FOR_MONTH_KEY], :day),
205
- performance_for_month_graph_full_path,
206
- performance_for_month_graph_filename,
207
- I18n.t('qa_server.monitor_status.performance.x_axis_day'))
208
- end
209
-
210
- def performance_for_year_graph
211
- performance_graph_file(rework_performance_data_for_gruff(@performance_data[PERFORMANCE_FOR_YEAR_KEY], :month),
212
- performance_for_year_graph_full_path,
213
- performance_for_year_graph_filename,
214
- I18n.t('qa_server.monitor_status.performance.x_axis_month'))
215
- end
216
-
217
- private
218
-
219
- def historical_graph_theme(g)
220
- g.theme_pastel
221
- g.colors = ['#ffcccc', '#ccffcc']
222
- g.marker_font_size = 12
223
- g.x_axis_increment = 10
224
- end
225
-
226
- def graph_relative_path
227
- File.join('qa_server', 'charts')
228
- end
229
-
230
- def graph_full_path(graph_filename)
231
- path = Rails.root.join('app', 'assets', 'images', graph_relative_path)
232
- FileUtils.mkdir_p path
233
- File.join(path, graph_filename)
234
- end
235
-
236
- def historical_graph_full_path
237
- graph_full_path(historical_graph_filename)
238
- end
239
-
240
- def historical_graph_filename
241
- 'historical_side_stacked_bar.png'
242
- end
243
-
244
- def rework_historical_data_for_gruff
245
- labels = {}
246
- pass_data = []
247
- fail_data = []
248
- i = 0
249
- historical_summary.each do |data|
250
- labels[i] = data[0]
251
- i += 1
252
- fail_data << data[1]
253
- pass_data << data[2]
254
- end
255
- [labels, fail_data, pass_data]
256
- end
257
-
258
- def performance_graph_theme(g, x_axis_label)
259
- g.theme_pastel
260
- g.colors = ['#81adf4', '#8696b0', '#06578a']
261
- g.marker_font_size = 12
262
- g.x_axis_increment = 10
263
- g.x_axis_label = x_axis_label
264
- g.y_axis_label = I18n.t('qa_server.monitor_status.performance.y_axis_ms')
265
- g.dot_radius = 3
266
- g.line_width = 2
267
- g.minimum_value = 0
268
- g.maximum_value = 1000
269
- end
270
-
271
- def performance_for_day_graph_filename
272
- 'performance_for_day_graph.png'
273
- end
274
-
275
- def performance_for_day_graph_full_path
276
- graph_full_path(performance_for_day_graph_filename)
277
- end
278
-
279
- def performance_for_month_graph_filename
280
- 'performance_for_month_graph.png'
281
- end
282
-
283
- def performance_for_month_graph_full_path
284
- graph_full_path(performance_for_month_graph_filename)
285
- end
286
-
287
- def performance_for_year_graph_filename
288
- 'performance_for_year_graph.png'
289
- end
290
-
291
- def performance_for_year_graph_full_path
292
- graph_full_path(performance_for_year_graph_filename)
293
- end
294
-
295
- def rework_performance_data_for_gruff(performance_data, label_key)
296
- labels = {}
297
- load_data = []
298
- normalization_data = []
299
- combined_data = []
300
- performance_data.each do |i, data|
301
- labels[i] = data[label_key]
302
- load_data << data[LOAD_TIME_KEY]
303
- normalization_data << data[NORMALIZATION_TIME_KEY]
304
- combined_data << data[COMBINED_TIME_KEY]
305
- end
306
- [labels, load_data, normalization_data, combined_data]
307
- end
308
-
309
- def performance_graph_file(performance_data, performance_graph_full_path, performance_graph_filename, x_axis_label)
310
- g = Gruff::Line.new
311
- performance_graph_theme(g, x_axis_label)
312
- g.title = ''
313
- g.labels = performance_data[0]
314
- g.data(I18n.t('qa_server.monitor_status.performance.load_time_ms'), performance_data[1])
315
- g.data(I18n.t('qa_server.monitor_status.performance.normalization_time_ms'), performance_data[2])
316
- g.data(I18n.t('qa_server.monitor_status.performance.combined_time_ms'), performance_data[3])
317
- g.write performance_graph_full_path
318
- File.join(graph_relative_path, performance_graph_filename)
319
- end
12
+ @current_status_presenter = QaServer::MonitorStatus::CurrentStatusPresenter.new(current_summary: current_summary, current_failure_data: current_failure_data)
13
+ @history_presenter = QaServer::MonitorStatus::HistoryPresenter.new(historical_summary_data: historical_summary_data)
14
+ @performance_presenter = QaServer::MonitorStatus::PerformancePresenter.new(performance_data: performance_data)
15
+ end
16
+
17
+ def_delegators :@current_status_presenter, :last_updated, :first_updated, :authorities_count, :failing_authorities_count,
18
+ :authorities_count_style, :tests_count, :passing_tests_count, :failing_tests_count, :failing_tests_style,
19
+ :failures, :failures?
20
+
21
+ def_delegators :@history_presenter, :historical_summary, :history?, :historical_graph, :status_style_class, :status_label,
22
+ :historical_data_authority_name, :days_authority_passing, :days_authority_failing, :days_authority_tested,
23
+ :percent_authority_failing, :percent_authority_failing_str, :failure_style_class, :passing_style_class,
24
+ :display_history_details?, :display_historical_graph?, :display_historical_datatable?
25
+
26
+ def_delegators :@performance_presenter, :performance_data, :performance_data?, :display_performance?, :display_performance_graph?,
27
+ :display_performance_datatable?, :performance_data_authority_name, :performance_for_day_graph, :performance_for_month_graph,
28
+ :performance_for_year_graph, :lifetime_stats, :min_load, :min_normalization, :min_full_request, :max_load,
29
+ :max_normalization, :max_full_request, :avg_load, :avg_normalization, :avg_full_request, :min_load_style,
30
+ :min_normalization_style, :min_full_request_style, :max_load_style, :max_normalization_style, :max_full_request_style,
31
+ :avg_load_style, :avg_normalization_style, :avg_full_request_style, :performance_style_class, :max_threshold_exceeded,
32
+ :min_threshold_not_met
320
33
  end
321
34
  end
@@ -91,10 +91,11 @@
91
91
  </div>
92
92
  <% end %>
93
93
 
94
- <% if @presenter.performance_data? %>
94
+ <% if @presenter.display_performance? && @presenter.performance_data? %>
95
95
  <div id="performance-data" class="status-section">
96
96
  <h3><%= t('qa_server.monitor_status.performance.title') %></h3>
97
97
 
98
+ <% if @presenter.display_performance_graph? %>
98
99
  <script>
99
100
  function switch_performance_view(id) {
100
101
  document.getElementById('performance-by-the-hour').style.display = 'none';
@@ -149,5 +150,41 @@
149
150
  </div>
150
151
  </div>
151
152
  </div>
153
+ <% end %>
154
+
155
+ <% if @presenter.display_performance_datatable? %>
156
+ <table class="status">
157
+ <tr>
158
+ <th></th>
159
+ <th><%= t('qa_server.monitor_status.performance.slowest_times') %></th>
160
+ <th><%= t('qa_server.monitor_status.performance.average_times') %></th>
161
+ <th><%= t('qa_server.monitor_status.performance.fastest_times') %></th>
162
+ </tr>
163
+ <% @presenter.performance_data.each do |authority_name, data| %>
164
+ <% stats = @presenter.lifetime_stats(data) %>
165
+ <tr>
166
+ <td class="table_subheading" colspan="4"><%= authority_name %></td>
167
+ </tr>
168
+ <tr>
169
+ <th><%= t('qa_server.monitor_status.performance.load_times') %></th>
170
+ <td class="<%= @presenter.max_load_style(stats) %>"><%= @presenter.max_load(stats) %></td>
171
+ <td class="<%= @presenter.avg_load_style(stats) %>"><%= @presenter.avg_load(stats) %></td>
172
+ <td class="<%= @presenter.min_load_style(stats) %>"><%= @presenter.min_load(stats) %></td>
173
+ </tr>
174
+ <tr>
175
+ <th><%= t('qa_server.monitor_status.performance.normalization_times') %></th>
176
+ <td class="<%= @presenter.max_normalization_style(stats) %>"><%= @presenter.max_normalization(stats) %></td>
177
+ <td class="<%= @presenter.avg_normalization_style(stats) %>"><%= @presenter.avg_normalization(stats) %></td>
178
+ <td class="<%= @presenter.min_normalization_style(stats) %>"><%= @presenter.min_normalization(stats) %></td>
179
+ </tr>
180
+ <tr>
181
+ <th><%= t('qa_server.monitor_status.performance.full_request_times') %></th>
182
+ <td class="<%= @presenter.max_full_request_style(stats) %>"><%= @presenter.max_full_request(stats) %></td>
183
+ <td class="<%= @presenter.avg_full_request_style(stats) %>"><%= @presenter.avg_full_request(stats) %></td>
184
+ <td class="<%= @presenter.min_full_request_style(stats) %>"><%= @presenter.min_full_request(stats) %></td>
185
+ </tr>
186
+ <% end %>
187
+ </table>
188
+ <% end %>
152
189
  <% end %>
153
190
  </div>
@@ -81,12 +81,19 @@ en:
81
81
  menu_year: Year
82
82
  load_time_ms: Load Time (ms)
83
83
  normalization_time_ms: Normalization Time (ms)
84
- combined_time_ms: Full Request Time (ms)
84
+ full_request_time_ms: Full Request Time (ms)
85
85
  x_axis_hour: Hour
86
86
  x_axis_day: Day
87
87
  x_axis_month: Month
88
88
  y_axis_ms: Milliseconds (ms)
89
89
  now: NOW
90
90
  today: TODAY
91
+ authority: Authority
92
+ average_times: Average (ms)
93
+ fastest_times: Fastest (ms)
94
+ slowest_times: Slowest (ms)
95
+ load_times: Load
96
+ normalization_times: Normalization
97
+ full_request_times: Total
91
98
  usage:
92
99
  title: Usage
@@ -8,6 +8,14 @@ QaServer.config do |config|
8
8
  # @param [Boolean] display history datatable when true
9
9
  # config.display_historical_datatable = true
10
10
 
11
+ # Displays a graph of performance test data when true
12
+ # @param [Boolean] display performance graph when true
13
+ # config.display_performance_graph = false
14
+
15
+ # Displays a datatable of performance test data when true
16
+ # @param [Boolean] display performance datatable when true
17
+ # config.display_performance_datatable = true
18
+
11
19
  # Additional menu items to add to the main navigation menu's set of left justified menu items
12
20
  # @param [Array<Hash<String,String>>] array of menu items to append with hash label: is menu item label to display and hash url: is URL for the menu item link
13
21
  # config.navmenu_extra_leftitems = [