spectre-core 1.8.0 → 1.9.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a15b70a0865cac8f59408847056d512ca190458c3dd208bc094d341bea27bcf
4
- data.tar.gz: 4fe55b4c7ee8112739a04618f876a955d4ac24885a7b560c550ee55809f619e1
3
+ metadata.gz: 4b3c5faed7a6a34d2c9fe9e2c3b637ce8cc818e8ea597649e7b1c386dd444fde
4
+ data.tar.gz: 330492cacaad784dea242b35bd539a75660268022485afde75e47cdc99d374a7
5
5
  SHA512:
6
- metadata.gz: 31539fcff4b1d247c9cb6d7453acdd9faad80da9e189a8c47f074c6b9563efc0e87fb2def7cf9c54db9762f06512357ad9cf47fc978ddb6e40a6b0400cca3a44
7
- data.tar.gz: 10fe914139d2f6afc5cc0d06ea571057f9665bf848e0cc3a232ce8dad2b1e8a5938eb758436418b32d16525caf3731208840aebf583ad0aa04fbcb9eb91d49ef
6
+ metadata.gz: 02b2682ae4911e462be2c9e48622c0dca079916719a9b2ce519bae1d7945290a989572e16c8c21768201f811177ef5580d3077f2a0f50ce0225639a93c1c1b9a
7
+ data.tar.gz: 140ebcba6bbbd1056510bd8c231fe16b0e63a6d0a4209abb69701fdfc9d99b2a2655742e334880e31e3fbda55cf0a434d2dee1290a95a7513a5a64699bb5a288
data/exe/spectre CHANGED
@@ -48,6 +48,7 @@ DEFAULT_CONFIG = {
48
48
  },
49
49
  'debug' => false,
50
50
  'out_path' => './reports',
51
+ 'secure_keys' => ['password', 'secret', 'token', 'secure', 'authorization'],
51
52
  'spec_patterns' => ['./specs/**/*.spec.rb'],
52
53
  'mixin_patterns' => ['../common/mixins/**/*.mixin.rb', './mixins/**/*.mixin.rb'],
53
54
  'env_patterns' => ['./environments/**/*.env.yml'],
@@ -68,10 +69,6 @@ DEFAULT_CONFIG = {
68
69
  'spectre/http/basic_auth',
69
70
  'spectre/http/keystone',
70
71
  'spectre/resources',
71
- 'spectre/ssh',
72
- 'spectre/ftp',
73
- 'spectre/mysql',
74
- # 'spectre/postgres',
75
72
  ],
76
73
  'include' => [
77
74
 
@@ -102,7 +99,7 @@ Specific options:}
102
99
  cmd_options['specs'] = specs
103
100
  end
104
101
 
105
- opts.on('-t TAG,TAG', '--tags TAG,TAG', Array, 'Run only specs with give tags') do |tags|
102
+ opts.on('-t TAG,TAG', '--tags TAG,TAG', Array, 'Run only specs with given tags') do |tags|
106
103
  cmd_options['tags'] = tags
107
104
  end
108
105
 
@@ -126,12 +123,16 @@ Specific options:}
126
123
  cmd_options['colored'] = false
127
124
  end
128
125
 
126
+ opts.on('--ignore-failure', 'Always exit with code 0') do
127
+ cmd_options['ignore_failure'] = true
128
+ end
129
+
129
130
  opts.on('-o PATH', '--out PATH', 'Output directory path') do |path|
130
- cmd_options['out_path'] = path
131
+ cmd_options['out_path'] = File.absolute_path(path)
131
132
  end
132
133
 
133
- opts.on('-r NAME', '--reporter NAME', "The name of the reporter to use") do |reporter|
134
- cmd_options['reporter'] = reporter
134
+ opts.on('-r NAME', '--reporters NAME', Array, "A list of reporters to use") do |reporters|
135
+ cmd_options['reporters'] = reporters
135
136
  end
136
137
 
137
138
  opts.on('-d', '--debug', "Run in debug mode") do
@@ -147,7 +148,7 @@ Specific options:}
147
148
 
148
149
  curr_opt = cmd_options
149
150
  (key.split '.').each do |k|
150
- curr_opt[k] = {} if not curr_opt.has_key? k
151
+ curr_opt[k] = {} if not curr_opt.key? k
151
152
  end
152
153
  curr_opt = val
153
154
 
@@ -205,10 +206,11 @@ envs = {}
205
206
  read_env_files = {}
206
207
  cfg['env_patterns'].each do |pattern|
207
208
  Dir.glob(pattern).each do|f|
208
- spec_env = YAML.load_file(f)
209
- name = spec_env.delete('name') || 'default'
209
+ spec_env = YAML.load_file(f) || {}
210
210
 
211
- if envs.has_key? name
211
+ name = spec_env['name'] || 'default'
212
+
213
+ if envs.key? name
212
214
  existing_env_file = read_env_files[name]
