super-test 1.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.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGE.txt +9 -0
  3. data/README.txt +13 -0
  4. data/bin/idb +19 -0
  5. data/bin/ii +113 -0
  6. data/bin/istart_mock +36 -0
  7. data/bin/istop_mock +16 -0
  8. data/bin/kk +181 -0
  9. data/bin/rubyatp +42 -0
  10. data/bin/start_mock +36 -0
  11. data/bin/stop_mock +16 -0
  12. data/bin/xgo +45 -0
  13. data/conf/conf.rb +11 -0
  14. data/conf/db03.yml +31 -0
  15. data/conf/db13.yml +37 -0
  16. data/conf/db19.yml +33 -0
  17. data/conf/online.yml +32 -0
  18. data/conf/super_test.yml +40 -0
  19. data/conf/system.yml +26 -0
  20. data/conf/sz00.yml +31 -0
  21. data/conf/sz06.yml +34 -0
  22. data/conf/wise00.yml +11 -0
  23. data/data/case.house +0 -0
  24. data/data/char.house +0 -0
  25. data/data/images/Bluehills.jpg +0 -0
  26. data/data/images/Sunset.jpg +0 -0
  27. data/data/images/Waterlilies.jpg +0 -0
  28. data/data/images/Winter.jpg +0 -0
  29. data/data/query.house +18595 -0
  30. data/data/user.house +8 -0
  31. data/lib/action/module/check_action.rb +58 -0
  32. data/lib/action/module/cnnt_action.rb +161 -0
  33. data/lib/action/module/datacenter_action.rb +48 -0
  34. data/lib/action/module/http_pack_helper.rb +163 -0
  35. data/lib/action/module/httpserver_action.rb +297 -0
  36. data/lib/action/module/inc.rb +21 -0
  37. data/lib/action/module/mcpack_action.rb +57 -0
  38. data/lib/action/module/sql_action.rb +84 -0
  39. data/lib/action/module/ssh_action.rb +37 -0
  40. data/lib/action/system/user_action.rb +180 -0
  41. data/lib/common/appium_helper.rb +217 -0
  42. data/lib/common/atp_helper.rb +74 -0
  43. data/lib/common/atp_report.rb +344 -0
  44. data/lib/common/data_house.rb +405 -0
  45. data/lib/common/data_model.rb +87 -0
  46. data/lib/common/http/assert_helper.rb +343 -0
  47. data/lib/common/http/fix_hpricot.rb +118 -0
  48. data/lib/common/http/html_helper.rb +362 -0
  49. data/lib/common/http/http_helper.rb +469 -0
  50. data/lib/common/http/multipart.rb +81 -0
  51. data/lib/common/isandbox_helper.rb +195 -0
  52. data/lib/common/json_helper.rb +43 -0
  53. data/lib/common/mock_helper.rb +168 -0
  54. data/lib/common/mtop_helper.rb +141 -0
  55. data/lib/common/myconf_helper.rb +49 -0
  56. data/lib/common/mylog_helper.rb +77 -0
  57. data/lib/common/pairwise.rb +121 -0
  58. data/lib/common/query_house.rb +89 -0
  59. data/lib/common/report_helper.rb +97 -0
  60. data/lib/common/robot_helper.rb +85 -0
  61. data/lib/common/socket/check.rb +325 -0
  62. data/lib/common/socket/conf_modifier.rb +149 -0
  63. data/lib/common/socket/context.rb +55 -0
  64. data/lib/common/socket/data.rb +392 -0
  65. data/lib/common/socket/data_helper.rb +41 -0
  66. data/lib/common/socket/env.rb +317 -0
  67. data/lib/common/socket/inc.rb +24 -0
  68. data/lib/common/socket/log.rb +213 -0
  69. data/lib/common/socket/log4s.rb +58 -0
  70. data/lib/common/socket/log_helper.rb +332 -0
  71. data/lib/common/socket/my_sql.rb +77 -0
  72. data/lib/common/socket/net.rb +74 -0
  73. data/lib/common/socket/network.rb +115 -0
  74. data/lib/common/socket/rlib/conf_modifier.rb +130 -0
  75. data/lib/common/socket/rlib/data_helper.rb +33 -0
  76. data/lib/common/socket/rlib/log_helper.rb +303 -0
  77. data/lib/common/socket/rlib/process_helper.rb +91 -0
  78. data/lib/common/socket/stub.rb +276 -0
  79. data/lib/common/socket/util.rb +266 -0
  80. data/lib/patterns/inc.rb +10 -0
  81. data/lib/patterns/mc_base_pattern.rb +474 -0
  82. data/lib/patterns/some_pattern.rb +145 -0
  83. data/lib/super_test.rb +114 -0
  84. data/log/super_test.log +0 -0
  85. data/log/super_test.log.wf +0 -0
  86. data/test/cover_me.rb +6 -0
  87. data/tool/jenny +0 -0
  88. data/tool/mcsend/mcsend2 +0 -0
  89. data/tool/mcsend/mcsend2_shead +0 -0
  90. data/tool/mcserver/conf/mcserver.conf +77 -0
  91. data/tool/mcserver/conf/mcserverauthip +17 -0
  92. data/tool/mcserver/mcserver +0 -0
  93. data/tool/mcserver/mcserver_trans +0 -0
  94. data/tool/mysql +0 -0
  95. data/tool/net/mcsend/mcsend +0 -0
  96. data/tool/net/mcsend/mcsend_trans +0 -0
  97. data/tool/net/mcsend/nshead.data +7 -0
  98. data/tool/net/mcsend/res_nshead.data +7 -0
  99. data/tool/net/my_client/my_client +0 -0
  100. data/tool/net/tsclient/client.tcl +205 -0
  101. data/tool/others/kk +190 -0
  102. data/tool/others/rubyatp +42 -0
  103. data/tool/others/supertest_install.sh +34 -0
  104. data/tool/trip/idb +0 -0
  105. data/tool/ts-agent/nshead.bft +12 -0
  106. data/tool/ts-agent/server.conf +10 -0
  107. data/tool/ts-agent/server.tcl +376 -0
  108. metadata +275 -0
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+ #####################################
4
+ # File:: atp.rb
5
+ # Author:: hanyu
6
+ # Create Date:: Mon Aug 3 23:06:14 CST 2009
7
+ # Update Date:: Mon Aug 3 23:06:14 CST 2009
8
+ #####################################
9
+
10
+ require "test/unit/testcase"
11
+ require "test/unit/testresult"
12
+ require "common/atp_report"
13
+
14
+ # 采用动态改变类行为的方式来实现透明插入 atp报表 的功能
15
+ # 缺点是污染了原始对象 :(
16
+ module Test
17
+ module Unit
18
+ # 一个 TestCase 对应一个 文本case,
19
+ # 所以改写了 startup 和 shutdown 两个方法
20
+ #class TestCase
21
+ # def self.startup
22
+ # #return unless ENV.key? 'AT_LOGFILE'
23
+
24
+ # #if File.exist? ENV['AT_LOGFILE'] and File.new(ENV['AT_LOGFILE']).lines.to_a.size > 6
25
+ # # Report.re_open
26
+ # #else
27
+ # # Report.open
28
+ # # Report.suiteBegin
29
+ # #end
30
+ # #Report.caseBegin self.to_s
31
+ # ## pass or not
32
+ # #ENV['PASS_OR_NOT'] = "pass"
33
+ #
34
+ # end
35
+ # def self.shutdown
36
+ # #return unless ENV.key? 'AT_LOGFILE'
37
+
38
+ # ## 如果一切顺利,也要打印一个step ? ...yes
39
+ # #if ENV['PASS_OR_NOT'] == "pass"
40
+ # # Report.stepBegin self.to_s
41
+ # # Report.expect "all",0
42
+ # # Report.actual "all",0
43
+ # # Report.stepEnd
44
+ # #end
45
+ # #Report.caseEnd
46
+ # #Report.suiteEnd
47
+ # #Report.close
48
+ # end
49
+ #end
50
+
51
+ class TestResult
52
+ def summary
53
+ ["#{run_count} tests",
54
+ "#{assertion_count} assertions",
55
+ *@summary_generators.collect{|generator| send(generator)} ].join(", ") + ", hi atp!"
56
+ end
57
+ def notify_fault(fault)
58
+ @faults << fault
59
+ notify_listeners(FAULT, fault)
60
+
61
+ return unless ENV.key? 'AT_LOGFILE'
62
+ Report.stepBegin fault.test_name
63
+ Report.expect "逻辑错误",0
64
+ Report.actual "逻辑错误",1
65
+ Report.more fault.short_display,fault.long_display
66
+ Report.stepEnd
67
+ # pass or not
68
+ #ENV['PASS_OR_NOT'] = "not"
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+
@@ -0,0 +1,344 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+ #
4
+ # author: atd
5
+
6
+
7
+ class Report
8
+ require 'cgi'
9
+ require 'base64'
10
+ require 'pathname'
11
+ require 'fileutils'
12
+
13
+ $logfile_is_existed = 0
14
+ $at_in_report = 0
15
+ $at_in_suite = 0
16
+ $at_in_case = 0
17
+ $at_in_step = 0
18
+
19
+ # 打开报告
20
+ def self.open(owner=nil,title="No Title",filename="report.xml",encoding="gb2312")
21
+ #若尚未打开报告
22
+ if ENV['AT_IN_REPORT']!="1"
23
+ $logfile_is_existed = 1
24
+ if ENV['AT_LOGFILE'] == nil
25
+ path = Pathname.new(filename)
26
+ filename = "#{Dir.pwd}/#{filename}" if path.relative?
27
+ FileUtils.mkpath(File.dirname(filename))
28
+ ENV['AT_LOGFILE'] = filename
29
+ $logfile_is_existed = 0
30
+ end
31
+ # 设置环境变量
32
+ ENV['AT_IN_SUITE'] = nil
33
+ ENV['AT_IN_CASE'] = nil
34
+ ENV['AT_IN_STEP'] = nil
35
+ ENV['AT_IN_REPORT']="1"
36
+
37
+ if owner.nil?
38
+ if ENV['OS'] =~ /windows/i
39
+ owner = "#{ENV['USERNAME']}@#{ENV['COMPUTERNAME']}"
40
+ else
41
+ owner = "#{ENV['USER']}@#{ENV['HOSTNAME']}"
42
+ end
43
+ end
44
+
45
+ File.open(ENV['AT_LOGFILE'],'w') do |f|
46
+ f.write <<-endblock
47
+ <?xml version="1.0" encoding="#{encoding}"?>
48
+ <report>
49
+ <schemaversion>2.0.0</schemaversion>
50
+ <owner>#{owner}</owner>
51
+ <title>#{CGI::escapeHTML(title)}</title>
52
+ <s>#{Time.now.to_i}</s>
53
+ endblock
54
+ end
55
+ #若已经打开报告
56
+ else
57
+ $at_in_report = 1
58
+ $at_in_suite = ENV['AT_IN_SUITE'].to_i if ENV['AT_IN_SUITE'] != nil
59
+ $at_in_case = ENV['AT_IN_CASE'].to_i if ENV['AT_IN_CASE'] != nil
60
+ $at_in_step = ENV['AT_IN_STEP'].to_i if ENV['AT_IN_STEP'] != nil
61
+ end
62
+ end
63
+
64
+ # 关闭报告
65
+ def self.close
66
+ # 恢复成打开报告前的状态
67
+ suite_level = 0
68
+ case_level = 0
69
+ step_level = 0
70
+
71
+ step_level = ENV['AT_IN_STEP'].to_i if ENV['AT_IN_STEP'] != nil
72
+ if $at_in_step < step_level
73
+ self.stepEnd
74
+ elsif $at_in_step > step_level
75
+ self.stepBegin
76
+ end
77
+
78
+ case_level = ENV['AT_IN_CASE'].to_i if ENV['AT_IN_CASE'] != nil
79
+ if $at_in_case < case_level
80
+ self.caseEnd
81
+ elsif $at_in_case > case_level
82
+ self.caseBegin
83
+ end
84
+
85
+ suite_level = ENV['AT_IN_SUITE'].to_i if ENV['AT_IN_SUITE'] != nil
86
+ while $at_in_suite < suite_level
87
+ self.suiteEnd
88
+ suite_level -= 1
89
+ end
90
+ while $at_in_suite > suite_level
91
+ self.suiteBegin
92
+ suite_level += 1
93
+ end
94
+
95
+ #若尚未关闭报告
96
+ if ENV['AT_IN_REPORT']=="1" and $at_in_report == 0
97
+ _append("<f>#{Time.now.to_i}</f>\n</report>\n")
98
+ ENV['AT_IN_REPORT'] = nil
99
+ ENV['AT_LOGFILE'] = nil if $logfile_is_existed == 0
100
+ end
101
+ end
102
+
103
+ # add by hanyu
104
+ def self.re_open
105
+ #去除末尾4行
106
+ lines = nil
107
+ File.open ENV['AT_LOGFILE'],"r" do |file|
108
+ lines = file.readlines
109
+ lines = lines[0,lines.size-2]
110
+ end
111
+
112
+ File.open ENV['AT_LOGFILE'],"w" do |file|
113
+ file.puts lines
114
+ end
115
+
116
+ ENV['AT_IN_REPORT'] = "1"
117
+ ENV['AT_IN_SUITE'] = "1"
118
+ end
119
+
120
+ # 进入Suite
121
+ def self.suiteBegin(title="No Title")
122
+ if ENV['AT_IN_REPORT']== nil
123
+ self.open()
124
+ end
125
+ if ENV['AT_IN_CASE']=="1"
126
+ self.caseEnd
127
+ end
128
+ title = "No Title" if title.length == 0
129
+
130
+ if title.include? "/"
131
+ if ! title.include? ":"
132
+ print "absolute suite syntax error: #{title}\n"
133
+ return 1
134
+ end
135
+ end
136
+
137
+ title = CGI::escapeHTML(title)
138
+ _append("<suite title=\"#{title}\">\n<s>#{Time.now.to_i}</s>\n")
139
+ t=ENV['AT_IN_SUITE'].to_i
140
+ t+=1
141
+ ENV['AT_IN_SUITE']=t.to_s
142
+ end
143
+
144
+ # 结束Suite
145
+ def self.suiteEnd
146
+ t = ENV['AT_IN_SUITE'].to_i
147
+ if t > 0
148
+ if ENV['AT_IN_CASE']=="1"
149
+ self.caseEnd
150
+ end
151
+ _append("<f>#{Time.now.to_i}</f>\n</suite>\n")
152
+ if t > 1
153
+ ENV['AT_IN_SUITE'] = (t - 1).to_s
154
+ else
155
+ ENV['AT_IN_SUITE'] = nil
156
+ end
157
+ end
158
+ end
159
+
160
+ # 进入Case
161
+ def self.caseBegin(title="No Title", id="")
162
+ if ENV['AT_IN_CASE']=="1"
163
+ self.caseEnd
164
+ end
165
+
166
+ if ENV['AT_IN_SUITE']==nil
167
+ if self.suiteBegin(title) == 1
168
+ return 1
169
+ end
170
+ end
171
+
172
+ title = "No Title" if title.length == 0
173
+ title = CGI::escapeHTML(title)
174
+ if id.length > 0
175
+ _append("<case title=\"#{title}\" id=\"#{id}\">\n<s>#{Time.now.to_i}</s>\n")
176
+ else
177
+ _append("<case title=\"#{title}\">\n<s>#{Time.now.to_i}</s>\n")
178
+ end
179
+ ENV['AT_IN_CASE']="1"
180
+ end
181
+
182
+ # 结束Case
183
+ def self.caseEnd
184
+ if ENV['AT_IN_CASE']=="1"
185
+ if ENV['AT_IN_STEP']=="1"
186
+ self.stepEnd
187
+ end
188
+
189
+ _append("<f>#{Time.now.to_i}</f>\n</case>\n")
190
+ ENV['AT_IN_CASE']= nil
191
+ end
192
+ end
193
+
194
+ # 进入Step
195
+ def self.stepBegin(title="No Title")
196
+ if ENV['AT_IN_STEP']=="1"
197
+ self.stepEnd
198
+ end
199
+
200
+ if ENV['AT_IN_CASE']==nil
201
+ if self.caseBegin(title) == 1
202
+ return 1
203
+ end
204
+ end
205
+
206
+ title = "No Title" if title.length == 0
207
+ title = CGI::escapeHTML(title)
208
+ _append("<step title=\"#{title}\">\n<s>#{Time.now.to_i}</s>\n")
209
+ ENV['AT_IN_STEP']="1"
210
+ end
211
+
212
+ # 结束Step
213
+ def self.stepEnd
214
+ if ENV['AT_IN_STEP']=="1"
215
+ _append("<f>#{Time.now.to_i}</f>\n</step>\n")
216
+ ENV['AT_IN_STEP']=nil
217
+ end
218
+ end
219
+
220
+ # 指定预期输出
221
+ def self.expect(title,value,filetype=nil)
222
+ if ENV['AT_IN_STEP']!="1"
223
+ self.stepBegin()
224
+ end
225
+ value = value.to_s
226
+ #Tclerk.trace "Report Expect [#{title}], value=[#{value}] and filetype is [#{filetype}]"
227
+ title = "No Title" if title.length == 0
228
+ title = CGI::escapeHTML(title)
229
+ if filetype.nil?
230
+ _append("<e title=\"#{title}\" type=\"text/plain\">\n#{Base64.encode64(value)}</e>\n")
231
+ else
232
+ # 测试文件存在与否
233
+ if File.file? value
234
+ content = IO.read(value)
235
+ _append("<e title=\"#{title}\" type=\"#{filetype}\">\n#{Base64.encode64(content)}</e>\n")
236
+ else
237
+ print "Error: Expect file not exists!\n"
238
+ end
239
+ end
240
+ end
241
+
242
+ # 指定实际输出
243
+ def self.actual(title,value,filetype=nil)
244
+ if ENV['AT_IN_STEP']!="1"
245
+ self.stepBegin()
246
+ end
247
+ value = value.to_s
248
+ #Tclerk.trace "Report Actual [#{title}], value=[#{value}] and filetype is [#{filetype}]"
249
+ title = "No Title" if title.length == 0
250
+ title = CGI::escapeHTML(title)
251
+ if filetype.nil?
252
+ _append("<a title=\"#{title}\" type=\"text/plain\">\n#{Base64.encode64(value)}</a>\n")
253
+ else
254
+ # 测试文件存在与否
255
+ if File.file? value
256
+ content = IO.read(value)
257
+ _append("<a title=\"#{title}\" type=\"#{filetype}\">\n#{Base64.encode64(content)}</a>\n")
258
+ else
259
+ print "Error: Actual file not exists!\n"
260
+ end
261
+ end
262
+ end
263
+ def self.assertTrue(title,cond)
264
+ stepBegin(title)
265
+ expect(title,true.to_s)
266
+ actual(title,cond.to_s)
267
+ stepEnd
268
+ end
269
+
270
+ # 判断返回值
271
+ def self.assertReturn(title,erc=0,act=nil)
272
+ act ||= $?.to_s
273
+ act = act.to_s
274
+ erc = erc.to_s
275
+ stepBegin(title)
276
+ expect("返回值",erc)
277
+ actual("返回值",act)
278
+ stepEnd
279
+ end
280
+
281
+ # 其他附件信息
282
+ def self.more(title,value,filetype=nil)
283
+ if ENV['AT_IN_REPORT']== nil
284
+ self.open()
285
+ end
286
+ value = value.to_s
287
+ #Tclerk.trace "{report} More [#{title}], value=[#{value}] and filetype is [#{filetype}]"
288
+ title = "No Title" if title.length == 0
289
+ title = CGI::escapeHTML(title)
290
+ if filetype.nil?
291
+ _append("<more title=\"#{title}\" type=\"text/plain\">\n#{Base64.encode64(value)}</more>\n")
292
+ else
293
+ # 测试文件存在与否
294
+ if File.file? value
295
+ content = IO.read(value)
296
+ _append("<more title=\"#{title}\" type=\"#{filetype}\">\n#{Base64.encode64(content)}</more>\n")
297
+ else
298
+ print "Error: More file not exists!\n"
299
+ end
300
+ end
301
+ end
302
+
303
+ # 为了兼容,定义一堆别名
304
+ def suite_begin(title="No Title")
305
+ Report.suiteEnd(title)
306
+ end
307
+ def suite_end
308
+ Report.suiteEnd
309
+ end
310
+ def case_begin(title="No Title")
311
+ Report.caseBegin(title)
312
+ end
313
+ def case_end
314
+ Report.caseEnd
315
+ end
316
+ def step_begin(title="No Title")
317
+ Report.stepBegin(title)
318
+ end
319
+ def step_end
320
+ Report.stepEnd
321
+ end
322
+ def assert_true(title,cond)
323
+ Report.assertTrue(title,cond)
324
+ end
325
+ def assert_return(title,erc=0,act=nil)
326
+ Report.assertReturn(title,erc,act)
327
+ end
328
+ def expect(title="No Title",value="",filetype=nil)
329
+ Report.expect(title,value,filetype)
330
+ end
331
+ def actual(title="No Title",value="",filetype=nil)
332
+ Report.actual(title,value,filetype)
333
+ end
334
+ def more(title,value="",filetype=nil)
335
+ Report.more(title,value,filetype)
336
+ end
337
+
338
+ protected
339
+
340
+ # 为报告追加一行
341
+ def self._append(line)
342
+ File.open(ENV['AT_LOGFILE'],"a"){|f| f << line}
343
+ end
344
+ end
@@ -0,0 +1,405 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+ #
4
+ # Author:: hanyu
5
+ # Date:: 2009.5.7
6
+
7
+ if __FILE__ == $0
8
+ $LIB_ROOT = "#{File.dirname(__FILE__)}/.."
9
+ $TEST_ROOT = "#{$LIB_ROOT}/.."
10
+ $: << "#{$LIB_ROOT}"
11
+ require 'common/log_helper'
12
+ require 'common/config_helper'
13
+ end
14
+
15
+ require 'yaml'
16
+
17
+ # 数据仓库基类
18
+ # - 读取数据仓库文件,如 user.house
19
+ # - 与当前环境绑定,如先读 user.house.sz00 若失败则再读 user.house
20
+ class DataHouse
21
+ def initialize(house_yaml)
22
+ if File.exist? $WORK_ROOT+ "/data/" +house_yaml + ".house."+ ConfigHelper::CONF["env"]
23
+ @data_house = YAML.load_file($WORK_ROOT+ "/data/" +house_yaml + ".house."+ ConfigHelper::CONF["env"])
24
+ $log.info( "load data_house[" + $WORK_ROOT+ "/data/" +house_yaml + ".house."+ ConfigHelper::CONF["env"]+"] success!" )
25
+ elsif File.exist? $WORK_ROOT+ "/data/" +house_yaml+ ".house"
26
+ @data_house = YAML.load_file($WORK_ROOT+ "/data/" +house_yaml+ ".house")
27
+ $log.info( "load data_house[" + $WORK_ROOT+ "/data/" +house_yaml + ".house."+"] success!" )
28
+ elsif File.exist? $SUPER_ROOT+ "/data/" +house_yaml + ".house."+ ConfigHelper::CONF["env"]
29
+ @data_house = YAML.load_file($SUPER_ROOT+ "/data/" +house_yaml + ".house."+ ConfigHelper::CONF["env"])
30
+ $log.info( "load data_house[" + $SUPER_ROOT+ "/data/" +house_yaml + ".house."+ ConfigHelper::CONF["env"]+"] success!" )
31
+ elsif File.exist? $SUPER_ROOT+ "/data/" +house_yaml+ ".house"
32
+ @data_house = YAML.load_file($SUPER_ROOT+ "/data/" +house_yaml+ ".house")
33
+ $log.info( "load data_house[" + $SUPER_ROOT+ "/data/" +house_yaml + ".house."+"] success!" )
34
+ else
35
+ raise "no file to load"
36
+ end
37
+ end
38
+
39
+ # 返回数据仓库的大小
40
+ def size
41
+ @data_house.size
42
+ end
43
+
44
+ end
45
+
46
+ # 用户库
47
+ # === Example
48
+ #
49
+ # require 'data_house'
50
+ #
51
+ class UserHouse < DataHouse
52
+ private_class_method :new
53
+ @@instance = nil
54
+ def self.get_instance
55
+ @@instance = new("user") unless @@instance
56
+ @@instance
57
+ end
58
+
59
+ # 随机取得一个用户
60
+ def get_a_nobody
61
+ @data_house.at rand(@data_house.size)
62
+ end
63
+
64
+ # 根据用户名取用户
65
+ #
66
+ # Example:
67
+ #
68
+ # user = UserHouse.get_instance.by_name "ruguo"
69
+ # puts user
70
+ def get_by_name(name)
71
+ @data_house.find do |u|
72
+ u["name"] == name if u.key? "name"
73
+ end
74
+ end
75
+
76
+ # 根据Tag来取用户,user.house中的多个tag可以用空格来分隔
77
+ #
78
+ # Example:
79
+ #
80
+ # user = @user_house.by_tag "haha"
81
+ #
82
+ # # @user_house在SystemTest的setup中经过初始化
83
+ # # @user_house = UserHouse.get_instance
84
+ #
85
+ # puts user
86
+ #
87
+ # # user.house的内容如下
88
+ # #---
89
+ # #- name: ruguo
90
+ # # password: aaaa
91
+ # # spaceurl: ruguo32
92
+ # # tag : haha hoho gaga
93
+ def get_by_tag(tag)
94
+ @data_house.find do |u|
95
+ u["tag"].split(/\s+/).include?(tag) if u.key? "tag"
96
+ end
97
+ end
98
+
99
+ end
100
+
101
+ # 特殊字符库
102
+ #
103
+ # 由通用测试点库提供相关功能
104
+ class CharHouse < DataHouse
105
+ private_class_method :new
106
+ @@instance = nil
107
+ def self.get_instance
108
+ @@instance = new("char") unless @@instance
109
+ @@instance
110
+ end
111
+
112
+ # 未实现
113
+ def rand_string(size)
114
+ #TODO
115
+ end
116
+ end
117
+
118
+ # 通用测试点库
119
+ # liqiang01@baidu.com
120
+ class CaseHouse < DataHouse
121
+ private_class_method :new
122
+ @@instance = nil
123
+ def self.get_instance
124
+ @@instance = new("case") unless @@instance
125
+ @@instance
126
+ end
127
+
128
+ # 功能
129
+ # 生成随机字符串
130
+ #
131
+ # 参数
132
+ # size: 串的长度
133
+ # mask: 串的内容,mask是个字符串类型。其中包含一些用于表示字符串类型的字符。
134
+ # a: 小写字符串
135
+ # A: 大写字符串
136
+ # 0: 数字串
137
+ # $: 特殊字符串
138
+ # B: 空白字符
139
+ # mask中字符顺序无关
140
+ #
141
+ # 返回
142
+ # ret字符串
143
+ #
144
+ # Example
145
+ # CaseHouse.get_instance.rand_string(10,"aAB0$")
146
+ def rand_string(size, mask)
147
+ charpool=[]
148
+ if mask.scan("a").size > 0
149
+ charpool = charpool+("a".."z").to_a
150
+ end
151
+ if mask.scan("A").size > 0
152
+ charpool = charpool+("A".."Z").to_a
153
+ end
154
+ if mask.scan("0").size > 0
155
+ charpool = charpool+("0".."9").to_a
156
+ end
157
+ if mask.scan("$").size > 0
158
+ charpool = charpool+"~!@#\$%^&*()_+=-{}|\\][:\"';<>?/.,".split(//)
159
+ end
160
+ if mask.scan("B").size > 0
161
+ charpool = charpool+[" "," ","
162
+ end
163
+ ret=""
164
+ 1.upto(size){|i|
165
+ ret << charpool[rand(charpool.size-1)]
166
+ }
167
+ return ret
168
+ end
169
+
170
+ # 功能:
171
+ # 产生8,16,32,64位数字的所有边界值
172
+ #
173
+ # 参数:
174
+ # 无
175
+ #
176
+ # 返回:
177
+ # ret数字的数组
178
+ #
179
+ # Example:
180
+ # CaseHouse.get_instance.get_all_number
181
+ def get_all_number
182
+ return [-18446744073709551616, -18446744073709551615, -9223372036854775808, -9223372036854775807, -4294967296, -4294967295, -2147483648, -2147483647, -65536,-65535, -32768, -32767, -256, -255, -1, 0, 1, 255, 256, 32767, 32768, 65535, 65536, 2147483647, 2147483648, 4294967295, 4294967296, 9223372036854775807, 9223372036854775808, 18446744073709551615, 18446744073709551616]
183
+ end
184
+ end
185
+
186
+
187
+ # 模块库
188
+ # liqiang01@baidu.com
189
+ #
190
+ # 模块信息采用的数据结构:
191
+ =begin
192
+ {
193
+ "[模块名称]" => {
194
+ "host"=>"[ip]",
195
+ "username"=>"[用户名]",
196
+ "password"=>"[密码]",
197
+ "datacenter_rootdir"=>"[数据根目录在数据中心的位置信息,可以在这里对数据进行tag分类]"
198
+ "testing_rootdir"=>"[数据根目录在测试环境的位置信息]"
199
+ "subfiles"=>"[数组,需要进行同步的数据文件,其位置在相应的tag分类下]"
200
+ "subdirs"=>"[数组,需要进行同步的文件夹,其位置在相应的tag分类下]"
201
+ "dbversion"=>"[数组,需要同步的每个数据库的版本,目前支持 5.1.30|5.22]"
202
+ "dbname"=>"[数组,需要同步的每个数据库的名字]"
203
+ "backsql"=>"[数组,需要同步的每个数据库的sql数据文件名]"
204
+ "depends"=>"[数组,该模块依赖的其他模块,将递归的同步所有依赖模块]"
205
+ },
206
+ "[模块名称]" => {
207
+ ...
208
+ }
209
+ }
210
+ 注:当不需要同步数据文件的时候,将subs置为空。
211
+ 当不需要同步数据库数据的时候,将dbversion,dbname,backsql置为空。
212
+ =end
213
+ # 数据文件示例:
214
+ =begin
215
+ - module: ufriend
216
+ host: 127.0.0.1
217
+ username: space
218
+ password: spaceapptest
219
+ datacenter_rootdir: space
220
+ testing_rootdir: /home/space/space
221
+ subfiles: conf/friend.conf
222
+ subdirs: conf
223
+ dbversion: 5.1.30
224
+ dbname: newfriend
225
+ backsql: friend/friend_new.sql
226
+ depends: albumlogic
227
+ =end
228
+ class ModuleHouse < DataHouse
229
+ private_class_method :new
230
+ @@instance = nil
231
+ def self.get_instance
232
+ @@instance = new("module") unless @@instance
233
+ @@instance
234
+ end
235
+
236
+ # 功能:
237
+ # 根据模块名取模块数据
238
+ #
239
+ # 参数:
240
+ # name - 模块的名字
241
+ #
242
+ # Example:
243
+ # mdl1 = ModuleHouse.get_instance.get_by_name "ufriend"
244
+ def get_by_name(name)
245
+ @data_house.find do |u|
246
+ u["module"] == name if u.key? "module"
247
+ end
248
+ end
249
+
250
+ # 功能:
251
+ # 进行数据同步
252
+ #
253
+ # 参数
254
+ # name - 模块的名字
255
+ #
256
+ # Example:
257
+ # ModuleHouse.get_instance.sync "ufriend"
258
+ def sync(name)
259
+ dc = DCHouse.get_instance.get_by_name("datacenter1")
260
+ mdl = ModuleHouse.get_instance.get_by_name(name)
261
+ if(mdl["host"]==nil || mdl["username"]==nil || mdl["password"]==nil || mdl["datacenter_rootdir"]==nil || mdl["testing_rootdir"]==nil)
262
+ puts "Uncomplate Module conf file."
263
+ return
264
+ end
265
+ #对每个subs cp,对每个数据库恢复
266
+ mdl["subfiles"]!=nil && subfiles = mdl["subfiles"].split
267
+ mdl["subdirs"]!=nil && subdirs = mdl["subdirs"].split
268
+ mdl["dbversion"]!=nil && dbversion = mdl["dbversion"].split
269
+ mdl["dbname"]!=nil && dbname = mdl["dbname"].split
270
+ mdl["backsql"]!=nil && backsql = mdl["backsql"].split
271
+ mdl["depends"]!=nil && depends = mdl["depends"].split
272
+
273
+ # 首先将所有依赖模块递归同步
274
+ if(depends!=nil)
275
+ print "#{name} depends === "
276
+ end
277
+ depends!=nil && depends.uniq.each{ |depend_module|
278
+ print " > #{depend_module}"
279
+ }
280
+ puts ""
281
+ depends!=nil && depends.uniq.each{ |depend_module|
282
+ puts "try to sync depends module: #{depend_module}"
283
+ ModuleHouse.get_instance.sync "#{depend_module}"
284
+ }
285
+
286
+ # 同步本模块的数据文件
287
+ subfiles!=nil && subfiles.each{|dir|
288
+ puts "try to transfer "+dc["host"]+":"+dc["datacenterpath"]+"/"+mdl["datacenter_rootdir"]+"/"+dir+" to "+mdl["host"]+"@"+mdl["testing_rootdir"]+"/"+dir
289
+ Util.scpfromto dc["host"], dc["datacenterpath"]+"/"+mdl["datacenter_rootdir"]+"/"+dir, mdl["host"], mdl["testing_rootdir"]+"/"+dir, dc["username"], dc["password"], mdl["username"], mdl["password"]
290
+ }
291
+ subdirs!=nil && subdirs.each{|dir|
292
+ puts "try to transfer "+dc["host"]+":"+dc["datacenterpath"]+"/"+mdl["datacenter_rootdir"]+"/"+dir+" to "+mdl["host"]+"@"+mdl["testing_rootdir"]+"/"+dir
293
+ Util.scpfromtod dc["host"], dc["datacenterpath"]+"/"+mdl["datacenter_rootdir"]+"/"+dir, mdl["host"], mdl["testing_rootdir"]+"/"+dir, dc["username"], dc["password"], mdl["username"], mdl["password"]
294
+ }
295
+
296
+ # 同步本模块的数据库数据
297
+ backsql!=nil && backsql.each{|file|
298
+ if mdl["dbversion"] == "5.1.30"
299
+ puts "try to #{dc["db01"]["dbpath"]}/bin/mysql -u#{dc["db01"]["dbuser"]} -p#{dc["db01"]["dbpass"]} #{mdl["dbname"]} < #{dc["datacenterpath"]}/#{mdl["backsql"]}"
300
+ ssh_cmd dc["host"], dc["username"], dc["password"], "#{dc["db01"]["dbpath"]}/bin/mysql -u#{dc["db01"]["dbuser"]} -p#{dc["db01"]["dbpass"]} #{mdl["dbname"]} < #{dc["datacenterpath"]}/#{mdl["backsql"]}"
301
+ puts Context.get("IOBODY")
302
+ end
303
+ if mdl["dbversion"] == "5.22"
304
+ puts "try to #{dc["db02"]["dbpath"]}/bin/mysql -u#{dc["db02"]["dbuser"]} -p#{dc["db02"]["dbpass"]} #{mdl["dbname"]} < #{dc["datacenterpath"]}/#{mdl["backsql"]}"
305
+ ssh_cmd dc["host"], dc["username"], dc["password"], "#{dc["db02"]["dbpath"]}/bin/mysql -u#{dc["db02"]["dbuser"]} -p#{dc["db02"]["dbpass"]} #{mdl["dbname"]} < #{dc["datacenterpath"]}/#{mdl["backsql"]}"
306
+ puts Context.get("IOBODY")
307
+ end
308
+ }
309
+ end
310
+
311
+ # 功能:
312
+ # 进行环境的恢复
313
+
314
+ def rollback(name)
315
+ end
316
+ end
317
+
318
+ # 数据中心库
319
+ # liqiang01@baidu.com
320
+ #
321
+ # 返回一个数据中心的相关数据 datacenter.house
322
+ # 系统中可以扩充为存在多个数据中心
323
+ #
324
+ # 数据中心使用的步骤:
325
+ =begin
326
+ =end
327
+ #
328
+ # 数据中心采用的数据结构
329
+ =begin
330
+ {
331
+ "datacenter"=>{
332
+ "host"=>"",
333
+ "username"=>"",
334
+ "password"=>"",
335
+ "datacenterpath"=>"",
336
+ "db01"=>{
337
+ "dbpath"=>"",
338
+ "dbuser"=>"",
339
+ "dbpass"=>"",
340
+ "dbport"=>"",
341
+ },
342
+ "db02"=>{
343
+ "dbpath"=>"",
344
+ "dbuser"=>"",
345
+ "dbpass"=>"",
346
+ "dbport"=>""
347
+ }
348
+ }
349
+ }
350
+ =end
351
+ # 数据示例:
352
+ =begin
353
+ - datacenter: datacenter1
354
+ host: 10.81.13.169
355
+ username: space
356
+ password: spaceapptest
357
+ datacenterpath: /home/space/datacenter/
358
+ db01:
359
+ dbpath: /home/space/database/mysql5.1.30/
360
+ dbuser: root
361
+ dbpass: "123456"
362
+ dbport: "3308"
363
+ db02:
364
+ dbpath: /home/space/database/mysql5.22/
365
+ dbuser: root
366
+ dbpass: "123456"
367
+ dbport: "3308"
368
+ =end
369
+ class DCHouse < DataHouse
370
+ private_class_method :new
371
+ @@instance = nil
372
+ def self.get_instance
373
+ @@instance = new("datacenter") unless @@instance
374
+ @@instance
375
+ end
376
+
377
+ # 功能:
378
+ # 根据名字获取数据中心的相关信息
379
+ #
380
+ # Example:
381
+ # dc = DCHouse.get_instance.get_by_name("datacenter1")
382
+ # str = dc["host"]
383
+ # str = dc["db01"]["dbpath"]
384
+ def get_by_name(name)
385
+ @data_house.find do |u|
386
+ u["datacenter"] == name if u.key? "datacenter"
387
+ end
388
+ end
389
+ end
390
+
391
+
392
+
393
+ if __FILE__ == $0
394
+ class MyTest
395
+ def test(str)
396
+ puts str
397
+ puts str.encoding
398
+ end
399
+ end
400
+ Test.new.test "放了时间来访"
401
+ p UserHouse.get_instance.one_nobody
402
+ p UserHouse.get_instance.find_by_name "iii"
403
+
404
+ end
405
+