liri 0.3.0 → 0.3.1
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 +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +5 -1
- data/Gemfile +3 -0
- data/Gemfile.lock +54 -1
- data/README.md +3 -0
- data/bash_script_examples.sh +3 -1
- data/config/locales/to_duration_es.yml +9 -9
- data/exe/liri +26 -7
- data/lib/agent/agent.rb +66 -87
- data/lib/all_libraries.rb +2 -0
- data/lib/common/benchmarking.rb +10 -9
- data/lib/common/manager_data.rb +4 -4
- data/lib/common/setup.rb +14 -4
- data/lib/common/tests_result.rb +59 -30
- data/lib/common/text_time_parser.rb +47 -0
- data/lib/common/unit_test/rspec.rb +4 -18
- data/lib/common/unit_test/rspec_result_parser.rb +37 -0
- data/lib/hash_extend.rb +8 -6
- data/lib/liri.rb +15 -7
- data/lib/manager/credential.rb +1 -1
- data/lib/manager/manager.rb +176 -112
- data/lib/task.rb +6 -2
- data/template/liri-config.yml +9 -3
- metadata +4 -2
data/lib/common/tests_result.rb
CHANGED
@@ -8,12 +8,19 @@ module Liri
|
|
8
8
|
module Common
|
9
9
|
# Esta clase se encarga de guardar y procesar el archivo de resultados
|
10
10
|
class TestsResult
|
11
|
+
attr_reader :examples, :failures, :pending, :passed, :files_processed
|
12
|
+
|
11
13
|
def initialize(folder_path)
|
12
14
|
@folder_path = folder_path
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
15
|
+
@examples = 0
|
16
|
+
@failures = 0
|
17
|
+
@pending = 0
|
18
|
+
@passed = 0
|
19
|
+
@finish_in = 0
|
20
|
+
@files_load = 0
|
21
|
+
@files_processed = 0
|
22
|
+
@failures_list = ''
|
23
|
+
@failed_examples = ''
|
17
24
|
end
|
18
25
|
|
19
26
|
def save(file_name, raw_tests_result)
|
@@ -28,22 +35,28 @@ module Liri
|
|
28
35
|
|
29
36
|
# Procesa el resultado crudo de las pruebas unitarias y lo devuelve en formato hash manejable
|
30
37
|
# Ejemplo del hash retornado:
|
31
|
-
# {
|
32
|
-
|
38
|
+
# { examples: 0, failures: 0, pending: 0, passed: 0, finish_in: 0, files_load: 0,
|
39
|
+
# failures_list: '', failed_examples: '' }
|
40
|
+
def process(tests_result_file_name, files_processed)
|
33
41
|
file_path = File.join(@folder_path, '/', tests_result_file_name)
|
34
42
|
result_hash = process_tests_result_file(file_path)
|
43
|
+
result_hash[:files_processed] = files_processed
|
35
44
|
update_partial_result(result_hash)
|
36
|
-
#print_partial_result(result_hash)
|
37
45
|
result_hash
|
38
46
|
end
|
39
47
|
|
40
48
|
def print_summary
|
41
|
-
puts "\n#{@
|
49
|
+
puts "\n#{@examples} examples, #{@failures} failures, #{@pending} pending\n\n"
|
50
|
+
end
|
51
|
+
|
52
|
+
def print_failures_list
|
53
|
+
puts "\nFailures: " unless @failures_list.empty?
|
54
|
+
puts @failures_list
|
42
55
|
end
|
43
56
|
|
44
|
-
def
|
45
|
-
puts "\
|
46
|
-
puts @
|
57
|
+
def print_failed_examples
|
58
|
+
puts "\nFailed examples: " unless @failed_examples.empty?
|
59
|
+
puts @failed_examples
|
47
60
|
end
|
48
61
|
|
49
62
|
private
|
@@ -51,10 +64,12 @@ module Liri
|
|
51
64
|
# Recibe el resultado crudo de las pruebas unitarias
|
52
65
|
# Procesa el archivo con los resultados crudos y lo devuelve en formato hash manejable
|
53
66
|
# Ejemplo del hash retornado:
|
54
|
-
# {result: '.F', failures: '',
|
67
|
+
# {result: '.F', failures: '', examples: 2, failures: 1, failed_examples: ''}
|
55
68
|
def process_tests_result_file(file_path)
|
56
|
-
result_hash = {failures:
|
69
|
+
result_hash = { examples: 0, failures: 0, pending: 0, passed: 0, finish_in: 0, files_load: 0,
|
70
|
+
failures_list: '', failed_examples: '' }
|
57
71
|
flag = ''
|
72
|
+
@failures_lists_count = @failures
|
58
73
|
File.foreach(file_path) do |line|
|
59
74
|
if flag == '' && line.strip.start_with?('Randomized')
|
60
75
|
flag = 'Randomized'
|
@@ -67,6 +82,9 @@ module Liri
|
|
67
82
|
end
|
68
83
|
|
69
84
|
if ['Randomized', 'Failures', ''].include?(flag) && line.strip.start_with?('Finished')
|
85
|
+
values = finish_in_values(line)
|
86
|
+
result_hash[:finish_in] = values[:finish_in]
|
87
|
+
result_hash[:files_load] = values[:files_load]
|
70
88
|
flag = 'Finished'
|
71
89
|
next
|
72
90
|
end
|
@@ -78,15 +96,17 @@ module Liri
|
|
78
96
|
|
79
97
|
case flag
|
80
98
|
when 'Failures'
|
81
|
-
|
99
|
+
line = fix_failure_number(line)
|
100
|
+
result_hash[:failures_list] << line
|
82
101
|
when 'Finished'
|
83
|
-
values = line
|
84
|
-
result_hash[:
|
85
|
-
result_hash[:
|
86
|
-
result_hash[:
|
102
|
+
values = finished_summary_values(line)
|
103
|
+
result_hash[:examples] = values[:examples]
|
104
|
+
result_hash[:failures] = values[:failures]
|
105
|
+
result_hash[:passed] = result_hash[:examples] - result_hash[:failures]
|
106
|
+
result_hash[:pending] = values[:pending]
|
87
107
|
flag = ''
|
88
108
|
when 'Failed'
|
89
|
-
result_hash[:failed_examples] << line
|
109
|
+
result_hash[:failed_examples] << line if line.strip.start_with?('rspec')
|
90
110
|
end
|
91
111
|
end
|
92
112
|
|
@@ -94,22 +114,31 @@ module Liri
|
|
94
114
|
end
|
95
115
|
|
96
116
|
def update_partial_result(hash_result)
|
97
|
-
@
|
98
|
-
@
|
99
|
-
@
|
100
|
-
@
|
117
|
+
@examples += hash_result[:examples]
|
118
|
+
@failures += hash_result[:failures]
|
119
|
+
@pending += hash_result[:pending]
|
120
|
+
@passed += hash_result[:passed]
|
121
|
+
@files_processed += hash_result[:files_processed]
|
122
|
+
@failures_list << hash_result[:failures_list]
|
123
|
+
@failed_examples << hash_result[:failed_examples]
|
101
124
|
end
|
102
125
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
end
|
126
|
+
def finish_in_values(line)
|
127
|
+
UnitTest::RspecResultParser.finish_in_values(line)
|
128
|
+
end
|
107
129
|
|
108
|
-
|
109
|
-
|
110
|
-
end
|
130
|
+
def finished_summary_values(line)
|
131
|
+
UnitTest::RspecResultParser.finished_summary_values(line)
|
111
132
|
end
|
112
133
|
|
134
|
+
def fix_failure_number(line)
|
135
|
+
line_number_regex = /(\d+\))/
|
136
|
+
if line.strip.start_with?(line_number_regex)
|
137
|
+
@failures_lists_count += 1
|
138
|
+
line.gsub!(line_number_regex, "#{@failures_lists_count})")
|
139
|
+
end
|
140
|
+
line
|
141
|
+
end
|
113
142
|
end
|
114
143
|
end
|
115
144
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# = text_time_parser.rb
|
2
|
+
#
|
3
|
+
# @author Rodrigo Fernández
|
4
|
+
#
|
5
|
+
# == Clase TextTimeParser
|
6
|
+
|
7
|
+
require 'bigdecimal'
|
8
|
+
|
9
|
+
module Liri
|
10
|
+
module Common
|
11
|
+
# Esta clase parsea texto en horas, minutos y segundos a un valor decimal en segundos
|
12
|
+
class TextTimeParser
|
13
|
+
class << self
|
14
|
+
def to_seconds(text_time)
|
15
|
+
values = text_time.split(' ')
|
16
|
+
case values.size
|
17
|
+
when 2 # cuando se tiene por ejemplo '15 minutes'
|
18
|
+
text_time_to_seconds(values[0], values[1])
|
19
|
+
when 4 # cuando se tiene por ejemplo '1 minute 5 seconds'
|
20
|
+
text_time_to_seconds(values[0], values[1]) + text_time_to_seconds(values[2], values[3])
|
21
|
+
when 6 # cuando se tiene por ejemplo '1 hour 30 minutes 25 seconds'
|
22
|
+
text_time_to_seconds(values[0], values[1]) +
|
23
|
+
text_time_to_seconds(values[2], values[3]) +
|
24
|
+
text_time_to_seconds(values[4], values[5])
|
25
|
+
end
|
26
|
+
# queda pendiente agregar el caso de dias, horas, minutos y segundos, además hace falta verificar como lo muestra Rspec
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def text_time_to_seconds(number, text)
|
32
|
+
# Se usa BigDecimal porque
|
33
|
+
# En una multiplicación normal: (203.033*3600).to_f = 730918.7999999999
|
34
|
+
# Con BigDecimal: (BigDecimal('203.033') * 3600).to_f = 730918.8
|
35
|
+
time = BigDecimal(number)
|
36
|
+
time_in_seconds = case text
|
37
|
+
when 'second', 'seconds' then time
|
38
|
+
when 'minute', 'minutes' then time * 60
|
39
|
+
when 'hour', 'hours' then time * 3600
|
40
|
+
when 'day', 'days' then time * 86_400
|
41
|
+
end
|
42
|
+
time_in_seconds.to_f
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -14,7 +14,8 @@ module Liri
|
|
14
14
|
def all_tests
|
15
15
|
tests_count = 1
|
16
16
|
tests_hash = {}
|
17
|
-
test_files.
|
17
|
+
sorted_test_files = test_files.sort
|
18
|
+
sorted_test_files.each do |test_file|
|
18
19
|
tests_hash[tests_count] = test_file.sub(@source_code_folder_path + '/', '')
|
19
20
|
tests_count += 1
|
20
21
|
end
|
@@ -36,8 +37,8 @@ module Liri
|
|
36
37
|
# raw_tests_result = %x|bundle exec rspec #{tests.join(' ')} --format progress|
|
37
38
|
# Descomentar para el entorno de producción
|
38
39
|
raw_tests_result = ''
|
39
|
-
Liri::Common::Benchmarking.start(start_msg: "
|
40
|
-
raw_tests_result = %x|bash -lc 'rvm use #{Liri.current_folder_ruby_and_gemset}; rspec #{tests.join(' ')}
|
40
|
+
Liri::Common::Benchmarking.start(start_msg: "Running tests batch. Wait... ") do
|
41
|
+
raw_tests_result = %x|bash -lc 'rvm use #{Liri.current_folder_ruby_and_gemset}; rspec #{tests.join(' ')}'|
|
41
42
|
end
|
42
43
|
|
43
44
|
return raw_tests_result
|
@@ -49,21 +50,6 @@ module Liri
|
|
49
50
|
def test_files
|
50
51
|
Dir[@tests_folder_path + "/**/*spec.rb"]
|
51
52
|
end
|
52
|
-
|
53
|
-
# Revisa si la línea se encuentra dentro de un bloque comentado
|
54
|
-
def line_inside_comment_block(line)
|
55
|
-
if line.strip.start_with?('=begin')
|
56
|
-
@inside_comment = true
|
57
|
-
return true
|
58
|
-
end
|
59
|
-
|
60
|
-
if line.strip.start_with?('=end')
|
61
|
-
@inside_comment = false
|
62
|
-
return false
|
63
|
-
end
|
64
|
-
|
65
|
-
return true if @inside_comment
|
66
|
-
end
|
67
53
|
end
|
68
54
|
end
|
69
55
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# = rspec_result_parser.rb
|
2
|
+
#
|
3
|
+
# @author Rodrigo Fernández
|
4
|
+
#
|
5
|
+
# == Clase RspecResultParser
|
6
|
+
|
7
|
+
module Liri
|
8
|
+
module Common
|
9
|
+
module UnitTest
|
10
|
+
# Esta clase parsea texto de resultado en rspec a volores numéricos
|
11
|
+
class RspecResultParser
|
12
|
+
class << self
|
13
|
+
def finish_in_values(finish_in_line)
|
14
|
+
values = finish_in_line.to_s.match(/Finished in (.+)\(files took (.+) to load\)/)
|
15
|
+
finish_in_text = values[1]
|
16
|
+
files_load_text = values[2]
|
17
|
+
{ finish_in: text_value_to_seconds(finish_in_text), files_load: text_value_to_seconds(files_load_text) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def finished_summary_values(finished_summary_line)
|
21
|
+
values = finished_summary_line.to_s.match(/(.+) examples*, (.+) failures*,*\s*(\d*)/)
|
22
|
+
examples = values[1]
|
23
|
+
failures = values[2]
|
24
|
+
pending = values[3].empty? ? '0' : values[3]
|
25
|
+
{ examples: examples.to_i, failures: failures.to_i, pending: pending.to_i }
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def text_value_to_seconds(text)
|
31
|
+
TextTimeParser.to_seconds(text)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/hash_extend.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# = hash_extend.rb
|
2
4
|
#
|
3
5
|
# @author Rodrigo Fernández
|
@@ -14,8 +16,8 @@ class Hash
|
|
14
16
|
# => {dos: 'dos'}
|
15
17
|
# hash.sample(2)
|
16
18
|
# => {uno: 'uno', tres: 'tres'}
|
17
|
-
def sample(quantity=1)
|
18
|
-
sample_keys =
|
19
|
+
def sample(quantity = 1)
|
20
|
+
sample_keys = keys.sample(quantity)
|
19
21
|
sample_values = {}
|
20
22
|
sample_keys.each do |sample_key|
|
21
23
|
sample_values[sample_key] = self[sample_key]
|
@@ -32,8 +34,8 @@ class Hash
|
|
32
34
|
# => {dos: 'dos'}
|
33
35
|
# hash.sample(2)
|
34
36
|
# => {uno: 'uno', tres: 'tres'}
|
35
|
-
def sample!(quantity=1)
|
36
|
-
samples =
|
37
|
+
def sample!(quantity = 1)
|
38
|
+
samples = sample(quantity)
|
37
39
|
remove!(samples.keys)
|
38
40
|
samples
|
39
41
|
end
|
@@ -51,7 +53,7 @@ class Hash
|
|
51
53
|
# hash
|
52
54
|
# => {}
|
53
55
|
def remove!(*keys)
|
54
|
-
keys.flatten.each{|key|
|
56
|
+
keys.flatten.each { |key| delete(key) }
|
55
57
|
self
|
56
58
|
end
|
57
|
-
end
|
59
|
+
end
|
data/lib/liri.rb
CHANGED
@@ -3,11 +3,11 @@
|
|
3
3
|
# Este modulo contiene datos del programa que son reutilizados en otras partes de la aplicacion
|
4
4
|
module Liri
|
5
5
|
NAME = 'liri' # El gemspec requiere que el nombre este en minusculas
|
6
|
-
VERSION = '0.3.
|
6
|
+
VERSION = '0.3.1'
|
7
7
|
|
8
8
|
class << self
|
9
|
-
def set_setup(destination_folder_path)
|
10
|
-
load_setup_manager(destination_folder_path)
|
9
|
+
def set_setup(destination_folder_path, program, manager_tests_results_folder_time: nil)
|
10
|
+
load_setup_manager(destination_folder_path, program, manager_tests_results_folder_time: manager_tests_results_folder_time)
|
11
11
|
end
|
12
12
|
|
13
13
|
# Carga las configuraciones en memoria desde un archivo de configuracion
|
@@ -81,8 +81,16 @@ module Liri
|
|
81
81
|
setup.ports.tcp
|
82
82
|
end
|
83
83
|
|
84
|
-
def
|
85
|
-
setup.
|
84
|
+
def print_failures_list
|
85
|
+
setup.print_failures_list
|
86
|
+
end
|
87
|
+
|
88
|
+
def print_failed_examples
|
89
|
+
setup.print_failed_examples
|
90
|
+
end
|
91
|
+
|
92
|
+
def print_agents_detailed_summary
|
93
|
+
setup.print_agents_detailed_summary
|
86
94
|
end
|
87
95
|
|
88
96
|
def udp_request_delay
|
@@ -96,8 +104,8 @@ module Liri
|
|
96
104
|
private
|
97
105
|
|
98
106
|
# Inicializa el objeto que gestiona las configuraciones
|
99
|
-
def load_setup_manager(destination_folder_path)
|
100
|
-
@setup_manager = Liri::Common::Setup.new(destination_folder_path)
|
107
|
+
def load_setup_manager(destination_folder_path, program, manager_tests_results_folder_time: nil)
|
108
|
+
@setup_manager = Liri::Common::Setup.new(destination_folder_path, program, manager_tests_results_folder_time: manager_tests_results_folder_time)
|
101
109
|
@setup_manager.init
|
102
110
|
@setup = @setup_manager.load
|
103
111
|
@setup_manager
|
data/lib/manager/credential.rb
CHANGED
@@ -35,7 +35,7 @@ module Liri
|
|
35
35
|
|
36
36
|
def ask_credentials
|
37
37
|
local_user = get_local_user
|
38
|
-
password = ask("
|
38
|
+
password = ask("Enter password of user #{local_user}: ") { |q| q.echo = "*" }
|
39
39
|
return local_user, password
|
40
40
|
end
|
41
41
|
|