teuton 2.4.5 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -10
  3. data/docs/CHANGELOG.md +2 -0
  4. data/docs/changelog/todo.md +2 -9
  5. data/docs/changelog/v2.5.md +6 -0
  6. data/docs/changelog/v2.6.md +4 -0
  7. data/docs/commands/example_check.md +2 -3
  8. data/docs/diagram.md +54 -0
  9. data/docs/install/README.md +3 -2
  10. data/docs/learn/02-target.md +37 -12
  11. data/docs/learn/03-remote_hosts.md +1 -1
  12. data/docs/learn/04-config.md +1 -1
  13. data/docs/learn/06-cmd_check.md +1 -4
  14. data/docs/learn/07-target_weight.md +1 -3
  15. data/docs/learn/14-moodle_id.md +20 -2
  16. data/docs/learn/README.md +1 -1
  17. data/lib/teuton/application.rb +4 -4
  18. data/lib/teuton/{case_manager/case → case}/case.rb +9 -12
  19. data/lib/teuton/{case_manager/case → case}/config.rb +1 -1
  20. data/lib/teuton/{case_manager/case → case}/dsl/macro.rb +1 -1
  21. data/lib/teuton/case/dsl.rb +10 -0
  22. data/lib/teuton/{case_manager/case → case}/play.rb +5 -8
  23. data/lib/teuton/{case_manager/case → case}/runner.rb +3 -0
  24. data/lib/teuton/case_manager/case_manager.rb +9 -32
  25. data/lib/teuton/case_manager/dsl.rb +1 -1
  26. data/lib/teuton/case_manager/export_manager.rb +18 -4
  27. data/lib/teuton/case_manager/send_manager.rb +17 -0
  28. data/lib/teuton/case_manager/utils.rb +9 -4
  29. data/lib/teuton/check/laboratory.rb +1 -1
  30. data/lib/teuton/check/show.rb +7 -11
  31. data/lib/teuton/cli.rb +3 -2
  32. data/lib/teuton/readme/readme.rb +1 -1
  33. data/lib/teuton/report/formatter/moodle_csv_formatter.rb +6 -1
  34. data/lib/teuton/{case_manager/case/result → result}/ext_array.rb +5 -5
  35. data/lib/teuton/{case_manager/case/result → result}/result.rb +1 -1
  36. data/lib/teuton/version.rb +1 -1
  37. data/lib/teuton.rb +15 -17
  38. metadata +34 -29
  39. data/lib/teuton/case_manager/case/dsl/main.rb +0 -10
  40. data/lib/teuton/case_manager/case/main.rb +0 -7
  41. data/lib/teuton/case_manager/main.rb +0 -3
  42. /data/lib/teuton/{case_manager/case → case}/builtin/main.rb +0 -0
  43. /data/lib/teuton/{case_manager/case → case}/builtin/package.rb +0 -0
  44. /data/lib/teuton/{case_manager/case → case}/builtin/service.rb +0 -0
  45. /data/lib/teuton/{case_manager/case → case}/builtin/teuton_file.rb +0 -0
  46. /data/lib/teuton/{case_manager/case → case}/builtin/teuton_host.rb +0 -0
  47. /data/lib/teuton/{case_manager/case → case}/builtin/user.rb +0 -0
  48. /data/lib/teuton/{case_manager/case → case}/close.rb +0 -0
  49. /data/lib/teuton/{case_manager/case → case}/dsl/expect.rb +0 -0
  50. /data/lib/teuton/{case_manager/case → case}/dsl/getset.rb +0 -0
  51. /data/lib/teuton/{case_manager/case → case}/dsl/goto.rb +0 -0
  52. /data/lib/teuton/{case_manager/case → case}/dsl/log.rb +0 -0
  53. /data/lib/teuton/{case_manager/case → case}/dsl/send.rb +0 -0
  54. /data/lib/teuton/{case_manager/case → case}/dsl/target.rb +0 -0
  55. /data/lib/teuton/{case_manager/case → case}/dsl/unique.rb +0 -0
  56. /data/lib/teuton/{report/show.rb → case_manager/show_report.rb} +0 -0
  57. /data/lib/teuton/{case_manager/case/result → result}/ext_compare.rb +0 -0
  58. /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: 23e6309b8f112199998d8afd4517a06ec5b80ec4d68421ef67ef87b3c63684ef