213
215
  puts "Duplicate environment definition detected with name #{name} in '#{f}'. Previously defined in '#{existing_env_file}'"
214
216
  exit 1
@@ -224,7 +226,7 @@ cfg['env_partial_patterns'].each do |pattern|
224
226
  Dir.glob(pattern).each do|f|
225
227
  partial_env = YAML.load_file(f)
226
228
  name = partial_env.delete('name') || 'default'
227
- next if not envs.has_key? name
229
+ next if not envs.key? name
228
230
 
229
231
  envs[name].deep_merge! partial_env
230
232
  end
@@ -295,7 +297,7 @@ if action == 'run'
295
297
  })
296
298
 
297
299
  log_dir = File.dirname cfg['log_file']
298
- Dir.mkdir log_dir if !Dir.exists? log_dir
300
+ FileUtils.makedirs log_dir if !Dir.exists? log_dir
299
301
 
300
302
  # Load Modules
301
303
  cfg['modules']
@@ -303,12 +305,19 @@ if action == 'run'
303
305
  .select { |mod| !cfg['exclude'].include? mod }
304
306
  .each do |mod|
305
307
  begin
306
- if !File.exists? mod
307
- require_relative File.join('../lib', mod)
308
- else
308
+ spectre_lib_mod = File.join('../lib', mod)
309
+
310
+ if File.exists? mod
309
311
  require_relative mod
312
+
313
+ elsif File.exists? spectre_lib_mod
314
+ require_relative spectre_lib_mod
315
+
316
+ else
317
+ require mod
310
318
  end
311
- rescue => e
319
+
320
+ rescue LoadError => e
312
321
  puts "Unable to load module #{mod}. Check if the module exists or remove it from your spectre config:\n#{e.message}"
313
322
  exit 1
314
323
  end
@@ -337,7 +346,11 @@ if action == 'run'
337
346
  reporter.report(run_infos)
338
347
  end
339
348
 
340
- exit 0
349
+ errors = run_infos.select { |x| x.error != nil or x.failure != nil }
350
+
351
+ exit 0 if cfg['ignore_failure'] or errors.count == 0
352
+
353
+ exit 1
341
354
  end
342
355
 
343
356
 
