solaris-kstat 1.0.3 → 1.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.
@@ -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