solaris-kstat 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ require File.join(File.dirname(__FILE__), 'structs')
2
+
3
+ module Solaris
4
+ module Functions
5
+ extend FFI::Library
6
+ ffi_lib :kstat
7
+
8
+ include Solaris::Structs
9
+
10
+ attach_function :kstat_chain_update, [KstatCtl], :int
11
+ attach_function :kstat_close, [KstatCtl], :int
12
+ attach_function :kstat_lookup, [KstatCtl, :string, :int, :string], KstatStruct.by_ref
13
+ attach_function :kstat_open, [], KstatCtl.by_ref
14
+ attach_function :kstat_read, [KstatCtl, KstatStruct, :pointer], :int
15
+
16
+ private :kstat_chain_update
17
+ private :kstat_close
18
+ private :kstat_lookup
19
+ private :kstat_open
20
+ private :kstat_read
21
+ end
22
+ end
@@ -0,0 +1,260 @@
1
+ require 'ffi'
2
+
3
+ module Solaris
4
+ module Structs
5
+ extend FFI::Library
6
+
7
+ class KstatCtl < FFI::Struct
8
+ layout(
9
+ :kc_chain_id, :int,
10
+ :kc_chain, :pointer,
11
+ :kc_kd, :int
12
+ )
13
+ end
14
+
15
+ class KstatStruct < FFI::Struct
16
+ layout(
17
+ :ks_crtime, :long_long,
18
+ :ks_next, :pointer,
19
+ :ks_kid, :int,
20
+ :ks_module, [:char, 31],
21
+ :ks_resv, :uchar,
22
+ :ks_instance, :int,
23
+ :ks_name, [:char, 31],
24
+ :ks_type, :uchar,
25
+ :ks_class, [:char, 31],
26
+ :ks_flags, :uchar,
27
+ :ks_data, :pointer,
28
+ :ks_ndata, :uint,
29
+ :ks_data_size, :ulong,
30
+ :ks_snaptime, :long_long,
31
+ :ks_update, :int,
32
+ :ks_private, :pointer,
33
+ :ks_snapshot, :int,
34
+ :ks_lock, :pointer,
35
+ )
36
+ end
37
+
38
+ class Addr < FFI::Union
39
+ layout(
40
+ :ptr, :pointer,
41
+ :ptr32, :int32_t,
42
+ :pad, [:char, 8]
43
+ )
44
+ end
45
+
46
+ class Str < FFI::Struct
47
+ layout(:union, Addr, :len, :uint32_t)
48
+ end
49
+
50
+ class Value < FFI::Union
51
+ layout(
52
+ :c, [:char, 16],
53
+ :i32, :int32_t,
54
+ :ui32, :uint32_t,
55
+ :str, Str,
56
+ :i64, :int64_t,
57
+ :ui64, :uint64_t,
58
+ :l, :long,
59
+ :ul, :ulong_t,
60
+ :ll, :longlong_t,
61
+ :ull, :ulong_long,
62
+ :f, :float,
63
+ :d, :double
64
+ )
65
+ end
66
+
67
+ class KstatNamed < FFI::Struct
68
+ layout(
69
+ :name, [:char, 31],
70
+ :data_type, :uchar_t,
71
+ :value, Value
72
+ )
73
+ end
74
+
75
+ class Vminfo < FFI::Struct
76
+ layout(
77
+ :freemem, :uint64_t,
78
+ :swap_resv, :uint64_t,
79
+ :swap_alloc, :uint64_t,
80
+ :swap_avail, :uint64_t,
81
+ :swap_free, :uint64_t,
82
+ :updates, :uint64_t
83
+ )
84
+ end
85
+
86
+ class Flushmeter < FFI::Struct
87
+ layout(
88
+ :f_ctx, :uint,
89
+ :f_segment, :uint,
90
+ :f_page, :uint,
91
+ :f_partial, :uint,
92
+ :f_usr, :uint,
93
+ :f_region, :uint
94
+ )
95
+ end
96
+
97
+ class NcStats < FFI::Struct
98
+ layout(
99
+ :hits, :int,
100
+ :misses, :int,
101
+ :enters, :int,
102
+ :dbl_enters, :int,
103
+ :long_enter, :int,
104
+ :long_look, :int,
105
+ :move_to_front, :int,
106
+ :purges, :int
107
+ )
108
+ end
109
+
110
+ class Sysinfo < FFI::Struct
111
+ layout(
112
+ :updates, :uint,
113
+ :runque, :uint,
114
+ :runocc, :uint,
115
+ :swpque, :uint,
116
+ :swpocc, :uint,
117
+ :waiting, :uint
118
+ )
119
+ end
120
+
121
+ class Var < FFI::Struct
122
+ layout(
123
+ :v_buf, :int,
124
+ :v_call, :int,
125
+ :v_proc, :int,
126
+ :v_maxupttl, :int,
127
+ :v_nglobpris, :int,
128
+ :v_maxsyspri, :int,
129
+ :v_clist, :int,
130
+ :v_maxup, :int,
131
+ :v_hbuf, :int,
132
+ :v_hmask, :int,
133
+ :v_pbuf, :int,
134
+ :v_sptmap, :int,
135
+ :v_maxpmem, :int,
136
+ :v_autoup, :int,
137
+ :v_bufhwm, :int
138
+ )
139
+ end
140
+
141
+ class KstatIntr < FFI::Struct
142
+ layout(:intrs, [:uint, 5])
143
+ end
144
+
145
+ class KstatIo < FFI::Struct
146
+ layout(
147
+ :nread, :ulong_long,
148
+ :nwritten, :ulong_long,
149
+ :reads, :uint,
150
+ :writes, :uint,
151
+ :wtime, :long_long,
152
+ :wlentime, :long_long,
153
+ :wlastupdate, :long_long,
154
+ :rtime, :long_long,
155
+ :rlentime, :long_long,
156
+ :rlastupdate, :long_long,
157
+ :wcnt, :uint,
158
+ :rcnt, :uint
159
+ )
160
+ end
161
+
162
+ class KstatTimer < FFI::Struct
163
+ layout(
164
+ :name, [:char, 31],
165
+ :resv, :uchar,
166
+ :num_events, :ulong_long,
167
+ :elapsed_time, :long_long,
168
+ :min_time, :long_long,
169
+ :max_time, :long_long,
170
+ :start_time, :long_long,
171
+ :stop_time, :long_long
172
+ )
173
+ end
174
+
175
+ class CpuSysinfo < FFI::Struct
176
+ layout(
177
+ :cpu, [:uint_t, 4],
178
+ :wait, [:uint_t, 3],
179
+ :bread, :uint_t,
180
+ :bwrite, :uint_t,
181
+ :lread, :uint_t,
182
+ :lwrite, :uint_t,
183
+ :phread, :uint_t,
184
+ :phwrite, :uint_t,
185
+ :pswitch, :uint_t,
186
+ :trap, :uint_t,
187
+ :intr, :uint_t,
188
+ :syscall, :uint_t,
189
+ :sysread, :uint_t,
190
+ :syswrite, :uint_t,
191
+ :sysfork, :uint_t,
192
+ :sysvfork, :uint_t,
193
+ :sysexec, :uint_t,
194
+ :readch, :uint_t,
195
+ :writech, :uint_t,
196
+ :rcvint, :uint_t,
197
+ :xmtint, :uint_t,
198
+ :mdmint, :uint_t,
199
+ :rawch, :uint_t,
200
+ :canch, :uint_t,
201
+ :outch, :uint_t,
202
+ :msg, :uint_t,
203
+ :sema, :uint_t,
204
+ :namei, :uint_t,
205
+ :ufsiget, :uint_t,
206
+ :ufsdirblk, :uint_t,
207
+ :ufsipage, :uint_t,
208
+ :ufsinopage, :uint_t,
209
+ :inodeovf, :uint_t,
210
+ :fileovf, :uint_t,
211
+ :procovf, :uint_t,
212
+ :intrthread, :uint_t,
213
+ :intrblk, :uint_t,
214
+ :idlethread, :uint_t,
215
+ :inv_swtch, :uint_t,
216
+ :nthreads, :uint_t,
217
+ :cpumigrate, :uint_t,
218
+ :xcalls, :uint_t,
219
+ :mutex_adenters, :uint_t,
220
+ :rw_rdfails, :uint_t,
221
+ :rw_wrfails, :uint_t,
222
+ :modload, :uint_t,
223
+ :modunload, :uint_t,
224
+ :bawrite, :uint_t,
225
+ :rw_enters, :uint_t,
226
+ :win_uo_cnt, :uint_t,
227
+ :win_uu_cnt, :uint_t,
228
+ :win_so_cnt, :uint_t,
229
+ :win_su_cnt, :uint_t,
230
+ :win_suo_cnt, :uint_t
231
+ )
232
+ end
233
+
234
+ class MikStruct < FFI::Struct
235
+ layout(:srtt, :uint32_t, :deviate, :uint32_t, :rtxcur, :uint32_t)
236
+ end
237
+
238
+ class Mntinfo < FFI::Struct
239
+ layout(
240
+ :mik_proto, [:char, 128],
241
+ :mik_vers, :uint32_t,
242
+ :mik_flags, :uint_t,
243
+ :mik_secmod, :uint_t,
244
+ :mik_curread, :uint32_t,
245
+ :mik_curwrite, :uint32_t,
246
+ :mik_timeo, :int,
247
+ :mik_retrans, :int,
248
+ :mik_acregmin, :uint_t,
249
+ :mik_acregmax, :uint_t,
250
+ :mik_acdirmin, :uint_t,
251
+ :mik_acdirmax, :uint_t,
252
+ :mik_timers, [MikStruct, 4],
253
+ :mik_noresponse, :uint32_t,
254
+ :mik_failover, :uint32_t,
255
+ :mik_remap, :uint32_t,
256
+ :mik_curserver, [:char, 257]
257
+ )
258
+ end
259
+ end
260
+ end
@@ -2,25 +2,27 @@ require 'rubygems'
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'solaris-kstat'
5
- spec.version = '1.0.3'
5
+ spec.version = '1.1.0'
6
6
  spec.author = 'Daniel J. Berger'
