teuton 2.4.5 → 2.6.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.
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