tesults 1.0.1 → 1.1.0

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 (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tesults.rb +191 -8
  3. metadata +33 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7fa9be7865cbdeda9f2eccd4dd11c4810788b279
4
- data.tar.gz: 3aebfd30793e3d4ccb90ebce82215b9611e6d846
3
+ metadata.gz: ee8de6dd8552c947659aebea45ef94cb5e6f738e
4
+ data.tar.gz: 771e0d69d0f437251875edbd5f1d7f8b56c16c16
5
5
  SHA512:
6
- metadata.gz: 2a43aa758c8d5284900d819fd954dac879baffa35c1b28d720115b3d4b9974542648f9ff8d4eb23ea7e4d63154d38899c091f684ebc02c1eadbc4b0aca894f7d
7
- data.tar.gz: cece65ac6296ca768f93c1862b24295c020923a9327965e7bee21433cf71ac84b2990e8d14ed2a67945aa5eddf9dc4faaf44cd1e84436d690acd4c324c4d9dde
6
+ metadata.gz: f4d84658b97a8f05b737c3efd110317e81ea1b25b7a92e35b1315f0872317ebfa688c24d3389bd7dfde86a8eedbee652a293e1783dee56c5e5df65844b84c922
7
+ data.tar.gz: 8a8a34a60c0b6381fbe389cb41c99c0fdf343d89ebfd70f16fa84ee4bdaa19df5d69c5a52cb3ee896201a371867491d60cdd16edbb00e35312d17e0c63ce93e0
data/lib/tesults.rb CHANGED
@@ -1,10 +1,28 @@
1
1
  require 'json'
2
2
  require 'uri'
3
3
  require 'net/https'
4
+ require 'aws-sdk'
4
5
 
5
- module Tesults
6
- def self.upload(data)
7
- uri = URI("https://www.tesults.com/results")
6
+ class Tesults
7
+ @@expire_buffer = 30 # 30 seconds
8
+ @@files_uploaded = 0
9
+ @@bytes_uploaded = 0
10
+ @@uploading = []
11
+ @@warnings = []
12
+
13
+ def self.create_s3_cilent(credentials)
14
+ s3_client = Aws::S3::Client.new(
15
+ region: 'us-east-1',
16
+ access_key_id: credentials['AccessKeyId'],
17
+ secret_access_key: credentials['SecretAccessKey'],
18
+ session_token: credentials['SessionToken']
19
+ )
20
+ Aws::S3::Resource.new(client: s3_client)
21
+ end
22
+
23
+ def self.refresh_credentials(target, key)
24
+ data = {:target => target, :key => key}
25
+ uri = URI("https://www.tesults.com/permitupload")
8
26
  http = Net::HTTP.new(uri.host, uri.port)
9
27
  http.use_ssl = true
10
28
  req = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json')
@@ -13,15 +31,180 @@ module Tesults
13
31
  jsonData = JSON.parse(res.body)
14
32
  success = false
15
33
  message = ""
34
+ upload = nil
16
35
  if jsonData['error'] == nil
17
36
  success = true
18
- message = (jsonData['data'])['message']
37
+ d = jsonData['data']
38
+ message = d['message']
39
+ upload = d['upload']
19
40
  else
20
41
  success = false
21
- message = (jsonData['error'])['message']
42
+ err = jsonData['error']
43
+ message = err['message']
22
44
  end
23
- val = {:success => success, :message => message}
45
+ val = {:success => success, :message => message, :upload => upload}
24
46
  rescue => e
25
- val = {:success => false, :message => e}
47
+ return {:success => false, :message => e.message, :upload => nil}
48
+
49
+ end
50
+
51
+ def self.transfer(file, bytes, key, auth)
52
+ Thread.new {
53
+ s3 = create_s3_cilent(auth)
54
+ increment = 1
55
+ bytes_increment = bytes
56
+ begin
57
+ result = s3.bucket('tesults-results').object(key).upload_file(file)
58
+ rescue
59
+ # upload failed
60
+ increment = 0
61
+ bytes_increment = 0
62
+ ensure
63
+ if result != true
64
+ increment = 0
65
+ bytes_increment = 0
66
+ end
67
+ @@files_uploaded += increment
68
+ @@bytes_uploaded += bytes_increment
69
+ @@uploading.delete_at @@uploading.index file
70
+ end
71
+ }
72
+
73
+ end
74
+
75
+ def self.files_upload(files, keyPrefix, auth, target)
76
+ expiration_string = auth['Expiration']
77
+ expiration = expiration_string.to_i
78
+ max_active_uploads = 10 # Upload at most 10 files simultaneously to avoid hogging the client machine.
79
+
80
+ while files.length != 0 || @@uploading.length != 0 do
81
+ begin
82
+ if @@uploading.length < max_active_uploads && files.length != 0
83
+ # Check if new credentials required.
84
+ now = Time.now.to_i
85
+ if now + @@expire_buffer > expiration # Check within 30 seconds of expiry.
86
+ # Refresh credentials.
87
+ if @@uploading.length == 0
88
+ # Wait for all current transfers to complete so we can set a new s3 client.
89
+ response = refresh_credentials(target, keyPrefix)
90
+ if response[:success] != true
91
+ # Must stop upload due to failure to be permitted for new credentials.
92
+ @@warnings.push(response[:message])
93
+ break
94
+ else
95
+ upload = response[:upload]
96
+ key = upload['key']
97
+ upload_message = upload['message']
98
+ permit = upload['permit']
99
+ auth = upload['auth']
100
+ if permit != true
101
+ # Must stop upload due to failure to be permitted for new credentials.
102
+ @@warnings.push(upload_message)
103
+ break
104
+ else
105
+ # Upload permitted.
106
+ expiration_string = auth['Expiration']
107
+ expiration = expiration_string.to_i
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ if now + @@expire_buffer < expiration
114
+ # Load new file for upload.
115
+ f = files.shift
116
+ if File.file?(f[:file])
117
+ fname = File.basename f[:file]
118
+ key = keyPrefix + '/' + f[:num].to_s + '/' + fname
119
+ @@uploading.push(f[:file])
120
+ transfer(f[:file], File.size(f[:file]), key, auth)
121
+ else
122
+ @@warnings.push('File not found: ' + f[:file])
123
+ end
124
+ end
125
+ end
126
+
127
+ # Check if existing upload complete - handled by each transfer.
128
+ rescue => e
129
+ @@warnings.push(e.message)
130
+ end
131
+ end
132
+
133
+ return {:message => '. ' + @@files_uploaded.to_s + ' files uploaded. ' + @@bytes_uploaded.to_s + ' bytes uploaded.', :warnings => @@warnings}
134
+ end
135
+
136
+ def self.files_in_test_cases(data)
137
+ results = data[:results]
138
+ cases = results[:cases]
139
+ files = []
140
+ num = 0
141
+ cases.each do |c|
142
+ c_files = c[:files]
143
+ if c_files == nil
144
+ next
145
+ else
146
+ c_files.each do |f|
147
+ files.push({:num => num, :file => f})
148
+ end
149
+ end
150
+ num += 1
151
+ end
152
+ return files
153
+ end
154
+
155
+ def self.upload(data)
156
+ begin
157
+ uri = URI("https://www.tesults.com/results")
158
+ http = Net::HTTP.new(uri.host, uri.port)
159
+ http.use_ssl = true
160
+ req = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json')
161
+ req.body = data.to_json
162
+ res = http.request(req)
163
+ jsonData = JSON.parse(res.body)
164
+ success = false
165
+ message = ""
166
+ if jsonData['error'] == nil
167
+ success = true
168
+ d = jsonData['data']
169
+ message = d['message']
170
+ upload = d['upload']
171
+
172
+ if upload == nil
173
+ # No files to upload, complete.
174
+ val = {:success => success, :message => message, :warnings => [], :errors => []}
175
+ else
176
+ # Upload files.
177
+ target = data[:target]
178
+ files = files_in_test_cases(data)
179
+
180
+ key = upload['key']
181
+ upload_message = upload['message']
182
+ permit = upload['permit']
183
+ auth = upload['auth']
184
+
185
+ if permit != true
186
+ val = {:success => success, :message => message, :warnings => [uploadMessage], :errors => []}
187
+ else
188
+ # Upload required and permitted.
189
+ begin
190
+ file_upload_return = files_upload(files, key, auth, target) # This can take a while
191
+ upload_message = file_upload_return[:message]
192
+ rescue => e
193
+ @@warnings.push(e.message)
194
+ upload_message = '. View warnings.'
195
+ ensure
196
+ return {:success => success, :message => "Success" + upload_message.to_s, :warnings => @@warnings, :errors => []}
197
+ end
198
+ end
199
+ end
200
+ else
201
+ success = false
202
+ error = jsonData['error']
203
+ message = error['message']
204
+ return {:success => success, :message => message, :warnings => [], :errors => [message]}
205
+ end
206
+ rescue => e
207
+ return {:success => false, :message => e.message, :warnings=> [], :errors => [e.message]}
208
+ end
26
209
  end
27
- end
210
+ end
metadata CHANGED
@@ -1,17 +1,45 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tesults
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tesults
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-11 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Tesults is a test automation results reporting service. This API library
14
- makes it easier to upload your test results from your Ruby application.
11
+ date: 2017-04-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Tesults API library for uploading test results to Tesults in your Ruby
42
+ application.
15
43
  email:
16
44
  - support@tesults.com
17
45
  executables: []