7
7
  spec.license = 'Artistic 2.0'
8
8
  spec.email = 'djberg96@gmail.com'
9
- spec.homepage = 'http://www.rubyforge.org/projects/solarisutils'
9
+ spec.homepage = 'https://github.com/djberg96/solaris-kstat'
10
10
  spec.summary = 'Interface for the Solaris kstat library'
11
- spec.test_file = 'test/test_solaris_kstat.rb'
12
- spec.extensions = ['ext/extconf.rb']
11
+ spec.test_files = Dir['test/*.rb']
13
12
  spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
14
13
 
15
14
  spec.rubyforge_project = 'solarisutils'
16
15
 
16
+ spec.add_dependency('ffi')
17
+
17
18
  spec.add_development_dependency('test-unit')
19
+ spec.add_development_dependency('mkmf-lite')
20
+ spec.add_development_dependency('rake')
18
21
 
19
22
  spec.extra_rdoc_files = [
20
23
  'README',
21
24
  'CHANGES',
22
25
  'MANIFEST',
23
- 'ext/solaris/rkstat.c'
24
26
  ]
25
27
 
26
28
  spec.description = <<-EOF
@@ -1,15 +1,11 @@
1
- ###############################################################################
1
+ ########################################################################
2
2
  # test_solaris_kstat.rb
