ztk 0.0.3 → 0.0.4
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.
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.rvmrc.template +1 -0
- data/.travis.yml +11 -0
- data/LICENSE +202 -22
- data/README.md +24 -28
- data/Rakefile +43 -2
- data/WIKI.md +181 -0
- data/lib/ztk/logger.rb +4 -4
- data/lib/ztk/parallel.rb +62 -43
- data/lib/ztk/ssh.rb +57 -53
- data/lib/ztk/version.rb +1 -1
- data/spec/spec_helper.rb +38 -0
- data/spec/ztk/logger_spec.rb +133 -0
- data/spec/ztk/parallel_spec.rb +53 -0
- data/ztk.gemspec +6 -2
- metadata +69 -6
- data/.rvmrc +0 -2
data/lib/ztk/logger.rb
CHANGED
@@ -41,7 +41,7 @@ module ZTK
|
|
41
41
|
file = Regexp.last_match[1]
|
42
42
|
line = Regexp.last_match[2]
|
43
43
|
method = Regexp.last_match[3]
|
44
|
-
"#{File.basename(file)}:#{line}:#{method}
|
44
|
+
"#{File.basename(file)}:#{line}:#{method}|"
|
45
45
|
else
|
46
46
|
""
|
47
47
|
end
|
@@ -54,9 +54,9 @@ module ZTK
|
|
54
54
|
|
55
55
|
called_by = parse_caller(caller[1])
|
56
56
|
msg = (block && block.call)
|
57
|
-
|
58
|
-
message = [message, progname, msg].delete_if{|i| i
|
59
|
-
message = "%19s.%06d
|
57
|
+
(msg.nil? || msg.strip.empty?) and return
|
58
|
+
message = [message, progname, msg].delete_if{ |i| i.nil? }.join(": ")
|
59
|
+
message = "%19s.%06d|%05d|%5s|%s%s\n" % [Time.now.utc.strftime("%Y-%m-%d|%H:%M:%S"), Time.now.utc.usec, Process.pid, SEVERITIES[severity], called_by, message]
|
60
60
|
|
61
61
|
@logdev.write(message)
|
62
62
|
|
data/lib/ztk/parallel.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
#
|
3
3
|
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
4
|
# Copyright: Copyright (c) Jove Labs
|
5
|
-
# License: Apache License,
|
5
|
+
# License: Apache License, Vers::IOn 2.0
|
6
6
|
#
|
7
|
-
# Licensed under the Apache License,
|
7
|
+
# Licensed under the Apache License, Vers::IOn 2.0 (the "License");
|
8
8
|
# you may not use this file except in compliance with the License.
|
9
9
|
# You may obtain a copy of the License at
|
10
10
|
#
|
@@ -12,61 +12,81 @@
|
|
12
12
|
#
|
13
13
|
# Unless required by applicable law or agreed to in writing, software
|
14
14
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
-
# WITHOUT WARRANTIES OR
|
16
|
-
# See the License for the specific language governing
|
17
|
-
#
|
15
|
+
# WITHOUT WARRANTIES OR CONDIT::IONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permiss::IOns and
|
17
|
+
# limitat::IOns under the License.
|
18
18
|
#
|
19
19
|
################################################################################
|
20
|
+
require "base64"
|
21
|
+
require "ostruct"
|
20
22
|
|
21
23
|
module ZTK
|
22
24
|
class Parallel
|
23
25
|
|
24
26
|
################################################################################
|
25
27
|
|
26
|
-
attr_accessor :results
|
28
|
+
attr_accessor :config, :results
|
27
29
|
|
28
30
|
################################################################################
|
29
31
|
|
30
|
-
def initialize(
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
:
|
35
|
-
:
|
36
|
-
|
32
|
+
def initialize(config={})
|
33
|
+
@config = OpenStruct.new({
|
34
|
+
:stdout => $stdout,
|
35
|
+
:stderr => $stderr,
|
36
|
+
:stdin => $stdin,
|
37
|
+
:logger => $logger,
|
38
|
+
:max_forks => `grep -c processor /proc/cpuinfo`.chomp.to_i,
|
39
|
+
:one_shot => false,
|
40
|
+
:before_fork => nil,
|
41
|
+
:after_fork => nil
|
42
|
+
}.merge(config))
|
43
|
+
@config.stdout.sync = true if @config.stdout.respond_to?(:sync=)
|
44
|
+
@config.stderr.sync = true if @config.stderr.respond_to?(:sync=)
|
45
|
+
@config.stdin.sync = true if @config.stdin.respond_to?(:sync=)
|
46
|
+
@config.logger.sync = true if @config.logger.respond_to?(:sync=)
|
47
|
+
|
48
|
+
@forks = ::Array.new
|
49
|
+
@results = ::Array.new
|
50
|
+
::GC.respond_to?(:copy_on_write_friendly=) and ::GC.copy_on_write_friendly = true
|
51
|
+
end
|
37
52
|
|
38
|
-
|
39
|
-
@one_shot = options[:one_shot]
|
53
|
+
################################################################################
|
40
54
|
|
41
|
-
|
42
|
-
|
55
|
+
def config(&block)
|
56
|
+
if block_given?
|
57
|
+
yield(@config)
|
58
|
+
else
|
59
|
+
@config
|
60
|
+
end
|
43
61
|
end
|
44
62
|
|
45
63
|
################################################################################
|
46
64
|
|
47
|
-
def process
|
65
|
+
def process(*args)
|
66
|
+
@config.logger.debug{ "FORKS #{@forks.inspect}" }
|
48
67
|
pid = nil
|
49
|
-
return pid if (@forks.count >= @max_forks)
|
68
|
+
return pid if (@forks.count >= @config.max_forks)
|
50
69
|
|
51
|
-
child_reader, parent_writer = IO.pipe
|
52
|
-
parent_reader, child_writer = IO.pipe
|
70
|
+
child_reader, parent_writer = ::IO.pipe
|
71
|
+
parent_reader, child_writer = ::IO.pipe
|
53
72
|
|
54
|
-
|
55
|
-
pid = Process.fork do
|
56
|
-
|
73
|
+
@config.before_fork and @config.before_fork.call(::Process.pid)
|
74
|
+
pid = ::Process.fork do
|
75
|
+
@config.after_fork and @config.after_fork.call(::Process.pid)
|
57
76
|
|
58
77
|
parent_writer.close
|
59
78
|
parent_reader.close
|
60
79
|
|
61
|
-
if (data = yield).
|
62
|
-
|
80
|
+
if !(data = yield).nil?
|
81
|
+
@config.logger.debug{ "WRITE #{data.inspect}" }
|
82
|
+
child_writer.write(::Base64.encode64(::Marshal.dump(data)))
|
63
83
|
end
|
64
84
|
|
65
85
|
child_reader.close
|
66
86
|
child_writer.close
|
67
|
-
Process.exit!(0)
|
87
|
+
::Process.exit!(0)
|
68
88
|
end
|
69
|
-
|
89
|
+
@config.after_fork and @config.after_fork.call(::Process.pid)
|
70
90
|
|
71
91
|
child_reader.close
|
72
92
|
child_writer.close
|
@@ -80,18 +100,17 @@ module ZTK
|
|
80
100
|
################################################################################
|
81
101
|
|
82
102
|
def wait
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
103
|
+
@config.logger.debug{ "FORKS #{@forks.inspect}" }
|
104
|
+
pid, status = (::Process.wait2(-1, ::Process::WNOHANG) rescue nil)
|
105
|
+
if !pid.nil? && !status.nil? && !(fork = @forks.select{ |f| f[:pid] == pid }.first).nil?
|
106
|
+
data = (::Marshal.load(::Base64.decode64(fork[:reader].read.to_s)) rescue nil)
|
107
|
+
@config.logger.debug{ "READ #{data.inspect}" }
|
108
|
+
@results.push(data) if (!data.nil? && !@config.one_shot)
|
109
|
+
fork[:reader].close
|
110
|
+
fork[:writer].close
|
111
|
+
|
112
|
+
@forks -= [fork]
|
113
|
+
return [pid, status, data]
|
95
114
|
end
|
96
115
|
nil
|
97
116
|
end
|
@@ -99,11 +118,11 @@ module ZTK
|
|
99
118
|
################################################################################
|
100
119
|
|
101
120
|
def waitall
|
102
|
-
|
121
|
+
data = ::Array.new
|
103
122
|
while @forks.count > 0
|
104
|
-
|
123
|
+
data << self.wait
|
105
124
|
end
|
106
|
-
|
125
|
+
data
|
107
126
|
end
|
108
127
|
|
109
128
|
################################################################################
|
data/lib/ztk/ssh.rb
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
################################################################################
|
20
|
+
require "ostruct"
|
20
21
|
|
21
22
|
module ZTK
|
22
23
|
class SSHError < Error; end
|
@@ -28,21 +29,24 @@ module ZTK
|
|
28
29
|
|
29
30
|
################################################################################
|
30
31
|
|
31
|
-
def initialize(
|
32
|
-
@
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
@config =
|
32
|
+
def initialize(config={})
|
33
|
+
@config = OpenStruct.new({
|
34
|
+
:stdout => $stdout,
|
35
|
+
:stderr => $stderr,
|
36
|
+
:stdin => $stdin,
|
37
|
+
:logger => $logger,
|
38
|
+
:ssh => Hash.new(nil)
|
39
|
+
}.merge(config))
|
40
|
+
@config.stdout.sync = true if @config.stdout.respond_to?(:sync=)
|
41
|
+
@config.stderr.sync = true if @config.stderr.respond_to?(:sync=)
|
42
|
+
@config.stdin.sync = true if @config.stdin.respond_to?(:sync=)
|
43
|
+
@config.logger.sync = true if @config.logger.respond_to?(:sync=)
|
40
44
|
end
|
41
45
|
|
42
46
|
################################################################################
|
43
47
|
|
44
48
|
def console
|
45
|
-
@logger and @logger.debug { "config(#{@config.inspect})" }
|
49
|
+
@config.logger and @config.logger.debug { "config(#{@config.ssh.inspect})" }
|
46
50
|
|
47
51
|
command = [ "ssh" ]
|
48
52
|
command << [ "-q" ]
|
@@ -50,47 +54,47 @@ module ZTK
|
|
50
54
|
command << [ "-o", "StrictHostKeyChecking=no" ]
|
51
55
|
command << [ "-o", "KeepAlive=yes" ]
|
52
56
|
command << [ "-o", "ServerAliveInterval=60" ]
|
53
|
-
command << [ "-i", @config[:identity_file] ] if @config[:identity_file]
|
54
|
-
command << [ "-o", "ProxyCommand=\"#{proxy_command}\"" ] if @config[:proxy]
|
55
|
-
command << "#{@config[:ssh_user]}@#{@config[:host]}"
|
57
|
+
command << [ "-i", @config.ssh[:identity_file] ] if @config.ssh[:identity_file]
|
58
|
+
command << [ "-o", "ProxyCommand=\"#{proxy_command}\"" ] if @config.ssh[:proxy]
|
59
|
+
command << "#{@config.ssh[:ssh_user]}@#{@config.ssh[:host]}"
|
56
60
|
command = command.flatten.compact.join(" ")
|
57
|
-
@logger and @logger.info { "command(#{command})" }
|
61
|
+
@config.logger and @config.logger.info { "command(#{command})" }
|
58
62
|
Kernel.exec(command)
|
59
63
|
end
|
60
64
|
|
61
65
|
################################################################################
|
62
66
|
|
63
67
|
def exec(command, options={})
|
64
|
-
@ssh ||= Net::SSH.start(@config[:host], @config[:ssh_user], ssh_options)
|
68
|
+
@ssh ||= Net::SSH.start(@config.ssh[:host], @config.ssh[:ssh_user], ssh_options)
|
65
69
|
|
66
70
|
options = { :silence => false }.merge(options)
|
67
71
|
silence = options[:silence]
|
68
72
|
output = ""
|
69
73
|
|
70
|
-
@logger and @logger.debug { "config(#{@config.inspect})" }
|
71
|
-
@logger and @logger.debug { "options(#{options.inspect})" }
|
72
|
-
@logger and @logger.info { "command(#{command})" }
|
74
|
+
@config.logger and @config.logger.debug { "config(#{@config.ssh.inspect})" }
|
75
|
+
@config.logger and @config.logger.debug { "options(#{options.inspect})" }
|
76
|
+
@config.logger and @config.logger.info { "command(#{command})" }
|
73
77
|
channel = @ssh.open_channel do |chan|
|
74
|
-
@logger and @logger.debug { "channel opened" }
|
78
|
+
@config.logger and @config.logger.debug { "channel opened" }
|
75
79
|
chan.exec(command) do |ch, success|
|
76
80
|
raise SSHError, "Could not execute '#{command}'." unless success
|
77
81
|
|
78
82
|
ch.on_data do |c, data|
|
79
83
|
output += data
|
80
|
-
@logger and @logger.debug { data.chomp.strip }
|
81
|
-
@stdout.print(data) if !silence
|
84
|
+
@config.logger and @config.logger.debug { data.chomp.strip }
|
85
|
+
@config.stdout.print(data) if !silence
|
82
86
|
end
|
83
87
|
|
84
88
|
ch.on_extended_data do |c, type, data|
|
85
89
|
output += data
|
86
|
-
@logger and @logger.debug { data.chomp.strip }
|
87
|
-
@stderr.print(data) if !silence
|
90
|
+
@config.logger and @config.logger.debug { data.chomp.strip }
|
91
|
+
@config.stderr.print(data) if !silence
|
88
92
|
end
|
89
93
|
|
90
94
|
end
|
91
95
|
end
|
92
96
|
channel.wait
|
93
|
-
@logger and @logger.debug { "channel closed" }
|
97
|
+
@config.logger and @config.logger.debug { "channel closed" }
|
94
98
|
|
95
99
|
output
|
96
100
|
end
|
@@ -98,22 +102,22 @@ module ZTK
|
|
98
102
|
################################################################################
|
99
103
|
|
100
104
|
def upload(local, remote)
|
101
|
-
@sftp ||= Net::SFTP.start(@config[:host], @config[:ssh_user], ssh_options)
|
105
|
+
@sftp ||= Net::SFTP.start(@config.ssh[:host], @config.ssh[:ssh_user], ssh_options)
|
102
106
|
|
103
|
-
@logger and @logger.debug { "config(#{@config.inspect})" }
|
104
|
-
@logger and @logger.info { "parameters(#{local},#{remote})" }
|
107
|
+
@config.logger and @config.logger.debug { "config(#{@config.ssh.inspect})" }
|
108
|
+
@config.logger and @config.logger.info { "parameters(#{local},#{remote})" }
|
105
109
|
@sftp.upload!(local.to_s, remote.to_s) do |event, uploader, *args|
|
106
110
|
case event
|
107
111
|
when :open
|
108
|
-
@logger and @logger.info { "upload(#{args[0].local} -> #{args[0].remote})" }
|
112
|
+
@config.logger and @config.logger.info { "upload(#{args[0].local} -> #{args[0].remote})" }
|
109
113
|
when :close
|
110
|
-
@logger and @logger.debug { "close(#{args[0].remote})" }
|
114
|
+
@config.logger and @config.logger.debug { "close(#{args[0].remote})" }
|
111
115
|
when :mkdir
|
112
|
-
@logger and @logger.debug { "mkdir(#{args[0]})" }
|
116
|
+
@config.logger and @config.logger.debug { "mkdir(#{args[0]})" }
|
113
117
|
when :put
|
114
|
-
@logger and @logger.debug { "put(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
|
118
|
+
@config.logger and @config.logger.debug { "put(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
|
115
119
|
when :finish
|
116
|
-
@logger and @logger.info { "finish" }
|
120
|
+
@config.logger and @config.logger.info { "finish" }
|
117
121
|
end
|
118
122
|
end
|
119
123
|
end
|
@@ -121,22 +125,22 @@ module ZTK
|
|
121
125
|
################################################################################
|
122
126
|
|
123
127
|
def download(remote, local)
|
124
|
-
@sftp ||= Net::SFTP.start(@config[:host], @config[:ssh_user], ssh_options)
|
128
|
+
@sftp ||= Net::SFTP.start(@config.ssh[:host], @config.ssh[:ssh_user], ssh_options)
|
125
129
|
|
126
|
-
@logger and @logger.debug { "config(#{@config.inspect})" }
|
127
|
-
@logger and @logger.info { "parameters(#{remote},#{local})" }
|
130
|
+
@config.logger and @config.logger.debug { "config(#{@config.ssh.inspect})" }
|
131
|
+
@config.logger and @config.logger.info { "parameters(#{remote},#{local})" }
|
128
132
|
@sftp.download!(remote.to_s, local.to_s) do |event, downloader, *args|
|
129
133
|
case event
|
130
134
|
when :open
|
131
|
-
@logger and @logger.info { "download(#{args[0].remote} -> #{args[0].local})" }
|
135
|
+
@config.logger and @config.logger.info { "download(#{args[0].remote} -> #{args[0].local})" }
|
132
136
|
when :close
|
133
|
-
@logger and @logger.debug { "close(#{args[0].local})" }
|
137
|
+
@config.logger and @config.logger.debug { "close(#{args[0].local})" }
|
134
138
|
when :mkdir
|
135
|
-
@logger and @logger.debug { "mkdir(#{args[0]})" }
|
139
|
+
@config.logger and @config.logger.debug { "mkdir(#{args[0]})" }
|
136
140
|
when :get
|
137
|
-
@logger and @logger.debug { "get(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
|
141
|
+
@config.logger and @config.logger.debug { "get(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
|
138
142
|
when :finish
|
139
|
-
@logger and @logger.info { "finish" }
|
143
|
+
@config.logger and @config.logger.info { "finish" }
|
140
144
|
end
|
141
145
|
end
|
142
146
|
end
|
@@ -147,11 +151,11 @@ module ZTK
|
|
147
151
|
################################################################################
|
148
152
|
|
149
153
|
def proxy_command
|
150
|
-
@logger and @logger.debug { "config(#{@config.inspect})" }
|
154
|
+
@config.logger and @config.logger.debug { "config(#{@config.ssh.inspect})" }
|
151
155
|
|
152
|
-
if !@config[:identity_file]
|
156
|
+
if !@config.ssh[:identity_file]
|
153
157
|
message = "You must specify an identity file in order to SSH proxy."
|
154
|
-
@logger and @logger.fatal { message }
|
158
|
+
@config.logger and @config.logger.fatal { message }
|
155
159
|
raise SSHError, message
|
156
160
|
end
|
157
161
|
|
@@ -161,25 +165,25 @@ module ZTK
|
|
161
165
|
command << [ "-o", "StrictHostKeyChecking=no" ]
|
162
166
|
command << [ "-o", "KeepAlive=yes" ]
|
163
167
|
command << [ "-o", "ServerAliveInterval=60" ]
|
164
|
-
command << [ "-i", @config[:proxy_identity_file] ] if @config[:proxy_identity_file]
|
165
|
-
command << "#{@config[:proxy_ssh_user]}@#{@config[:proxy_host]}"
|
168
|
+
command << [ "-i", @config.ssh[:proxy_identity_file] ] if @config.ssh[:proxy_identity_file]
|
169
|
+
command << "#{@config.ssh[:proxy_ssh_user]}@#{@config.ssh[:proxy_host]}"
|
166
170
|
command << "nc %h %p"
|
167
171
|
command = command.flatten.compact.join(" ")
|
168
|
-
@logger and @logger.debug { "command(#{command})" }
|
172
|
+
@config.logger and @config.logger.debug { "command(#{command})" }
|
169
173
|
command
|
170
174
|
end
|
171
175
|
|
172
176
|
################################################################################
|
173
177
|
|
174
178
|
def ssh_options
|
175
|
-
@logger and @logger.debug { "config(#{@config.inspect})" }
|
179
|
+
@config.logger and @config.logger.debug { "config(#{@config.ssh.inspect})" }
|
176
180
|
options = {}
|
177
|
-
options.merge!(:password => @config[:ssh_password]) if @config[:ssh_password]
|
178
|
-
options.merge!(:keys => @config[:identity_file]) if @config[:identity_file]
|
179
|
-
options.merge!(:timeout => @config[:timeout]) if @config[:timeout]
|
180
|
-
options.merge!(:user_known_hosts_file => '/dev/null') if !@config[:host_key_verify]
|
181
|
-
options.merge!(:proxy => Net::SSH::Proxy::Command.new(proxy_command)) if @config[:proxy]
|
182
|
-
@logger and @logger.debug { "options(#{options.inspect})" }
|
181
|
+
options.merge!(:password => @config.ssh[:ssh_password]) if @config.ssh[:ssh_password]
|
182
|
+
options.merge!(:keys => @config.ssh[:identity_file]) if @config.ssh[:identity_file]
|
183
|
+
options.merge!(:timeout => @config.ssh[:timeout]) if @config.ssh[:timeout]
|
184
|
+
options.merge!(:user_known_hosts_file => '/dev/null') if !@config.ssh[:host_key_verify]
|
185
|
+
options.merge!(:proxy => Net::SSH::Proxy::Command.new(proxy_command)) if @config.ssh[:proxy]
|
186
|
+
@config.logger and @config.logger.debug { "options(#{options.inspect})" }
|
183
187
|
options
|
184
188
|
end
|
185
189
|
|
data/lib/ztk/version.rb
CHANGED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
|
+
# Copyright: Copyright (c) Jove Labs
|
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 "ztk"
|
22
|
+
|
23
|
+
################################################################################
|
24
|
+
|
25
|
+
$logger = ZTK::Logger.new("/dev/null")
|
26
|
+
|
27
|
+
dev_null = File.open("/dev/null", "w")
|
28
|
+
$stdout = dev_null
|
29
|
+
$stderr = dev_null
|
30
|
+
|
31
|
+
################################################################################
|
32
|
+
|
33
|
+
require 'simplecov'
|
34
|
+
SimpleCov.start do
|
35
|
+
add_filter '/spec/'
|
36
|
+
end if ENV["COVERAGE"]
|
37
|
+
|
38
|
+
################################################################################
|
@@ -0,0 +1,133 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
|
+
# Copyright: Copyright (c) Jove Labs
|
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::Logger do
|
24
|
+
|
25
|
+
before(:all) do
|
26
|
+
ENV["LOG_LEVEL"] = "DEBUG"
|
27
|
+
@messages = {
|
28
|
+
:debug => "This is a test debug message",
|
29
|
+
:info => "This is a test info message",
|
30
|
+
:warn => "This is a test warn message",
|
31
|
+
:error => "This is a test error message",
|
32
|
+
:fatal => "This is a test fatal message"
|
33
|
+
}
|
34
|
+
@logfile = "/tmp/test.log"
|
35
|
+
File.exists?(@logfile) && File.delete(@logfile)
|
36
|
+
end
|
37
|
+
|
38
|
+
subject { ZTK::Logger.new(@logfile) }
|
39
|
+
|
40
|
+
it "should be of kind ZTK::Logger class" do
|
41
|
+
subject.should be_an_instance_of ZTK::Logger
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "general logging functionality" do
|
45
|
+
|
46
|
+
it "should accept debug log messages" do
|
47
|
+
subject.debug { @messages[:debug] }
|
48
|
+
IO.read(@logfile).match(@messages[:debug]).should_not be nil
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should accept info log messages" do
|
52
|
+
subject.info { @messages[:info] }
|
53
|
+
IO.read(@logfile).match(@messages[:info]).should_not be nil
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should accept warn log messages" do
|
57
|
+
subject.warn { @messages[:warn] }
|
58
|
+
IO.read(@logfile).match(@messages[:warn]).should_not be nil
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should accept error log messages" do
|
62
|
+
subject.error { @messages[:error] }
|
63
|
+
IO.read(@logfile).match(@messages[:error]).should_not be nil
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should accept fatal log messages" do
|
67
|
+
subject.fatal { @messages[:fatal] }
|
68
|
+
IO.read(@logfile).match(@messages[:fatal]).should_not be nil
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "log message" do
|
74
|
+
|
75
|
+
before(:all) do
|
76
|
+
subject.debug { @messages[:debug] }
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should contain the date (YYYY-MM-DD)" do
|
80
|
+
IO.read(@logfile).match(Time.now.utc.strftime("%Y-%m-%d")).should_not be nil
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should contain the time (HH:MM)" do
|
84
|
+
IO.read(@logfile).match(Time.now.utc.strftime("%H:%M")).should_not be nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should contain the current process ID" do
|
88
|
+
IO.read(@logfile).match(Process.pid.to_s).should_not be nil
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should contain the current log level" do
|
92
|
+
IO.read(@logfile).match("DEBUG").should_not be nil
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should contain the basename of the file containing the method call" do
|
96
|
+
IO.read(@logfile).match(File.basename(__FILE__)).should_not be nil
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should contain the log message itself" do
|
100
|
+
IO.read(@logfile).match(@messages[:debug]).should_not be nil
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "log level" do
|
106
|
+
|
107
|
+
LOG_LEVEL_STEPS = [:debug, :info, :warn, :error, :fatal]
|
108
|
+
|
109
|
+
LOG_LEVEL_STEPS.each do |current_log_level_step|
|
110
|
+
|
111
|
+
it "should allow setting log level to #{current_log_level_step.to_s.upcase} via ENV[\"#{current_log_level_step.to_s.upcase}\"]" do
|
112
|
+
|
113
|
+
ENV["LOG_LEVEL"] = current_log_level_step.to_s.upcase
|
114
|
+
File.exists?(@logfile) && File.delete(@logfile)
|
115
|
+
subject = ZTK::Logger.new(@logfile)
|
116
|
+
|
117
|
+
LOG_LEVEL_STEPS.each do |log_level_step|
|
118
|
+
subject.send(log_level_step) { @messages[log_level_step] }
|
119
|
+
if LOG_LEVEL_STEPS.index(log_level_step) >= LOG_LEVEL_STEPS.index(current_log_level_step)
|
120
|
+
IO.read(@logfile).match(@messages[log_level_step]).should_not be nil
|
121
|
+
IO.read(@logfile).match(log_level_step.to_s.upcase).should_not be nil
|
122
|
+
else
|
123
|
+
IO.read(@logfile).match(@messages[log_level_step]).should be nil
|
124
|
+
IO.read(@logfile).match(log_level_step.to_s.upcase).should be nil
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|