liri 0.3.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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/exe/liri +27 -8
- 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 +4 -18
- 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 +470 -164
- data/lib/task.rb +6 -2
- data/liri.gemspec +6 -6
- data/template/liri-config.yml +75 -30
- metadata +14 -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: 6a9d3148572b163bc3f6cc5ad627b47bcc27ea976c4ca020e945cdfdbbbb941f
|
4
|
+
data.tar.gz: d7c73dea139fa130a2dbfcd770b2b07f7dc1c113c609e891c2d351b88a10fd04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4189307cce67d58828440a1692e1be0e9bf006718e980a9465244f48b757031ed88a8ba106cec9eaaf3621a9abb1fcd500c1ecba19bded99878388a5503cfbe
|
7
|
+
data.tar.gz: 4f26eb422e762be63962a7685f5f7a7194ad7c9d28762af146e3e519fe9b00b376dbcbab88bb8da9ef181fd41fb534287e9ac93fdc320eced15e5e5f45125528
|
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.1)
|
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,8 +26,8 @@ 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)
|
30
|
-
Liri::Common::Benchmarking.start(end_msg: "\
|
29
|
+
Liri.set_setup(current_folder, :manager)
|
30
|
+
Liri::Common::Benchmarking.start(end_msg: "\nFinished in: ", stdout: true) do
|
31
31
|
# Metodo que se ejecuta al llamar al comando manager
|
32
32
|
Liri::Manager.run(current_folder)
|
33
33
|
end
|
@@ -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
|