teuton 3.2.1 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -7
- data/docs/commands/README.md +8 -7
- data/docs/commands/check.md +17 -15
- data/docs/commands/help.md +17 -7
- data/docs/devel/todo.md +1 -4
- data/docs/dsl/target.md +0 -14
- data/docs/install/t-node.md +10 -21
- data/docs/learn/02-target.md +49 -47
- data/docs/learn/03-remote_hosts.md +14 -15
- data/docs/learn/04-config.md +67 -68
- data/docs/learn/06-cmd_check.md +26 -24
- data/docs/learn/07-target_weight.md +3 -3
- data/docs/learn/08-unique_values.md +31 -29
- data/docs/learn/10-debug.md +36 -0
- data/docs/learn/13-feedback.md +10 -9
- data/docs/learn/15-readme.md +2 -2
- data/docs/learn/16-include.md +7 -7
- data/docs/learn/18-log.md +44 -43
- data/docs/learn/23-test-code.md +13 -10
- data/docs/learn/24-test-sql.md +5 -5
- data/docs/learn/26-expect_sequence.md +1 -1
- data/docs/learn/27-run_script.md +8 -5
- data/lib/teuton/case/{action.rb → action/action.rb} +18 -10
- data/lib/teuton/case/action/manager.rb +63 -0
- data/lib/teuton/case/case.rb +13 -13
- data/lib/teuton/case/close.rb +3 -3
- data/lib/teuton/case/dsl/all.rb +1 -0
- data/lib/teuton/case/dsl/event.rb +24 -0
- data/lib/teuton/case/dsl/expect.rb +5 -3
- data/lib/teuton/case/dsl/log.rb +3 -7
- data/lib/teuton/case/dsl/macro.rb +1 -1
- data/lib/teuton/case/dsl/run.rb +10 -15
- data/lib/teuton/case/dsl/target.rb +4 -2
- data/lib/teuton/case/play.rb +1 -1
- data/lib/teuton/case/result/ext_compare.rb +10 -10
- data/lib/teuton/case_manager/dsl.rb +6 -2
- data/lib/teuton/case_manager/ext/report.rb +0 -4
- data/lib/teuton/case_manager/show_resume_report.rb +29 -30
- data/lib/teuton/check/checker.rb +17 -8
- data/lib/teuton/check/dsl/all.rb +18 -10
- data/lib/teuton/check/dsl/expect.rb +29 -45
- data/lib/teuton/check/dsl/getset.rb +2 -2
- data/lib/teuton/check/dsl/run.rb +2 -2
- data/lib/teuton/check/show.rb +28 -34
- data/lib/teuton/cli/app.rb +1 -1
- data/lib/teuton/readme/dsl/all.rb +10 -1
- data/lib/teuton/readme/main.rb +2 -2
- data/lib/teuton/report/formatter/default/array.rb +15 -29
- data/lib/teuton/report/formatter/default/txt.rb +41 -30
- data/lib/teuton/report/formatter/resume/txt.rb +27 -26
- data/lib/teuton/report/formatter/resume/xml.rb +4 -4
- data/lib/teuton/report/report.rb +3 -1
- data/lib/teuton/utils/project.rb +4 -3
- data/lib/teuton/version.rb +1 -1
- metadata +4 -5
- data/docs/tutorial/es/nginx/README.md +0 -546
- data/lib/teuton/deprecated/utils.rb +0 -14
|
@@ -22,19 +22,26 @@ end
|
|
|
22
22
|
Cheking test:
|
|
23
23
|
|
|
24
24
|
```
|
|
25
|
-
$ teuton check examples/08-unique_values
|
|
25
|
+
$ teuton check examples/08-unique_values
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
┌─────────────────────────┐
|
|
28
|
+
│ USE: external libraries │
|
|
29
|
+
└─────────────────────────┘
|
|
30
|
+
1. examples/08-unique_values/lib/users.rb
|
|
31
|
+
2. examples/08-unique_values/lib/network.rb
|
|
32
|
+
3. examples/08-unique_values/lib/unique.rb
|
|
33
|
+
|
|
34
|
+
┌──────────────────────────┐
|
|
35
|
+
│ GROUP: Using file: users │
|
|
36
|
+
└──────────────────────────┘
|
|
30
37
|
(001) target Create user get(username)
|
|
31
38
|
weight 1.0
|
|
32
39
|
run 'id get(username)' on host1
|
|
33
40
|
expect get(username) (String)
|
|
34
41
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
┌────────────────────────────┐
|
|
43
|
+
│ GROUP: Using file: network │
|
|
44
|
+
└────────────────────────────┘
|
|
38
45
|
(002) target Update computer name with get(hostname)
|
|
39
46
|
weight 1.0
|
|
40
47
|
run 'hostname' on host1
|
|
@@ -45,28 +52,23 @@ $ teuton check examples/08-unique_values
|
|
|
45
52
|
run 'host www.google.es' on host1
|
|
46
53
|
expect www.google.es has address (String)
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
┌───────────────────────────────┐
|
|
56
|
+
│ GROUP: Unique value: hostname │
|
|
57
|
+
└───────────────────────────────┘
|
|
51
58
|
run 'hostname -f' on host1
|
|
52
|
-
|
|
59
|
+
unique value for <Host name>
|
|
53
60
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
| Sets | 0 |
|
|
68
|
-
+-------------+-------+
|
|
69
|
-
+----------------------+
|
|
70
|
-
| Revising CONFIG file |
|
|
71
|
-
+----------------------+
|
|
61
|
+
┌─────────────┬───────┐
|
|
62
|
+
│ DSL Stats │ Count │
|
|
63
|
+
├─────────────┼───────┤
|
|
64
|
+
│ Uses │ 3 │
|
|
65
|
+
│ Groups │ 3 │
|
|
66
|
+
│ Targets │ 3 │
|
|
67
|
+
│ Runs │ 4 │
|
|
68
|
+
│ * host1 │ 4 │
|
|
69
|
+
│ Uniques │ 1 │
|
|
70
|
+
│ Gets │ 5 │
|
|
71
|
+
│ * username │ 3 │
|
|
72
|
+
│ * hostname │ 2 │
|
|
73
|
+
└─────────────┴───────┘
|
|
72
74
|
```
|
data/docs/learn/10-debug.md
CHANGED
|
@@ -45,3 +45,39 @@ end
|
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
`result.debug` it's usefull when you are verifying command output captured by Teuton.
|
|
48
|
+
|
|
49
|
+
## Output example
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
$ teuton examples/10-debug
|
|
53
|
+
------------------------------------
|
|
54
|
+
Started at 2026-10-21 21:50:52 +0100
|
|
55
|
+
|
|
56
|
+
******************** [DEBUG] count=6 ********************
|
|
57
|
+
0: PING 192.168.1.1 (192.168.1.1) 56(84) bytes de datos.
|
|
58
|
+
1: 64 bytes desde 192.168.1.1: icmp_seq=1 ttl=64 tiempo=2.22 ms
|
|
59
|
+
2:
|
|
60
|
+
3: --- 192.168.1.1 estadísticas ping ---
|
|
61
|
+
4: 1 paquetes transmitidos, 1 recibidos, 0% packet loss, time 0ms
|
|
62
|
+
5: rtt min/avg/max/mdev = 2.220/2.220/2.220/0.000 ms
|
|
63
|
+
*********************************************************
|
|
64
|
+
.
|
|
65
|
+
******************** [DEBUG] count=1 ********************
|
|
66
|
+
0: 1
|
|
67
|
+
*********************************************************
|
|
68
|
+
FFFFFF
|
|
69
|
+
Finished in 35.898 seconds
|
|
70
|
+
------------------------------------
|
|
71
|
+
|
|
72
|
+
CASE RESULTS
|
|
73
|
+
┌──────┬───────────┬───────┬───────┐
|
|
74
|
+
│ CASE │ MEMBERS │ GRADE │ STATE │
|
|
75
|
+
│ 01 │ student_1 │ 14.0 │ ? │
|
|
76
|
+
└──────┴───────────┴───────┴───────┘
|
|
77
|
+
|
|
78
|
+
CONN ERRORS
|
|
79
|
+
┌──────┬───────────┬─────────┬───────┐
|
|
80
|
+
│ CASE │ MEMBERS │ HOST │ ERROR │
|
|
81
|
+
│ 01 │ student_1 │ windows │ error │
|
|
82
|
+
└──────┴───────────┴─────────┴───────┘
|
|
83
|
+
```
|
data/docs/learn/13-feedback.md
CHANGED
|
@@ -37,13 +37,14 @@ Executing `teuton run examples/13-feedback`, we get this output:
|
|
|
37
37
|
|
|
38
38
|
```
|
|
39
39
|
GROUPS
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Description
|
|
43
|
-
Command
|
|
44
|
-
Output
|
|
45
|
-
Duration
|
|
46
|
-
Alterations
|
|
47
|
-
Expected
|
|
48
|
-
Result
|
|
40
|
+
▶ Hide feedback messages from output
|
|
41
|
+
✔ 01 (1.0/1.0) ┌──
|
|
42
|
+
Description │ Service SSH disabled
|
|
43
|
+
Command │ *********************
|
|
44
|
+
Output │ *********
|
|
45
|
+
Duration │ 0.008 (local)
|
|
46
|
+
Alterations │ **********************
|
|
47
|
+
Expected │ **************
|
|
48
|
+
Result │ ********
|
|
49
|
+
└──
|
|
49
50
|
```
|
data/docs/learn/15-readme.md
CHANGED
data/docs/learn/16-include.md
CHANGED
|
@@ -59,11 +59,11 @@ Config files into `moreconfigfiles` folder:
|
|
|
59
59
|
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`.
|
|
60
60
|
|
|
61
61
|
```
|
|
62
|
-
CASE RESULTS
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
CASE RESULTS
|
|
63
|
+
┌──────┬────────────┬───────┬───────┐
|
|
64
|
+
│ CASE │ MEMBERS │ GRADE │ STATE │
|
|
65
|
+
│ 01 │ student_02 │ 0.0 │ ? │
|
|
66
|
+
│ 02 │ student_01 │ 100.0 │ ✔ │
|
|
67
|
+
│ 03 │ student_03 │ 0.0 │ ? │
|
|
68
|
+
└──────┴────────────┴───────┴───────┘
|
|
69
69
|
```
|
data/docs/learn/18-log.md
CHANGED
|
@@ -53,49 +53,50 @@ end
|
|
|
53
53
|
Content of `var/18-log/case-01.txt` file.
|
|
54
54
|
|
|
55
55
|
```txt
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
56
|
+
❯ cat var/18-log/case-01.txt
|
|
57
|
+
CONFIGURATION
|
|
58
|
+
┌────────────────┬───────────────────────────────────┐
|
|
59
|
+
│ tt_config_path │ examples/18-log/config.yaml │
|
|
60
|
+
│ tt_members │ TOCHANGE │
|
|
61
|
+
│ tt_script_path │ examples/18-log/start.rb │
|
|
62
|
+
│ tt_sequence │ false │
|
|
63
|
+
│ tt_skip │ false │
|
|
64
|
+
│ values1 │ ["A1", "B1", "C1"] │
|
|
65
|
+
│ values2 │ {:p1=>"A2", :p2=>"B2", :p3=>"C2"} │
|
|
66
|
+
└────────────────┴───────────────────────────────────┘
|
|
66
67
|
|
|
67
68
|
LOGS
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
GROUPS
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
Description
|
|
81
|
-
Command
|
|
82
|
-
Output
|
|
83
|
-
Duration
|
|
84
|
-
Alterations
|
|
85
|
-
Expected
|
|
86
|
-
Result
|
|
87
|
-
|
|
88
|
-
RESULTS
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
69
|
+
[22:00:21] INFO| Using log messages.
|
|
70
|
+
[22:00:21] INFO| uid=1000(david) gid=1000(david) grupos=1000(david),478(wheel),464(vboxusers),108(libvirt),107(qemu),462(vagrant),460(docker),452(ollama)
|
|
71
|
+
[22:00:21] ERROR| Problem detected!
|
|
72
|
+
[22:00:21] WARN| This is a warning
|
|
73
|
+
[22:00:21] INFO| Hi, there!
|
|
74
|
+
[22:00:21] INFO| -------------
|
|
75
|
+
[22:00:21] INFO| Array values : ["A1", "B1", "C1"]
|
|
76
|
+
[22:00:21] INFO| Hash values : {:p1=>"A2", :p2=>"B2", :p3=>"C2"}
|
|
77
|
+
|
|
78
|
+
GROUPS
|
|
79
|
+
▶ Learning about log messages
|
|
80
|
+
✔ 01 (1.0/1.0) ┌──
|
|
81
|
+
Description │ Create user david
|
|
82
|
+
Command │ id david
|
|
83
|
+
Output │ uid=1000(david) gid=1000(david) grupos=1000(david),478(wheel),464(vboxusers),108(libvirt),107(qemu),462(vagrant),460(docker),452(ollama)
|
|
84
|
+
Duration │ 0.005 (local)
|
|
85
|
+
Alterations │ find(david) & count
|
|
86
|
+
Expected │ Greater than 0
|
|
87
|
+
Result │ 1
|
|
88
|
+
└──
|
|
89
|
+
RESULTS
|
|
90
|
+
┌──────────────┬───────────────────────────┐
|
|
91
|
+
│ unique_fault │ 0 │
|
|
92
|
+
│ case_id │ 01 │
|
|
93
|
+
│ start_time │ 2026-10-21 21:57:57 +0100 │
|
|
94
|
+
│ finish_time │ 2026-10-21 21:57:57 +0100 │
|
|
95
|
+
│ duration │ 0.005315073 │
|
|
96
|
+
│ max_weight │ 1.0 │
|
|
97
|
+
│ good_weight │ 1.0 │
|
|
98
|
+
│ fail_weight │ 0 │
|
|
99
|
+
│ fail_counter │ 0 │
|
|
100
|
+
│ grade │ 100 │
|
|
101
|
+
└──────────────┴───────────────────────────┘
|
|
101
102
|
```
|
data/docs/learn/23-test-code.md
CHANGED
|
@@ -43,22 +43,25 @@ Define config params:
|
|
|
43
43
|
global:
|
|
44
44
|
folder: examples/23-test-code/code
|
|
45
45
|
cases:
|
|
46
|
-
- tt_members:
|
|
46
|
+
- tt_members: student_1_python
|
|
47
47
|
filename: math_1.py
|
|
48
|
-
- tt_members:
|
|
48
|
+
- tt_members: student_2_python
|
|
49
49
|
filename: math_2.py
|
|
50
|
+
- tt_members: student_3_ruby
|
|
51
|
+
filename: math_3.rb
|
|
50
52
|
```
|
|
51
53
|
|
|
52
54
|
* Copy students files into `code` subfolder.
|
|
53
55
|
* Now run Teuton test:
|
|
54
56
|
|
|
55
57
|
```
|
|
56
|
-
$ teuton examples/23-test-code
|
|
57
|
-
|
|
58
|
-
CASE RESULTS
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
$ teuton examples/23-test-code
|
|
59
|
+
|
|
60
|
+
CASE RESULTS
|
|
61
|
+
┌──────┬──────────────────┬───────┬───────┐
|
|
62
|
+
│ CASE │ MEMBERS │ GRADE │ STATE │
|
|
63
|
+
│ 01 │ student_1_python │ 100.0 │ ✔ │
|
|
64
|
+
│ 02 │ student_2_python │ 100.0 │ ✔ │
|
|
65
|
+
│ 03 │ student_3_ruby │ 100.0 │ ✔ │
|
|
66
|
+
└──────┴──────────────────┴───────┴───────┘
|
|
64
67
|
```
|
data/docs/learn/24-test-sql.md
CHANGED
|
@@ -62,9 +62,9 @@ cases:
|
|
|
62
62
|
```
|
|
63
63
|
$ teuton examples/24-test-sql
|
|
64
64
|
|
|
65
|
-
CASE RESULTS
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
CASE RESULTS
|
|
66
|
+
┌──────┬────────────────┬───────┬───────┐
|
|
67
|
+
│ CASE │ MEMBERS │ GRADE │ STATE │
|
|
68
|
+
│ 01 │ student_1_name │ 100.0 │ ✔ │
|
|
69
|
+
└──────┴────────────────┴───────┴───────┘
|
|
70
70
|
```
|
|
@@ -8,7 +8,7 @@ Evaluate the occurrence of a certain sequence that takes place in different line
|
|
|
8
8
|
|
|
9
9
|
## Description
|
|
10
10
|
|
|
11
|
-
In the classic target/run/expect, the expect statement works by locating lines from the output of the previous command that meet certain criteria.
|
|
11
|
+
In the classic "target/run/expect", the expect statement works by locating lines from the output of the previous command that meet certain criteria.
|
|
12
12
|
|
|
13
13
|
We can even (using regular expressions) detect if there is any line in the output where a certain sequence appears.
|
|
14
14
|
|
data/docs/learn/27-run_script.md
CHANGED
|
@@ -90,8 +90,11 @@ CONN ERRORS
|
|
|
90
90
|
+------+---------+-------+------------------+
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
Meaning of progress symbols
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
**Meaning of progress symbols**
|
|
94
|
+
|
|
95
|
+
| Symbol | Description |
|
|
96
|
+
| ------ | --------------- |
|
|
97
|
+
| `.` | check ok |
|
|
98
|
+
| `F` | check fail |
|
|
99
|
+
| `!` | connection fail |
|
|
100
|
+
| `u` | upload ok |
|
|
@@ -1,30 +1,38 @@
|
|
|
1
1
|
class Case
|
|
2
2
|
class Action
|
|
3
3
|
attr_reader :id
|
|
4
|
-
attr_accessor :groupname, :description, :weight,
|
|
5
|
-
:command, :encoding, :host, :exec,
|
|
6
|
-
:
|
|
4
|
+
attr_accessor :groupname, :description, :weight,
|
|
5
|
+
:command, :encoding, :host, :exec,
|
|
6
|
+
:conn_type, :duration,
|
|
7
|
+
:result, :output,
|
|
8
|
+
:alterations, :expected, :check
|
|
9
|
+
attr_writer :score
|
|
7
10
|
|
|
8
|
-
def initialize
|
|
9
|
-
@id =
|
|
11
|
+
def initialize(id = 1)
|
|
12
|
+
@id = id
|
|
10
13
|
@groupname = nil
|
|
11
14
|
@description = "No description!"
|
|
12
15
|
@weight = 1.0
|
|
16
|
+
@check = false
|
|
17
|
+
@score = nil
|
|
13
18
|
end
|
|
14
19
|
|
|
15
|
-
def
|
|
16
|
-
@
|
|
17
|
-
|
|
20
|
+
def score
|
|
21
|
+
return @score unless @score.nil?
|
|
22
|
+
return 0.0 if @check == false
|
|
23
|
+
|
|
24
|
+
@weight
|
|
18
25
|
end
|
|
19
26
|
|
|
20
27
|
def to_h
|
|
21
28
|
{
|
|
22
29
|
id: id,
|
|
23
|
-
groupname: groupname, description: description, weight: weight,
|
|
30
|
+
groupname: groupname, description: description, weight: weight,
|
|
24
31
|
command: command, encoding: encoding, host: host, exec: exec,
|
|
25
32
|
conn_type: conn_type, duration: duration,
|
|
26
33
|
result: result, output: output,
|
|
27
|
-
alterations: alterations, expected: expected, check: check
|
|
34
|
+
alterations: alterations, expected: expected, check: check,
|
|
35
|
+
score: score
|
|
28
36
|
}
|
|
29
37
|
end
|
|
30
38
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require_relative "action"
|
|
2
|
+
|
|
3
|
+
class Case
|
|
4
|
+
class ActionManager
|
|
5
|
+
OBJECTS = %i[last_target every_target all_targets].freeze
|
|
6
|
+
CONDITIONS = %i[failed is_ok].freeze
|
|
7
|
+
ACTIONS = %i[scores_to_zero stop log].freeze
|
|
8
|
+
|
|
9
|
+
attr_reader :actions, :events, :current_action
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@current_action = nil
|
|
13
|
+
@actions = []
|
|
14
|
+
@events = {runonce: [], repeat: []}
|
|
15
|
+
@stopped = false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def add_event(...)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def check_event(...)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def last_action
|
|
25
|
+
@actions.last
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def next_action
|
|
29
|
+
if @current_action.nil?
|
|
30
|
+
@current_action = Action.new(1)
|
|
31
|
+
return @current_action
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
@actions << @current_action
|
|
35
|
+
@current_action = Action.new(last_action.id + 1)
|
|
36
|
+
@current_action.groupname = last_action.groupname
|
|
37
|
+
@current_action.description = last_action.description
|
|
38
|
+
@current_action
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def stopped?
|
|
42
|
+
@stopped
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def scores_to_zero
|
|
46
|
+
@action.each { |action| action.score = 0 }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def stop
|
|
50
|
+
@stop_test = true
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def to_h
|
|
54
|
+
@actions.map { _1.to_h }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def trigger_events!
|
|
58
|
+
@events[:repeat].each do |event|
|
|
59
|
+
# TODO: Do something
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/teuton/case/case.rb
CHANGED
|
@@ -4,7 +4,8 @@ require_relative "../utils/project"
|
|
|
4
4
|
require_relative "../utils/verbose"
|
|
5
5
|
require_relative "../report/report"
|
|
6
6
|
require_relative "dsl/all"
|
|
7
|
-
require_relative "action"
|
|
7
|
+
# require_relative "action/action"
|
|
8
|
+
require_relative "action/manager"
|
|
8
9
|
require_relative "config"
|
|
9
10
|
require_relative "close"
|
|
10
11
|
# require_relative "builtin/main"
|
|
@@ -16,12 +17,11 @@ class Case
|
|
|
16
17
|
include DSL
|
|
17
18
|
include Verbose
|
|
18
19
|
|
|
19
|
-
#
|
|
20
|
+
# INFO: Used by ExecuteManager
|
|
20
21
|
attr_accessor :action, :result, :sessions, :conn_status
|
|
21
|
-
|
|
22
|
-
attr_reader :id, :config, :uniques, :skip
|
|
22
|
+
attr_reader :id, :config, :uniques, :skip, :action_manager
|
|
23
23
|
|
|
24
|
-
@current_case_id =
|
|
24
|
+
@current_case_id = Project.value[:base_case_id]
|
|
25
25
|
|
|
26
26
|
def self.next_id
|
|
27
27
|
@current_case_id = @current_case_id.next
|
|
@@ -32,12 +32,9 @@ class Case
|
|
|
32
32
|
local: config,
|
|
33
33
|
global: Project.value[:global]
|
|
34
34
|
)
|
|
35
|
-
@groups = Project.value[:groups]
|
|
36
35
|
@id = Case.next_id
|
|
37
|
-
|
|
38
|
-
# Define Case Report
|
|
36
|
+
@groups = Project.value[:groups]
|
|
39
37
|
@report = Report.new(@id)
|
|
40
|
-
@report.output_dir = Project.value[:output_dir]
|
|
41
38
|
|
|
42
39
|
# Default configuration
|
|
43
40
|
@skip = false
|
|
@@ -46,13 +43,13 @@ class Case
|
|
|
46
43
|
@skip = true
|
|
47
44
|
@skip = false if Project.value[:options]["case"].include? @id.to_i
|
|
48
45
|
end
|
|
49
|
-
@verbose = Project.value[:verbose]
|
|
50
|
-
|
|
51
46
|
@tempdir = File.join(Project.value[:output_dir], "tmp", @id.to_s)
|
|
47
|
+
@verbose = Project.value[:verbose]
|
|
52
48
|
|
|
53
49
|
@unique_values = {}
|
|
54
50
|
@result = Result.new
|
|
55
|
-
@
|
|
51
|
+
@action_manager = ActionManager.new
|
|
52
|
+
@action = @action_manager.next_action
|
|
56
53
|
@uniques = []
|
|
57
54
|
@sessions = {} # Store opened sessions for this case
|
|
58
55
|
@conn_status = {}
|
|
@@ -65,7 +62,6 @@ class Case
|
|
|
65
62
|
end
|
|
66
63
|
|
|
67
64
|
def filename
|
|
68
|
-
# called from: close_main_report
|
|
69
65
|
@report.filename
|
|
70
66
|
end
|
|
71
67
|
|
|
@@ -75,6 +71,10 @@ class Case
|
|
|
75
71
|
@report.tail[:grade]
|
|
76
72
|
end
|
|
77
73
|
|
|
74
|
+
def last_action
|
|
75
|
+
@action_manager.actions.last
|
|
76
|
+
end
|
|
77
|
+
|
|
78
78
|
def members
|
|
79
79
|
return "-" if skip
|
|
80
80
|
|
data/lib/teuton/case/close.rb
CHANGED
|
@@ -5,11 +5,11 @@ class Case
|
|
|
5
5
|
# Invoked from check_cases!
|
|
6
6
|
|
|
7
7
|
fails = 0
|
|
8
|
-
uniques.
|
|
9
|
-
next unless
|
|
8
|
+
uniques.each_pair do |key, values|
|
|
9
|
+
next unless values&.include?(id) && (values&.count&.> 1)
|
|
10
10
|
|
|
11
11
|
fails += 1
|
|
12
|
-
log_unique_message(key,
|
|
12
|
+
log_unique_message(key, values)
|
|
13
13
|
end
|
|
14
14
|
@report.tail[:unique_fault] = fails
|
|
15
15
|
@report.close
|
data/lib/teuton/case/dsl/all.rb
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module DSL
|
|
2
|
+
def event(**args, &block)
|
|
3
|
+
object = args[:on]
|
|
4
|
+
unless Case::ActionManager::OBJECTS.include? object
|
|
5
|
+
Logger.warn "Incorrect argument in event on: #{object} ..."
|
|
6
|
+
Logger.info "Valid OBJECTS: #{Case::ActionManager::OBJECTS.join(",")}"
|
|
7
|
+
return
|
|
8
|
+
end
|
|
9
|
+
condition = args[:when]
|
|
10
|
+
unless Case::ActionManager::CONDITIONS.include? condition
|
|
11
|
+
Logger.warn "Incorrect argument in event on: :#{object} when: #{condition}"
|
|
12
|
+
Logger.info "Valid CONDITIONS: #{Case::ActionManager::CONDITIONS.join(",")}"
|
|
13
|
+
return
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
if object == :every_target
|
|
17
|
+
@action_manager.events << {args: args, block: block}
|
|
18
|
+
else
|
|
19
|
+
# last_target, all_targets
|
|
20
|
+
log "Event triggered on: #{object}, when: #{condition} Target #{@action.id}"
|
|
21
|
+
# TODO: do something more
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -15,12 +15,11 @@ module DSL
|
|
|
15
15
|
elsif input.instance_of?(String) || input.instance_of?(Regexp) || input.instance_of?(Array)
|
|
16
16
|
expect_any input
|
|
17
17
|
else
|
|
18
|
-
|
|
18
|
+
Logger.warn "Case expect TypeError: <expect #{input} (#{input.class})>"
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def expect2(cond, args = {})
|
|
23
|
-
@action.next
|
|
24
23
|
if @result.exitcode.negative?
|
|
25
24
|
# When exitcode is less than zero, it is because there has been
|
|
26
25
|
# an error in the remote connection (SSH or Telnet)
|
|
@@ -33,8 +32,11 @@ module DSL
|
|
|
33
32
|
|
|
34
33
|
@action.alterations = @result.alterations
|
|
35
34
|
@action.expected = (args[:expected] || @result.expected)
|
|
35
|
+
|
|
36
|
+
@action_manager.trigger_events!
|
|
36
37
|
@report.lines << @action.to_h
|
|
37
|
-
|
|
38
|
+
@action = @action_manager.next_action
|
|
39
|
+
# TODO: weight(1.0)
|
|
38
40
|
|
|
39
41
|
c = Settings.letter[:fail]
|
|
40
42
|
c = Settings.letter[:good] if cond
|
data/lib/teuton/case/dsl/log.rb
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
require "rainbow"
|
|
2
2
|
|
|
3
3
|
module DSL
|
|
4
|
-
|
|
5
|
-
# Record log message
|
|
6
|
-
# @param text (String)
|
|
7
|
-
# @param type (Symbol) Values :info, :warn or :error
|
|
4
|
+
# type => :info, :warn or :error
|
|
8
5
|
def log(text = "", type = :info)
|
|
9
6
|
s = " INFO"
|
|
10
|
-
s = Rainbow("WARN
|
|
7
|
+
s = Rainbow(" WARN").color(:yellow) if type == :warn
|
|
11
8
|
s = Rainbow("ERROR").bg(:red) if type == :error
|
|
12
9
|
t = Time.now
|
|
13
10
|
f = format("%<hour>02d:%<min>02d:%<sec>02d", {hour: t.hour, min: t.min, sec: t.sec})
|
|
14
|
-
msg = "[#{f}] #{s}
|
|
11
|
+
msg = "[#{f}] #{s}| #{text}"
|
|
15
12
|
msg = "[#{f}] #{text}" if s == ""
|
|
16
13
|
@report.lines << msg
|
|
17
14
|
end
|
|
18
|
-
# alias_method :msg, :log
|
|
19
15
|
end
|