automate-standard-baseline 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,228 @@
1
+ require 'rubygems'
2
+ require "securerandom"
3
+ require 'rexml/document'
4
+ require 'rexml/xpath'
5
+ require 'tempfile'
6
+ require "uri"
7
+ require "net/http"
8
+ require 'fileutils'
9
+
10
+ include REXML
11
+
12
+ def default_timeout_val
13
+ 300
14
+ end
15
+
16
+ def logger
17
+ @logger ||= Logger.new(STDOUT)
18
+ end
19
+
20
+ def set_env(device_id,id)
21
+ ENV["ADB_DEVICE_ARG"]="#{device_id}"
22
+ ENV["ADB_DEVICE_INDEX"]="#{id}"
23
+ end
24
+
25
+ def log(message)
26
+ logger.info message
27
+ end
28
+
29
+
30
+ def pull_out_apk(device_serial, package_name, to_path = nil)
31
+ out_path = File.expand_path(to_path) if to_path
32
+ out_path ||= File.expand_path("#{package_name}.apk")
33
+
34
+ if File.exists?(out_path)
35
+ new_name = "#{out_path}.#{Time.now.strftime('%Y%m%d%H%M%S%s%S')}"
36
+ puts %Q{rename #{out_path} to #{new_name} since it already exists.}
37
+ File.rename(out_path, new_name)
38
+ end
39
+
40
+ for num in ['2', '1', '3']
41
+ begin
42
+ cmd = %Q{ #{adb_cmd(device_serial)} pull /data/app/#{package_name}-#{num}.apk #{out_path} }
43
+ exec_command(cmd, 120)
44
+ rescue
45
+ end
46
+
47
+ if File.exists?(out_path)
48
+ break
49
+ end
50
+ end
51
+
52
+ raise %Q{Failed to pull out the package "#{}"} unless File.exists?(out_path)
53
+ out_path
54
+ end
55
+
56
+ def mkdirs(path)
57
+ if(!File.directory?(path))
58
+ if(!mkdirs(File.dirname(path)))
59
+ return false;
60
+ end
61
+ Dir.mkdir(path)
62
+ end
63
+
64
+ return true
65
+ end
66
+
67
+
68
+ def get_available_devices
69
+ # grep the connected devices
70
+ cmd = "#{adb_cmd} devices | ruby -nae 'puts $F[0] if $F[1] =~ /device/'"
71
+ devices = exec_command(cmd, 10).output
72
+ devices = devices.split /\s+/
73
+
74
+ if devices.length > 0
75
+ logger.info {
76
+ msg = "\nAvailable devices\n"
77
+ for i in 0...devices.length
78
+ msg += "#{devices[i]}\n"
79
+ end
80
+
81
+ msg
82
+ }
83
+ end
84
+
85
+ devices
86
+ end
87
+
88
+ # pull out all /sdcard/*.pcap to logs/
89
+ def pull_out_tcpdump(devices)
90
+ dest_dir = "/sdcard/"
91
+ devices.each do |d|
92
+ cmd = "#{adb_cmd(d)} shell su -c ls #{dest_dir} | grep pcap"
93
+ tcpdump_files = exec_command(cmd, 10).output.strip
94
+ tcpdump_files.each_line do |f|
95
+ Dir.mkdir('logs') unless Dir.exists?('logs')
96
+
97
+ cmd = "#{adb_cmd(d)} pull #{File.join(dest_dir, f)} logs/#{d}_#{f}"
98
+ logger.info(cmd)
99
+ exec_command(cmd, 120)
100
+ cmd = "#{adb_cmd(d)} shell su -c rm #{File.join(dest_dir, f)}"
101
+ logger.info(cmd)
102
+ exec_command(cmd, 10)
103
+ end
104
+ end
105
+ end
106
+
107
+
108
+ def download_file(url, saved_path = nil)
109
+ uri = URI.parse(url)
110
+ path = (!uri.query or uri.query.blank?) ? uri.path : uri.path+"?"+uri.query
111
+ unless saved_path
112
+ saved_path = 'oc_apks'
113
+ Dir.mkdir(saved_path) unless Dir.exists?(saved_path)
114
+ saved_path = "#{saved_path}/#{uri.path[uri.path.rindex("/") + 1, uri.path.length]}"
115
+ end
116
+ saved_path = File.expand_path(saved_path)
117
+ puts "Download file by url #{url}; saved_path: #{saved_path}"
118
+ f = File.new(saved_path, "wb")
119
+ begin
120
+ print "Downloading\n"
121
+ i = 0
122
+ Net::HTTP.start(uri.host, uri.port) do |http|
123
+ http.request_get(path) do |resp|
124
+ resp.read_body do |segment|
125
+ f.write(segment)
126
+ i = i + 1
127
+ if (i % 80 == 0)
128
+ print "\n"
129
+ else
130
+ print "."
131
+ end
132
+ end
133
+ end
134
+ end
135
+ ensure
136
+ f.close()
137
+ end
138
+ print "\n"
139
+ return saved_path
140
+ end
141
+
142
+
143
+ def package_name(app)
144
+ require 'rexml/document'
145
+ require 'rexml/xpath'
146
+
147
+ manifest = Document.new(manifest(app))
148
+ manifest.root.attributes['package']
149
+ end
150
+
151
+ def manifest(app)
152
+ cmd = %Q{java -jar "#{File.dirname(__FILE__)}/manifest_extractor.jar" "#{app}"}
153
+ puts "exec #{cmd}"
154
+ exec_command(cmd, default_timeout_val).output
155
+ end
156
+
157
+ class ExecResult
158
+ attr_accessor :output, :is_success, :status_code
159
+
160
+ def initialize(output, is_success, status_code)
161
+ @output = output
162
+ @is_success = is_success
163
+ @status_code = status_code
164
+ end
165
+ end
166
+
167
+ ## Add timeout mechanism here to avoid external command executing the whole
168
+ ## program.
169
+ def exec_command(cmd, time_out = nil)
170
+ rd, wr = IO.pipe
171
+ pid = spawn(cmd, [:out, :err] => wr)
172
+
173
+ begin
174
+ unless time_out
175
+ Process.waitpid(pid)
176
+ status_code = $?.exitstatus
177
+ else
178
+ begin
179
+ Timeout.timeout(time_out) do
180
+ Process.waitpid(pid)
181
+ status_code = $?.exitstatus
182
+ end
183
+ rescue Timeout::Error => e
184
+ puts 'Timeout::Error'
185
+ puts "kill"
186
+ Process.kill("KILL", pid) rescue nil
187
+ status_code = -99999
188
+
189
+ backtrace = e.backtrace || []
190
+ new_error = Timeout::Error.new("Failed to execute command #{cmd} due to it spent too much time than expected time: #{time_out}s")
191
+ new_error.set_backtrace(backtrace + [e.message])
192
+
193
+ raise new_error
194
+ end
195
+ end
196
+ ensure
197
+ wr.close
198
+ output = rd.read
199
+ rd.close
200
+ end
201
+
202
+ ExecResult.new(output, status_code == 0, status_code)
203
+ end
204
+
205
+
206
+
207
+ def is_windows?
208
+ require 'rbconfig'
209
+ (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
210
+ end
211
+
212
+ def adb_cmd(device_serial = nil)
213
+ if is_windows?
214
+ %Q("#{ENV["ANDROID_HOME"]}\\platform-tools\\adb.exe" #{_device_args(device_serial)})
215
+ else
216
+ %Q("#{ENV["ANDROID_HOME"]}/platform-tools/adb" #{_device_args(device_serial)})
217
+ end
218
+ end
219
+
220
+ def _device_args(device_serial = nil)
221
+ if ENV["ADB_DEVICE_ARG"]
222
+ "-s #{ENV["ADB_DEVICE_ARG"]}"
223
+ elsif device_serial
224
+ " -s #{device_serial} "
225
+ else
226
+ ""
227
+ end
228
+ end
@@ -0,0 +1,238 @@
1
+ require 'net/http'
2
+ require 'open-uri'
3
+ require 'rubygems'
4
+ require 'timeout'
5
+ require 'retriable'
6
+ require 'yaml'
7
+ require 'uri'
8
+ require File.join(File.dirname(__FILE__), "helpers")
9
+
10
+
11
+ module Seven module ASB
12
+
13
+ OC_GA_PROCESSES = ['occ', 'ochttpd', 'ocdnsd', 'ocshttpd', 'octcpd']
14
+
15
+ module Operations
16
+
17
+ @@default_device = nil
18
+
19
+ @@default_time_out = 300 # 5 minutes
20
+
21
+ def default_device
22
+ unless @@default_device
23
+ puts "create a default device"
24
+ @@default_device = Device.new(self, ENV['ADB_DEVICE_ARG'],ENV['ADB_DEVICE_INDEX'])
25
+ end
26
+ @@default_device
27
+ end
28
+
29
+
30
+ def install_or_dump_oc_client(path, reinstall = true)
31
+
32
+
33
+ if reinstall
34
+ uri = URI.parse(path)
35
+ if uri.scheme == 'http' or uri.scheme == 'https'
36
+ install_and_start_oc_client_by_url(path)
37
+ else
38
+ install_and_start_oc_client(path)
39
+ end
40
+ else
41
+ #log "Only dump the OC info but not re-install OC client."
42
+ #oc_info = dump_oc_info(path, "logs/device-#{ENV['ADB_DEVICE_ARG']}-oc-info.yml")
43
+ #log "OC Info: #{oc_info}"
44
+ end
45
+ end
46
+
47
+ def reset_data()
48
+ # install the oc client apk
49
+ default_device.device_reset_data()
50
+
51
+ end
52
+
53
+ def install_and_start_oc_client_by_url(url, saved_path = nil)
54
+ default_device.reinstall_oc_client_by_url(url, saved_path)
55
+ end
56
+
57
+ def install_and_start_oc_client(oc_apk_path)
58
+ default_device.reinstall_oc_client(oc_apk_path)
59
+ end
60
+
61
+ def uninstall_oc_client(package_name)
62
+ default_device.uninstall_oc_client(package_name)
63
+ end
64
+
65
+ def start_oc_client()
66
+ default_device.start_oc_client()
67
+ end
68
+
69
+ def stop_oc_client(package_name)
70
+ default_device.stop_oc_client(package_name)
71
+ end
72
+
73
+
74
+
75
+ ###
76
+
77
+ class Device
78
+
79
+ def make_default_device
80
+ @cucumber_world.default_device = self
81
+ end
82
+
83
+ def initialize(cucumber_world, serial, index)
84
+ @cucumber_world = cucumber_world
85
+ @serial = serial
86
+ @index = index
87
+ log "ADB_DEVICE_INDEX; #{ENV['ADB_DEVICE_INDEX']}"
88
+ if @index
89
+ @index = Integer(@index) * 100
90
+ else
91
+ @index = 0
92
+ end
93
+ log "device_index; #{@index}"
94
+ @apps = Hash.new
95
+
96
+ end
97
+
98
+
99
+ def uninstall_oc_client(package_name)
100
+ # uninstall the oc client apk
101
+ log "Uninstall oc client"
102
+ cmd = "#{adb_command} uninstall #{package_name}"
103
+ log cmd
104
+ result = exec_command(cmd, @@default_time_out)
105
+ log result.is_success
106
+
107
+ stop_oc_client(package_name)
108
+
109
+ # remove /data/misc/openchannel
110
+ cmd = "#{adb_command} shell su -c rm -r /data/misc/openchannel"
111
+ log cmd
112
+ result = exec_command(cmd, @@default_time_out)
113
+ log result.is_success
114
+
115
+ cmd = "#{adb_command} shell su -c rm -r /sdcard/OpenChannel"
116
+ log cmd
117
+ result = exec_command(cmd, @@default_time_out)
118
+ log result.is_success
119
+
120
+ log "Uninstall oc client finished"
121
+ end
122
+
123
+ def start_oc_client()
124
+ log "Starting oc client...."
125
+ cmd = "#{adb_command} shell am startservice -a com.seven.asimov.ocengine.OCENGINESERVICE"
126
+ log cmd
127
+ result = exec_command(cmd, @@default_time_out)
128
+ raise "Can not start oc by am startservice" unless result.is_success
129
+
130
+ # check if oc is running
131
+ retriable :tries => 5, :interval => 30 do
132
+ cmd = "#{adb_command} shell su -c ps"
133
+ log cmd
134
+ result = exec_command(cmd, @@default_time_out)
135
+ for oc_process in OC_GA_PROCESSES
136
+ raise "OC client is not running" unless result.output.include?(oc_process)
137
+ end
138
+ end
139
+
140
+ # check iptables is modified
141
+ retriable :tries => 3, :interval => 30 do
142
+ cmd = "#{adb_command} shell su -c iptables -t nat -nvL"
143
+ log cmd
144
+ result = exec_command(cmd, @@default_time_out)
145
+ raise "iptables is not modified" unless result.output.include?('redir ports 65002')
146
+ end
147
+ puts "oc client is started."
148
+ end
149
+
150
+ def stop_oc_client(package_name)
151
+ log "Stopping oc client...."
152
+ cmd = "#{adb_command} shell am force-stop #{package_name}"
153
+ log cmd
154
+ result = exec_command(cmd, @@default_time_out)
155
+ log result.is_success
156
+ raise "Can not stop oc by am force-stop" unless result.is_success
157
+
158
+ # kill oc client processes
159
+ for oc_process in OC_GA_PROCESSES
160
+ cmd = "#{adb_command} shell su -c cat /data/misc/openchannel/pids/#{oc_process}"
161
+ log cmd
162
+ result = exec_command(cmd, @@default_time_out).output.strip
163
+ log result
164
+ cmd = "#{adb_command} shell su -c kill -9 #{result}"
165
+ log cmd
166
+ result = exec_command(cmd, @@default_time_out)
167
+ log result.is_success
168
+ end
169
+
170
+ # flush iptables
171
+ cmd = "#{adb_command} shell su -c iptables -t nat -F"
172
+ log cmd
173
+ result = exec_command(cmd, @@default_time_out)
174
+ log result.is_success
175
+ end
176
+
177
+ def install_and_start_oc_client(oc_apk_path)
178
+ # install the oc client apk
179
+ log "Install oc client"
180
+ cmd = "#{adb_command} install -r #{oc_apk_path}"
181
+ log cmd
182
+ result = exec_command(cmd, @@default_time_out)
183
+ raise "Can not install oc client" unless result.is_success
184
+ start_oc_client()
185
+
186
+ #oc_info = dump_oc_info(oc_apk_path, "logs/device-#{ENV['ADB_DEVICE_ARG']}-oc-info.yml")
187
+ #log "oc_info: #{oc_info}"
188
+ log "Install and start oc client finished."
189
+ end
190
+
191
+ def device_reset_data()
192
+ # install the oc client apk
193
+ log "Reset Data Usage/Mobile data (off/on)"
194
+ cmd = "#{adb_command} shell svc data disable && #{adb_command} shell svc data enable"
195
+ log cmd
196
+ result = exec_command(cmd, @@default_time_out)
197
+ raise "Can not reset data" unless result.is_success
198
+
199
+ log "Reset data usage done."
200
+ end
201
+
202
+ def reinstall_oc_client(oc_apk_path)
203
+ oc_pkg_name = package_name(oc_apk_path)
204
+ uninstall_oc_client(oc_pkg_name)
205
+ install_and_start_oc_client(oc_apk_path)
206
+ end
207
+
208
+ def reinstall_oc_client_by_url(url, saved_path = nil)
209
+ if saved_path
210
+ saved_path = File.expand_path(saved_path)
211
+ end
212
+ saved_path = download_file(url, saved_path)
213
+ reinstall_oc_client(saved_path)
214
+ end
215
+
216
+
217
+ def adb_command
218
+ if is_windows?
219
+ %Q("#{ENV["ANDROID_HOME"]}\\platform-tools\\adb.exe" #{device_args})
220
+ else
221
+ %Q("#{ENV["ANDROID_HOME"]}/platform-tools/adb" #{device_args})
222
+ end
223
+ end
224
+
225
+ def device_args
226
+ if @serial
227
+ "-s #{@serial}"
228
+ else
229
+ ""
230
+ end
231
+ end
232
+
233
+ end
234
+
235
+ end
236
+
237
+
238
+ end end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: automate-standard-baseline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2013-04-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: retriable
16
- requirement: &14319260 !ruby/object:Gem::Requirement
16
+ requirement: &19215380 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *14319260
24
+ version_requirements: *19215380
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: sys-proctable
27
- requirement: &14318700 !ruby/object:Gem::Requirement
27
+ requirement: &19214360 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *14318700
35
+ version_requirements: *19214360
36
36
  description: auomated standard baseline test
37
37
  email: rfu@seven.com
38
38
  executables:
@@ -41,6 +41,9 @@ executables:
41
41
  extensions: []
42
42
  extra_rdoc_files: []
43
43
  files:
44
+ - lib/automate-standard-baseline/manifest_extractor.jar
45
+ - lib/automate-standard-baseline/operations.rb
46
+ - lib/automate-standard-baseline/helpers.rb
44
47
  - bin/automate-standard-baseline
45
48
  - bin/abs-stop
46
49
  homepage: http://rubygems.org/gems/automate-standard-baseline