teuton 2.1.9 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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} +8 -20
- 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 -61
- 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/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.9' # 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
|