@@ -464,6 +477,16 @@ reports/
464
477
  **/environments/*.env.secret.yml
465
478
  ]
466
479
 
480
+ DEFAULT_GEMFILE = %[source 'https://rubygems.org'
481
+
482
+ gem 'spectre-core', '>= #{Spectre::VERSION}'
483
+ # gem 'spectre-mysql', '>= 1.0.0'
484
+ # gem 'spectre-ssh', '>= 1.0.0'
485
+ # gem 'spectre-ftp', '>= 1.0.0'
486
+ # gem 'spectre-curl', '>= 1.0.0'
487
+ # gem 'spectre-git', '>= 0.1.0'
488
+ ]
489
+
467
490
  if action == 'init'
468
491
  DEFAULT_FILES = [
469
492
  ['./environments/default.env.yml', DEFAULT_ENV_CFG],
@@ -471,6 +494,7 @@ if action == 'init'
471
494
  ['./specs/sample.spec.rb', SAMPLE_SPEC],
472
495
  ['./spectre.yml', DEFAULT_SPECTRE_CFG],
473
496
  ['./.gitignore', DEFAULT_GITIGNORE],
497
+ ['./Gemfile', DEFAULT_GEMFILE],
474
498
  ]
475
499
 
476
500
  %w(environments logs specs).each do |dir_name|
data/lib/spectre.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Spectre
2
2
  module Version
3
3
  MAJOR = 1
4
- MINOR = 8
4
+ MINOR = 9
5
5
  TINY = 0
6
6
  end
7
7
 
data/lib/spectre/curl.rb CHANGED
@@ -159,7 +159,7 @@ module Spectre::Curl
159
159
  'use_ssl' => secure,
160
160
  }
161
161
 
162
- if @@http_cfg.has_key? name
162
+ if @@http_cfg.key? name
163
163
  req.merge! @@http_cfg[name]
164
164
  raise "No `base_url' set for HTTP client '#{name}'. Check your HTTP config in your environment." if !req['base_url']
165
165
  else
@@ -355,7 +355,7 @@ module Spectre::Curl
355
355
 
356
356
  @@curl_path = config['curl_path'] || 'curl'
357
357
 
358
- if config.has_key? 'http'
358
+ if config.key? 'http'
359
359
  @@http_cfg = {}
360
360
 
361
361
  config['http'].each do |name, cfg|
@@ -17,12 +17,22 @@ class ::String
17
17
  file_content = File.read(self)
18
18
 
19
19
  if with
20
- with.each do |key, value|
21
- file_content = file_content.gsub '#{' + key.to_s + '}', value.to_s
22
- end
20
+ file_content.with(with)
21
+ else
22
+ file_content
23
+ end
24
+ end
25
+
26
+ def with mapping
27
+ return self unless mapping and mapping.is_a? Hash
28
+
29
+ new_string = self
30
+
31
+ mapping.each do |key, value|
32
+ new_string = new_string.gsub '#{' + key.to_s + '}', value.to_s
23
33
  end
24
34
 
25
- file_content
35
+ new_string
26
36
  end
27
37
 
28
38
  def exists?
@@ -35,9 +45,9 @@ class ::String
35
45
  File.delete self
36
46
  end
37
47
 
38
- def trim count=50
48
+ def trim count = 50
39
49
  if (self.length + 3) > count
40
- return self[0..count] + '...'
50
+ return self[0..count-4] + '...'
41
51
  end
42
52
 
43
53
  self
@@ -60,5 +70,5 @@ end
60
70
 
61
71
 
62
72
  def uuid length = 5
63
- SecureRandom.uuid().gsub('-', '')[0..length]
73
+ SecureRandom.uuid().gsub('-', '')[0..length-1]
64
74
  end
data/lib/spectre/http.rb CHANGED
@@ -62,8 +62,7 @@ module Spectre
62
62
  end
63
63
 
64
64
  def body body_content
65
- raise 'Body value must be a string' if not body_content.is_a? String
66
- @__req['body'] = body_content
65
+ @__req['body'] = body_content.to_s
67
66
  end
68
67
 
69
68
  def ensure_success!
@@ -102,6 +101,7 @@ module Spectre
102
101
  end
103
102
 
104
103
  def [] key
104
+ return nil if not @headers.has_key?(key.downcase)
105
105
  @headers[key.downcase].first
106
106
  end
107
107
 
@@ -166,6 +166,7 @@ module Spectre
166
166
  @@response = nil
167
167
  @@request = nil
168
168
  @@modules = []
169
+ @@secure_keys = []
169
170
 
170
171
  def https name, &block
171
172
  http(name, secure: true, &block)
@@ -174,7 +175,7 @@ module Spectre
174
175
  def http name, secure: nil, &block
175
176
  req = {}
176
177
 
177
- if @@http_cfg.has_key? name
178
+ if @@http_cfg.key? name
178
179
  req.merge! @@http_cfg[name]
179
180
  raise "No `base_url' set for HTTP client '#{name}'. Check your HTTP config in your environment." if !req['base_url']
180
181
  else
@@ -209,20 +210,35 @@ module Spectre
209
210
  return str unless str or str.empty?
210
211
 
211
212
  begin
212
- json = JSON.parse str
213
+ json = JSON.parse(str)
214
+ json.obfuscate!(@@secure_keys) if not @@debug
213
215
 
214
216
  if pretty
215
217
  str = JSON.pretty_generate(json)
216
218
  else
217
219
  str = JSON.dump(json)
218
220
  end
219
- rescue
220
- # do nothing
221
+ # rescue => e
222
+ # # do nothing
223
+ # @@logger.error(e)
221
224
  end
222
225
 
223
226
  str
224
227
  end
225
228
 
229
+ def is_secure? key
230
+ @@secure_keys.any? { |x| key.to_s.downcase.include? x.downcase }
231
+ end
232
+
233
+ def header_to_s headers
234
+ s = ''
235
+ headers.each_header.each do |header, value|
236
+ value = '*****' if is_secure?(header) and not @@debug
237
+ s += "#{header.to_s.ljust(30, '.')}: #{value.to_s}\n"
238
+ end
239
+ s
240
+ end
241
+
226
242
  def invoke req
227
243
  @@request = nil
228
244
 
@@ -254,7 +270,7 @@ module Spectre
254
270
  if uri.scheme == 'https'
255
271
  net_http.use_ssl = true
256
272
 
257
- if req.has_key? 'cert'
273
+ if req.key? 'cert'
258
274
  raise "Certificate '#{req['cert']}' does not exist" unless File.exists? req['cert']
259
275
  net_http.verify_mode = OpenSSL::SSL::VERIFY_PEER
260
276
  net_http.ca_file = req['cert']
@@ -275,28 +291,28 @@ module Spectre
275
291
 
276
292
  req_id = SecureRandom.uuid()[0..5]
277
293
 
294
+ # Run HTTP modules
295
+
296
+ @@modules.each do |mod|
297
+ mod.on_req(net_http, net_req, req) if mod.respond_to? :on_req
298
+ end
299
+
278
300
  # Log request
279
301
 
280
- req_log = "[>] #{req_id} #{req['method']} #{uri}"
281
- req['headers'].each do |header|
282
- req_log += "\n#{header[0].to_s.ljust(30, '.')}: #{header[1].to_s}"
283
- end if req['headers']
284
- req_log += "\n" + try_format_json(req['body'], pretty: true) if req['body'] != nil and not req['body'].empty?
302
+ req_log = "[>] #{req_id} #{req['method']} #{uri}\n"
303
+ req_log += header_to_s(net_req)
304
+ req_log += try_format_json(req['body'], pretty: true) if req['body'] != nil and not req['body'].empty?
285
305
 
286
306
  @@logger.info req_log
287
307
 
288
308
  # Request
289
309
 
290
310
  start_time = Time.now
291
-
292
- @@modules.each do |mod|
293
- mod.on_req(net_http, net_req, req) if mod.respond_to? :on_req
294
- end
295
-
296
311
  net_res = net_http.request(net_req)
297
-
298
312
  end_time = Time.now
299
313
 
314
+ # Run HTTP modules
315
+
300
316
  @@modules.each do |mod|
301
317
  mod.on_res(net_http, net_res, req) if mod.respond_to? :on_res
302
318
  end
@@ -304,9 +320,7 @@ module Spectre
304
320
  # Log response
305
321
 
306
322
  res_log = "[<] #{req_id} #{net_res.code} #{net_res.message} (#{end_time - start_time}s)\n"
307
- net_res.each_header do |header, value|
308
- res_log += "#{header.to_s.ljust(30, '.')}: #{value}\n"
309
- end
323
+ res_log += header_to_s(net_res)
310
324
  res_log += try_format_json(net_res.body, pretty: true) if net_res.body != nil and !net_res.body.empty?
311
325
 
312
326
  @@logger.info(res_log)
@@ -328,8 +342,10 @@ module Spectre
328
342
 
329
343
  Spectre.register do |config|
330
344
  @@logger = ::Logger.new config['log_file'], progname: 'spectre/http'
345
+ @@secure_keys = config['secure_keys'] || []
346
+ @@debug = config['debug']
331
347
 
332
- if config.has_key? 'http'
348
+ if config.key? 'http'
333
349
  @@http_cfg = {}
334
350
 
335
351
  config['http'].each do |name, cfg|
@@ -1,7 +1,7 @@
1
1
  module Spectre::Http
2
2
  class SpectreHttpRequest
3
3
  def basic_auth username, password
4
- @__req['basic_auth'] = {} if not @__req.has_key? 'basic_auth'
4
+ @__req['basic_auth'] = {} if not @__req.key? 'basic_auth'
5
5
 
6
6
  @__req['basic_auth']['username'] = username
7
7
  @__req['basic_auth']['password'] = password
@@ -12,7 +12,7 @@ module Spectre::Http
12
12
 
13
13
  module BasicAuth
14
14
  def self.on_req http, net_req, req
15
- return unless req.has_key? 'basic_auth' and req['auth'] == 'basic_auth'
15
+ return unless req.key? 'basic_auth' and req['auth'] == 'basic_auth'
16
16
  basic_auth_cfg = req['basic_auth']
17
17
  net_req.basic_auth(basic_auth_cfg['username'], basic_auth_cfg['password'])
18
18
  end
@@ -1,6 +1,6 @@
1
1
  class HttpRequest
2
2
  def keystone url, username, password, project, domain, cert
3
- @__req['keystone'] = {} if not @__req.has_key? 'keystone'
3
+ @__req['keystone'] = {} if not @__req.key? 'keystone'
4
4
 
5
5
  @__req['keystone']['url'] = url
6
6
  @__req['keystone']['username'] = username
@@ -18,11 +18,11 @@ module Spectre::Http::Keystone
18
18
  @@cache = {}
19
19
 
20
20
  def self.on_req http, net_req, req
21
- return unless req.has_key? 'keystone' and req['auth'] == 'keystone'
21
+ return unless req.key? 'keystone' and req['auth'] == 'keystone'
22
22
 
23
23
  keystone_cfg = req['keystone']
24
24
 
25
- if @@cache.has_key? keystone_cfg
25
+ if @@cache.key? keystone_cfg
26
26
  token = @@cache[keystone_cfg]
27
27
  else
28
28
  token, _ = authenticate(
@@ -4,7 +4,7 @@ module Spectre
4
4
  module Logger
5
5
  class Console
6
6
  def initialize config
7
- raise 'No log format section in config for console logger' unless config.has_key? 'log_format' and config['log_format'].has_key? 'console'
7
+ raise 'No log format section in config for console logger' unless config.key? 'log_format' and config['log_format'].key? 'console'
8
8
 
9
9
  @config = config['log_format']['console']
10
10
  @indent = @config['indent'] || 2
@@ -2,7 +2,7 @@ module Spectre
2
2
  module Logger
3
3
  class File
4
4
  def initialize config
5
- raise 'No log format section in config for console logger' unless config.has_key? 'log_format' and config['log_format'].has_key? 'file'
5
+ raise 'No log format section in config for console logger' unless config.key? 'log_format' and config['log_format'].key? 'file'
6
6
 
7
7
  @config = config['log_format']['file']
8
8
  @fmt_start_group = @config['start_group']
data/lib/spectre/mixin.rb CHANGED
@@ -10,7 +10,7 @@ module Spectre
10
10
  end
11
11
 
12
12
  def run desc, with: []
13
- raise "no mixin with desc '#{desc}' defined" unless @@mixins.has_key? desc
13
+ raise "no mixin with desc '#{desc}' defined" unless @@mixins.key? desc
14
14
  Logger.log_debug "running mixin '#{desc}'"
15
15
 
16
16
  if with.is_a? Array
@@ -25,7 +25,7 @@ module Spectre
25
25
  end
26
26
 
27
27
  Spectre.register do |config|
28
- if not config.has_key? 'mixin_patterns'
28
+ if not config.key? 'mixin_patterns'
29
29
  return
30
30
  end
31
31
 
@@ -12,7 +12,7 @@ module Spectre
12
12
  end
13
13
 
14
14
  def [] name
15
- raise "Resource with name '#{name}' does not exist" if not @items.has_key? name
15
+ raise "Resource with name '#{name}' does not exist" if not @items.key? name
16
16
  @items[name]
17
17
  end
18
18
  end
@@ -26,7 +26,7 @@ module Spectre
26
26
  end
27
27
 
28
28
  Spectre.register do |config|
29
- return if !config.has_key? 'resource_paths'
29
+ return if !config.key? 'resource_paths'
30
30
 
31
31
  config['resource_paths'].each do |resource_path|
32
32
  resource_files = Dir.glob File.join(resource_path, '**/*')