4
- data.tar.gz: b0c17aefadc82be10bc1c52de45fdaa65f070046bc30bad7a0416803c62c5daf
3
+ metadata.gz: 8d4dba357b30b42efc7a32e8389bd6c7dfa98e835f46907d2f4a3dbe7e5942e8
4
+ data.tar.gz: 0bb5add96b17f02f791568d02e2fc8ca698cc9138c9e25e9075d2e686fb6ba88
5
5
  SHA512:
6
- metadata.gz: dc3e324bb363b77302758a8210e02a6258d94e99c0797806c2e2f02894a970a6ca6977984abcc7cd647982c9752b7e5799c762684ca14131d06a1260ecb49eab
7
- data.tar.gz: b0bed729989027e9916b214b7421f88a172ef522197d1a5f589c2a5424f54688d5ea3695a3cded4410f2a68d63d5ef1687374b740b90ce91450558f03a1bcc37
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
- Teuton is an infrastructure test tool, useful for:
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
- * [Free Software License](LICENSE).
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
- * Remote machines/devices only require SSH or Telnet service installed.
46
+ * [Free Software License](LICENSE).
51
47
 
52
48
  # Documentation
53
49
 
54
- * [Learn](docs/learn/README.md)
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
@@ -2,6 +2,8 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ * [version 2.5](changelog/v2.5.md)
6
+ * [version 2.4](changelog/v2.4.md)
5
7
  * [version 2.3](changelog/v2.3.md)
6
8
  * [version 2.2](changelog/v2.2.md)
7
9
  * [version 2.1](changelog/v2.1.md)
@@ -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.
@@ -0,0 +1,4 @@
1
+
2
+ ## [2.6.0]
3
+
4
+ - [ADD] When running local or SSH commands, stdout and stderr are captured and readed by "expect" sentence.
@@ -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 is OK!
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
+ ```
@@ -1,8 +1,8 @@
1
1
  [<< back](../../README.md)
2
2
 
3
- # Installation process
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 |
@@ -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/01-target
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
- └── 01-target
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
- > more var/02-target/case-01.txt
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 | 01-target |
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 | 2022-12-24 13:31:28 +0000 |
90
- | finish_time | 2022-12-24 13:31:28 +0000 |
91
- | duration | 0.001880141 |
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 | 1.0 |
94
- | good_weight | 1.0 |
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 |
@@ -43,7 +43,7 @@ Define 1 target (item to be checked):
43
43
  group "Remote hosts" do
44
44
  target "Create user david"
45
45
  run "id david", on: :host1
46
- expect "david"
46
+ expect [ "uid=", "(david)", "gid=" ]
47
47
  end
48
48
  ```
49
49
 
@@ -24,7 +24,7 @@ group "Reading params from config file" do
24
24
 
25
25
  target "Create user #{get(:username)}"
26
26
  run "id #{get(:username)}"
27
- expect get(:username)
27
+ expect [ "uid=", "("+get(:username)+")", "gid=" ]
28
28
 
29
29
  end