3
3
  #
4
- # Test suite for the solaris-kstat Ruby library. You should run this via
5
- # the 'rake test' task.
6
- ###############################################################################
7
- require 'rubygems'
8
- gem 'test-unit'
9
-
4
+ # Test suite for the solaris-kstat Ruby library. You should run this
5
+ # via the 'rake test' task.
6
+ ########################################################################
10
7
  require 'solaris/kstat'
11
- require 'test/unit'
12
- require 'set'
8
+ require 'test-unit'
13
9
  include Solaris
14
10
 
15
11
  class TC_Solaris_Kstat < Test::Unit::TestCase
@@ -17,88 +13,124 @@ class TC_Solaris_Kstat < Test::Unit::TestCase
17
13
  @kstat = Kstat.new
18
14
  end
19
15
 
20
- def test_version
21
- assert_equal('1.0.3', Kstat::VERSION)
16
+ test "version number is set to the expected value" do
17
+ assert_equal('1.1.0', Kstat::VERSION)
22
18
  end
23
19
 
24
- def test_name
20
+ test "name method basic functionality" do
25
21
  assert_respond_to(@kstat, :name)
26
- assert_respond_to(@kstat, :name=)
27
- assert_nil(@kstat.name)
28
22
  assert_nothing_raised{ @kstat.name }