metadata CHANGED
@@ -1,85 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spectre-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Neubauer
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-14 00:00:00.000000000 Z
11
+ date: 2021-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ectoplasm
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.1.0
19
+ version: 1.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.1.0
27
- - !ruby/object:Gem::Dependency
28
- name: openssl
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 2.2.0
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 2.2.0
41
- - !ruby/object:Gem::Dependency
42
- name: net-ssh
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 6.1.0
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 6.1.0
55
- - !ruby/object:Gem::Dependency
56
- name: net-sftp
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 3.0.0
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 3.0.0
69
- - !ruby/object:Gem::Dependency
70
- name: mysql2
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 0.5.3
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 0.5.3
26
+ version: 1.2.0
83
27
  description: A DSL and command line tool to describe and run automated tests
84
28
  email:
85
29
  - me@christianneubauer.de
@@ -93,10 +37,8 @@ files:
93
37
  - lib/spectre/assertion.rb
94
38
  - lib/spectre/bag.rb
95
39
  - lib/spectre/curl.rb
96
- - lib/spectre/database/postgres.rb
97
40
  - lib/spectre/diagnostic.rb
98
41
  - lib/spectre/environment.rb
99
- - lib/spectre/ftp.rb
100
42
  - lib/spectre/helpers.rb
101
43
  - lib/spectre/http.rb
