teuton 2.4.5 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -10
- data/docs/CHANGELOG.md +2 -0
- data/docs/changelog/todo.md +2 -9
- data/docs/changelog/v2.5.md +6 -0
- data/docs/changelog/v2.6.md +4 -0
- data/docs/commands/example_check.md +2 -3
- data/docs/diagram.md +54 -0
- data/docs/install/README.md +3 -2
- data/docs/learn/02-target.md +37 -12
- data/docs/learn/03-remote_hosts.md +1 -1
- data/docs/learn/04-config.md +1 -1
- data/docs/learn/06-cmd_check.md +1 -4
- data/docs/learn/07-target_weight.md +1 -3
- data/docs/learn/14-moodle_id.md +20 -2
- data/docs/learn/README.md +1 -1
- data/lib/teuton/application.rb +4 -4
- data/lib/teuton/{case_manager/case → case}/case.rb +9 -12
- data/lib/teuton/{case_manager/case → case}/config.rb +1 -1
- data/lib/teuton/{case_manager/case → case}/dsl/macro.rb +1 -1
- data/lib/teuton/case/dsl.rb +10 -0
- data/lib/teuton/{case_manager/case → case}/play.rb +5 -8
- data/lib/teuton/{case_manager/case → case}/runner.rb +3 -0
- data/lib/teuton/case_manager/case_manager.rb +9 -32
- data/lib/teuton/case_manager/dsl.rb +1 -1
- data/lib/teuton/case_manager/export_manager.rb +18 -4
- data/lib/teuton/case_manager/send_manager.rb +17 -0
- data/lib/teuton/case_manager/utils.rb +9 -4
- data/lib/teuton/check/laboratory.rb +1 -1
- data/lib/teuton/check/show.rb +7 -11
- data/lib/teuton/cli.rb +3 -2
- data/lib/teuton/readme/readme.rb +1 -1
- data/lib/teuton/report/formatter/moodle_csv_formatter.rb +6 -1
- data/lib/teuton/{case_manager/case/result → result}/ext_array.rb +5 -5
- data/lib/teuton/{case_manager/case/result → result}/result.rb +1 -1
- data/lib/teuton/version.rb +1 -1
- data/lib/teuton.rb +15 -17
- metadata +34 -29
- data/lib/teuton/case_manager/case/dsl/main.rb +0 -10
- data/lib/teuton/case_manager/case/main.rb +0 -7
- data/lib/teuton/case_manager/main.rb +0 -3
- /data/lib/teuton/{case_manager/case → case}/builtin/main.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/builtin/package.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/builtin/service.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/builtin/teuton_file.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/builtin/teuton_host.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/builtin/user.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/close.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/dsl/expect.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/dsl/getset.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/dsl/goto.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/dsl/log.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/dsl/send.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/dsl/target.rb +0 -0
- /data/lib/teuton/{case_manager/case → case}/dsl/unique.rb +0 -0
- /data/lib/teuton/{report/show.rb → case_manager/show_report.rb} +0 -0
- /data/lib/teuton/{case_manager/case/result → result}/ext_compare.rb +0 -0
- /data/lib/teuton/{case_manager/case/result → result}/ext_filter.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d4dba357b30b42efc7a32e8389bd6c7dfa98e835f46907d2f4a3dbe7e5942e8
|
4
|
+
data.tar.gz: 0bb5add96b17f02f791568d02e2fc8ca698cc9138c9e25e9075d2e686fb6ba88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 694a956fde1cb64e76d78bf4513df7f011001654aef7d305c9ac54ea0df6748b945d8b0b69514c7172c2e56404093824dd59636f54e647b33d0b068d9d3ef5eb
|
7
|
+
data.tar.gz: 4a8d0fa96fdc396d2da7cd129b1458525abe0d6acb15944f965a3facc692980cd76c33d2321a4997a5e03e3af087eea020054ff308b62d37a9b848778d6c8b79
|
data/README.md
CHANGED
@@ -3,21 +3,16 @@
|
|
3
3
|
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/teuton.svg)](https://badge.fury.io/rb/teuton)
|
5
5
|
![GitHub](https://img.shields.io/github/license/dvarrui/teuton)
|
6
|
-
![Gem](https://img.shields.io/gem/dv/teuton/2.4.0)
|
7
6
|
|
8
7
|
_Create Unit Test for your machines. Test your infrastructure as code._
|
9
8
|
|
10
9
|
![logo](./docs/images/logo.png)
|
11
10
|
|
12
|
-
|
11
|
+
Infrastructure test, useful for:
|
13
12
|
* Sysadmin teachers who want to evaluate students remote machines.
|
14
13
|
* Sysadmin apprentices who want to evaluate their learning process as a game.
|
15
14
|
* Professional sysadmin who want to monitor remote machines.
|
16
15
|
|
17
|
-
Teuton allow us:
|
18
|
-
* Write unit tests for real or virtual devices, using simple DSL.
|
19
|
-
* Check compliance with requirements on local or remote devices.
|
20
|
-
|
21
16
|
# Installation
|
22
17
|
|
23
18
|
Install Ruby and then:
|
@@ -40,18 +35,19 @@ CASE RESULTS
|
|
40
35
|
| CASE | MEMBERS | GRADE | STATE |
|
41
36
|
| 01 | anonymous | 100.0 | ✔ |
|
42
37
|
+------+-----------+-------+-------+
|
43
|
-
|
44
38
|
```
|
45
39
|
|
46
40
|
# Features
|
47
41
|
|
48
|
-
*
|
42
|
+
* Simple DSL to define your tests: `target`, `run`,`expect` and more.
|
43
|
+
* Remote devices only require SSH or Telnet service installed.
|
44
|
+
* Output format: txt, html, json, yaml, etc.
|
49
45
|
* Multiplatform.
|
50
|
-
*
|
46
|
+
* [Free Software License](LICENSE).
|
51
47
|
|
52
48
|
# Documentation
|
53
49
|
|
54
|
-
* [
|
50
|
+
* [Getting started](docs/learn/README.md)
|
55
51
|
* [Language reference](docs/dsl/README.md)
|
56
52
|
* [Commands](docs/commands/README.md)
|
57
53
|
* [Installation](docs/install/README.md)
|
data/docs/CHANGELOG.md
CHANGED
data/docs/changelog/todo.md
CHANGED
@@ -1,27 +1,20 @@
|
|
1
1
|
|
2
|
+
|
2
3
|
## TO-DO
|
3
4
|
|
4
5
|
New features:
|
5
6
|
- Parse new input format, and detect parse errors
|
6
7
|
- Teuton readme --lang=es
|
7
8
|
- Export files with other langs
|
9
|
+
- Snode Dockerfile
|
8
10
|
|
9
11
|
Revise:
|
10
12
|
* verify get(:key) and get('key') works fine!
|
11
13
|
* Formatter: xml,
|
12
14
|
|
13
|
-
Revise documentation:
|
14
|
-
* Doc learn 10,11, 12,13 y 14
|
15
|
-
* 10 result and moodle_id
|
16
|
-
* 12 alias
|
17
|
-
* 13 include
|
18
|
-
* 14 macro
|
19
|
-
* Doc tt_include
|
20
|
-
|
21
15
|
Internal changes:
|
22
16
|
* Application to Settings
|
23
17
|
* Laboratory to Checker
|
24
|
-
* Colorize to Rainbow
|
25
18
|
* Unify messages ERROR, INFO, WARN. etc
|
26
19
|
* Create SendManager as ExportManager?
|
27
20
|
* Add tt_label as alias of tt_members
|
@@ -0,0 +1,6 @@
|
|
1
|
+
|
2
|
+
## [2.5.0]
|
3
|
+
|
4
|
+
- ADD: "tt_moodle_max_score" global configuration param. Teuton grades (0-100) are divided by this value when exporting data into "moodle.csv" output file.
|
5
|
+
- UPDATE: Revise documentation. Doc learn 10,11, 12,13 y 14. 10 result and moodle_id, 12 alias, 13 include, 14 macro, Doc tt_include
|
6
|
+
- UPDATE: Internal changes. Remove Colorize gem and replace with Rainbow.
|
@@ -51,11 +51,10 @@ Example:
|
|
51
51
|
:global:
|
52
52
|
:cases:
|
53
53
|
- :tt_members: VALUE
|
54
|
-
|
55
|
-
Check OK!
|
56
54
|
```
|
57
55
|
|
58
56
|
The check process notifies that
|
59
57
|
* This test hasn't config file
|
60
58
|
* and recommends content for our config file. But it isn't necessary for this example.
|
61
|
-
* Syntax
|
59
|
+
* exit_code 0 = Syntax ok.
|
60
|
+
* exit code 1 = Syntax ERROR.
|
data/docs/diagram.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
[<<back](../README.md)
|
2
|
+
|
3
|
+
# Diagram
|
4
|
+
|
5
|
+
```mermaid
|
6
|
+
flowchart TB
|
7
|
+
|
8
|
+
subgraph user
|
9
|
+
CLI --> Teuton
|
10
|
+
end
|
11
|
+
|
12
|
+
subgraph "create\nnew\nproject"
|
13
|
+
Teuton -- create --> Skeleton("Sekeleton\nFiles")
|
14
|
+
end
|
15
|
+
|
16
|
+
subgraph "check\nproject files"
|
17
|
+
Teuton -- check --> Laboratory("Laboratory\nDSL\nShow\nBuiltin!")
|
18
|
+
end
|
19
|
+
|
20
|
+
subgraph "create readme\nfrom project"
|
21
|
+
Teuton -- readme --> Readme("Readme\nDSL\nLang!")
|
22
|
+
end
|
23
|
+
|
24
|
+
subgraph manager
|
25
|
+
Teuton -- require --> manager/DSL
|
26
|
+
manager/DSL -- play --> CaseManager("CaseManager\ncheck_cases\nExportManager\nSendManager\nShowReport")
|
27
|
+
ReportManager --> HallOfFame
|
28
|
+
end
|
29
|
+
|
30
|
+
subgraph utils
|
31
|
+
manager/DSL -- use/macros/groups --> Application("Application\nNameFileFinder")
|
32
|
+
Readme --> ConfigFileReader
|
33
|
+
Laboratory --> ConfigFileReader
|
34
|
+
CaseManager --> ConfigFileReader
|
35
|
+
Verbose
|
36
|
+
end
|
37
|
+
|
38
|
+
subgraph "case folder"
|
39
|
+
CaseManager --> Case("Case\nConfig\nClose\nPlay\nRunner")
|
40
|
+
Case --> case/DSL
|
41
|
+
end
|
42
|
+
|
43
|
+
subgraph "result class"
|
44
|
+
Laboratory --> Result
|
45
|
+
Readme --> Result("Result\next_array\next_compare\next_filter")
|
46
|
+
Case --> Result
|
47
|
+
end
|
48
|
+
|
49
|
+
subgraph report
|
50
|
+
CaseManager --> Report
|
51
|
+
Report --> Formatter
|
52
|
+
Formatter --> files/template
|
53
|
+
end
|
54
|
+
```
|
data/docs/install/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
[<< back](../../README.md)
|
2
2
|
|
3
|
-
# Installation
|
3
|
+
# Installation
|
4
4
|
|
5
|
-
There are 2 types of nodes/hosts:
|
5
|
+
There are 2 types of nodes/hosts, so there are 2 installations:
|
6
6
|
|
7
7
|
| ID | Software | Description |
|
8
8
|
| -- | -------- | ----------- |
|
@@ -20,6 +20,7 @@ Read [modes of use](modes_of_use.md) to know more about differents T-NODE/S-NODE
|
|
20
20
|
| | Fedora | Workstation 29 | x84-64 | Ok | |
|
21
21
|
| | LinuxMint | 18.3 | x86-64 | Ok | |
|
22
22
|
| | openSUSE | Leap 15 | x86-64 | Ok | Ok |
|
23
|
+
| | openSUSE | Tumbleweed | x86-64 | Ok | Ok |
|
23
24
|
| | Ubuntu | 18.04 | x86-64 | Ok | Ok |
|
24
25
|
| Microsoft | Windows | 7 Enterprise | x86 | Ok | |
|
25
26
|
| | Windows | 10 Pro | x86-64 | Ok | Ok |
|
data/docs/learn/02-target.md
CHANGED
@@ -15,13 +15,31 @@ group "Learn about targets" do
|
|
15
15
|
|
16
16
|
target "Create user david"
|
17
17
|
run "id david"
|
18
|
-
expect "david"
|
18
|
+
expect ["uid=", "(david)", "gid="]
|
19
|
+
|
20
|
+
target "Delete user vader"
|
21
|
+
run "id vader"
|
22
|
+
expect ["id:", "vader", "no exist"]
|
19
23
|
|
20
24
|
end
|
21
25
|
```
|
22
26
|
|
23
27
|
> In this example, our localhost's OS is GNU/Linux (or any other compatible OS) because the command executed is `id david`.
|
24
28
|
|
29
|
+
When the user exists, we expect this words: `uid=, (david), gid=`.
|
30
|
+
|
31
|
+
```
|
32
|
+
❯ id david
|
33
|
+
uid=1000(david) gid=1000(david) grupos=1000(david)
|
34
|
+
```
|
35
|
+
|
36
|
+
But when user does not exist, we expect different words: `id:, vader, no exist`.
|
37
|
+
|
38
|
+
```
|
39
|
+
❯ id vader
|
40
|
+
id: «vader»: no existe ese usuario
|
41
|
+
```
|
42
|
+
|
25
43
|
## Execution section
|
26
44
|
|
27
45
|
When we run this teuton test, the execution section (`play`) is processed. This seccion now contains this:
|
@@ -41,7 +59,7 @@ end
|
|
41
59
|
Execute this command to run the test:
|
42
60
|
|
43
61
|
```console
|
44
|
-
> teuton run examples/
|
62
|
+
> teuton run examples/02-target
|
45
63
|
|
46
64
|
CASE RESULTS
|
47
65
|
+------+-----------+-------+-------+
|
@@ -54,7 +72,7 @@ Report files are created into `var/02-target/` folder:
|
|
54
72
|
|
55
73
|
```console
|
56
74
|
var
|
57
|
-
└──
|
75
|
+
└── 02-target
|
58
76
|
├── case-01.txt
|
59
77
|
├── moodle.csv
|
60
78
|
└── resume.txt
|
@@ -63,35 +81,42 @@ var
|
|
63
81
|
Let's see one report:
|
64
82
|
|
65
83
|
```
|
66
|
-
|
67
|
-
|
84
|
+
❯ cat var/02-target/case-01.txt
|
68
85
|
CONFIGURATION
|
69
86
|
+-------------+-----------+
|
70
87
|
| tt_members | anonymous |
|
71
88
|
| tt_sequence | false |
|
72
89
|
| tt_skip | false |
|
73
|
-
| tt_testname |
|
90
|
+
| tt_testname | 02-target |
|
74
91
|
+-------------+-----------+
|
75
92
|
|
93
|
+
|
76
94
|
GROUPS
|
77
95
|
- Learn about targets
|
78
96
|
01 (1.0/1.0)
|
79
97
|
Description : Create user david
|
80
98
|
Command : id david
|
81
99
|
Duration : 0.002 (local)
|
82
|
-
Alterations : find(david) & count
|
100
|
+
Alterations : find(uid=) & find((david)) & find(gid=) & count
|
101
|
+
Expected : Greater than 0 (String)
|
102
|
+
Result : 1 (Integer)
|
103
|
+
02 (1.0/1.0)
|
104
|
+
Description : Delete user vader
|
105
|
+
Command : id vader
|
106
|
+
Duration : 0.002 (local)
|
107
|
+
Alterations : find(id:) & find(vader) & find(no exist) & count
|
83
108
|
Expected : Greater than 0 (String)
|
84
109
|
Result : 1 (Integer)
|
85
110
|
|
86
111
|
RESULTS
|
87
112
|
+--------------+---------------------------+
|
88
113
|
| case_id | 01 |
|
89
|
-
| start_time |
|
90
|
-
| finish_time |
|
91
|
-
| duration | 0.
|
114
|
+
| start_time | 2023-04-10 09:09:30 +0100 |
|
115
|
+
| finish_time | 2023-04-10 09:09:30 +0100 |
|
116
|
+
| duration | 0.003863242 |
|
92
117
|
| unique_fault | 0 |
|
93
|
-
| max_weight |
|
94
|
-
| good_weight |
|
118
|
+
| max_weight | 2.0 |
|
119
|
+
| good_weight | 2.0 |
|
95
120
|
| fail_weight | 0.0 |
|
96
121
|
| fail_counter | 0 |
|
97
122
|
| grade | 100 |
|
data/docs/learn/04-config.md
CHANGED
data/docs/learn/06-cmd_check.md
CHANGED
@@ -14,7 +14,7 @@ Check Teuton test syntax and show statistics.
|
|
14
14
|
(001) target Create user get(username)
|
15
15
|
weight 1.0
|
16
16
|
run 'id get(username)' on host1
|
17
|
-
expect get(username) (
|
17
|
+
expect ["uid=", "(get(username))", "gid="] (Array)
|
18
18
|
|
19
19
|
+----------------------------+
|
20
20
|
| GROUP: Using file: network |
|
@@ -44,7 +44,4 @@ Check Teuton test syntax and show statistics.
|
|
44
44
|
| * hostname | 2 |
|
45
45
|
| Sets | 0 |
|
46
46
|
+-------------+-------+
|
47
|
-
+----------------------+
|
48
|
-
| Revising CONFIG file |
|
49
|
-
+----------------------+
|
50
47
|
```
|
@@ -19,15 +19,13 @@ end
|
|
19
19
|
```
|
20
20
|
|
21
21
|
```
|
22
|
-
❯ teuton check examples/07-target_weight
|
23
|
-
|
24
22
|
+--------------------------+
|
25
23
|
| GROUP: Using file: users |
|
26
24
|
+--------------------------+
|
27
25
|
(001) target Create user get(username)
|
28
26
|
weight 1.0
|
29
27
|
run 'id get(username)' on host1
|
30
|
-
expect get(username) (
|
28
|
+
expect ["uid=", "(get(username))", "gid="] (Array)
|
31
29
|
|
32
30
|
+----------------------------+
|
33
31
|
| GROUP: Using file: network |
|
data/docs/learn/14-moodle_id.md
CHANGED
@@ -8,7 +8,7 @@ Teuton generates a file called `moodle.csv` with the grades of each student into
|
|
8
8
|
|
9
9
|
## tt_moodle_id
|
10
10
|
|
11
|
-
Add a new field called `tt_moodle_id` to each case in "config.yaml". Fill it with the student's identification
|
11
|
+
Add a new field called `tt_moodle_id` to each case in "config.yaml". Fill it with the student's Moodle identification. For example, registered email on or ID number on Moodle platform.
|
12
12
|
|
13
13
|
Example:
|
14
14
|
|
@@ -21,4 +21,22 @@ cases:
|
|
21
21
|
tt_moodle_id: obiwan@starwars.com
|
22
22
|
```
|
23
23
|
|
24
|
-
Now, when
|
24
|
+
Now, when after test execution, use "moodle.csv" output file to load students grades and feedback into your Moodle platform.
|
25
|
+
|
26
|
+
## tt_moodle_max_score
|
27
|
+
|
28
|
+
By default, teuton evaluates grades from 0 to 100. So grade max score is 100.0 by default. Sometimes teachers configure their moodle tasks with diferents max score, so it is necesary adjust Teuton output grades with Moodle input grades.
|
29
|
+
|
30
|
+
We use `tt_moodle_max_score` to customize Moodle max score. So when Teuton export `moodle.csv` values, divides Teuton grades by this value.
|
31
|
+
|
32
|
+
Example:
|
33
|
+
|
34
|
+
```
|
35
|
+
global:
|
36
|
+
tt_moodle_max_score: 10
|
37
|
+
cases:
|
38
|
+
- tt_members: Darth Vader
|
39
|
+
tt_moodle_id: vader@starwars.com
|
40
|
+
- tt_members: Obiwan Kenobi
|
41
|
+
tt_moodle_id: obiwan@starwars.com
|
42
|
+
```
|
data/docs/learn/README.md
CHANGED
@@ -17,7 +17,7 @@ Learn how write your own Teuton tests:
|
|
17
17
|
1. [Export other FORMATS](11-export.md)
|
18
18
|
1. [PRESERVE old reports](12-preserve.md)
|
19
19
|
1. [Hide FEEDBACK from reports](13-feedback.md)
|
20
|
-
1. [MOODLE
|
20
|
+
1. [MOODLE](14-moodle_id.md)
|
21
21
|
1. [Build README from test](15-readme.md)
|
22
22
|
1. [INCLUDE more configuration files](16-include.md)
|
23
23
|
1. [ALIAS](17-alias.md)
|
data/lib/teuton/application.rb
CHANGED
@@ -70,9 +70,9 @@ class Application
|
|
70
70
|
Rainbow.enabled = @options["color"]
|
71
71
|
@options["panel"] = false if @options["panel"].nil?
|
72
72
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
unless @options["case"].nil?
|
74
|
+
numbers = @options["case"].split(",")
|
75
|
+
@options["case"] = numbers.collect!(&:to_i)
|
76
|
+
end
|
77
77
|
end
|
78
78
|
end
|
@@ -1,16 +1,16 @@
|
|
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 "../case_manager/utils"
|
6
|
+
require_relative "../result/result"
|
7
|
+
require_relative "dsl"
|
8
|
+
require_relative "config"
|
9
|
+
require_relative "close"
|
10
|
+
require_relative "play"
|
11
|
+
require_relative "runner"
|
9
12
|
require_relative "builtin/main"
|
10
13
|
|
11
|
-
# TODO: split Case class into several classes:
|
12
|
-
# * Case, Action?, Session?, RunCommand class
|
13
|
-
|
14
14
|
# Case class
|
15
15
|
# * initialize
|
16
16
|
# * export
|
@@ -29,9 +29,6 @@ class Case
|
|
29
29
|
attr_reader :skip
|
30
30
|
@@id = "01" # First case ID value
|
31
31
|
|
32
|
-
##
|
33
|
-
# Initialize case from specified config
|
34
|
-
# @param config (Hash)
|
35
32
|
def initialize(config)
|
36
33
|
app = Application.instance
|
37
34
|
@config = Case::Config.new(local: config, global: app.global)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "dsl/expect"
|
4
|
+
require_relative "dsl/getset"
|
5
|
+
require_relative "dsl/goto"
|
6
|
+
require_relative "dsl/log"
|
7
|
+
require_relative "dsl/macro"
|
8
|
+
require_relative "dsl/send"
|
9
|
+
require_relative "dsl/target"
|
10
|
+
require_relative "dsl/unique"
|
@@ -13,15 +13,11 @@ class Case
|
|
13
13
|
return false
|
14
14
|
end
|
15
15
|
start_time = Time.now
|
16
|
-
|
17
|
-
play_in_sequence
|
18
|
-
else
|
19
|
-
play_in_parallel
|
20
|
-
end
|
16
|
+
play_groups_in_sequence
|
21
17
|
fill_report(start_time, Time.now)
|
22
18
|
close_opened_sessions
|
23
19
|
end
|
24
|
-
|
20
|
+
alias_method :start, :play
|
25
21
|
|
26
22
|
def close_opened_sessions
|
27
23
|
@sessions.each_value do |s|
|
@@ -31,14 +27,15 @@ class Case
|
|
31
27
|
|
32
28
|
private
|
33
29
|
|
34
|
-
def
|
30
|
+
def play_groups_in_sequence
|
31
|
+
verboseln "\n=> Starting case [#{@config.get(:tt_members)}]" if get(:tt_sequence) == true
|
35
32
|
@groups.each do |t|
|
36
33
|
@action[:groupname] = t[:name]
|
37
34
|
instance_eval(&t[:block])
|
38
35
|
end
|
39
36
|
end
|
40
37
|
|
41
|
-
def
|
38
|
+
def play_groups_in_parallel
|
42
39
|
verboseln "Starting case [#{@config.get(:tt_members)}]"
|
43
40
|
@groups.each do |t|
|
44
41
|
verbose "* Processing [#{t[:name]}] "
|
@@ -100,6 +100,9 @@ class Case
|
|
100
100
|
end
|
101
101
|
text = if @sessions[hostname].instance_of? Net::SSH::Connection::Session
|
102
102
|
@sessions[hostname].exec!(@action[:command])
|
103
|
+
# ssh.exec!("ls -l /home/jamis") do |channel, stream, data|
|
104
|
+
# stdout << data if stream == :stdout
|
105
|
+
# end
|
103
106
|
else
|
104
107
|
"SSH: NO CONNECTION!"
|
105
108
|
end
|
@@ -1,12 +1,13 @@
|
|
1
|
-
require "rainbow"
|
2
|
-
require "singleton"
|
3
1
|
require_relative "../application"
|
2
|
+
require_relative "../case/case"
|
4
3
|
require_relative "../report/report"
|
5
|
-
require_relative "../report/show"
|
6
4
|
require_relative "../utils/configfile_reader"
|
7
|
-
require_relative "case/case"
|
8
5
|
require_relative "export_manager"
|
9
|
-
require_relative "
|
6
|
+
require_relative "send_manager"
|
7
|
+
require_relative "show_report"
|
8
|
+
require_relative "check_cases"
|
9
|
+
require_relative "report"
|
10
|
+
require_relative "utils"
|
10
11
|
|
11
12
|
# This class does all the job
|
12
13
|
# Organize the hole job, sending orders to others classes
|
@@ -18,7 +19,6 @@ require_relative "main"
|
|
18
19
|
# * case_manager/hall_of_fame
|
19
20
|
# * case_manager/report
|
20
21
|
class CaseManager
|
21
|
-
include Singleton
|
22
22
|
include Utils
|
23
23
|
attr_reader :report, :cases
|
24
24
|
|
@@ -30,7 +30,6 @@ class CaseManager
|
|
30
30
|
|
31
31
|
##
|
32
32
|
# Execute "play" order: Start every single case test
|
33
|
-
# @param block (Block)
|
34
33
|
def play(&block)
|
35
34
|
check_cases!
|
36
35
|
instance_eval(&block)
|
@@ -42,37 +41,15 @@ class CaseManager
|
|
42
41
|
export(format: i.to_sym) unless i.nil?
|
43
42
|
end
|
44
43
|
|
45
|
-
##
|
46
|
-
# Execute "export" order: Export every case report
|
47
|
-
# @param args (Hash) Export options
|
48
44
|
def export(args = {})
|
49
|
-
|
50
|
-
puts Rainbow("[ERROR] Argument error with 'export'!").red
|
51
|
-
puts Rainbow(" Code : CaseManager#export").red
|
52
|
-
puts Rainbow(" Line : export #{args}").red
|
53
|
-
puts Rainbow(" Use : export format: 'txt'").red
|
54
|
-
puts ""
|
55
|
-
exit 1
|
56
|
-
end
|
57
|
-
ExportManager.run(@report, @cases, args)
|
45
|
+
ExportManager.new.call(@report, @cases, args)
|
58
46
|
end
|
59
47
|
|
60
|
-
##
|
61
|
-
# Execute "send" order: Send every case report
|
62
|
-
# @param args (Hash) Send options
|
63
48
|
def send(args = {})
|
64
|
-
|
65
|
-
puts ""
|
66
|
-
puts Rainbow("-" * 50).green
|
67
|
-
puts Rainbow("Sending files...#{args}").color(:green)
|
68
|
-
@cases.each { |c| threads << Thread.new { c.send(args) } }
|
69
|
-
threads.each(&:join)
|
70
|
-
puts Rainbow("Sending finished!").color(:green)
|
71
|
-
puts Rainbow("-" * 50).green
|
49
|
+
SendManager.new.call(@cases, args)
|
72
50
|
end
|
73
51
|
|
74
52
|
def show(options = {verbose: 1})
|
75
|
-
|
76
|
-
ShowReport.new(@report).call(verbose)
|
53
|
+
ShowReport.new(@report).call(options[:verbose])
|
77
54
|
end
|
78
55
|
end
|
@@ -1,14 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "rainbow"
|
3
4
|
require_relative "../application"
|
4
5
|
|
5
|
-
|
6
|
+
##
|
7
|
+
# Execute "export" order: Export every case report
|
8
|
+
# @param args (Hash) Export options
|
9
|
+
class ExportManager
|
6
10
|
##
|
7
11
|
# Run export function
|
8
12
|
# @param main_report (Report)
|
9
13
|
# @param cases (Array)
|
10
14
|
# @param input (Hash) Selected export options
|
11
|
-
def
|
15
|
+
def call(main_report, cases, args)
|
16
|
+
if args.class != Hash
|
17
|
+
puts Rainbow("[ERROR] Export argument error!").red
|
18
|
+
puts Rainbow(" Revise: export #{args}").red
|
19
|
+
puts Rainbow(" Use : export format: 'txt'").red
|
20
|
+
puts ""
|
21
|
+
exit 1
|
22
|
+
end
|
23
|
+
|
12
24
|
options = strings2symbols(args)
|
13
25
|
if options[:format].nil?
|
14
26
|
options[:format] = Application.instance.default[:format]
|
@@ -26,10 +38,12 @@ module ExportManager
|
|
26
38
|
preserve_files if options[:preserve] == true
|
27
39
|
end
|
28
40
|
|
41
|
+
private
|
42
|
+
|
29
43
|
##
|
30
44
|
# Convert Hash String values into Symbol values
|
31
45
|
# @param input (Hash)
|
32
|
-
|
46
|
+
def strings2symbols(input)
|
33
47
|
args = {}
|
34
48
|
input.each_pair do |key, value|
|
35
49
|
args[key] = if value.instance_of? String
|
@@ -43,7 +57,7 @@ module ExportManager
|
|
43
57
|
|
44
58
|
##
|
45
59
|
# Preserve output files for current project execution
|
46
|
-
|
60
|
+
def preserve_files
|
47
61
|
app = Application.instance
|
48
62
|
t = Time.now
|
49
63
|
data = {year: t.year, month: t.month, day: t.day, hour: t.hour, min: t.min, sec: t.sec}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rainbow"
|
2
|
+
|
3
|
+
class SendManager
|
4
|
+
##
|
5
|
+
# Execute "send" order: Send every case report
|
6
|
+
# @param args (Hash) Send options
|
7
|
+
def call(cases, args)
|
8
|
+
threads = []
|
9
|
+
puts ""
|
10
|
+
puts Rainbow("-" * 50).green
|
11
|
+
puts Rainbow("Sending files...#{args}").color(:green)
|
12
|
+
cases.each { |c| threads << Thread.new { c.send(args) } }
|
13
|
+
threads.each(&:join)
|
14
|
+
puts Rainbow("Sending finished!").color(:green)
|
15
|
+
puts Rainbow("-" * 50).green
|
16
|
+
end
|
17
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require_relative "../application"
|
2
2
|
require "fileutils"
|
3
|
+
require "open3"
|
4
|
+
require "rainbow"
|
3
5
|
|
4
6
|
module Utils
|
5
7
|
def ensure_dir(dirname)
|
@@ -33,11 +35,14 @@ module Utils
|
|
33
35
|
return {exitstatus: 0, content: ""} if Application.instance.debug
|
34
36
|
|
35
37
|
begin
|
36
|
-
text = `#{cmd}`
|
37
|
-
exitstatus = $CHILD_STATUS.exitstatus
|
38
|
+
# text = `#{cmd}`
|
39
|
+
# exitstatus = $CHILD_STATUS.exitstatus
|
40
|
+
text, status = Open3.capture2e(cmd)
|
41
|
+
exitstatus = status.exitstatus
|
38
42
|
rescue => e
|
39
|
-
verbose "!"
|
40
|
-
|
43
|
+
verbose Rainbow("!").green
|
44
|
+
text = e.to_s
|
45
|
+
exitstatus = 1
|
41
46
|
end
|
42
47
|
content = encode_and_split(encoding, text)
|
43
48
|
{exitstatus: exitstatus, content: content}
|
data/lib/teuton/check/show.rb
CHANGED
@@ -16,7 +16,7 @@ class Laboratory
|
|
16
16
|
revise_config_content
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def show_onlyconfig
|
20
20
|
@verbose = false
|
21
21
|
process_content
|
22
22
|
@verbose = true
|
@@ -69,9 +69,9 @@ class Laboratory
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def recomended_config_content
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
warn Rainbow("[WARN] Configfile not found").bright.yellow
|
73
|
+
warn Rainbow(" #{@path[:config]}").white
|
74
|
+
warn Rainbow("[INFO] Recomended content:").bright.yellow
|
75
75
|
output = {global: nil, cases: []}
|
76
76
|
output[:cases][0] = {}
|
77
77
|
script_vars = find_script_vars
|
@@ -80,18 +80,14 @@ class Laboratory
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def recomended_panelconfig_content
|
83
|
-
output = {global:
|
83
|
+
output = {global: nil, cases: [{}]}
|
84
84
|
script_vars = find_script_vars
|
85
|
-
script_vars.each { |i| output[:global][i] = "VALUE" }
|
85
|
+
# script_vars.each { |i| output[:global][i] = "VALUE" }
|
86
|
+
script_vars.each { |i| output[:cases][0][i] = "VALUE" }
|
86
87
|
verboseln YAML.dump(output)
|
87
88
|
end
|
88
89
|
|
89
90
|
def revise_config_content
|
90
|
-
my_screen_table = Terminal::Table.new do |st|
|
91
|
-
st.add_row ["Revising CONFIG file"]
|
92
|
-
end
|
93
|
-
verboseln my_screen_table
|
94
|
-
|
95
91
|
unless File.exist?(@path[:config])
|
96
92
|
recomended_config_content
|
97
93
|
return
|
data/lib/teuton/cli.rb
CHANGED
@@ -15,7 +15,8 @@ class CLI < Thor
|
|
15
15
|
end
|
16
16
|
|
17
17
|
map ["c", "-c", "--check"] => "check"
|
18
|
-
option :
|
18
|
+
option :onlyconfig, type: :boolean
|
19
|
+
option :color, type: :boolean
|
19
20
|
option :cname, type: :string
|
20
21
|
option :cpath, type: :string
|
21
22
|
desc "check [OPTIONS] DIRECTORY", "Check test and config file content"
|
@@ -25,7 +26,7 @@ class CLI < Thor
|
|
25
26
|
|
26
27
|
(2) teuton check PATH/TO/DIR --cname=demo , Check content of start.rb and demo.yaml files:
|
27
28
|
|
28
|
-
(3) teuton check PATH/TO/DIR --
|
29
|
+
(3) teuton check PATH/TO/DIR --onlyconfig , Only show config file recomendations
|
29
30
|
|
30
31
|
(4) teuton check PATH/TO/DIR/foo.rb , Check content of foo.rb and foo.yaml files.
|
31
32
|
|
data/lib/teuton/readme/readme.rb
CHANGED
@@ -16,13 +16,18 @@ class MoodleCSVFormatter < ResumeArrayFormatter
|
|
16
16
|
private
|
17
17
|
|
18
18
|
def process_cases
|
19
|
+
max = @data[:config][:tt_moodle_max_score] || 100.0
|
20
|
+
grade_adjust = max.to_f / 100.0
|
19
21
|
# MoodleID, Grade, Feedback
|
20
22
|
w "MoodleID, TeutonGrade, TeutonFeedback\n"
|
21
23
|
@data[:cases].each do |line|
|
22
24
|
moodle_id = line[:moodle_id]
|
23
25
|
moodle_id = line[:moodle_id].split(",") if moodle_id.instance_of? String
|
24
26
|
moodle_id.each do |id|
|
25
|
-
|
27
|
+
unless line[:skip]
|
28
|
+
grade = line[:grade].to_f * grade_adjust
|
29
|
+
w "#{id.strip},#{grade},#{line[:moodle_feedback]}\n"
|
30
|
+
end
|
26
31
|
end
|
27
32
|
end
|
28
33
|
end
|
@@ -35,9 +35,9 @@ class Result
|
|
35
35
|
@content.empty
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
alias_method :count!, :count
|
39
|
+
alias_method :length, :count
|
40
|
+
alias_method :len, :count
|
41
|
+
alias_method :size, :count
|
42
|
+
alias_method :empty?, :empty
|
43
43
|
end
|
data/lib/teuton/version.rb
CHANGED
data/lib/teuton.rb
CHANGED
@@ -6,36 +6,34 @@ module Teuton
|
|
6
6
|
Skeleton.create(path_to_new_dir)
|
7
7
|
end
|
8
8
|
|
9
|
+
def self.check(projectpath, options = {})
|
10
|
+
Application.instance.add_input_params(projectpath, options)
|
11
|
+
require_dsl_and_script("teuton/check/laboratory") # Define DSL
|
12
|
+
|
13
|
+
app = Application.instance
|
14
|
+
lab = Laboratory.new(app.script_path, app.config_path)
|
15
|
+
if options[:onlyconfig]
|
16
|
+
lab.show_onlyconfig
|
17
|
+
else
|
18
|
+
lab.show
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
9
22
|
def self.run(projectpath, options = {})
|
10
23
|
Application.instance.add_input_params(projectpath, options)
|
11
|
-
require_dsl_and_script("teuton/case_manager/dsl") # Define DSL
|
24
|
+
require_dsl_and_script("teuton/case_manager/dsl") # Define DSL
|
12
25
|
end
|
13
26
|
|
14
27
|
def self.readme(projectpath, options = {})
|
15
28
|
# Create Readme file for a teuton test
|
16
29
|
Application.instance.add_input_params(projectpath, options)
|
17
|
-
require_dsl_and_script("teuton/readme/readme") # Define DSL
|
30
|
+
require_dsl_and_script("teuton/readme/readme") # Define DSL
|
18
31
|
|
19
32
|
app = Application.instance
|
20
33
|
readme = Readme.new(app.script_path, app.config_path)
|
21
34
|
readme.show
|
22
35
|
end
|
23
36
|
|
24
|
-
def self.check(projectpath, options = {})
|
25
|
-
Application.instance.add_input_params(projectpath, options)
|
26
|
-
require_dsl_and_script("teuton/check/laboratory") # Define DSL keywords
|
27
|
-
|
28
|
-
app = Application.instance
|
29
|
-
lab = Laboratory.new(app.script_path, app.config_path)
|
30
|
-
if options[:panelconfig]
|
31
|
-
lab.show_panelconfig
|
32
|
-
else
|
33
|
-
lab.show
|
34
|
-
end
|
35
|
-
puts Rainbow("Check OK!").green
|
36
|
-
exit 0
|
37
|
-
end
|
38
|
-
|
39
37
|
private_class_method def self.require_dsl_and_script(dslpath)
|
40
38
|
app = Application.instance
|
41
39
|
require_relative dslpath
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: teuton
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Vargas Ruiz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rainbow
|
@@ -131,10 +131,13 @@ extra_rdoc_files:
|
|
131
131
|
- docs/changelog/v2.2.md
|
132
132
|
- docs/changelog/v2.3.md
|
133
133
|
- docs/changelog/v2.4.md
|
134
|
+
- docs/changelog/v2.5.md
|
135
|
+
- docs/changelog/v2.6.md
|
134
136
|
- docs/changelog/version2.1.md
|
135
137
|
- docs/commands/README.md
|
136
138
|
- docs/commands/example_check.md
|
137
139
|
- docs/commands/example_run.md
|
140
|
+
- docs/diagram.md
|
138
141
|
- docs/dsl/README.md
|
139
142
|
- docs/dsl/expect.md
|
140
143
|
- docs/dsl/export.md
|
@@ -197,10 +200,13 @@ files:
|
|
197
200
|
- docs/changelog/v2.2.md
|
198
201
|
- docs/changelog/v2.3.md
|
199
202
|
- docs/changelog/v2.4.md
|
203
|
+
- docs/changelog/v2.5.md
|
204
|
+
- docs/changelog/v2.6.md
|
200
205
|
- docs/changelog/version2.1.md
|
201
206
|
- docs/commands/README.md
|
202
207
|
- docs/commands/example_check.md
|
203
208
|
- docs/commands/example_run.md
|
209
|
+
- docs/diagram.md
|
204
210
|
- docs/dsl/README.md
|
205
211
|
- docs/dsl/expect.md
|
206
212
|
- docs/dsl/export.md
|
@@ -254,38 +260,34 @@ files:
|
|
254
260
|
- docs/videos.md
|
255
261
|
- lib/teuton.rb
|
256
262
|
- lib/teuton/application.rb
|
257
|
-
- lib/teuton/
|
258
|
-
- lib/teuton/
|
259
|
-
- lib/teuton/
|
260
|
-
- lib/teuton/
|
261
|
-
- lib/teuton/
|
262
|
-
- lib/teuton/
|
263
|
-
- lib/teuton/
|
264
|
-
- lib/teuton/
|
265
|
-
- lib/teuton/
|
266
|
-
- lib/teuton/
|
267
|
-
- lib/teuton/
|
268
|
-
- lib/teuton/
|
269
|
-
- lib/teuton/
|
270
|
-
- lib/teuton/
|
271
|
-
- lib/teuton/
|
272
|
-
- lib/teuton/
|
273
|
-
- lib/teuton/
|
274
|
-
- lib/teuton/
|
275
|
-
- lib/teuton/
|
276
|
-
- lib/teuton/
|
277
|
-
- lib/teuton/case_manager/case/result/ext_array.rb
|
278
|
-
- lib/teuton/case_manager/case/result/ext_compare.rb
|
279
|
-
- lib/teuton/case_manager/case/result/ext_filter.rb
|
280
|
-
- lib/teuton/case_manager/case/result/result.rb
|
281
|
-
- lib/teuton/case_manager/case/runner.rb
|
263
|
+
- lib/teuton/case/builtin/main.rb
|
264
|
+
- lib/teuton/case/builtin/package.rb
|
265
|
+
- lib/teuton/case/builtin/service.rb
|
266
|
+
- lib/teuton/case/builtin/teuton_file.rb
|
267
|
+
- lib/teuton/case/builtin/teuton_host.rb
|
268
|
+
- lib/teuton/case/builtin/user.rb
|
269
|
+
- lib/teuton/case/case.rb
|
270
|
+
- lib/teuton/case/close.rb
|
271
|
+
- lib/teuton/case/config.rb
|
272
|
+
- lib/teuton/case/dsl.rb
|
273
|
+
- lib/teuton/case/dsl/expect.rb
|
274
|
+
- lib/teuton/case/dsl/getset.rb
|
275
|
+
- lib/teuton/case/dsl/goto.rb
|
276
|
+
- lib/teuton/case/dsl/log.rb
|
277
|
+
- lib/teuton/case/dsl/macro.rb
|
278
|
+
- lib/teuton/case/dsl/send.rb
|
279
|
+
- lib/teuton/case/dsl/target.rb
|
280
|
+
- lib/teuton/case/dsl/unique.rb
|
281
|
+
- lib/teuton/case/play.rb
|
282
|
+
- lib/teuton/case/runner.rb
|
282
283
|
- lib/teuton/case_manager/case_manager.rb
|
283
284
|
- lib/teuton/case_manager/check_cases.rb
|
284
285
|
- lib/teuton/case_manager/dsl.rb
|
285
286
|
- lib/teuton/case_manager/export_manager.rb
|
286
287
|
- lib/teuton/case_manager/hall_of_fame.rb
|
287
|
-
- lib/teuton/case_manager/main.rb
|
288
288
|
- lib/teuton/case_manager/report.rb
|
289
|
+
- lib/teuton/case_manager/send_manager.rb
|
290
|
+
- lib/teuton/case_manager/show_report.rb
|
289
291
|
- lib/teuton/case_manager/utils.rb
|
290
292
|
- lib/teuton/check/builtin.rb
|
291
293
|
- lib/teuton/check/dsl.rb
|
@@ -317,7 +319,10 @@ files:
|
|
317
319
|
- lib/teuton/report/formatter/resume/txt.rb
|
318
320
|
- lib/teuton/report/formatter/resume/yaml.rb
|
319
321
|
- lib/teuton/report/report.rb
|
320
|
-
- lib/teuton/
|
322
|
+
- lib/teuton/result/ext_array.rb
|
323
|
+
- lib/teuton/result/ext_compare.rb
|
324
|
+
- lib/teuton/result/ext_filter.rb
|
325
|
+
- lib/teuton/result/result.rb
|
321
326
|
- lib/teuton/skeleton.rb
|
322
327
|
- lib/teuton/utils/configfile_reader.rb
|
323
328
|
- lib/teuton/utils/name_file_finder.rb
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|