super-test 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
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
+