teuton 2.1.10 → 2.3.1

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -12
  3. data/bin/check_teuton +0 -2
  4. data/docs/changelog/ideas.md +132 -0
  5. data/docs/changelog/v2.1.md +14 -122
  6. data/docs/changelog/v2.2.md +52 -28
  7. data/docs/changelog/version2.1.md +4 -0
  8. data/docs/commands/README.md +58 -15
  9. data/docs/commands/example_check.md +0 -4
  10. data/docs/commands/example_run.md +0 -4
  11. data/docs/dsl/README.md +1 -1
  12. data/docs/dsl/definition/result.md +1 -0
  13. data/docs/dsl/definition/run_remote.md +12 -6
  14. data/docs/dsl/definition/target.md +9 -10
  15. data/docs/dsl/execution/export.md +27 -20
  16. data/docs/install/README.md +13 -18
  17. data/docs/install/vagrant_docker.md +1 -1
  18. data/docs/learn/README.md +8 -8
  19. data/docs/learn/example-01-target.md +25 -25
  20. data/docs/learn/example-02-config.md +38 -49
  21. data/docs/learn/example-03-remote-hosts.md +22 -22
  22. data/docs/learn/{example-11-first-test.md → example-04-new-test.md} +23 -24
  23. data/docs/learn/{example-04-use.md → example-05-use.md} +6 -6
  24. data/docs/learn/{example-05-debug.md → example-06-debug.md} +8 -8
  25. data/docs/learn/{example-06-log.md → example-07-log.md} +7 -7
  26. data/docs/learn/example-08-readme.md +59 -0
  27. data/docs/learn/example-09-preserve.md +41 -0
  28. data/docs/videos.md +19 -0
  29. data/lib/teuton/application.rb +22 -3
  30. data/lib/teuton/case_manager/case/builtin/main.rb +3 -19
  31. data/lib/teuton/case_manager/case/builtin/package.rb +7 -6
  32. data/lib/teuton/case_manager/case/builtin/service.rb +9 -8
  33. data/lib/teuton/case_manager/case/builtin/teuton_file.rb +28 -0
  34. data/lib/teuton/case_manager/case/builtin/teuton_host.rb +31 -0
  35. data/lib/teuton/case_manager/case/builtin/user.rb +8 -7
  36. data/lib/teuton/case_manager/case/case.rb +1 -1
  37. data/lib/teuton/case_manager/case/dsl/goto.rb +2 -2
  38. data/lib/teuton/case_manager/case/dsl/log.rb +1 -1
  39. data/lib/teuton/case_manager/case/dsl/macro.rb +4 -1
  40. data/lib/teuton/case_manager/case/dsl/send.rb +2 -1
  41. data/lib/teuton/case_manager/case/play.rb +2 -0
  42. data/lib/teuton/case_manager/case/result/ext_compare.rb +16 -0
  43. data/lib/teuton/case_manager/case/result/result.rb +1 -1
  44. data/lib/teuton/case_manager/case/runner.rb +30 -4
  45. data/lib/teuton/case_manager/case_manager.rb +1 -1
  46. data/lib/teuton/case_manager/dsl.rb +10 -0
  47. data/lib/teuton/case_manager/export_manager.rb +24 -5
  48. data/lib/teuton/case_manager/utils.rb +1 -1
  49. data/lib/teuton/{project/laboratory → check}/builtin.rb +0 -0
  50. data/lib/teuton/{project/laboratory → check}/dsl.rb +40 -28
  51. data/lib/teuton/{project/laboratory → check}/laboratory.rb +3 -8
  52. data/lib/teuton/{project/laboratory → check}/show.rb +53 -59
  53. data/lib/teuton/cli.rb +85 -14
  54. data/lib/teuton/{project/readme → readme}/dsl.rb +0 -0
  55. data/lib/teuton/{project/readme → readme}/lang.rb +1 -1
  56. data/lib/teuton/{project/readme → readme}/readme.rb +22 -18
  57. data/lib/teuton/report/formatter/array_formatter.rb +13 -1
  58. data/lib/teuton/report/formatter/base_formatter.rb +18 -5
  59. data/lib/teuton/{project/skeleton.rb → skeleton.rb} +7 -18
  60. data/lib/teuton/utils/configfile_reader.rb +121 -0
  61. data/lib/teuton/{project → utils}/name_file_finder.rb +46 -26
  62. data/lib/teuton/version.rb +8 -0
  63. data/lib/teuton.rb +39 -32
  64. metadata +109 -62
  65. data/lib/teuton/case_manager/case/dsl/deprecated.rb +0 -14
  66. data/lib/teuton/cli/check.rb +0 -38
  67. data/lib/teuton/cli/main.rb +0 -6
  68. data/lib/teuton/cli/play.rb +0 -38
  69. data/lib/teuton/cli/readme.rb +0 -26
  70. data/lib/teuton/cli/version.rb +0 -12
  71. data/lib/teuton/files/gitignore +0 -2
  72. data/lib/teuton/project/configfile_reader.rb +0 -49
  73. data/lib/teuton/project/project.rb +0 -80
