teuton 2.7.3 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -4
  3. data/docs/changelog/changelog.1.md +119 -0
  4. data/docs/changelog/changelog.2.md +105 -0
  5. data/docs/diagram.md +10 -10
  6. data/docs/dsl/expect.md +76 -23
  7. data/docs/dsl/export.md +6 -3
  8. data/docs/dsl/result.md +24 -30
  9. data/docs/dsl/send.md +34 -23
  10. data/docs/learn/02-target.md +32 -27
  11. data/docs/learn/13-feedback.md +8 -9
  12. data/docs/learn/25-expect-result.md +39 -0
  13. data/docs/learn/26-expect_sequence.md +79 -0
  14. data/docs/learn/27-run_script.md +91 -0
  15. data/docs/learn/28-upload.md +55 -0
  16. data/docs/learn/README.md +4 -15
  17. data/docs/videos.md +14 -8
  18. data/lib/teuton/case/case.rb +3 -3
  19. data/lib/teuton/case/config.rb +0 -5
  20. data/lib/teuton/case/dsl/all.rb +5 -1
  21. data/lib/teuton/case/dsl/expect.rb +20 -33
  22. data/lib/teuton/case/dsl/expect_exitcode.rb +31 -0
  23. data/lib/teuton/case/dsl/expect_sequence.rb +173 -0
  24. data/lib/teuton/case/dsl/getset.rb +0 -1
  25. data/lib/teuton/case/dsl/host.rb +5 -0
  26. data/lib/teuton/case/dsl/macro.rb +7 -4
  27. data/lib/teuton/case/dsl/run_script.rb +35 -0
  28. data/lib/teuton/case/dsl/send.rb +3 -3
  29. data/lib/teuton/case/dsl/upload.rb +42 -0
  30. data/lib/teuton/case/dsl/weight.rb +12 -0
  31. data/lib/teuton/case/execute/execute_ssh.rb +11 -7
  32. data/lib/teuton/case/host.rb +68 -0
  33. data/lib/teuton/case/play.rb +2 -6
  34. data/lib/teuton/{utils → case}/result/ext_array.rb +0 -1
  35. data/lib/teuton/{utils → case}/result/ext_compare.rb +0 -1
  36. data/lib/teuton/{utils → case}/result/ext_filter.rb +0 -2
  37. data/lib/teuton/{utils → case}/result/result.rb +13 -21
  38. data/lib/teuton/check/checker.rb +82 -0
  39. data/lib/teuton/check/dsl/all.rb +37 -0
  40. data/lib/teuton/check/{builtin.rb → dsl/builtin.rb} +1 -3
  41. data/lib/teuton/check/dsl/expect.rb +90 -0
  42. data/lib/teuton/check/dsl/expect_sequence.rb +29 -0
  43. data/lib/teuton/check/dsl/getset.rb +23 -0
  44. data/lib/teuton/check/dsl/run.rb +35 -0
  45. data/lib/teuton/check/main.rb +29 -0
  46. data/lib/teuton/check/show.rb +75 -100
  47. data/lib/teuton/{utils → deprecated}/application.rb +0 -6
  48. data/lib/teuton/deprecated/application_test.rb +32 -0
  49. data/lib/teuton/readme/dsl/all.rb +32 -0
  50. data/lib/teuton/readme/dsl/expect.rb +29 -0
  51. data/lib/teuton/readme/dsl/getset.rb +33 -0
  52. data/lib/teuton/readme/dsl/run.rb +51 -0
  53. data/lib/teuton/readme/lang.rb +8 -10
  54. data/lib/teuton/readme/main.rb +27 -0
  55. data/lib/teuton/readme/readme.rb +31 -58
  56. data/lib/teuton/readme/result.rb +7 -0
  57. data/lib/teuton/report/formatter/default/txt.rb +2 -2
  58. data/lib/teuton/utils/configfile_reader.rb +8 -4
  59. data/lib/teuton/utils/logger.rb +32 -0
  60. data/lib/teuton/utils/verbose.rb +1 -1
  61. data/lib/teuton/version.rb +1 -1
  62. data/lib/teuton.rb +6 -5
  63. metadata +45 -37
  64. data/docs/CHANGELOG.md +0 -10
  65. data/docs/changelog/v2.0.md +0 -18
  66. data/docs/changelog/v2.1.md +0 -54
  67. data/docs/changelog/v2.2.md +0 -42
  68. data/docs/changelog/v2.3.md +0 -10
  69. data/docs/changelog/v2.4.md +0 -41
  70. data/docs/changelog/v2.5.md +0 -6
  71. data/docs/changelog/v2.6.md +0 -4
  72. data/docs/changelog/v2.7.md +0 -23
  73. data/docs/changelog/version2.1.md +0 -4
  74. data/docs/learn/videos.md +0 -13
  75. data/lib/teuton/case/execute/copy_ssh.rb +0 -70
  76. data/lib/teuton/check/dsl.rb +0 -112
  77. data/lib/teuton/check/laboratory.rb +0 -59
  78. data/lib/teuton/readme/dsl.rb +0 -126
  79. /data/lib/teuton/case/dsl/{goto.rb → run.rb} +0 -0
  80. /data/lib/teuton/{case/deprecated → deprecated}/runner.rb +0 -0
  81. /data/lib/teuton/{case/deprecated → deprecated}/utils.rb +0 -0
