Skip to content

Commit 77ecac0

Browse files
rueyjyenk-ty
authored andcommitted
Enhance/parallel linkstatus (#28)
* change parallel helper to module * change template config setting * change to block * fix spec * change into float * fix number * move check hash place * fix for rubocop * change to include * change block parameter * fix block * fix for review. * fix for rubocop
1 parent ebfa74a commit 77ecac0

File tree

21 files changed

+110
-49
lines changed

21 files changed

+110
-49
lines changed

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
bucky-core (0.9.5)
4+
bucky-core (0.9.7)
55
color_echo (~> 3.1)
66
json (~> 2.1)
77
nokogiri (~> 1.8)

example/bucky-management/config/bucky_config.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
:parallel_num: 4
21
:test_result_path: './system/test_results/'
32
:log_path: './system/logs/'
43
:screen_shot_path: './system/evidences/screen_shots/'

example/bucky-management/config/e2e_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
:selenium_port: '4444' # Default selenium port
33
:browser: :chrome # Only chrome
44
:headless: false
5+
:e2e_parallel_num: 1
56
:sp_device_name: :iphone
67
:tablet_device_name: :ipad
78
:device_name_on_chrome:
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
:linkstatus_parallel_num: 8
1+
:linkstatus_parallel_num: 1
2+
:linkstatus_thread_num: 4
23
:linkstatus_open_timeout: 60
34
:linkstatus_read_timeout: 60

example/hands-on/config/bucky_config.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
:parallel_num: 4
21
:test_result_path: './system/test_results/'
32
:log_path: './system/logs/'
43
:screen_shot_path: './system/evidences/screen_shots/'

example/hands-on/config/e2e_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
:selenium_port: '4444' # default selenium port
33
:browser: :chrome # Only chrome
44
:headless: false
5+
:e2e_parallel_num: 1
56
:sp_device_name: :iphone
67
:tablet_device_name: :ipad
78
:device_name_on_chrome:
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
:linkstatus_parallel_num: 8
1+
:linkstatus_parallel_num: 1
2+
:linkstatus_thread_num: 4
23
:linkstatus_open_timeout: 60
34
:linkstatus_read_timeout: 60

lib/bucky/core/test_core/test_class_generator.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def initialize(test_cond)
4545
end
4646

4747
# Genrate test class by test suite and test case data
48-
def generate_test_class(data, link_status_url_log)
48+
def generate_test_class(data, link_status_url_log = {})
4949
test_cond = @test_cond
5050
# Common proccessing
5151
# e.g.) TestSampleAppPcE2e1, TestSampleAppPcHttpstatus1

lib/bucky/core/test_core/test_manager.rb

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,50 @@
88
module Bucky
99
module Core
1010
module TestCore
11+
module ParallelHelper
12+
parent_pid = Process.pid
13+
14+
# Terminate parent and child process when getting interrupt signal
15+
Signal.trap('INT') do
16+
Process.kill('TERM', -1 * parent_pid)
17+
end
18+
19+
private
20+
21+
def parallel_new_worker_each(data_set, max_processes, &block)
22+
# Max parallel workers number
23+
available_workers = max_processes
24+
25+
# If child process dead, available workers increase
26+
Signal.trap('CLD') { available_workers += 1 }
27+
28+
data_set.each do |data|
29+
# Wait until worker is available
30+
Process.wait unless available_workers.positive?
31+
# Workers decrease when start working
32+
available_workers -= 1
33+
fork { block.call(data) }
34+
end
35+
Process.waitall
36+
end
37+
38+
def parallel_distribute_into_workers(data_set, max_processes, &block)
39+
# Group the data by remainder of index
40+
data_set_grouped = data_set.group_by.with_index { |_elem, index| index % max_processes }
41+
# Use 'values' method to get only hash's key into an array
42+
data_set_grouped.values.each do |data_for_pre_worker|
43+
# Number of child process is equal to max_processes (or equal to data_set length when data_set length is less than max_processes)
44+
fork do
45+
data_for_pre_worker.each { |data| block.call(data) }
46+
end
47+
end
48+
Process.waitall
49+
end
50+
end
51+
1152
class TestManager
53+
include ParallelHelper
54+
1255
# Keep test conditions and round number
1356
def initialize(test_cond)
1457
@test_cond = test_cond
@@ -45,8 +88,17 @@ def load_test_suites
4588

4689
# Generate and execute test
4790
def do_test_suites(test_suite_data)
48-
parallel_num = Bucky::Utils::Config.instance[:parallel_num]
49-
parallel_helper(test_suite_data, parallel_num)
91+
# For checking on linkstatus
92+
e2e_parallel_num = Bucky::Utils::Config.instance[:e2e_parallel_num]
93+
linkstatus_parallel_num = Bucky::Utils::Config.instance[:linkstatus_parallel_num]
94+
tcg = Bucky::Core::TestCore::TestClassGenerator.new(@test_cond)
95+
96+
case @test_cond[:test_category][0]
97+
when 'e2e' then parallel_new_worker_each(test_suite_data, e2e_parallel_num) { |data| tcg.generate_test_class(data) }
98+
when 'linkstatus' then
99+
link_status_url_log = {}
100+
parallel_distribute_into_workers(test_suite_data, linkstatus_parallel_num) { |data| tcg.generate_test_class(data, link_status_url_log) }
101+
end
50102
end
51103

52104
def execute_test
@@ -60,31 +112,6 @@ def execute_test
60112
break if @test_cond[:re_test_cond].empty?
61113
end
62114
end
63-
64-
def parallel_helper(test_suite_data, max_processes)
65-
# Max parallel workers number
66-
available_workers = max_processes
67-
# For checking on linkstatus
68-
link_status_url_log = {}
69-
parent_pid = Process.pid
70-
tcg = Bucky::Core::TestCore::TestClassGenerator.new(@test_cond)
71-
72-
# If child process dead, available workers increase
73-
Signal.trap('CLD') { available_workers += 1 }
74-
# Terminate parent and child process when getting interrupt signal
75-
Signal.trap('INT') do
76-
Process.kill('TERM', -1 * parent_pid)
77-
end
78-
79-
test_suite_data.each do |data|
80-
# Wait until worker is available
81-
Process.wait unless available_workers.positive?
82-
# Workers decrease when start working
83-
available_workers -= 1
84-
fork { tcg.generate_test_class(data, link_status_url_log) }
85-
end
86-
Process.waitall
87-
end
88115
end
89116
end
90117
end

lib/bucky/test_equipment/verifications/status_checker.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def link_status_check(args)
9090
links = exclude(links, exclude_urls) unless exclude_urls.nil?
9191

9292
errors = []
93-
Parallel.each(links.uniq, in_threads: Bucky::Utils::Config.instance[:linkstatus_parallel_num]) do |link|
93+
Parallel.each(links.uniq, in_threads: Bucky::Utils::Config.instance[:linkstatus_thread_num]) do |link|
9494
http_status_check_args[:url] = link
9595
http_status_check_args[:redirect_url_list] = []
9696
link_response = http_status_check(http_status_check_args)

spec/core/test_core/test_manager_spec.rb

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,18 @@
7070

7171
describe '#parallel_helper' do
7272
let(:tm) { Bucky::Core::TestCore::TestManager.new(re_test_count: 1) }
73+
let(:parallel_helper) { Class.new { extend Bucky::Core::TestCore::ParallelHelper } }
74+
let(:block_mock) { proc { 'Block mock' } }
75+
let(:ng_case_data) { {} }
7376
before do
7477
$debug = true
7578
end
7679
after do
7780
$debug = false
7881
end
79-
context 'run test in multiprocess' do
80-
let(:ng_case_data) { {} }
81-
let(:parallel_num) { 2 }
82-
let(:test_suite_data) do
82+
context 'parallel_new_worker_each' do
83+
let(:e2e_parallel_num) { 2 }
84+
let(:test_suite_data_e2e) do
8385
[
8486
{ test_class_name: 'test',
8587
test_suite_name: 'test',
@@ -95,11 +97,38 @@
9597
]
9698
end
9799

98-
it 'create test class instance in fork' do
99-
allow(tm).to receive(:fork) do |&block|
100-
expect(block.call).to eq(Bucky::Core::TestCore::TestClasses::TestSpecPcE2etest)
100+
it 'call target block in fork' do
101+
allow(parallel_helper).to receive(:fork) do |&block|
102+
expect(block.call).to eq('Block mock')
101103
end
102-
tm.send(:parallel_helper, test_suite_data, parallel_num)
104+
parallel_helper.send(:parallel_new_worker_each, test_suite_data_e2e, e2e_parallel_num, &block_mock)
105+
end
106+
end
107+
108+
context 'parallel_distribute_into_workers' do
109+
let(:linkstatus_parallel_num) { 2 }
110+
let(:test_suite_data_linkstatus) do
111+
[
112+
{ test_class_name: 'test',
113+
test_suite_name: 'test',
114+
test_category: 'linkstatus',
115+
suite: {
116+
device: 'pc',
117+
service: 'spec',
118+
test_category: 'linkstatus',
119+
cases: [
120+
{ case_name: 'test_1' }
121+
]
122+
} }
123+
]
124+
end
125+
it 'make workers in fork then call block in each' do
126+
allow(parallel_helper).to receive(:fork) do |&block_fork|
127+
allow(block_fork.call).to receive(:each) do |&block_each|
128+
expect(block_each.call).to eq('Block mock')
129+
end
130+
end
131+
parallel_helper.send(:parallel_distribute_into_workers, test_suite_data_linkstatus, linkstatus_parallel_num, &block_mock)
103132
end
104133
end
105134
end

spec/test_equipment/verifications/status_checker_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
allow(response).to receive(:code).and_return(code)
105105
allow(response).to receive(:entity)
106106
allow(subject).to receive(:make_target_links).and_return(links)
107-
allow(Bucky::Utils::Config).to receive(:instance).and_return(linkstatus_parallel_num: 4)
107+
allow(Bucky::Utils::Config).to receive(:instance).and_return(linkstatus_thread_num: 4)
108108
end
109109
context 'no error base url, link url' do
110110
it 'not raise exception' do

spec/utils/bucky_config.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
:parallel_num: 4
21
:log_path: './spec/utils/'
32
:screen_shot_path: './system/screen_shots/'
43
:bucky_error: 'bucky_error'

spec/utils/e2e_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
:selenium_mode: :remote # Other selection: :local(only PC mode), :headless
44
:browser: :chrome # Other selection: :firefox (only PC mode)
55
:headless: false
6+
:e2e_parallel_num: 1
67
:sp_device_name: :iphone6 # Other selection: nexus5
78
:device_chrome_name:
89
:iphone6: 'Apple iPhone 6'

spec/utils/linkstatus_config.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
:linkstatus_open_timeout: 60
22
:linkstatus_read_timeout: 60
3-
:linkstatus_parallel_num: 8
3+
:linkstatus_parallel_num: 1
4+
:linkstatus_thread_num: 4

system_testing/test_bucky_project/config/bucky_config.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
:parallel_num: 4
21
:test_result_path: './system/test_results/'
32
:log_path: './system/logs/'
43
:screen_shot_path: './system/evidences/screen_shots/'

system_testing/test_bucky_project/config/e2e_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
:selenium_port: '4444' # Default selenium port
33
:browser: :chrome # Only chrome
44
:headless: false
5+
:e2e_parallel_num: 1
56
:sp_device_name: :iphone
67
:tablet_device_name: :ipad
78
:device_name_on_chrome:
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
:linkstatus_parallel_num: 8
1+
:linkstatus_parallel_num: 1
2+
:linkstatus_thread_num: 4
23
:linkstatus_open_timeout: 60
34
:linkstatus_read_timeout: 60

template/new/config/bucky_config.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
:parallel_num: 4
21
:test_result_path: './system/test_results/'
32
:log_path: './system/logs/'
43
:screen_shot_path: './system/evidences/screen_shots/'

template/new/config/e2e_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
:selenium_port: '4444' # Default selenium port
33
:browser: :chrome # Only chrome
44
:headless: false
5+
:e2e_parallel_num: 1
56
:sp_device_name: :iphone
67
:tablet_device_name: :ipad
78
:device_name_on_chrome:
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
:linkstatus_parallel_num: 8
1+
:linkstatus_parallel_num: 1
2+
:linkstatus_thread_num: 4
23
:linkstatus_open_timeout: 60
34
:linkstatus_read_timeout: 60

0 commit comments

Comments
 (0)