@@ -1,14 +1,14 @@
1
1
  [<< back](README.md)
2
2
 
3
- 1. [Definition section](#definition-section)
4
- 2. [Run test](#execution-section)
5
- 3. [Result](#result)
3
+ # Example: learn-07-log
6
4
 
7
- # Example: learn-06-log
5
+ > This example is on GitHub repository at `examples/learn-06-log/`.
8
6
 
9
7
  Let's learn how to create log messages.
10
8
 
11
- > This example is on GitHub repository at `examples/learn-06-log/`.
9
+ 1. [Definition section](#definition-section)
10
+ 2. [Run test](#execution-section)
11
+ 3. [Result](#result)
12
12
 
13
13
  ## Definition section
14
14
 
@@ -29,7 +29,7 @@ end
29
29
 
30
30
  ## Result
31
31
 
32
- **Let's see example**: Content of `var/learn-06-log/case-01.txt` file.
32
+ **Let's see example**: Content of `var/learn-07-log/case-01.txt` file.
33
33
 
34
34
  ```bash
35
35
  CONFIGURATION
@@ -37,7 +37,7 @@ CONFIGURATION
37
37
  | tt_members | anonymous |
38
38
  | tt_sequence | false |
39
39
  | tt_skip | false |
40
- | tt_testname | learn-06-log |
40
+ | tt_testname | learn-07-log |
41
41
  +-------------+--------------+
42
42
 
43
43
  LOGS
@@ -0,0 +1,59 @@
1
+ [<< back](README.md)
2
+
3
+ # Example: learn-07-readme
4
+
5
+ > This example is on GitHub repository at `examples/learn-08-readme/`.
6
+
7
+ Create README files (with test instructions) from our test definition.
8
+
9
+ 1. [Definition section](#definition-section)
10
+ 2. [Execute command](#execute-command)
11
+ 3. [Result](#result)
12
+
13
+ ## Definition section
14
+
15
+ Take a look at our test definition section (Group):
16
+ ```ruby
17
+ group "Customize readme output" do
18
+ readme "This is our README example."
19
+ readme "And here we'll see how to use readme keyword"
20
+
21
+ target "Create user david."
22
+ readme "Help: you can use 'useradd' command to create users."
23
+ readme "Remember: Only root is permitted to create new users."
24
+
25
+ run "id david"
26
+ expect "david"
27
+
28
+ end
29
+ ```
30
+
31
+ > In this example, localhost's OS must be GNU/Linux (any other compatible OS) because the command used is `id david`.
32
+
33
+ There exists some `readme` instructions after `group` and `target` lines.
34
+
35
+ ## Execute command
36
+
37
+ To generate automatically a README file from previous test, execute this:
38
+
39
+ ```
40
+ teuton readme example/learn-08-readme > example/learn-08-readme/README.md
41
+ ```
42
+
43
+ ## Result
44
+
45
+ **Let's see the output**: Content of `example/learn-08-readme/README.md` file.
46
+
47
+ ---
48
+ # learn-08-readme
49
+
50
+ ## Customize readme output
51
+
52
+ This is our README example.
53
+ And here we'll see how to use readme keyword
54
+
55
+ Go to [LOCALHOST](#required-hosts) host, and do next:
56
+ * Create user david.
57
+ * Help: you can use 'useradd' command to create users.
58
+ * Remember: Only root is permitted to create new users.
59
+ ---
@@ -0,0 +1,41 @@
1
+ [<< back](README.md)
2
+
3
+ # Example: learn-09-preserve
4
+
5
+ > This example is on GitHub repository at `examples/learn-09-preserve/`.
6
+
7
+ Older output report files are overwritten with new reports, every time we run teuton test. With `preserve` option we keep copies.
8
+
9
+ 1. [Execution section](#execution-section)
10
+ 2. [Result](#result)
11
+
12
+ ## Execution section
13
+
14
+ Take a look at our test execution section (Play):
15
+ ```ruby
16
+ play do
17
+ show
18
+ export preserve: true
19
+ end
20
+ ```
21
+
22
+ > More information about [export](../dsl/execution/export.md) keyword.
23
+ ## Result
24
+
25
+ Example, executing `teuton run example/learn-09-preserve` twice:
26
+
27
+ ```
28
+ var
29
+ └── learn-09-preserve
30
+ ├── 20200519-113035
31
+ │   ├── case-01.txt
32
+ │   ├── moodle.csv
33
+ │   └── resume.txt
34
+ ├── 20200520-113039
35
+ │   ├── case-01.txt
36
+ │   ├── moodle.csv
37
+ │   └── resume.txt
38
+ ├── case-01.txt
39
+ ├── moodle.csv
40
+ └── resume.txt
41
+ ```
data/docs/videos.md ADDED
@@ -0,0 +1,19 @@
1
+ [<< back](../README.md)
2
+
3
+ # News
4
+
5
+ * [Introducción a Teuton](https://elpuig.xeill.net/Members/vcarceler/articulos/introduccion-a-teuton): iniciarse en el uso de Teutón gracias al fantástico artículo de Víctor Carceler.
6
+ * [Verificar prácticas de GNS3 con Teuton](https://elpuig.xeill.net/Members/juanmorote/articulos/verificar-practicas-de-gns3-con-teuton): GNS3 es un excelente simulador de red Open Source que además se entiende con Teuton a las mil maravillas.
7
+
8
+ # Videos
9
+
10
+ Teuton en el 2016 se llamaba "sysadmingame".
11
+ * [CHAPI16 - Presentación sysadmingame chapi16 - Abril 2016](https://youtu.be/cNJaB5xzHHQ)
12
+ * sysadmingame:
13
+ 1. [Instalación del programa](https://youtu.be/dnyMq9_KDco)
14
+ 2. [Crear un caso simple](https://youtu.be/0e2g5Izvc6c)
15
+ 3. [Crear un caso complejo](https://youtu.be/ebEK6OXH8kQ)
16
+
17
+ Teuton:
18
+ * [Apuntes FP Informática - I Congreso Virtual - Mayo 2020](https://youtu.be/RxIV26BAoGo)
19
+ * [Teuton Software 2.1 - Tutorial - Oct 2020](https://youtu.be/cyBN-rOYQeY)
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'singleton'
4
+ require_relative 'version'
5
+ require_relative 'utils/name_file_finder'
4
6
 
5
7
  # This Singleton contains application params
6
8
  class Application
7
9
  include Singleton
8
-
9
- VERSION = '2.1.10' # Application version
10
- NAME = 'teuton' # Application name
10
+ include Teuton
11
11
 
12
12
  attr_reader :letter
13
13
  attr_reader :running_basedir, :output_basedir
@@ -71,4 +71,23 @@ class Application
71
71
 
72
72
  false
73
73
  end
74
+
75
+ ##
76
+ # Preprocess input options:
77
+ # * Convert input case options String to an Array of integers
78
+ # * Read color input option
79
+ # rubocop:disable Metrics/AbcSize
80
+ def add_input_params(projectpath, options)
81
+ @options.merge! options
82
+ NameFileFinder.find_filenames_for(projectpath)
83
+ @options['color'] = true if @options['color'].nil?
84
+ Rainbow.enabled = @options['color']
85
+ @options['panel'] = false if @options['panel'].nil?
86
+
87
+ return if @options['case'].nil?
88
+
89
+ a = @options['case'].split(',')
90
+ @options['case'] = a.collect!(&:to_i)
91
+ end
92
+ # rubocop:enable Metrics/AbcSize
74
93
  end
@@ -1,24 +1,8 @@
1
1
 
2
- require_relative 'package'
3
- require_relative 'service'
4
- require_relative 'user'
2
+ require_relative 'teuton_host'
5
3
 
6
4
  class Case
7
- def package(param)
8
- @package = @package || Package.new(self)
9
- @package.param = param
10
- @package
11
- end
12
-
13
- def service(param)
14
- @service = @service || Service.new(self)
15
- @service.param = param
16
- @service
17
- end
18
-
19
- def user(param)
20
- @user = @user || User.new(self)
21
- @user.param = param
22
- @user
5
+ def host(host = 'localhost')
6
+ TeutonHost.new(self, host)
23
7
  end
24
8
  end
@@ -1,20 +1,21 @@
1
1
 
2
2
  class Package
3
- attr_accessor :param
4
-
5
- def initialize(parent)
6
- @parent = parent
3
+ def initialize(teuton_host, param)
4
+ @teuton_host = teuton_host
5
+ @parent = teuton_host.parent
6
+ @host = teuton_host.host
7
+ @param = param
7
8
  end
8
9
 
9
10
  def installed?
10
11
  @parent.target("Package #{@param} installed?")
11
- @parent.run "whereis #{@param}"
12
+ @parent.run "whereis #{@param}", on: @host
12
13
  @parent.expect_one [ 'bin', @param ]
13
14
  end
14
15
 
15
16
  def not_installed?
16
17
  @parent.target("Package #{@param} not installed?")
17
- @parent.run "whereis #{@param}"
18
+ @parent.run "whereis #{@param}", on: @host
18
19
  @parent.expect_none [ 'bin' , @param ]
19
20
  end
20
21
  end
@@ -1,32 +1,33 @@
1
1
 
2
2
  class Service
3
- attr_accessor :param
4
-
5
- def initialize(parent)
6
- @parent = parent
3
+ def initialize(teuton_host, param)
4
+ @teuton_host = teuton_host
5
+ @parent = teuton_host.parent
6
+ @host = teuton_host.host
7
+ @param = param
7
8
  end
8
9
 
9
10
  def is_running?
10
11
  @parent.target("Service #{@param} is running?")
11
- @parent.run "systemctl status #{@param}"
12
+ @parent.run "systemctl status #{@param}", on: @host
12
13
  @parent.expect_one ['Active:', 'running' ]
13
14
  end
14
15
 
15
16
  def is_inactive?
16
17
  @parent.target("Service #{@param} is inactive?")
17
- @parent.run "systemctl status #{@param}"
18
+ @parent.run "systemctl status #{@param}", on: @host
18
19
  @parent.expect_one ['Active:', 'inactive' ]
19
20
  end
20
21
 
21
22
  def is_enable?
22
23
  @parent.target("Service #{@param} is enable?")
23
- @parent.run "systemctl status #{@param}"
24
+ @parent.run "systemctl status #{@param}", on: @host
24
25
  @parent.expect_one ['Loaded:', 'enable' ]
25
26
  end
26
27
 
27
28
  def is_disable?
28
29
  @parent.target("Service #{@param} is disable?")
29
- @parent.run "systemctl status #{@param}"
30
+ @parent.run "systemctl status #{@param}", on: @host
30
31
  @parent.expect_one ['Loaded:', 'disable' ]
31
32
  end
32
33
  end
@@ -0,0 +1,28 @@
1
+
2
+ class TeutonFile
3
+ def initialize(teuton_host, param)
4
+ @teuton_host = teuton_host
5
+ @parent = teuton_host.parent
6
+ @result = @parent.result
7
+ @host = teuton_host.host
8
+ @param = param
9
+ end
10
+
11
+ def exist?
12
+ @parent.target("File #{@param} exists?")
13
+ @parent.run "file #{@param}", on: @host
14
+ @parent.expect @result.grep_v('cannot open').grep(@param).count.eq 1
15
+ end
16
+
17
+ def directory?
18
+ @parent.target("File #{@param} is directory?")
19
+ @parent.run "file #{@param}", on: @host
20
+ @parent.expect @result.grep_v('cannot open').grep(@param).grep('directory').count.eq 1
21
+ end
22
+
23
+ def regular?
24
+ @parent.target("File #{@param} is regular?")
25
+ @parent.run "file #{@param}", on: @host
26
+ @parent.expect @result.grep(@param).grep('directory').count.eq 0
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+
2
+ require_relative 'teuton_file'
3
+ require_relative 'package'
4
+ require_relative 'service'
5
+ require_relative 'user'
6
+
7
+ class TeutonHost
8
+ attr_reader :parent
9
+ attr_reader :host
10
+
11
+ def initialize(parent, host = 'localhost')
12
+ @parent = parent
13
+ @host = host
14
+ end
15
+
16
+ def file(param)
17
+ TeutonFile.new(self, param)
18
+ end
19
+
20
+ def package(param)
21
+ Package.new(self, param)
22
+ end
23
+
24
+ def service(param)
25
+ Service.new(self, param)
26
+ end
27
+
28
+ def user(param)
29
+ User.new(self, param)
30
+ end
31
+ end
@@ -1,20 +1,21 @@
1
1
 
2
2
  class User
3
- attr_accessor :param
4
-
5
- def initialize(parent)
6
- @parent = parent
3
+ def initialize(teuton_host, param)
4
+ @teuton_host = teuton_host
5
+ @parent = teuton_host.parent
6
+ @host = teuton_host.host
7
+ @param = param
7
8
  end
8
9
 
9
10
  def exists?
10
11
  @parent.target("User #{@param} exists?")
11
- @parent.run "id #{@param}"
12
- @parent.expect_one @param
12
+ @parent.run "id #{@param}", on: @host
13
+ @parent.expect_one [ 'uid=', @param ]
13
14
  end
14
15
 
15
16
  def is_member_of?(groupname)
16
17
  @parent.target("User #{@param} is member of #{groupname}?")
17
- @parent.run "id #{@param}"
18
+ @parent.run "id #{@param}", on: @host
18
19
  @parent.expect_one [@param, groupname]
19
20
  end
20
21
  end
@@ -115,7 +115,7 @@ class Case
115
115
  alias skip? skip
116
116
 
117
117
  ##
118
- # Show case
118
+ # Show case report data on screen
119
119
  def show
120
120
  @report.show
121
121
  end
@@ -22,8 +22,8 @@ module DSL
22
22
  def goto(host = :localhost, args = {})
23
23
  @result.reset
24
24
  args[:on] = host unless args[:on]
25
- @action[:command] = args[:execute] if args[:execute]
26
- @action[:command] = args[:exec] if args[:exec]
25
+ @action[:command] = args[:execute].to_s if args[:execute]
26
+ @action[:command] = args[:exec].to_s if args[:exec]
27
27
  tempfile(args[:tempfile]) if args[:tempfile]
28
28
  @action[:encoding] = args[:encoding] || 'UTF-8'
29
29
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  ##
4
- # Case class -> DSL module : log function
4
+ # Define DSL#log function
5
5
  module DSL
6
6
  ##
7
7
  # Record log message
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require_relative '../../../application'
3
+ require 'os'
3
4
 
4
5
  # DSL module methods: assert, missing_method
5
6
  module DSL
@@ -31,7 +32,9 @@ module DSL
31
32
  # * Invoke macro (assert)
32
33
  def method_missing(method, args = {})
33
34
  a = method.to_s
34
- return instance_eval("get(:#{a[0, a.size - 1]})") if a[a.size - 1] == '?'
35
+ if a.start_with?('_') && a.end_with?('_')
36
+ return instance_eval("get(:#{a[1, a.size - 2]})")
37
+ end
35
38
  return macro a[6, a.size], args if a[0,6]=='macro_'
36
39
  macro a, args
37
40
  end
@@ -18,6 +18,7 @@ module DSL
18
18
  ip = get((host + '_ip').to_sym)
19
19
  username = get((host + '_username').to_sym).to_s
20
20
  password = get((host + '_password').to_sym).to_s
21
+ port = get((host + '_port').to_sym) || 22
21
22
 
22
23
  filename = @report.filename + '.' + @report.format.to_s
23
24
  localfilepath = File.join(@report.output_dir, filename)
@@ -32,7 +33,7 @@ module DSL
32
33
 
33
34
  # Upload a file or directory to the remote host
34
35
  begin
35
- Net::SFTP.start(ip, username, password: password) do |sftp|
36
+ Net::SFTP.start(ip, username, password: password, port: port) do |sftp|
36
37
  sftp.upload!(localfilepath, remotefilepath)
37
38
  end
38
39
  verboseln("=> [ OK ] #{(get(:tt_members)[0,15]).ljust(16)} : #{remotefilepath}")
@@ -58,6 +58,7 @@ class Case
58
58
 
59
59
  ##
60
60
  # Fill case report with time information
61
+ # rubocop:disable Metrics/AbcSize
61
62
  def fill_report(start_time, finish_time)
62
63
  @report.head.merge! @config.global
63
64
  @report.head.merge! @config.local
@@ -67,4 +68,5 @@ class Case
67
68
  @report.tail[:finish_time] = finish_time
68
69
  @report.tail[:duration] = finish_time - start_time
69
70
  end
71
+ # rubocop:enable Metrics/AbcSize
70
72
  end
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # This is an extension of Result class
4
+ # rubocop:disable Metrics/ClassLength
4
5
  class Result
6
+ # rubocop:disable Metrics/MethodLength
7
+ # Return true when content is equal than input
8
+ # @param input (Object)
5
9
  def eq(input)
6
10
  @expected = input
7
11
 
@@ -21,11 +25,13 @@ class Result
21
25
  end
22
26
  value == input
23
27
  end
28
+ # rubocop:enable Metrics/MethodLength
24
29
  alias eq? eq
25
30
  alias equal eq
26
31
  alias equal? eq
27
32
  alias is_equal? eq
28
33
 
34
+ # rubocop:disable Metrics/MethodLength
29
35
  def neq(external)
30
36
  @expected = "Not equal to #{external}"
31
37
 
@@ -43,10 +49,12 @@ class Result
43
49
  end
44
50
  internal != external
45
51
  end
52
+ # rubocop:enable Metrics/MethodLength
46
53
  alias neq? neq
47
54
  alias not_equal neq
48
55
  alias not_equal? neq
49
56
 
57
+ # rubocop:disable Metrics/MethodLength
50
58
  def ge(input)
51
59
  @expected = "Greater or equal to #{input}"
52
60
  return false if @content.nil? || @content[0].nil?
@@ -64,9 +72,11 @@ class Result
64
72
  end
65
73
  value >= input
66
74
  end
75
+ # rubocop:enable Metrics/MethodLength
67
76
  alias greater_or_equal ge
68
77
  alias greater_or_equal? ge
69
78
 
79
+ # rubocop:disable Metrics/MethodLength
70
80
  def gt(input)
71
81
  @expected = "Greater than #{input}"
72
82
  return false if @content.nil? || @content[0].nil?
@@ -84,9 +94,11 @@ class Result
84
94
  end
85
95
  value > input
86
96
  end
97
+ # rubocop:enable Metrics/MethodLength
87
98
  alias greater gt
88
99
  alias greater_than gt
89
100
 
101
+ # rubocop:disable Metrics/MethodLength
90
102
  def le(input)
91
103
  @expected = "Lesser or equal to #{input}"
92
104
 
@@ -105,9 +117,11 @@ class Result
105
117
  end
106
118
  value <= input
107
119
  end
120
+ # rubocop:enable Metrics/MethodLength
108
121
  alias lesser_or_equal le
109
122
  alias lesser_or_equal? le
110
123
 
124
+ # rubocop:disable Metrics/MethodLength
111
125
  def lt(input)
112
126
  @expected = "Lesser than #{input}"
113
127
  return false if @content.nil? || @content[0].nil?
@@ -125,6 +139,7 @@ class Result
125
139
  end
126
140
  value < input
127
141
  end
142
+ # rubocop:enable Metrics/MethodLength
128
143
  alias lesser lt
129
144
  alias smaller lt
130
145
  alias lesser_than lt
@@ -145,3 +160,4 @@ class Result
145
160
  alias near? near_to?
146
161
  alias near near_to?
147
162
  end
163
+ # rubocop:enable Metrics/ClassLength
@@ -44,7 +44,7 @@ class Result
44
44
  print " [DEBUG] count=#{@content.count} "
45
45
  puts '*' * 20
46
46
  @content.each_with_index do |item, index|
47
- puts format('%2d: %s', index, item)
47
+ puts format('%<index>2d: %<item>s', { index: index, item: item })
48
48
  end
49
49
  puts '*' * 57
50
50
  end
@@ -8,6 +8,7 @@ require_relative 'dsl/log'
8
8
  # * run_local_cmd
9
9
  # * run_remote_cmd
10
10
  # * run_remote_cmd_ssh
11
+ # * reconfigure_command_with_gateway
11
12
  # * run_remote_cmd_telnet
12
13
  class Case
13
14
 
@@ -65,21 +66,45 @@ class Case
65
66
  def run_cmd_remote_ssh(input_hostname)
66
67
  @action[:conn_type] = :ssh
67
68
  hostname = input_hostname.to_s
68
- ip = @config.get((hostname + '_ip').to_sym)
69
- username = @config.get((hostname + '_username').to_sym).to_s
70
- password = @config.get((hostname + '_password').to_sym).to_s
69
+ ip = @config.get("#{hostname}_ip".to_sym).to_s
70
+ username = @config.get("#{hostname}_username".to_sym).to_s
71
+ password = @config.get("#{hostname}_password".to_sym).to_s
72
+ port = @config.get("#{hostname}_port".to_sym).to_i || 22
73
+
74
+ unless @config.get("#{hostname}_route".to_sym) == 'NODATA'
75
+ # Reconfigure command with gateway. Example host1_route: IP.
76
+ hostname2 = hostname
77
+ ip2 = ip
78
+ username2 = username
79
+ password2 = password
80
+ command2 = @action[:command]
81
+ hostname = @config.get("#{hostname}_route".to_sym)
82
+ ip = @config.get("#{hostname}_ip".to_sym).to_s
83
+ username = @config.get("#{hostname}_username".to_sym).to_s
84
+ password = @config.get("#{hostname}_password".to_sym).to_s
85
+ ostype = @config.get("#{hostname}_ostype".to_sym).to_s
86
+
87
+ if ostype.downcase.start_with? 'win'
88
+ # echo y | plink idp@2.tcp.eu.ngrok.io -ssh -P 16256 -pw idp "echo > Desktop\hola.txt"
89
+ @action[:command] = "echo y | plink #{username2}@#{ip2} -ssh -pw #{password2} \"#{command2}\""
90
+ else
91
+ @action[:command] = "sshpass -p #{password2} #{username2}@#{ip2} #{command2}"
92
+ end
93
+ end
94
+
71
95
  text = ''
72
96
  begin
73
97
  if @sessions[hostname].nil?
74
98
  @sessions[hostname] = Net::SSH.start(ip,
75
99
  username,
100
+ port: port,
76
101
  password: password,
77
102
  keepalive: true,
78
103
  timeout: 30,
79
104
  non_interactive: true)
80
105
  end
81
106
  if @sessions[hostname].class == Net::SSH::Connection::Session
82
- text = @sessions[hostname].exec!(@action[:command].to_s)
107
+ text = @sessions[hostname].exec!(@action[:command])
83
108
  end
84
109
  rescue Errno::EHOSTUNREACH
85
110
  @sessions[hostname] = :nosession
@@ -109,6 +134,7 @@ class Case
109
134
  " exec: #{@action[:command]}", :error)
110
135
  end
111
136
  output = encode_and_split(@action[:encoding], text)
137
+ # revise: @result.exitstatus = text.exitstatus
112
138
  @result.content = output
113
139
  @result.content.compact!
114
140
  end
@@ -3,7 +3,7 @@
3
3
  require 'singleton'
4
4
  require_relative '../application'
5
5
  require_relative '../report/report'
6
- require_relative '../project/configfile_reader'
6
+ require_relative '../utils/configfile_reader'
7
7
  require_relative 'case/case'
8
8
  require_relative 'export_manager'
9
9
  require_relative 'main'
@@ -1,6 +1,8 @@
1
1
  require_relative '../application'
2
2
  require_relative 'case_manager'
3
3
 
4
+ # Define filename to be used into our test
5
+ # @param filename (String) Filename to be required
4
6
  def use(filename)
5
7
  filename += '.rb'
6
8
  app = Application.instance
@@ -12,17 +14,25 @@ def use(filename)
12
14
  app.uses << File.basename(findfiles.first)
13
15
  end
14
16
 
17
+ # Define macro. That's a name to predefined target-run-expect evaluation.
18
+ # @param name (String) macro name
19
+ # @param block (Block) macro code
15
20
  def define_macro(name, *args, &block)
16
21
  Application.instance.macros[name] = { args: args, block: block }
17
22
  end
18
23
  alias def_macro define_macro
19
24
  alias defmacro define_macro
20
25
 
26
+ # Define a group of tests
27
+ # @param name (String) Group name
28
+ # @param block (Block) Tests code
21
29
  def group(name, &block)
22
30
  Application.instance.groups << { name: name, block: block }
23
31
  end
24
32
  alias task group
25
33
 
34
+ # Start test
35
+ # @param block (Block) Extra code executed at the end.
26
36
  def play(&block)
27
37
  CaseManager.instance.play(&block)
28
38
  end