liri 0.2.1 → 0.4.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 +4 -4
- data/.gitignore +4 -2
- data/.rubocop.yml +5 -1
- data/Gemfile +3 -0
- data/Gemfile.lock +67 -7
- data/README.md +3 -0
- data/Rakefile +5 -0
- data/bash_script_examples.sh +3 -1
- data/dummy-app/spec/dummy/dummy_spec.rb +11 -0
- data/exe/liri +26 -7
- data/lib/agent/agent.rb +120 -108
- data/lib/all_libraries.rb +5 -0
- data/lib/common/benchmarking.rb +11 -16
- data/lib/common/compressor/zip.rb +3 -2
- data/lib/common/duration.rb +28 -0
- data/lib/common/hardware.rb +29 -0
- data/lib/common/log.rb +59 -17
- data/lib/common/manager_data.rb +4 -4
- data/lib/common/progressbar.rb +3 -3
- data/lib/common/setup.rb +14 -4
- data/lib/common/source_code.rb +2 -2
- data/lib/common/tests_result.rb +72 -31
- data/lib/common/text_time_parser.rb +51 -0
- data/lib/common/tty_progressbar.rb +70 -0
- data/lib/common/unit_test/rspec.rb +6 -33
- data/lib/common/unit_test/rspec_result_parser.rb +47 -0
- data/lib/hash_extend.rb +15 -6
- data/lib/liri.rb +29 -21
- data/lib/manager/credential.rb +15 -1
- data/lib/manager/manager.rb +471 -165
- data/lib/task.rb +6 -2
- data/liri.gemspec +6 -6
- data/template/liri-config.yml +74 -30
- metadata +15 -10
- data/config/locales/to_duration_es.yml +0 -25
@@ -14,22 +14,10 @@ module Liri
|
|
14
14
|
def all_tests
|
15
15
|
tests_count = 1
|
16
16
|
tests_hash = {}
|
17
|
-
test_files.
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
next if line_inside_comment_block(line)
|
22
|
-
|
23
|
-
if line.strip.start_with?('it')
|
24
|
-
absolute_file_path = file.to_path
|
25
|
-
relative_file_path = absolute_file_path.sub(@source_code_folder_path + '/', '')
|
26
|
-
|
27
|
-
test_line = relative_file_path + ":#{index + 1}"
|
28
|
-
tests_hash[tests_count] = test_line
|
29
|
-
tests_count += 1
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
17
|
+
sorted_test_files = test_files.sort
|
18
|
+
sorted_test_files.each do |test_file|
|
19
|
+
tests_hash[tests_count] = test_file.sub(@source_code_folder_path + '/', '')
|
20
|
+
tests_count += 1
|
33
21
|
end
|
34
22
|
tests_hash
|
35
23
|
end
|
@@ -49,8 +37,8 @@ module Liri
|
|
49
37
|
# raw_tests_result = %x|bundle exec rspec #{tests.join(' ')} --format progress|
|
50
38
|
# Descomentar para el entorno de producción
|
51
39
|
raw_tests_result = ''
|
52
|
-
Liri::Common::Benchmarking.start(start_msg: "
|
53
|
-
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(' ')}'|
|
54
42
|
end
|
55
43
|
|
56
44
|
return raw_tests_result
|
@@ -62,21 +50,6 @@ module Liri
|
|
62
50
|
def test_files
|
63
51
|
Dir[@tests_folder_path + "/**/*spec.rb"]
|
64
52
|
end
|
65
|
-
|
66
|
-
# Revisa si la línea se encuentra dentro de un bloque comentado
|
67
|
-
def line_inside_comment_block(line)
|
68
|
-
if line.strip.start_with?('=begin')
|
69
|
-
@inside_comment = true
|
70
|
-
return true
|
71
|
-
end
|
72
|
-
|
73
|
-
if line.strip.start_with?('=end')
|
74
|
-
@inside_comment = false
|
75
|
-
return false
|
76
|
-
end
|
77
|
-
|
78
|
-
return true if @inside_comment
|
79
|
-
end
|
80
53
|
end
|
81
54
|
end
|
82
55
|
end
|
@@ -0,0 +1,47 @@
|
|
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
|
+
# Received string like this "rspec ./spec/failed_spec.rb:4 # Liri debería fallar a propósito" and
|
29
|
+
# return string like this "/spec/failed_spec.rb:4"
|
30
|
+
# or for "rspec ./spec/system/management/budget_investments_spec.rb[1:3:1:3] # Budget Investments behaves like mappable At new_management_budget_investment_path Should create budget_investment with map"
|
31
|
+
# return "/spec/system/management/budget_investments_spec.rb[1:3:1:3]"
|
32
|
+
def failed_example(failed_example_line)
|
33
|
+
values = failed_example_line.to_s.match(/(\/.+.rb:\d+)/)
|
34
|
+
values ||= failed_example_line.to_s.match(/(\/.+.rb.*\])/)
|
35
|
+
values[1] # failed_example
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def text_value_to_seconds(text)
|
41
|
+
TextTimeParser.to_seconds(text)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
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,14 @@ 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
|
-
|
59
|
+
|
60
|
+
# Retorna un nuevo hash con los elementos borrados según las claves indicadas
|
61
|
+
def remove(*keys)
|
62
|
+
cloned_hash = self.clone
|
63
|
+
keys.flatten.each { |key| cloned_hash.delete(key) }
|
64
|
+
cloned_hash
|
65
|
+
end
|
66
|
+
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.
|
6
|
+
VERSION = '0.4.0'
|
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
|
@@ -44,16 +44,13 @@ module Liri
|
|
44
44
|
@setup_manager ? @setup_manager.delete_setup_folder : false
|
45
45
|
end
|
46
46
|
|
47
|
-
def init_exit(stop, threads
|
47
|
+
def init_exit(stop, threads)
|
48
48
|
threads = threads.compact
|
49
49
|
kill(threads) if stop
|
50
50
|
|
51
51
|
# Con la siguiente línea se asegura que los hilos no mueran antes de que finalize el programa principal
|
52
52
|
# Fuente: https://underc0de.org/foro/ruby/hilos-en-ruby/
|
53
53
|
threads.each{|thread| thread.join}
|
54
|
-
#rescue SignalException => e
|
55
|
-
#puts "\nEjecución del #{program} terminada manualmente\n"
|
56
|
-
#kill(threads)
|
57
54
|
end
|
58
55
|
|
59
56
|
def kill(threads)
|
@@ -66,38 +63,42 @@ module Liri
|
|
66
63
|
end
|
67
64
|
|
68
65
|
def compression_class
|
69
|
-
"Liri::Common::Compressor::#{setup.library.compression}"
|
66
|
+
"Liri::Common::Compressor::#{setup.general.library.compression}"
|
70
67
|
end
|
71
68
|
|
72
69
|
def unit_test_class
|
73
|
-
"Liri::Common::UnitTest::#{setup.library.unit_test}"
|
70
|
+
"Liri::Common::UnitTest::#{setup.general.library.unit_test}"
|
74
71
|
end
|
75
72
|
|
76
73
|
def udp_port
|
77
|
-
setup.ports.udp
|
74
|
+
setup.general.ports.udp
|
78
75
|
end
|
79
76
|
|
80
77
|
def tcp_port
|
81
|
-
setup.ports.tcp
|
78
|
+
setup.general.ports.tcp
|
82
79
|
end
|
83
80
|
|
84
|
-
def
|
85
|
-
|
81
|
+
def current_folder_ruby_and_gemset
|
82
|
+
"#{File.read('.ruby-version').strip}@#{File.read('.ruby-gemset').strip}"
|
86
83
|
end
|
87
84
|
|
88
|
-
def
|
89
|
-
setup.
|
85
|
+
def ignored_folders_in_compress
|
86
|
+
setup.general.ignored_folders_in_compress
|
90
87
|
end
|
91
88
|
|
92
|
-
def
|
93
|
-
|
89
|
+
def times_round
|
90
|
+
setup.general.times_round
|
91
|
+
end
|
92
|
+
|
93
|
+
def times_round_type
|
94
|
+
setup.general.times_round_type.to_sym
|
94
95
|
end
|
95
96
|
|
96
97
|
private
|
97
98
|
|
98
99
|
# 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)
|
100
|
+
def load_setup_manager(destination_folder_path, program, manager_tests_results_folder_time: nil)
|
101
|
+
@setup_manager = Liri::Common::Setup.new(destination_folder_path, program, manager_tests_results_folder_time: manager_tests_results_folder_time)
|
101
102
|
@setup_manager.init
|
102
103
|
@setup = @setup_manager.load
|
103
104
|
@setup_manager
|
@@ -105,7 +106,7 @@ module Liri
|
|
105
106
|
|
106
107
|
# Inicializa y configura la librería encargada de loguear
|
107
108
|
def load_logger(folder_path = nil, file_name = nil)
|
108
|
-
log = Liri::Common::Log.new('daily', folder_path: folder_path, file_name: file_name, stdout: setup.log.stdout.show)
|
109
|
+
log = Liri::Common::Log.new('daily', folder_path: folder_path, file_name: file_name, stdout: setup.general.log.stdout.show)
|
109
110
|
log
|
110
111
|
end
|
111
112
|
end
|
@@ -113,7 +114,14 @@ module Liri
|
|
113
114
|
# EXCEPTIONS
|
114
115
|
class FileNotFoundError < StandardError
|
115
116
|
def initialize(file_path)
|
116
|
-
msg = "
|
117
|
+
msg = "File not found #{file_path}"
|
118
|
+
super(msg)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class InxiCommandNotFoundError < StandardError
|
123
|
+
def initialize
|
124
|
+
msg = "Inxi command not found"
|
117
125
|
super(msg)
|
118
126
|
end
|
119
127
|
end
|
data/lib/manager/credential.rb
CHANGED
@@ -31,17 +31,31 @@ module Liri
|
|
31
31
|
else
|
32
32
|
return nil, nil
|
33
33
|
end
|
34
|
+
rescue Psych::SyntaxError
|
35
|
+
# Este error ocurre cuando se guardan caracteres raros en el archivo liri-credentials.yml
|
36
|
+
# en este caso se borra el archivo y se pide de nuevo la contraseña
|
37
|
+
delete_credentials
|
38
|
+
return nil, nil
|
34
39
|
end
|
35
40
|
|
36
41
|
def ask_credentials
|
37
42
|
local_user = get_local_user
|
38
|
-
password = ask("
|
43
|
+
password = ask("Enter password of user #{local_user}: ") { |q| q.echo = "*" }
|
39
44
|
return local_user, password
|
40
45
|
end
|
41
46
|
|
42
47
|
def save_credentials(user, password)
|
43
48
|
File.write(@file_path, "user: #{user}\npassword: #{password}")
|
44
49
|
end
|
50
|
+
|
51
|
+
def delete_credentials
|
52
|
+
if File.exist?(@file_path)
|
53
|
+
File.delete(@file_path)
|
54
|
+
File.exist?(@file_path) ? false : true
|
55
|
+
else
|
56
|
+
false
|
57
|
+
end
|
58
|
+
end
|
45
59
|
end
|
46
60
|
end
|
47
61
|
end
|