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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d28f136456100f5326e4434296950754e7ec7246504de6152ae0941e3955dc35
|
4
|
+
data.tar.gz: b91ee07874e27b8dce462a593c8cde523da893355fd1fcbf12a362e0903af306
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b42a37864b77d875ae48576a54199f244326d2b2132bcbebc35412f19a805634ac65aca61d3dd172c40c6c21eeea21059b97288af979abb65aed1d4c87ee69a1
|
7
|
+
data.tar.gz: 575c5765c9aa4a2f558a6ee2a33b1559babb85c3ca5849aaa32f93ea65f98b647893683680a96658f2947baebdf2ff86de015235e2b94feba4b1788b89983491
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
@@ -27,6 +27,9 @@ group :development do
|
|
27
27
|
# Ruby static code analyzer and formatter, based on the community Ruby style guide. https://github.com/rubocop-hq/rubocop
|
28
28
|
gem 'rubocop', '~>1', require: false
|
29
29
|
|
30
|
+
# RubyCritic is a gem that wraps around static analysis gems such as Reek, Flay and Flog to provide a quality report of your Ruby code.
|
31
|
+
gem 'rubycritic', '~>4', require: false
|
32
|
+
|
30
33
|
# A Ruby Documentation Tool. https://github.com/lsegal/yard
|
31
34
|
gem 'yard', '~>0'
|
32
35
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,37 +1,68 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
liri (0.
|
4
|
+
liri (0.4.0)
|
5
|
+
chronic_duration (~> 0)
|
5
6
|
commander (~> 4)
|
6
7
|
highline (~> 2)
|
7
|
-
i18n (~> 1)
|
8
8
|
net-scp (~> 3)
|
9
9
|
ruby-progressbar (~> 1)
|
10
10
|
rubyzip (~> 2)
|
11
11
|
terminal-table (~> 3)
|
12
|
-
|
12
|
+
tty-progressbar (~> 0)
|
13
13
|
|
14
14
|
GEM
|
15
15
|
remote: https://rubygems.org/
|
16
16
|
specs:
|
17
|
+
addressable (2.8.0)
|
18
|
+
public_suffix (>= 2.0.2, < 5.0)
|
17
19
|
ast (2.4.2)
|
20
|
+
axiom-types (0.1.1)
|
21
|
+
descendants_tracker (~> 0.0.4)
|
22
|
+
ice_nine (~> 0.11.0)
|
23
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
24
|
+
chronic_duration (0.10.6)
|
25
|
+
numerizer (~> 0.1.1)
|
18
26
|
coderay (1.1.3)
|
27
|
+
coercible (1.0.0)
|
28
|
+
descendants_tracker (~> 0.0.1)
|
19
29
|
commander (4.6.0)
|
20
30
|
highline (~> 2.0.0)
|
21
|
-
|
31
|
+
descendants_tracker (0.0.4)
|
32
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
22
33
|
diff-lcs (1.4.4)
|
23
34
|
docile (1.4.0)
|
35
|
+
equalizer (0.0.11)
|
36
|
+
erubi (1.10.0)
|
37
|
+
flay (2.13.0)
|
38
|
+
erubi (~> 1.10)
|
39
|
+
path_expander (~> 1.0)
|
40
|
+
ruby_parser (~> 3.0)
|
41
|
+
sexp_processor (~> 4.0)
|
42
|
+
flog (4.6.5)
|
43
|
+
path_expander (~> 1.0)
|
44
|
+
ruby_parser (~> 3.1, > 3.1.0)
|
45
|
+
sexp_processor (~> 4.8)
|
24
46
|
highline (2.0.3)
|
25
|
-
|
26
|
-
|
47
|
+
ice_nine (0.11.2)
|
48
|
+
kwalify (0.7.2)
|
49
|
+
launchy (2.5.0)
|
50
|
+
addressable (~> 2.7)
|
27
51
|
net-scp (3.0.0)
|
28
52
|
net-ssh (>= 2.6.5, < 7.0.0)
|
29
53
|
net-ssh (6.1.0)
|
54
|
+
numerizer (0.1.1)
|
30
55
|
parallel (1.22.1)
|
31
56
|
parser (3.1.2.0)
|
32
57
|
ast (~> 2.4.1)
|
58
|
+
path_expander (1.1.0)
|
59
|
+
public_suffix (4.0.7)
|
33
60
|
rainbow (3.1.1)
|
34
61
|
rake (13.0.6)
|
62
|
+
reek (6.1.1)
|
63
|
+
kwalify (~> 0.7.0)
|
64
|
+
parser (~> 3.1.0)
|
65
|
+
rainbow (>= 2.0, < 4.0)
|
35
66
|
regexp_parser (2.4.0)
|
36
67
|
rexml (3.2.5)
|
37
68
|
rspec (3.10.0)
|
@@ -59,17 +90,45 @@ GEM
|
|
59
90
|
rubocop-ast (1.17.0)
|
60
91
|
parser (>= 3.1.1.0)
|
61
92
|
ruby-progressbar (1.11.0)
|
93
|
+
ruby_parser (3.19.1)
|
94
|
+
sexp_processor (~> 4.16)
|
95
|
+
rubycritic (4.7.0)
|
96
|
+
flay (~> 2.8)
|
97
|
+
flog (~> 4.4)
|
98
|
+
launchy (>= 2.0.0)
|
99
|
+
parser (>= 2.6.0)
|
100
|
+
rainbow (~> 3.0)
|
101
|
+
reek (~> 6.0, < 7.0)
|
102
|
+
ruby_parser (~> 3.8)
|
103
|
+
simplecov (>= 0.17.0)
|
104
|
+
tty-which (~> 0.4.0)
|
105
|
+
virtus (~> 1.0)
|
62
106
|
rubyzip (2.3.2)
|
107
|
+
sexp_processor (4.16.1)
|
63
108
|
simplecov (0.21.2)
|
64
109
|
docile (~> 1.1)
|
65
110
|
simplecov-html (~> 0.11)
|
66
111
|
simplecov_json_formatter (~> 0.1)
|
67
112
|
simplecov-html (0.12.3)
|
68
113
|
simplecov_json_formatter (0.1.4)
|
114
|
+
strings-ansi (0.2.0)
|
69
115
|
terminal-table (3.0.2)
|
70
116
|
unicode-display_width (>= 1.1.1, < 3)
|
71
|
-
|
117
|
+
thread_safe (0.3.6)
|
118
|
+
tty-cursor (0.7.1)
|
119
|
+
tty-progressbar (0.18.2)
|
120
|
+
strings-ansi (~> 0.2)
|
121
|
+
tty-cursor (~> 0.7)
|
122
|
+
tty-screen (~> 0.8)
|
123
|
+
unicode-display_width (>= 1.6, < 3.0)
|
124
|
+
tty-screen (0.8.1)
|
125
|
+
tty-which (0.4.2)
|
72
126
|
unicode-display_width (2.1.0)
|
127
|
+
virtus (1.0.5)
|
128
|
+
axiom-types (~> 0.1)
|
129
|
+
coercible (~> 1.0)
|
130
|
+
descendants_tracker (~> 0.0, >= 0.0.3)
|
131
|
+
equalizer (~> 0.0, >= 0.0.9)
|
73
132
|
yard (0.9.26)
|
74
133
|
|
75
134
|
PLATFORMS
|
@@ -81,6 +140,7 @@ DEPENDENCIES
|
|
81
140
|
rake (~> 13)
|
82
141
|
rspec (~> 3.10.0)
|
83
142
|
rubocop (~> 1)
|
143
|
+
rubycritic (~> 4)
|
84
144
|
simplecov (~> 0)
|
85
145
|
yard (~> 0)
|
86
146
|
|
data/README.md
CHANGED
@@ -59,6 +59,9 @@ unitarias de una gema X, si esta gema X requiere una versión específica de Rub
|
|
59
59
|
de cosas deben configurarse de manera manual.
|
60
60
|
|
61
61
|
## Desarrollo
|
62
|
+
La rama master siempre debe ser estable.
|
63
|
+
Se debe crear un release cada vez que se llega a una versión estable de algún agregado nuevo.
|
64
|
+
Agregar fixes y mejoras en ramas.
|
62
65
|
|
63
66
|
### Pruebas Unitarias
|
64
67
|
|
data/Rakefile
CHANGED
@@ -47,6 +47,11 @@ task :install => [:build, :update_agent_installer, :compress_agent_installer] do
|
|
47
47
|
system "gem install " + Liri::NAME + "-" + Liri::VERSION + ".gem"
|
48
48
|
end
|
49
49
|
|
50
|
+
# Borra la gema despues de llamar a la tarea install
|
51
|
+
Rake::Task[:install].enhance do
|
52
|
+
Rake::Task[:clean].invoke
|
53
|
+
end
|
54
|
+
|
50
55
|
# Publica la gema después de compilar.
|
51
56
|
# > rake publish
|
52
57
|
task :publish => :build do
|
data/bash_script_examples.sh
CHANGED
data/exe/liri
CHANGED
@@ -26,7 +26,7 @@ command :manager do |c|
|
|
26
26
|
c.option '-o', '--output [filename]', String, 'Especifica donde guardar los resultados de la ejecución de pruebas unitarias'
|
27
27
|
c.action do |args, options|
|
28
28
|
current_folder = Dir.pwd
|
29
|
-
Liri.set_setup(current_folder)
|
29
|
+
Liri.set_setup(current_folder, :manager)
|
30
30
|
Liri::Common::Benchmarking.start(end_msg: "\nFinalizado en: ", stdout: true) do
|
31
31
|
# Metodo que se ejecuta al llamar al comando manager
|
32
32
|
Liri::Manager.run(current_folder)
|
@@ -57,22 +57,41 @@ end
|
|
57
57
|
# Define el alias m para el comando agent
|
58
58
|
alias_command :a, :agent
|
59
59
|
|
60
|
+
# Define el comando y los parámetros para obtener los archivos de tests
|
61
|
+
command :tests_files do |c|
|
62
|
+
c.syntax = 'Liri tests_files [options]'
|
63
|
+
c.summary = 'Retorna los archivos de tests'
|
64
|
+
c.description = 'Ejecuta el comando para obtener la cantidad total de tests del proyecto'
|
65
|
+
c.example 'Ejecuta el comando tests', 'liri tf'
|
66
|
+
c.example 'Ejecuta el comando tests', 'liri tests_files'
|
67
|
+
c.action do |args, options|
|
68
|
+
# Método que se ejecuta al llamar al comando tests
|
69
|
+
current_folder = Dir.pwd
|
70
|
+
Liri.set_setup(current_folder, :manager)
|
71
|
+
tests_count = Liri::Task.tests_files(current_folder)
|
72
|
+
puts tests_count
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Define el alias t para el comando tests
|
77
|
+
alias_command :tf, :tests_files
|
78
|
+
|
60
79
|
# Define el comando y los parámetros para obtener la cantidad de tests
|
61
|
-
command :
|
62
|
-
c.syntax = 'Liri
|
80
|
+
command :tests_count do |c|
|
81
|
+
c.syntax = 'Liri tests_count [options]'
|
63
82
|
c.summary = 'Retorna la cantidad total de tests'
|
64
83
|
c.description = 'Ejecuta el comando para obtener la cantidad total de tests del proyecto'
|
65
|
-
c.example 'Ejecuta el comando tests', 'liri
|
66
|
-
c.example 'Ejecuta el comando tests', 'liri
|
84
|
+
c.example 'Ejecuta el comando tests', 'liri tc'
|
85
|
+
c.example 'Ejecuta el comando tests', 'liri tests_count'
|
67
86
|
c.action do |args, options|
|
68
87
|
# Método que se ejecuta al llamar al comando tests
|
69
88
|
current_folder = Dir.pwd
|
70
|
-
Liri.set_setup(current_folder)
|
89
|
+
Liri.set_setup(current_folder, :manager)
|
71
90
|
tests_count = Liri::Task.tests_count(current_folder)
|
72
91
|
puts tests_count
|
73
92
|
end
|
74
93
|
end
|
75
94
|
|
76
95
|
# Define el alias t para el comando tests
|
77
|
-
alias_command :
|
96
|
+
alias_command :tc, :tests_count
|
78
97
|
|
data/lib/agent/agent.rb
CHANGED
@@ -12,43 +12,43 @@ module Liri
|
|
12
12
|
# Inicia la ejecución del Agent
|
13
13
|
# @param stop [Boolean] el valor true es para que no se ejecute infinitamente el método en el test unitario.
|
14
14
|
def run(work_folder_path, stop = false)
|
15
|
-
setup_manager = Liri.set_setup(work_folder_path)
|
15
|
+
setup_manager = Liri.set_setup(work_folder_path, :agent)
|
16
16
|
agent_folder_path = setup_manager.agent_folder_path
|
17
17
|
|
18
|
-
Liri.set_logger(setup_manager.logs_folder_path, '
|
19
|
-
Liri.logger.info("
|
20
|
-
Liri.logger.info("
|
18
|
+
Liri.set_logger(setup_manager.logs_folder_path, 'liriagent.log')
|
19
|
+
Liri.logger.info("Agent process started", true)
|
20
|
+
Liri.logger.info("Press Ctrl + c to finish Agent process manually\n", true)
|
21
21
|
|
22
|
-
|
23
|
-
source_code = Common::SourceCode.new(decompressed_source_code_path, agent_folder_path, Liri.compression_class, Liri.unit_test_class)
|
24
|
-
runner = Agent::Runner.new(Liri.unit_test_class, source_code.decompressed_file_folder_path)
|
25
|
-
tests_result = Common::TestsResult.new(agent_folder_path)
|
26
|
-
agent = Agent.new(Liri.udp_port, Liri.tcp_port, source_code, runner, tests_result, agent_folder_path)
|
22
|
+
agent = Agent.new(Liri.udp_port, Liri.tcp_port, agent_folder_path)
|
27
23
|
threads = []
|
28
24
|
threads << agent.start_server_socket_to_process_manager_connection_request # Esperar y procesar la petición de conexión del Manager
|
29
25
|
|
30
|
-
Liri.init_exit(stop, threads
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
Liri.
|
26
|
+
Liri.init_exit(stop, threads)
|
27
|
+
rescue SignalException
|
28
|
+
Liri.logger.info("Agent process finished manually", true)
|
29
|
+
rescue InxiCommandNotFoundError => e
|
30
|
+
Liri.logger.error("Exception(#{e}) Please, install inxi in your operating system", true)
|
31
|
+
ensure
|
32
|
+
# Siempre se ejecutan estos comandos, haya o no excepción
|
33
|
+
Liri.kill(threads) if threads && threads.any?
|
34
|
+
Liri.logger.info("Agent process finished", true)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def initialize(udp_port, tcp_port,
|
38
|
+
def initialize(udp_port, tcp_port, agent_folder_path)
|
39
39
|
@udp_port = udp_port
|
40
40
|
@udp_socket = UDPSocket.new
|
41
41
|
@tcp_port = tcp_port
|
42
42
|
|
43
|
-
@source_code = source_code
|
44
|
-
@runner = runner
|
45
|
-
@tests_result = tests_result
|
46
|
-
|
47
43
|
@all_tests = {}
|
48
44
|
|
49
45
|
@managers = {}
|
50
46
|
|
51
47
|
@agent_folder_path = agent_folder_path
|
48
|
+
|
49
|
+
@processing = true
|
50
|
+
|
51
|
+
@hardware_specs = hardware_specs
|
52
52
|
end
|
53
53
|
|
54
54
|
# Inicia un servidor udp que se mantiene en espera de la primera petición de conexión del Manager
|
@@ -60,17 +60,17 @@ module Liri
|
|
60
60
|
begin
|
61
61
|
@udp_socket.bind('0.0.0.0', @udp_port)
|
62
62
|
rescue Errno::EADDRINUSE => e
|
63
|
-
Liri.logger.error("Exception(#{e})
|
63
|
+
Liri.logger.error("Exception(#{e}) Busy UDP port #{@udp_port}", true)
|
64
64
|
Thread.exit
|
65
65
|
end
|
66
|
-
Liri.logger.info("
|
67
|
-
(Se espera que algún Manager se contacte por primera vez para establecer una conexión TCP)
|
68
|
-
")
|
66
|
+
Liri.logger.info("Waiting managers request in UDP port #{@udp_port}")
|
69
67
|
|
70
|
-
|
68
|
+
while @processing
|
71
69
|
@manager_request = @udp_socket.recvfrom(1024)
|
72
70
|
manager_ip_address = @manager_request.last.last
|
73
71
|
manager_data = get_manager_data(JSON.parse(@manager_request.first))
|
72
|
+
# TODO: El cliente TCP debería inicicarse en otro hilo, de este modo se tendrá un cliente TCP para cada Manager
|
73
|
+
# y se evita que un mismo cliente procese la ejecución de varios Manager
|
74
74
|
process_manager_connection_request(manager_ip_address, manager_data)
|
75
75
|
end
|
76
76
|
end
|
@@ -79,56 +79,61 @@ module Liri
|
|
79
79
|
# Inicia un cliente tcp para responder a la petición broadcast del Manager para que éste sepa donde enviar las pruebas
|
80
80
|
def start_client_socket_to_process_tests(manager_ip_address, manager_data)
|
81
81
|
tcp_socket = TCPSocket.open(manager_ip_address, @tcp_port)
|
82
|
-
|
83
82
|
agent_ip_address = tcp_socket.addr[2]
|
83
|
+
tcp_socket.puts({ msg: 'get_source_code', hardware_specs: @hardware_specs }.to_json)
|
84
84
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
# En la siguiente línea se espera un puts desde el Manager, pero el Manager no lo hace
|
91
|
-
response = JSON.parse(tcp_socket.gets)
|
92
|
-
return unless response['exist_tests']
|
93
|
-
|
94
|
-
get_source_code(manager_ip_address, manager_data)
|
85
|
+
# Las siguientes variables se usan para guardar momentaneamente los resultados mientras se hace un chequeo de que
|
86
|
+
# el Manager siga ejecutandose o que ya no haya procesado los mismos tests ya ejecutados por otro agente
|
87
|
+
tests_result_file_name = ""
|
88
|
+
tests_result_file_path = ""
|
89
|
+
tests_result = {}
|
95
90
|
|
96
|
-
# Se procesan las pruebas enviadas por el Manager
|
97
91
|
while line = tcp_socket.gets
|
98
|
-
|
99
|
-
|
92
|
+
tcp_socket_data = JSON.parse(line.chop)
|
93
|
+
msg = tcp_socket_data['msg']
|
100
94
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
raw_tests_result = @runner.run_tests(tests)
|
95
|
+
if msg == 'already_connected' || msg == 'no_exist_tests' || msg == 'finish_agent'
|
96
|
+
break
|
97
|
+
end
|
105
98
|
|
106
|
-
|
107
|
-
|
108
|
-
|
99
|
+
if msg == 'proceed_get_source_code'
|
100
|
+
init_work_folders(manager_ip_address)
|
101
|
+
result = get_source_code(manager_ip_address, manager_data)
|
102
|
+
tcp_socket.puts({ msg: result }.to_json)
|
103
|
+
end
|
109
104
|
|
110
|
-
|
111
|
-
|
112
|
-
|
105
|
+
if msg == 'process_tests'
|
106
|
+
tests_batch = tcp_socket_data
|
107
|
+
tests = get_tests(tests_batch, manager_ip_address)
|
108
|
+
|
109
|
+
compressed_file_folder_path = @managers[manager_ip_address][:compressed_file_folder_path]
|
110
|
+
decompressed_file_folder_path = @managers[manager_ip_address][:decompressed_file_folder_path]
|
111
|
+
|
112
|
+
runner = Agent::Runner.new(Liri.unit_test_class, decompressed_file_folder_path)
|
113
|
+
raw_tests_result = runner.run_tests(tests)
|
114
|
+
batch_num = tests_batch['batch_num']
|
115
|
+
tests_result = Common::TestsResult.new(compressed_file_folder_path)
|
116
|
+
tests_result_file_name = tests_result.build_file_name(agent_ip_address, batch_num)
|
117
|
+
tests_result_file_path = tests_result.save(tests_result_file_name, raw_tests_result)
|
118
|
+
# TODO No se debería enviar el resultado si otro agente ya lo procesó, porque osinó reemplazaría el archivo de resultados
|
119
|
+
# ya procesado. ACTUALIZACION: Puede que esto ya se haya arreglado
|
120
|
+
send_tests_results_file(manager_ip_address, manager_data, tests_result_file_path)
|
121
|
+
tests_result = { msg: 'processed_tests', batch_num: batch_num, tests_result_file_name: tests_result_file_name}
|
122
|
+
tcp_socket.puts(tests_result.to_json) # Envía el número de lote y el nombre del archivo de resultados.
|
123
|
+
end
|
113
124
|
end
|
114
125
|
|
115
126
|
tcp_socket.close
|
116
|
-
Liri.logger.info("Se termina la conexión con el Manager #{manager_ip_address} en el puerto TCP: #{@tcp_port}")
|
117
|
-
|
118
|
-
Liri.clean_folder_content(@agent_folder_path)
|
119
|
-
|
120
|
-
start_client_to_close_manager_server(manager_ip_address, 'Conexión Terminada')
|
121
127
|
unregister_manager(manager_ip_address)
|
122
128
|
rescue Errno::EADDRINUSE => e
|
123
|
-
Liri.logger.error("Exception(#{e})
|
129
|
+
Liri.logger.error("Exception(#{e}) Busy UDP port #{@udp_port}")
|
130
|
+
@processing = false
|
124
131
|
rescue Errno::ECONNRESET => e
|
125
132
|
tcp_socket.close
|
126
|
-
Liri.logger.error("Exception(#{e})
|
127
|
-
Liri.logger.info("Se termina la conexión con el Manager #{manager_ip_address} en el puerto TCP: #{@tcp_port}")
|
133
|
+
Liri.logger.error("Exception(#{e}) Closed connection in TCP port #{@tcp_port}", true)
|
128
134
|
unregister_manager(manager_ip_address)
|
129
135
|
rescue Errno::ECONNREFUSED => e
|
130
|
-
Liri.logger.error("Exception(#{e})
|
131
|
-
Liri.logger.info("Se termina la conexión con el Manager #{manager_ip_address} en el puerto TCP: #{@tcp_port}")
|
136
|
+
Liri.logger.error("Exception(#{e}) Rejected connection in TCP port #{@tcp_port}", true)
|
132
137
|
unregister_manager(manager_ip_address)
|
133
138
|
end
|
134
139
|
|
@@ -140,46 +145,36 @@ module Liri
|
|
140
145
|
def process_manager_connection_request(manager_ip_address, manager_data)
|
141
146
|
unless registered_manager?(manager_ip_address)
|
142
147
|
register_manager(manager_ip_address)
|
143
|
-
Liri.logger.info("
|
144
|
-
|
145
|
-
start_client_socket_to_process_tests(manager_ip_address, manager_data)
|
146
|
-
#else
|
147
|
-
#unregister_manager(manager_ip_address)
|
148
|
-
#end
|
148
|
+
Liri.logger.info("Broadcast request received from Manager: #{manager_ip_address} in UDP port: #{@udp_port}")
|
149
|
+
start_client_socket_to_process_tests(manager_ip_address, manager_data)
|
149
150
|
end
|
150
151
|
end
|
151
152
|
|
152
|
-
# Se establece una nueva comunicación con el servidor TCP del Manager con el único objetivo de cerrar el servidor
|
153
|
-
# Esta conexión permitirá al Manager cerrar sus hilos pendientes con servidores TCP en espera y terminar el proceso
|
154
|
-
def start_client_to_close_manager_server(manager_ip_address, msg)
|
155
|
-
tcp_socket = TCPSocket.open(manager_ip_address, @tcp_port)
|
156
|
-
Liri.logger.info("Se termina cualquier proceso pendiente con el Manager #{manager_ip_address} en el puerto TCP: #{@tcp_port}")
|
157
|
-
tcp_socket.print({ msg: msg }.to_json)
|
158
|
-
tcp_socket.close
|
159
|
-
end
|
160
|
-
|
161
153
|
def get_source_code(manager_ip_address, manager_data)
|
162
|
-
#puts "#{manager_data.to_h}"
|
163
154
|
puts ''
|
164
|
-
|
155
|
+
compressed_file_folder_path = @managers[manager_ip_address][:compressed_file_folder_path]
|
156
|
+
decompressed_file_folder_path = @managers[manager_ip_address][:decompressed_file_folder_path]
|
157
|
+
source_code = Liri::Common::SourceCode.new(decompressed_file_folder_path,compressed_file_folder_path, "", Liri.compression_class, Liri.unit_test_class)
|
158
|
+
|
159
|
+
Liri::Common::Benchmarking.start(start_msg: "Getting source code. Wait... ", stdout: true) do
|
165
160
|
puts ''
|
166
161
|
Net::SCP.start(manager_ip_address, manager_data.user, password: manager_data.password) do |scp|
|
167
|
-
scp.download!(manager_data.compressed_file_path,
|
162
|
+
scp.download!(manager_data.compressed_file_path, compressed_file_folder_path)
|
168
163
|
end
|
169
164
|
end
|
170
165
|
puts ''
|
171
166
|
|
172
167
|
downloaded_file_name = manager_data.compressed_file_path.split('/').last
|
173
|
-
downloaded_file_path = File.join(
|
168
|
+
downloaded_file_path = File.join(compressed_file_folder_path, '/', downloaded_file_name)
|
174
169
|
|
175
|
-
Liri::Common::Benchmarking.start(start_msg: "
|
176
|
-
|
177
|
-
@all_tests =
|
170
|
+
Liri::Common::Benchmarking.start(start_msg: "Uncompressing source code. Wait... ", stdout: true) do
|
171
|
+
source_code.decompress_file(downloaded_file_path)
|
172
|
+
@all_tests = source_code.all_tests
|
178
173
|
end
|
179
174
|
puts ''
|
180
175
|
|
181
176
|
# Se cambia temporalmente la carpeta de trabajo a la carpeta de código fuente descomprimida
|
182
|
-
Dir.chdir(
|
177
|
+
Dir.chdir(decompressed_file_folder_path) do
|
183
178
|
# Se borra el directorio .git para evitar el siguiente error al ejecutar las pruebas: fatal: not a git repository (or any of the parent directories): .git
|
184
179
|
# Una mejor alternativa es no traer siquiera esa carpeta junto al código fuente excluyendo la carpeta .git al comprimir el código fuente.
|
185
180
|
# Por cuestiones de tiempo se procede a borrar la carpeta .git por ahora, aunque al parecer el error mostrado no afecta la ejecución del Agent
|
@@ -193,49 +188,44 @@ module Liri
|
|
193
188
|
# Se setea la versión de ruby y el gemset para el código fuente descomprimido
|
194
189
|
# Se especifica el Gemfile del cual se van a instalar los requerimientos
|
195
190
|
# Esto se hace porque por defecto se usa la versión de Ruby de Liri y su Gemset y por ello hay que cambiarlos explicitamente aquí
|
196
|
-
Liri::Common::Benchmarking.start(start_msg: "
|
191
|
+
Liri::Common::Benchmarking.start(start_msg: "Running bundle install. Wait... ", end_msg: "Running bundle install. Duration: ", stdout: true) do
|
197
192
|
puts ''
|
198
193
|
system("bash -lc 'rvm use #{Liri.current_folder_ruby_and_gemset}; BUNDLE_GEMFILE=Gemfile bundle install'")
|
199
194
|
end
|
200
195
|
puts ''
|
201
196
|
|
202
|
-
Liri::Common::Benchmarking.start(start_msg: "
|
197
|
+
Liri::Common::Benchmarking.start(start_msg: "Running rake db:migrate RAILS_ENV=test. Wait... ", end_msg: "Running rake db:migrate RAILS_ENV=test. Duration: ", stdout: true) do
|
203
198
|
puts ''
|
204
199
|
system("bash -lc 'rvm use #{Liri.current_folder_ruby_and_gemset}; rake db:migrate RAILS_ENV=test'")
|
205
200
|
end
|
206
201
|
puts ''
|
207
|
-
|
208
|
-
#Liri::Common::Benchmarking.start(start_msg: "Ejecutando rake db:migrate:reset RAILS_ENV=test. Espere... ", end_msg: "Ejecución de rake db:migrate:reset RAILS_ENV=test. Duración: ", stdout: true) do
|
209
|
-
# puts ''
|
210
|
-
# system("bash -lc 'rvm use #{Liri.current_folder_ruby_and_gemset}; rake db:migrate:reset RAILS_ENV=test'")
|
211
|
-
#end
|
212
|
-
#puts ''
|
213
202
|
end
|
214
|
-
|
203
|
+
'get_tests_files'
|
204
|
+
rescue Liri::FileNotFoundError => e
|
205
|
+
Liri.logger.error("Exception(#{e}) Not found file to decompress in Agent")
|
206
|
+
'get_source_code_fail'
|
215
207
|
rescue Errno::ECONNREFUSED => e
|
216
|
-
Liri.logger.error("Exception(#{e})
|
217
|
-
|
208
|
+
Liri.logger.error("Exception(#{e}) Rejected connection by #{manager_ip_address}. Maybe ssh is not running in #{manager_ip_address}")
|
209
|
+
'get_source_code_fail'
|
218
210
|
rescue Errno::ENOTTY => e
|
219
211
|
# Este rescue es temporal, hay que ver una mejor manera de detectar si la contraseña es incorrecta
|
220
|
-
Liri.logger.error("Exception(#{e})
|
221
|
-
|
222
|
-
false
|
212
|
+
Liri.logger.error("Exception(#{e}) Invalid password received in #{manager_ip_address} for ssh connection")
|
213
|
+
'get_source_code_fail'
|
223
214
|
rescue Net::SSH::AuthenticationFailed => e
|
224
215
|
# Este rescue es temporal, hay que ver una mejor manera de detectar si la contraseña es incorrecta
|
225
|
-
Liri.logger.error("Exception(#{e})
|
226
|
-
|
227
|
-
false
|
216
|
+
Liri.logger.error("Exception(#{e}) Invalid password received in #{manager_ip_address} for ssh connection")
|
217
|
+
'get_source_code_fail'
|
228
218
|
rescue Net::SCP::Error => e
|
229
|
-
Liri.logger.warn("Exception(#{e})
|
230
|
-
|
219
|
+
Liri.logger.warn("Exception(#{e}) File not found in #{manager_ip_address} through scp")
|
220
|
+
'get_source_code_fail'
|
231
221
|
rescue TypeError => e
|
232
|
-
Liri.logger.warn("Exception(#{e})
|
233
|
-
|
222
|
+
Liri.logger.warn("Exception(#{e}) Undetermined error")
|
223
|
+
'get_source_code_fail'
|
234
224
|
end
|
235
225
|
|
236
226
|
def get_manager_data(manager_data_hash)
|
237
227
|
Common::ManagerData.new(
|
238
|
-
|
228
|
+
tests_results_folder_path: manager_data_hash['tests_results_folder_path'],
|
239
229
|
compressed_file_path: manager_data_hash['compressed_file_path'],
|
240
230
|
user: manager_data_hash['user'],
|
241
231
|
password: manager_data_hash['password']
|
@@ -244,9 +234,9 @@ module Liri
|
|
244
234
|
|
245
235
|
def send_tests_results_file(manager_ip_address, manager_data, tests_result_file_path)
|
246
236
|
puts ''
|
247
|
-
Liri::Common::Benchmarking.start(start_msg: "
|
237
|
+
Liri::Common::Benchmarking.start(start_msg: "Sending test files results. Wait... ", stdout: true) do
|
248
238
|
Net::SCP.start(manager_ip_address, manager_data.user, password: manager_data.password) do |scp|
|
249
|
-
scp.upload!(tests_result_file_path, manager_data.
|
239
|
+
scp.upload!(tests_result_file_path, manager_data.tests_results_folder_path)
|
250
240
|
end
|
251
241
|
end
|
252
242
|
puts ''
|
@@ -255,22 +245,44 @@ module Liri
|
|
255
245
|
def get_tests(tests_batch, manager_ip_address)
|
256
246
|
# Se convierte "[5, 9, 13, 1]" a un arreglo [5, 9, 13, 1]
|
257
247
|
tests_keys = tests_batch['tests_batch_keys']
|
258
|
-
Liri.logger.debug("
|
248
|
+
Liri.logger.debug("Tests keys received from Manager #{manager_ip_address}: #{tests_keys}")
|
259
249
|
# Se buscan obtienen los tests que coincidan con las claves recibidas de @all_tests = {1=>"spec/hash_spec.rb:2", 2=>"spec/hash_spec.rb:13", 3=>"spec/hash_spec.rb:24", ..., 29=>"spec/liri_spec.rb:62"}
|
260
250
|
# Se retorna un arreglo con los tests a ejecutar ["spec/liri_spec.rb:4", "spec/hash_spec.rb:5", "spec/hash_spec.rb:59", ..., "spec/hash_spec.rb:37"]
|
261
251
|
tests_keys.map { |test_key| @all_tests[test_key] }
|
262
252
|
end
|
263
253
|
|
254
|
+
def hardware_specs
|
255
|
+
"#{Common::Hardware.cpu} #{Common::Hardware.memory}GB"
|
256
|
+
end
|
257
|
+
|
264
258
|
def registered_manager?(manager_ip_address)
|
265
259
|
@managers[manager_ip_address]
|
266
260
|
end
|
267
261
|
|
268
262
|
def register_manager(manager_ip_address)
|
269
|
-
|
263
|
+
unless registered_manager?(manager_ip_address)
|
264
|
+
@managers[manager_ip_address] = {
|
265
|
+
manager_ip_address: @managers[manager_ip_address]
|
266
|
+
}
|
267
|
+
end
|
270
268
|
end
|
271
269
|
|
272
270
|
def unregister_manager(manager_ip_address)
|
273
271
|
@managers.remove!(manager_ip_address)
|
272
|
+
Liri.logger.info("Finish connection with Manager #{manager_ip_address} in TCP port: #{@tcp_port}")
|
273
|
+
end
|
274
|
+
|
275
|
+
def init_work_folders(manager_ip_address)
|
276
|
+
return if @managers[manager_ip_address][:compressed_file_folder_path]
|
277
|
+
|
278
|
+
compressed_file_folder_path = File.join(@agent_folder_path, '/', "#{DateTime.now.strftime("%d_%m_%y_%H_%M_%S")}_work")
|
279
|
+
Dir.mkdir(compressed_file_folder_path) unless Dir.exist?(compressed_file_folder_path)
|
280
|
+
decompressed_file_folder_path = File.join(compressed_file_folder_path, '/', Common::SourceCode::DECOMPRESSED_FOLDER_NAME)
|
281
|
+
|
282
|
+
@managers[manager_ip_address] = {
|
283
|
+
compressed_file_folder_path: compressed_file_folder_path,
|
284
|
+
decompressed_file_folder_path: decompressed_file_folder_path
|
285
|
+
}
|
274
286
|
end
|
275
287
|
end
|
276
|
-
end
|
288
|
+
end
|