xtc-ops 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES.txt +1 -0
- data/README.md +6 -0
- data/bin/xtc-ops-sync-logs +182 -0
- metadata +62 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5795caf4efc0770a5fb89e5da304a5f2b61f756d
|
4
|
+
data.tar.gz: f7a2dbb19b8276e1a9b6c21b12453fd6bc97804d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 56e114a07a793e19fc4f2927e47c91686edf86770fa58c73c2e28ee21c43ee20805653158d5efa3fef51d8aee022df22c88d99c2ad9875e36147739308d33c5c
|
7
|
+
data.tar.gz: 1f94931f81c0b36ddadbc8e8e3c750c110608f86741c24e0d9095fd3026755afadb6463db845ac3a7f007fdeca2803d0ae9f71fe308e46b0bef65efe9e27c4fd
|
data/CHANGES.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
data/README.md
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'uri'
|
6
|
+
require 'net/http'
|
7
|
+
require 'set'
|
8
|
+
require 'open3'
|
9
|
+
|
10
|
+
unless ENV['XTC_PASSWORD'] && ENV['XTC_USERNAME']
|
11
|
+
puts "You must set env var XTC_USERNAME and XTC_PASSWORD or we can't fetch data"
|
12
|
+
exit(1)
|
13
|
+
end
|
14
|
+
|
15
|
+
logs ="logfiles"
|
16
|
+
FileUtils.mkdir_p logs
|
17
|
+
|
18
|
+
url_or_app_upload_id = ARGV[0]
|
19
|
+
|
20
|
+
def find_app_upload_id(input)
|
21
|
+
uri = URI(input)
|
22
|
+
if uri.scheme == 'https'
|
23
|
+
@domain = uri.host
|
24
|
+
|
25
|
+
if /device.?=(.*)$/ =~ uri.query
|
26
|
+
@snapshot = $1
|
27
|
+
end
|
28
|
+
uri.path.split("/")[3] # ["", "app", "app-id", "app-upload-id"]
|
29
|
+
else
|
30
|
+
@domain = "testcloud.xamarin.com"
|
31
|
+
uri.path
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def fetch_test_data(app_upload_id)
|
36
|
+
uri = URI("https://#{@domain}/admin/api/app_uploads/#{app_upload_id}/status")
|
37
|
+
req = Net::HTTP::Get.new(uri)
|
38
|
+
req.basic_auth ENV['XTC_USERNAME'], ENV['XTC_PASSWORD']
|
39
|
+
|
40
|
+
res = Net::HTTP.start(uri.hostname, uri.port,:use_ssl => true) do |http|
|
41
|
+
http.request(req)
|
42
|
+
end
|
43
|
+
JSON.parse(res.body)
|
44
|
+
end
|
45
|
+
|
46
|
+
@app_upload_id = find_app_upload_id url_or_app_upload_id
|
47
|
+
test=@test = fetch_test_data @app_upload_id
|
48
|
+
if ENV['DEBUG'] == '1'
|
49
|
+
puts JSON.pretty_generate(test)
|
50
|
+
puts "-"*40
|
51
|
+
end
|
52
|
+
test_id = @test_id = test['test_id']
|
53
|
+
@snapshots = test['device_snapshots']
|
54
|
+
|
55
|
+
def log_test
|
56
|
+
puts ""
|
57
|
+
puts "="*40
|
58
|
+
puts " Upload id: #{@app_upload_id} "
|
59
|
+
puts " Devices: #{@snapshots.count} "
|
60
|
+
if @snapshot
|
61
|
+
@snapshot_data = @snapshots.find {|s| s['id']==@snapshot}
|
62
|
+
puts " Queue: #{@snapshot_data['queue']} " if @snapshot_data
|
63
|
+
|
64
|
+
end
|
65
|
+
puts " Test #{@test['test_class']} "
|
66
|
+
puts " Test id: #{@test_id} "
|
67
|
+
puts " App: #{@test['app']} "
|
68
|
+
puts " App-id: #{@test['app_id']} "
|
69
|
+
puts " Owner: #{@test['owner']} "
|
70
|
+
puts "="*40
|
71
|
+
puts ""
|
72
|
+
end
|
73
|
+
|
74
|
+
execution_hosts = test['execution_hosts']
|
75
|
+
log_path = @log_path = File.join(logs,test_id)
|
76
|
+
|
77
|
+
unless File.directory?(@log_path)
|
78
|
+
puts "Sync logs from #{execution_hosts.count} executionhosts to #{logs}"
|
79
|
+
|
80
|
+
pids = []
|
81
|
+
execution_hosts.each do |eh|
|
82
|
+
err_log = "#{@app_upload_id}_#{eh['name']}.log"
|
83
|
+
puts "-"*40
|
84
|
+
puts "Background copy logs from #{eh['name']}:/xamarin/logs/tests/#{test_id}/*. Error log: #{err_log}"
|
85
|
+
pid = Process.spawn(%Q[scp -q -r "#{eh['name']}:/xamarin/logs/tests/#{test_id}" #{logs}],:err=> err_log)
|
86
|
+
pids << {pid: pid, host: eh['name']}
|
87
|
+
puts ""
|
88
|
+
end
|
89
|
+
|
90
|
+
log_test
|
91
|
+
set = Set.new(pids)
|
92
|
+
i=0
|
93
|
+
puts "Waiting for pids/hosts\n#{pids.join("\n")}"
|
94
|
+
until set.empty? do
|
95
|
+
i += 1
|
96
|
+
sleep 1
|
97
|
+
$stdout.write('.')
|
98
|
+
pids = set.to_a
|
99
|
+
if i%6 == 0
|
100
|
+
log_test
|
101
|
+
puts "\n\nWaiting for pids/hosts\n#{pids.join("\n")}\n\n"
|
102
|
+
end
|
103
|
+
pids.each do |pid_host|
|
104
|
+
pid = pid_host[:pid]
|
105
|
+
host = pid_host[:host]
|
106
|
+
_, status = Process.waitpid2(pid, Process::WNOHANG | Process::WUNTRACED )
|
107
|
+
if status
|
108
|
+
puts "\nCopy from host #{host} completed with status: success=#{status.success?}."
|
109
|
+
set.delete(pid_host)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
puts "Done!"
|
116
|
+
puts "Saved to path #{log_path}"
|
117
|
+
else
|
118
|
+
puts "Logs already fetched for id #{@app_upload_id}"
|
119
|
+
end
|
120
|
+
|
121
|
+
def fetch_devicehost_log(queue_name)
|
122
|
+
logs = File.join(@log_path, queue_name)
|
123
|
+
|
124
|
+
calabash_log = File.join(logs, 'calabash.log')
|
125
|
+
mono_log = File.join(logs, 'mono.log')
|
126
|
+
log = if File.exist?(calabash_log)
|
127
|
+
File.join(logs,'calabash.log')
|
128
|
+
elsif File.exist?(mono_log)
|
129
|
+
File.join(logs,'mono.log')
|
130
|
+
else
|
131
|
+
raise "Unable to find calabash/mono log for #{queue_name}"
|
132
|
+
end
|
133
|
+
|
134
|
+
puts "Analyzing log #{log}"
|
135
|
+
|
136
|
+
device_id = nil
|
137
|
+
corr_id = @test_id
|
138
|
+
host = nil
|
139
|
+
IO.read(log).lines.each do |line|
|
140
|
+
if /DeviceID:/.match(line)
|
141
|
+
device_id = line.strip.split("DeviceID:").last.strip
|
142
|
+
elsif /DeviceHost:/.match(line)
|
143
|
+
host = line.strip.split("DeviceHost:").last.strip
|
144
|
+
end
|
145
|
+
break if host && device_id
|
146
|
+
end
|
147
|
+
|
148
|
+
puts "Snapshot ran on Host: #{host}"
|
149
|
+
puts "Snapshot ran on Device: #{device_id}"
|
150
|
+
|
151
|
+
prefix = "#{logs}/devicehost"
|
152
|
+
FileUtils.mkdir_p prefix
|
153
|
+
`scp deployer@#{host}:/xamarin/logs/devicehost/#{corr_id}/#{device_id}_* #{prefix}`
|
154
|
+
puts "General log stored in: #{@log_path}"
|
155
|
+
puts "Device logs stored in #{prefix}"
|
156
|
+
puts "Path copied to copy/paste buffer:"
|
157
|
+
Open3.capture2("pbcopy", :stdin_data=>logs)
|
158
|
+
end
|
159
|
+
|
160
|
+
if @snapshot_data
|
161
|
+
puts "Fetching devicehost logs for #{@snapshot_data['queue']}"
|
162
|
+
fetch_devicehost_log(@snapshot_data['queue'])
|
163
|
+
else
|
164
|
+
|
165
|
+
@snapshots.each_with_index do |snapshot, index|
|
166
|
+
puts "#{index}\t #{snapshot["queue"]}"
|
167
|
+
end
|
168
|
+
|
169
|
+
puts "Select one:"
|
170
|
+
index = STDIN.gets.chomp.to_i
|
171
|
+
|
172
|
+
selected = @snapshots[index]
|
173
|
+
raise "NO NO NO! That's not a thing!" unless selected
|
174
|
+
|
175
|
+
puts ""
|
176
|
+
|
177
|
+
puts "Selected: #{selected['queue']}. Fetching..."
|
178
|
+
fetch_devicehost_log(selected['queue'])
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xtc-ops
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Karl Krukow
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: json
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: ' - '
|
28
|
+
email:
|
29
|
+
- karl@xamarin.com
|
30
|
+
executables:
|
31
|
+
- xtc-ops-sync-logs
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- bin/xtc-ops-sync-logs
|
36
|
+
- README.md
|
37
|
+
- CHANGES.txt
|
38
|
+
homepage: http://xamarin.com
|
39
|
+
licenses: []
|
40
|
+
metadata: {}
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
requirements: []
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 2.0.2
|
58
|
+
signing_key:
|
59
|
+
specification_version: 4
|
60
|
+
summary: Collection of tools for ops in XTC
|
61
|
+
test_files: []
|
62
|
+
has_rdoc:
|