teuton 2.3.6 → 2.3.8
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 +3 -4
- data/bin/teuton +1 -1
- data/docs/CHANGELOG.md +8 -0
- data/docs/changelog/v2.4.md +16 -0
- data/docs/dsl/definition/expect.md +11 -7
- data/docs/dsl/definition/result.md +7 -6
- data/docs/dsl/definition/run_local.md +0 -1
- data/docs/dsl/definition/target.md +1 -1
- data/docs/dsl/execution/export.md +14 -16
- data/docs/dsl/execution/send.md +1 -1
- data/docs/dsl/setting/get.md +5 -5
- data/docs/es/exit_code.md +59 -0
- data/docs/es/guess_os.md +28 -0
- data/docs/{Challenge-Server-Project.md → ideas/Challenge-Server-Project.md} +0 -0
- data/docs/{changelog → ideas}/contributions.md +0 -0
- data/docs/{changelog → ideas}/ideas.md +0 -0
- data/docs/{changelog → ideas}/servidor-de-retos.md +0 -0
- data/docs/learn/{example-01-target.md → 01-target.md} +1 -3
- data/docs/learn/{example-02-config.md → 02-config.md} +1 -3
- data/docs/learn/{example-03-remote-hosts.md → 03-remote_hosts.md} +10 -10
- data/docs/learn/{example-04-new-test.md → 04-new_test.md} +8 -16
- data/docs/learn/{example-05-use.md → 05-use.md} +1 -3
- data/docs/learn/{example-06-debug.md → 06-debug.md} +1 -3
- data/docs/learn/{example-07-log.md → 07-log.md} +1 -3
- data/docs/learn/{example-08-readme.md → 08-readme.md} +1 -3
- data/docs/learn/{example-09-preserve.md → 09-preserve.md} +7 -4
- data/docs/learn/10-result.md +36 -0
- data/docs/learn/11-moodle_id.md +19 -0
- data/docs/learn/12-get_vars.md +37 -0
- data/docs/learn/13-include.md +59 -0
- data/docs/learn/14-alias.md +47 -0
- data/docs/learn/16-exit_codes.md +24 -0
- data/docs/learn/README.md +19 -17
- data/lib/teuton/application.rb +24 -17
- data/lib/teuton/case_manager/case/builtin/main.rb +2 -3
- data/lib/teuton/case_manager/case/builtin/package.rb +2 -3
- data/lib/teuton/case_manager/case/builtin/service.rb +4 -5
- data/lib/teuton/case_manager/case/builtin/teuton_file.rb +3 -4
- data/lib/teuton/case_manager/case/builtin/teuton_host.rb +5 -6
- data/lib/teuton/case_manager/case/builtin/user.rb +1 -2
- data/lib/teuton/case_manager/case/case.rb +27 -27
- data/lib/teuton/case_manager/case/close.rb +2 -2
- data/lib/teuton/case_manager/case/config.rb +14 -14
- data/lib/teuton/case_manager/case/dsl/expect.rb +46 -39
- data/lib/teuton/case_manager/case/dsl/goto.rb +2 -2
- data/lib/teuton/case_manager/case/dsl/log.rb +5 -6
- data/lib/teuton/case_manager/case/dsl/macro.rb +11 -7
- data/lib/teuton/case_manager/case/dsl/main.rb +8 -8
- data/lib/teuton/case_manager/case/dsl/send.rb +11 -14
- data/lib/teuton/case_manager/case/dsl/unique.rb +1 -3
- data/lib/teuton/case_manager/case/main.rb +5 -5
- data/lib/teuton/case_manager/case/play.rb +1 -1
- data/lib/teuton/case_manager/case/result/ext_array.rb +9 -9
- data/lib/teuton/case_manager/case/result/ext_compare.rb +44 -58
- data/lib/teuton/case_manager/case/result/ext_filter.rb +20 -8
- data/lib/teuton/case_manager/case/result/result.rb +19 -18
- data/lib/teuton/case_manager/case/runner.rb +53 -60
- data/lib/teuton/case_manager/case_manager.rb +15 -15
- data/lib/teuton/case_manager/check_cases.rb +1 -4
- data/lib/teuton/case_manager/dsl.rb +5 -5
- data/lib/teuton/case_manager/export_manager.rb +8 -19
- data/lib/teuton/case_manager/hall_of_fame.rb +4 -6
- data/lib/teuton/case_manager/main.rb +4 -5
- data/lib/teuton/case_manager/report.rb +21 -16
- data/lib/teuton/case_manager/show.rb +2 -2
- data/lib/teuton/case_manager/utils.rb +13 -14
- data/lib/teuton/check/builtin.rb +5 -1
- data/lib/teuton/check/dsl.rb +10 -11
- data/lib/teuton/check/laboratory.rb +13 -15
- data/lib/teuton/check/show.rb +33 -35
- data/lib/teuton/cli.rb +31 -35
- data/lib/teuton/files/start.rb +3 -6
- data/lib/teuton/readme/dsl.rb +12 -6
- data/lib/teuton/readme/lang.rb +20 -21
- data/lib/teuton/readme/readme.rb +40 -42
- data/lib/teuton/report/close.rb +1 -3
- data/lib/teuton/report/formatter/array_formatter.rb +28 -39
- data/lib/teuton/report/formatter/base_formatter.rb +2 -13
- data/lib/teuton/report/formatter/csv_formatter.rb +12 -18
- data/lib/teuton/report/formatter/formatter_factory.rb +31 -29
- data/lib/teuton/report/formatter/html_formatter.rb +37 -21
- data/lib/teuton/report/formatter/json_formatter.rb +2 -8
- data/lib/teuton/report/formatter/list_formatter.rb +6 -12
- data/lib/teuton/report/formatter/moodle_csv_formatter.rb +3 -6
- data/lib/teuton/report/formatter/resume_array_formatter.rb +1 -1
- data/lib/teuton/report/formatter/resume_html_formatter.rb +29 -19
- data/lib/teuton/report/formatter/resume_json_formatter.rb +2 -3
- data/lib/teuton/report/formatter/resume_list_formatter.rb +4 -4
- data/lib/teuton/report/formatter/resume_txt_formatter.rb +14 -18
- data/lib/teuton/report/formatter/resume_yaml_formatter.rb +1 -9
- data/lib/teuton/report/formatter/txt_formatter.rb +19 -20
- data/lib/teuton/report/formatter/xml_formatter.rb +29 -37
- data/lib/teuton/report/formatter/yaml_formatter.rb +2 -12
- data/lib/teuton/report/report.rb +10 -10
- data/lib/teuton/report/show.rb +14 -33
- data/lib/teuton/skeleton.rb +6 -14
- data/lib/teuton/utils/configfile_reader.rb +22 -21
- data/lib/teuton/utils/name_file_finder.rb +21 -26
- data/lib/teuton/utils/verbose.rb +1 -2
- data/lib/teuton/version.rb +3 -4
- data/lib/teuton.rb +5 -6
- metadata +62 -86
- data/bin/check_teuton +0 -41
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
[<< back](README.md)
|
|
2
|
+
|
|
3
|
+
# Example: 13-include
|
|
4
|
+
|
|
5
|
+
Until now, all the tests we have seen came with a configuration file (`config.yaml`) that contained all the parameters that will later be used in the test. It is also possible to have the information distributed among several configuration files.
|
|
6
|
+
|
|
7
|
+
Suppose we have the following file structure.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
├── config.yaml
|
|
11
|
+
├── include_this_files
|
|
12
|
+
│ ├── 02
|
|
13
|
+
│ │ └── file02.yaml
|
|
14
|
+
│ ├── file01.yaml
|
|
15
|
+
│ └── file03.yml
|
|
16
|
+
└── start.rb
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`config.yaml` will be the main config file. Using `tt_include` parameter, we define a folder where the rest of the configuration files will be.
|
|
20
|
+
|
|
21
|
+
In this example the contents of the files in the include_this_files folder will be included in the configuration:
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
---
|
|
25
|
+
# Fiel: config.yaml
|
|
26
|
+
:global:
|
|
27
|
+
:tt_include: include_this_files
|
|
28
|
+
:cases:
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
If we execute the test we will see that 3 cases are processed. Which are defined in the files `file01.yaml`, `02/file02.yaml` and `file03.yml`.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
CASE RESULTS
|
|
36
|
+
+------+---------+-------+-------+
|
|
37
|
+
| CASE | MEMBERS | GRADE | STATE |
|
|
38
|
+
| 01 | file02 | 0.0 | ? |
|
|
39
|
+
| 02 | file01 | 100.0 | ✔ |
|
|
40
|
+
| 03 | file03 | 0.0 | ? |
|
|
41
|
+
+------+---------+-------+-------+
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Config files into `include_this_files` folder:
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
:tt_members: file01
|
|
48
|
+
:username: root
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
:tt_members: file02
|
|
53
|
+
:username: quigon
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```yaml
|
|
57
|
+
:tt_members: file03
|
|
58
|
+
:username: vader
|
|
59
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[<< back](README.md)
|
|
2
|
+
|
|
3
|
+
# Example: 14-alias
|
|
4
|
+
|
|
5
|
+
Supongamos que tenemos un test como el siguiente:
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
group "Using alias" do
|
|
9
|
+
target "Verify user #{get(:super)} with key alias."
|
|
10
|
+
run "id #{get(:super)}"
|
|
11
|
+
expect get(:super)
|
|
12
|
+
|
|
13
|
+
target "Verify user #{_username} with method alias."
|
|
14
|
+
run "id #{_username}"
|
|
15
|
+
expect _username
|
|
16
|
+
end
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Tenemos sólo 2 targets pero podríamos tener muchos más.
|
|
20
|
+
|
|
21
|
+
> Recordemos que `_username` es equivalente a `get(:username)`
|
|
22
|
+
|
|
23
|
+
Sabemos que el fichero de configuración debe definir los valores para los parámetros `super` y `username`. Queremos aprovechar un fichero de configuración que ya teníamos de otro test, pero tiene el siguiente contenido:
|
|
24
|
+
|
|
25
|
+
```yaml
|
|
26
|
+
# Version 1
|
|
27
|
+
# File: config.yaml
|
|
28
|
+
global:
|
|
29
|
+
cases:
|
|
30
|
+
- tt_members: Anonymous
|
|
31
|
+
superuser: root
|
|
32
|
+
username: obiwan
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Podemos comprobar que nuestro test require el parámetro `super` pero el fichero de configuración lo ha nombrado como `superuser`.
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
# Version 2
|
|
39
|
+
# File: config.yaml
|
|
40
|
+
alias:
|
|
41
|
+
super: :superuser
|
|
42
|
+
global:
|
|
43
|
+
cases:
|
|
44
|
+
- tt_members: Anonymous
|
|
45
|
+
superuser: root
|
|
46
|
+
username: obiwan
|
|
47
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[<< back](README.md)
|
|
2
|
+
|
|
3
|
+
# Example: 16-exit_codes
|
|
4
|
+
|
|
5
|
+
_I am sorry! We have not solved the problem of getting the exit code of the commands so that it works for any platform. But we can help you do this work._
|
|
6
|
+
|
|
7
|
+
`result` stores information from the last command executed by a "run" action. [Offers many functions](../dsl/definition/result.md)) that transforms output data, but also we have been added tow more: first and last.
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
|
|
11
|
+
Take a look at this section:
|
|
12
|
+
```ruby
|
|
13
|
+
target "Exist user root"
|
|
14
|
+
run "id root;echo $?"
|
|
15
|
+
expect_last "0"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
It is posible to invoke the execution of several commands in sequence "cmd1;cmd2". Keep in mind that the last one must show the exit code. In the case of GNU/Linux is "echo $?", but it is different on others OOSS.
|
|
19
|
+
|
|
20
|
+
All terminal output generated by `run` action is captured (Use `result.debug` to show result content into screen), and as we need only the last line, we use `expect_last "0"`.
|
|
21
|
+
|
|
22
|
+
> More information about:
|
|
23
|
+
> * [expect](../dsl/definition/expect.md) keyword.
|
|
24
|
+
> * [result](../dsl/execution/result.md) keyword.
|
data/docs/learn/README.md
CHANGED
|
@@ -8,28 +8,30 @@
|
|
|
8
8
|
# Learning
|
|
9
9
|
|
|
10
10
|
Learn how to use Teuton language to write your own tests:
|
|
11
|
-
- [
|
|
12
|
-
- [
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
- Example 14 -
|
|
11
|
+
- [01 - Target](01-target.md)
|
|
12
|
+
- [02 - Config file](02-config.md)
|
|
13
|
+
- [03 - Remote hosts](03-remote_hosts.md)
|
|
14
|
+
- [04 - Create new test](04-new_test.md)
|
|
15
|
+
- [05 - Use](05-use.md)
|
|
16
|
+
- [06 - Debug](06-debug.md)
|
|
17
|
+
- [07 - Log](07-log.md)
|
|
18
|
+
- [08 - Readme](08-readme.md)
|
|
19
|
+
- [09 - Preserve](09-preserve.md)
|
|
20
|
+
- [10 - Result object](10-result.md)
|
|
21
|
+
- [11 - Moodle ID](11-moodle_id.md)
|
|
22
|
+
- [12 - Get vars](12-get_vars.md)
|
|
23
|
+
- [13 - Include](13-include.md)
|
|
24
|
+
- Example 14 - Alias
|
|
25
|
+
- Example 15 - Macros
|
|
26
|
+
- [Example 16 - Exit codes](16-exit_codes.md)
|
|
25
27
|
- [Videos](videos.md)
|
|
26
28
|
|
|
27
29
|
# Examples
|
|
28
30
|
|
|
29
31
|
More examples
|
|
30
|
-
* Let's see examples at [teuton-
|
|
32
|
+
* Let's see examples at [teuton-tests](https://github.com/dvarrui/teuton-tests) GitHub repository.
|
|
31
33
|
* Ask us by email at `teuton.software@protonmail.com` or Twitter at `@SoftwareTeuton`.
|
|
32
|
-
* [
|
|
34
|
+
* [ES - CHAPI19: Teuton demo](https://github.com/dvarrui/proyectos-de-ejemplo/tree/master/charlas/teuton)
|
|
33
35
|
|
|
34
36
|
# Videos
|
|
35
37
|
|
|
@@ -37,7 +39,7 @@ By now there are no English videos. We are sorry!
|
|
|
37
39
|
But if you want to see Spanish videos, here you are:
|
|
38
40
|
|
|
39
41
|
Teuton (v2.0):
|
|
40
|
-
* [
|
|
42
|
+
* [ES - CHAPI19: Charla Teuton](https://youtu.be/KFWQDfNAFxI?t=12221)
|
|
41
43
|
|
|
42
44
|
Sysadmingame (Teuton v1.0)
|
|
43
45
|
* [Sysadmingame (1 de 3): Instalación del programa](https://youtu.be/dnyMq9_KDco)
|
data/lib/teuton/application.rb
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
3
|
+
require "singleton"
|
|
4
|
+
require_relative "version"
|
|
5
|
+
require_relative "utils/name_file_finder"
|
|
6
6
|
|
|
7
7
|
# This Singleton contains application params
|
|
8
8
|
class Application
|
|
9
9
|
include Singleton
|
|
10
10
|
include Teuton
|
|
11
11
|
|
|
12
|
-
attr_reader
|
|
13
|
-
attr_reader
|
|
14
|
-
attr_reader
|
|
12
|
+
attr_reader :letter
|
|
13
|
+
attr_reader :running_basedir, :output_basedir
|
|
14
|
+
attr_reader :default
|
|
15
15
|
attr_accessor :options
|
|
16
16
|
attr_accessor :verbose
|
|
17
17
|
attr_accessor :global # Global configuration params
|
|
@@ -27,11 +27,18 @@ class Application
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def reset
|
|
30
|
-
@letter = {
|
|
30
|
+
@letter = {
|
|
31
|
+
good: ".",
|
|
32
|
+
bad: "F",
|
|
33
|
+
error: "?",
|
|
34
|
+
none: " ",
|
|
35
|
+
ok: "\u{2714}",
|
|
36
|
+
cross: "\u{2716}"
|
|
37
|
+
}
|
|
31
38
|
@running_basedir = Dir.getwd
|
|
32
|
-
@output_basedir =
|
|
33
|
-
@default = {
|
|
34
|
-
@options = {
|
|
39
|
+
@output_basedir = "var"
|
|
40
|
+
@default = {name: "teuton", format: :txt, debug: false}
|
|
41
|
+
@options = {"lang" => "en"}
|
|
35
42
|
@verbose = true
|
|
36
43
|
|
|
37
44
|
@global = {}
|
|
@@ -51,7 +58,7 @@ class Application
|
|
|
51
58
|
end
|
|
52
59
|
|
|
53
60
|
def quiet?
|
|
54
|
-
return true if Application.instance.options[
|
|
61
|
+
return true if Application.instance.options["quiet"]
|
|
55
62
|
return true unless Application.instance.verbose
|
|
56
63
|
|
|
57
64
|
false
|
|
@@ -64,13 +71,13 @@ class Application
|
|
|
64
71
|
def add_input_params(projectpath, options)
|
|
65
72
|
@options.merge! options
|
|
66
73
|
NameFileFinder.find_filenames_for(projectpath)
|
|
67
|
-
@options[
|
|
68
|
-
Rainbow.enabled = @options[
|
|
69
|
-
@options[
|
|
74
|
+
@options["color"] = true if @options["color"].nil?
|
|
75
|
+
Rainbow.enabled = @options["color"]
|
|
76
|
+
@options["panel"] = false if @options["panel"].nil?
|
|
70
77
|
|
|
71
|
-
return if @options[
|
|
78
|
+
return if @options["case"].nil?
|
|
72
79
|
|
|
73
|
-
a = @options[
|
|
74
|
-
@options[
|
|
80
|
+
a = @options["case"].split(",")
|
|
81
|
+
@options["case"] = a.collect!(&:to_i)
|
|
75
82
|
end
|
|
76
83
|
end
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
class Package
|
|
3
2
|
def initialize(teuton_host, param)
|
|
4
3
|
@teuton_host = teuton_host
|
|
@@ -10,12 +9,12 @@ class Package
|
|
|
10
9
|
def installed?
|
|
11
10
|
@parent.target("Package #{@param} installed?")
|
|
12
11
|
@parent.run "whereis #{@param}", on: @host
|
|
13
|
-
@parent.expect_one [
|
|
12
|
+
@parent.expect_one ["bin", @param]
|
|
14
13
|
end
|
|
15
14
|
|
|
16
15
|
def not_installed?
|
|
17
16
|
@parent.target("Package #{@param} not installed?")
|
|
18
17
|
@parent.run "whereis #{@param}", on: @host
|
|
19
|
-
@parent.expect_none [
|
|
18
|
+
@parent.expect_none ["bin", @param]
|
|
20
19
|
end
|
|
21
20
|
end
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
class Service
|
|
3
2
|
def initialize(teuton_host, param)
|
|
4
3
|
@teuton_host = teuton_host
|
|
@@ -10,24 +9,24 @@ class Service
|
|
|
10
9
|
def is_running?
|
|
11
10
|
@parent.target("Service #{@param} is running?")
|
|
12
11
|
@parent.run "systemctl status #{@param}", on: @host
|
|
13
|
-
@parent.expect_one [
|
|
12
|
+
@parent.expect_one ["Active:", "running"]
|
|
14
13
|
end
|
|
15
14
|
|
|
16
15
|
def is_inactive?
|
|
17
16
|
@parent.target("Service #{@param} is inactive?")
|
|
18
17
|
@parent.run "systemctl status #{@param}", on: @host
|
|
19
|
-
@parent.expect_one [
|
|
18
|
+
@parent.expect_one ["Active:", "inactive"]
|
|
20
19
|
end
|
|
21
20
|
|
|
22
21
|
def is_enable?
|
|
23
22
|
@parent.target("Service #{@param} is enable?")
|
|
24
23
|
@parent.run "systemctl status #{@param}", on: @host
|
|
25
|
-
@parent.expect_one [
|
|
24
|
+
@parent.expect_one ["Loaded:", "enable"]
|
|
26
25
|
end
|
|
27
26
|
|
|
28
27
|
def is_disable?
|
|
29
28
|
@parent.target("Service #{@param} is disable?")
|
|
30
29
|
@parent.run "systemctl status #{@param}", on: @host
|
|
31
|
-
@parent.expect_one [
|
|
30
|
+
@parent.expect_one ["Loaded:", "disable"]
|
|
32
31
|
end
|
|
33
32
|
end
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
class TeutonFile
|
|
3
2
|
def initialize(teuton_host, param)
|
|
4
3
|
@teuton_host = teuton_host
|
|
@@ -11,18 +10,18 @@ class TeutonFile
|
|
|
11
10
|
def exist?
|
|
12
11
|
@parent.target("File #{@param} exists?")
|
|
13
12
|
@parent.run "file #{@param}", on: @host
|
|
14
|
-
@parent.expect @result.grep_v(
|
|
13
|
+
@parent.expect @result.grep_v("cannot open").grep(@param).count.eq 1
|
|
15
14
|
end
|
|
16
15
|
|
|
17
16
|
def directory?
|
|
18
17
|
@parent.target("File #{@param} is directory?")
|
|
19
18
|
@parent.run "file #{@param}", on: @host
|
|
20
|
-
@parent.expect @result.grep_v(
|
|
19
|
+
@parent.expect @result.grep_v("cannot open").grep(@param).grep("directory").count.eq 1
|
|
21
20
|
end
|
|
22
21
|
|
|
23
22
|
def regular?
|
|
24
23
|
@parent.target("File #{@param} is regular?")
|
|
25
24
|
@parent.run "file #{@param}", on: @host
|
|
26
|
-
@parent.expect @result.grep(@param).grep(
|
|
25
|
+
@parent.expect @result.grep(@param).grep("directory").count.eq 0
|
|
27
26
|
end
|
|
28
27
|
end
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
require_relative
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative 'user'
|
|
1
|
+
require_relative "teuton_file"
|
|
2
|
+
require_relative "package"
|
|
3
|
+
require_relative "service"
|
|
4
|
+
require_relative "user"
|
|
6
5
|
|
|
7
6
|
class TeutonHost
|
|
8
7
|
attr_reader :parent
|
|
9
8
|
attr_reader :host
|
|
10
9
|
|
|
11
|
-
def initialize(parent, host =
|
|
10
|
+
def initialize(parent, host = "localhost")
|
|
12
11
|
@parent = parent
|
|
13
12
|
@host = host
|
|
14
13
|
end
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
class User
|
|
3
2
|
def initialize(teuton_host, param)
|
|
4
3
|
@teuton_host = teuton_host
|
|
@@ -10,7 +9,7 @@ class User
|
|
|
10
9
|
def exists?
|
|
11
10
|
@parent.target("User #{@param} exists?")
|
|
12
11
|
@parent.run "id #{@param}", on: @host
|
|
13
|
-
@parent.expect_one [
|
|
12
|
+
@parent.expect_one ["uid=", @param]
|
|
14
13
|
end
|
|
15
14
|
|
|
16
15
|
def is_member_of?(groupname)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
3
|
+
require_relative "../../application"
|
|
4
|
+
require_relative "../../report/report"
|
|
5
|
+
require_relative "../utils"
|
|
6
|
+
require_relative "main"
|
|
7
|
+
require_relative "result/result"
|
|
8
|
+
require_relative "builtin/main"
|
|
9
9
|
|
|
10
10
|
# TODO: split Case class into several classes:
|
|
11
11
|
# * Case, Action?, Session?, RunCommand class
|
|
@@ -26,7 +26,8 @@ class Case
|
|
|
26
26
|
attr_accessor :result
|
|
27
27
|
attr_accessor :action # TODO: why not reader only???
|
|
28
28
|
attr_reader :id, :config, :uniques, :conn_status
|
|
29
|
-
|
|
29
|
+
attr_reader :skip
|
|
30
|
+
@@id = "01" # First case ID value
|
|
30
31
|
|
|
31
32
|
##
|
|
32
33
|
# Initialize case from specified config
|
|
@@ -41,21 +42,21 @@ class Case
|
|
|
41
42
|
|
|
42
43
|
# Define Case Report
|
|
43
44
|
@report = Report.new(@id)
|
|
44
|
-
@report.output_dir = File.join(
|
|
45
|
+
@report.output_dir = File.join("var", @config.global[:tt_testname])
|
|
45
46
|
ensure_dir @report.output_dir
|
|
46
47
|
|
|
47
48
|
# Default configuration
|
|
48
49
|
@skip = false
|
|
49
|
-
@skip = get(:tt_skip) unless get(:tt_skip) ==
|
|
50
|
-
unless app.options[
|
|
50
|
+
@skip = get(:tt_skip) unless get(:tt_skip) == "NODATA"
|
|
51
|
+
unless app.options["case"].nil?
|
|
51
52
|
@skip = true
|
|
52
|
-
@skip = false if app.options[
|
|
53
|
+
@skip = false if app.options["case"].include? @id.to_i
|
|
53
54
|
end
|
|
54
55
|
|
|
55
56
|
@conn_status = {}
|
|
56
|
-
@tmpdir = File.join(
|
|
57
|
+
@tmpdir = File.join("var", @config.get(:tt_testname), "tmp", @id.to_s)
|
|
57
58
|
# ensure_dir @tmpdir # REVISE: When we will need this? Samba?
|
|
58
|
-
@remote_tmpdir = File.join(
|
|
59
|
+
@remote_tmpdir = File.join("/", "tmp")
|
|
59
60
|
|
|
60
61
|
@unique_values = {}
|
|
61
62
|
@result = Result.new
|
|
@@ -64,10 +65,12 @@ class Case
|
|
|
64
65
|
@verbose = Application.instance.verbose
|
|
65
66
|
|
|
66
67
|
@action_counter = 0
|
|
67
|
-
@action = {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
@action = {
|
|
69
|
+
id: 0,
|
|
70
|
+
weight: 1.0,
|
|
71
|
+
description: "No description!",
|
|
72
|
+
groupname: nil
|
|
73
|
+
}
|
|
71
74
|
@uniques = []
|
|
72
75
|
@sessions = {} # Store opened sessions for this case
|
|
73
76
|
tempfile :default
|
|
@@ -101,17 +104,14 @@ class Case
|
|
|
101
104
|
## Return case members
|
|
102
105
|
# @return members
|
|
103
106
|
def members
|
|
104
|
-
return
|
|
107
|
+
return "-" if skip
|
|
105
108
|
|
|
106
|
-
@report.head[:tt_members] ||
|
|
109
|
+
@report.head[:tt_members] || "noname"
|
|
107
110
|
end
|
|
108
111
|
|
|
109
112
|
##
|
|
110
113
|
# Return case skip value
|
|
111
114
|
# @return skip
|
|
112
|
-
def skip
|
|
113
|
-
@skip
|
|
114
|
-
end
|
|
115
115
|
alias skip? skip
|
|
116
116
|
|
|
117
117
|
##
|
|
@@ -124,13 +124,13 @@ class Case
|
|
|
124
124
|
|
|
125
125
|
def read_filename(filename)
|
|
126
126
|
begin
|
|
127
|
-
file = File.open(filename,
|
|
127
|
+
file = File.open(filename, "r")
|
|
128
128
|
item = file.readlines
|
|
129
129
|
file.close
|
|
130
|
-
item.map! { |i| i.sub(/\n/,
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return []
|
|
130
|
+
item.map! { |i| i.sub(/\n/, "") }
|
|
131
|
+
rescue
|
|
132
|
+
item = []
|
|
134
133
|
end
|
|
134
|
+
item
|
|
135
135
|
end
|
|
136
136
|
end
|
|
@@ -17,11 +17,11 @@ class Case
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
19
|
def log_unique_message(key, value)
|
|
20
|
-
log(
|
|
20
|
+
log("UNIQUE:", :error)
|
|
21
21
|
begin
|
|
22
22
|
log(" ├── Value => #{key}", :error)
|
|
23
23
|
log(" └── Conflicts => #{value}", :error)
|
|
24
|
-
rescue
|
|
24
|
+
rescue => e
|
|
25
25
|
log(key, :error)
|
|
26
26
|
log(e.to_s, :error)
|
|
27
27
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "../../application"
|
|
4
4
|
|
|
5
5
|
# Class Case::Config
|
|
6
6
|
# * get
|
|
@@ -8,14 +8,14 @@ require_relative '../../application'
|
|
|
8
8
|
# * unset
|
|
9
9
|
# * missing_method
|
|
10
10
|
class Case
|
|
11
|
-
# This class manage configuration for only one case
|
|
12
11
|
class Config
|
|
12
|
+
# This class manage configuration for only one case
|
|
13
13
|
attr_reader :ialias, :global, :local, :running
|
|
14
14
|
|
|
15
15
|
def initialize(args)
|
|
16
|
-
@ialias
|
|
17
|
-
@global
|
|
18
|
-
@local
|
|
16
|
+
@ialias = args[:alias] || Application.instance.ialias.clone
|
|
17
|
+
@global = args[:global] || Application.instance.global.clone
|
|
18
|
+
@local = args[:local] || {}
|
|
19
19
|
@running = {}
|
|
20
20
|
|
|
21
21
|
# Set defaults values
|
|
@@ -24,7 +24,7 @@ class Case
|
|
|
24
24
|
|
|
25
25
|
# Read param Option from [running, config or global] Hash data
|
|
26
26
|
def get(option, level = 0)
|
|
27
|
-
return
|
|
27
|
+
return "NODATA" if level > 3
|
|
28
28
|
|
|
29
29
|
return @running[option] if @running[option]
|
|
30
30
|
|
|
@@ -46,19 +46,19 @@ class Case
|
|
|
46
46
|
private
|
|
47
47
|
|
|
48
48
|
def search_alias(key, level)
|
|
49
|
-
if @ialias[key].
|
|
49
|
+
if @ialias[key].instance_of? Array
|
|
50
50
|
return search_array_alias(@ialias[key], level)
|
|
51
51
|
elsif [Integer, String, Symbol].include? @ialias[key].class
|
|
52
52
|
return get(@ialias[key])
|
|
53
53
|
end
|
|
54
|
-
|
|
55
|
-
words = key.to_s.split('_')
|
|
56
|
-
return 'NODATA' if words.size < 2
|
|
57
54
|
|
|
58
|
-
|
|
55
|
+
words = key.to_s.split("_")
|
|
56
|
+
return "NODATA" if words.size < 2
|
|
57
|
+
|
|
58
|
+
return "NODATA" unless %w[ip hostname username password].include? words[1]
|
|
59
59
|
|
|
60
60
|
key2 = @ialias[words[0].to_sym]
|
|
61
|
-
return
|
|
61
|
+
return "NODATA" unless key2
|
|
62
62
|
|
|
63
63
|
get("#{key2}_#{words[1]}".to_sym, level)
|
|
64
64
|
end
|
|
@@ -66,13 +66,13 @@ class Case
|
|
|
66
66
|
def search_array_alias(keys, level)
|
|
67
67
|
values = []
|
|
68
68
|
keys.each do |k|
|
|
69
|
-
if k.
|
|
69
|
+
if k.instance_of? Symbol
|
|
70
70
|
values << get(k, level + 1)
|
|
71
71
|
next
|
|
72
72
|
end
|
|
73
73
|
values << k
|
|
74
74
|
end
|
|
75
|
-
values.join(
|
|
75
|
+
values.join("")
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
end
|