102
44
  - lib/spectre/http/basic_auth.rb
@@ -105,20 +47,18 @@ files:
105
47
  - lib/spectre/logger/console.rb
106
48
  - lib/spectre/logger/file.rb
107
49
  - lib/spectre/mixin.rb
108
- - lib/spectre/mysql.rb
109
50
  - lib/spectre/reporter/console.rb
110
51
  - lib/spectre/reporter/junit.rb
111
52
  - lib/spectre/resources.rb
112
- - lib/spectre/ssh.rb
113
- homepage: https://bitbucket.org/cneubaur/spectre-core
53
+ homepage: https://github.com/cneubauer/spectre-core
114
54
  licenses:
115
55
  - MIT
116
56
  metadata:
117
57
  allowed_push_host: https://rubygems.org/
118
- homepage_uri: https://bitbucket.org/cneubaur/spectre-core
119
- source_code_uri: https://bitbucket.org/cneubaur/spectre-core
120
- changelog_uri: https://bitbucket.org/cneubaur/spectre-core/src/master/CHANGELOG.md
121
- post_install_message:
58
+ homepage_uri: https://github.com/cneubauer/spectre-core
59
+ source_code_uri: https://github.com/cneubauer/spectre-core
60
+ changelog_uri: https://github.com/cneubauer/spectre-core/blob/master/CHANGELOG.md
61
+ post_install_message:
122
62
  rdoc_options: []
123
63
  require_paths:
124
64
  - lib
@@ -133,8 +73,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
73
  - !ruby/object:Gem::Version
134
74
  version: '0'
135
75
  requirements: []
136
- rubygems_version: 3.2.3
137
- signing_key:
76
+ rubygems_version: 3.0.8
77
+ signing_key:
138
78
  specification_version: 4
139
79
  summary: Describe and run automated tests
140
80
  test_files: []
