liri 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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/manager/manager.rb
CHANGED
@@ -15,29 +15,32 @@ module Liri
|
|
15
15
|
def run(source_code_folder_path, stop = false)
|
16
16
|
return unless valid_project
|
17
17
|
|
18
|
-
setup_manager = Liri.set_setup(source_code_folder_path)
|
18
|
+
setup_manager = Liri.set_setup(source_code_folder_path, :manager, manager_tests_results_folder_time: DateTime.now.strftime("%d_%m_%y_%H_%M_%S"))
|
19
19
|
manager_folder_path = setup_manager.manager_folder_path
|
20
|
+
manager_tests_results_folder_path = setup_manager.manager_tests_results_folder_path
|
20
21
|
|
21
22
|
Liri.set_logger(setup_manager.logs_folder_path, 'liri-manager.log')
|
22
|
-
Liri.logger.info(
|
23
|
-
Liri.logger.info("
|
23
|
+
Liri.logger.info('Manager process started')
|
24
|
+
Liri.logger.info("Press Ctrl + c to finish Manager process manually\n", true)
|
24
25
|
|
25
26
|
user, password = get_credentials(setup_manager.setup_folder_path)
|
26
27
|
source_code = compress_source_code(source_code_folder_path, manager_folder_path)
|
27
|
-
manager_data = get_manager_data(user, password,
|
28
|
+
manager_data = get_manager_data(user, password, manager_tests_results_folder_path, source_code)
|
28
29
|
all_tests = get_all_tests(source_code)
|
29
|
-
tests_result = Common::TestsResult.new(
|
30
|
+
tests_result = Common::TestsResult.new(manager_tests_results_folder_path)
|
30
31
|
|
31
|
-
manager = Manager.new(Liri.udp_port, Liri.tcp_port, all_tests, tests_result
|
32
|
+
manager = Manager.new(Liri.udp_port, Liri.tcp_port, all_tests, tests_result)
|
32
33
|
|
33
34
|
threads = []
|
34
35
|
threads << manager.start_client_socket_to_search_agents(manager_data) # Enviar peticiones broadcast a toda la red para encontrar Agents
|
35
36
|
manager.start_server_socket_to_process_tests(threads[0]) unless stop # Esperar y enviar los test unitarios a los Agents
|
36
37
|
|
38
|
+
source_code.delete_compressed_file
|
39
|
+
|
37
40
|
Liri.init_exit(stop, threads, 'Manager')
|
38
|
-
Liri.logger.info(
|
41
|
+
Liri.logger.info('Manager process finished')
|
39
42
|
rescue SignalException => e
|
40
|
-
Liri.logger.info("Exception(#{e}) Proceso Manager
|
43
|
+
Liri.logger.info("Exception(#{e}) Proceso Manager process finished manually")
|
41
44
|
Liri.kill(threads)
|
42
45
|
end
|
43
46
|
|
@@ -50,9 +53,9 @@ module Liri
|
|
50
53
|
if File.exist?(File.join(Dir.pwd, 'Gemfile'))
|
51
54
|
true
|
52
55
|
else
|
53
|
-
Liri.logger.info(
|
54
|
-
Liri.logger.info(
|
55
|
-
Liri.logger.info(
|
56
|
+
Liri.logger.info('Not found Gemfile. Assuming run Manager in not Ruby project')
|
57
|
+
Liri.logger.info('Liri can be run only in Ruby projects')
|
58
|
+
Liri.logger.info('Manager process finished')
|
56
59
|
false
|
57
60
|
end
|
58
61
|
end
|
@@ -65,7 +68,7 @@ module Liri
|
|
65
68
|
def compress_source_code(source_code_folder_path, manager_folder_path)
|
66
69
|
source_code = Common::SourceCode.new(source_code_folder_path, manager_folder_path, Liri.compression_class, Liri.unit_test_class)
|
67
70
|
|
68
|
-
Common::Progressbar.start(total: nil, length: 100, format: '
|
71
|
+
Common::Progressbar.start(total: nil, length: 100, format: 'Compressing source code |%B| %a') do
|
69
72
|
source_code.compress_folder
|
70
73
|
end
|
71
74
|
puts "\n\n"
|
@@ -73,9 +76,9 @@ module Liri
|
|
73
76
|
source_code
|
74
77
|
end
|
75
78
|
|
76
|
-
def get_manager_data(user, password,
|
79
|
+
def get_manager_data(user, password, tests_results_folder_path, source_code)
|
77
80
|
Common::ManagerData.new(
|
78
|
-
|
81
|
+
tests_results_folder_path: tests_results_folder_path,
|
79
82
|
compressed_file_path: source_code.compressed_file_path,
|
80
83
|
user: user,
|
81
84
|
password: password
|
@@ -85,7 +88,7 @@ module Liri
|
|
85
88
|
def get_all_tests(source_code)
|
86
89
|
all_tests = {}
|
87
90
|
|
88
|
-
Common::Progressbar.start(total: nil, length: 100, format: '
|
91
|
+
Common::Progressbar.start(total: nil, length: 100, format: 'Getting unit tests |%B| %a') do
|
89
92
|
all_tests = source_code.all_tests
|
90
93
|
end
|
91
94
|
puts "\n\n"
|
@@ -94,7 +97,7 @@ module Liri
|
|
94
97
|
end
|
95
98
|
end
|
96
99
|
|
97
|
-
def initialize(udp_port, tcp_port, all_tests, tests_result
|
100
|
+
def initialize(udp_port, tcp_port, all_tests, tests_result)
|
98
101
|
@udp_port = udp_port
|
99
102
|
@udp_socket = UDPSocket.new
|
100
103
|
@tcp_port = tcp_port
|
@@ -102,7 +105,7 @@ module Liri
|
|
102
105
|
@all_tests = all_tests
|
103
106
|
@all_tests_count = all_tests.size
|
104
107
|
@all_tests_results = {}
|
105
|
-
@
|
108
|
+
@files_processed = 0
|
106
109
|
@all_tests_processing_count = 0
|
107
110
|
@agents = {}
|
108
111
|
|
@@ -110,13 +113,11 @@ module Liri
|
|
110
113
|
@test_processing_enabled = true
|
111
114
|
|
112
115
|
@tests_batch_number = 0
|
113
|
-
@
|
116
|
+
@processed_tests_batches = {}
|
114
117
|
|
115
118
|
@tests_result = tests_result
|
116
119
|
@semaphore = Mutex.new
|
117
120
|
|
118
|
-
@manager_folder_path = manager_folder_path
|
119
|
-
|
120
121
|
@progressbar = ProgressBar.create(starting_at: 0, total: @all_tests_count, length: 100, format: 'Progress %c/%C |%b=%i| %p%% | %a')
|
121
122
|
end
|
122
123
|
|
@@ -125,10 +126,8 @@ module Liri
|
|
125
126
|
# El cliente udp se ejecuta en bucle dentro de un hilo, esto permite realizar otras tareas mientras este hilo sigue sondeando
|
126
127
|
# la red para obtener mas Agents. Una vez que los tests terminan de ejecutarse, este hilo será finalizado.
|
127
128
|
Thread.new do
|
128
|
-
Liri.logger.info(
|
129
|
-
Liri.logger.info("
|
130
|
-
(Se mantiene escaneando la red para encontrar Agents)
|
131
|
-
")
|
129
|
+
Liri.logger.info('Searching agents... Wait')
|
130
|
+
Liri.logger.info("Sending UDP broadcast each #{Liri.udp_request_delay} seconds in UDP port: #{@udp_port}")
|
132
131
|
while agents_search_processing_enabled
|
133
132
|
@udp_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
|
134
133
|
@udp_socket.send(manager_data.to_h.to_json, 0, '<broadcast>', @udp_port)
|
@@ -142,88 +141,94 @@ module Liri
|
|
142
141
|
begin
|
143
142
|
tcp_socket = TCPServer.new(@tcp_port) # se hace un bind al puerto dado
|
144
143
|
rescue Errno::EADDRINUSE => e
|
145
|
-
Liri.logger.error("Exception(#{e})
|
144
|
+
Liri.logger.error("Exception(#{e}) Busy UDP port #{@tcp_port}.")
|
146
145
|
Thread.kill(search_agents_thread)
|
147
|
-
|
146
|
+
return
|
148
147
|
end
|
149
148
|
|
150
|
-
Liri.logger.info("
|
151
|
-
(Se espera que algún Agent se conecte para ejecutar las pruebas como respuesta al broadcast UDP)
|
152
|
-
")
|
149
|
+
Liri.logger.info("Waiting Agents connection in TCP port: #{@tcp_port}")
|
153
150
|
# El siguiente bucle permite que varios clientes es decir Agents se conecten
|
154
151
|
# De: http://www.w3big.com/es/ruby/ruby-socket-programming.html
|
155
152
|
while test_processing_enabled
|
156
153
|
Thread.start(tcp_socket.accept) do |client|
|
157
154
|
agent_ip_address = client.remote_address.ip_address
|
158
|
-
|
159
|
-
|
160
|
-
Liri.logger.info("\nConexión iniciada con el Agente: #{agent_ip_address}")
|
161
|
-
Liri.logger.info("Respuesta al broadcast recibida del Agent: #{agent_ip_address} en el puerto TCP: #{@tcp_port}: #{response}")
|
162
|
-
|
163
|
-
# Se le indica al agente que proceda
|
164
|
-
client.puts({ msg: 'Recibido', exist_tests: all_tests.any? }.to_json)
|
165
|
-
|
166
|
-
if all_tests.empty?
|
167
|
-
# No importa lo que le haga, el broadcast udp no se muere al instante y el agente sigue respondiendo
|
168
|
-
# Las siguientes dos lineas son para que se deje de hacer el broadcast pero aun asi se llegan a hacer
|
169
|
-
# 3 a 4 broadcast antes de que se finalize el proceso, al parecer el broadcast va a tener que quedar asi
|
170
|
-
# y mejorar el codigo para que se envien test pendientes para eso hay que llevar una lista de test pendientes
|
171
|
-
# tests enviados sin resultados, tests finalizados, si se recibe respuesta al broadcast se trata de enviar primero test pendientes
|
172
|
-
# luego test enviados sin resultados o sino ignorar
|
173
|
-
Thread.kill(search_agents_thread)
|
174
|
-
agents_search_processing_enabled = false
|
175
|
-
Liri.logger.info("Se termina cualquier proceso pendiente con el Agent #{agent_ip_address} en el puerto TCP: #{@tcp_port}: #{response}")
|
176
|
-
client.close
|
177
|
-
Thread.exit
|
178
|
-
end
|
155
|
+
hardware_model = nil
|
156
|
+
run_tests_batch_time_start = nil
|
179
157
|
|
180
|
-
while
|
181
|
-
|
182
|
-
|
183
|
-
break unless tests_batch
|
158
|
+
while line = client.gets
|
159
|
+
client_data = JSON.parse(line.chop)
|
160
|
+
msg = client_data['msg']
|
184
161
|
|
185
|
-
|
186
|
-
|
162
|
+
if msg == 'get_source_code'
|
163
|
+
if registered_agent?(agent_ip_address)
|
164
|
+
client.puts({ msg: 'already_connected' }.to_json)
|
165
|
+
client.close
|
166
|
+
break
|
167
|
+
else
|
168
|
+
register_agent(agent_ip_address)
|
169
|
+
hardware_model = client_data['hardware_model']
|
170
|
+
msg = all_tests.any? ? 'proceed_get_source_code' : 'no_exist_tests'
|
171
|
+
client.puts({ msg: msg }.to_json)
|
172
|
+
end
|
173
|
+
end
|
187
174
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
175
|
+
if msg == 'get_source_code_fail'
|
176
|
+
client.puts({ msg: 'finish_agent' }.to_json)
|
177
|
+
client.close
|
178
|
+
break
|
179
|
+
end
|
180
|
+
|
181
|
+
if msg == 'get_tests_files'
|
182
|
+
Liri.logger.info("Running unit tests. Agent: #{agent_ip_address}. Wait... ", false)
|
183
|
+
run_tests_batch_time_start = Time.now
|
184
|
+
|
185
|
+
tests_batch = tests_batch(agent_ip_address)
|
186
|
+
if tests_batch.empty?
|
187
|
+
client.puts({ msg: 'no_exist_tests' }.to_json)
|
188
|
+
client.close
|
194
189
|
break
|
190
|
+
else
|
191
|
+
client.puts(tests_batch.to_json) # Se envia el lote de tests
|
195
192
|
end
|
196
193
|
end
|
197
194
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
process_tests_result(agent_ip_address, tests_result,
|
203
|
-
|
204
|
-
|
195
|
+
if msg == 'processed_tests'
|
196
|
+
tests_result = client_data
|
197
|
+
Liri.logger.debug("Agent response #{agent_ip_address}: #{tests_result}")
|
198
|
+
batch_run = Time.now - run_tests_batch_time_start
|
199
|
+
process_tests_result(agent_ip_address, hardware_model, tests_result, batch_run)
|
200
|
+
|
201
|
+
run_tests_batch_time_start = Time.now
|
202
|
+
|
203
|
+
tests_batch = tests_batch(agent_ip_address)
|
204
|
+
if tests_batch.empty?
|
205
|
+
client.puts({ msg: 'no_exist_tests' }.to_json)
|
206
|
+
client.close
|
207
|
+
break
|
208
|
+
else
|
209
|
+
client.puts(tests_batch.to_json) # Se envia el lote de tests
|
210
|
+
end
|
205
211
|
end
|
206
212
|
end
|
207
213
|
|
208
214
|
update_processing_statuses
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
Thread.exit
|
219
|
-
end
|
215
|
+
Thread.kill(search_agents_thread)
|
216
|
+
unregister_agent(agent_ip_address)
|
217
|
+
rescue Errno::EPIPE => e
|
218
|
+
# Esto al parecer se da cuando el Agent ya cerró las conexiones y el Manager intenta contactar
|
219
|
+
Liri.logger.error("Exception(#{e}) Agent #{agent_ip_address} already finished connection")
|
220
|
+
# Si el Agente ya no responde es mejor terminar el hilo. Aunque igual quedará colgado el Manager
|
221
|
+
# mientras sigan pruebas pendientes
|
222
|
+
unregister_agent(agent_ip_address)
|
223
|
+
Thread.exit
|
220
224
|
end
|
221
225
|
end
|
222
226
|
|
223
|
-
Liri.clean_folder_content(@manager_folder_path)
|
224
227
|
@tests_result.print_summary
|
225
228
|
print_agents_summary
|
226
|
-
|
229
|
+
print_agents_detailed_summary if Liri.print_agents_detailed_summary
|
230
|
+
@tests_result.print_failures_list if Liri.print_failures_list
|
231
|
+
@tests_result.print_failed_examples if Liri.print_failed_examples
|
227
232
|
end
|
228
233
|
|
229
234
|
def all_tests
|
@@ -252,7 +257,7 @@ module Liri
|
|
252
257
|
|
253
258
|
def update_processing_statuses
|
254
259
|
@semaphore.synchronize do
|
255
|
-
@test_processing_enabled = false if @all_tests_count == @
|
260
|
+
@test_processing_enabled = false if @all_tests_count == @files_processed
|
256
261
|
@agents_search_processing_enabled = false if @all_tests_count == @all_tests_processing_count
|
257
262
|
end
|
258
263
|
end
|
@@ -260,61 +265,120 @@ module Liri
|
|
260
265
|
def tests_batch(agent_ip_address)
|
261
266
|
# Se inicia un semáforo para evitar que varios hilos actualicen variables compartidas
|
262
267
|
@semaphore.synchronize do
|
263
|
-
return
|
268
|
+
return {} if @all_tests.empty?
|
264
269
|
|
265
270
|
@tests_batch_number += 1 # Se numera cada lote
|
266
271
|
samples = @all_tests.sample!(Manager.test_files_by_runner) # Se obtiene algunos tests
|
267
272
|
samples_keys = samples.keys # Se obtiene la clave asignada a los tests
|
268
273
|
@all_tests_processing_count += samples_keys.size
|
269
274
|
|
270
|
-
|
271
|
-
|
272
|
-
#@tests_batches[@tests_batch_number] = { agent_ip_address: agent_ip_address, tests_batch_keys: samples_keys } # Se guarda el lote a enviar
|
273
|
-
tests_batch = { tests_batch_number: @tests_batch_number, tests_batch_keys: samples_keys } # Se construye el lote a enviar
|
275
|
+
tests_batch = { msg: 'process_tests', tests_batch_number: @tests_batch_number, tests_batch_keys: samples_keys } # Se construye el lote a enviar
|
276
|
+
Liri.logger.debug("Tests batches sent to Agent #{agent_ip_address}: #{tests_batch}")
|
274
277
|
tests_batch
|
275
278
|
end
|
276
279
|
end
|
277
280
|
|
278
|
-
def process_tests_result(agent_ip_address, tests_result,
|
281
|
+
def process_tests_result(agent_ip_address, hardware_model, tests_result, batch_run)
|
279
282
|
# Se inicia un semáforo para evitar que varios hilos actualicen variables compartidas
|
280
283
|
@semaphore.synchronize do
|
281
284
|
tests_batch_number = tests_result['tests_batch_number']
|
282
285
|
tests_result_file_name = tests_result['tests_result_file_name']
|
283
|
-
|
284
|
-
|
285
|
-
#tests_batch_keys = @tests_batches[tests_batch_number][:tests_batch_keys]
|
286
|
-
tests_processed_count = tests_batch_keys_size
|
287
|
-
@all_tests_results_count += tests_processed_count
|
286
|
+
files_processed = tests_result['tests_batch_keys_size']
|
288
287
|
|
289
|
-
@
|
288
|
+
@files_processed += files_processed
|
290
289
|
|
291
|
-
|
290
|
+
@progressbar.progress = @files_processed
|
292
291
|
|
293
|
-
tests_result = @tests_result.process(tests_result_file_name)
|
292
|
+
tests_result = @tests_result.process(tests_result_file_name, files_processed)
|
294
293
|
|
295
|
-
@
|
296
|
-
@
|
297
|
-
@
|
298
|
-
@
|
299
|
-
@
|
294
|
+
@processed_tests_batches[tests_batch_number] = tests_result.clone
|
295
|
+
@processed_tests_batches[tests_batch_number][:batch_run] = batch_run
|
296
|
+
@processed_tests_batches[tests_batch_number][:agent_ip_address] = agent_ip_address
|
297
|
+
@processed_tests_batches[tests_batch_number][:hardware_model] = hardware_model
|
298
|
+
@processed_tests_batches[tests_batch_number][:tests_batch_number] = tests_batch_number
|
300
299
|
|
301
|
-
Liri.logger.info("
|
300
|
+
Liri.logger.info("Processed unit tests by Agent: #{agent_ip_address}: #{files_processed}")
|
302
301
|
end
|
303
302
|
end
|
304
303
|
|
305
304
|
def print_agents_summary
|
306
|
-
|
307
|
-
|
305
|
+
processed_tests_batches_by_agent = processed_tests_batches_by_agents
|
306
|
+
rows = processed_tests_batches_by_agent.values.map do |value|
|
307
|
+
value[:finish_in] = value[:finish_in].to_duration
|
308
|
+
value[:files_load] = value[:files_load].to_duration
|
309
|
+
value[:batch_run] = value[:batch_run].to_duration
|
310
|
+
value.values
|
311
|
+
end
|
308
312
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
table.align_column(2, :right)
|
313
|
-
table.align_column(3, :right)
|
314
|
-
table.align_column(4, :right)
|
315
|
-
table.align_column(5, :right)
|
313
|
+
rows << Array.new(9) # Se agrega una linea vacia antes de mostrar los totales
|
314
|
+
rows << get_footer_values
|
315
|
+
header = processed_tests_batches_by_agent.values.first.keys
|
316
316
|
|
317
|
+
table = Terminal::Table.new title: 'Summary', headings: header, rows: rows
|
318
|
+
table.style = { padding_left: 3, border_x: '=', border_i: 'x'}
|
317
319
|
puts table
|
318
320
|
end
|
321
|
+
|
322
|
+
def processed_tests_batches_by_agents
|
323
|
+
tests_batches = {}
|
324
|
+
@processed_tests_batches.values.each do |processed_test_batch|
|
325
|
+
agent_ip_address = processed_test_batch[:agent_ip_address]
|
326
|
+
if tests_batches[agent_ip_address]
|
327
|
+
tests_batches[agent_ip_address][:examples] += processed_test_batch[:examples]
|
328
|
+
tests_batches[agent_ip_address][:failures] += processed_test_batch[:failures]
|
329
|
+
tests_batches[agent_ip_address][:pending] += processed_test_batch[:pending]
|
330
|
+
tests_batches[agent_ip_address][:passed] += processed_test_batch[:passed]
|
331
|
+
tests_batches[agent_ip_address][:finish_in] += processed_test_batch[:finish_in]
|
332
|
+
tests_batches[agent_ip_address][:files_load] += processed_test_batch[:files_load]
|
333
|
+
tests_batches[agent_ip_address][:files_processed] += processed_test_batch[:files_processed]
|
334
|
+
tests_batches[agent_ip_address][:batch_run] += processed_test_batch[:batch_run]
|
335
|
+
else
|
336
|
+
_processed_test_batch = processed_test_batch.clone # Clone to change values in other hash
|
337
|
+
_processed_test_batch.remove!(:failures_list, :failed_examples, :agent_ip_address, :tests_batch_number)
|
338
|
+
tests_batches[agent_ip_address] = _processed_test_batch
|
339
|
+
end
|
340
|
+
end
|
341
|
+
tests_batches
|
342
|
+
end
|
343
|
+
|
344
|
+
def print_agents_detailed_summary
|
345
|
+
puts "\n"
|
346
|
+
rows = @processed_tests_batches.values.map do |value|
|
347
|
+
value.remove!(:failures_list, :failed_examples, :agent_ip_address, :tests_batch_number)
|
348
|
+
value[:finish_in] = value[:finish_in].to_duration
|
349
|
+
value[:files_load] = value[:files_load].to_duration
|
350
|
+
value[:batch_run] = value[:batch_run].to_duration
|
351
|
+
value.values
|
352
|
+
end
|
353
|
+
|
354
|
+
rows << Array.new(9) # Se agrega una linea vacia antes de mostrar los totales
|
355
|
+
rows << get_footer_values
|
356
|
+
header = @processed_tests_batches.values.first.keys
|
357
|
+
|
358
|
+
table = Terminal::Table.new title: 'Detailed Summary', headings: header, rows: rows
|
359
|
+
table.style = { padding_left: 3, border_x: '=', border_i: 'x' }
|
360
|
+
|
361
|
+
puts table
|
362
|
+
end
|
363
|
+
|
364
|
+
def get_footer_values
|
365
|
+
footer = { examples: @tests_result.examples, failures: @tests_result.failures, pending: @tests_result.pending,
|
366
|
+
passed: @tests_result.passed, finish_in: "", files_load: "",
|
367
|
+
files_processed: @tests_result.files_processed, batch_run: "", hardware_model: "" }
|
368
|
+
footer.values
|
369
|
+
end
|
370
|
+
|
371
|
+
def registered_agent?(agent_ip_address)
|
372
|
+
@agents[agent_ip_address]
|
373
|
+
end
|
374
|
+
|
375
|
+
def register_agent(agent_ip_address)
|
376
|
+
@agents[agent_ip_address] = agent_ip_address
|
377
|
+
Liri.logger.info("\nStarted connection with Agent: #{agent_ip_address} in TCP port: #{@tcp_port}")
|
378
|
+
end
|
379
|
+
|
380
|
+
def unregister_agent(agent_ip_address)
|
381
|
+
@agents.remove!(agent_ip_address)
|
382
|
+
end
|
319
383
|
end
|
320
384
|
end
|
data/lib/task.rb
CHANGED
@@ -5,9 +5,13 @@
|
|
5
5
|
module Liri
|
6
6
|
module Task
|
7
7
|
class << self
|
8
|
-
def
|
8
|
+
def tests_files(source_code_folder_path)
|
9
9
|
source_code = Liri::Common::SourceCode.new(source_code_folder_path,'', Liri.compression_class, Liri.unit_test_class)
|
10
|
-
source_code.all_tests
|
10
|
+
source_code.all_tests
|
11
|
+
end
|
12
|
+
|
13
|
+
def tests_count(source_code_folder_path)
|
14
|
+
tests_files(source_code_folder_path).size
|
11
15
|
end
|
12
16
|
end
|
13
17
|
end
|
data/template/liri-config.yml
CHANGED
@@ -2,10 +2,16 @@
|
|
2
2
|
# Configuración del Nombre del archivo de código fuente comprimido enviado a los agentes
|
3
3
|
# Obs.: Puede que no sea útil para el usuario poder cambiar este nombre
|
4
4
|
compressed_file_name: compressed_source_code
|
5
|
-
# Configuración de la cantidad de tests a ejecutar
|
5
|
+
# Configuración de la cantidad de archivos de tests a ejecutar en cada tanda
|
6
6
|
test_files_by_runner: 10
|
7
|
-
|
8
|
-
|
7
|
+
# Configuración para imprimir la lista detallada de tests fallidos
|
8
|
+
print_failures_list: false
|
9
|
+
# Configuración para imprimir la lista resumida de tests fallidos
|
10
|
+
print_failed_examples: false
|
11
|
+
# Configuración para imprimir un resumen detallado del proceso realizado por los agentes
|
12
|
+
print_agents_detailed_summary: false
|
13
|
+
# Configuración para definir cada cuantos segundo el Manager enviará un broadcast UDP a la red para sondear agentes
|
14
|
+
udp_request_delay: 3
|
9
15
|
log:
|
10
16
|
stdout:
|
11
17
|
# Configuración que define si se muestra el log de ejecución del programa en línea de comando. Puede ser true o false.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: liri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rodrigo Fernández
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-05-
|
12
|
+
date: 2022-05-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rubyzip
|
@@ -192,7 +192,9 @@ files:
|
|
192
192
|
- lib/common/setup.rb
|
193
193
|
- lib/common/source_code.rb
|
194
194
|
- lib/common/tests_result.rb
|
195
|
+
- lib/common/text_time_parser.rb
|
195
196
|
- lib/common/unit_test/rspec.rb
|
197
|
+
- lib/common/unit_test/rspec_result_parser.rb
|
196
198
|
- lib/exe/agent.rb
|
197
199
|
- lib/exe/manager.rb
|
198
200
|
- lib/hash_extend.rb
|