win32-eventlog 0.6.3 → 0.6.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +2 -0
- data/CHANGES +254 -248
- data/MANIFEST +21 -19
- data/README +81 -82
- data/Rakefile +3 -6
- data/certs/djberg96_pub.pem +21 -0
- data/doc/tutorial.txt +136 -136
- data/examples/example_notify.rb +23 -23
- data/examples/example_read.rb +83 -83
- data/examples/example_write.rb +64 -64
- data/lib/win32-eventlog.rb +1 -0
- data/lib/win32/eventlog.rb +1139 -1139
- data/lib/win32/mc.rb +120 -120
- data/lib/win32/windows/constants.rb +56 -56
- data/lib/win32/windows/functions.rb +61 -61
- data/lib/win32/windows/helper.rb +13 -13
- data/lib/win32/windows/structs.rb +30 -30
- data/misc/install_msg.rb +46 -46
- data/misc/rubymsg.mc +35 -35
- data/test/foo.mc +24 -24
- data/test/test_eventlog.rb +319 -319
- data/test/test_mc.rb +64 -64
- data/win32-eventlog.gemspec +30 -30
- metadata +29 -5
- metadata.gz.sig +0 -0
data/lib/win32/windows/helper.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
class String
|
2
|
-
# Convenience method for converting strings to UTF-16LE for wide character
|
3
|
-
# functions that require it.
|
4
|
-
def wincode
|
5
|
-
(self.tr(File::SEPARATOR, File::ALT_SEPARATOR) + 0.chr).encode('UTF-16LE')
|
6
|
-
end
|
7
|
-
|
8
|
-
# Read a wide character string up until the first double null, and delete
|
9
|
-
# any remaining null characters.
|
10
|
-
def read_wide
|
11
|
-
self[/^.*?(?=\x00{2})/].delete(0.chr)
|
12
|
-
end
|
13
|
-
end
|
1
|
+
class String
|
2
|
+
# Convenience method for converting strings to UTF-16LE for wide character
|
3
|
+
# functions that require it.
|
4
|
+
def wincode
|
5
|
+
(self.tr(File::SEPARATOR, File::ALT_SEPARATOR) + 0.chr).encode('UTF-16LE')
|
6
|
+
end
|
7
|
+
|
8
|
+
# Read a wide character string up until the first double null, and delete
|
9
|
+
# any remaining null characters.
|
10
|
+
def read_wide
|
11
|
+
self[/^.*?(?=\x00{2})/].delete(0.chr)
|
12
|
+
end
|
13
|
+
end
|
@@ -1,30 +1,30 @@
|
|
1
|
-
require 'ffi'
|
2
|
-
|
3
|
-
module Windows
|
4
|
-
module Structs
|
5
|
-
extend FFI::Library
|
6
|
-
typedef :ulong, :dword
|
7
|
-
typedef :ushort, :word
|
8
|
-
|
9
|
-
class EVENTLOGRECORD < FFI::Struct
|
10
|
-
layout(
|
11
|
-
:Length, :dword,
|
12
|
-
:Reserved, :dword,
|
13
|
-
:RecordNumber, :dword,
|
14
|
-
:TimeGenerated, :dword,
|
15
|
-
:TimeWritten, :dword,
|
16
|
-
:EventID, :dword,
|
17
|
-
:EventType, :word,
|
18
|
-
:NumStrings, :word,
|
19
|
-
:EventCategory, :word,
|
20
|
-
:ReservedFlags, :word,
|
21
|
-
:ClosingRecordNumber, :dword,
|
22
|
-
:StringOffset, :dword,
|
23
|
-
:UserSidLength, :dword,
|
24
|
-
:UserSidOffset, :dword,
|
25
|
-
:DataLength, :dword,
|
26
|
-
:DataOffset, :dword
|
27
|
-
)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module Windows
|
4
|
+
module Structs
|
5
|
+
extend FFI::Library
|
6
|
+
typedef :ulong, :dword
|
7
|
+
typedef :ushort, :word
|
8
|
+
|
9
|
+
class EVENTLOGRECORD < FFI::Struct
|
10
|
+
layout(
|
11
|
+
:Length, :dword,
|
12
|
+
:Reserved, :dword,
|
13
|
+
:RecordNumber, :dword,
|
14
|
+
:TimeGenerated, :dword,
|
15
|
+
:TimeWritten, :dword,
|
16
|
+
:EventID, :dword,
|
17
|
+
:EventType, :word,
|
18
|
+
:NumStrings, :word,
|
19
|
+
:EventCategory, :word,
|
20
|
+
:ReservedFlags, :word,
|
21
|
+
:ClosingRecordNumber, :dword,
|
22
|
+
:StringOffset, :dword,
|
23
|
+
:UserSidLength, :dword,
|
24
|
+
:UserSidOffset, :dword,
|
25
|
+
:DataLength, :dword,
|
26
|
+
:DataOffset, :dword
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/misc/install_msg.rb
CHANGED
@@ -1,46 +1,46 @@
|
|
1
|
-
###############################################################################
|
2
|
-
# install_msg.rb
|
3
|
-
#
|
4
|
-
# This script will create a 'RubyMsg' event source in your registry. All of
|
5
|
-
# the relevant files will be copied to the 'rubymsg' directory under C:\ruby,
|
6
|
-
# or wherever your toplevel Ruby installation directory is located. By default
|
7
|
-
# this will be installed in the 'Application' log. If you wish to change that
|
8
|
-
# then change the word 'Application' to either 'Security' or 'System' (or your
|
9
|
-
# own custom log).
|
10
|
-
#
|
11
|
-
# DO NOT MOVE THE DLL FILE ONCE IT IS INSTALLED. If you do, you will have
|
12
|
-
# to delete the registry entry and reinstall the event source pointing to the
|
13
|
-
# proper directory.
|
14
|
-
#
|
15
|
-
# You should only run this script *after* you have installed win32-eventlog.
|
16
|
-
###############################################################################
|
17
|
-
require 'rbconfig'
|
18
|
-
require 'fileutils'
|
19
|
-
require 'win32/eventlog'
|
20
|
-
require 'win32/mc'
|
21
|
-
include Win32
|
22
|
-
|
23
|
-
msg_dir = File.join(RbConfig::CONFIG['prefix'], 'rubymsg')
|
24
|
-
msg_file = 'rubymsg.mc'
|
25
|
-
|
26
|
-
Dir.mkdir(msg_dir) unless File.exists?(msg_dir)
|
27
|
-
FileUtils.cp('misc/rubymsg.mc', msg_dir)
|
28
|
-
Dir.chdir(msg_dir)
|
29
|
-
|
30
|
-
mc = Win32::MC.new(msg_file)
|
31
|
-
mc.create_all
|
32
|
-
|
33
|
-
puts ".dll created"
|
34
|
-
|
35
|
-
dll_file = File.expand_path(mc.dll_file)
|
36
|
-
|
37
|
-
# Change 'Application' to whatever you feel is appropriate
|
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
|
44
|
-
)
|
45
|
-
|
46
|
-
puts "Event source 'RubyMsg' added to registry"
|
1
|
+
###############################################################################
|
2
|
+
# install_msg.rb
|
3
|
+
#
|
4
|
+
# This script will create a 'RubyMsg' event source in your registry. All of
|
5
|
+
# the relevant files will be copied to the 'rubymsg' directory under C:\ruby,
|
6
|
+
# or wherever your toplevel Ruby installation directory is located. By default
|
7
|
+
# this will be installed in the 'Application' log. If you wish to change that
|
8
|
+
# then change the word 'Application' to either 'Security' or 'System' (or your
|
9
|
+
# own custom log).
|
10
|
+
#
|
11
|
+
# DO NOT MOVE THE DLL FILE ONCE IT IS INSTALLED. If you do, you will have
|
12
|
+
# to delete the registry entry and reinstall the event source pointing to the
|
13
|
+
# proper directory.
|
14
|
+
#
|
15
|
+
# You should only run this script *after* you have installed win32-eventlog.
|
16
|
+
###############################################################################
|
17
|
+
require 'rbconfig'
|
18
|
+
require 'fileutils'
|
19
|
+
require 'win32/eventlog'
|
20
|
+
require 'win32/mc'
|
21
|
+
include Win32
|
22
|
+
|
23
|
+
msg_dir = File.join(RbConfig::CONFIG['prefix'], 'rubymsg')
|
24
|
+
msg_file = 'rubymsg.mc'
|
25
|
+
|
26
|
+
Dir.mkdir(msg_dir) unless File.exists?(msg_dir)
|
27
|
+
FileUtils.cp('misc/rubymsg.mc', msg_dir)
|
28
|
+
Dir.chdir(msg_dir)
|
29
|
+
|
30
|
+
mc = Win32::MC.new(msg_file)
|
31
|
+
mc.create_all
|
32
|
+
|
33
|
+
puts ".dll created"
|
34
|
+
|
35
|
+
dll_file = File.expand_path(mc.dll_file)
|
36
|
+
|
37
|
+
# Change 'Application' to whatever you feel is appropriate
|
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
|
44
|
+
)
|
45
|
+
|
46
|
+
puts "Event source 'RubyMsg' added to registry"
|
data/misc/rubymsg.mc
CHANGED
@@ -1,35 +1,35 @@
|
|
1
|
-
MessageId=0x1
|
2
|
-
SymbolicName=CATEGORY_ERROR
|
3
|
-
Language=English
|
4
|
-
Error
|
5
|
-
.
|
6
|
-
|
7
|
-
MessageId=0x2
|
8
|
-
SymbolicName=CATEGORY_WARNING
|
9
|
-
Language=English
|
10
|
-
Warning
|
11
|
-
.
|
12
|
-
|
13
|
-
MessageId=0x3
|
14
|
-
SymbolicName=CATEGORY_OUTPUT
|
15
|
-
Language=English
|
16
|
-
Output
|
17
|
-
.
|
18
|
-
|
19
|
-
MessageId=0x4
|
20
|
-
SymbolicName=RUBY_ERROR
|
21
|
-
Language=English
|
22
|
-
Ruby error: %1
|
23
|
-
.
|
24
|
-
|
25
|
-
MessageId=0x5
|
26
|
-
SymbolicName=RUBY_WARNING
|
27
|
-
Language=English
|
28
|
-
Ruby warning: %1
|
29
|
-
.
|
30
|
-
|
31
|
-
MessageId=0x6
|
32
|
-
SymbolicName=RUBY_OUTPUT
|
33
|
-
Language=English
|
34
|
-
Ruby output: %1
|
35
|
-
.
|
1
|
+
MessageId=0x1
|
2
|
+
SymbolicName=CATEGORY_ERROR
|
3
|
+
Language=English
|
4
|
+
Error
|
5
|
+
.
|
6
|
+
|
7
|
+
MessageId=0x2
|
8
|
+
SymbolicName=CATEGORY_WARNING
|
9
|
+
Language=English
|
10
|
+
Warning
|
11
|
+
.
|
12
|
+
|
13
|
+
MessageId=0x3
|
14
|
+
SymbolicName=CATEGORY_OUTPUT
|
15
|
+
Language=English
|
16
|
+
Output
|
17
|
+
.
|
18
|
+
|
19
|
+
MessageId=0x4
|
20
|
+
SymbolicName=RUBY_ERROR
|
21
|
+
Language=English
|
22
|
+
Ruby error: %1
|
23
|
+
.
|
24
|
+
|
25
|
+
MessageId=0x5
|
26
|
+
SymbolicName=RUBY_WARNING
|
27
|
+
Language=English
|
28
|
+
Ruby warning: %1
|
29
|
+
.
|
30
|
+
|
31
|
+
MessageId=0x6
|
32
|
+
SymbolicName=RUBY_OUTPUT
|
33
|
+
Language=English
|
34
|
+
Ruby output: %1
|
35
|
+
.
|
data/test/foo.mc
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
MessageId=0x1
|
2
|
-
SymbolicName=CATEGORY_HELLO
|
3
|
-
Language=English
|
4
|
-
Foohello
|
5
|
-
.
|
6
|
-
|
7
|
-
MessageId=0x2
|
8
|
-
SymbolicName=CATEGORY_WORLD
|
9
|
-
Language=English
|
10
|
-
Fooworld
|
11
|
-
.
|
12
|
-
|
13
|
-
MessageId=0x3
|
14
|
-
SymbolicName=FOO_ERROR
|
15
|
-
Language=English
|
16
|
-
Foo error: %1
|
17
|
-
.
|
18
|
-
|
19
|
-
MessageId=0x4
|
20
|
-
SymbolicName=FOO_WARN
|
21
|
-
Language=English
|
22
|
-
Foo warning: %1
|
23
|
-
.
|
24
|
-
|
1
|
+
MessageId=0x1
|
2
|
+
SymbolicName=CATEGORY_HELLO
|
3
|
+
Language=English
|
4
|
+
Foohello
|
5
|
+
.
|
6
|
+
|
7
|
+
MessageId=0x2
|
8
|
+
SymbolicName=CATEGORY_WORLD
|
9
|
+
Language=English
|
10
|
+
Fooworld
|
11
|
+
.
|
12
|
+
|
13
|
+
MessageId=0x3
|
14
|
+
SymbolicName=FOO_ERROR
|
15
|
+
Language=English
|
16
|
+
Foo error: %1
|
17
|
+
.
|
18
|
+
|
19
|
+
MessageId=0x4
|
20
|
+
SymbolicName=FOO_WARN
|
21
|
+
Language=English
|
22
|
+
Foo warning: %1
|
23
|
+
.
|
24
|
+
|
data/test/test_eventlog.rb
CHANGED
@@ -1,319 +1,319 @@
|
|
1
|
-
##############################################################################
|
2
|
-
# test_eventlog.rb
|
3
|
-
#
|
4
|
-
# Test case for the win32-eventlog package. You should run this test case
|
5
|
-
# via the 'rake test' Rakefile task. This test will take a minute or two
|
6
|
-
# to complete.
|
7
|
-
#############################################################################
|
8
|
-
require 'test-unit'
|
9
|
-
require 'win32/eventlog'
|
10
|
-
require 'socket'
|
11
|
-
require 'tmpdir'
|
12
|
-
include Win32
|
13
|
-
|
14
|
-
class TC_Win32_EventLog < Test::Unit::TestCase
|
15
|
-
def self.startup
|
16
|
-
@@hostname = Socket.gethostname
|
17
|
-
end
|
18
|
-
|
19
|
-
def setup
|
20
|
-
@log = EventLog.new('Application')
|
21
|
-
@logfile = 'temp.evt'
|
22
|
-
@bakfile = File.join(Dir.tmpdir, 'test_event_log.bak')
|
23
|
-
@records = []
|
24
|
-
@last = nil
|
25
|
-
end
|
26
|
-
|
27
|
-
test "version constant is set to expected value" do
|
28
|
-
assert_equal('0.6.
|
29
|
-
end
|
30
|
-
|
31
|
-
test "constructor basic functionality" do
|
32
|
-
assert_respond_to(EventLog, :new)
|
33
|
-
assert_nothing_raised{ EventLog.new }
|
34
|
-
end
|
35
|
-
|
36
|
-
test "constructor accepts a block" do
|
37
|
-
assert_nothing_raised{ EventLog.new{ |log| } }
|
38
|
-
end
|
39
|
-
|
40
|
-
test "constructor accepts a log type" do
|
41
|
-
assert_nothing_raised{ EventLog.new('System') }
|
42
|
-
end
|
43
|
-
|
44
|
-
test "constructor accepts a host name" do
|
45
|
-
assert_nothing_raised{ EventLog.new('System', @@hostname) }
|
46
|
-
end
|
47
|
-
|
48
|
-
#test "open is a singleton alias for new" do
|
49
|
-
# assert_alias_method(EventLog, :new, :open)
|
50
|
-
#end
|
51
|
-
|
52
|
-
test "constructor accepts a maximum of three arguments" do
|
53
|
-
assert_raises(ArgumentError){ EventLog.new('System', @@hostname, 'foo', 'bar') }
|
54
|
-
end
|
55
|
-
|
56
|
-
test "arguments to constructor must be strings" do
|
57
|
-
assert_raises(TypeError){ EventLog.open(1) }
|
58
|
-
assert_raises(TypeError){ EventLog.open('System', 1) }
|
59
|
-
end
|
60
|
-
|
61
|
-
test "source accessor method basic functionality" do
|
62
|
-
@log = EventLog.new('Application', @@hostname)
|
63
|
-
assert_respond_to(@log, :source)
|
64
|
-
assert_equal('Application', @log.source)
|
65
|
-
end
|
66
|
-
|
67
|
-
test "server accessor method basic functionality" do
|
68
|
-
@log = EventLog.new('Application', @@hostname)
|
69
|
-
assert_respond_to(@log, :server)
|
70
|
-
assert_equal(@@hostname, @log.server)
|
71
|
-
end
|
72
|
-
|
73
|
-
test "backup basic functionality" do
|
74
|
-
assert_respond_to(@log, :backup)
|
75
|
-
assert_nothing_raised{ @log.backup(@bakfile) }
|
76
|
-
end
|
77
|
-
|
78
|
-
test "backup works as expected" do
|
79
|
-
assert_nothing_raised{ @log.backup(@bakfile) }
|
80
|
-
assert(File.exist?(@bakfile))
|
81
|
-
end
|
82
|
-
|
83
|
-
test "backup method fails if backup file already exists" do
|
84
|
-
assert_nothing_raised{ @log.backup(@bakfile) }
|
85
|
-
assert_raise(SystemCallError){ @log.backup(@bakfile) }
|
86
|
-
end
|
87
|
-
|
88
|
-
test "open_backup basic functionality" do
|
89
|
-
assert_respond_to(EventLog, :open_backup)
|
90
|
-
end
|
91
|
-
|
92
|
-
test "open_backup works as expected" do
|
93
|
-
EventLog.new('Application', @@hostname){ |log| log.backup(@bakfile) }
|
94
|
-
assert_nothing_raised{ @log = EventLog.open_backup(@bakfile) }
|
95
|
-
assert_kind_of(EventLog, @log)
|
96
|
-
end
|
97
|
-
|
98
|
-
test "it is possible to read and close the backup log file" do
|
99
|
-
EventLog.new('Application', @@hostname){ |log| log.backup(@bakfile) }
|
100
|
-
@log = EventLog.open_backup(@bakfile)
|
101
|
-
assert_nothing_raised{ @log.read{ break } }
|
102
|
-
assert_nothing_raised{ @log.close }
|
103
|
-
end
|
104
|
-
|
105
|
-
# Ensure that an Array is returned in non-block form and that none of the
|
106
|
-
# descriptions are nil.
|
107
|
-
#
|
108
|
-
# The test for descriptions was added as a result of ruby-talk:116528.
|
109
|
-
# Thanks go to Joey Gibson for the spot. The test for unique record
|
110
|
-
# numbers was added to ensure no dups.
|
111
|
-
#
|
112
|
-
test "singleton read method works as expected" do
|
113
|
-
assert_nothing_raised{ @array = EventLog.read }
|
114
|
-
assert_kind_of(Array, @array)
|
115
|
-
|
116
|
-
record_numbers = []
|
117
|
-
@array.each{ |log|
|
118
|
-
assert_not_nil(log.description)
|
119
|
-
assert_equal(false, record_numbers.include?(log.record_number))
|
120
|
-
record_numbers << log.record_number
|
121
|
-
}
|
122
|
-
end
|
123
|
-
|
124
|
-
# I've added explicit breaks because an event log could be rather large.
|
125
|
-
#
|
126
|
-
test "singleton read method does not require any arguments" do
|
127
|
-
assert_nothing_raised{ EventLog.read{ break } }
|
128
|
-
end
|
129
|
-
|
130
|
-
test "singleton read method accepts a log type" do
|
131
|
-
assert_nothing_raised{ EventLog.read("Application"){ break } }
|
132
|
-
end
|
133
|
-
|
134
|
-
test "singleton read method accepts a server argument" do
|
135
|
-
assert_nothing_raised{ EventLog.read("Application", nil){ break } }
|
136
|
-
end
|
137
|
-
|
138
|
-
test "singleton read method accepts a flags argument" do
|
139
|
-
assert_nothing_raised{ EventLog.read("Application", nil, nil){ break } }
|
140
|
-
end
|
141
|
-
|
142
|
-
test "singleton read method accepts an offset argument" do
|
143
|
-
assert_nothing_raised{ EventLog.read("Application", nil, nil, 10){ break } }
|
144
|
-
end
|
145
|
-
|
146
|
-
test "singleton read method accepts a maximum of four arguments" do
|
147
|
-
assert_raises(ArgumentError){
|
148
|
-
EventLog.read("Application", nil, nil, nil, nil){}
|
149
|
-
}
|
150
|
-
end
|
151
|
-
|
152
|
-
test "instance method read basic functionality" do
|
153
|
-
assert_respond_to(@log, :read)
|
154
|
-
assert_nothing_raised{ @log.read{ break } }
|
155
|
-
end
|
156
|
-
|
157
|
-
test "instance method read accepts flags" do
|
158
|
-
flags = EventLog::FORWARDS_READ | EventLog::SEQUENTIAL_READ
|
159
|
-
assert_nothing_raised{ @log.read(flags){ break } }
|
160
|
-
end
|
161
|
-
|
162
|
-
test "instance method read accepts an offset" do
|
163
|
-
assert_nothing_raised{ @log.read(nil, 500){ break } }
|
164
|
-
end
|
165
|
-
|
166
|
-
test "instance method read accepts a maximum of two arguments" do
|
167
|
-
assert_raises(ArgumentError){ @log.read(nil, 500, 'foo') }
|
168
|
-
end
|
169
|
-
|
170
|
-
test "read_last_event method basic functionality" do
|
171
|
-
assert_respond_to(@log, :read_last_event)
|
172
|
-
assert_nothing_raised{ @log.read_last_event }
|
173
|
-
end
|
174
|
-
|
175
|
-
test "read_last_event returns the expected results" do
|
176
|
-
assert_kind_of(Win32::EventLog::EventLogStruct, @log.read_last_event)
|
177
|
-
end
|
178
|
-
|
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
|
195
|
-
|
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
|
200
|
-
|
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
|
230
|
-
|
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
|
236
|
-
|
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
|
245
|
-
|
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
|
262
|
-
|
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(ArgumentError){ @log.tail }
|
269
|
-
end
|
270
|
-
|
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(ArgumentError){ @log.notify_change }
|
277
|
-
end
|
278
|
-
|
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
|
291
|
-
|
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_TYPE)
|
302
|
-
assert_not_nil(EventLog::WARN_TYPE)
|
303
|
-
assert_not_nil(EventLog::INFO_TYPE)
|
304
|
-
assert_not_nil(EventLog::AUDIT_SUCCESS)
|
305
|
-
assert_not_nil(EventLog::AUDIT_FAILURE)
|
306
|
-
end
|
307
|
-
|
308
|
-
def teardown
|
309
|
-
@log.close rescue nil
|
310
|
-
File.delete(@bakfile) if File.exist?(@bakfile)
|
311
|
-
@logfile = nil
|
312
|
-
@records = nil
|
313
|
-
@last = nil
|
314
|
-
end
|
315
|
-
|
316
|
-
def self.shutdown
|
317
|
-
@@hostname = nil
|
318
|
-
end
|
319
|
-
end
|
1
|
+
##############################################################################
|
2
|
+
# test_eventlog.rb
|
3
|
+
#
|
4
|
+
# Test case for the win32-eventlog package. You should run this test case
|
5
|
+
# via the 'rake test' Rakefile task. This test will take a minute or two
|
6
|
+
# to complete.
|
7
|
+
#############################################################################
|
8
|
+
require 'test-unit'
|
9
|
+
require 'win32/eventlog'
|
10
|
+
require 'socket'
|
11
|
+
require 'tmpdir'
|
12
|
+
include Win32
|
13
|
+
|
14
|
+
class TC_Win32_EventLog < Test::Unit::TestCase
|
15
|
+
def self.startup
|
16
|
+
@@hostname = Socket.gethostname
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup
|
20
|
+
@log = EventLog.new('Application')
|
21
|
+
@logfile = 'temp.evt'
|
22
|
+
@bakfile = File.join(Dir.tmpdir, 'test_event_log.bak')
|
23
|
+
@records = []
|
24
|
+
@last = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
test "version constant is set to expected value" do
|
28
|
+
assert_equal('0.6.4', EventLog::VERSION)
|
29
|
+
end
|
30
|
+
|
31
|
+
test "constructor basic functionality" do
|
32
|
+
assert_respond_to(EventLog, :new)
|
33
|
+
assert_nothing_raised{ EventLog.new }
|
34
|
+
end
|
35
|
+
|
36
|
+
test "constructor accepts a block" do
|
37
|
+
assert_nothing_raised{ EventLog.new{ |log| } }
|
38
|
+
end
|
39
|
+
|
40
|
+
test "constructor accepts a log type" do
|
41
|
+
assert_nothing_raised{ EventLog.new('System') }
|
42
|
+
end
|
43
|
+
|
44
|
+
test "constructor accepts a host name" do
|
45
|
+
assert_nothing_raised{ EventLog.new('System', @@hostname) }
|
46
|
+
end
|
47
|
+
|
48
|
+
#test "open is a singleton alias for new" do
|
49
|
+
# assert_alias_method(EventLog, :new, :open)
|
50
|
+
#end
|
51
|
+
|
52
|
+
test "constructor accepts a maximum of three arguments" do
|
53
|
+
assert_raises(ArgumentError){ EventLog.new('System', @@hostname, 'foo', 'bar') }
|
54
|
+
end
|
55
|
+
|
56
|
+
test "arguments to constructor must be strings" do
|
57
|
+
assert_raises(TypeError){ EventLog.open(1) }
|
58
|
+
assert_raises(TypeError){ EventLog.open('System', 1) }
|
59
|
+
end
|
60
|
+
|
61
|
+
test "source accessor method basic functionality" do
|
62
|
+
@log = EventLog.new('Application', @@hostname)
|
63
|
+
assert_respond_to(@log, :source)
|
64
|
+
assert_equal('Application', @log.source)
|
65
|
+
end
|
66
|
+
|
67
|
+
test "server accessor method basic functionality" do
|
68
|
+
@log = EventLog.new('Application', @@hostname)
|
69
|
+
assert_respond_to(@log, :server)
|
70
|
+
assert_equal(@@hostname, @log.server)
|
71
|
+
end
|
72
|
+
|
73
|
+
test "backup basic functionality" do
|
74
|
+
assert_respond_to(@log, :backup)
|
75
|
+
assert_nothing_raised{ @log.backup(@bakfile) }
|
76
|
+
end
|
77
|
+
|
78
|
+
test "backup works as expected" do
|
79
|
+
assert_nothing_raised{ @log.backup(@bakfile) }
|
80
|
+
assert(File.exist?(@bakfile))
|
81
|
+
end
|
82
|
+
|
83
|
+
test "backup method fails if backup file already exists" do
|
84
|
+
assert_nothing_raised{ @log.backup(@bakfile) }
|
85
|
+
assert_raise(SystemCallError){ @log.backup(@bakfile) }
|
86
|
+
end
|
87
|
+
|
88
|
+
test "open_backup basic functionality" do
|
89
|
+
assert_respond_to(EventLog, :open_backup)
|
90
|
+
end
|
91
|
+
|
92
|
+
test "open_backup works as expected" do
|
93
|
+
EventLog.new('Application', @@hostname){ |log| log.backup(@bakfile) }
|
94
|
+
assert_nothing_raised{ @log = EventLog.open_backup(@bakfile) }
|
95
|
+
assert_kind_of(EventLog, @log)
|
96
|
+
end
|
97
|
+
|
98
|
+
test "it is possible to read and close the backup log file" do
|
99
|
+
EventLog.new('Application', @@hostname){ |log| log.backup(@bakfile) }
|
100
|
+
@log = EventLog.open_backup(@bakfile)
|
101
|
+
assert_nothing_raised{ @log.read{ break } }
|
102
|
+
assert_nothing_raised{ @log.close }
|
103
|
+
end
|
104
|
+
|
105
|
+
# Ensure that an Array is returned in non-block form and that none of the
|
106
|
+
# descriptions are nil.
|
107
|
+
#
|
108
|
+
# The test for descriptions was added as a result of ruby-talk:116528.
|
109
|
+
# Thanks go to Joey Gibson for the spot. The test for unique record
|
110
|
+
# numbers was added to ensure no dups.
|
111
|
+
#
|
112
|
+
test "singleton read method works as expected" do
|
113
|
+
assert_nothing_raised{ @array = EventLog.read }
|
114
|
+
assert_kind_of(Array, @array)
|
115
|
+
|
116
|
+
record_numbers = []
|
117
|
+
@array.each{ |log|
|
118
|
+
assert_not_nil(log.description)
|
119
|
+
assert_equal(false, record_numbers.include?(log.record_number))
|
120
|
+
record_numbers << log.record_number
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
# I've added explicit breaks because an event log could be rather large.
|
125
|
+
#
|
126
|
+
test "singleton read method does not require any arguments" do
|
127
|
+
assert_nothing_raised{ EventLog.read{ break } }
|
128
|
+
end
|
129
|
+
|
130
|
+
test "singleton read method accepts a log type" do
|
131
|
+
assert_nothing_raised{ EventLog.read("Application"){ break } }
|
132
|
+
end
|
133
|
+
|
134
|
+
test "singleton read method accepts a server argument" do
|
135
|
+
assert_nothing_raised{ EventLog.read("Application", nil){ break } }
|
136
|
+
end
|
137
|
+
|
138
|
+
test "singleton read method accepts a flags argument" do
|
139
|
+
assert_nothing_raised{ EventLog.read("Application", nil, nil){ break } }
|
140
|
+
end
|
141
|
+
|
142
|
+
test "singleton read method accepts an offset argument" do
|
143
|
+
assert_nothing_raised{ EventLog.read("Application", nil, nil, 10){ break } }
|
144
|
+
end
|
145
|
+
|
146
|
+
test "singleton read method accepts a maximum of four arguments" do
|
147
|
+
assert_raises(ArgumentError){
|
148
|
+
EventLog.read("Application", nil, nil, nil, nil){}
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
test "instance method read basic functionality" do
|
153
|
+
assert_respond_to(@log, :read)
|
154
|
+
assert_nothing_raised{ @log.read{ break } }
|
155
|
+
end
|
156
|
+
|
157
|
+
test "instance method read accepts flags" do
|
158
|
+
flags = EventLog::FORWARDS_READ | EventLog::SEQUENTIAL_READ
|
159
|
+
assert_nothing_raised{ @log.read(flags){ break } }
|
160
|
+
end
|
161
|
+
|
162
|
+
test "instance method read accepts an offset" do
|
163
|
+
assert_nothing_raised{ @log.read(nil, 500){ break } }
|
164
|
+
end
|
165
|
+
|
166
|
+
test "instance method read accepts a maximum of two arguments" do
|
167
|
+
assert_raises(ArgumentError){ @log.read(nil, 500, 'foo') }
|
168
|
+
end
|
169
|
+
|
170
|
+
test "read_last_event method basic functionality" do
|
171
|
+
assert_respond_to(@log, :read_last_event)
|
172
|
+
assert_nothing_raised{ @log.read_last_event }
|
173
|
+
end
|
174
|
+
|
175
|
+
test "read_last_event returns the expected results" do
|
176
|
+
assert_kind_of(Win32::EventLog::EventLogStruct, @log.read_last_event)
|
177
|
+
end
|
178
|
+
|
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
|
195
|
+
|
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
|
200
|
+
|
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
|
230
|
+
|
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
|
236
|
+
|
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
|
245
|
+
|
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
|
262
|
+
|
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(ArgumentError){ @log.tail }
|
269
|
+
end
|
270
|
+
|
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(ArgumentError){ @log.notify_change }
|
277
|
+
end
|
278
|
+
|
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
|
291
|
+
|
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_TYPE)
|
302
|
+
assert_not_nil(EventLog::WARN_TYPE)
|
303
|
+
assert_not_nil(EventLog::INFO_TYPE)
|
304
|
+
assert_not_nil(EventLog::AUDIT_SUCCESS)
|
305
|
+
assert_not_nil(EventLog::AUDIT_FAILURE)
|
306
|
+
end
|
307
|
+
|
308
|
+
def teardown
|
309
|
+
@log.close rescue nil
|
310
|
+
File.delete(@bakfile) if File.exist?(@bakfile)
|
311
|
+
@logfile = nil
|
312
|
+
@records = nil
|
313
|
+
@last = nil
|
314
|
+
end
|
315
|
+
|
316
|
+
def self.shutdown
|
317
|
+
@@hostname = nil
|
318
|
+
end
|
319
|
+
end
|