@@ -1,23 +0,0 @@
1
-
2
- ## [2.7.3] 20230607
3
-
4
- - [FIX] Hall of fame now use Project class instead of Application.
5
-
6
- ## [2.7.2] 20230607
7
-
8
- - [FIX] Fixed an issue that appeared when exporting reports without feedback after failing to connect to remote computer.
9
-
10
- ## [2.7.1]
11
-
12
- - [FIX] Fixed an issue that appeared when executing test and fail connection to remote computer.
13
-
14
- ## [2.7.0]
15
-
16
- New features:
17
- - [ADD] "teuton config PROJECTPATH" will suggest suitable configuration for the project.
18
- - [ADD] Every one line command output is registered into reports.
19
- - [ADD] "expect_exit 1", check last command exit code is equal to 1.
20
-
21
- Internal changes:
22
- * Application class splited into Settings and Project classes
23
- * Create SendManager similar to ExportManager
@@ -1,4 +0,0 @@
1
-
2
- # TEUTON (version 2.1)
3
-
4
- Goto to [version 2.1](https://github.com/teuton-software/teuton/tree/devel).
data/docs/learn/videos.md DELETED
@@ -1,13 +0,0 @@
1
-
2
- By now there are no English videos. We are sorry!
3
- But if you want to see Spanish videos, here you are:
4
-
5
- Teuton (v2.0):
6
- * [CHAPI19 - Charla Teuton](https://youtu.be/KFWQDfNAFxI?t=12221)
7
-
8
- Sysadmingame (Teuton v1.0)
9
- * [Sysadmingame (1 de 3): Instalación del programa](https://youtu.be/dnyMq9_KDco)
10
- * [Sysadmingame (2 de 3): Crear un caso simple](https://youtu.be/0e2g5Izvc6c)
11
- * [Sysadmingame (3 de 3): Crear un caso complejo](https://youtu.be/ebEK6OXH8kQ)
12
- * [CHAPI16 - Charla sysadmingame](https://youtu.be/cNJaB5xzHHQ)
13
-
@@ -1,70 +0,0 @@
1
- require "net/ssh"
2
- require "net/sftp"
3
- require "rainbow"
4
- require_relative "../../utils/project"
5
- require_relative "../../utils/verbose"
6
- require_relative "execute_base"
7
-
8
- class CopySSH < ExecuteBase
9
- def call(host, localfilename)
10
- # Check params
11
- unless config.get("#{host}_route".to_sym) == "NODATA"
12
- log("'copy script' requires direct host access!", :error)
13
- return false
14
- end
15
-
16
- host = host.to_s
17
-
18
- begin
19
- if sessions[host].nil?
20
- # Open new SSH session
21
- ip = config.get("#{host}_ip".to_sym).to_s
22
- username = config.get("#{host}_username".to_sym).to_s
23
- password = config.get("#{host}_password".to_sym).to_s
24
- port = config.get("#{host}_port".to_sym).to_i
25
- port = 22 if port.zero?
26
-
27
- sessions[host] = Net::SSH.start(
28
- ip,
29
- username,
30
- port: port,
31
- password: password,
32
- keepalive: true,
33
- timeout: 30,
34
- non_interactive: true
35
- )
36
- end
37
- if sessions[host].instance_of? Net::SSH::Connection::Session
38
- copy_to(host, localfilename)
39
- else
40
- "SSH: NO CONNECTION!"
41
- end
42
- rescue => e
43
- sessions[host] = :nosession
44
- conn_status[host] = :error
45
- log("[#{e.class}] SSH on <#{username}@#{ip}>", :error)
46
- end
47
- end
48
-
49
- def copy_to(host, localfilename)
50
- ip = get((host + "_ip").to_sym)
51
- username = get((host + "_username").to_sym).to_s
52
- password = get((host + "_password").to_sym).to_s
53
- port = get((host + "_port").to_sym).to_i
54
- port = 22 if port.zero?
55
-
56
- localfilepath = File.join(Dir.pwd, localfilename)
57
- remotefilepath = File.join(".", File.basename(localfilename))
58
-
59
- # Upload a file or directory to the remote host
60
- begin
61
- Net::SFTP.start(ip, username, password: password, port: port) do |sftp|
62
- sftp.upload!(localfilepath, remotefilepath)
63
- end
64
- rescue
65
- log("copy file: #{localfilename} => #{remotefilepath}", :error)
66
- return false
67
- end
68
- true
69
- end
70
- end
@@ -1,112 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Laboratory
4
- # Include Teuton DSL keywords into Laboratory class
5
- def readme(_text)
6
- # Usefull for "teuton readme" command action.
7
- end
8
-
9
- def target(desc, args = {})
10
- @stats[:targets] += 1
11
- @targetid += 1
12
- weight = args[:weight] || 1.0
13
- verboseln format("(%03<targetid>d) target %<desc>s", targetid: @targetid, desc: desc)
14
- verboseln " weight #{weight}"
15
- end
16
- alias goal target
17
-
18
- def expect(cond)
19
- verboseln " alter #{result.alterations}" unless result.alterations.empty?
20
- verboseln " expect #{cond} (#{cond.class})"
21
- verboseln ""
22
- end
23
-
24
- def expect_first(cond)
25
- verboseln " alter #{result.alterations}" unless result.alterations.empty?
26
- verboseln " expect_first #{cond} (#{cond.class})"
27
- verboseln ""
28
- end
29
-
30
- def expect_last(cond)
31
- verboseln " alter #{result.alterations}" unless result.alterations.empty?
32
- verboseln " expect_last #{cond} (#{cond.class})"
33
- verboseln ""
34
- end
35
-
36
- def expect_none(cond)
37
- verboseln " alter #{result.alterations}" unless result.alterations.empty?
38
- verboseln " expect_none #{cond} (#{cond.class})"
39
- verboseln ""
40
- end
41
-
42
- def expect_one(cond)
43
- verboseln " alter #{result.alterations}" unless result.alterations.empty?
44
- verboseln " expect_one #{cond} (#{cond.class})"
45
- verboseln ""
46
- end
47
-
48
- def get(varname)
49
- @stats[:gets] += 1
50
-
51
- if @gets[varname]
52
- @gets[varname] += 1
53
- else
54
- @gets[varname] = 1
55
- end
56
-
57
- "get(#{varname})"
58
- end
59
-
60
- def run(command, args = {})
61
- args[:exec] = command
62
- host = :localhost
63
- host = args[:on] if args[:on]
64
- goto(host, args)
65
- end
66
-
67
- def goto(host = :localhost, args = {})
68
- result.reset
69
- args[:on] = host unless args[:on]
70
-
71
- if @hosts[host]
72
- @hosts[host] += 1
73
- else
74
- @hosts[host] = 1
75
- end
76
- verboseln " run '#{args[:exec]}' on #{args[:on]}"
77
- end
78
-
79
- # Check macros and _get_vars
80
- def method_missing(method, *args, &block)
81
- a = method.to_s
82
- if args.nil? && block.nil?
83
- instance_eval("get(:#{a[0, a.size - 1]})", __FILE__, __LINE__) if a[a.size - 1] == "?"
84
- end
85
- end
86
-
87
- def gett(option)
88
- get(option)
89
- end
90
-
91
- def unique(key, _value)
92
- @stats[:uniques] += 1
93
-
94
- verboseln " ! Unique value for <#{key}>"
95
- verboseln ""
96
- end
97
-
98
- def log(text = "", type = :info)
99
- @stats[:logs] += 1
100
- verboseln " log [#{type}]: " + text.to_s
101
- end
102
-
103
- def set(key, value)
104
- @stats[:sets] += 1
105
-
106
- key = ":" + key.to_s if key.instance_of? Symbol
107
- value = ":" + value.to_s if value.instance_of? Symbol
108
-
109
- @sets[key] = value
110
- "set(#{key},#{value})"
111
- end
112
- end
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../utils/project"
4
- require_relative "../utils/result/result"
5
- require_relative "show"
6
- require_relative "dsl"
7
- require_relative "builtin"
8
-
9
- def use(filename)
10
- filename += ".rb"
11
- rbfiles = File.join(Project.value[:project_path], "**", filename)
12
- files = Dir.glob(rbfiles)
13
- use = []
14
- files.sort.each { |f| use << f if f.include?(filename) }
15
- require_relative use[0]
16
- Project.value[:uses] << use[0]
17
- end
18
-
19
- def group(name, &block)
20
- Project.value[:groups] << {name: name, block: block}
21
- end
22
- alias task group
23
-
24
- def define_macro(name, *args, &block)
25
- Project.value[:macros][name] = {args: args, block: block}
26
- end
27
- alias def_macro define_macro
28
- alias defmacro define_macro
29
-
30
-
31
- def start(&block)
32
- # Don't do nothing. We are checking test not running it
33
- end
34
- alias play start
35
-
36
- # Show objectives stats from RB script file
37
- class Laboratory
38
- attr_reader :result
39
-
40
- def initialize(script_path, config_path)
41
- @path = {}
42
- @path[:script] = script_path
43
- @path[:dirname] = File.dirname(script_path)
44
- @path[:filename] = File.basename(script_path, ".rb")
45
- @path[:config] = config_path
46
- reset
47
- end
48
-
49
- def reset
50
- @result = Result.new
51
- @targetid = 0
52
- @stats = {groups: 0, targets: 0, uniques: 0, gets: 0, logs: 0, sets: 0}
53
- @gets = {}
54
- @sets = {}
55
- @hosts = {}
56
- @requests = [] # REVISE this
57
- @verbose = Project.value[:verbose]
58
- end
59
- end
@@ -1,126 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Readme
4
- # readme, target, goto, run
5
- # expect,
6
- # gett, set, unique, log
7
- class Readme
8
- def readme(text)
9
- if @action[:target].nil?
10
- # It's a group readme
11
- @current[:readme] << text
12
- else
13
- # It's a target readme
14
- @action[:readme] << text
15
- end
16
- end
17
-
18
- def target(desc, args = {})
19
- previous_host = @action[:host]
20
- @action = {target: desc, host: previous_host, readme: []}
21
- weight = 1.0
22
- weight = args[:weight].to_f if args[:weight]
23
- @action[:weight] = weight
24
- end
25
- alias goal target
26
-
27
- def goto(host = :localhost, args = {})
28
- unless host == :localhost
29
- b = {}
30
- a = "#{host}_ip".to_sym
31
- if @config[:global][a].nil? && !@setted_params.include?(a)
32
- @cases_params << a
33
- end
34
- b[:ip] = @config[:global][a] if @config[:global][a]
35
- b[:ip] = @setted_params[a] if @setted_params[a]
36
-
37
- a = "#{host}_username".to_sym
38
- if @config[:global][a].nil? && !@setted_params.include?(a)
39
- @cases_params << a
40
- end
41
- b[:username] = @config[:global][a] if @config[:global][a]
42
- b[:username] = @setted_params[a] if @setted_params[a]
43
-
44
- a = "#{host}_password".to_sym
45
- if @config[:global][a].nil? && !@setted_params.include?(a)
46
- @cases_params << a
47
- end
48
- b[:password] = @config[:global][a] if @config[:global][a]
49
- b[:password] = @setted_params[a] if @setted_params[a]
50
-
51
- @required_hosts[host.to_s] = b
52
- end
53
- @action[:host] = host
54
- @action[:exec] = args[:exec] || "noexec"
55
- end
56
-
57
- def run(command, args = {})
58
- args[:exec] = command
59
- host = :localhost
60
- host = args[:on] if args[:on]
61
- goto(host, args)
62
- end
63
-
64
- def expect(_cond, _args = {})
65
- @current[:actions] << @action
66
- result.reset
67
- end
68
- alias expect_any expect
69
- alias expect_first expect
70
- alias expect_last expect
71
- alias expect_none expect
72
- alias expect_one expect
73
-
74
- def get(value)
75
- unless @config[:global][value].nil?
76
- @global_params[value] = @config[:global][value]
77
- return @config[:global][value]
78
- end
79
-
80
- return value.to_s.upcase if @setted_params.include? value
81
-
82
- @cases_params << value
83
- value.to_s.upcase
84
- end
85
-
86
- # If a method call is missing, then delegate to concept parent.
87
- # def method_missing(method, args = {})
88
- def method_missing(method, *args, &block)
89
- m = method.to_s
90
- if m[0] == "_"
91
- instance_eval("get(:#{m[1, m.size - 1]})", __FILE__, __LINE__)
92
- # elsif not Application.instance.macros[m].nil?
93
- elsif not Project.value[:macros][m].nil?
94
- puts "macro exec: #{m}"
95
- code = ""
96
- args[0].keys.each { |key| code += "set(:#{key}, '#{args[0][key]}')\n" }
97
- puts code
98
- # instance_eval(code)
99
- # Application.instance.macros[m].call
100
- end
101
- end
102
-
103
- def respond_to_missing?(method_name, include_private = false)
104
- true
105
- end
106
-
107
- def gett(value)
108
- a = get(value)
109
- return "[#{value}](\#required-params)" if @cases_params.include? value
110
- return "[#{value}](\#created-params)" if @setted_params[value]
111
-
112
- "[#{a}](\#global-params)" if @global_params.include? value
113
- end
114
-
115
- def set(key, value)
116
- @setted_params[key] = value
117
- end
118
-
119
- def unique(_key, _value)
120
- # don't do nothing
121
- end
122
-
123
- def log(text = "", type = :info)
124
- @data[:logs] << "[#{type}]: " + text.to_s
125
- end
126
- end
File without changes