ztk 3.0.4 → 3.1.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/lib/ztk/profiler/core.rb +8 -3
- data/lib/ztk/version.rb +1 -1
- data/spec/ztk/ansi_spec.rb +3 -3
- data/spec/ztk/background_spec.rb +22 -22
- data/spec/ztk/base_spec.rb +1 -1
- data/spec/ztk/benchmark_spec.rb +13 -20
- data/spec/ztk/command_spec.rb +48 -61
- data/spec/ztk/config_spec.rb +16 -9
- data/spec/ztk/locator_spec.rb +3 -3
- data/spec/ztk/logger_spec.rb +40 -35
- data/spec/ztk/parallel_spec.rb +20 -20
- data/spec/ztk/profiler_spec.rb +100 -0
- data/spec/ztk/rescue_retry_spec.rb +18 -18
- data/spec/ztk/spinner_spec.rb +3 -3
- data/spec/ztk/ssh_spec.rb +87 -548
- data/spec/ztk/tcp_socket_check_spec.rb +11 -11
- data/spec/ztk/template_spec.rb +14 -13
- data/spec/ztk/ui_spec.rb +9 -9
- data/spec/ztk/version_spec.rb +2 -2
- metadata +4 -2
data/spec/ztk/config_spec.rb
CHANGED
@@ -22,19 +22,23 @@ require "spec_helper"
|
|
22
22
|
|
23
23
|
describe ZTK::Config do
|
24
24
|
|
25
|
-
subject
|
25
|
+
subject do
|
26
|
+
class C
|
27
|
+
extend(ZTK::Config)
|
28
|
+
end
|
29
|
+
end
|
26
30
|
|
27
31
|
describe "class" do
|
28
32
|
|
29
33
|
it "should be a kind of ZTK::Config" do
|
30
|
-
subject.
|
34
|
+
expect(subject).to be_a_kind_of ZTK::Config
|
31
35
|
end
|
32
36
|
|
33
37
|
describe "default config" do
|
34
38
|
|
35
39
|
it "should have an OpenStruct object for holding the configuration" do
|
36
|
-
subject.configuration.
|
37
|
-
subject.keys.length.
|
40
|
+
expect(subject.configuration).to be_an_instance_of OpenStruct
|
41
|
+
expect(subject.keys.length).to be == 0
|
38
42
|
end
|
39
43
|
|
40
44
|
end
|
@@ -45,20 +49,23 @@ describe ZTK::Config do
|
|
45
49
|
|
46
50
|
it "should allow setting of arbratary configuration keys" do
|
47
51
|
subject.thing = "something"
|
48
|
-
|
49
|
-
subject
|
52
|
+
|
53
|
+
expect(subject.thing).to be == "something"
|
54
|
+
expect(subject[:thing]).to be == "something"
|
50
55
|
end
|
51
56
|
|
52
57
|
it "should allow hash bracket style access to configuration keys" do
|
53
58
|
subject[:thing] = "nothing"
|
54
|
-
|
59
|
+
|
60
|
+
expect(subject[:thing]).to be == "nothing"
|
55
61
|
end
|
56
62
|
|
57
63
|
it "should allow loading of configurations from disk" do
|
58
64
|
config_file = File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "test-config.rb"))
|
59
65
|
subject.from_file(config_file)
|
60
|
-
|
61
|
-
subject.
|
66
|
+
|
67
|
+
expect(subject.message).to be == "Hello World"
|
68
|
+
expect(subject.thing).to be == 2
|
62
69
|
end
|
63
70
|
|
64
71
|
end
|
data/spec/ztk/locator_spec.rb
CHANGED
@@ -27,7 +27,7 @@ describe ZTK::Locator do
|
|
27
27
|
describe "class" do
|
28
28
|
|
29
29
|
it "should be ZTK::Locator" do
|
30
|
-
subject.
|
30
|
+
expect(subject).to be ZTK::Locator
|
31
31
|
end
|
32
32
|
|
33
33
|
describe "methods" do
|
@@ -35,11 +35,11 @@ describe ZTK::Locator do
|
|
35
35
|
describe "#find" do
|
36
36
|
|
37
37
|
it "should find home" do
|
38
|
-
subject.find("home").
|
38
|
+
expect(subject.find("home")).to be == "/home"
|
39
39
|
end
|
40
40
|
|
41
41
|
it "should not find funkytown_123_abc" do
|
42
|
-
|
42
|
+
expect{ subject.find("funkytown_123_abc") }.to raise_error ZTK::LocatorError
|
43
43
|
end
|
44
44
|
|
45
45
|
end
|
data/spec/ztk/logger_spec.rb
CHANGED
@@ -20,30 +20,36 @@
|
|
20
20
|
|
21
21
|
require "spec_helper"
|
22
22
|
|
23
|
+
LOG_LEVEL_STEPS = [:debug, :info, :warn, :error, :fatal]
|
24
|
+
|
23
25
|
describe ZTK::Logger do
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
@messages = {
|
27
|
+
let(:messages) do
|
28
|
+
{
|
28
29
|
:debug => "This is a test debug message",
|
29
30
|
:info => "This is a test info message",
|
30
31
|
:warn => "This is a test warn message",
|
31
32
|
:error => "This is a test error message",
|
32
33
|
:fatal => "This is a test fatal message"
|
33
34
|
}
|
34
|
-
@logfile = File.join(ZTK::Locator.root, "tmp", "logger.log")
|
35
35
|
end
|
36
36
|
|
37
|
+
let(:logfile) { File.join(File.dirname(Tempfile.new('logger')), "logger-#{Time.now.to_i}") }
|
38
|
+
|
39
|
+
subject { ZTK::Logger.new(logfile) }
|
40
|
+
|
37
41
|
before(:each) do
|
38
|
-
|
42
|
+
ENV["LOG_LEVEL"] = "DEBUG"
|
39
43
|
end
|
40
44
|
|
41
|
-
|
45
|
+
after(:each) do
|
46
|
+
File.exists?(logfile) && File.delete(logfile)
|
47
|
+
end
|
42
48
|
|
43
49
|
describe "class" do
|
44
50
|
|
45
51
|
it "should be an instance of ZTK::Logger" do
|
46
|
-
subject.
|
52
|
+
expect(subject).to be_an_instance_of ZTK::Logger
|
47
53
|
end
|
48
54
|
|
49
55
|
end
|
@@ -51,28 +57,28 @@ describe ZTK::Logger do
|
|
51
57
|
describe "general logging functionality" do
|
52
58
|
|
53
59
|
it "should accept debug log messages" do
|
54
|
-
subject.debug {
|
55
|
-
IO.read(
|
60
|
+
subject.debug { messages[:debug] }
|
61
|
+
expect(IO.read(logfile)).to match(messages[:debug])
|
56
62
|
end
|
57
63
|
|
58
64
|
it "should accept info log messages" do
|
59
|
-
subject.info {
|
60
|
-
IO.read(
|
65
|
+
subject.info { messages[:info] }
|
66
|
+
expect(IO.read(logfile)).to match(messages[:info])
|
61
67
|
end
|
62
68
|
|
63
69
|
it "should accept warn log messages" do
|
64
|
-
subject.warn {
|
65
|
-
IO.read(
|
70
|
+
subject.warn { messages[:warn] }
|
71
|
+
expect(IO.read(logfile)).to match(messages[:warn])
|
66
72
|
end
|
67
73
|
|
68
74
|
it "should accept error log messages" do
|
69
|
-
subject.error {
|
70
|
-
IO.read(
|
75
|
+
subject.error { messages[:error] }
|
76
|
+
expect(IO.read(logfile)).to match(messages[:error])
|
71
77
|
end
|
72
78
|
|
73
79
|
it "should accept fatal log messages" do
|
74
|
-
subject.fatal {
|
75
|
-
IO.read(
|
80
|
+
subject.fatal { messages[:fatal] }
|
81
|
+
expect(IO.read(logfile)).to match(messages[:fatal])
|
76
82
|
end
|
77
83
|
|
78
84
|
end
|
@@ -82,7 +88,7 @@ describe ZTK::Logger do
|
|
82
88
|
it "should allow writing directly to the log device" do
|
83
89
|
data = "Hello World"
|
84
90
|
subject << data
|
85
|
-
IO.read(
|
91
|
+
expect(IO.read(logfile)).to match(data)
|
86
92
|
end
|
87
93
|
|
88
94
|
it "should allow us to echo log statements to STDOUT" do
|
@@ -94,7 +100,7 @@ describe ZTK::Logger do
|
|
94
100
|
subject.debug { data }
|
95
101
|
|
96
102
|
stdout.rewind
|
97
|
-
stdout.read.match(data)
|
103
|
+
expect(stdout.read).to match(data)
|
98
104
|
end
|
99
105
|
|
100
106
|
end
|
@@ -102,55 +108,54 @@ describe ZTK::Logger do
|
|
102
108
|
describe "log message" do
|
103
109
|
|
104
110
|
before(:each) do
|
105
|
-
subject.debug {
|
111
|
+
subject.debug { messages[:debug] }
|
106
112
|
end
|
107
113
|
|
108
114
|
it "should contain the date (YYYY-MM-DD)" do
|
109
|
-
IO.read(
|
115
|
+
expect(IO.read(logfile)).to match(Time.now.utc.strftime("%Y-%m-%d"))
|
110
116
|
end
|
111
117
|
|
112
118
|
it "should contain the time (HH:MM)" do
|
113
|
-
IO.read(
|
119
|
+
expect(IO.read(logfile)).to match(Time.now.utc.strftime("%H:%M"))
|
114
120
|
end
|
115
121
|
|
116
122
|
it "should contain the current process ID" do
|
117
|
-
IO.read(
|
123
|
+
expect(IO.read(logfile)).to match(Process.pid.to_s)
|
118
124
|
end
|
119
125
|
|
120
126
|
it "should contain the current log level" do
|
121
|
-
IO.read(
|
127
|
+
expect(IO.read(logfile)).to match("DEBUG")
|
122
128
|
end
|
123
129
|
|
124
130
|
it "should contain the basename of the file containing the method call" do
|
125
|
-
IO.read(
|
131
|
+
expect(IO.read(logfile)).to match(File.basename(__FILE__))
|
126
132
|
end
|
127
133
|
|
128
134
|
it "should contain the log message itself" do
|
129
|
-
IO.read(
|
135
|
+
expect(IO.read(logfile)).to match(messages[:debug])
|
130
136
|
end
|
131
137
|
|
132
138
|
end
|
133
139
|
|
134
140
|
describe "log level" do
|
135
141
|
|
136
|
-
LOG_LEVEL_STEPS = [:debug, :info, :warn, :error, :fatal]
|
137
|
-
|
138
142
|
LOG_LEVEL_STEPS.each do |current_log_level_step|
|
139
143
|
|
140
144
|
it "should allow setting log level to #{current_log_level_step.to_s.upcase} via ENV[\"#{current_log_level_step.to_s.upcase}\"]" do
|
141
145
|
|
142
146
|
ENV["LOG_LEVEL"] = current_log_level_step.to_s.upcase
|
143
|
-
File.exists?(@logfile) && File.delete(@logfile)
|
144
|
-
subject = ZTK::Logger.new(@logfile)
|
145
147
|
|
146
148
|
LOG_LEVEL_STEPS.each do |log_level_step|
|
147
|
-
subject.send(log_level_step) {
|
149
|
+
subject.send(log_level_step) { messages[log_level_step] }
|
150
|
+
|
151
|
+
logdata = IO.read(logfile)
|
152
|
+
|
148
153
|
if LOG_LEVEL_STEPS.index(log_level_step) >= LOG_LEVEL_STEPS.index(current_log_level_step)
|
149
|
-
|
150
|
-
|
154
|
+
expect(logdata).to match(messages[log_level_step])
|
155
|
+
expect(logdata).to match(log_level_step.to_s.upcase)
|
151
156
|
else
|
152
|
-
|
153
|
-
|
157
|
+
expect(logdata).not_to match(messages[log_level_step])
|
158
|
+
expect(logdata).not_to match(log_level_step.to_s.upcase)
|
154
159
|
end
|
155
160
|
end
|
156
161
|
|
data/spec/ztk/parallel_spec.rb
CHANGED
@@ -27,7 +27,7 @@ describe ZTK::Parallel do
|
|
27
27
|
describe "class" do
|
28
28
|
|
29
29
|
it "should be an instance of ZTK::Parallel" do
|
30
|
-
subject.
|
30
|
+
expect(subject).to be_an_instance_of ZTK::Parallel
|
31
31
|
end
|
32
32
|
|
33
33
|
end
|
@@ -38,7 +38,7 @@ describe ZTK::Parallel do
|
|
38
38
|
describe "#process" do
|
39
39
|
|
40
40
|
it "should throw an exception if the process method is called without a block" do
|
41
|
-
|
41
|
+
expect{ subject.process }.to raise_error ZTK::ParallelError
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should spawn multiple processes to handle each iteration" do
|
@@ -50,14 +50,14 @@ describe ZTK::Parallel do
|
|
50
50
|
|
51
51
|
subject.waitall
|
52
52
|
|
53
|
-
subject.results.
|
54
|
-
subject.results.
|
55
|
-
subject.results.uniq.count.
|
56
|
-
subject.results.include?(Process.pid).
|
53
|
+
subject.results.each{ |r| expect(r).to be_kind_of Integer }
|
54
|
+
subject.results.each{ |r| expect(r).to be > 0 }
|
55
|
+
expect(subject.results.uniq.count).to be == 3
|
56
|
+
expect(subject.results.include?(Process.pid)).to be == false
|
57
57
|
end
|
58
58
|
|
59
59
|
it "should stop all execution when the ZTK::Parallel::Break exception is raised" do
|
60
|
-
|
60
|
+
expect do
|
61
61
|
|
62
62
|
3.times do |x|
|
63
63
|
subject.process do
|
@@ -67,11 +67,11 @@ describe ZTK::Parallel do
|
|
67
67
|
|
68
68
|
subject.waitall
|
69
69
|
|
70
|
-
|
70
|
+
end.to raise_error ZTK::Parallel::Break
|
71
71
|
end
|
72
72
|
|
73
73
|
it "should stop all execution when any exception is raised" do
|
74
|
-
|
74
|
+
expect do
|
75
75
|
3.times do |x|
|
76
76
|
subject.process do
|
77
77
|
raise "SomeException"
|
@@ -79,13 +79,13 @@ describe ZTK::Parallel do
|
|
79
79
|
end
|
80
80
|
|
81
81
|
subject.waitall
|
82
|
-
|
82
|
+
end.to raise_error "SomeException"
|
83
83
|
end
|
84
84
|
|
85
85
|
it "should allow us to ignore exceptions" do
|
86
86
|
subject = ZTK::Parallel.new(:raise_exceptions => false)
|
87
87
|
|
88
|
-
|
88
|
+
expect do
|
89
89
|
3.times do |x|
|
90
90
|
subject.process do
|
91
91
|
raise "SomeException"
|
@@ -93,13 +93,13 @@ describe ZTK::Parallel do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
subject.waitall
|
96
|
-
|
96
|
+
end.not_to raise_error "SomeException"
|
97
97
|
end
|
98
98
|
|
99
99
|
it "should not ignore ZTK::Parallel::Break exceptions" do
|
100
100
|
subject = ZTK::Parallel.new(:raise_exceptions => false)
|
101
101
|
|
102
|
-
|
102
|
+
expect do
|
103
103
|
3.times do |x|
|
104
104
|
subject.process do
|
105
105
|
raise ZTK::Parallel::Break
|
@@ -107,7 +107,7 @@ describe ZTK::Parallel do
|
|
107
107
|
end
|
108
108
|
|
109
109
|
subject.waitall
|
110
|
-
|
110
|
+
end.to raise_error ZTK::Parallel::Break
|
111
111
|
end
|
112
112
|
|
113
113
|
end
|
@@ -125,10 +125,10 @@ describe ZTK::Parallel do
|
|
125
125
|
subject.wait
|
126
126
|
end
|
127
127
|
|
128
|
-
subject.results.
|
129
|
-
subject.results.
|
130
|
-
subject.results.uniq.count.
|
131
|
-
subject.results.include?(Process.pid).
|
128
|
+
subject.results.each{ |r| expect(r).to be_kind_of Integer }
|
129
|
+
subject.results.each{ |r| expect(r).to be > 0 }
|
130
|
+
expect(subject.results.uniq.count).to be == 3
|
131
|
+
expect(subject.results.include?(Process.pid)).to be == false
|
132
132
|
end
|
133
133
|
|
134
134
|
end
|
@@ -143,7 +143,7 @@ describe ZTK::Parallel do
|
|
143
143
|
end
|
144
144
|
|
145
145
|
subject.waitall
|
146
|
-
subject.count.
|
146
|
+
expect(subject.count).to be == 0
|
147
147
|
end
|
148
148
|
|
149
149
|
end
|
@@ -159,7 +159,7 @@ describe ZTK::Parallel do
|
|
159
159
|
|
160
160
|
expected_count = ((3 > ZTK::Parallel::MAX_FORKS) ? ZTK::Parallel::MAX_FORKS : 3)
|
161
161
|
|
162
|
-
subject.count.
|
162
|
+
expect(subject.count).to be == expected_count
|
163
163
|
subject.waitall
|
164
164
|
end
|
165
165
|
|
@@ -0,0 +1,100 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary AT jovelabs DOT com>
|
4
|
+
# Copyright: Copyright (c) Zachary Patten
|
5
|
+
# License: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
require "spec_helper"
|
22
|
+
|
23
|
+
describe ZTK::Profiler do
|
24
|
+
|
25
|
+
let(:ui) { ZTK::UI.new(:stdout => StringIO.new, :stderr => StringIO.new, :stdin => StringIO.new) }
|
26
|
+
|
27
|
+
subject { ZTK::Profiler }
|
28
|
+
|
29
|
+
describe "class" do
|
30
|
+
|
31
|
+
it "should be ZTK::Profiler" do
|
32
|
+
expect(subject).to be ZTK::Profiler
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
before(:each) { subject.reset }
|
38
|
+
|
39
|
+
describe "methods" do
|
40
|
+
|
41
|
+
describe "#reset" do
|
42
|
+
|
43
|
+
it "should reset the timings" do
|
44
|
+
subject.start
|
45
|
+
sleep(0.5)
|
46
|
+
expect(subject.total_time).to be > 0.0
|
47
|
+
total_time = subject.total_time
|
48
|
+
|
49
|
+
subject.start
|
50
|
+
expect(subject.total_time).to be > 0.0
|
51
|
+
expect(subject.total_time).to be < total_time
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#start" do
|
57
|
+
|
58
|
+
it "should start the profiler" do
|
59
|
+
subject.start
|
60
|
+
expect(subject.total_time).to be > 0.0
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#total_time" do
|
66
|
+
|
67
|
+
it "should report the total time of the profiling" do
|
68
|
+
subject.start
|
69
|
+
expect(subject.total_time).to be > 0.0
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should raise an exception if the profiler is not started first" do
|
73
|
+
expect{subject.total_time}.to raise_error ZTK::ProfilerError
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "#report" do
|
79
|
+
|
80
|
+
it "should return a report of the profile timings" do
|
81
|
+
subject.start
|
82
|
+
subject.operation_a do
|
83
|
+
sleep(0.1)
|
84
|
+
end
|
85
|
+
|
86
|
+
report = subject.report(:ui => ui)
|
87
|
+
|
88
|
+
expect(report).to be_kind_of Array
|
89
|
+
|
90
|
+
expect(report.first).to be_kind_of Hash
|
91
|
+
expect(report.first.keys.first).to be == :operation_a
|
92
|
+
expect(report.first.values.first).to be_kind_of Float
|
93
|
+
|
94
|
+
expect(report.last).to be_kind_of Hash
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|