tes-request 0.8 → 0.9
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 +5 -5
- data/.travis.yml +1 -0
- data/bin/tes-ci-pool +28 -0
- data/bin/tes-ci-slicer +4 -2
- data/lib/hash.rb +3 -3
- data/lib/tes/request/client.rb +5 -2
- data/lib/tes/request/expression.rb +2 -0
- data/lib/tes/request/rspec/ci_pool.rb +42 -0
- data/lib/tes/request/rspec/ci_slicer.rb +17 -6
- data/lib/tes/request/rspec/distribute.rb +25 -14
- data/lib/tes/request/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 30fe936e59566c32df4a77198ead6bda9409c4186a2d806958e36e0ae8f52b64
|
4
|
+
data.tar.gz: 8e54ca43d1549510541f2222ef64128bfabe3f7d462892d86c1e2cb4837ad999
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2dd71729d9b743a767d7081161bad2bff5174dabe8bfc6ce72a5faa373b71336fd3247f0de6ee386a029e5c75484cd088c82690d4dc063a93b1ff6851dcd316a
|
7
|
+
data.tar.gz: 28c3aa96ce12781a0746e4732a0995c7f6c8a00a4a93927ac27463d28592d1b1578e890572ac911ff0bf7f50867f9898a741ed4487fadf4eaa9be0cbcf12ff03
|
data/.travis.yml
CHANGED
data/bin/tes-ci-pool
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'tes/request/rspec/ci_pool'
|
4
|
+
|
5
|
+
usage = <<EOF
|
6
|
+
Usage:
|
7
|
+
#{$0} {tes_pool_url} #{Tes::Request::RSpec::CiPool::SUPPORT_FUNCTIONS.join('|')} {project_dir} {job_type} [res_addition_attr_map_json_file_path]
|
8
|
+
|
9
|
+
Example:
|
10
|
+
#{$0} http://tes.com/func/ satisfy apps/test_project func_test apps/test_project/res_attr_add_map.json
|
11
|
+
EOF
|
12
|
+
|
13
|
+
if ARGV.size < 4
|
14
|
+
warn usage
|
15
|
+
exit 2
|
16
|
+
end
|
17
|
+
|
18
|
+
tes_pool_url = ARGV.shift
|
19
|
+
pool_func = ARGV.shift.to_sym
|
20
|
+
project_dir = ARGV.shift
|
21
|
+
ci_job_type = ARGV.shift
|
22
|
+
res_addition_attr_map_json_file = ARGV.shift
|
23
|
+
Tes::Request::RSpec::CiPool.
|
24
|
+
new(tes_pool_url, pool_func).
|
25
|
+
run(project_dir, ci_job_type, res_addition_attr_map_json_file)
|
26
|
+
|
27
|
+
|
28
|
+
|
data/bin/tes-ci-slicer
CHANGED
@@ -3,11 +3,12 @@
|
|
3
3
|
require 'tes/request/rspec/ci_slicer'
|
4
4
|
|
5
5
|
usage = <<EOF
|
6
|
-
Usage: % #{$0} {#{Tes::Request::RSpec::CiSlicer::SUPPORT_FILE_TYPES.join('|')}} {project_dir} {job_type} {job_min_pieces} [res_addition_attr_map_json_file_path]
|
6
|
+
Usage: % #{$0} {#{Tes::Request::RSpec::CiSlicer::SUPPORT_FILE_TYPES.join('|')}} {project_dir} {job_type} {job_min_pieces} [res_addition_attr_map_json_file_path] [pool_url_to_adapt]
|
7
7
|
|
8
8
|
Example:
|
9
9
|
#{$0} json apps/test_project ci_merge_test 4
|
10
10
|
#{$0} properties apps/test_project func_test 16 apps/test_project/res_attr_add_map.json
|
11
|
+
#{$0} properties apps/test_project func_test 16 apps/test_project/res_attr_add_map.json http://tes.server.com/func_test/
|
11
12
|
EOF
|
12
13
|
|
13
14
|
if ARGV.size < 4
|
@@ -20,7 +21,8 @@ project_dir = ARGV.shift
|
|
20
21
|
ci_job_type = ARGV.shift
|
21
22
|
job_piece_count = ARGV.shift
|
22
23
|
res_addition_attr_map_json_file = ARGV.shift
|
24
|
+
pool_url = ARGV.shift
|
23
25
|
Tes::Request::RSpec::CiSlicer.
|
24
|
-
new(cfg_type, project_dir, res_addition_attr_map_json_file).
|
26
|
+
new(cfg_type, project_dir, res_addition_attr_map_json_file, pool_url).
|
25
27
|
run(ci_job_type, job_piece_count.to_i)
|
26
28
|
|
data/lib/hash.rb
CHANGED
@@ -17,8 +17,8 @@ class Hash
|
|
17
17
|
# @param [String] chain_str 嵌套取值表达式
|
18
18
|
# @return [Object]
|
19
19
|
def get_by_chain(chain_str)
|
20
|
-
chains = chain_str.split('.')
|
21
|
-
chains.keep_if {
|
22
|
-
chains.inject(self) {
|
20
|
+
chains = chain_str.split('.').map(&:to_sym)
|
21
|
+
chains.keep_if {|k| k =~ /.+/}
|
22
|
+
chains.inject(self) {|t, p| t && t.send(p)}
|
23
23
|
end
|
24
24
|
end
|
data/lib/tes/request/client.rb
CHANGED
@@ -53,12 +53,15 @@ module Tes
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def release_all_res(user)
|
56
|
-
|
57
|
-
res_list[:data].select {|_k, c| c[:users] && c[:users].include?(user)}.each do |id, _c|
|
56
|
+
get_all_res.select {|_k, c| c[:users] && c[:users].include?(user)}.each do |id, _c|
|
58
57
|
release_res(id, user)
|
59
58
|
end
|
60
59
|
end
|
61
60
|
|
61
|
+
def get_all_res
|
62
|
+
parse_res(@driver.get('res'))[:data]
|
63
|
+
end
|
64
|
+
|
62
65
|
private
|
63
66
|
def parse_res(res)
|
64
67
|
unless res.ok? or res.redirect?
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'fileutils'
|
3
|
+
require_relative 'distribute'
|
4
|
+
require_relative '../client'
|
5
|
+
|
6
|
+
module Tes::Request::RSpec
|
7
|
+
class CiPool
|
8
|
+
SUPPORT_FUNCTIONS = %i[satisfy]
|
9
|
+
|
10
|
+
def initialize(tes_pool_url, pool_func) #
|
11
|
+
@pool_url = tes_pool_url
|
12
|
+
@pool_func = pool_func
|
13
|
+
driver = HTTPClient.new(base_url: tes_pool_url)
|
14
|
+
driver.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
15
|
+
client = ::Tes::Request::Client.new(driver)
|
16
|
+
@pool = client.get_all_res
|
17
|
+
end
|
18
|
+
|
19
|
+
def run(*args)
|
20
|
+
send(@pool_func, *args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def satisfy(project_dir, ci_type, res_replace_map_json_file=nil)
|
24
|
+
res_addition_attr_map = (res_replace_map_json_file && JSON.parse(File.read(res_replace_map_json_file)))
|
25
|
+
rspec_distribute = Distribute.new(project_dir)
|
26
|
+
jobs = rspec_distribute.distribute_jobs(ci_type, 1, res_addition_attr_map)
|
27
|
+
not_satisfied_profiles = jobs.inject([]) do |t, job|
|
28
|
+
t << job[:profile] unless job[:profile].request(@pool).all?
|
29
|
+
t
|
30
|
+
end
|
31
|
+
unless not_satisfied_profiles.empty?
|
32
|
+
warn <<EOF
|
33
|
+
!!!No matched resources in pool for profiles ==>
|
34
|
+
|
35
|
+
#{not_satisfied_profiles.join("\n------------------\n")}
|
36
|
+
~~~~~~~~~~~~~~~~~~~~~~~!!!
|
37
|
+
EOF
|
38
|
+
raise('No matched resources in pool')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -2,12 +2,13 @@ require 'yaml'
|
|
2
2
|
require 'java-properties'
|
3
3
|
require 'fileutils'
|
4
4
|
require_relative 'distribute'
|
5
|
+
require_relative '../client'
|
5
6
|
|
6
7
|
module Tes::Request::RSpec
|
7
8
|
class CiSlicer
|
8
9
|
SUPPORT_FILE_TYPES = [:yaml, :yml, :json, :properties]
|
9
10
|
|
10
|
-
def initialize(file_type, project_dir, res_replace_map_json_file=nil)
|
11
|
+
def initialize(file_type, project_dir, res_replace_map_json_file=nil, pool_url=nil)
|
11
12
|
unless SUPPORT_FILE_TYPES.include?(file_type.to_sym)
|
12
13
|
raise(ArgumentError, "Not supported file type:#{file_type}!")
|
13
14
|
end
|
@@ -16,12 +17,21 @@ module Tes::Request::RSpec
|
|
16
17
|
@project_dir = project_dir
|
17
18
|
@res_addition_attr_map = (res_replace_map_json_file && JSON.parse(File.read(res_replace_map_json_file)))
|
18
19
|
@cfg_target_dir = File.join(@project_dir, '.ci_jobs')
|
20
|
+
@pool_url = pool_url
|
19
21
|
end
|
20
22
|
|
21
23
|
def run(ci_type, slice_count)
|
22
24
|
puts "Generate RSpec distribute jobs #{@cfg_file_type} file for CI"
|
23
25
|
rspec_distribute = Distribute.new(@project_dir)
|
24
|
-
|
26
|
+
pool = if @pool_url
|
27
|
+
driver = HTTPClient.new(base_url: @pool_url)
|
28
|
+
driver.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
29
|
+
client = ::Tes::Request::Client.new(driver)
|
30
|
+
@pool = client.get_all_res
|
31
|
+
else
|
32
|
+
{}
|
33
|
+
end
|
34
|
+
jobs = rspec_distribute.distribute_jobs(ci_type, slice_count, @res_addition_attr_map, pool)
|
25
35
|
save_job_files(jobs, @cfg_target_dir, @cfg_file_type)
|
26
36
|
@cfg_target_dir
|
27
37
|
end
|
@@ -29,7 +39,7 @@ module Tes::Request::RSpec
|
|
29
39
|
def spec_tag_param_str(tags)
|
30
40
|
case tags
|
31
41
|
when Array
|
32
|
-
tags.map {
|
42
|
+
tags.map {|t| "--tag #{t}"}.join(' ')
|
33
43
|
when String
|
34
44
|
"--tag #{tags}"
|
35
45
|
when nil
|
@@ -44,17 +54,17 @@ module Tes::Request::RSpec
|
|
44
54
|
raise(ArgumentError, "Not supported file type:#{file_type}!")
|
45
55
|
end
|
46
56
|
|
47
|
-
job_configs_for_ci = jobs.map {
|
57
|
+
job_configs_for_ci = jobs.map {|j| gen_job_ci_params(j)}
|
48
58
|
FileUtils.rm_rf(target_dir)
|
49
59
|
FileUtils.mkdir(target_dir)
|
50
60
|
case file_type
|
51
61
|
when :json
|
52
62
|
save_file = File.join(target_dir, 'ci_tasks.json')
|
53
|
-
File.open(save_file, 'w') {
|
63
|
+
File.open(save_file, 'w') {|f| f.write job_configs_for_ci.to_json}
|
54
64
|
puts "Generated #{jobs.size} jobs, Stored in:#{save_file} ."
|
55
65
|
when :yml, :yaml
|
56
66
|
save_file = File.join(target_dir, 'ci_tasks.yml')
|
57
|
-
File.open(save_file, 'w') {
|
67
|
+
File.open(save_file, 'w') {|f| f.write job_configs_for_ci.to_yaml}
|
58
68
|
puts "Generated #{jobs.size} jobs, Stored in:#{save_file} ."
|
59
69
|
when :properties
|
60
70
|
job_configs_for_ci.each_with_index do |params, i|
|
@@ -75,6 +85,7 @@ module Tes::Request::RSpec
|
|
75
85
|
job[:profile].to_s(split)
|
76
86
|
end
|
77
87
|
|
88
|
+
private
|
78
89
|
def gen_job_ci_params(job)
|
79
90
|
{'RSPEC_PARAM' => get_job_rspec_run_args_str(job), 'REQUEST_ASKS' => get_job_env_profile_str(job)}
|
80
91
|
end
|
@@ -24,18 +24,22 @@ module Tes
|
|
24
24
|
attr_reader :project_dir, :ci_cfg
|
25
25
|
|
26
26
|
# 生成分发任务的配置结构
|
27
|
+
# @param [String] type task type
|
28
|
+
# @param [Integer] count 分批任务数
|
29
|
+
# @param [Hash] res_addition_attr_map 资源属性需要调整的映射表
|
30
|
+
# @param [Hash,nil] adapt_pool
|
27
31
|
# @return [Array<Hash>]
|
28
|
-
def distribute_jobs(type, count, res_addition_attr_map=
|
32
|
+
def distribute_jobs(type, count, res_addition_attr_map={}, adapt_pool = {})
|
29
33
|
task_cfg = get_rspec_task(type)
|
30
34
|
spec_paths = spec_files(type)
|
31
35
|
rspec_parser = Tes::Request::RSpec::ProfileParser.new(spec_paths)
|
32
36
|
rspec_parser.parse_profiles!
|
37
|
+
rspec_profiles = rspec_parser.profiles
|
33
38
|
|
34
|
-
|
35
|
-
|
36
|
-
if res_addition_attr_map and res_addition_attr_map.size > 0
|
39
|
+
if res_addition_attr_map and res_addition_attr_map.size > 0
|
40
|
+
rspec_profiles.each do |spec|
|
37
41
|
res_addition_attr_map.each do |res_filter_pattern, attr_add_map|
|
38
|
-
request_asks = profile.data.select {
|
42
|
+
request_asks = spec[:profile].data.select {|ask| ask.to_s.include? res_filter_pattern}
|
39
43
|
request_asks.each do |ask|
|
40
44
|
# only add the resource attribution when no request the attribution for the resource
|
41
45
|
attr_add_map.each do |attr_name, attr_limit|
|
@@ -46,7 +50,19 @@ module Tes
|
|
46
50
|
end
|
47
51
|
end
|
48
52
|
end
|
53
|
+
end
|
49
54
|
|
55
|
+
|
56
|
+
if adapt_pool and adapt_pool.size > 0
|
57
|
+
rspec_profiles.delete_if do |spec|
|
58
|
+
pool_not_satisfied = !(spec[:profile].request(adapt_pool).all?)
|
59
|
+
warn "POOL is not satisfied for: #{spec[:file]}" if pool_not_satisfied
|
60
|
+
pool_not_satisfied
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
gen_pieces(rspec_profiles, count).map do |piece|
|
65
|
+
profile = piece[:profile]
|
50
66
|
specs = piece[:specs].inject([]) do |t, spec|
|
51
67
|
file_path = spec[:file].sub(/^#{@project_dir}/, '').sub(/^\//, '')
|
52
68
|
if (spec[:locations] and spec[:locations].size > 0) or (spec[:ids] and spec[:ids].size > 0)
|
@@ -63,7 +79,7 @@ module Tes
|
|
63
79
|
end
|
64
80
|
|
65
81
|
{profile: profile, specs: specs}
|
66
|
-
end.map {
|
82
|
+
end.map {|p| p.merge(tag: task_cfg['tag'])}
|
67
83
|
end
|
68
84
|
|
69
85
|
private
|
@@ -89,7 +105,6 @@ module Tes
|
|
89
105
|
piece[:profile] == to_merge_spec[:profile]
|
90
106
|
end
|
91
107
|
if join_piece
|
92
|
-
# puts 'http://join'
|
93
108
|
join_piece[:specs] << to_merge_spec
|
94
109
|
else
|
95
110
|
# 2. 然后再是资源多少不同的归并
|
@@ -102,7 +117,6 @@ module Tes
|
|
102
117
|
end
|
103
118
|
end
|
104
119
|
if super_piece
|
105
|
-
# puts 'http://inherit'
|
106
120
|
super_piece[:specs] << to_merge_spec
|
107
121
|
else
|
108
122
|
# 3. 可整合计算的的归并,但要求已经达到的任务分片数已经达到了要求那么大,否则直接以新建来搞
|
@@ -112,13 +126,10 @@ module Tes
|
|
112
126
|
piece[:profile].merge_able?(to_merge_spec[:profile])
|
113
127
|
end
|
114
128
|
if merge_piece
|
115
|
-
# puts 'http://merge'
|
116
129
|
merge_piece[:profile] = merge_piece[:profile] + to_merge_spec[:profile]
|
117
|
-
# puts merge_piece[:profile]
|
118
130
|
merge_piece[:specs] << to_merge_spec
|
119
131
|
else
|
120
132
|
# 4. 最后再尝试独立出一个新的piece,在剩余数量达到一半要求的时候
|
121
|
-
# puts 'http://new'
|
122
133
|
common_jobs << {profile: to_merge_spec[:profile], specs: [to_merge_spec]}
|
123
134
|
end
|
124
135
|
else
|
@@ -165,7 +176,7 @@ module Tes
|
|
165
176
|
pattern_filter_lab.call(pattern)
|
166
177
|
Dir[File.join(@project_dir, pattern)]
|
167
178
|
when Array
|
168
|
-
pattern.inject([]) {
|
179
|
+
pattern.inject([]) {|t, ep| t + pattern_filter_lab.call(ep)}
|
169
180
|
else
|
170
181
|
raise('Error pattern type')
|
171
182
|
end
|
@@ -176,7 +187,7 @@ module Tes
|
|
176
187
|
when String
|
177
188
|
ret -= Dir[File.join(@project_dir, exclude_pattern)]
|
178
189
|
when Array
|
179
|
-
ret -= exclude_pattern.inject([]) {
|
190
|
+
ret -= exclude_pattern.inject([]) {|t, ep| t + Dir[File.join(@project_dir, ep)]}
|
180
191
|
else
|
181
192
|
raise('Error exclude_pattern type')
|
182
193
|
end
|
@@ -206,7 +217,7 @@ module Tes
|
|
206
217
|
exclude_pattern
|
207
218
|
end
|
208
219
|
res_attrs = res_attrs.split(',')
|
209
|
-
profile_lines.any? {
|
220
|
+
profile_lines.any? {|line| res_attrs.all? {|attr| line =~ /\b#{attr}\b/}}
|
210
221
|
end
|
211
222
|
end
|
212
223
|
end
|
data/lib/tes/request/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tes-request
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.9'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- wuhuizuo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: java-properties
|
@@ -84,6 +84,7 @@ description: Provide Tes-Client, Tes-Provider to use public Logic and data struc
|
|
84
84
|
email:
|
85
85
|
- wuhuizuo@126.com
|
86
86
|
executables:
|
87
|
+
- tes-ci-pool
|
87
88
|
- tes-ci-slicer
|
88
89
|
- tes-client
|
89
90
|
extensions: []
|
@@ -97,6 +98,7 @@ files:
|
|
97
98
|
- LICENSE.txt
|
98
99
|
- README.md
|
99
100
|
- Rakefile
|
101
|
+
- bin/tes-ci-pool
|
100
102
|
- bin/tes-ci-slicer
|
101
103
|
- bin/tes-client
|
102
104
|
- lib/hash.rb
|
@@ -105,6 +107,7 @@ files:
|
|
105
107
|
- lib/tes/request/client.rb
|
106
108
|
- lib/tes/request/expression.rb
|
107
109
|
- lib/tes/request/profile.rb
|
110
|
+
- lib/tes/request/rspec/ci_pool.rb
|
108
111
|
- lib/tes/request/rspec/ci_slicer.rb
|
109
112
|
- lib/tes/request/rspec/distribute.rb
|
110
113
|
- lib/tes/request/rspec/function.rb
|
@@ -132,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
135
|
version: '0'
|
133
136
|
requirements: []
|
134
137
|
rubyforge_project:
|
135
|
-
rubygems_version: 2.
|
138
|
+
rubygems_version: 2.7.4
|
136
139
|
signing_key:
|
137
140
|
specification_version: 4
|
138
141
|
summary: Request libs and bins for TES(Test Env Service)
|