30
30
  ```
@@ -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) (String)
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) (String)
28
+ expect ["uid=", "(get(username))", "gid="] (Array)
31
29
 
32
30
  +----------------------------+
33
31
  | GROUP: Using file: network |
@@ -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 (For example, the email registered on the Moodle, or ID number, etc.).
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 running test "moodle.csv" will be generated with all student grades.
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 ID](14-moodle_id.md)
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)
@@ -70,9 +70,9 @@ class Application
70
70
  Rainbow.enabled = @options["color"]
71
71
  @options["panel"] = false if @options["panel"].nil?
72
72
 
73
- return if @options["case"].nil?
74
-
75
- a = @options["case"].split(",")
76
- @options["case"] = a.collect!(&:to_i)
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 "../../application"
4
- require_relative "../../report/report"
5
- require_relative "../../report/show"
6
- require_relative "../utils"
7
- require_relative "main"
8
- require_relative "result/result"
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)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../application"
3
+ require_relative "../application"
4
4
 
5
5
  # Class Case::Config
6
6
  # * get
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../../application"
3
+ require_relative "../../application"
4
4
 
5
5
  # DSL module methods: assert, missing_method
6
6
  module DSL
@@ -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
- if get(:tt_sequence) == true
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
- alias start play
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 play_in_parallel
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 play_in_sequence
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 "main"
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
- if args.class != Hash
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
- threads = []
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
- verbose = options[:verbose]
76
- ShowReport.new(@report).call(verbose)
53
+ ShowReport.new(@report).call(options[:verbose])
77
54
  end
78
55
  end
@@ -35,6 +35,6 @@ alias task group
35
35
  # Start test
36
36
  # @param block (Block) Extra code executed at the end.
37
37
  def play(&block)
38
- CaseManager.instance.play(&block)
38
+ CaseManager.new.play(&block)
39
39
  end
40
40
  alias start play
@@ -1,14 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "rainbow"
3
4
  require_relative "../application"
4
5
 
5
- module ExportManager
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 self.run(main_report, cases, args)
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
- private_class_method def self.strings2symbols(input)
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
- private_class_method def self.preserve_files
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
- puts("[ERROR] #{e}: Local exec: #{cmd}")
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}
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../application"
4
- require_relative "../case_manager/case/result/result"
4
+ require_relative "../result/result"
5
5
  require_relative "show"
6
6
  require_relative "dsl"
7
7
  require_relative "builtin"
@@ -16,7 +16,7 @@ class Laboratory
16
16
  revise_config_content
17
17
  end
18
18
 
19
- def show_panelconfig
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
- verboseln Rainbow("[WARN] Configfile not found").bright.yellow
73
- verboseln Rainbow(" #{@path[:config]}").white
74
- verboseln Rainbow("[INFO] Recomended content:").bright.yellow
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: {}, cases: nil}
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 :panelconfig, type: :boolean
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 --panelconfig , Only show config file recomendations
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
 
@@ -1,6 +1,6 @@
1
1
  require_relative "../application"
2
2
  require_relative "../utils/configfile_reader"
3
- require_relative "../case_manager/case/result/result"
3
+ require_relative "../result/result"
4
4
  require_relative "../version"
5
5
  require_relative "dsl"
6
6
  require_relative "lang"
@@ -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
- w "#{id.strip},#{line[:grade]},#{line[:moodle_feedback]}\n" unless line[:skip]
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
- alias count! count
39
- alias length count
40
- alias len count
41
- alias size count
42
- alias empty? empty
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
@@ -66,7 +66,7 @@ class Result
66
66
  @content_backup = temp
67
67
  @content = temp.clone
68
68
  end
69
- alias restore! restore
69
+ alias_method :restore!, :restore
70
70
 
71
71
  def value
72
72
  @content[0]
@@ -1,5 +1,5 @@
1
1
  module Teuton
2
- VERSION = "2.4.5"
2
+ VERSION = "2.6.0"
3
3
  APPNAME = "teuton"
4
4
  GEMNAME = "teuton"
5
5
  DOCKERNAME = "dvarrui/#{GEMNAME}"
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 keywords
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 keywords
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.5
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-02-24 00:00:00.000000000 Z
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/case_manager/case/builtin/main.rb
258
- - lib/teuton/case_manager/case/builtin/package.rb
259
- - lib/teuton/case_manager/case/builtin/service.rb
260
- - lib/teuton/case_manager/case/builtin/teuton_file.rb
261
- - lib/teuton/case_manager/case/builtin/teuton_host.rb
262
- - lib/teuton/case_manager/case/builtin/user.rb
263
- - lib/teuton/case_manager/case/case.rb
264
- - lib/teuton/case_manager/case/close.rb
265
- - lib/teuton/case_manager/case/config.rb
266
- - lib/teuton/case_manager/case/dsl/expect.rb
267
- - lib/teuton/case_manager/case/dsl/getset.rb
268
- - lib/teuton/case_manager/case/dsl/goto.rb
269
- - lib/teuton/case_manager/case/dsl/log.rb
270
- - lib/teuton/case_manager/case/dsl/macro.rb
271
- - lib/teuton/case_manager/case/dsl/main.rb
272
- - lib/teuton/case_manager/case/dsl/send.rb
273
- - lib/teuton/case_manager/case/dsl/target.rb
274
- - lib/teuton/case_manager/case/dsl/unique.rb
275
- - lib/teuton/case_manager/case/main.rb
276
- - lib/teuton/case_manager/case/play.rb
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/report/show.rb
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
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "expect"
4
- require_relative "getset"
5
- require_relative "goto"
6
- require_relative "log"
7
- require_relative "macro"
8
- require_relative "send"
9
- require_relative "target"
10
- require_relative "unique"
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "dsl/main"
4
- require_relative "config"
5
- require_relative "close"
6
- require_relative "play"
7
- require_relative "runner"
@@ -1,3 +0,0 @@
1
- require_relative "check_cases"
2
- require_relative "report"
3
- require_relative "utils"
File without changes
File without changes
File without changes
File without changes