@@ -1,78 +0,0 @@
1
- require 'pg'
2
-
3
-
4
- class PG::Result
5
- alias :count :ntuples
6
- end
7
-
8
-
9
- module Spectre
10
- module Database
11
- module Postgres
12
- @@modules = []
13
-
14
- class SQLStatement
15
- attr_accessor :query, :params
16
-
17
- def initialize
18
- @query = nil
19
- @params = []
20
- end
21
-
22
- def statement query
23
- @query = query
24
- end
25
-
26
- def param val
27
- @params << val
28
- end
29
- end
30
-
31
-
32
- class << self
33
- def postgres name, &block
34
- raise "postgres '#{name}' not configured" unless @@db_cfg.has_key? name
35
-
36
- statement = SQLStatement.new
37
- statement.instance_eval &block
38
-
39
- cfg = @@db_cfg[name]
40
-
41
- begin
42
- con = PG.connect({
43
- host: cfg['host'],
44
- port: cfg['port'],
45
- dbname: cfg['database'],
46
- user: cfg['username'],
47
- password: cfg['username'],
48
- })
49
-
50
- if statement.params
51
- @@result = con.exec_params(statement.query, statement.params)
52
- else
53
- @@result = con.exec(statement.query)
54
- end
55
-
56
- ensure
57
- con.close if con
58
- end
59
- end
60
-
61
-
62
- def result
63
- @@result
64
- end
65
- end
66
-
67
- Spectre.register do |config|
68
- @@db_cfg = {}
69
-
70
- config['postgres'].each do |name, cfg|
71
- @@db_cfg[name] = cfg
72
- end
73
- end
74
-
75
- Spectre.delegate :postgres, :result, to: self
76
- end
77
- end
78
- end
data/lib/spectre/ftp.rb DELETED
@@ -1,195 +0,0 @@
1
- require 'net/ftp'
2
- require 'net/sftp'
3
- require 'logger'
4
- require 'json'
5
-
6
-
7
- module Spectre
8
- module FTP
9
- @@cfg = {}
10
-
11
- class FTPConnection < DslClass
12
- def initialize host, username, password, opts, logger
13
- @__logger = logger
14
- @__session = nil
15
-
16
- @__host = host
17
- @__username = username
18
- @__password = password
19
- @__opts = opts
20
- end
21
-
22
- def connect!
23
- return unless @__session == nil or @__session.closed?
24
- @__logger.info "Connecting to '#{@__host}' with user '#{@__username}'"
25
- @__session = Net::FTP.new(@__host, @__opts)
26
- @__session.login @__username, @__password
27
- end
28
-
29
- def close
30
- return unless @__session and not @__session.closed?
31
- @__session.close
32
- end
33
-
34
- def can_connect?
35
- begin
36
- connect!
37
- return true
38
- rescue
39
- return false
40
- end
41
- end
42
-
43
- def download remotefile, to: File.basename(remotefile)
44
- connect!
45
- @__logger.info "Downloading '#{@__username}@#{@__host}:#{File.join @__session.pwd, remotefile}' to '#{File.expand_path to}'"
46
- @__session.getbinaryfile(remotefile, to)
47
- end
48
-
49
- def upload localfile, to: File.basename(localfile)
50
- connect!
51
- @__logger.info "Uploading '#{File.expand_path localfile}' to '#{@__username}@#{@__host}:#{File.join @__session.pwd, to}'"
52
- @__session.putbinaryfile(localfile, to)
53
- end
54
-
55
- def list
56
- connect!
57
- file_list = @__session.list
58
- @__logger.info "Listing file in #{@__session.pwd}\n#{file_list}"
59
- file_list
60
- end
61
- end
62
-
63
-
64
- class SFTPConnection < DslClass
65
- def initialize host, username, opts, logger
66
- opts[:non_interactive] = true
67
-
68
- @__logger = logger
69
- @__session = nil
70
- @__host = host
71
- @__username = username
72
- @__opts = opts
73
- end
74
-
75
- def connect!
76
- return unless @__session == nil or @__session.closed?
77
- @__logger.info "Connecting to '#{@__host}' with user '#{@__username}'"
78
- @__session = Net::SFTP.start(@__host, @__username, @__opts)
79
- @__session.connect!
80
- end
81
-
82
- def close
83
- return unless @__session and not @__session.closed?
84
- # @__session.close!
85
- end
86
-
87
- def can_connect?
88
- begin
89
- connect!
90
- return true
91
- rescue
92
- return false
93
- end
94
- end
95
-
96
- def download remotefile, to: File.basename(remotefile)
97
- @__logger.info "Downloading '#{@__username}@#{@__host}:#{remotefile}' to '#{File.expand_path to}'"
98
- connect!
99
- @__session.download!(remotefile, to)
100
- end
101
-
102
- def upload localfile, to: File.basename(localfile)
103
- @__logger.info "Uploading '#{File.expand_path localfile}' to '#{@__username}@#{@__host}:#{to}'"
104
- connect!
105
- @__session.upload!(localfile, to)
106
- end
107
-
108
- def stat path
109
- connect!
110
- file_info = @__session.stat! path
111
- @__logger.info "Stat '#{path}'\n#{JSON.pretty_generate file_info.attributes}"
112
- file_info.attributes
113
- end
114
-
115
- def exists path
116
- begin
117
- file_info = @__session.stat! path
118
-
119
- rescue Net::SFTP::StatusException => e
120
- return false if e.description == 'no such file'
121
- raise e
122
- end
123
-
124
- return true
125
- end
126
- end
127
-
128
-
129
- class << self
130
- def ftp name, config={}, &block
131
- raise "FTP connection '#{name}' not configured" unless @@cfg.has_key?(name) or config.count > 0
132
- cfg = @@cfg[name] || {}
133
-
134
- host = config[:host] || cfg['host'] || name
135
- username = config[:username] || cfg['username']
136
- password = config[:password] || cfg['password']
137
-
138
- opts = {}
139
- opts[:ssl] = config[:ssl]
140
- opts[:port] = config[:port] || cfg['port'] || 21
141
-
142
- @@logger.info "Connecting to #{host} with user #{username}"
143
-
144
- ftp_conn = FTPConnection.new(host, username, password, opts, @@logger)
145
-
146
- begin
147
- ftp_conn.instance_eval &block
148
- ensure
149
- ftp_conn.close
150
- end
151
- end
152
-
153
- def sftp name, config={}, &block
154
- raise "FTP connection '#{name}' not configured" unless @@cfg.has_key?(name) or config.count > 0
155
-
156
- cfg = @@cfg[name] || {}
157
-
158
- host = config[:host] || cfg['host'] || name
159
- username = config[:username] || cfg['username']
160
- password = config[:password] || cfg['password']
161
-
162
- opts = {}
163
- opts[:password] = password
164
- opts[:port] = config[:port] || cfg['port'] || 22
165
- opts[:keys] = [cfg['key']] if cfg.has_key? 'key'
166
- opts[:passphrase] = cfg['passphrase'] if cfg.has_key? 'passphrase'
167
-
168
- opts[:auth_methods] = []
169
- opts[:auth_methods].push 'publickey' if opts[:keys]
170
- opts[:auth_methods].push 'password' if opts[:password]
171
-
172
- sftp_con = SFTPConnection.new(host, username, opts, @@logger)
173
-
174
- begin
175
- sftp_con.instance_eval &block
176
- ensure
177
- sftp_con.close
178
- end
179
- end
180
- end
181
-
182
- Spectre.register do |config|
183
- @@logger = ::Logger.new config['log_file'], progname: 'spectre/ftp'
184
-
185
- if config.has_key? 'ftp'
186
-
187
- config['ftp'].each do |name, cfg|
188
- @@cfg[name] = cfg
189
- end
190
- end
191
- end
192
-
193
- Spectre.delegate :ftp, :sftp, to: self
194
- end
195
- end
data/lib/spectre/mysql.rb DELETED
@@ -1,97 +0,0 @@
1
- require 'mysql2'
2
-
3
- module Spectre
4
- module MySQL
5
-
6
- class MySqlQuery < DslClass
7
- def initialize query
8
- @__query = query
9
- end
10
-
11
- def host hostname
12
- @__query['host'] = hostname
13
- end
14
-
15
- def username user
16
- @__query['username'] = user
17
- end
18
-
19
- def password pass
20
- @__query['password'] = pass
21
- end
22
-
23
- def database name
24
- @__query['database'] = name
25
- end
26
-
27
- def query statement
28
- @__query['query'] = [] if not @__query.has_key? 'query'
29
- @__query['query'].append(statement)
30
- end
31
- end
32
-
33
- class << self
34
- @@mysql_cfg = {}
35
- @@result = nil
36
- @@last_conn = nil
37
-
38
- def mysql name = nil, &block
39
- query = {}
40
-
41
- if name != nil and @@mysql_cfg.has_key? name
42
- query.merge! @@mysql_cfg[name]
43
- raise "No `host' set for MySQL client '#{name}'. Check your MySQL config in your environment." if !query['host']
44
- elsif name != nil
45
- query['host'] = name
46
- elsif @@last_conn == nil
47
- raise 'No name given and there was no previous MySQL connection to use'
48
- end
49
-
50
- MySqlQuery.new(query).instance_eval(&block) if block_given?
51
-
52
- if name != nil
53
- @@last_conn = {
54
- host: query['host'],
55
- username: query['username'],
56
- password: query['password'],
57
- database: query['database']
58
- }
59
- end
60
-
61
- @@logger.info "Connecting to database #{query['username']}@#{query['host']}:#{query['database']}"
62
-
63
- client = ::Mysql2::Client.new(**@@last_conn)
64
-
65
- res = []
66
-
67
- query['query'].each do |statement|
68
- @@logger.info 'Executing statement "' + statement + '"'
69
- res = client.query(statement, cast_booleans: true)
70
- end if query['query']
71
-
72
- @@result = res.map { |row| OpenStruct.new row } if res
73
-
74
- client.close
75
- end
76
-
77
- def result
78
- raise 'No MySQL query has been executed yet' unless @@result
79
- @@result
80
- end
81
- end
82
-
83
- Spectre.register do |config|
84
- @@logger = ::Logger.new config['log_file'], progname: 'spectre/mysql'
85
-
86
- if config.has_key? 'mysql'
87
- @@mysql_cfg = {}
88
-
89
- config['mysql'].each do |name, cfg|
90
- @@mysql_cfg[name] = cfg
91
- end
92
- end
93
- end
94
-
95
- Spectre.delegate :mysql, :result, to: self
96
- end
97
- end
data/lib/spectre/ssh.rb DELETED
@@ -1,149 +0,0 @@
1
- require 'net/ssh'
2
- require 'logger'
3
-
4
-
5
- module Spectre
6
- module SSH
7
- @@cfg = {}
8
-
9
- class SSHConnection < DslClass
10
- def initialize host, username, opts, logger
11
- opts[:non_interactive] = true
12
-
13
- @__logger = logger
14
- @__host = host
15
- @__username = username
16
- @__opts = opts
17
- @__session = nil
18
- @__exit_code = nil
19
- @__output = ''
20
- end
21
-
22
- def file_exists path
23
- exec "ls #{path}"
24
- exit_code == 0
25
- end
26
-
27
- def owner_of path
28
- exec "stat -c %U #{path}"
29
- output.chomp
30
- end
31
-
32
- def connect!
33
- return unless @__session == nil or @__session.closed?
34
- @__session = Net::SSH.start(@__host, @__username, @__opts)
35
- end
36
-
37
- def close
38
- return unless @__session and not @__session.closed?
39
- @__session.close
40
- end
41
-
42
- def can_connect?
43
- @__output = nil
44
-
45
- begin
46
- connect!
47
- @__session.open_channel.close
48
- @__output = "successfully connected to #{@__host} with user #{@__username}"
49
- @__exit_code = 0
50
- return true
51
- rescue Exception => e
52
- @__logger.error e.message
53
- @__output = "unable to connect to #{@__host} with user #{@__username}"
54
- @__exit_code = 1
55
- end
56
-
57
- return false
58
- end
59
-
60
- def exec command
61
- connect!
62
-
63
- log_str = "#{@__session.options[:user]}@#{@__session.host} -p #{@__session.options[:port]} #{command}"
64
-
65
- @channel = @__session.open_channel do |channel|
66
- channel.exec(command) do |ch, success|
67
- abort "could not execute #{command} on #{@__session.host}" unless success
68
-
69
- @__output = ''
70
-
71
- channel.on_data do |ch, data|
72
- @__output += data
73
- end
74
-
75
- channel.on_extended_data do |ch,type,data|
76
- @__output += data
77
- end
78
-
79
- channel.on_request('exit-status') do |ch, data|
80
- @__exit_code = data.read_long
81
- end
82
-
83
- # channel.on_request('exit-signal') do |ch, data|
84
- # exit_code = data.read_long
85
- # end
86
- end
87
-
88
- end
89
-
90
- @channel.wait
91
- @__session.loop
92
-
93
- log_str += "\n" + @__output
94
- @__logger.info log_str
95
- end
96
-
97
- def output
98
- @__output
99
- end
100
-
101
- def exit_code
102
- @__exit_code
103
- end
104
- end
105
-
106
-
107
- class << self
108
- def ssh name, config = {}, &block
109
- raise "SSH connection '#{name}' not configured" unless @@cfg.has_key?(name) or config.count > 0
110
-
111
- cfg = @@cfg[name] || {}
112
-
113
- host = cfg['host'] || name
114
- username = config[:username] || cfg['username']
115
- password = config[:password] || cfg['password']
116
-
117
- opts = {}
118
- opts[:password] = password
119
- opts[:port] = config[:port] || cfg['port'] || 22
120
- opts[:keys] = [cfg['key']] if cfg.has_key? 'key'
121
- opts[:passphrase] = cfg['passphrase'] if cfg.has_key? 'passphrase'
122
-
123
- opts[:auth_methods] = []
124
- opts[:auth_methods].push 'publickey' if opts[:keys]
125
- opts[:auth_methods].push 'password' if opts[:password]
126
-
127
- ssh_con = SSHConnection.new(host, username, opts, @@logger)
128
-
129
- begin
130
- ssh_con.instance_eval &block
131
- ensure
132
- ssh_con.close
133
- end
134
- end
135
- end
136
-
137
- Spectre.register do |config|
138
- @@logger = ::Logger.new config['log_file'], progname: 'spectre/ssh'
139
-
140
- if config.has_key? 'ssh'
141
- config['ssh'].each do |name, cfg|
142
- @@cfg[name] = cfg
143
- end
144
- end
145
- end
146
-
147
- Spectre.delegate :ssh, to: self
148
- end
149
- end