win32-eventlog 0.5.2 → 0.5.3
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/CHANGES +7 -2
- data/README +42 -47
- data/Rakefile +51 -32
- data/lib/win32/eventlog.rb +192 -187
- data/misc/install_msg.rb +19 -21
- data/test/test_eventlog.rb +282 -199
- data/win32-eventlog.gemspec +23 -27
- metadata +49 -21
data/misc/install_msg.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
###############################################################################
|
2
2
|
# install_msg.rb
|
3
3
|
#
|
4
4
|
# This script will create a 'RubyMsg' event source in your registry. All of
|
@@ -13,36 +13,34 @@
|
|
13
13
|
# proper directory.
|
14
14
|
#
|
15
15
|
# You should only run this script *after* you have installed win32-eventlog.
|
16
|
-
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
16
|
+
###############################################################################
|
17
|
+
require 'rbconfig'
|
18
|
+
require 'fileutils'
|
19
|
+
require 'win32/eventlog'
|
20
|
+
require 'win32/mc'
|
21
21
|
include Win32
|
22
|
-
include Config
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
msgfile = 'rubymsg.mc'
|
23
|
+
msg_dir = File.join(Config::CONFIG['prefix'], 'rubymsg')
|
24
|
+
msg_file = 'rubymsg.mc'
|
27
25
|
|
28
|
-
Dir.mkdir(
|
29
|
-
FileUtils.cp(
|
30
|
-
Dir.chdir(
|
26
|
+
Dir.mkdir(msg_dir) unless File.exists?(msg_dir)
|
27
|
+
FileUtils.cp('misc/rubymsg.mc', msg_dir)
|
28
|
+
Dir.chdir(msg_dir)
|
31
29
|
|
32
|
-
|
33
|
-
|
30
|
+
mc = Win32::MC.new(msg_file)
|
31
|
+
mc.create_all
|
34
32
|
|
35
33
|
puts ".dll created"
|
36
34
|
|
37
35
|
dll_file = File.expand_path(m.dll_file)
|
38
36
|
|
39
37
|
# Change 'Application' to whatever you feel is appropriate
|
40
|
-
EventLog.add_event_source(
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
38
|
+
Win32::EventLog.add_event_source(
|
39
|
+
:source => "Application",
|
40
|
+
:key_name => "RubyMsg",
|
41
|
+
:category_count => 3,
|
42
|
+
:event_message_file => dll_file,
|
43
|
+
:category_message_file => dll_file
|
46
44
|
)
|
47
45
|
|
48
46
|
puts "Event source 'RubyMsg' added to registry"
|
data/test/test_eventlog.rb
CHANGED
@@ -11,226 +11,309 @@ gem 'test-unit'
|
|
11
11
|
require 'test/unit'
|
12
12
|
require 'win32/eventlog'
|
13
13
|
require 'socket'
|
14
|
+
require 'tmpdir'
|
14
15
|
include Win32
|
15
16
|
|
16
|
-
class
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
class TC_Win32_EventLog < Test::Unit::TestCase
|
18
|
+
def self.startup
|
19
|
+
@@hostname = Socket.gethostname
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
def setup
|
23
|
+
@log = EventLog.new('Application')
|
24
|
+
@logfile = 'temp.evt'
|
25
|
+
@bakfile = File.join(Dir.tmpdir, 'test_event_log.bak')
|
26
|
+
@records = []
|
27
|
+
@last = nil
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
30
|
+
def test_version
|
31
|
+
assert_equal('0.5.3', EventLog::VERSION)
|
32
|
+
end
|
33
|
+
|
34
|
+
test "constructor basic functionality" do
|
35
|
+
assert_respond_to(EventLog, :new)
|
36
|
+
assert_nothing_raised{ EventLog.new }
|
37
|
+
end
|
38
|
+
|
39
|
+
test "constructor accepts a block" do
|
40
|
+
assert_nothing_raised{ EventLog.new{ |log| } }
|
41
|
+
end
|
42
|
+
|
43
|
+
test "constructor accepts a log type" do
|
44
|
+
assert_nothing_raised{ EventLog.new('System') }
|
45
|
+
end
|
46
|
+
|
47
|
+
test "constructor accepts a host name" do
|
48
|
+
assert_nothing_raised{ EventLog.new('System', @@hostname) }
|
49
|
+
end
|
50
|
+
|
51
|
+
test "open is a singleton alias for new" do
|
52
|
+
assert_alias_method(EventLog, :new, :open)
|
53
|
+
end
|
47
54
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
55
|
+
test "constructor accepts a maximum of two arguments" do
|
56
|
+
assert_raises(EventLog::Error){ EventLog.new('System', @@hostname, 'foo') }
|
57
|
+
end
|
58
|
+
|
59
|
+
test "arguments to constructor must be strings" do
|
60
|
+
assert_raises(TypeError){ EventLog.open(1) }
|
61
|
+
assert_raises(TypeError){ EventLog.open('System', 1) }
|
62
|
+
end
|
63
|
+
|
64
|
+
test "source accessor method basic functionality" do
|
65
|
+
@log = EventLog.new('Application', @@hostname)
|
66
|
+
assert_respond_to(@log, :source)
|
67
|
+
assert_equal('Application', @log.source)
|
68
|
+
end
|
69
|
+
|
70
|
+
test "server accessor method basic functionality" do
|
71
|
+
@log = EventLog.new('Application', @@hostname)
|
72
|
+
assert_respond_to(@log, :server)
|
73
|
+
assert_equal(@@hostname, @log.server)
|
74
|
+
end
|
75
|
+
|
76
|
+
test "backup basic functionality" do
|
77
|
+
assert_respond_to(@log, :backup)
|
78
|
+
assert_nothing_raised{ @log.backup(@bakfile) }
|
79
|
+
end
|
80
|
+
|
81
|
+
test "backup works as expected" do
|
82
|
+
assert_nothing_raised{ @log.backup(@bakfile) }
|
83
|
+
assert(File.exists?(@bakfile))
|
84
|
+
end
|
85
|
+
|
86
|
+
test "backup method fails if backup file already exists" do
|
87
|
+
assert_nothing_raised{ @log.backup(@bakfile) }
|
88
|
+
assert_raise(EventLog::Error){ @log.backup(@bakfile) }
|
89
|
+
end
|
90
|
+
|
91
|
+
test "open_backup basic functionality" do
|
92
|
+
assert_respond_to(EventLog, :open_backup)
|
93
|
+
end
|
53
94
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
95
|
+
test "open_backup works as expected" do
|
96
|
+
EventLog.new('Application', @@hostname) do |log|
|
97
|
+
log.backup(@bakfile)
|
98
|
+
end
|
99
|
+
|
100
|
+
assert_nothing_raised{ @log = EventLog.open_backup(@bakfile) }
|
101
|
+
assert_kind_of(EventLog, @log)
|
102
|
+
end
|
103
|
+
|
104
|
+
test "it is possible to read and close the backup log file" do
|
105
|
+
EventLog.new('Application', @@hostname) do |log|
|
106
|
+
log.backup(@bakfile)
|
107
|
+
end
|
108
|
+
|
109
|
+
@log = EventLog.open_backup(@bakfile)
|
110
|
+
assert_nothing_raised{ @log.read{ break } }
|
111
|
+
assert_nothing_raised{ @log.close }
|
112
|
+
end
|
62
113
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
114
|
+
# Ensure that an Array is returned in non-block form and that none of the
|
115
|
+
# descriptions are nil.
|
116
|
+
#
|
117
|
+
# The test for descriptions was added as a result of ruby-talk:116528.
|
118
|
+
# Thanks go to Joey Gibson for the spot. The test for unique record
|
119
|
+
# numbers was added to ensure no dups.
|
120
|
+
#
|
121
|
+
test "singleton read method works as expected" do
|
122
|
+
assert_nothing_raised{ @array = EventLog.read }
|
123
|
+
assert_kind_of(Array, @array)
|
73
124
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
125
|
+
record_numbers = []
|
126
|
+
@array.each{ |log|
|
127
|
+
assert_not_nil(log.description)
|
128
|
+
assert_equal(false, record_numbers.include?(log.record_number))
|
129
|
+
record_numbers << log.record_number
|
130
|
+
}
|
131
|
+
end
|
81
132
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
assert_nothing_raised{ @log.read(flags, 500){ break } }
|
104
|
-
end
|
133
|
+
# I've added explicit breaks because an event log could be rather large.
|
134
|
+
#
|
135
|
+
test "singleton read method does not require any arguments" do
|
136
|
+
assert_nothing_raised{ EventLog.read{ break } }
|
137
|
+
end
|
138
|
+
|
139
|
+
test "singleton read method accepts a log type" do
|
140
|
+
assert_nothing_raised{ EventLog.read("Application"){ break } }
|
141
|
+
end
|
142
|
+
|
143
|
+
test "singleton read method accepts a server argument" do
|
144
|
+
assert_nothing_raised{ EventLog.read("Application", nil){ break } }
|
145
|
+
end
|
146
|
+
|
147
|
+
test "singleton read method accepts a flags argument" do
|
148
|
+
assert_nothing_raised{ EventLog.read("Application", nil, nil){ break } }
|
149
|
+
end
|
150
|
+
|
151
|
+
test "singleton read method accepts an offset argument" do
|
152
|
+
assert_nothing_raised{ EventLog.read("Application", nil, nil, 10){ break } }
|
153
|
+
end
|
105
154
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
155
|
+
test "singleton read method accepts a maximum of four arguments" do
|
156
|
+
assert_raises(ArgumentError){
|
157
|
+
EventLog.read("Application", nil, nil, nil, nil){}
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
test "instance method read basic functionality" do
|
162
|
+
assert_respond_to(@log, :read)
|
163
|
+
assert_nothing_raised{ @log.read{ break } }
|
164
|
+
end
|
165
|
+
|
166
|
+
test "instance method read accepts flags" do
|
167
|
+
flags = EventLog::FORWARDS_READ | EventLog::SEQUENTIAL_READ
|
168
|
+
assert_nothing_raised{ @log.read(flags){ break } }
|
169
|
+
end
|
170
|
+
|
171
|
+
test "instance method read accepts an offset" do
|
172
|
+
assert_nothing_raised{ @log.read(nil, 500){ break } }
|
173
|
+
end
|
110
174
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
assert_nothing_raised{
|
115
|
-
@records = EventLog.read(nil, nil, flags, @last)
|
116
|
-
}
|
117
|
-
assert_equal(10, @records.length)
|
118
|
-
end
|
175
|
+
test "instance method read accepts a maximum of two arguments" do
|
176
|
+
assert_raises(ArgumentError){ @log.read(nil, 500, 'foo') }
|
177
|
+
end
|
119
178
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
179
|
+
test "seek_read flag plus forwards_read flag works as expected" do
|
180
|
+
flags = EventLog::SEEK_READ | EventLog::FORWARDS_READ
|
181
|
+
assert_nothing_raised{ @last = @log.read[-10].record_number }
|
182
|
+
assert_nothing_raised{
|
183
|
+
@records = EventLog.read(nil, nil, flags, @last)
|
184
|
+
}
|
185
|
+
assert_equal(10, @records.length)
|
186
|
+
end
|
187
|
+
|
188
|
+
# This test could fail, since a record number + 10 may not actually exist.
|
189
|
+
test "seek_read flag plus backwards_read flag works as expected" do
|
190
|
+
flags = EventLog::SEEK_READ | EventLog::BACKWARDS_READ
|
191
|
+
assert_nothing_raised{ @last = @log.oldest_record_number + 10 }
|
192
|
+
assert_nothing_raised{ @records = EventLog.read(nil, nil, flags, @last) }
|
193
|
+
assert_equal(11, @records.length)
|
194
|
+
end
|
127
195
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
196
|
+
test "the eventlog struct returned by read is frozen" do
|
197
|
+
EventLog.read{ |log| @entry = log; break }
|
198
|
+
assert_true(@entry.frozen?)
|
199
|
+
end
|
132
200
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
201
|
+
test "server method basic functionality" do
|
202
|
+
assert_respond_to(@log, :server)
|
203
|
+
assert_nothing_raised{ @log.server }
|
204
|
+
assert_nil(@log.server)
|
205
|
+
end
|
206
|
+
|
207
|
+
test "server method is readonly" do
|
208
|
+
assert_raises(NoMethodError){ @log.server = 'foo' }
|
209
|
+
end
|
210
|
+
|
211
|
+
test "source method basic functionality" do
|
212
|
+
assert_respond_to(@log, :source)
|
213
|
+
assert_nothing_raised{ @log.source }
|
214
|
+
assert_kind_of(String, @log.source)
|
215
|
+
end
|
216
|
+
|
217
|
+
test "source method is readonly" do
|
218
|
+
assert_raises(NoMethodError){ @log.source = 'foo' }
|
219
|
+
end
|
220
|
+
|
221
|
+
test "file method basic functionality" do
|
222
|
+
assert_respond_to(@log, :file)
|
223
|
+
assert_nothing_raised{ @log.file }
|
224
|
+
assert_nil(@log.file)
|
225
|
+
end
|
226
|
+
|
227
|
+
test "file method is readonly" do
|
228
|
+
assert_raises(NoMethodError){ @log.file = 'foo' }
|
229
|
+
end
|
156
230
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
end
|
231
|
+
# Since I don't want to actually clear anyone's event log, I can't really
|
232
|
+
# verify that it works.
|
233
|
+
test "clear method basic functionality" do
|
234
|
+
assert_respond_to(@log, :clear)
|
235
|
+
end
|
163
236
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
237
|
+
test "full method basic functionality" do
|
238
|
+
assert_respond_to(@log, :full?)
|
239
|
+
assert_nothing_raised{ @log.full? }
|
240
|
+
end
|
241
|
+
|
242
|
+
test "full method returns a boolean" do
|
243
|
+
assert_boolean(@log.full?)
|
244
|
+
end
|
168
245
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
246
|
+
test "close method basic functionality" do
|
247
|
+
assert_respond_to(@log, :close)
|
248
|
+
assert_nothing_raised{ @log.close }
|
249
|
+
end
|
250
|
+
|
251
|
+
test "oldest_record_number basic functionality" do
|
252
|
+
assert_respond_to(@log, :oldest_record_number)
|
253
|
+
assert_nothing_raised{ @log.oldest_record_number }
|
254
|
+
assert_kind_of(Fixnum, @log.oldest_record_number)
|
255
|
+
end
|
256
|
+
|
257
|
+
test "total_records basic functionality" do
|
258
|
+
assert_respond_to(@log, :total_records)
|
259
|
+
assert_nothing_raised{ @log.total_records }
|
260
|
+
assert_kind_of(Fixnum, @log.total_records)
|
261
|
+
end
|
183
262
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
263
|
+
# We can't test that this method actually executes properly since it goes
|
264
|
+
# into an endless loop.
|
265
|
+
#
|
266
|
+
test "tail basic functionality" do
|
267
|
+
assert_respond_to(@log, :tail)
|
268
|
+
assert_raises(EventLog::Error){ @log.tail }
|
269
|
+
end
|
191
270
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
271
|
+
# We can't test that this method actually executes properly since it goes
|
272
|
+
# into an endless loop.
|
273
|
+
#
|
274
|
+
test "notify_change basic functionality" do
|
275
|
+
assert_respond_to(@log, :notify_change)
|
276
|
+
assert_raises(EventLog::Error){ @log.notify_change }
|
277
|
+
end
|
199
278
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
279
|
+
# I can't really do more in depth testing for this method since there
|
280
|
+
# isn't an event source I can reliably and safely write to.
|
281
|
+
#
|
282
|
+
test "report_event basic functionality" do
|
283
|
+
assert_respond_to(@log, :report_event)
|
284
|
+
assert_raises(ArgumentError){ @log.report_event }
|
285
|
+
end
|
286
|
+
|
287
|
+
test "write is an alias for report_event" do
|
288
|
+
assert_respond_to(@log, :write)
|
289
|
+
assert_alias_method(@log, :write, :report_event)
|
290
|
+
end
|
208
291
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
292
|
+
test "read event constants" do
|
293
|
+
assert_not_nil(EventLog::FORWARDS_READ)
|
294
|
+
assert_not_nil(EventLog::BACKWARDS_READ)
|
295
|
+
assert_not_nil(EventLog::SEEK_READ)
|
296
|
+
assert_not_nil(EventLog::SEQUENTIAL_READ)
|
297
|
+
end
|
298
|
+
|
299
|
+
test "event type constants" do
|
300
|
+
assert_not_nil(EventLog::SUCCESS)
|
301
|
+
assert_not_nil(EventLog::ERROR)
|
302
|
+
assert_not_nil(EventLog::WARN)
|
303
|
+
assert_not_nil(EventLog::INFO)
|
304
|
+
assert_not_nil(EventLog::AUDIT_SUCCESS)
|
305
|
+
assert_not_nil(EventLog::AUDIT_FAILURE)
|
306
|
+
end
|
224
307
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
308
|
+
def teardown
|
309
|
+
@log.close rescue nil
|
310
|
+
File.delete(@bakfile) if File.exists?(@bakfile)
|
311
|
+
@logfile = nil
|
312
|
+
@records = nil
|
313
|
+
@last = nil
|
314
|
+
end
|
232
315
|
|
233
|
-
|
234
|
-
|
235
|
-
|
316
|
+
def self.shutdown
|
317
|
+
@@hostname = nil
|
318
|
+
end
|
236
319
|
end
|