23
+ end
24
+
25
+ test "name is nil by default" do
26
+ assert_nil(@kstat.name)
27
+ end
28
+
29
+ test "name= method basic functionality" do
30
+ assert_respond_to(@kstat, :name=)
29
31
  assert_nothing_raised{ @kstat.name = 'foo' }
30
32
  end
31
33
 
32
- def test_module
34
+ test "name= method works as expected" do
35
+ assert_nothing_raised{ @kstat.name = 'cpu' }
36
+ assert_equal('cpu', @kstat.name)
37
+ end
38
+
39
+ test "module basic functionality" do
33
40
  assert_respond_to(@kstat, :module)
34
- assert_respond_to(@kstat, :module=)
35
- assert_nil(@kstat.module)
36
41
  assert_nothing_raised{ @kstat.module }
42
+ end
43
+
44
+ test "module is nil by default" do
45
+ assert_nil(@kstat.module)
46
+ end
47
+
48
+ test "module= method basic functionality" do
49
+ assert_respond_to(@kstat, :module=)
37
50
  assert_nothing_raised{ @kstat.module = 'bar' }
38
51
  end
39
52
 
40
- def test_instance
53
+ test "module= method works as expected" do
54
+ assert_nothing_raised{ @kstat.module = 'bar' }
55
+ assert_equal('bar', @kstat.module)
56
+ end
57
+
58
+ test "instance method basic functionality" do
41
59
  assert_respond_to(@kstat, :instance)
42
- assert_respond_to(@kstat, :instance=)
43
- assert_nil(@kstat.instance)
44
60
  assert_nothing_raised{ @kstat.instance }
61
+ end
62
+
63
+ test "instance method is -1 by default" do
64
+ assert_equal(-1, @kstat.instance)
65
+ end
66
+
67
+ test "instance= method basic functionality" do
68
+ assert_respond_to(@kstat, :instance=)
45
69
  assert_nothing_raised{ @kstat.instance = 0 }
46
70
  end
47
71
 
48
- def test_constructor_valid_values
49
- assert_nothing_raised{ Kstat.new('cpu_info',0,'cpu_info0').record }
50
- assert_nothing_raised{ Kstat.new(nil,0,'cpu_info0').record }
51
- assert_nothing_raised{ Kstat.new('cpu_info',0,nil).record }
72
+ test "instance= method works as expected" do
73
+ assert_nothing_raised{ @kstat.instance = 0 }
74
+ assert_equal(0, @kstat.instance)
52
75
  end
53
76
 
