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.
- checksums.yaml +4 -4
- data/README.md +15 -12
- data/bin/check_teuton +0 -2
- data/docs/changelog/ideas.md +132 -0
- data/docs/changelog/v2.1.md +14 -122
- data/docs/changelog/v2.2.md +52 -28
- data/docs/changelog/version2.1.md +4 -0
- data/docs/commands/README.md +58 -15
- data/docs/commands/example_check.md +0 -4
- data/docs/commands/example_run.md +0 -4
- data/docs/dsl/README.md +1 -1
- data/docs/dsl/definition/result.md +1 -0
- data/docs/dsl/definition/run_remote.md +12 -6
- data/docs/dsl/definition/target.md +9 -10
- data/docs/dsl/execution/export.md +27 -20
- data/docs/install/README.md +13 -18
- data/docs/install/vagrant_docker.md +1 -1
- data/docs/learn/README.md +8 -8
- data/docs/learn/example-01-target.md +25 -25
- data/docs/learn/example-02-config.md +38 -49
- data/docs/learn/example-03-remote-hosts.md +22 -22
- data/docs/learn/{example-11-first-test.md → example-04-new-test.md} +23 -24
- data/docs/learn/{example-04-use.md → example-05-use.md} +6 -6
- data/docs/learn/{example-05-debug.md → example-06-debug.md} +8 -8
- data/docs/learn/{example-06-log.md → example-07-log.md} +7 -7
- data/docs/learn/example-08-readme.md +59 -0
- data/docs/learn/example-09-preserve.md +41 -0
- data/docs/videos.md +19 -0
- data/lib/teuton/application.rb +22 -3
- data/lib/teuton/case_manager/case/builtin/main.rb +3 -19
- data/lib/teuton/case_manager/case/builtin/package.rb +7 -6
- data/lib/teuton/case_manager/case/builtin/service.rb +9 -8
- data/lib/teuton/case_manager/case/builtin/teuton_file.rb +28 -0
- data/lib/teuton/case_manager/case/builtin/teuton_host.rb +31 -0
- data/lib/teuton/case_manager/case/builtin/user.rb +8 -7
- data/lib/teuton/case_manager/case/case.rb +1 -1
- data/lib/teuton/case_manager/case/dsl/goto.rb +2 -2
- data/lib/teuton/case_manager/case/dsl/log.rb +1 -1
- data/lib/teuton/case_manager/case/dsl/macro.rb +4 -1
- data/lib/teuton/case_manager/case/dsl/send.rb +2 -1
- data/lib/teuton/case_manager/case/play.rb +2 -0
- data/lib/teuton/case_manager/case/result/ext_compare.rb +16 -0
- data/lib/teuton/case_manager/case/result/result.rb +1 -1
- data/lib/teuton/case_manager/case/runner.rb +30 -4
- data/lib/teuton/case_manager/case_manager.rb +1 -1
- data/lib/teuton/case_manager/dsl.rb +10 -0
- data/lib/teuton/case_manager/export_manager.rb +24 -5
- data/lib/teuton/case_manager/utils.rb +1 -1
- data/lib/teuton/{project/laboratory → check}/builtin.rb +0 -0
- data/lib/teuton/{project/laboratory → check}/dsl.rb +40 -28
- data/lib/teuton/{project/laboratory → check}/laboratory.rb +3 -8
- data/lib/teuton/{project/laboratory → check}/show.rb +53 -59
- data/lib/teuton/cli.rb +85 -14
- data/lib/teuton/{project/readme → readme}/dsl.rb +0 -0
- data/lib/teuton/{project/readme → readme}/lang.rb +1 -1
- data/lib/teuton/{project/readme → readme}/readme.rb +22 -18
- data/lib/teuton/report/formatter/array_formatter.rb +13 -1
- data/lib/teuton/report/formatter/base_formatter.rb +18 -5
- data/lib/teuton/{project/skeleton.rb → skeleton.rb} +7 -18
- data/lib/teuton/utils/configfile_reader.rb +121 -0
- data/lib/teuton/{project → utils}/name_file_finder.rb +46 -26
- data/lib/teuton/version.rb +8 -0
- data/lib/teuton.rb +39 -32
- metadata +109 -62
- data/lib/teuton/case_manager/case/dsl/deprecated.rb +0 -14
- data/lib/teuton/cli/check.rb +0 -38
- data/lib/teuton/cli/main.rb +0 -6
- data/lib/teuton/cli/play.rb +0 -38
- data/lib/teuton/cli/readme.rb +0 -26
- data/lib/teuton/cli/version.rb +0 -12
- data/lib/teuton/files/gitignore +0 -2
- data/lib/teuton/project/configfile_reader.rb +0 -49
- data/lib/teuton/project/project.rb +0 -80
@@ -1,14 +1,14 @@
|
|
1
1
|
[<< back](README.md)
|
2
2
|
|
3
|
-
|
4
|
-
2. [Run test](#execution-section)
|
5
|
-
3. [Result](#result)
|
3
|
+
# Example: learn-07-log
|
6
4
|
|
7
|
-
|
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
|
-
|
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-
|
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-
|
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)
|
data/lib/teuton/application.rb
CHANGED
@@ -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 '
|
3
|
-
require_relative 'service'
|
4
|
-
require_relative 'user'
|
2
|
+
require_relative 'teuton_host'
|
5
3
|
|
6
4
|
class Case
|
7
|
-
def
|
8
|
-
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@
|
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
|
@@ -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,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
|
-
|
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
|
@@ -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(
|
69
|
-
username = @config.get(
|
70
|
-
password = @config.get(
|
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]
|
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 '../
|
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
|