teuton 3.3.0 → 3.4.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.
- checksums.yaml +4 -4
- data/README.md +12 -14
- data/docs/commands/README.md +5 -4
- data/docs/commands/{readme.md → doc.md} +3 -5
- data/docs/commands/help.md +8 -8
- data/docs/devel/todo.md +1 -4
- data/docs/dsl/README.md +9 -8
- data/docs/dsl/event.md +172 -0
- data/docs/learn/01-cmd_new.md +1 -1
- data/docs/learn/02-target.md +18 -18
- data/docs/learn/03-remote_hosts.md +1 -1
- data/docs/learn/04-config.md +15 -13
- data/docs/learn/05-use.md +1 -1
- data/docs/learn/06-cmd_check.md +2 -2
- data/docs/learn/07-target_weight.md +4 -2
- data/docs/learn/08-unique_values.md +1 -1
- data/docs/learn/09-send.md +2 -2
- data/docs/learn/10-debug.md +10 -9
- data/docs/learn/11-export.md +1 -1
- data/docs/learn/12-preserve.md +4 -4
- data/docs/learn/13-feedback.md +3 -3
- data/docs/learn/14-moodle_id.md +3 -3
- data/docs/learn/15-readme.md +10 -10
- data/docs/learn/16-include.md +3 -3
- data/docs/learn/17-alias.md +2 -2
- data/docs/learn/18-log.md +3 -2
- data/docs/learn/19-read_vars.md +1 -1
- data/docs/learn/20-macros.md +1 -1
- data/docs/learn/21-exit_codes.md +1 -1
- data/docs/learn/22-result.md +1 -1
- data/docs/learn/23-test-code.md +1 -1
- data/docs/learn/24-test-sql.md +1 -1
- data/docs/learn/25-expect-result.md +1 -1
- data/docs/learn/26-expect_sequence.md +1 -1
- data/docs/learn/27-run_script.md +1 -1
- data/docs/learn/28-upload.md +3 -1
- data/docs/learn/31-event-stop.md +134 -0
- data/docs/learn/32-event-zero.md +127 -0
- data/docs/more.md +4 -1
- data/lib/teuton/case/action/manager.rb +146 -11
- data/lib/teuton/case/case.rb +2 -0
- data/lib/teuton/case/close.rb +4 -4
- data/lib/teuton/case/dsl/event.rb +1 -20
- data/lib/teuton/case/dsl/expect.rb +1 -1
- data/lib/teuton/case/dsl/log.rb +8 -3
- data/lib/teuton/case/dsl/target.rb +6 -1
- data/lib/teuton/case_manager/show_resume_report.rb +2 -2
- data/lib/teuton/check/checker.rb +2 -0
- data/lib/teuton/check/dsl/all.rb +8 -22
- data/lib/teuton/check/dsl/event.rb +10 -0
- data/lib/teuton/check/dsl/expect.rb +8 -16
- data/lib/teuton/check/dsl/target.rb +17 -0
- data/lib/teuton/check/show.rb +12 -12
- data/lib/teuton/cli/app.rb +15 -7
- data/lib/teuton/readme/dsl/all.rb +6 -1
- data/lib/teuton/report/formatter/default/txt.rb +9 -8
- data/lib/teuton/report/formatter/resume/txt.rb +5 -5
- data/lib/teuton/report/report.rb +2 -35
- data/lib/teuton/version.rb +1 -1
- metadata +11 -3
|
@@ -2,23 +2,83 @@ require_relative "action"
|
|
|
2
2
|
|
|
3
3
|
class Case
|
|
4
4
|
class ActionManager
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
AVAILABLE = [
|
|
6
|
+
%i[last_target failed now],
|
|
7
|
+
%i[last_target passed now],
|
|
8
|
+
%i[every_target failed eachtime],
|
|
9
|
+
%i[every_target passed eachtime],
|
|
10
|
+
%i[all_targets failed atend],
|
|
11
|
+
%i[all_targets passed atend]
|
|
12
|
+
].freeze
|
|
9
13
|
attr_reader :actions, :events, :current_action
|
|
14
|
+
attr_writer :log
|
|
10
15
|
|
|
11
16
|
def initialize
|
|
12
17
|
@current_action = nil
|
|
13
18
|
@actions = []
|
|
14
|
-
@events =
|
|
19
|
+
@events = []
|
|
15
20
|
@stopped = false
|
|
21
|
+
@log = nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def check_event(args)
|
|
25
|
+
object = args[:on]
|
|
26
|
+
condition = args[:when]
|
|
27
|
+
options = AVAILABLE.select { |obj, cond| obj == object && cond == condition }
|
|
28
|
+
if options.empty?
|
|
29
|
+
Logger.warn "Unkown! Event on: #{object}, when: #{condition}"
|
|
30
|
+
return false
|
|
31
|
+
elsif options.count > 1
|
|
32
|
+
Logger.warn "More than one definition! Event on: #{object}, when: #{condition}"
|
|
33
|
+
end
|
|
34
|
+
true
|
|
16
35
|
end
|
|
17
36
|
|
|
18
|
-
def add_event(
|
|
37
|
+
def add_event(args, block)
|
|
38
|
+
return unless check_event(args)
|
|
39
|
+
|
|
40
|
+
object = args[:on]
|
|
41
|
+
condition = args[:when]
|
|
42
|
+
if object == :last_target
|
|
43
|
+
trigger_on_last_target(args, block)
|
|
44
|
+
elsif object == :all_targets
|
|
45
|
+
trigger_on_all_targets(args, block)
|
|
46
|
+
else
|
|
47
|
+
id = events.count
|
|
48
|
+
events << {id: id, args: args, block: block, type: :eachtime}
|
|
49
|
+
log "Register (sinde target #{last_action.id}) event on: #{object} , when: #{condition}"
|
|
50
|
+
end
|
|
19
51
|
end
|
|
20
52
|
|
|
21
|
-
def
|
|
53
|
+
def close(report)
|
|
54
|
+
trigger_events!
|
|
55
|
+
@current_action = nil
|
|
56
|
+
|
|
57
|
+
# Calculate final values
|
|
58
|
+
@grade = @max_weight = @good_weight = @fails_weight = @fail_counter = 0
|
|
59
|
+
@history = ""
|
|
60
|
+
|
|
61
|
+
@actions.each do |action|
|
|
62
|
+
@max_weight += action.weight if action.weight.positive?
|
|
63
|
+
|
|
64
|
+
if action.check
|
|
65
|
+
@good_weight += action.weight
|
|
66
|
+
@history += Settings.letter[:good]
|
|
67
|
+
else
|
|
68
|
+
@fails_weight += action.weight
|
|
69
|
+
@fail_counter += 1
|
|
70
|
+
@history += Settings.letter[:fail]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
report.lines += @actions.map(&:to_h)
|
|
75
|
+
report.history = @history
|
|
76
|
+
|
|
77
|
+
report.tail[:max_weight] = @max_weight
|
|
78
|
+
report.tail[:good_weight] = @good_weight
|
|
79
|
+
report.tail[:fail_weight] = @fails_weight
|
|
80
|
+
report.tail[:fail_counter] = @fail_counter
|
|
81
|
+
report.tail[:grade] = calculate_grade(report)
|
|
22
82
|
end
|
|
23
83
|
|
|
24
84
|
def last_action
|
|
@@ -38,16 +98,28 @@ class Case
|
|
|
38
98
|
@current_action
|
|
39
99
|
end
|
|
40
100
|
|
|
101
|
+
def current_score
|
|
102
|
+
current_good_weight = @actions.sum(&:score)
|
|
103
|
+
value = current_good_weight.to_f / @max_weight
|
|
104
|
+
value = 0.0 if value.nan?
|
|
105
|
+
value
|
|
106
|
+
end
|
|
107
|
+
|
|
41
108
|
def stopped?
|
|
42
109
|
@stopped
|
|
43
110
|
end
|
|
44
111
|
|
|
45
112
|
def scores_to_zero
|
|
46
|
-
@
|
|
113
|
+
@actions.each do |action|
|
|
114
|
+
action.score = 0.0
|
|
115
|
+
action.description << " (SCORE TO ZERO)"
|
|
116
|
+
end
|
|
117
|
+
log("Scores set to ZERO!")
|
|
47
118
|
end
|
|
48
119
|
|
|
49
120
|
def stop
|
|
50
|
-
@
|
|
121
|
+
@stopped = true
|
|
122
|
+
log("Test STOPPED!")
|
|
51
123
|
end
|
|
52
124
|
|
|
53
125
|
def to_h
|
|
@@ -55,9 +127,72 @@ class Case
|
|
|
55
127
|
end
|
|
56
128
|
|
|
57
129
|
def trigger_events!
|
|
58
|
-
@events
|
|
59
|
-
# TODO: Do something
|
|
130
|
+
@events.each do |event|
|
|
131
|
+
# TODO: Do something if type == :eachtime
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
return unless @stopped
|
|
135
|
+
|
|
136
|
+
@current_action.description = "TEST STOPPED!"
|
|
137
|
+
@current_action.command = ""
|
|
138
|
+
@current_action.exec = ""
|
|
139
|
+
@current_action.conn_type = "?"
|
|
140
|
+
@current_action.duration = "?"
|
|
141
|
+
@current_action.result = ""
|
|
142
|
+
@current_action.output = ""
|
|
143
|
+
@current_action.alterations = ""
|
|
144
|
+
@current_action.expected = ""
|
|
145
|
+
@current_action.check = false
|
|
146
|
+
@current_action.score = 0.0
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
private
|
|
150
|
+
|
|
151
|
+
def log(...)
|
|
152
|
+
return if @log.nil?
|
|
153
|
+
|
|
154
|
+
@log.call(...)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def calculate_grade(report)
|
|
158
|
+
current_good_weight = @actions.sum(&:score)
|
|
159
|
+
current_score = current_good_weight.to_f / @max_weight
|
|
160
|
+
current_score = 0.0 if current_score.nan?
|
|
161
|
+
|
|
162
|
+
@grade = (100.0 * current_score).round
|
|
163
|
+
|
|
164
|
+
@grade = 0.0 if report.tail[:unique_fault].positive?
|
|
165
|
+
@grade
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def trigger_on_last_target(args, block)
|
|
169
|
+
do_ok = last_action.check && args[:when] == :is_ok
|
|
170
|
+
do_failed = !last_action.check && args[:when] == :failed
|
|
171
|
+
unless do_ok || do_failed
|
|
172
|
+
id = events.count
|
|
173
|
+
events << {id: id, args: args, block: block, status: :cancelled}
|
|
174
|
+
log "Event[#{id}] cancelled because target[#{last_action.id}] #{args[:when]}"
|
|
175
|
+
end
|
|
176
|
+
id = events.count
|
|
177
|
+
events << {id: id, args: args, block: block, status: :triggered}
|
|
178
|
+
log "Event[#{id}] triggered because target[#{last_action.id}] #{args[:when]}"
|
|
179
|
+
instance_exec(**args, &block) if block
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def trigger_on_all_targets(args, block)
|
|
183
|
+
all_targets_passed = @actions.map { _1.check }.all?
|
|
184
|
+
do_all_passed = all_targets_passed && args[:when] == :is_ok
|
|
185
|
+
all_targets_failed = @actions.map { !_1.check }.all?
|
|
186
|
+
do_all_failed = all_targets_failed && args[:when] == :failed
|
|
187
|
+
unless do_all_passed || do_all_failed
|
|
188
|
+
id = events.count
|
|
189
|
+
events << {id: id, args: args, block: block, status: :cancelled}
|
|
190
|
+
log "Event[#{id}] cancelled. Not all_targets[1, #{last_action.id}] #{args[:when]}"
|
|
60
191
|
end
|
|
192
|
+
id = events.count
|
|
193
|
+
events << {id: id, args: args, block: block, status: :triggered}
|
|
194
|
+
log "Event[#{id}] triggered. All_targets[1, #{last_action.id}] #{args[:when]}"
|
|
195
|
+
instance_exec(**args, &block) if block
|
|
61
196
|
end
|
|
62
197
|
end
|
|
63
198
|
end
|
data/lib/teuton/case/case.rb
CHANGED
|
@@ -49,6 +49,7 @@ class Case
|
|
|
49
49
|
@unique_values = {}
|
|
50
50
|
@result = Result.new
|
|
51
51
|
@action_manager = ActionManager.new
|
|
52
|
+
@action_manager.log = method(:log)
|
|
52
53
|
@action = @action_manager.next_action
|
|
53
54
|
@uniques = []
|
|
54
55
|
@sessions = {} # Store opened sessions for this case
|
|
@@ -69,6 +70,7 @@ class Case
|
|
|
69
70
|
return 0.0 if skip
|
|
70
71
|
|
|
71
72
|
@report.tail[:grade]
|
|
73
|
+
# @action_manager.score
|
|
72
74
|
end
|
|
73
75
|
|
|
74
76
|
def last_action
|
data/lib/teuton/case/close.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
class Case
|
|
4
4
|
def close(uniques)
|
|
5
5
|
# Invoked from check_cases!
|
|
6
|
+
@action_manager.close(@report)
|
|
6
7
|
|
|
7
8
|
fails = 0
|
|
8
9
|
uniques.each_pair do |key, values|
|
|
@@ -12,16 +13,15 @@ class Case
|
|
|
12
13
|
log_unique_message(key, values)
|
|
13
14
|
end
|
|
14
15
|
@report.tail[:unique_fault] = fails
|
|
15
|
-
@report.close
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
private
|
|
19
19
|
|
|
20
20
|
def log_unique_message(key, value)
|
|
21
|
-
log("UNIQUE:", :
|
|
21
|
+
log("UNIQUE:", :warn)
|
|
22
22
|
begin
|
|
23
|
-
log("
|
|
24
|
-
log("
|
|
23
|
+
log(" ├── Value => #{key}", :warn)
|
|
24
|
+
log(" └── Conflicts => #{value}", :warn)
|
|
25
25
|
rescue => e
|
|
26
26
|
log(key, :error)
|
|
27
27
|
log(e.to_s, :error)
|
|
@@ -1,24 +1,5 @@
|
|
|
1
1
|
module DSL
|
|
2
2
|
def event(**args, &block)
|
|
3
|
-
|
|
4
|
-
unless Case::ActionManager::OBJECTS.include? object
|
|
5
|
-
Logger.warn "Incorrect argument in event on: #{object} ..."
|
|
6
|
-
Logger.info "Valid OBJECTS: #{Case::ActionManager::OBJECTS.join(",")}"
|
|
7
|
-
return
|
|
8
|
-
end
|
|
9
|
-
condition = args[:when]
|
|
10
|
-
unless Case::ActionManager::CONDITIONS.include? condition
|
|
11
|
-
Logger.warn "Incorrect argument in event on: :#{object} when: #{condition}"
|
|
12
|
-
Logger.info "Valid CONDITIONS: #{Case::ActionManager::CONDITIONS.join(",")}"
|
|
13
|
-
return
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
if object == :every_target
|
|
17
|
-
@action_manager.events << {args: args, block: block}
|
|
18
|
-
else
|
|
19
|
-
# last_target, all_targets
|
|
20
|
-
log "Event triggered on: #{object}, when: #{condition} Target #{@action.id}"
|
|
21
|
-
# TODO: do something more
|
|
22
|
-
end
|
|
3
|
+
@action_manager.add_event(args, block)
|
|
23
4
|
end
|
|
24
5
|
end
|
data/lib/teuton/case/dsl/log.rb
CHANGED
|
@@ -4,12 +4,17 @@ module DSL
|
|
|
4
4
|
# type => :info, :warn or :error
|
|
5
5
|
def log(text = "", type = :info)
|
|
6
6
|
s = " INFO"
|
|
7
|
-
s =
|
|
8
|
-
s =
|
|
7
|
+
s = " WARN" if type == :warn
|
|
8
|
+
s = "ERROR" if type == :error
|
|
9
9
|
t = Time.now
|
|
10
10
|
f = format("%<hour>02d:%<min>02d:%<sec>02d", {hour: t.hour, min: t.min, sec: t.sec})
|
|
11
11
|
msg = "[#{f}] #{s}| #{text}"
|
|
12
12
|
msg = "[#{f}] #{text}" if s == ""
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
colored_msg = msg
|
|
15
|
+
colored_msg = Rainbow(msg).yellow.bright if type == :warn
|
|
16
|
+
colored_msg = Rainbow(msg).bg(:red) if type == :error
|
|
17
|
+
|
|
18
|
+
@report.lines << colored_msg
|
|
14
19
|
end
|
|
15
20
|
end
|
|
@@ -2,11 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
# DSL#target
|
|
4
4
|
module DSL
|
|
5
|
-
def
|
|
5
|
+
def doc(_text)
|
|
6
6
|
# Usefull when running.
|
|
7
7
|
# It's works only with "teuton reamde" command action.
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
def readme(...)
|
|
11
|
+
Logger.warn("Keyword deprecated: Replace 'readme' by 'doc'.")
|
|
12
|
+
doc(...)
|
|
13
|
+
end
|
|
14
|
+
|
|
10
15
|
def target(desc, args = {})
|
|
11
16
|
@action.description = desc.to_s
|
|
12
17
|
w = args[:weight] || 1.0
|
|
@@ -46,7 +46,7 @@ class ShowResumeReport
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def show_case_list
|
|
49
|
-
Logger.puts Rainbow(" CASE RESULTS").bright
|
|
49
|
+
Logger.puts Rainbow(" \u{2630} CASE RESULTS").bright
|
|
50
50
|
table = Terminal::Table.new do |t|
|
|
51
51
|
t.style = {border: :unicode}
|
|
52
52
|
t.add_row %w[CASE MEMBERS GRADE STATE]
|
|
@@ -62,7 +62,7 @@ class ShowResumeReport
|
|
|
62
62
|
@report.lines.each { |line| errors += line[:conn_status].size }
|
|
63
63
|
return if errors.zero?
|
|
64
64
|
|
|
65
|
-
Logger.puts Rainbow(" CONN ERRORS").bright
|
|
65
|
+
Logger.puts Rainbow(" \u{1f5f2} CONN ERRORS").bright
|
|
66
66
|
table = Terminal::Table.new do |t|
|
|
67
67
|
t.style = {border: :unicode}
|
|
68
68
|
t.add_row %w[CASE MEMBERS HOST ERROR]
|
data/lib/teuton/check/checker.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../case/action/manager"
|
|
3
4
|
require_relative "../case/dsl/macro"
|
|
4
5
|
require_relative "../case/result/result"
|
|
5
6
|
require_relative "../utils/project"
|
|
@@ -14,6 +15,7 @@ class Checker
|
|
|
14
15
|
attr_reader :result
|
|
15
16
|
|
|
16
17
|
def initialize(script_path, config_path)
|
|
18
|
+
@action_manager = Case::ActionManager.new
|
|
17
19
|
@path = {}
|
|
18
20
|
@path[:script] = script_path
|
|
19
21
|
@path[:dirname] = File.dirname(script_path)
|
data/lib/teuton/check/dsl/all.rb
CHANGED
|
@@ -1,45 +1,31 @@
|
|
|
1
1
|
require_relative "builtin"
|
|
2
2
|
require_relative "expect"
|
|
3
|
+
require_relative "event"
|
|
3
4
|
require_relative "getset"
|
|
4
5
|
require_relative "run"
|
|
6
|
+
require_relative "target"
|
|
5
7
|
|
|
6
8
|
module CheckDSL
|
|
7
|
-
def event(**args) # , &block)
|
|
8
|
-
@stats[:events] += 1
|
|
9
|
-
# args = on: XXX, when: XXX
|
|
10
|
-
Logger.puts " event on: #{args[:on]}, when: #{args[:when]}"
|
|
11
|
-
end
|
|
12
|
-
|
|
13
9
|
def log(text = "", type = :info)
|
|
14
10
|
@stats[:logs] += 1
|
|
15
11
|
prefix = (type == :info) ? "" : "#{type.to_s.upcase}: "
|
|
16
12
|
Logger.puts " log #{prefix}" + text.to_s
|
|
17
13
|
end
|
|
18
14
|
|
|
19
|
-
def
|
|
15
|
+
def doc(text)
|
|
20
16
|
@stats[:readmes] += 1
|
|
21
|
-
Logger.puts "
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def target(desc, args = {})
|
|
25
|
-
Logger.warn "WARN Previous 'target' requires 'expect'" if @target_begin
|
|
26
|
-
@target_begin = true
|
|
27
|
-
@stats[:targets] += 1
|
|
28
|
-
@targetid += 1
|
|
29
|
-
weight = args[:weight] ? args[:weight].to_f : 1.0
|
|
30
|
-
Logger.puts format("(%03<targetid>d) target %<desc>s", targetid: @targetid, desc: desc)
|
|
31
|
-
Logger.puts " weight #{weight}"
|
|
17
|
+
Logger.puts " doc #{text}"
|
|
32
18
|
end
|
|
33
19
|
|
|
34
|
-
def
|
|
35
|
-
Logger.warn("Keyword deprecated: Replace '
|
|
36
|
-
|
|
20
|
+
def readme(...)
|
|
21
|
+
Logger.warn("Keyword deprecated: Replace 'readme' by 'doc'.")
|
|
22
|
+
doc(...)
|
|
37
23
|
end
|
|
38
24
|
|
|
39
25
|
def unique(key, _value)
|
|
40
26
|
@stats[:uniques] += 1
|
|
41
27
|
|
|
42
|
-
Logger.puts "
|
|
28
|
+
Logger.puts " \u{26bf} unique value for <#{key}>"
|
|
43
29
|
Logger.puts ""
|
|
44
30
|
end
|
|
45
31
|
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module CheckDSL
|
|
2
|
+
def event(**args)
|
|
3
|
+
if @action_manager.check_event(args)
|
|
4
|
+
@stats[:events] += 1
|
|
5
|
+
Logger.puts " \u{1f5f2} event on: #{args[:on]}, when: #{args[:when]}"
|
|
6
|
+
else
|
|
7
|
+
Logger.puts " \u{2718} event on: #{args[:on]}, when: #{args[:when]} (UNKOWN!)"
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -2,48 +2,42 @@ require_relative "expect_sequence"
|
|
|
2
2
|
|
|
3
3
|
module CheckDSL
|
|
4
4
|
def expect(cond)
|
|
5
|
-
Logger.warn "
|
|
5
|
+
Logger.warn " \u{1f6c8} 'expect' with no previous 'target'" unless @target_begin
|
|
6
6
|
Logger.puts " alter #{result.alterations}" unless result.alterations.empty?
|
|
7
7
|
Logger.puts " expect #{cond} (#{cond.class})"
|
|
8
|
-
Logger.puts ""
|
|
9
8
|
@target_begin = false
|
|
10
9
|
end
|
|
11
10
|
|
|
12
11
|
def expect_exit(cond)
|
|
13
|
-
Logger.warn "
|
|
12
|
+
Logger.warn " \u{1f6c8} 'expect' with no previous 'target'" unless @target_begin
|
|
14
13
|
Logger.puts " expect_exit #{cond} (#{cond.class})"
|
|
15
|
-
Logger.puts ""
|
|
16
14
|
@target_begin = false
|
|
17
15
|
end
|
|
18
16
|
|
|
19
17
|
def expect_fail
|
|
20
|
-
Logger.warn "
|
|
18
|
+
Logger.warn " \u{1f6c8} 'expect' with no previous 'target'" unless @target_begin
|
|
21
19
|
Logger.puts " expect_fail"
|
|
22
|
-
Logger.puts ""
|
|
23
20
|
@target_begin = false
|
|
24
21
|
end
|
|
25
22
|
|
|
26
23
|
def expect_first(cond)
|
|
27
|
-
Logger.warn "
|
|
24
|
+
Logger.warn " \u{1f6c8} 'expect' with no previous 'target'" unless @target_begin
|
|
28
25
|
Logger.puts " alter #{result.alterations}" unless result.alterations.empty?
|
|
29
26
|
Logger.puts " expect_first #{cond} (#{cond.class})"
|
|
30
|
-
Logger.puts ""
|
|
31
27
|
@target_begin = false
|
|
32
28
|
end
|
|
33
29
|
|
|
34
30
|
def expect_last(cond)
|
|
35
|
-
Logger.warn "
|
|
31
|
+
Logger.warn " \u{1f6c8} 'expect' with no previous 'target'" unless @target_begin
|
|
36
32
|
Logger.puts " alter #{result.alterations}" unless result.alterations.empty?
|
|
37
33
|
Logger.puts " expect_last #{cond} (#{cond.class})"
|
|
38
|
-
Logger.puts ""
|
|
39
34
|
@target_begin = false
|
|
40
35
|
end
|
|
41
36
|
|
|
42
37
|
def expect_none(cond = nil, args = {})
|
|
43
|
-
Logger.warn "
|
|
38
|
+
Logger.warn " \u{1f6c8} 'expect' with no previous 'target'" unless @target_begin
|
|
44
39
|
Logger.puts " alter #{result.alterations}" unless result.alterations.empty?
|
|
45
40
|
Logger.puts " expect_none #{cond} (#{cond.class})"
|
|
46
|
-
Logger.puts ""
|
|
47
41
|
@target_begin = false
|
|
48
42
|
end
|
|
49
43
|
|
|
@@ -56,19 +50,17 @@ module CheckDSL
|
|
|
56
50
|
end
|
|
57
51
|
|
|
58
52
|
def expect_one(cond)
|
|
59
|
-
Logger.warn "
|
|
53
|
+
Logger.warn " \u{1f6c8} 'expect' with no previous 'target'" unless @target_begin
|
|
60
54
|
Logger.puts " alter #{result.alterations}" unless result.alterations.empty?
|
|
61
55
|
Logger.puts " expect_one #{cond} (#{cond.class})"
|
|
62
|
-
Logger.puts ""
|
|
63
56
|
@target_begin = false
|
|
64
57
|
end
|
|
65
58
|
|
|
66
59
|
def expect_sequence(&block)
|
|
67
|
-
Logger.warn "
|
|
60
|
+
Logger.warn " \u{1f6c8} 'expect' with no previous 'target'" unless @target_begin
|
|
68
61
|
seq = CheckDSL::ExpectSequence.new
|
|
69
62
|
seq.is_valid?(&block)
|
|
70
63
|
Logger.puts " expect_sequence #{seq.expected}"
|
|
71
|
-
Logger.puts ""
|
|
72
64
|
@target_begin = false
|
|
73
65
|
end
|
|
74
66
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module CheckDSL
|
|
2
|
+
def target(desc, args = {})
|
|
3
|
+
Logger.warn "Previous 'target' requires 'expect'" if @target_begin
|
|
4
|
+
@target_begin = true
|
|
5
|
+
@stats[:targets] += 1
|
|
6
|
+
@targetid += 1
|
|
7
|
+
weight = args[:weight] ? args[:weight].to_f : 1.0
|
|
8
|
+
Logger.puts ""
|
|
9
|
+
Logger.puts format("(%03<targetid>d) target %<desc>s", targetid: @targetid, desc: desc)
|
|
10
|
+
Logger.puts " weight #{weight}"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def goal(...)
|
|
14
|
+
Logger.warn("Keyword deprecated: Replace 'goal' by 'target'.")
|
|
15
|
+
target(...)
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/teuton/check/show.rb
CHANGED
|
@@ -64,19 +64,19 @@ class ShowCheck
|
|
|
64
64
|
end
|
|
65
65
|
t.add_row ["Groups", @stats[:groups]]
|
|
66
66
|
t.add_row ["Targets", @stats[:targets]]
|
|
67
|
-
t.add_row ["Events", @stats[:events]]
|
|
67
|
+
t.add_row ["Events", @stats[:events]]
|
|
68
68
|
runs = @stats[:hosts].values.sum
|
|
69
69
|
t.add_row ["Runs", runs]
|
|
70
|
-
@stats[:hosts].each_pair { |k, v| t.add_row ["
|
|
70
|
+
@stats[:hosts].each_pair { |k, v| t.add_row ["- #{k}", v] }
|
|
71
71
|
t.add_row ["Uniques", @stats[:uniques]] if @stats[:uniques].positive?
|
|
72
72
|
t.add_row ["Logs", @stats[:logs]] if @stats[:logs].positive?
|
|
73
|
-
t.add_row ["
|
|
73
|
+
t.add_row ["Docs", @stats[:readmes]] if @stats[:readmes].positive?
|
|
74
74
|
|
|
75
75
|
if @stats[:gets].size.positive?
|
|
76
76
|
total = @stats[:gets].values.sum
|
|
77
77
|
t.add_row ["Gets", total]
|
|
78
78
|
list = @stats[:gets].sort_by { |_k, v| v }
|
|
79
|
-
list.reverse_each { |item| t.add_row ["
|
|
79
|
+
list.reverse_each { |item| t.add_row [" - #{item[0]}", item[1].to_s] }
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
if @stats[:sets].size.positive?
|
|
@@ -89,7 +89,7 @@ class ShowCheck
|
|
|
89
89
|
uploads.each { |value| t.add_row ["", value] }
|
|
90
90
|
end
|
|
91
91
|
end
|
|
92
|
-
Logger.puts "#{table}\n"
|
|
92
|
+
Logger.puts "\n#{table}\n"
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
private
|
|
@@ -100,16 +100,16 @@ class ShowCheck
|
|
|
100
100
|
next if k == :localhost
|
|
101
101
|
|
|
102
102
|
if k.instance_of? Symbol
|
|
103
|
-
script_vars <<
|
|
104
|
-
script_vars <<
|
|
105
|
-
script_vars <<
|
|
103
|
+
script_vars << :"#{k}_ip"
|
|
104
|
+
script_vars << :"#{k}_username"
|
|
105
|
+
script_vars << :"#{k}_password"
|
|
106
106
|
else
|
|
107
|
-
script_vars << k
|
|
108
|
-
script_vars << k
|
|
109
|
-
script_vars << k
|
|
107
|
+
script_vars << "#{k}_ip"
|
|
108
|
+
script_vars << "#{k}_username"
|
|
109
|
+
script_vars << "#{k}_password"
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
|
-
@stats[:gets].
|
|
112
|
+
@stats[:gets].each_key { |value| script_vars << value }
|
|
113
113
|
script_vars
|
|
114
114
|
end
|
|
115
115
|
end
|
data/lib/teuton/cli/app.rb
CHANGED
|
@@ -50,22 +50,30 @@ module Teuton
|
|
|
50
50
|
Teuton.check(projectpath, opt)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
map ["--
|
|
53
|
+
map ["--doc"] => "doc"
|
|
54
54
|
option :lang, type: :string
|
|
55
|
-
desc "
|
|
55
|
+
desc "doc DIRECTORY", "Display practice exercise statement"
|
|
56
56
|
long_desc <<-LONGDESC
|
|
57
57
|
|
|
58
|
-
(1) teuton
|
|
59
|
-
,
|
|
58
|
+
(1) teuton doc foo
|
|
59
|
+
, Display exercise statement from foo/start.rb.
|
|
60
60
|
|
|
61
|
-
(2) teuton
|
|
62
|
-
,
|
|
61
|
+
(2) teuton doc foo/demo.rb
|
|
62
|
+
, Display exercise statement from foo/demo.rb.
|
|
63
63
|
LONGDESC
|
|
64
64
|
|
|
65
|
-
def
|
|
65
|
+
def doc(projectpath)
|
|
66
66
|
Teuton.readme(projectpath, options)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
+
map ["--readme"] => "readme"
|
|
70
|
+
desc "readme DIRECTORY", "DEPRECATED! Use 'teuton doc'"
|
|
71
|
+
|
|
72
|
+
def readme(projectpath)
|
|
73
|
+
Logger.info "Use: teuton doc"
|
|
74
|
+
Logger.warn "'teuton readme' has been DEPRECATED!"
|
|
75
|
+
end
|
|
76
|
+
|
|
69
77
|
map ["--run", "run"] => "play"
|
|
70
78
|
option :export, type: :string
|
|
71
79
|
option :cname, type: :string
|
|
@@ -5,7 +5,7 @@ require_relative "getset"
|
|
|
5
5
|
require_relative "run"
|
|
6
6
|
|
|
7
7
|
module ReadmeDSL
|
|
8
|
-
def
|
|
8
|
+
def doc(text)
|
|
9
9
|
if @action.description.nil?
|
|
10
10
|
@current[:readme] << text # It's a group readme
|
|
11
11
|
else
|
|
@@ -13,6 +13,11 @@ module ReadmeDSL
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
def readme(...)
|
|
17
|
+
Logger.warn("Keyword deprecated: Replace 'readme' by 'doc'.")
|
|
18
|
+
doc(...)
|
|
19
|
+
end
|
|
20
|
+
|
|
16
21
|
def target(desc, args = {})
|
|
17
22
|
previous_host = @action.host
|
|
18
23
|
@action.description = desc
|