54
- def test_constructor_invalid_values
55
- assert_raises(Kstat::Error){ Kstat.new('bogus').record }
56
- assert_raises(Kstat::Error){ Kstat.new('cpu_info',99).record }
57
- assert_raises(Kstat::Error){ Kstat.new('cpu_info',0,'bogus').record }
58
- assert_raises(TypeError){ Kstat.new('cpu_info','x').record }
77
+ test "the module argument must be a string" do
78
+ assert_nothing_raised{ Kstat.new('cpu_info') }
79
+ assert_raise(TypeError){ Kstat.new(0) }
59
80
  end
60
81
 
61
- def test_record_basic
82
+ test "the instance argument must be a number" do
83
+ assert_nothing_raised{ Kstat.new(nil, 0, nil) }
84
+ assert_raise(TypeError){ Kstat.new(nil, 'test', nil) }
85
+ end
86
+
87
+ test "the name argument must be a string" do
88
+ assert_nothing_raised{ Kstat.new('cpu_info', 0, 'cpu_info0') }
89
+ assert_raise(TypeError){ Kstat.new('cpu_info', 0, 0) }
90
+ end
91
+
92
+ test "record method basic functionality" do
62
93
  assert_respond_to(@kstat, :record)
94
+ assert_nothing_raised{ @kstat.record }
63
95
  end
64
96
 
65
- def test_record_named
97
+ test "named record works as expected" do
66
98
  assert_nothing_raised{ @kstat.record['cpu_info'][0]['cpu_info0'] }
67
99
  assert_kind_of(Hash, @kstat.record['cpu_info'][0]['cpu_info0'])
68
100
  end
69
101
 
70
- def test_record_io
102
+ test "io record works as expected" do
71
103
  assert_nothing_raised{ @kstat.record['nfs'][1]['nfs1'] }
72
104
  assert_kind_of(Hash, @kstat.record['nfs'][1]['nfs1'])
73
105
  end
74
106
 
75
- def test_record_intr
107
+ test "intr record works as expected" do
76
108
  assert_nothing_raised{ @kstat.record['fd'][0]['fd0'] }
77
109
  assert_kind_of(Hash, @kstat.record['fd'][0]['fd0'])
78
110
  end
79
111
 
80
- def test_record_raw_vminfo
81
- keys = %w/class freemem swap_alloc swap_avail swap_free swap_resv/
112
+ test "raw vminfo record returns expected values" do
113
+ keys = %w[class freemem swap_alloc swap_avail swap_free swap_resv updates]
82
114
 
83
115
  assert_nothing_raised{ @kstat.record['unix'][0]['vminfo'] }
84
116
  assert_kind_of(Hash, @kstat.record['unix'][0]['vminfo'])
85
117
  assert_equal(keys, @kstat.record['unix'][0]['vminfo'].keys.sort)
86
118
  end
87
119
 
88
- def test_record_raw_var
89
- keys = %w/
120
+ test "raw var record returns expected values" do
121
+ keys = %w[
90
122
  class v_autoup v_buf v_bufhwm v_call v_clist v_hbuf v_hmask
91
123
  v_maxpmem v_maxsyspri v_maxup v_maxupttl v_nglobpris v_pbuf
92
124
  v_proc v_sptmap
93
- /
125
+ ]
94
126
 
95
127
  assert_nothing_raised{ @kstat.record['unix'][0]['var'] }
96
128
  assert_kind_of(Hash, @kstat.record['unix'][0]['var'])
97
129
  assert_equal(keys, @kstat.record['unix'][0]['var'].keys.sort)
98
130
  end
99
131
 
100
- def test_record_raw_biostats
101
- keys = %w/
132
+ test "raw biostats returns expected values" do
133
+ keys = %w[
102
134
  buffer_cache_hits
103
135
  buffer_cache_lookups
104
136
  buffers_locked_by_someone
@@ -106,15 +138,15 @@ class TC_Solaris_Kstat < Test::Unit::TestCase
106
138
  duplicate_buffers_found
107
139
  new_buffer_requests
108
140
  waits_for_buffer_allocs
109
- /
141
+ ]
110
142
 
