Extend storage of Testrun Messages and truncate long output

This commit is contained in:
Sebastian Serth
2022-04-29 16:03:36 +02:00
parent 5ecba6ef70
commit ea02dff0e5
9 changed files with 90 additions and 46 deletions

View File

@@ -11,14 +11,14 @@ class TestrunMessage < ApplicationRecord
turtlebatch: 4,
render: 5,
exit: 6,
timeout: 7,
out_of_memory: 8,
status: 9,
hint: 10,
client_kill: 11,
exception: 12,
result: 13,
canvasevent: 14,
status: 7,
hint: 8,
client_kill: 9,
exception: 10,
result: 11,
canvasevent: 12,
timeout: 13, # TODO: Shouldn't be in the data, this is a status and can be removed after the migration finished
out_of_memory: 14, # TODO: Shouldn't be in the data, this is a status and can be removed after the migration finished
}, _default: :write, _prefix: true
enum stream: {
@@ -34,21 +34,52 @@ class TestrunMessage < ApplicationRecord
validate :either_data_or_log
def self.create_for(testrun, messages)
# We don't want to store anything if the testrun passed
return if testrun.passed?
messages.map! do |message|
# We create a new hash and move all known keys
result = {}
result[:testrun] = testrun
result[:log] = message.delete(:log) || (message.delete(:data) if message[:cmd] == :write)
result[:log] = (message.delete(:log) || message.delete(:data)) if message[:cmd] == :write || message.key?(:log)
result[:timestamp] = message.delete :timestamp
result[:stream] = message.delete :stream
result[:stream] = message.delete :stream if message.key?(:stream)
result[:cmd] = message.delete :cmd
# The remaining keys will be stored in the `data` column
result[:data] = message.presence
result[:data] = message.presence if message.present?
result
end
# Before storing all messages, we truncate some to save storage
filtered_messages = filter_messages_by_size testrun, messages
# An array with hashes is passed, all are stored
TestrunMessage.create!(messages)
TestrunMessage.create!(filtered_messages)
end
def self.filter_messages_by_size(testrun, messages)
limits = if testrun.submission.cause == 'requestComments'
{data: {limit: 25, size: 0}, log: {limit: 5000, size: 0}}
else
{data: {limit: 10, size: 0}, log: {limit: 500, size: 0}}
end
filtered_messages = messages.map do |message|
if message.key?(:log) && limits[:log][:size] < limits[:log][:limit]
message[:log] = message[:log][0, limits[:log][:limit] - limits[:log][:size]]
limits[:log][:size] += message[:log].size
elsif message[:data] && limits[:data][:size] < limits[:data][:limit]
limits[:data][:size] += 1
elsif !message.key?(:log) && limits[:data][:size] < limits[:data][:limit]
# Accept short TestrunMessages (e.g. just transporting a status information)
# without increasing the `limits[:data][:limit]` before the limit is reached
else
# Clear all remaining messages
message = nil
end
message
end
filtered_messages.select(&:present?)
end
def either_data_or_log