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