111
143
  assert_nothing_raised{ @kstat.record['unix'][0]['biostats'] }
112
144
  assert_kind_of([Hash, NilClass], @kstat.record['unix'][0]['biostats'])
113
145
  assert_equal(keys, @kstat.record['unix'][0]['biostats'].keys.sort)
114
146
  end
115
147
 
116
- def test_record_raw_cpu_stat
117
- keys = %w/
148
+ test "raw cpu_stat returns expected values" do
149
+ keys = %w[
118
150
  class cpu_idle cpu_user cpu_kernel cpu_wait wait_io wait_swap
119
151
  wait_pio bread bwrite lread lwrite phread phwrite pswitch
120
152
  trap intr syscall sysread syswrite sysfork sysvfork sysexec
@@ -122,22 +154,20 @@ class TC_Solaris_Kstat < Test::Unit::TestCase
122
154
  sema namei ufsiget ufsdirblk ufsipage ufsinopage inodeovf
123
155
  fileovf procovf intrthread intrblk idlethread inv_swtch
124
156
  nthreads cpumigrate xcalls mutex_adenters rw_rdfails
125
- rw_wrfails modload modunload bawrite
126
- /
157
+ rw_wrfails modload modunload bawrite win_so_cnt win_su_cnt
158
+ win_suo_cnt win_uo_cnt win_uu_cnt rw_enters
159
+ ]
127
160
 
128
161
  assert_nothing_raised{ @kstat.record['cpu_stat'][0]['cpu_stat0'] }
129
162
  assert_kind_of(Hash, @kstat.record['cpu_stat'][0]['cpu_stat0'])
130
163
 
131
- # Too big and difficult to sort manually - so use a Set
132
- set1 = Set.new(keys)
133
- set2 = Set.new(@kstat.record['cpu_stat'][0]['cpu_stat0'].keys)
134
- diff = set1 - set2
135
-
136
- assert_equal(set1,set2,'Diff was: #{diff.to_a}')
164
+ set1 = keys.sort
165
+ set2 = @kstat.record['cpu_stat'][0]['cpu_stat0'].keys.sort
166
+ assert_equal(set1, set2)
137
167
  end
138
168
 
139
- def test_record_ncstats
140
- keys = %w/
169
+ test "ncstats returns expected values" do
170
+ keys = %w[
141
171
  class
142
172
  dbl_enters
143
173
  enters
@@ -146,25 +176,29 @@ class TC_Solaris_Kstat < Test::Unit::TestCase
146
176
  long_look misses
147
177
  move_to_front
148
178
  purges
149
- /
179
+ ]
150
180
 
151
181
  assert_nothing_raised{ @kstat.record['unix'][0]['ncstats'] }
152
182
  assert_kind_of(Hash, @kstat.record['unix'][0]['ncstats'])
153
183
  assert_equal(keys, @kstat.record['unix'][0]['ncstats'].keys.sort)
154
184
  end
155
185
 
156
- def test_record_sysinfo
157
- keys = %w/class runocc runque swpocc swpque updates waiting/
186
+ test "sysinfo works as expected" do
187
+ keys = %w[class runocc runque swpocc swpque updates waiting]
158
188
 
159
189
  assert_nothing_raised{ @kstat.record['unix'][0]['sysinfo'] }
160
190
  assert_kind_of(Hash, @kstat.record['unix'][0]['sysinfo'])
161
191
  assert_equal(keys, @kstat.record['unix'][0]['sysinfo'].keys.sort)
162
192
  end
163
193
 
164
- def test_class_set
194
+ test "class key is set to expected value" do
165
195
  assert_equal("misc", @kstat.record['unix'][0]['sysinfo']['class'])
166
196
  end
167
197
 
198
+ test "ffi functions are private" do
199
+ assert_not_respond_to(Kstat, :kstat_open)
200
+ end
201
+
168
202
  def teardown
169
203
  @kstat = nil
170
204
  end